Skip to content

Commit 71d1e82

Browse files
committed
feat: persist workspace state and refine onboarding
1 parent df02649 commit 71d1e82

30 files changed

Lines changed: 2368 additions & 1120 deletions

docs/PRD.en.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ The implementation baseline comes primarily from:
2323

2424
Coder Studio is a Tauri-based desktop workbench that brings the following tasks into one operational surface:
2525

26-
- connecting local or remote Git repositories
26+
- connecting local Git workspaces
2727
- starting and managing Claude agent sessions
2828
- splitting parallel agent workstreams
2929
- browsing, editing, and saving code files
@@ -45,20 +45,21 @@ The current product position is:
4545
## 4. Supported Environment
4646

4747
- runtime: desktop app built with Tauri
48-
- workspace sources: `Remote Git` and `Local Folder`
48+
- current workspace source: `Local Folder`
49+
- remote Git: backend plumbing still exists, but the creation entry is hidden in the current release and deferred to the next phase
4950
- execution targets: `Native`, plus `WSL` when available
5051
- agent provider: currently `Claude` only
5152
- languages: Chinese and English
5253
- theme: dark-only in the current build
53-
- storage: local-first, with frontend state in Local Storage and backend session/archive persistence in a local database
54+
- storage: local-first, with workspace/session/layout/view persistence in backend SQLite and app settings plus language preference in browser local storage
5455

5556
## 5. Current Product Scope
5657

5758
### 5.1 Workspace Onboarding
5859

5960
- The app starts with a workspace launch overlay.
60-
- Users can choose `Remote Git` or `Local Folder`.
61-
- In remote mode, the app clones a repository URL into a temporary working directory inside the selected execution target.
61+
- The current release only exposes `Local Folder` for workspace creation.
62+
- The remote Git clone path still exists in backend code, but the UI entry is intentionally hidden and should not be described as a shipped feature.
6263
- In local mode, the app uses a backend-backed directory browser that supports:
6364
- current path display
6465
- Home
@@ -204,12 +205,10 @@ The current product position is:
204205

205206
### 5.10 Local Persistence
206207

207-
- Workbench state is stored in Local Storage.
208-
- Persisted frontend data includes:
209-
- workspace and layout state
210-
- app settings
211-
- selected language
212-
- The backend persists session and archive snapshots into a local database.
208+
- Workbench state is no longer stored in Local Storage.
209+
- Persisted data now includes:
210+
- backend SQLite: workspaces, sessions, archives, workbench layout, and per-workspace view state
211+
- browser local storage: app settings and selected language
213212
- Closing a non-draft pane archives the related backend session.
214213
- The UI can already render a read-only archive session view, but archive browsing is not yet exposed as a complete user-facing center.
215214

@@ -219,9 +218,9 @@ The current product position is:
219218

220219
1. Open the app.
221220
2. Enter the workspace launch overlay.
222-
3. Choose `Remote Git` or `Local Folder`.
223-
4. Choose `Native` or `WSL`.
224-
5. Enter a Git URL or pick a local directory.
221+
3. Choose `Native` or `WSL`.
222+
4. Pick a local directory in the built-in directory browser.
223+
5. Let the app resolve and attach the matching Git repository root.
225224
6. After launch, the main workspace loads repository data, file tree, and Git information.
226225

227226
### 6.2 Start the First Agent Task
@@ -275,19 +274,20 @@ The following should not be presented as current shipped user-facing functionali
275274
- a complete auto-suspend execution loop
276275
- user-facing session mode switching between `branch` and `git_tree`
277276
- MCP settings UI or advanced Claude configuration screens
277+
- a user-visible remote Git workspace creation entry
278278

279279
## 8. Current Constraints
280280

281281
- Local folder onboarding depends on resolving a Git repository root rather than accepting arbitrary folders.
282-
- Remote repositories are cloned into temporary directories whose location depends on the execution target.
282+
- Remote Git still has backend plumbing, but the current release hides the entry point, so it must not be documented as a supported user flow.
283283
- WSL support depends on `wsl.exe` and target-specific path resolution.
284284
- The configured Claude launch command must exist in the selected runtime environment.
285285
- Queue, archive, and worktree capabilities currently show a “backend first, UI surface incomplete” shape, so documentation must describe only what users can actually do in the interface.
286286

287287
## 9. Acceptance Criteria
288288

289289
1. The app must show the workspace launch overlay on first entry or when creating a new workspace.
290-
2. Users must be able to start a workspace from either `Remote Git` or `Local Folder`.
290+
2. Users must currently be able to start a workspace only through `Local Folder`, and the creation flow must not expose a remote Git option.
291291
3. In supported environments, users must be able to choose `Native` or `WSL` execution.
292292
4. Once a workspace loads, the main agent area must be visible and non-started panes must show the draft input field.
293293
5. Submitting the first draft input must materialize a session, start the agent, generate the title, and switch the pane to interactive terminal mode.

