makecindy / makecindy/cindy

[Feature] fix(desktop): show remote machine identity for remote projects

Open
#71 2 comments 0 reactions 0 assignees View on GitHub
feature
Dominant language
TypeScript
Stars
2.7k
Forks
395
Avg merge
21h 48m
Merged PRs (30d)
776

Description

## 问题描述

创建远程项目后,项目选择器和左侧项目树只能通过地球图标判断这是一个远程项目,无法直接看到项目具体对应的远程机器名称、SSH Host alias 或配置的 hostname/IP。

当相同或相似路径的项目位于多台远程机器上时,用户无法快速区分它们。

## 复现步骤

1. 配置并连接两台不同的远程机器。
2. 分别在两台机器上创建或打开远程项目。
3. 返回项目选择器,查看远程项目。
4. 查看左侧项目树中的远程项目及其会话。

## 当前表现

- 项目选择器只显示项目目录名/路径和远程标记。
- 左侧项目树只显示项目名和地球图标。
- 侧栏中的 SSH 图标 tooltip 只显示 `remoteHostId`。
- 用户无法直接确认项目对应哪台远程机器。
- 两台远程机器存在同名项目或相同路径时尤其难以区分。

## 期望表现

远程项目应在项目选择器、左侧项目树以及相关项目筛选入口中显示明确且一致的机器身份。

建议至少显示以下信息之一:

- SSH Host alias;
- 配置的 `hostname` 或 IP;
- `user@hostname`;
- 对于 device-link 项目,显示设备名称。

示例:

```text
torch-piat
root@
```

或:

```text
torch-piat · qa-11
```

当 SSH 主机配置被删除、改名或暂时无法加载时,应回退显示已持久化的 `remoteHostId`。

## 初步定位

远程项目的业务身份实际上已经包含主机维度:

- Session 持久化了 `remoteHostId`。
- 项目分组键使用 `remoteHostId + workingDir`,不同机器上的同路径项目不会被错误合并。
- SSH `HostConfig` 已包含 `id`、`hostname`、`port` 和 `user`。

但展示链路没有完成 `remoteHostId → HostConfig` 的关联:

- `apps/desktop/src/renderer/features/cc-agent/lib/projectGrouping.ts`
- `ProjectNode` 只携带 `remoteHostId`,项目标题仍然只根据 `workingDir` 计算。
- `apps/desktop/src/renderer/features/cc-agent/sidebar/sections/ProjectNode.tsx`
- SSH 项目只渲染地球图标,tooltip 内容仅为 `remoteHostId`。
- `apps/desktop/src/renderer/features/cc-agent/sidebar/ConversationSearchBox.tsx`
- `apps/desktop/src/renderer/features/cc-agent/sidebar/SidebarFilterPopover.tsx`
- 同样只通过图标和 `remoteHostId` 表达远程身份。
- `apps/desktop/src/renderer/hooks/useProjectPickerOptions.ts`
- 普通项目选择器选项只有 `path`、`name`、`description`,没有远程主机维度。
- `apps/desktop/src/main/localDb/schema.ts`
- `recent_workdirs` 只有 `path` 和 `lastUsedAt`。
- `apps/desktop/src/main/localDb/ipc/sessions.ts`
- SSH 远程项目被明确排除在 `recent_workdirs` 外,防止远程路径丢失 host 后被误当成本机路径。

## 建议处理方向

建议分两个可独立交付的阶段处理:

### 1. 先补齐桌面侧栏的机器身份展示

- 在 renderer 中复用 `remoteSsh.list()` 返回的 SSH host registry。
- 根据 `remoteHostId` 查询 `HostConfig`。
- 为远程项目生成统一的人类可读标签。
- 在项目树、搜索筛选和项目筛选中显示。
- 查不到配置时回退到 `remoteHostId`。
- device-link 项目继续使用 `deviceLinkDeviceName`,不要与 SSH 身份模型混用。

这一阶段不需要修改数据库。

### 2. 单独设计 host-aware 的项目选择器持久化

当前 `recent_workdirs` 以 `path` 为唯一身份,无法安全表示:

```text
host-a + /root/torch-piat
host-b + /root/torch-piat
```

如果要让远程项目持久出现在普通项目选择器中,需要让 picker option、持久化和选择结果同时携带项目来源、host/device identity 与 path,不能只保存路径。

## 验收标准

- [ ] 两台远程机器存在同名项目时,用户无需悬停即可区分机器。
- [ ] SSH 项目能显示 alias,以及配置的 hostname/IP 或 `user@hostname`。
- [ ] SSH 主机配置不存在或加载失败时回退显示 `remoteHostId`。
- [ ] device-link 项目显示设备名称。
- [ ] 本地项目展示不受影响。
- [ ] 项目树、会话搜索项目筛选和侧栏项目筛选采用一致的机器标签。
- [ ] 选择远程项目后仍保留正确的 `remoteHostId`,不会把远程路径当成本机路径。
- [ ] 明确评估手机版中“外层被控设备”和“被控设备内部 SSH 主机”的双层身份。

## 测试建议

- 同一路径分别位于本地、SSH host A、SSH host B 和 device-link device C。
- 两台 SSH 主机上存在相同 basename 的项目。
- SSH alias 指向 hostname。
- SSH alias 直接指向 IP。
- SSH 配置被删除或改名。
- SSH host list 加载失败。
- device-link 设备离线或改名。

Contributor guide

Open the contributing guide

Research direction

Start with projectGrouping.ts, ProjectNode.tsx, ConversationSearchBox.tsx, SidebarFilterPopover.tsx, and useProjectPickerOptions.ts; trace how remoteHostId and deviceLinkDeviceName reach each UI entry point, then inspect remoteSsh.list(). The first delivery can focus on consistent sidebar identity labels with remoteHostId fallback. Done means local projects remain unchanged, SSH and device-link identities are distinguishable, and remote selections preserve the correct host.

Written by the indexing model from the issue text.

Assessment

Tech stack
electron, react, typescript
Domain
desktop, frontend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.