Skip to content

Commit 437c798

Browse files
authored
Merge pull request #3840 from GCWing/gcwing/session-workspace-improvements
Improve session history and workspace navigation
2 parents be56bf7 + 5e973e1 commit 437c798

64 files changed

Lines changed: 1232 additions & 181 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎docs/interactive-capabilities/README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ OpenBitFun Playbook currently contains **22 features**, **22 settings pages**, a
2727
- Generated per-item interaction audit: `docs/interactive-capabilities/technical/product-control-open-audit.json`
2828
- Generated low-level audit map: `docs/interactive-capabilities/technical/tauri-command-map.json`
2929

30-
说明书、网站、搜索和智能体只看“功能 + 设置 + 子能力”。每项子能力都必须引用已注册 Tauri Command 或可解析的源码标记;这些证据不会进入公开目录。当前 **705** 个 Tauri 命令只用于实现覆盖审计。产品 UI 交互源码会在生成和检查时扫描并校验,但不会保存成随普通 UI 改动频繁变化的版本化快照。
30+
说明书、网站、搜索和智能体只看“功能 + 设置 + 子能力”。每项子能力都必须引用已注册 Tauri Command 或可解析的源码标记;这些证据不会进入公开目录。当前 **706** 个 Tauri 命令只用于实现覆盖审计。产品 UI 交互源码会在生成和检查时扫描并校验,但不会保存成随普通 UI 改动频繁变化的版本化快照。
3131

32-
Docs, website, search, and agents see only features, settings, and documented sub-capabilities. Every sub-capability must reference a registered Tauri command or a resolvable source marker; evidence is stripped from public projections. The **705** Tauri commands remain implementation-audit evidence only. Product UI interaction sources are scanned and validated during generation and checks, but are not stored as a versioned snapshot that churns with ordinary UI changes.
32+
Docs, website, search, and agents see only features, settings, and documented sub-capabilities. Every sub-capability must reference a registered Tauri command or a resolvable source marker; evidence is stripped from public projections. The **706** Tauri commands remain implementation-audit evidence only. Product UI interaction sources are scanned and validated during generation and checks, but are not stored as a versioned snapshot that churns with ordinary UI changes.
3333

3434
## 控制边界 / Control boundary
3535