docs/PRD.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
Coder Studio 是一个基于 Tauri 的桌面端本地工作台,用来把以下工作集中到一个操作面中:
2525

26-
- 连接本地或远程 Git 仓库
26+
- 连接本地 Git 工作区
2727
- 启动并管理 Claude Agent 会话
2828
- 并行拆分多个 Agent 工作流
2929
- 查看、编辑和保存代码文件
@@ -45,20 +45,21 @@ Coder Studio 是一个基于 Tauri 的桌面端本地工作台,用来把以下
4545
## 4. 当前支持范围 / Supported Environment
4646

4747
- 运行形态:桌面应用(Tauri)
48-
- 工作区来源:`Remote Git``Local Folder`
48+
- 当前工作区来源:`Local Folder`
49+
- 远程 Git:后端能力保留,但当前版本已隐藏创建入口,计划下一期开放
4950
- 执行目标:`Native`;在环境允许时支持 `WSL`
5051
- Agent 提供方:当前仅支持 `Claude`
5152
- 语言:中文、English
5253
- 主题:当前仅保留深色主题
53-
- 数据存储:本地存储为主,前端状态保存在 Local Storage,后端会话/归档支持本地持久化
54+
- 数据存储:本地优先;工作区、会话、布局与视图状态持久化到后端 SQLite,应用设置和语言偏好保存在浏览器本地存储
5455

5556
## 5. 当前产品范围 / Current Product Scope
5657

5758
### 5.1 工作区创建与接入 / Workspace Onboarding
5859

5960
- 应用启动后默认进入工作区启动浮层。
60-
- 用户可以选择 `Remote Git``Local Folder` 两种接入方式
61-
- 远程仓库模式下,输入 Git URL 后,应用会在目标运行时环境中克隆仓库到临时目录
61+
- 当前版本只开放 `Local Folder` 方式创建工作区
62+
- 远程 Git 克隆链路在后端仍有实现痕迹,但当前 UI 已隐藏,不应视为正式上线能力
6263
- 本地目录模式下,应用提供服务端目录浏览器,支持:
6364
- 查看当前浏览路径
6465
- 回到 Home
@@ -206,12 +207,10 @@ Coder Studio 是一个基于 Tauri 的桌面端本地工作台,用来把以下
206207

207208
### 5.10 本地持久化 / Local Persistence
208209

209-
- 工作台状态会保存在 Local Storage。
210+
- 工作区、会话、布局状态不再保存在 Local Storage。
210211
- 当前持久化内容包括:
211-
- 工作区与布局状态
212-
- 设置项
213-
- 语言选择
214-
- 后端支持把 Session 和 Archive 快照写入本地数据库。
212+
- 后端 SQLite:工作区、Session、Archive、工作台布局、Workspace 视图状态
213+
- 浏览器本地存储:设置项、语言选择
215214
- 关闭非草稿 Pane 时,会把对应 Session 归档到后端归档数据中。
216215
- 当前已有只读 Archive 视图渲染能力,但归档浏览入口还不是完整正式界面的一部分。
217216

@@ -221,9 +220,9 @@ Coder Studio 是一个基于 Tauri 的桌面端本地工作台,用来把以下
221220

222221
1. 用户打开应用。
223222
2. 进入工作区启动浮层。
224-
3. 选择 `Remote Git``Local Folder`
225-
4. 选择 `Native``WSL` 目标
226-
5. 输入 Git URL 或选择本地目录
223+
3. 选择 `Native``WSL` 目标
224+
4. 通过目录浏览器选择本地目录
225+
5. 应用解析并接入对应 Git 仓库根目录
227226
6. 启动工作区后,主界面加载仓库、文件树、Git 信息。
228227

