makecindy / makecindy/cindy

feat: support multi-root projects with primary and additional directories

Open
#1,762 6 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
TypeScript
Stars
2.7k
Forks
395
Avg merge
21h 48m
Merged PRs (30d)
776

Description

## 使用场景

希望把同一项 Cindy 工作涉及的多个目录放进一个逻辑项目,例如:

- `cindy/`:主 checkout
- `cindy-moved/`:迁移后的 checkout、worktree 或相关参考目录

用户希望在一个项目里持续处理相关代码、对话和 Agent 任务,而不是为每个目录分别维护项目。

这不只包括 Git worktree,也包括路径完全无关、无法靠 VCS 自动归一化的多 checkout 场景,例如:

- Perforce 的 Dev / TADev workspace;
- SVN 的多个分支 checkout;
- 用户手动迁移、复制或分别维护的多个代码目录。

这些目录需要由用户显式声明属于同一个逻辑 Project;不能依赖共同父目录、Git remote 或 worktree 关系猜测归属。

## 当前问题

Cindy 目前没有独立的 Project 实体。Project 主要由 session 的单值 `workingDir` 动态分组得到;session 数据只有一个 `working_dir`。

现有 `extra_dirs` 不能直接解决问题:它是 session 级的附加只读引用目录,不是持久化的 Project 成员目录,草稿重启时也会清空。

更重要的是,`workingDir` 同时承担:

1. Agent 实际 `cwd`;
2. 文件写入与 sandbox / auto-review 安全根;
3. Git、worktree、PR 目标;
4. Claude/Codex 的项目配置、resume、AGENTS/skills 发现;
5. Maker Memory、project-context、插件设置和自动化配置的 workdir scope;
6. Cindy 侧栏的 Project 分组与对话过滤。

因此不能简单把它从字符串改成数组,也不能把多个目录直接塞进 `extra_dirs`。

当前以绝对路径作为 scope key 的能力还会把同一逻辑项目的不同 checkout 隔离开。例如两个 P4 workspace 会各自维护独立的 Maker Memory,切换分支后无法共享已经建立的项目上下文。

## 调研结论

截至 2026-08-05,Codex Desktop 已支持本地项目绑定多个目录并指定 primary:

- primary 是默认 `cwd`、新任务起点、Git/PR/worktree 和项目级配置发现锚点;
- secondary 是同一项目的额外文件能力根,可用于搜索、读取和编辑;
- 实际读写由 sandbox / permission profile 决定;
- 开源 Codex app-server/core 将 `cwd` 与 `runtime_workspace_roots` 分开,roots 会进入 Agent filesystem context 和权限计算;
- Desktop 的 saved project / `rootPaths` 属于上层产品状态,不等同于底层 app-server 字段。

因此,目录一一匹配的主要原因不是 GitHub 映射,也不是对话查询性能,而是 Cindy 尚未拆分“项目身份、执行 cwd、安全根、Agent 原生项目 scope、持久化 scope”。

对话搜索在项目过滤时主要先收集 session IDs,再按 session IDs 查询;目录不是全文搜索的主要索引。

参考:

- https://learn.chatgpt.com/docs/projects
- https://learn.chatgpt.com/docs/changelog
- https://github.com/openai/codex/blob/main/codex-rs/app-server-protocol/src/protocol/v2/thread.rs
- https://github.com/openai/codex/blob/main/codex-rs/core/tests/suite/workspace_roots.rs
- https://github.com/openai/codex/issues/27943

## 目标

请后续专项设计并评估:

1. Project identity 与 ProjectRoot / membership 层;
2. primary root 与 additional roots;
3. 每个 root 的 read-only / read-write 权限;
4. Project identity 与 session 实际 `workingDir` 的解耦;
5. 项目变更后,已有 session runtime roots 和权限的生效时机;
6. local、SSH remote、device-link、mobile 的边界;
7. 多 root 下 Git、worktree、PR、AGENTS/skills/config、project-context、Memory、插件和自动化分别以什么 root 为准;
8. 旧项目、旧 session、alias、侧栏状态、scheduler consent 等数据迁移;
9. Git worktree、P4、SVN 与纯手工目录都能通过显式 membership 共享同一个稳定 Project scope,不依赖 VCS 探测。

## 关键语义

- Project identity 由稳定的 Project ID 表达,不由某个绝对路径、共同父目录或 VCS 身份代替。
- 同一 Project 的任意成员 root 都可以成为某个 session 的实际 `workingDir`。primary 是新任务的默认起点,以及默认 Git、配置和作用域锚点;不代表 additional root 只能作为只读参考目录。
- Maker Memory 与 project-context 应能按 Project ID 共享,让同一项目的多个 checkout 复用上下文;实际文件访问权限仍按本次运行的 roots、root access 与 sandbox / permission profile 共同决定。
- 第一阶段可以只开放受限的 runtime roots,但数据模型不能把 additional 永久建模为“只读附件”。

## 建议方向

评估以下模型,而不是直接改造 `workingDir`:

```ts
Project { id, displayName, primaryRootId }
ProjectRoot {
id, projectId, path,
role: 'primary' | 'additional',
access: 'read' | 'write',
remoteHostId?, deviceId?, order
}
```

兼容原则:

- 旧项目迁移为单 root Project;
- 旧 session 保留原始 `workingDir`,新增 nullable `projectId` 聚合;
- primary 继续作为默认 cwd / Git / 项目配置锚点;
- additional roots 不静默复用现有 session `extra_dirs` 语义;
- 不把共同父目录伪装成一个 Git 项目;
- 不依赖 Git/P4/SVN 自动探测决定 membership,允许用户显式归组;
- 配置必须提供可视化 UI,不要求用户手编辑配置文件。

## 非目标

- 本 Issue 不要求当前提交实现多目录项目;
- 不要求把多个 Git 仓库或 P4/SVN workspace 合并成一个仓库;
- 不要求一次性重写所有 Memory、transcript、Git 或插件历史数据;
- 不要求把所有附加目录的 AGENTS/config 无条件拼进全局 prompt;
- 不要求本 Issue 直接修改服务端或跨仓协议。

## 预期交付

后续负责该专项的人应先提交:

- 产品与数据模型方案;
- 迁移与向下兼容方案;
- 权限和运行时 roots 同步协议;
- Desktop / Mobile / SSH / device-link 影响面;
- 分阶段实现计划与验证矩阵。

其中验证矩阵必须包含:两个路径无关的 P4/SVN checkout 被显式归入同一 Project,在任一 checkout 中启动 session 时保持各自实际 `workingDir`,同时共享 Project 级 Memory / project-context,且不会静默扩大另一目录的文件写权限。

本 Issue 是调研和需求入口,不代表当前 Cindy 仓库已有实现承诺。

Contributor guide

Open the contributing guide

Research direction

The issue names no Cindy files, tests, or entry points; begin by mapping the session working_dir and extra_dirs data paths and the project-scoping consumers described in the issue. Read the referenced Codex thread protocol and workspace_roots.rs for comparison. Done means a product/data model, migration plan, runtime-roots and permission protocol, platform impact analysis, phased plan, and validation matrix.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
devtools
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.