chore: import upstream snapshot with attribution
FreeBSD Smoke / FreeBSD Smoke (x86_64) (push) Has been cancelled
CI / Quality Guardrails (push) Has been cancelled
CI / Build & Test (macos-latest) (push) Has been cancelled
CI / Build & Test (ubuntu-latest) (push) Has been cancelled
CI / Build & Test (windows-latest) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / PowerShell Syntax (push) Has been cancelled
CI / Windows Cross-Target Check (Linux) (push) Has been cancelled
FreeBSD Smoke / FreeBSD Smoke (x86_64) (push) Has been cancelled
CI / Quality Guardrails (push) Has been cancelled
CI / Build & Test (macos-latest) (push) Has been cancelled
CI / Build & Test (ubuntu-latest) (push) Has been cancelled
CI / Build & Test (windows-latest) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / PowerShell Syntax (push) Has been cancelled
CI / Windows Cross-Target Check (Linux) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,486 @@
|
||||
# Jcode Desktop Architecture Direction
|
||||
|
||||
Status: Proposed
|
||||
Updated: 2026-04-25
|
||||
|
||||
This document captures the initial direction for a desktop application for Jcode under these constraints:
|
||||
|
||||
- no Electron/Tauri/web-app shell
|
||||
- no general UI framework
|
||||
- very high performance
|
||||
- low idle resource use
|
||||
- very custom product UI
|
||||
- primary developer machine may be Linux
|
||||
- most early users are expected to be on macOS
|
||||
|
||||
The goal is to make the desktop client a first-class Jcode surface without forking the Jcode runtime or turning the app into a heavyweight IDE clone.
|
||||
|
||||
See also:
|
||||
|
||||
- [`DESKTOP_STABLE_HOST_RELOAD_STARTUP.md`](./DESKTOP_STABLE_HOST_RELOAD_STARTUP.md)
|
||||
- [`DESKTOP_SUPERAPP_WORKSPACE.md`](./DESKTOP_SUPERAPP_WORKSPACE.md)
|
||||
- [`DESKTOP_CODEBASE_ARCHITECTURE.md`](./DESKTOP_CODEBASE_ARCHITECTURE.md)
|
||||
- [`CLIENT_CORE_PRESENTATION_SPLIT_PLAN.md`](./CLIENT_CORE_PRESENTATION_SPLIT_PLAN.md)
|
||||
- [`MULTI_SESSION_CLIENT_ARCHITECTURE.md`](./MULTI_SESSION_CLIENT_ARCHITECTURE.md)
|
||||
- [`SERVER_ARCHITECTURE.md`](./SERVER_ARCHITECTURE.md)
|
||||
- [`MEMORY_BUDGET.md`](./MEMORY_BUDGET.md)
|
||||
|
||||
## Executive summary
|
||||
|
||||
Build Jcode Desktop as a small Rust desktop client with a custom GPU-rendered UI. The app should connect to a local Jcode server/daemon that owns sessions, tools, agent execution, persistence, and permissions.
|
||||
|
||||
The frontend should be optimized as a render/input surface:
|
||||
|
||||
- Linux should be a first-class development platform.
|
||||
- macOS should be the first-class product/distribution platform.
|
||||
- The UI should not depend on Linux-only desktop concepts.
|
||||
- The UI should not be a web view.
|
||||
- The UI should not embed the agent runtime directly.
|
||||
- Rendering should be on-demand, virtualized, and measurable from day one.
|
||||
|
||||
Recommended initial stack:
|
||||
|
||||
| Area | Decision |
|
||||
|---|---|
|
||||
| Frontend language | Rust |
|
||||
| Backend/runtime | Existing Rust Jcode server/session runtime |
|
||||
| Process model | Desktop frontend + local Jcode daemon/server |
|
||||
| Window/input layer | Thin platform layer, likely `winit` initially |
|
||||
| Rendering | `wgpu` with a custom 2D renderer |
|
||||
| UI architecture | Retained UI tree with dirty tracking |
|
||||
| Layout | Small custom layout system, not CSS/DOM |
|
||||
| Text | Dedicated text layout/raster cache, likely `cosmic-text`/`swash` or platform-backed text later |
|
||||
| Protocol | Versioned typed local event protocol |
|
||||
| Persistence | Server-owned session/event persistence |
|
||||
| Product identity | Agent operating console / mission control |
|
||||
|
||||
## Product stance
|
||||
|
||||
Jcode Desktop should not start as a full IDE and should not look like a conventional chatbot.
|
||||
|
||||
The differentiated product is a **keyboard-driven, Niri-like agent workspace superapp** for local development. The first-class object is not a chat window, but a workspace containing many navigable surfaces:
|
||||
|
||||
- agent sessions
|
||||
- activity/task views
|
||||
- diffs and changed files
|
||||
- file/diff/tool surfaces
|
||||
- optional future surfaces
|
||||
- settings/debug/tool surfaces
|
||||
|
||||
The app should help users:
|
||||
|
||||
- supervise autonomous coding work
|
||||
- inspect tool activity
|
||||
- manage background tasks
|
||||
- review changed files
|
||||
- respond to permission prompts
|
||||
- resume and coordinate sessions
|
||||
- navigate many related surfaces spatially
|
||||
|
||||
The desktop client should complement the TUI/CLI, not replace it.
|
||||
|
||||
## Platform strategy
|
||||
|
||||
### Development host: Linux
|
||||
|
||||
Linux should support the fastest inner loop:
|
||||
|
||||
- launch the desktop client locally
|
||||
- run renderer stress tests
|
||||
- run protocol integration tests
|
||||
- benchmark memory/frame/layout/text performance
|
||||
- debug the UI engine without a Mac in the loop
|
||||
|
||||
The Linux build should be real, not a fake simulator. It should render through the same UI engine and exercise the same protocol/view-model paths as macOS.
|
||||
|
||||
### Product target: macOS first
|
||||
|
||||
Most early users are expected to be on macOS, so macOS polish should be a product requirement even if day-to-day development happens on Linux.
|
||||
|
||||
Mac-specific work that should not be postponed too long:
|
||||
|
||||
- native `.app` bundle
|
||||
- app icon and menu bar integration
|
||||
- command-key shortcuts
|
||||
- system light/dark appearance
|
||||
- Retina rendering correctness
|
||||
- trackpad scrolling quality
|
||||
- native clipboard behavior
|
||||
- file/open-with integration
|
||||
- code signing and notarization path
|
||||
- good behavior under Mission Control, Spaces, and full-screen windows
|
||||
|
||||
### Avoid Linux-shaped product assumptions
|
||||
|
||||
Because the developer may use Linux, the architecture should explicitly avoid baking in assumptions that work well only with a Linux window manager.
|
||||
|
||||
Do not make these hard dependencies:
|
||||
|
||||
- Niri-style external spatial window management
|
||||
- X11-specific APIs
|
||||
- Wayland-only behavior
|
||||
- terminal-first session workflows
|
||||
- Linux notification semantics
|
||||
- global shortcuts that are unavailable or hostile on macOS
|
||||
|
||||
The existing Linux/Niri workflow should remain excellent, but desktop product quality should be judged primarily against macOS expectations.
|
||||
|
||||
## Process architecture
|
||||
|
||||
Use a split process architecture:
|
||||
|
||||
```text
|
||||
Jcode Desktop Frontend
|
||||
- window/input
|
||||
- custom rendering
|
||||
- local view model
|
||||
- transient UI state
|
||||
- surface-local state
|
||||
- protocol client
|
||||
|
||||
Jcode Server/Daemon
|
||||
- sessions
|
||||
- agent runtime
|
||||
- tool runtime
|
||||
- background tasks
|
||||
- persistence
|
||||
- permissions
|
||||
- model/provider configuration
|
||||
```
|
||||
|
||||
The server remains the source of truth for:
|
||||
|
||||
- canonical session history
|
||||
- streaming events
|
||||
- tool execution
|
||||
- file edits
|
||||
- background tasks
|
||||
- permission state
|
||||
- persisted configuration
|
||||
|
||||
The desktop frontend owns only surface-local state:
|
||||
|
||||
- selected session/surface
|
||||
- draft input
|
||||
- cursor and text selection
|
||||
- scroll offsets
|
||||
- pane sizes
|
||||
- focused panel
|
||||
- local command palette state
|
||||
- render caches
|
||||
|
||||
This aligns with the multi-session model where a server-owned session can be shown by different clients or surfaces over time.
|
||||
|
||||
## Local protocol direction
|
||||
|
||||
The desktop app should consume a versioned, typed event stream rather than periodically fetching complete session snapshots.
|
||||
|
||||
Early protocol properties:
|
||||
|
||||
- local-first transport
|
||||
- explicit protocol version
|
||||
- capability negotiation
|
||||
- append-only session events
|
||||
- streaming deltas for assistant/tool output
|
||||
- resumable subscriptions by event cursor
|
||||
- compact events for high-volume tool output
|
||||
- server-owned permission requests
|
||||
|
||||
Possible transports:
|
||||
|
||||
1. Existing Jcode server channel, if compatible with desktop needs.
|
||||
2. Unix domain socket on Linux/macOS and named pipe on Windows.
|
||||
3. Stdio JSON protocol for early prototypes and test harnesses.
|
||||
|
||||
Avoid localhost HTTP as the default unless there is a strong reason. It creates a larger local security surface than a user-owned socket/pipe.
|
||||
|
||||
Example event families:
|
||||
|
||||
```text
|
||||
session.created
|
||||
session.updated
|
||||
surface.attached
|
||||
message.created
|
||||
message.delta
|
||||
message.completed
|
||||
tool.started
|
||||
tool.output.delta
|
||||
tool.completed
|
||||
task.started
|
||||
task.progress
|
||||
task.completed
|
||||
workspace.changed
|
||||
git.changed
|
||||
permission.requested
|
||||
permission.resolved
|
||||
error
|
||||
```
|
||||
|
||||
## Rendering architecture
|
||||
|
||||
Use a custom renderer rather than a native widget hierarchy or web view.
|
||||
|
||||
Recommended layers:
|
||||
|
||||
```text
|
||||
Platform window/input
|
||||
-> input normalizer
|
||||
-> app state/view model
|
||||
-> retained UI tree
|
||||
-> layout
|
||||
-> text layout/cache
|
||||
-> display list
|
||||
-> GPU renderer
|
||||
```
|
||||
|
||||
Core rules:
|
||||
|
||||
- no continuous render loop when idle
|
||||
- render only on input, data events, animations, or explicit invalidation
|
||||
- virtualize every unbounded list
|
||||
- separate layout cost from paint cost
|
||||
- cache shaped text by content/font/width
|
||||
- use stable IDs for dirty tracking
|
||||
- make debug/performance counters visible in-app
|
||||
|
||||
The renderer should initially support:
|
||||
|
||||
- rectangles
|
||||
- rounded rectangles
|
||||
- borders
|
||||
- solid fills
|
||||
- clipping
|
||||
- scroll containers
|
||||
- text runs
|
||||
- monospaced blocks
|
||||
- simple icons or vector-like primitives
|
||||
- image support later
|
||||
|
||||
Defer:
|
||||
|
||||
- blur effects
|
||||
- complex shadows
|
||||
- animation framework
|
||||
- SVG-heavy rendering
|
||||
- full markdown renderer
|
||||
- full terminal emulator
|
||||
- embedded code editor
|
||||
|
||||
## UI architecture
|
||||
|
||||
Use a retained UI tree with immediate-style builder ergonomics.
|
||||
|
||||
Rationale:
|
||||
|
||||
- transcripts are long-lived and streamed incrementally
|
||||
- tool outputs can be large
|
||||
- panes need stable focus/selection state
|
||||
- dirty tracking matters for resource use
|
||||
- accessibility will eventually need stable semantic nodes
|
||||
- multi-session surfaces need stable identity
|
||||
|
||||
The model should not imitate the DOM/CSS stack. A small product-specific layout system is enough:
|
||||
|
||||
- row
|
||||
- column
|
||||
- stack
|
||||
- split pane
|
||||
- fixed size
|
||||
- flex fill
|
||||
- scroll container
|
||||
- virtual list
|
||||
- overlay/modal
|
||||
- intrinsic text measurement
|
||||
|
||||
## Text strategy
|
||||
|
||||
Text is one of the hardest parts of this project and should be treated as a core system, not a detail.
|
||||
|
||||
The desktop client needs:
|
||||
|
||||
- Unicode shaping
|
||||
- font fallback
|
||||
- monospace code/tool output
|
||||
- wrapping
|
||||
- incremental append layout
|
||||
- selection/copy
|
||||
- input cursor behavior
|
||||
- command palette text input
|
||||
- markdown-ish transcript styling
|
||||
- ANSI-like tool output styling eventually
|
||||
|
||||
Initial recommendation:
|
||||
|
||||
- use a Rust text stack such as `cosmic-text`/`swash` if dependency review is acceptable
|
||||
- maintain a GPU glyph atlas
|
||||
- cache shaped lines/runs by stable block ID and available width
|
||||
- specialize streamed append paths so new output does not re-layout the whole transcript
|
||||
|
||||
Mac-specific text quality should be evaluated early. If Rust text rendering is not good enough on macOS, consider platform-backed text for macOS while preserving the same higher-level text layout API.
|
||||
|
||||
## Performance and resource budgets
|
||||
|
||||
Initial budgets should be measured on both Linux development machines and representative macOS hardware.
|
||||
|
||||
| Metric | MVP target | Long-term target |
|
||||
|---|---:|---:|
|
||||
| Cold launch to visible window | < 500 ms | < 150 ms |
|
||||
| Frontend idle CPU | ~0% | ~0% |
|
||||
| Frontend idle RSS | < 100 MiB | < 50 MiB |
|
||||
| Input-to-paint latency | < 32 ms | < 16 ms |
|
||||
| Scrolling | 60 fps | 120 fps-capable |
|
||||
| Fake transcript stress case | 100k blocks usable | 100k blocks smooth |
|
||||
| Full transcript re-layout on append | forbidden | forbidden |
|
||||
| Unbounded retained visible nodes | forbidden | forbidden |
|
||||
| Renderer frame when idle | forbidden | forbidden |
|
||||
|
||||
Required early instrumentation:
|
||||
|
||||
- frame time
|
||||
- layout time
|
||||
- text shaping time
|
||||
- display-list build time
|
||||
- GPU submit time
|
||||
- visible node count
|
||||
- total retained node count
|
||||
- glyph atlas size
|
||||
- text cache size
|
||||
- protocol event backlog
|
||||
- daemon round-trip latency
|
||||
- frontend RSS if available
|
||||
|
||||
A debug HUD should exist in the prototype before real Jcode integration is considered complete.
|
||||
|
||||
Example HUD:
|
||||
|
||||
```text
|
||||
frame 1.8ms | layout 0.3ms | text 0.6ms | gpu 0.4ms
|
||||
nodes 812 | visible 47 | glyph atlas 12.4 MiB | events 0 | daemon 2ms
|
||||
```
|
||||
|
||||
## MVP scope
|
||||
|
||||
The first UI milestone should prove the engine before proving every product workflow.
|
||||
|
||||
### Milestone 1: custom shell with fake data
|
||||
|
||||
Success criteria:
|
||||
|
||||
- launches a native desktop window from Linux
|
||||
- renders through the custom GPU pipeline
|
||||
- shows session sidebar, transcript, composer, and activity panel
|
||||
- handles mouse, keyboard, focus, and scrolling
|
||||
- renders fake streamed transcript data
|
||||
- virtualizes a 100k-block transcript
|
||||
- idles at near-zero CPU
|
||||
- exposes performance/debug HUD
|
||||
- has screenshot or golden-state tests where practical
|
||||
|
||||
### Milestone 2: protocol connection
|
||||
|
||||
Success criteria:
|
||||
|
||||
- connects to local Jcode server/daemon
|
||||
- lists sessions
|
||||
- attaches to a session/surface
|
||||
- subscribes to event stream
|
||||
- sends a user prompt
|
||||
- streams assistant/tool events into the transcript
|
||||
- can stop/cancel an active run
|
||||
- recovers from daemon restart or disconnect gracefully enough for development use
|
||||
|
||||
### Milestone 3: useful agent console
|
||||
|
||||
Success criteria:
|
||||
|
||||
- activity center for background tasks/tool calls
|
||||
- permission request overlay
|
||||
- workspace/git status panel
|
||||
- changed-file list
|
||||
- open external editor/diff action
|
||||
- session search/filter
|
||||
- macOS app bundle prototype
|
||||
|
||||
## Crate layout proposal
|
||||
|
||||
Do not put the whole desktop app in the root crate.
|
||||
|
||||
Suggested structure:
|
||||
|
||||
```text
|
||||
crates/
|
||||
jcode-desktop-protocol/ # shared protocol/event types if not already covered by server types
|
||||
jcode-desktop-ui/ # UI tree, layout, text/cache abstractions, renderer-agnostic pieces
|
||||
jcode-desktop-renderer/ # wgpu renderer and GPU resources
|
||||
jcode-desktop/ # app shell, platform window, protocol client, product UI
|
||||
```
|
||||
|
||||
If compile time becomes a problem, keep protocol/UI crates lightweight and gate GPU/window dependencies behind the final app crate.
|
||||
|
||||
## Dependency policy
|
||||
|
||||
“No frameworks” does not have to mean “no libraries.” It should mean no heavyweight app framework and no web-shell product architecture.
|
||||
|
||||
Likely acceptable dependencies:
|
||||
|
||||
- `wgpu` for rendering abstraction
|
||||
- a very thin window/input layer such as `winit` for bootstrapping
|
||||
- `cosmic-text`/`swash` or equivalent for text shaping/rasterization
|
||||
- small serialization/protocol crates already consistent with Jcode
|
||||
|
||||
Avoid:
|
||||
|
||||
- Electron
|
||||
- Tauri
|
||||
- Qt
|
||||
- Flutter
|
||||
- GTK as the app framework
|
||||
- WebView UI shell
|
||||
- React/Vue/Svelte-style UI stack
|
||||
- CSS/DOM-based architecture
|
||||
|
||||
If `winit` becomes limiting for macOS polish, the platform layer can grow direct AppKit support while preserving the renderer and UI model.
|
||||
|
||||
## macOS validation checklist
|
||||
|
||||
Because macOS is the primary user target, validate these early even if development happens on Linux:
|
||||
|
||||
- Retina scale factor correctness
|
||||
- trackpad inertial scrolling
|
||||
- text clarity compared with native apps
|
||||
- keyboard shortcuts use Command rather than Control where appropriate
|
||||
- system dark/light mode follows user preference
|
||||
- window resizing and full-screen behavior feels native
|
||||
- app menu and close/minimize/quit semantics are correct
|
||||
- clipboard round-trips rich enough for code and transcripts
|
||||
- local socket permissions are safe
|
||||
- app bundle can launch/find the daemon reliably
|
||||
|
||||
## Open decisions
|
||||
|
||||
These should be resolved before implementation moves past the fake-data prototype:
|
||||
|
||||
1. Use `winit` initially or write direct platform shells from the start?
|
||||
2. Use `wgpu` or direct Metal-first rendering?
|
||||
3. Use `cosmic-text`/`swash` or platform text APIs?
|
||||
4. Reuse the existing Jcode server protocol or introduce a desktop-specific event protocol crate?
|
||||
5. Should the first desktop binary support multi-surface mode or only one active surface?
|
||||
6. What is the minimum macOS version to support?
|
||||
7. What is the first distribution path: local `.app`, Homebrew cask, or signed/notarized DMG?
|
||||
|
||||
## Recommended immediate next step
|
||||
|
||||
Create a fake-data desktop prototype that runs on Linux but measures the exact performance characteristics required by the eventual macOS product.
|
||||
|
||||
The prototype should not wait for a perfect daemon API. It should validate the expensive UI systems first:
|
||||
|
||||
- window creation
|
||||
- renderer startup
|
||||
- retained tree
|
||||
- layout
|
||||
- text cache
|
||||
- virtualized transcript
|
||||
- on-demand repaint
|
||||
- debug HUD
|
||||
|
||||
Only after that should the real Jcode event stream be connected.
|
||||
Reference in New Issue
Block a user