229228
### 6.2 启动第一个 Agent 任务
@@ -277,19 +276,20 @@ Coder Studio 是一个基于 Tauri 的桌面端本地工作台,用来把以下
277276
- 完整闭环的 Idle Auto-Suspend 执行逻辑
278277
- 用户可操作的 Session Mode 切换(`branch` / `git_tree`
279278
- MCP 设置页或 Claude 高级配置面板
279+
- 用户可见的远程 Git 工作区创建入口
280280

281281
## 8. 当前已知约束 / Current Constraints
282282

283283
- 本地目录接入依赖 Git 仓库解析,不是任意目录浏览器。
284-
- 远程仓库克隆到临时目录,目录位置会随运行目标变化
284+
- 远程 Git 虽然存在后端链路,但当前版本已隐藏入口,因此不能作为正式可用流程写入面向用户的说明
285285
- WSL 能力依赖宿主机存在 `wsl.exe`,且部分路径解析需根据 distro 环境决定。
286286
- Claude 命令必须在当前执行目标环境中可执行。
287287
- 当前归档、队列、worktree 等能力存在“底层能力先行、主界面入口不足”的状态,文档表述必须以用户实际能完成的操作为准。
288288

289289
## 9. 验收标准 / Acceptance Criteria
290290

291291
1. 应用首次进入或新增工作区时,必须显示工作区启动浮层。
292-
2. 用户必须可以通过 `Remote Git``Local Folder` 两种方式启动工作区
292+
2. 用户当前必须只能通过 `Local Folder` 方式启动工作区,创建入口中不应显示远程 Git 选项
293293
3. 在支持 WSL 的环境中,用户必须可以选择 `Native``WSL` 作为执行目标。
294294
4. 工作区进入主界面后,必须可以看到 Agent 主区域,并且未启动 Agent 的 Pane 显示草稿输入框。
295295
5. 用户在草稿输入框提交首条内容后,必须触发 Session 物化、Agent 启动、标题生成,并切换为交互式终端。

src-tauri/src/app.rs

Lines changed: 5 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@ use tokio::sync::broadcast;
1111

1212
use crate::{
1313
auth::{ip_guard::IpGuardMap, AuthRuntime},
14-
infra::time::{default_idle_policy, now_ts},
15-
models::{
16-
ArchiveEntry, ExecTarget, IdlePolicy, SessionInfo, SessionMode, SessionStatus,
17-
TerminalInfo, TransportEvent,
18-
},
14+
models::TransportEvent,
1915
};
2016

2117
#[derive(Clone)]
@@ -35,28 +31,13 @@ pub(crate) struct TerminalRuntime {
3531
pub master: Mutex<Box<dyn MasterPty + Send>>,
3632
}
3733

38-
#[derive(Clone, serde::Serialize, serde::Deserialize, Debug)]
39-
pub(crate) struct TabState {
40-
pub tab_id: String,
41-
pub project_path: String,
42-
pub target: ExecTarget,
43-
pub idle_policy: IdlePolicy,
44-
pub sessions: Vec<SessionInfo>,
45-
pub active_session_id: u64,
46-
pub archive: Vec<ArchiveEntry>,
47-
pub terminals: Vec<TerminalInfo>,
48-
pub next_session_id: u64,
49-
pub next_task_id: u64,
50-
pub next_terminal_id: u64,
51-
}
52-
5334
pub(crate) struct AppState {
54-
pub tabs: Mutex<HashMap<String, TabState>>,
5535
pub db: Mutex<Option<Connection>>,
5636
pub auth: Mutex<AuthRuntime>,
5737
pub agents: Mutex<HashMap<String, Arc<AgentRuntime>>>,
58-
pub ip_guard: Mutex<IpGuardMap>,
5938
pub terminals: Mutex<HashMap<String, Arc<TerminalRuntime>>>,
39+
pub next_terminal_id: Mutex<u64>,
40+
pub ip_guard: Mutex<IpGuardMap>,
6041
pub hook_endpoint: Mutex<Option<String>>,
6142
pub http_endpoint: Mutex<Option<String>>,
6243
pub transport_events: broadcast::Sender<TransportEvent>,
@@ -66,12 +47,12 @@ impl Default for AppState {
6647
fn default() -> Self {
6748
let (transport_events, _) = broadcast::channel(1024);
6849
Self {
69-
tabs: Mutex::new(HashMap::new()),
7050
db: Mutex::new(None),
7151
auth: Mutex::new(AuthRuntime::default()),
7252
agents: Mutex::new(HashMap::new()),
73-
ip_guard: Mutex::new(HashMap::new()),
7453
terminals: Mutex::new(HashMap::new()),
54+
next_terminal_id: Mutex::new(1),
55+
ip_guard: Mutex::new(HashMap::new()),
7556
hook_endpoint: Mutex::new(None),
7657
http_endpoint: Mutex::new(None),
7758
transport_events,
@@ -81,27 +62,3 @@ impl Default for AppState {
8162

8263
pub(crate) const DEV_FRONTEND_URL: &str = "http://127.0.0.1:5174";
8364
pub(crate) const DEV_BACKEND_PORT: u16 = 41033;
84-
85-
pub(crate) fn bootstrap_tab_state(tab_id: &str, target: &ExecTarget) -> TabState {
86-
TabState {
87-
tab_id: tab_id.to_string(),
88-
project_path: String::new(),
89-
target: target.clone(),
90-
idle_policy: default_idle_policy(),
91-
sessions: vec![SessionInfo {
92-
id: 1,
93-
status: SessionStatus::Idle,
94-
mode: SessionMode::Branch,
95-
auto_feed: true,
96-
queue: vec![],
97-
last_active_at: now_ts(),
98-
claude_session_id: None,
99-
}],
100-
active_session_id: 1,
101-
archive: vec![],
102-
terminals: vec![],
103-
next_session_id: 2,
104-
next_task_id: 1,
105-
next_terminal_id: 1,
106-
}
107-
}

0 commit comments

Comments
 (0)