Skip to content

Latest commit

 

History

History
167 lines (134 loc) · 5.82 KB

File metadata and controls

167 lines (134 loc) · 5.82 KB

FunCode

简体中文 | English

FunCode is a Tauri 2 desktop workbench that embeds the official Cline SDK in a Rust-managed Node.js sidecar. The WebView never receives direct shell access: commands and events cross a small, versioned JSON-lines protocol.

Preview

FunCode task workbench FunCode project file browser

Architecture

Tauri WebView
  └─ invoke / events
      └─ Rust host (process lifecycle and native boundary)
          └─ stdin / stdout JSONL
              └─ Node sidecar
                  └─ @cline/sdk / ClineCore

The current implementation uses ClineCore in local mode. Each task is an independent chat with its own workspace and approval mode. Ask first prompts before every tool call, Auto approves the built-in workspace tools while prompting for unknown or external tools, and Full access runs all tools without approval prompts.

Project structure

.
├── packages/
│   └── protocol/                 Shared host/sidecar message contracts
├── sidecar/
│   ├── scripts/                  Bundle and platform binary build scripts
│   └── src/
│       ├── cline/                ClineCore task runtime and approval bridge
│       ├── ipc/                  JSONL output and serialization
│       └── main.ts               Sidecar process entry
├── storage/                       Runtime task and conversation persistence
├── src/
│   ├── features/
│   │   ├── approvals/            Tool approval UI
│   │   └── chat/                 Agent event rendering
│   ├── services/                 Tauri IPC client
│   ├── main.ts                   Desktop UI coordinator
│   └── styles.css
└── src-tauri/
    ├── binaries/                 Generated target-specific sidecar binaries
    ├── capabilities/
    ├── src/
    │   ├── lib.rs                Tauri application setup
    │   └── sidecar.rs            Sidecar lifecycle and event bridge
    └── tauri.conf.json

Requirements

Commands

# Web UI only
npm run dev

# Type-check the WebView and sidecar
npm run typecheck

# Generate the target-specific sidecar binary
npm run sidecar:build

# Run the complete desktop application
npm run tauri dev

# Build production frontend assets
npm run build

The npm run tauri wrapper prepares the sidecar before invoking Tauri, so Vite can start immediately when Tauri begins waiting for its dev URL. Unchanged sidecar sources reuse the existing binary. The generated binary follows Tauri's required target-triple naming:

src-tauri/binaries/testcline-agent-<target-triple>[.exe]

Protocol

Host commands include:

  • system.ping
  • task.start
  • task.send
  • task.delete
  • task.list
  • task.config.save
  • workspace.files.list
  • task.abort
  • approval.resolve

Sidecar events include:

  • system.ready and system.status
  • task.status for per-task running, idle, and failed state
  • command.result
  • agent.event
  • approval.requested
  • sidecar.log

The sidecar reserves stdout for JSONL protocol messages. Operational logs go to stderr and are bridged to the desktop as structured log events.

Persistent storage

In development, FunCode creates the ignored storage/ directory in the project root. Packaged builds use the operating system's application-data directory. Set TESTCLINE_STORAGE=/absolute/path to override either location.

storage/
├── tasks/
│   └── <task-id>/
│       ├── task.json              Task workspace and model configuration
│       └── events.jsonl           FunCode-only notices and lifecycle events
└── cline/
    ├── db/sessions.db             Cline session metadata and lookup index
    └── sessions/<session-id>/
        └── <session-id>.messages.json
                                    Authoritative model conversation

FunCode does not duplicate user or assistant messages. Task history is projected from Cline's persisted session messages when the app starts, while events.jsonl contains only application-specific records such as cancellation and failure notices. Legacy conversation.jsonl files are not read or written. The tasks/ index also keeps configurations saved before their first Cline session starts; removing it requires either making those drafts ephemeral or migrating drafts and FunCode-only notices into Cline-owned metadata.

API keys are stored as plaintext per model connection in the funcode_connection_credentials table inside Cline's db/sessions.db. A saved credential can be reused by new tasks that use the same provider, model, and Base URL. Task metadata, task-list responses, and restored frontend state do not contain the credential. The API key field shows a masked saved state after the sidecar confirms that a matching credential exists.

Security notes

  • The frontend does not receive Tauri shell-plugin permissions.
  • Rust owns sidecar start, write, stop, and event forwarding.
  • Persisted API keys are not returned to the WebView or written into task metadata and Cline session manifests. They are plaintext in the local Cline SQLite database, so filesystem access to that database exposes them.
  • Every task is scoped to the configured absolute workspace path.
  • Approval behavior is selected per task with Ask first, Auto, or Full access.

For production, add native workspace selection, workspace path canonicalization, signed release binaries, and per-platform CI.