Skip to content

Latest commit

 

History

History
18 lines (14 loc) · 3.21 KB

AGENTS.md

File metadata and controls

18 lines (14 loc) · 3.21 KB

JuCode Desktop

Terms

  • 后端 (backend): the agent backend — the coding-agent engine that runs a session: JuCode's own engine, Claude Code, Codex, or an ACP agent. In code it is BackendId / backendId; the daemon protocol calls it engine. It never means a server side, the daemon (the UI calls that 后台服务, "background service"), or a model provider (provider).
  • 草稿 (draft session): a new session before its first message. It has a chosen backend, model and effort but no engine and no daemon session; the first op sent to it starts the engine (markDraft in src/lib/backends/router.ts, SessionStore.#startDraft). Until then nothing may spawn a backend: switching backend, model or effort only records the choice.

Recurring defects

  • An $effect that calls store methods reads that store's state too, so the store's own changes re-run it (the web chat reset a new conversation as its first message saved it). Wrap the calls in untrack and depend only on the inputs that should drive it.
  • The CSP applies only to the packaged app, so dev mode and CI never hit it. Tauri adds a nonce to style-src once the HTML has a <style>, and that disables 'unsafe-inline'; CodeMirror then loses every style. src/csp.test.ts pins the settings the frontend needs. Before a release, open the editor and a reply with math in a packaged build.
  • The daemon outlives desktop updates, so a field a newer desktop reads may be missing from the daemon still running. Treat a missing field as unknown and keep the current state; never read it as null or empty (read as null, a missing project would move every session out of its project, and the next save would drop their tabs from workspaces.json).
  • A session the daemon closed for idleness is asleep (markAsleep), not exited: it must not restart on its own, and anything that starts its engine clears the sleep (#spawn does). An op a sleeping session should act on goes in the router's WAKING, or it waits silently.
  • A global class in app.css must not reuse a name components already scope locally: the unscoped rule styles every one of them (a global .backdrop hid the click-outside layer of every Select, so menus stopped closing). Prefix app-wide classes (theme-backdrop).
  • A dialog that shows the head of a queue (connect requests) must remount per item ({#key item.id}) and ignore clicks while a decision is in flight: otherwise a double click, or an Enter, answers the next item that slid under the pointer.
  • Select calls onChange when the option already chosen is picked again. A handler that restarts an engine or writes config must ignore the current value (re-picking the current provider in the model menu restarted the engine mid-reply).
  • A user message is its text, its images and its files (files, sent apart from the text). Anything that sends one again or puts it back in the composer (automatic retry, rewind, edit, a queued message taken back) carries all three; a retry once sent the text alone and the files were silently gone.
  • While the theme follows the system, the native window setTheme gets null, never a concrete theme: setting one flips the webview's prefers-color-scheme, whose listener re-resolves the mode and flips it back, without end.