feat: add tauri desktop app (#1478)
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
# 0026: Tauri Desktop Shell Over Native Runtime
|
||||
|
||||
**Status:** accepted
|
||||
**Date:** 2026-06-23
|
||||
**Area:** frontend, backend, cli, infra
|
||||
|
||||
## Context
|
||||
|
||||
Kandev now has a native Go launcher/backend path and embeds the Vite SPA into the backend binary. Users can run Kandev from CLI-oriented channels, but a desktop install should open from the OS launcher, manage a local backend process, and avoid a production Node.js runtime. The desktop packaging choice needs to preserve the existing local-first backend, agent executors, and release versioning model.
|
||||
|
||||
## Decision
|
||||
|
||||
Add a Tauri v2 desktop app as a thin native shell over the existing Kandev runtime. The shell lives under `apps/desktop`, packages the platform runtime binaries as resources, launches the native Kandev launcher in headless mode, waits for the backend `/health` endpoint, and loads the existing Go-served SPA in a native WebView.
|
||||
|
||||
The installed desktop app will not include a Node.js runtime. Node.js and pnpm remain build-time tooling for Vite, TypeScript, Tauri CLI invocation, tests, and release automation.
|
||||
|
||||
Desktop launches set the backend to a loopback-only bind address and an app-selected local port. Public desktop releases require macOS Developer ID signing/notarization and Windows code signing before the artifacts are presented as trusted downloads. The first desktop implementation does not include Tauri's in-app updater; updates continue through GitHub release downloads/manual reinstall until a separate updater spec is approved.
|
||||
|
||||
## Consequences
|
||||
|
||||
The desktop app can reuse the existing backend, embedded web UI, data directory, agent runtime, and supervisor behavior instead of introducing a parallel application stack. Release artifacts grow by the Tauri shell and installer overhead, but avoid Electron's bundled Chromium and avoid a runtime Node.js dependency.
|
||||
|
||||
CI becomes more complex because desktop installers must be built on OS-specific runners and signing requires protected secrets. The desktop app also adds a new security boundary: the WebView must not get broad shell/filesystem permissions, and backend process spawning should stay in Rust-side Tauri code.
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
1. **Electron desktop app.** Rejected because it would add a bundled Chromium and Node.js runtime, increasing artifact size and conflicting with the no-production-Node direction established by ADR-0021 and ADR-0022.
|
||||
2. **Rewrite the UI in a native toolkit.** Rejected because it would duplicate the existing React product surface and slow delivery without improving the backend/runtime model.
|
||||
3. **Browser-only PWA.** Rejected because it does not solve OS-level desktop installation, app launcher integration, or process lifecycle ownership for the local backend.
|
||||
4. **Tauri shell that embeds all UI assets separately from the Go backend.** Rejected for the first implementation because the backend already embeds and serves the release-quality Vite SPA. Duplicating the assets would increase packaging complexity and risk frontend/backend version drift.
|
||||
@@ -31,3 +31,4 @@ Read individual ADRs for full context. Create new ones via `/record decision` or
|
||||
| 0023 | [Active workspace cookie for boot state](0023-active-workspace-cookie.md) | accepted | backend, frontend | 2026-06-18 |
|
||||
| 0024 | [Go-fronted Vite dev mode](0024-go-fronted-vite-dev-mode.md) | accepted | backend, frontend, cli | 2026-06-18 |
|
||||
| 0025 | [Runtime cleanup uses `executors_running`](0025-runtime-cleanup-uses-executors-running.md) | accepted | backend | 2026-06-22 |
|
||||
| 0026 | [Tauri desktop shell over native runtime](0026-tauri-desktop-shell.md) | accepted | frontend, backend, cli, infra | 2026-06-23 |
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# Kandev Desktop App
|
||||
|
||||
Kandev desktop is a Tauri app that starts the native Kandev runtime locally and shows the existing Kandev UI in a system WebView. It does not require Node.js at runtime. Node.js, pnpm, Rust, and the Tauri CLI are build-time tools only.
|
||||
|
||||
## Install Artifacts
|
||||
|
||||
GitHub releases publish desktop artifacts alongside the existing runtime tarballs. Desktop artifact names start with `kandev-desktop-<platform>-` and each artifact has a `.sha256` checksum.
|
||||
|
||||
Supported desktop platforms:
|
||||
|
||||
- `macos-arm64`
|
||||
- `macos-x64`
|
||||
- `linux-x64`
|
||||
- `linux-arm64`
|
||||
- `windows-x64`
|
||||
|
||||
Public recommended macOS artifacts must be Developer ID signed and notarized. Public recommended Windows artifacts must be code signed. Linux artifacts are checksum-gated; package-manager signatures can be added later.
|
||||
|
||||
Unsigned macOS or Windows desktop artifacts are for internal validation only. They may require manual OS security bypasses and should not be presented as trusted public downloads.
|
||||
|
||||
## Runtime Requirements
|
||||
|
||||
The desktop app packages the native Kandev runtime binaries and starts:
|
||||
|
||||
```text
|
||||
kandev --headless --port <local-port>
|
||||
```
|
||||
|
||||
The backend binds to `127.0.0.1` and serves the same embedded Vite UI used by the CLI/Homebrew/npm runtime.
|
||||
|
||||
Platform WebView requirements:
|
||||
|
||||
- macOS: system WebKit.
|
||||
- Windows: Microsoft WebView2 runtime.
|
||||
- Linux: WebKitGTK and package dependencies installed by the `.deb`/`.rpm` package.
|
||||
|
||||
Kandev data still lives in the existing Kandev home directory, `~/.kandev` by default, unless overridden by existing environment/config settings.
|
||||
|
||||
## Updates
|
||||
|
||||
The first desktop release does not include an in-app Tauri updater. Update by downloading and installing a newer desktop artifact from GitHub Releases. Existing worktrees, settings, tasks, and the SQLite database remain in the Kandev data directory.
|
||||
|
||||
The npm and Homebrew channels continue to update through:
|
||||
|
||||
```bash
|
||||
brew upgrade kandev
|
||||
npm install -g kandev@latest
|
||||
npx kandev@latest
|
||||
```
|
||||
|
||||
Those channels are separate from desktop installers, even though all release artifacts share the same SemVer.
|
||||
|
||||
## Agent CLI Discovery
|
||||
|
||||
Desktop apps launched from an OS app launcher may not inherit the same shell initialization as a terminal. Kandev preserves available environment variables and adds common user binary directories such as `/usr/local/bin`, `/opt/homebrew/bin`, `/usr/bin`, `/bin`, `~/.local/bin`, and common agent install directories.
|
||||
|
||||
If an agent CLI is not discoverable from the desktop app:
|
||||
|
||||
- Set the agent profile command to the full executable path.
|
||||
- Confirm the executable works from a normal terminal.
|
||||
- Put custom install directories in a location visible to GUI apps, or configure them through OS-level environment settings rather than only shell startup files.
|
||||
|
||||
Existing explicit command paths in Kandev settings remain authoritative over `PATH` lookup.
|
||||
|
||||
## Release Trust
|
||||
|
||||
See [desktop-tauri-signing.md](desktop-tauri-signing.md) for the CI secrets and signing expectations used for trusted desktop releases.
|
||||
@@ -0,0 +1,36 @@
|
||||
# Tauri Desktop Signing
|
||||
|
||||
Public recommended desktop releases require signing on macOS and Windows. The release workflow fails closed by default when those secrets are missing.
|
||||
|
||||
Use `allow_unsigned_desktop=true` only for internal validation builds. That mode may upload workflow artifacts for maintainer inspection, but it does not publish a GitHub release, npm packages, Homebrew updates, or public container tags. Unsigned desktop artifacts are internal validation only and must not be presented as trusted public downloads.
|
||||
|
||||
## macOS
|
||||
|
||||
Required signing secrets:
|
||||
|
||||
- `APPLE_CERTIFICATE`: base64 `.p12` Developer ID Application certificate.
|
||||
- `APPLE_CERTIFICATE_PASSWORD`: export password for the `.p12`.
|
||||
- `KEYCHAIN_PASSWORD`: temporary CI keychain password.
|
||||
|
||||
Required notarization secrets, choose one path:
|
||||
|
||||
- Apple ID path: `APPLE_ID`, `APPLE_PASSWORD`, `APPLE_TEAM_ID`.
|
||||
- App Store Connect API path: `APPLE_API_KEY`, `APPLE_API_ISSUER`, `APPLE_API_KEY_P8`.
|
||||
|
||||
Optional:
|
||||
|
||||
- `APPLE_PROVIDER_SHORT_NAME` when the Apple ID belongs to multiple provider teams.
|
||||
|
||||
## Windows
|
||||
|
||||
Required signing secrets:
|
||||
|
||||
- `WINDOWS_CERTIFICATE`: base64 `.pfx` code signing certificate.
|
||||
- `WINDOWS_CERTIFICATE_PASSWORD`: export password for the `.pfx`.
|
||||
|
||||
Optional:
|
||||
|
||||
- `WINDOWS_TIMESTAMP_URL`: timestamp server, defaults to `http://timestamp.digicert.com`.
|
||||
- `WINDOWS_SIGNTOOL_PATH`: custom `signtool.exe` path.
|
||||
|
||||
Linux desktop artifacts are checksum-gated. The x64 `.deb`/`.rpm` artifacts are built on Ubuntu 22.04 for an older glibc baseline. The arm64 artifacts use GitHub's Ubuntu 24.04 arm64 runner baseline. GPG/RPM signing can be added later without changing the macOS and Windows trust gate.
|
||||
@@ -25,6 +25,7 @@ This page expands the short feature list in the README without turning the READM
|
||||
|
||||
## Executors And Runtime
|
||||
|
||||
- **Desktop app:** install Kandev as a Tauri desktop app that starts the local backend and shows the existing Kandev UI without requiring Node.js at runtime. See [desktop-app.md](desktop-app.md).
|
||||
- **Executor types:** run agents as local host processes, git worktrees, Docker containers, remote SSH sessions, or Sprites cloud environments.
|
||||
- **Executor profiles:** save per-runtime configuration, including prepare scripts, environment variables, credentials, and profile-specific settings.
|
||||
- **Worktree isolation:** concurrent agents work in isolated git worktrees so their changes do not collide.
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
---
|
||||
spec: docs/specs/desktop-tauri-app/spec.md
|
||||
created: 2026-06-23
|
||||
status: done
|
||||
---
|
||||
|
||||
# Implementation Plan: Tauri Desktop App
|
||||
|
||||
## Overview
|
||||
|
||||
Add `apps/desktop` as a Tauri v2 shell that packages the existing native Kandev runtime, starts it in headless mode, waits for backend health, and loads the Go-served SPA in a desktop WebView. The implementation starts by tightening the backend/launcher contract for loopback desktop launches, then scaffolds the app, wires release packaging, adds signing gates, and finishes with desktop smoke coverage and docs.
|
||||
|
||||
---
|
||||
|
||||
## Architecture Records
|
||||
|
||||
- Spec: `docs/specs/desktop-tauri-app/spec.md`
|
||||
- Decision: `docs/decisions/0026-tauri-desktop-shell.md`
|
||||
- Existing dependencies: ADR-0021 Go-served SPA with boot state, ADR-0022 embedded Vite assets, and the native launcher spec at `docs/specs/native-kandev-cli/spec.md`.
|
||||
|
||||
---
|
||||
|
||||
## Backend
|
||||
|
||||
### Loopback bind contract
|
||||
|
||||
Files:
|
||||
|
||||
- `apps/backend/internal/common/config/config.go`
|
||||
- `apps/backend/internal/backendapp/main.go`
|
||||
- `apps/backend/internal/backendapp/helpers_test.go` or a focused backend server test
|
||||
- `apps/backend/internal/launcher/env.go`
|
||||
- `apps/backend/internal/launcher/start_test.go` or `apps/backend/internal/launcher/run_test.go`
|
||||
|
||||
Use the existing `ServerConfig.Host` field when constructing the HTTP server address and listener address. Preserve the current default unless a caller sets `server.host` / `KANDEV_SERVER_HOST`. The desktop app will set `KANDEV_SERVER_HOST=127.0.0.1`.
|
||||
|
||||
Add tests proving:
|
||||
|
||||
- `buildHTTPServer` uses the configured host in `http.Server.Addr`.
|
||||
- `startHTTPServer` listens on the configured host/port.
|
||||
- launcher env construction can pass a backend host override for desktop/headless launches without changing normal CLI defaults.
|
||||
|
||||
### Headless launcher lifecycle contract
|
||||
|
||||
Files:
|
||||
|
||||
- `apps/backend/internal/launcher/start.go`
|
||||
- `apps/backend/internal/launcher/health.go`
|
||||
- `apps/backend/internal/launcher/process.go`
|
||||
- Existing launcher tests under `apps/backend/internal/launcher/`
|
||||
|
||||
Keep `kandev --headless --port <port>` as the desktop process contract. It must supervise `kandev __backend`, wait for `/health`, skip opening a browser, and remain alive until the backend exits or the parent process terminates. Desktop-specific process termination should use the same process-group/job-object cleanup behavior already covered by the native launcher.
|
||||
|
||||
---
|
||||
|
||||
## Desktop App
|
||||
|
||||
### Workspace package
|
||||
|
||||
Files:
|
||||
|
||||
- `apps/pnpm-workspace.yaml`
|
||||
- `apps/package.json`
|
||||
- New `apps/desktop/package.json`
|
||||
- New `apps/desktop/index.html`
|
||||
- New `apps/desktop/src/main.ts`
|
||||
- New `apps/desktop/src/styles.css`
|
||||
- New `apps/desktop/src-tauri/Cargo.toml`
|
||||
- New `apps/desktop/src-tauri/build.rs`
|
||||
- New `apps/desktop/src-tauri/tauri.conf.json`
|
||||
- New `apps/desktop/src-tauri/src/main.rs`
|
||||
- New `apps/desktop/src-tauri/src/backend.rs`
|
||||
- New `apps/desktop/src-tauri/capabilities/default.json`
|
||||
|
||||
Add a minimal Tauri/Vite desktop package named `@kandev/desktop`. The app's first screen is a compact startup surface, not a marketing page. Rust-side Tauri code locates the packaged runtime resources, picks an available loopback port, spawns the native launcher in headless mode, polls `/health`, and navigates the main window to the backend URL.
|
||||
|
||||
Do not expose shell execution to frontend JavaScript. Backend process control should live in Rust-side Tauri code.
|
||||
|
||||
### Runtime resources
|
||||
|
||||
Files:
|
||||
|
||||
- New `scripts/release/prepare-desktop-runtime.sh`
|
||||
- New `scripts/release/verify-desktop-runtime.sh`
|
||||
- `apps/desktop/src-tauri/tauri.conf.json`
|
||||
- `apps/desktop/src-tauri/src/backend.rs`
|
||||
|
||||
Create a deterministic resource layout for the platform runtime extracted from the existing release bundle:
|
||||
|
||||
```text
|
||||
apps/desktop/src-tauri/resources/kandev/
|
||||
└── bin/
|
||||
├── kandev[.exe]
|
||||
├── agentctl[.exe]
|
||||
└── agentctl-linux-amd64
|
||||
```
|
||||
|
||||
The helper validates the exact binaries required by `internal/launcher/bundle.go` so the desktop app and existing runtime tarballs cannot drift.
|
||||
|
||||
### Desktop process environment
|
||||
|
||||
Files:
|
||||
|
||||
- `apps/desktop/src-tauri/src/backend.rs`
|
||||
- `apps/backend/internal/launcher/env.go`
|
||||
- `apps/backend/internal/launcher/service.go` for existing PATH precedent
|
||||
- `docs/desktop-tauri-signing.md` or desktop install docs for troubleshooting notes
|
||||
|
||||
Build the backend process environment explicitly. Preserve inherited variables, force `KANDEV_SERVER_HOST=127.0.0.1`, and normalize `PATH` for GUI app launches so agent CLIs installed under common user locations are visible. Existing explicit agent command paths in settings remain authoritative; this task only makes default command lookup reliable.
|
||||
|
||||
### Desktop UX
|
||||
|
||||
Files:
|
||||
|
||||
- `apps/desktop/src/main.ts`
|
||||
- `apps/desktop/src/styles.css`
|
||||
- `apps/desktop/src-tauri/src/main.rs`
|
||||
- `apps/desktop/src-tauri/src/backend.rs`
|
||||
|
||||
The startup surface shows only launch status and errors. Once the backend is ready, the WebView loads the existing Kandev UI. The app should support standard OS close/quit behavior and single-instance focus.
|
||||
|
||||
---
|
||||
|
||||
## Release Pipeline
|
||||
|
||||
### Build matrix
|
||||
|
||||
Files:
|
||||
|
||||
- `.github/workflows/release.yml`
|
||||
- `scripts/release/verify-desktop-assets.sh`
|
||||
- `apps/cli/src/release-config.test.ts`
|
||||
|
||||
Add a `build-desktop` job that depends on `build-bundles`, downloads the matching `bundle-<platform>` artifact, prepares desktop runtime resources, runs the Tauri build on the appropriate OS runner, checks artifact sizes/checksums, and uploads `desktop-<platform>` artifacts.
|
||||
|
||||
The initial matrix should mirror current runtime support:
|
||||
|
||||
- `macos-arm64`
|
||||
- `macos-x64`
|
||||
- `linux-x64`
|
||||
- `linux-arm64`
|
||||
- `windows-x64`
|
||||
|
||||
### GitHub release publishing
|
||||
|
||||
Files:
|
||||
|
||||
- `.github/workflows/release.yml`
|
||||
- `scripts/release/verify-desktop-assets.sh`
|
||||
- `scripts/release/update-homebrew-tap.sh` only if release asset assumptions need to ignore desktop artifacts
|
||||
|
||||
Update `publish-release` to download and publish desktop artifacts alongside the existing `kandev-*.tar.gz` runtime bundles. Keep existing npm and Homebrew publishing tied to runtime tarballs only.
|
||||
|
||||
### Signing
|
||||
|
||||
Files:
|
||||
|
||||
- `.github/workflows/release.yml`
|
||||
- `apps/desktop/src-tauri/tauri.conf.json`
|
||||
- New `docs/desktop-tauri-signing.md`
|
||||
- GitHub Actions release docs/comments in `.github/workflows/release.yml`
|
||||
|
||||
Add signing inputs/secrets behind conditional release steps:
|
||||
|
||||
- macOS: Developer ID Application certificate, Apple team/provider metadata, notarization credentials.
|
||||
- Windows: certificate/key-vault or custom signing command wiring.
|
||||
- Linux: checksum required; GPG/AppImage signing optional.
|
||||
|
||||
Unsigned desktop builds remain allowed for dry runs and internal validation, but public recommended artifacts should require signing success on macOS and Windows.
|
||||
|
||||
---
|
||||
|
||||
## Frontend
|
||||
|
||||
The existing `apps/web` product UI should not need route or state changes. Desktop-specific frontend work is limited to the Tauri startup surface under `apps/desktop`. If implementation discovers that the existing SPA needs to distinguish desktop WebView mode, add the smallest runtime flag necessary and document it in the spec before broadening scope.
|
||||
|
||||
---
|
||||
|
||||
## Tests
|
||||
|
||||
- **What:** backend honors configured host when constructing server addresses.
|
||||
**File:** `apps/backend/internal/backendapp/helpers_test.go` or a new focused test file.
|
||||
**How:** table-driven Go test over host/port config.
|
||||
|
||||
- **What:** launcher/headless env includes desktop host override only when requested.
|
||||
**File:** `apps/backend/internal/launcher/start_test.go` or `run_test.go`.
|
||||
**How:** Go unit test around env/config helpers.
|
||||
|
||||
- **What:** missing runtime resource binaries are detected before desktop launch.
|
||||
**File:** `apps/desktop/src-tauri/src/backend.rs` tests.
|
||||
**How:** Rust unit tests with temporary resource directories.
|
||||
|
||||
- **What:** backend command builder passes `--headless`, `--port`, and loopback env.
|
||||
**File:** `apps/desktop/src-tauri/src/backend.rs` tests.
|
||||
**How:** Rust unit tests over pure command-building helpers.
|
||||
|
||||
- **What:** desktop process environment preserves user env and adds common GUI-missing binary paths.
|
||||
**File:** `apps/desktop/src-tauri/src/backend.rs` tests.
|
||||
**How:** Rust unit tests around environment construction.
|
||||
|
||||
- **What:** desktop startup handles health success, timeout, and child-process exit.
|
||||
**File:** `apps/desktop/src-tauri/src/backend.rs` tests.
|
||||
**How:** Rust tests using a local fake HTTP server or injectable health client.
|
||||
|
||||
- **What:** release workflow requires desktop artifacts and leaves npm/Homebrew runtime publishing unchanged.
|
||||
**File:** `apps/cli/src/release-config.test.ts` or a shell test under `scripts/`.
|
||||
**How:** parse workflow/scripts and assert expected job names, artifacts, and publish filters.
|
||||
|
||||
- **What:** desktop runtime resource preparation validates the existing bundle shape.
|
||||
**File:** script test under `scripts/` or `apps/cli/src/release-config.test.ts`.
|
||||
**How:** create fake bundle directories and assert success/failure paths.
|
||||
|
||||
---
|
||||
|
||||
## E2E Tests
|
||||
|
||||
- **Scenario:** GIVEN a prepared Linux desktop runtime bundle, WHEN the desktop app is launched in CI, THEN the Tauri window loads the Kandev UI without Node.js at runtime.
|
||||
**File:** `apps/desktop/e2e/desktop-launch.spec.ts` or an equivalent Tauri WebDriver test.
|
||||
**What to verify:** startup screen transitions to the Kandev app shell and `/health` succeeds.
|
||||
|
||||
- **Scenario:** GIVEN the backend child fails during startup, WHEN the desktop app is launched, THEN the startup surface shows a failure and no child process remains running.
|
||||
**File:** `apps/desktop/e2e/desktop-launch.spec.ts` or Rust integration test if WebDriver cannot observe process state reliably.
|
||||
**What to verify:** visible error state plus process cleanup.
|
||||
|
||||
- **Scenario:** GIVEN the desktop app is already running, WHEN a second instance is opened, THEN the first window is focused and only one backend launcher process exists.
|
||||
**File:** `apps/desktop/e2e/desktop-single-instance.spec.ts` or Rust integration test.
|
||||
**What to verify:** single-instance behavior and no duplicate backend process.
|
||||
|
||||
Tauri desktop E2E should run on Linux with a fake display in CI first. macOS and Windows desktop smoke tests can be added after the Linux harness is stable.
|
||||
|
||||
---
|
||||
|
||||
## Implementation Waves
|
||||
|
||||
Wave 1:
|
||||
|
||||
- [x] [task-01-backend-desktop-launch-contract](task-01-backend-desktop-launch-contract.md)
|
||||
|
||||
Wave 2:
|
||||
|
||||
- [x] [task-02-tauri-desktop-scaffold](task-02-tauri-desktop-scaffold.md)
|
||||
- [x] [task-03-desktop-runtime-resources](task-03-desktop-runtime-resources.md)
|
||||
|
||||
Wave 3:
|
||||
|
||||
- [x] [task-04-release-desktop-artifacts](task-04-release-desktop-artifacts.md)
|
||||
- [x] [task-05-signing-and-release-trust](task-05-signing-and-release-trust.md)
|
||||
|
||||
Wave 4:
|
||||
|
||||
- [x] [task-06-desktop-e2e-smoke](task-06-desktop-e2e-smoke.md)
|
||||
- [x] [task-07-docs-and-release-notes](task-07-docs-and-release-notes.md)
|
||||
|
||||
---
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Which Windows installer target should be the public default: NSIS `.exe` or MSI? Recommendation: start with the Tauri default/recommended installer for direct GitHub release downloads, then add MSI only if enterprise deployment requires it.
|
||||
- Which Linux artifact set should be public by default: AppImage only, `.deb` plus AppImage, or `.deb`/`.rpm` plus AppImage? Recommendation: start with AppImage plus the package type Tauri produces reliably in CI, then broaden after QA.
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
id: "01-backend-desktop-launch-contract"
|
||||
title: "Backend desktop launch contract"
|
||||
status: done
|
||||
wave: 1
|
||||
depends_on: []
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/desktop-tauri-app/spec.md"
|
||||
---
|
||||
|
||||
# Task 01: Backend Desktop Launch Contract
|
||||
|
||||
## Acceptance
|
||||
|
||||
- The backend honors `server.host` / `KANDEV_SERVER_HOST` when binding the HTTP listener.
|
||||
- Desktop/headless launch can force `127.0.0.1` without changing normal CLI/service defaults.
|
||||
- `kandev --headless --port <port>` remains a stable process contract for a parent desktop app to supervise.
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
rtk bash -lc 'cd apps/backend && go test -tags fts5 ./internal/backendapp ./internal/launcher ./internal/common/config'
|
||||
```
|
||||
|
||||
## Files Likely Touched
|
||||
|
||||
- `apps/backend/internal/common/config/config.go`
|
||||
- `apps/backend/internal/backendapp/main.go`
|
||||
- `apps/backend/internal/backendapp/helpers_test.go`
|
||||
- `apps/backend/internal/launcher/env.go`
|
||||
- `apps/backend/internal/launcher/start.go`
|
||||
- `apps/backend/internal/launcher/start_test.go`
|
||||
- `apps/backend/internal/launcher/run_test.go`
|
||||
|
||||
## Dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec sections: API surface > Desktop launch contract; API surface > Backend bind contract; Failure modes.
|
||||
- Existing patterns: native launcher in `apps/backend/internal/launcher/`, backend HTTP server setup in `apps/backend/internal/backendapp/main.go`.
|
||||
- ADR: `docs/decisions/0026-tauri-desktop-shell.md`.
|
||||
|
||||
## Output Contract
|
||||
|
||||
When complete, update this file's `status` to `done`, update the Wave 1 checkbox in `plan.md`, and report changed files, tests run, blockers, and residual risks.
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
id: "02-tauri-desktop-scaffold"
|
||||
title: "Tauri desktop scaffold"
|
||||
status: done
|
||||
wave: 2
|
||||
depends_on: ["01-backend-desktop-launch-contract"]
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/desktop-tauri-app/spec.md"
|
||||
---
|
||||
|
||||
# Task 02: Tauri Desktop Scaffold
|
||||
|
||||
## Acceptance
|
||||
|
||||
- `apps/desktop` builds as a Tauri v2 desktop package in the pnpm workspace.
|
||||
- The Tauri Rust side starts the native Kandev launcher in headless mode, polls `/health`, and navigates the main window to the backend URL.
|
||||
- The backend process environment preserves inherited variables, forces loopback backend binding, and adds common GUI-missing user binary paths.
|
||||
- Frontend JavaScript is not granted broad shell/filesystem permissions.
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
rtk bash -lc 'cd apps && pnpm --filter @kandev/desktop build'
|
||||
rtk bash -lc 'cd apps/desktop/src-tauri && cargo test'
|
||||
```
|
||||
|
||||
## Files Likely Touched
|
||||
|
||||
- `apps/pnpm-workspace.yaml`
|
||||
- `apps/package.json`
|
||||
- `apps/desktop/package.json`
|
||||
- `apps/desktop/index.html`
|
||||
- `apps/desktop/src/main.ts`
|
||||
- `apps/desktop/src/styles.css`
|
||||
- `apps/desktop/src-tauri/Cargo.toml`
|
||||
- `apps/desktop/src-tauri/build.rs`
|
||||
- `apps/desktop/src-tauri/tauri.conf.json`
|
||||
- `apps/desktop/src-tauri/src/main.rs`
|
||||
- `apps/desktop/src-tauri/src/backend.rs`
|
||||
- `apps/desktop/src-tauri/capabilities/default.json`
|
||||
- `apps/backend/internal/launcher/service.go` only as a reference for existing service PATH conventions
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Task 01.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec sections: What, State machine, Permissions, Failure modes.
|
||||
- Plan sections: Desktop App > Workspace package; Desktop App > Desktop UX.
|
||||
- Existing runtime contract from Task 01.
|
||||
|
||||
## Output Contract
|
||||
|
||||
When complete, update this file's `status` to `done`, update the Wave 2 checkbox in `plan.md`, and report changed files, tests run, blockers, and residual risks.
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
id: "03-desktop-runtime-resources"
|
||||
title: "Desktop runtime resources"
|
||||
status: done
|
||||
wave: 2
|
||||
depends_on: ["01-backend-desktop-launch-contract"]
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/desktop-tauri-app/spec.md"
|
||||
---
|
||||
|
||||
# Task 03: Desktop Runtime Resources
|
||||
|
||||
## Acceptance
|
||||
|
||||
- A release helper extracts the existing platform runtime bundle into the deterministic Tauri resource layout.
|
||||
- The helper validates `kandev`, `agentctl`, and `agentctl-linux-amd64` requirements consistently with the native launcher.
|
||||
- The Tauri app resolves packaged resources without relying on `KANDEV_BUNDLE_DIR` or Node.js at runtime.
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
rtk bash -lc 'scripts/release/prepare-desktop-runtime.sh --help'
|
||||
rtk bash -lc 'cd apps/desktop/src-tauri && cargo test'
|
||||
rtk bash -lc 'cd apps && pnpm --filter @kandev/desktop build'
|
||||
```
|
||||
|
||||
## Files Likely Touched
|
||||
|
||||
- `scripts/release/prepare-desktop-runtime.sh`
|
||||
- `scripts/release/verify-desktop-runtime.sh`
|
||||
- `apps/desktop/src-tauri/tauri.conf.json`
|
||||
- `apps/desktop/src-tauri/src/backend.rs`
|
||||
- `apps/desktop/src-tauri/resources/.gitignore`
|
||||
- `apps/cli/src/release-config.test.ts` or a new script test if script behavior is tested from Node/Vitest
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Task 01.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec sections: API surface > Desktop artifact contract; Failure modes.
|
||||
- Plan sections: Desktop App > Runtime resources.
|
||||
- Existing bundle shape: `apps/cli/README_internal.md` and `scripts/release/package-bundle.sh`.
|
||||
|
||||
## Output Contract
|
||||
|
||||
When complete, update this file's `status` to `done`, update the Wave 2 checkbox in `plan.md`, and report changed files, tests run, blockers, and residual risks.
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
id: "04-release-desktop-artifacts"
|
||||
title: "Release desktop artifacts"
|
||||
status: done
|
||||
wave: 3
|
||||
depends_on: ["02-tauri-desktop-scaffold", "03-desktop-runtime-resources"]
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/desktop-tauri-app/spec.md"
|
||||
---
|
||||
|
||||
# Task 04: Release Desktop Artifacts
|
||||
|
||||
## Acceptance
|
||||
|
||||
- The release workflow builds desktop artifacts for macOS arm64, macOS x64, Linux x64, Linux arm64, and Windows x64.
|
||||
- `publish-release` attaches desktop artifacts and checksums without changing npm/Homebrew runtime publishing behavior.
|
||||
- Release verification fails when a required desktop artifact is missing.
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
rtk bash -lc 'cd apps && pnpm --filter kandev test -- release-config'
|
||||
rtk git diff --check
|
||||
```
|
||||
|
||||
## Files Likely Touched
|
||||
|
||||
- `.github/workflows/release.yml`
|
||||
- `scripts/release/verify-desktop-assets.sh`
|
||||
- `scripts/release/prepare-desktop-runtime.sh`
|
||||
- `apps/cli/src/release-config.test.ts`
|
||||
- `apps/desktop/package.json`
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Task 02.
|
||||
- Task 03.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec sections: API surface > Desktop artifact contract; Scenarios.
|
||||
- Plan sections: Release Pipeline > Build matrix; Release Pipeline > GitHub release publishing.
|
||||
- Existing workflow: `.github/workflows/release.yml`.
|
||||
|
||||
## Output Contract
|
||||
|
||||
When complete, update this file's `status` to `done`, update the Wave 3 checkbox in `plan.md`, and report changed files, tests run, blockers, and residual risks.
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
id: "05-signing-and-release-trust"
|
||||
title: "Signing and release trust"
|
||||
status: done
|
||||
wave: 3
|
||||
depends_on: ["04-release-desktop-artifacts"]
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/desktop-tauri-app/spec.md"
|
||||
---
|
||||
|
||||
# Task 05: Signing and Release Trust
|
||||
|
||||
## Acceptance
|
||||
|
||||
- macOS desktop release builds support Developer ID signing and notarization through GitHub Actions secrets.
|
||||
- Windows desktop release builds support code signing through the selected signing mechanism.
|
||||
- Unsigned desktop artifacts are clearly limited to dry runs/internal validation and are not treated as trusted public artifacts.
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
rtk bash -lc 'cd apps && pnpm --filter kandev test -- release-config'
|
||||
rtk git diff --check
|
||||
```
|
||||
|
||||
Manual verification for maintainers:
|
||||
|
||||
```bash
|
||||
rtk gh workflow run release.yml -f dry_run=true -f bump=patch
|
||||
```
|
||||
|
||||
## Files Likely Touched
|
||||
|
||||
- `.github/workflows/release.yml`
|
||||
- `apps/desktop/src-tauri/tauri.conf.json`
|
||||
- `docs/desktop-tauri-signing.md`
|
||||
- `apps/cli/src/release-config.test.ts`
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Task 04.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec sections: What; Permissions; Failure modes; Scenarios.
|
||||
- Plan sections: Release Pipeline > Signing.
|
||||
- Tauri signing docs for macOS, Windows, Linux, and updater signing constraints.
|
||||
|
||||
## Output Contract
|
||||
|
||||
When complete, update this file's `status` to `done`, update the Wave 3 checkbox in `plan.md`, and report changed files, tests run, blockers, and residual risks.
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
id: "06-desktop-e2e-smoke"
|
||||
title: "Desktop E2E smoke"
|
||||
status: done
|
||||
wave: 4
|
||||
depends_on: ["02-tauri-desktop-scaffold", "03-desktop-runtime-resources"]
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/desktop-tauri-app/spec.md"
|
||||
---
|
||||
|
||||
# Task 06: Desktop E2E Smoke
|
||||
|
||||
## Acceptance
|
||||
|
||||
- CI has at least one Linux desktop smoke test that launches the Tauri app with a prepared runtime bundle.
|
||||
- The smoke test verifies the startup screen transitions to the Kandev UI after backend health succeeds.
|
||||
- A failure-path test or Rust integration test verifies child process cleanup on startup failure.
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
rtk bash -lc 'cd apps && pnpm --filter @kandev/desktop e2e'
|
||||
rtk bash -lc 'cd apps/desktop/src-tauri && cargo test'
|
||||
```
|
||||
|
||||
## Files Likely Touched
|
||||
|
||||
- `apps/desktop/e2e/desktop-launch.spec.ts`
|
||||
- `apps/desktop/e2e/desktop-single-instance.spec.ts`
|
||||
- `apps/desktop/e2e/README.md`
|
||||
- `apps/desktop/package.json`
|
||||
- `apps/desktop/src-tauri/src/backend.rs`
|
||||
- `.github/workflows/release.yml` or a dedicated desktop test workflow
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Task 02.
|
||||
- Task 03.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec sections: State machine; Failure modes; Scenarios.
|
||||
- Plan sections: E2E Tests.
|
||||
- Existing web E2E patterns in `apps/web/e2e/README.md`; Tauri WebDriver guidance for desktop smoke coverage.
|
||||
|
||||
## Output Contract
|
||||
|
||||
When complete, update this file's `status` to `done`, update the Wave 4 checkbox in `plan.md`, and report changed files, tests run, blockers, and residual risks.
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
id: "07-docs-and-release-notes"
|
||||
title: "Docs and release notes"
|
||||
status: done
|
||||
wave: 4
|
||||
depends_on: ["04-release-desktop-artifacts", "05-signing-and-release-trust", "06-desktop-e2e-smoke"]
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/desktop-tauri-app/spec.md"
|
||||
---
|
||||
|
||||
# Task 07: Docs and Release Notes
|
||||
|
||||
## Acceptance
|
||||
|
||||
- User docs explain desktop install artifacts, runtime requirements, update expectations, and signing/trust status.
|
||||
- User docs explain GUI-launch environment differences and what to do when an agent CLI is not discoverable from the desktop app.
|
||||
- Engineering docs mention the `apps/desktop` package and release workflow ownership.
|
||||
- The spec status and plan task statuses are reconciled with the implementation state.
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
rtk git diff --check
|
||||
rtk bash -lc 'cd apps && pnpm format:check'
|
||||
```
|
||||
|
||||
## Files Likely Touched
|
||||
|
||||
- `docs/specs/desktop-tauri-app/spec.md`
|
||||
- `docs/plans/desktop-tauri-app/plan.md`
|
||||
- `docs/desktop-tauri-signing.md`
|
||||
- `docs/cli.md`
|
||||
- `docs/features.md`
|
||||
- `docs/remote-cloud-environment.md` if desktop build dependencies affect cloud dev setup
|
||||
- `AGENTS.md`
|
||||
- `apps/desktop/AGENTS.md`
|
||||
- `apps/cli/README_internal.md`
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Task 04.
|
||||
- Task 05.
|
||||
- Task 06.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec sections: What; Out of scope.
|
||||
- Plan sections: Release Pipeline; E2E Tests.
|
||||
- Root `AGENTS.md` maintenance rule for changed package layout/release conventions.
|
||||
|
||||
## Output Contract
|
||||
|
||||
When complete, update this file's `status` to `done`, update the Wave 4 checkbox in `plan.md`, and report changed files, tests run, blockers, and residual risks.
|
||||
@@ -111,6 +111,7 @@ System pages (Radarr/Sonarr-style) for status, disk usage, database maintenance,
|
||||
| [improve-kandev](improve-kandev/spec.md) | draft |
|
||||
| [homebrew-core](homebrew-core/spec.md) | draft |
|
||||
| [native-kandev-cli](native-kandev-cli/spec.md) | draft |
|
||||
| [desktop-tauri-app](desktop-tauri-app/spec.md) | shipped |
|
||||
| [public-share-links](public-share-links/spec.md) | draft |
|
||||
| [ssh-executor](ssh-executor/spec.md) | draft |
|
||||
| [cli-mode-parity](cli-mode-parity/spec.md) | draft |
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
---
|
||||
status: implemented
|
||||
created: 2026-06-23
|
||||
owner: tbd
|
||||
---
|
||||
|
||||
# Tauri Desktop App
|
||||
|
||||
## Why
|
||||
|
||||
Users who prefer a desktop workflow should be able to install and open Kandev from the OS app launcher without running a terminal command or managing a browser tab. The installed desktop app should keep Kandev's current local-first behavior while avoiding a production Node.js runtime.
|
||||
|
||||
## What
|
||||
|
||||
- Kandev provides desktop installers for the same primary release platforms as the native runtime bundle: macOS arm64, macOS x64, Linux x64, Linux arm64, and Windows x64.
|
||||
- Opening the desktop app starts a local Kandev backend and displays the existing Vite/React Kandev UI inside a native Tauri WebView window.
|
||||
- The installed desktop app does not require Node.js. Node.js and pnpm remain build-time tooling in CI and local development only.
|
||||
- The desktop app reuses the existing Go-served SPA with embedded Vite assets. It does not ship or start a separate web server.
|
||||
- The desktop app reuses the existing Kandev data directory, SQLite database, worktrees, executor settings, integrations, and agent configuration.
|
||||
- The desktop app owns the backend lifecycle for the process it starts: startup waits for `/health`, normal quit terminates child processes, and startup failure surfaces an error instead of leaving orphaned backend processes.
|
||||
- The desktop app starts the backend on a loopback-only address and an available local port unless the user has explicitly configured otherwise through existing environment/config mechanisms.
|
||||
- The desktop app launches the backend with a predictable process environment for GUI launches, including common user binary locations, so configured agent CLIs can be discovered as reliably as they are from terminal-launched Kandev.
|
||||
- Opening a second desktop instance focuses the existing app window or exits without starting a second backend for the same desktop launch context.
|
||||
- GitHub releases include desktop artifacts alongside the existing runtime tarballs and checksums.
|
||||
- Unsigned desktop artifacts may be produced for development or internal validation, but public recommended desktop releases require macOS Developer ID signing/notarization and Windows code signing before they are presented as trusted user-facing downloads.
|
||||
- Desktop release notes and install docs tell users which artifact to download for each operating system and call out any unsigned/pre-release limitations.
|
||||
|
||||
## Data model
|
||||
|
||||
The feature does not add backend database tables.
|
||||
|
||||
Desktop runtime state is process-local except for optional window placement/state stored by Tauri under the OS application data location. Kandev user data remains owned by the existing backend persistence model under `KANDEV_HOME_DIR` or the default `~/.kandev` location.
|
||||
|
||||
## API surface
|
||||
|
||||
### Desktop launch contract
|
||||
|
||||
The Tauri shell starts the packaged native Kandev launcher in headless mode with an explicit backend port:
|
||||
|
||||
```text
|
||||
kandev --headless --port <available-loopback-port>
|
||||
```
|
||||
|
||||
The launcher starts the backend through the existing hidden backend mode and keeps the supervisor process alive until the desktop app exits. The desktop shell polls:
|
||||
|
||||
```text
|
||||
GET http://127.0.0.1:<port>/health
|
||||
```
|
||||
|
||||
Desktop launches pass a per-launch `KANDEV_DESKTOP_HEALTH_TOKEN` to the native launcher
|
||||
environment. The backend echoes the token in the `X-Kandev-Desktop-Health-Token` response
|
||||
header on successful `/health` responses. The desktop shell treats `/health` as ready only
|
||||
when the status is successful and the response header matches its generated token, so a
|
||||
separate local process on the same loopback port cannot satisfy desktop readiness.
|
||||
|
||||
When `/health` reports ready for that launch, the desktop window navigates to:
|
||||
|
||||
```text
|
||||
http://127.0.0.1:<port>/
|
||||
```
|
||||
|
||||
### Backend bind contract
|
||||
|
||||
Desktop launches set the backend host to loopback:
|
||||
|
||||
```text
|
||||
KANDEV_SERVER_HOST=127.0.0.1
|
||||
```
|
||||
|
||||
The backend server honors `server.host` / `KANDEV_SERVER_HOST` when binding its listener. Existing CLI and service launches may keep their current default unless explicitly changed by their own specs.
|
||||
|
||||
### Desktop environment contract
|
||||
|
||||
The desktop shell passes an explicit environment to the native launcher:
|
||||
|
||||
- Existing user environment variables are preserved when available.
|
||||
- `KANDEV_SERVER_HOST=127.0.0.1` is set for desktop launches.
|
||||
- `PATH` includes common GUI-missing user binary locations such as `/usr/local/bin`, `/opt/homebrew/bin`, `/usr/bin`, `/bin`, `%USERPROFILE%/.local/bin`, and existing Kandev agent CLI install locations where applicable.
|
||||
- Explicit agent command paths configured in Kandev settings remain authoritative over `PATH` lookup.
|
||||
|
||||
### Desktop artifact contract
|
||||
|
||||
Each released version includes platform desktop artifacts with checksums. Exact file names may follow Tauri's generated naming, but the release must expose these platform groups:
|
||||
|
||||
- macOS arm64: signed/notarized `.dmg` for public release, unsigned `.dmg` allowed only for internal validation.
|
||||
- macOS x64: signed/notarized `.dmg` for public release, unsigned `.dmg` allowed only for internal validation.
|
||||
- Windows x64: signed installer (`.exe` or `.msi`) for public release, unsigned installer allowed only for internal validation.
|
||||
- Linux x64: AppImage and/or distro package generated by Tauri, with checksum.
|
||||
- Linux arm64: AppImage and/or distro package generated by Tauri, with checksum.
|
||||
|
||||
### Existing backend API
|
||||
|
||||
The desktop app uses the existing backend HTTP, WebSocket, and boot-payload contracts. No new product API is required for the main Kandev UI.
|
||||
|
||||
## State machine
|
||||
|
||||
Desktop app lifecycle:
|
||||
|
||||
- `idle`: the app process has started but no backend child is running.
|
||||
- `backend-starting`: the app has spawned the native launcher and is polling backend health.
|
||||
- `ready`: the backend is healthy and the WebView is displaying the Kandev UI.
|
||||
- `backend-restarting`: the launcher supervisor is replacing the backend child after an existing restart request.
|
||||
- `stopping`: the user quit the app or the app is terminating its child processes.
|
||||
- `failed`: startup failed before the UI became ready.
|
||||
|
||||
Transitions:
|
||||
|
||||
- `idle` -> `backend-starting`: user opens the desktop app.
|
||||
- `backend-starting` -> `ready`: `/health` returns success and the WebView navigates to the backend URL.
|
||||
- `backend-starting` -> `failed`: the launcher exits, a required bundled binary is missing, the backend cannot bind, or health times out.
|
||||
- `ready` -> `backend-restarting`: the existing backend restart supervisor handles a restart request.
|
||||
- `backend-restarting` -> `ready`: the replacement backend becomes healthy on the same launch URL.
|
||||
- any active state -> `stopping`: the user quits the app or the OS terminates the app.
|
||||
- `stopping` -> `idle`: child processes are terminated and the app exits.
|
||||
|
||||
## Permissions
|
||||
|
||||
- The desktop app runs with the current OS user's permissions and does not require administrator/root privileges for normal install or launch.
|
||||
- Backend filesystem, Docker, SSH, Git, and credential access remains governed by existing Kandev backend and executor behavior.
|
||||
- The WebView does not receive broad shell/filesystem permissions. Process spawning for the backend is owned by the Tauri Rust side, not by arbitrary frontend code.
|
||||
- Signing credentials are CI secrets. They are never committed to the repository or exposed to the desktop app runtime.
|
||||
|
||||
## Failure modes
|
||||
|
||||
- Missing packaged `kandev`, `agentctl`, or required helper binaries cause startup to fail with a visible desktop error that names the missing artifact.
|
||||
- If the selected backend port is unavailable, the desktop app chooses a different available port before launch. If no port can be selected, startup fails visibly.
|
||||
- If the backend exits before `/health` succeeds, the desktop app shows a startup failure and includes the captured launcher/backend output when available.
|
||||
- If `/health` does not succeed before the configured timeout, the desktop app terminates the launched child process tree and shows a timeout error.
|
||||
- If the WebView runtime is unavailable or broken on the host OS, the app fails using the platform's normal Tauri/WebView error behavior; the backend process must not remain running.
|
||||
- If an agent CLI cannot be found from a GUI-launched environment, the desktop app/backend surfaces the same setup-health guidance as browser/CLI Kandev rather than failing silently.
|
||||
- If signing/notarization secrets are absent in CI, release automation may still build explicitly unsigned internal artifacts, but public trusted desktop artifacts are not marked complete.
|
||||
|
||||
## Persistence guarantees
|
||||
|
||||
- Kandev data created through the desktop app survives app quit and process restart using the same persistence guarantees as CLI-launched Kandev.
|
||||
- In-flight backend process state does not survive app quit. On next launch, the desktop app starts a fresh backend process, and backend recovery follows existing Kandev recovery behavior.
|
||||
- Optional window size/position persistence survives app restart if the Tauri window-state plugin is enabled.
|
||||
- Desktop installer artifacts do not alter existing npm/Homebrew/manual runtime update semantics.
|
||||
|
||||
## Scenarios
|
||||
|
||||
- **GIVEN** Kandev is installed as a desktop app on a machine without Node.js, **WHEN** the user opens the app, **THEN** the backend starts and the Kandev UI appears in the desktop window.
|
||||
- **GIVEN** the desktop app is already running, **WHEN** the user opens the app again, **THEN** the existing window is focused and no second backend is started for that desktop app instance.
|
||||
- **GIVEN** the backend has not finished startup, **WHEN** the desktop app is open, **THEN** the user sees a startup/loading state until `/health` succeeds or startup fails.
|
||||
- **GIVEN** the backend becomes healthy, **WHEN** the desktop app navigates to the backend URL, **THEN** the existing Kandev boot payload hydrates the UI without a separate Node.js web runtime.
|
||||
- **GIVEN** an agent CLI is installed in a common user binary location but the desktop app was opened from the OS launcher, **WHEN** the user starts a session using that agent, **THEN** Kandev can discover the agent command or surfaces existing setup-health guidance.
|
||||
- **GIVEN** the user quits the desktop app, **WHEN** the app exits normally, **THEN** the launcher/backend child process tree is terminated.
|
||||
- **GIVEN** a bundled backend binary is missing, **WHEN** the user opens the desktop app, **THEN** startup fails with a visible error naming the missing binary.
|
||||
- **GIVEN** the release workflow builds desktop artifacts for a version, **WHEN** the GitHub release is published, **THEN** desktop installers and checksums are attached alongside the existing runtime tarballs.
|
||||
- **GIVEN** a public macOS desktop release, **WHEN** the user downloads and opens the `.dmg`, **THEN** the app is signed and notarized so macOS does not report the download as damaged or from an unidentified developer.
|
||||
- **GIVEN** a public Windows desktop release, **WHEN** the user runs the installer, **THEN** the installer is code signed to reduce SmartScreen trust warnings.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Replacing the existing npm, Homebrew, Docker, or runtime tarball channels.
|
||||
- Requiring `npx` or npm installs to be Node-free.
|
||||
- Mobile Tauri targets.
|
||||
- App Store, Microsoft Store, Snapcraft, AUR, or Homebrew Cask distribution.
|
||||
- In-app Tauri updater support in the first desktop release.
|
||||
- Running Kandev as a background tray app after all windows close.
|
||||
- Rewriting the Kandev frontend or backend in Rust.
|
||||
|
||||
## Implementation plan
|
||||
|
||||
- [Desktop Tauri App plan](../../plans/desktop-tauri-app/plan.md)
|
||||
- [ADR-0026: Tauri desktop shell over native runtime](../../decisions/0026-tauri-desktop-shell.md)
|
||||
Reference in New Issue
Block a user