github / github/copilot-cli

resume-auto-cd sets CWD to / when session was created by external producer (Agency)

未关闭
#3,515 0 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看
area:configuration area:sessions
主要语言
Shell
星标
11.2k
派生
1.9k
平均合并
14 小时 16 分钟
30 天内合并 PR
6

描述

## Bug Description

When Copilot CLI 1.0.55 resumes a session created by an external producer (e.g., Agency CLI via `agency cp`), the new `resume-auto-cd` feature changes the process working directory to `/` instead of using the actual terminal CWD.

## Current Behavior

1. User runs `agency cp` from `~/projects/my-repo`
2. Agency creates a session file (`events.jsonl`) with a `session.start` event (no `cwd` field — Agency does not set it)
3. Agency launches `copilot --resume ` — the child process correctly inherits the terminal CWD (`~/projects/my-repo`)
4. Copilot 1.0.55 reads `workspace.yaml` (which has no CWD yet, or defaults to `/`) and `resume-auto-cd` does `process.chdir("/")`
5. The `session.resume` event is emitted with `"context": { "cwd": "/" }` — no git info, no branch, no repository
6. `workspace.yaml` is written with `cwd: /`
7. The session operates from `/` — all file operations, git detection, etc. are broken

**Evidence from process log:**
```
[DEBUG] resume-auto-cd: chdir -> /
```

Yet the process itself was started in the correct directory — after the chdir, remoteHosts sees `/` instead of the real project dir.

## Expected Behavior

When `resume-auto-cd` finds no persisted CWD (or CWD is `/`), it should **fall back to `process.cwd()`** (the inherited terminal CWD) rather than changing to `/`. The logic should be:

1. If `workspace.yaml` has a valid, non-root CWD → use it (current behavior, correct)
2. If `workspace.yaml` has no CWD, or CWD is `/` or empty → **stay in `process.cwd()`** (do not chdir)
3. If `COPILOT_DISABLE_RESUME_AUTO_CD=1` → skip entirely (current behavior, correct)

## Regression

- **Works in:** Copilot CLI 1.0.51 (no `resume-auto-cd` feature)
- **Broken in:** Copilot CLI 1.0.55-0 (`resume-auto-cd` introduced)

Verified by comparing two sessions started 3 minutes apart in the same Agency session:
| Session | Copilot Version | `session.resume` context |
|---------|----------------|--------------------------|
| Good session | 1.0.51 | Full context: cwd, gitRoot, branch, repository ✅ |
| Bad session | 1.0.55 | `cwd: /` only ❌ |

## Steps to Reproduce

1. Create a session file manually (simulating what Agency does):
```bash
SESSION_ID=$(uuidgen | tr "[:upper:]" "[:lower:]")
mkdir -p ~/.copilot/session-state/$SESSION_ID
cat > ~/.copilot/session-state/$SESSION_ID/events.jsonl << EOF
{"type":"session.start","data":{"sessionId":"$SESSION_ID","version":1,"producer":"external","copilotVersion":"1.0.55","startTime":"2026-01-01T00:00:00.000Z"},"id":"00000000-0000-0000-0000-000000000001","timestamp":"2026-01-01T00:00:00.000Z","parentId":null}
EOF
```
2. From a project directory (e.g., `~/projects/my-repo`), run:
```bash
copilot --resume $SESSION_ID
```
3. Observe that CWD is `/` instead of `~/projects/my-repo`

## Workaround

```bash
export COPILOT_DISABLE_RESUME_AUTO_CD=1
agency cp
```

## Environment

- **Copilot CLI:** 1.0.55-0
- **Agency CLI:** 2026.5.23.2
- **OS:** macOS (arm64)

## Additional Context

The `resume-auto-cd` feature checks `workspace.yaml` for a persisted CWD before the session fully initializes. When the session was created by an external producer that does not write CWD to the session metadata, `workspace.yaml` either does not exist yet or has a default/empty CWD — and the feature interprets this as "change to `/`".

This affects any external tool that creates Copilot sessions programmatically (Agency CLI, CI/CD pipelines, custom integrations) — not just direct `copilot` invocations.

### Security Side-Effect

Because sessions resume with `cwd: /`, the user is prompted to trust `/` as a directory. If accepted, `/` gets added to `trustedFolders` in `~/.copilot/config.json`, which effectively trusts the entire filesystem — a security concern.

贡献指南

打开贡献指南

调研方向

首先跟踪 --resume 期间的 resume-auto-cd 路径,重点关注 workspace.yaml 和 session.start 事件如何提供持久化的 CWD。使用来自项目目录的 external-producer 会话复现,然后验证缺失、空值或 root 的 CWD 值会保留 process.cwd()、保留仓库上下文,并避免信任 /.

由索引模型根据 Issue 内容生成。

评估

技术栈
shell
领域
cli, security
Issue 类型
缺陷
难度
3/5
预计耗时
1-2 天
活跃度
冷清
描述清晰度
基本清楚
新手友好度
57/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。