‎docs/interactive-capabilities/technical/tauri-command-map.json‎

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
"schemaVersion": 2,
33
"generatedFrom": "src/shared/interactive-capabilities/catalog.json",
44
"catalogDigest": "8a02be2b328791ebb823e4b7a956bf0371c523caa7f881a6c778cbaa42d72575",
5-
"commandCount": 705,
5+
"commandCount": 706,
66
"coverage": {
7-
"commandCount": 705,
8-
"documentedCommandCount": 644,
7+
"commandCount": 706,
8+
"documentedCommandCount": 645,
99
"implementationCommandCount": 61,
1010
"implementationDigest": "fdb6f78b009b95270d26834349aade36e0987553167f325a9c674a085b876a2d"
1111
},
@@ -4806,6 +4806,22 @@
48064806
"signature": "fn git_get_status( state: State<'_, AppState>, mut request: GitRepositoryRequest, ) -> Result<GitStatus, String>",
48074807
"remoteWorkspacePolicy": "RemoteRouted"
48084808
},
4809+
{
4810+
"id": "git_get_tracked_change_count",
4811+
"moduleId": "git",
4812+
"capabilityId": "feature.git",
4813+
"capabilityIds": [
4814+
"feature.git"
4815+
],
4816+
"documentedItemIds": [
4817+
"feature.git:status-diff"
4818+
],
4819+
"visibility": "documented",
4820+
"rustPath": "git_get_tracked_change_count",
4821+
"sourceFile": "src/apps/desktop/src/api/git_api.rs",
4822+
"signature": "fn git_get_tracked_change_count( state: State<'_, AppState>, request: GitTrackedChangeCountRequest, ) -> Result<Option<usize>, String>",
4823+
"remoteWorkspacePolicy": "RemoteRouted"
4824+
},
48094825
{
48104826
"id": "git_is_repository",
48114827
"moduleId": "git",

‎src/apps/cli/src/peer_host/commands/git.rs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ fn resolved_repository_path(
5050
/// repository so an SSH workspace can never fall back to a same-named local path.
5151
pub(crate) async fn read(command: &str, args: &Value) -> Result<Value, String> {
5252
let request = request_value(args);
53+
if command == "git_get_tracked_change_count"
54+
&& optional_string(request, "workspaceId").is_none()
55+
{
56+
return Err("Workspace ID is required".into());
57+
}
5358
let path = repository_path_for_workspace(request).await?;
5459
read_at_path(command, &path, request).await
5560
}
@@ -80,6 +85,9 @@ async fn read_at_path(command: &str, path: &str, request: &Value) -> Result<Valu
8085
git_result(command, GitService::get_repository_basic(path).await)
8186
}
8287
"git_get_status" => git_result(command, GitService::get_status(path).await),
88+
"git_get_tracked_change_count" => {
89+
git_result(command, GitService::get_tracked_change_count(path).await)
90+
}
8391
"git_get_branches" | "git_get_enhanced_branches" => {
8492
let options: BranchOptions = serde_json::from_value(request.clone())
8593
.map_err(|error| format!("Invalid Git branch request: {error}"))?;
@@ -211,6 +219,10 @@ mod tests {
211219
.unwrap();
212220
assert_eq!(status["unstaged"][0]["path"], "tracked.txt");
213221
assert_eq!(status["untracked"][0], "untracked.txt");
222+
let count = read_at_path("git_get_tracked_change_count", path, &json!({}))
223+
.await
224+
.unwrap();
225+
assert_eq!(count, 1);
214226
for command in ["git_get_branches", "git_get_enhanced_branches"] {
215227
let branches = read_at_path(command, path, &json!({"includeRemote": false}))
216228
.await

‎src/apps/cli/src/peer_host/commands/mod.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ pub(crate) fn dispatch<'a>(
224224
"git_get_repository"
225225
| "git_get_repository_basic"
226226
| "git_get_status"
227+
| "git_get_tracked_change_count"
227228
| "git_get_branches"
228229
| "git_get_enhanced_branches"
229230
| "git_get_commits"
@@ -374,6 +375,7 @@ pub(crate) const HANDLED_COMMANDS: &[&str] = &[
374375
"git_get_repository",
375376
"git_get_repository_basic",
376377
"git_get_status",
378+
"git_get_tracked_change_count",
377379
"git_get_branches",
378380
"git_get_enhanced_branches",
379381
"git_get_commits",

‎src/apps/desktop/src/api/git_api.rs‎

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ use openbitfun_core::service::git::{
1616
use openbitfun_core::service::remote_ssh::{
1717
build_remote_git_command as build_remote_git_command_shared, normalize_remote_workspace_path,
1818
};
19-
use openbitfun_core::service::workspace::WorktreeTopologyFreshness;
19+
use openbitfun_core::service::workspace::{
20+
WorkspaceInfo, WorkspaceKind, WorktreeTopologyFreshness,
21+
};
22+
use openbitfun_services_integrations::remote_ssh::{
23+
build_remote_git_tracked_change_count_command, SSHCommandOptions,
24+
};
2025
use serde::{Deserialize, Serialize};
2126
use std::time::Instant;
2227
use tauri::State;
@@ -67,7 +72,14 @@ async fn resolve_remote_git_target(
6772
.require_workspace(workspace_id)
6873
.await
6974
.map_err(|e| e.to_string())?;
70-
if workspace.workspace_kind != openbitfun_core::service::workspace::WorkspaceKind::Remote {
75+
remote_git_target_for_workspace(&workspace, repository_path)
76+
}
77+
78+
fn remote_git_target_for_workspace(
79+
workspace: &WorkspaceInfo,
80+
repository_path: &str,
81+
) -> Result<Option<RemoteGitTarget>, String> {
82+
if workspace.workspace_kind != WorkspaceKind::Remote {
7183
return Ok(None);
7284
}
7385
let connection_id = workspace
@@ -431,6 +443,12 @@ pub struct GitRepositoryRequest {
431443
pub repository_path: String,
432444
}
433445

446+
#[derive(Debug, Deserialize)]
447+
#[serde(rename_all = "camelCase")]
448+
pub struct GitTrackedChangeCountRequest {
449+
pub workspace_id: String,
450+
}
451+
434452
#[derive(Debug, Deserialize)]
435453
#[serde(rename_all = "camelCase")]
436454
pub struct GitResolveRevisionRequest {
@@ -997,6 +1015,59 @@ pub async fn git_resolve_revision(
9971015
.map_err(|e| git_error_message("Failed to resolve Git revision", &e))
9981016
}
9991017

1018+
#[tauri::command]
1019+
pub async fn git_get_tracked_change_count(
1020+
state: State<'_, AppState>,
1021+
request: GitTrackedChangeCountRequest,
1022+
) -> Result<Option<usize>, String> {
1023+
let workspace = openbitfun_core::service::workspace::get_global_workspace_service()
1024+
.ok_or("Workspace service is unavailable")?
1025+
.require_workspace(&request.workspace_id)
1026+
.await
1027+
.map_err(|e| e.to_string())?;
1028+
if let Some(target) =
1029+
remote_git_target_for_workspace(&workspace, &workspace.root_path.to_string_lossy())?
1030+
{
1031+
let manager = state
1032+
.get_ssh_manager_async()
1033+
.await
1034+
.map_err(|e| e.to_string())?;
1035+
let command = build_remote_git_tracked_change_count_command(&target.repository_path);
1036+
let output = manager
1037+
.execute_command_with_options(
1038+
&target.connection_id,
1039+
&command,
1040+
SSHCommandOptions {
1041+
timeout_ms: Some(5_000),
1042+
..Default::default()
1043+
},
1044+
)
1045+
.await
1046+
.map_err(|e| e.to_string())?;
1047+
if output.timed_out || output.interrupted {
1048+
return Err("Remote Git change count was interrupted".into());
1049+
}
1050+
if output.exit_code != 0 {
1051+
if trust::is_missing_repository_message(&output.stderr) {
1052+
return Ok(None);
1053+
}
1054+
return Err(remote_git_error_message(
1055+
&target.repository_path,
1056+
format!("Failed to count tracked changes: {}", output.stderr.trim()),
1057+
));
1058+
}
1059+
return output
1060+
.stdout
1061+
.trim()
1062+
.parse()
1063+
.map(Some)
1064+
.map_err(|_| "Invalid remote Git change count".into());
1065+
}
1066+
GitService::get_tracked_change_count(&workspace.root_path)
1067+
.await
1068+
.map_err(|error| git_error_message("Failed to count tracked changes", &error))
1069+
}
1070+
10001071
#[tauri::command]
10011072
pub async fn git_get_status(
10021073
state: State<'_, AppState>,

‎src/apps/desktop/src/lib.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,6 +1683,7 @@ pub async fn run() {
16831683
review_platform_update_auth_token,
16841684
review_platform_clear_auth_token,
16851685
git_get_status,
1686+
git_get_tracked_change_count,
16861687
git_get_branches,
16871688
git_get_enhanced_branches,
16881689
git_get_commits,

0 commit comments

Comments
 (0)