agent 跑 npm test,看到 “3 passing”,就说”全部通过”。你自己跑同一条命令——10 failing。或者它 cd packages/web && npm install,几秒后说装完了,你 ls node_modules 发现根本没装。Cursor 的 agent 终端不是你日常 zsh 的镜像:它起的是一个非交互式(non-interactive)shell,有自己独立的 working directory,不会 source ~/.zshrc,长输出会被截断,连续命令之间的 shell state 也不一定持久。
最快修法: 别再假设 agent 知道你的环境。加一个 .cursor/rules/*.mdc 规则,强制它在跑任何命令前先 pwd 并点名包管理器,并让它去验证真实结果而不是只看退出码。截至 2026 年 6 月,最关键的一处正确性改动是把规则从老的 .cursorrules 文件迁出来(见下文)——那个文件在 Agent 模式里会被静默忽略。
你属于哪一类?
| 症状 | 最可能的原因 | 跳转 |
|---|---|---|
| ”测试通过”但其实没过 / 打错了包 | working directory 不对 | 原因 1 |
lockfile 被改乱、node_modules 是空的 | 在 pnpm/yarn/bun 仓库里用了 npm | 原因 2 |
process.env.X 是 undefined、DB/API 调用失败 | .envrc / .env 没在 agent shell 加载 | 原因 3 |
| 大日志里 agent “看不到”那个报错 | 输出从开头被截断 | 原因 4 |
| 输出和正在跑的 dev server 混在一起 | 残留的 background process | 原因 5 |
| 命令”成功了”但什么都没变 | 把退出码 0 当成了结果 | 原因 6 |
| 每条命令都卡住 / 输出乱码 | .zshrc 主题(Powerlevel10k / oh-my-zsh) | 原因 7 |
| 你写的规则像是完全没生效 | 规则还放在老的 .cursorrules 里 | Step 7 |
常见原因
1. Working directory 不是你以为的那个
agent 的终端 session 默认在 workspace 根。你以为它在 packages/web/,它其实在 monorepo 根,npm test 跑成了另一个包。Cursor 在 2026 年 6 月仍有未关闭的 bug 报告:终端不跟随当前激活的 workspace;以及 subagent 的 worktree 隔离结束后,父 session 的 cwd 会停在一个已经被清理掉、不再存在的目录上。
如何判断: 让 agent 先跑 pwd 并报出来,对照你期望的目录。
2. agent 用 npm 但项目是 pnpm / yarn / bun
模型的训练 prior 默认是 npm。哪怕仓库里有 pnpm-lock.yaml,agent 也可能视而不见,直接跑 npm install,把 lockfile 改写成另一棵依赖树。
如何判断:
ls *-lock.* package-lock.json 2>/dev/null
# pnpm-lock.yaml / yarn.lock / bun.lock(b) / package-lock.json——是哪个?
如果 agent 跑命令时没有先确认对应的工具,就是 prior 占了上风。
3. .envrc / direnv / .env 没在 agent shell 里加载
这是 shell 机制问题,不是 Cursor 的 bug。非交互式 shell 不会 source ~/.zshrc 或 ~/.zprofile,而 direnv 正是把自己挂在这些文件里的。所以 agent 的子进程从没跑过那个 hook,process.env.DATABASE_URL 对它就是 undefined。
如何判断: 让 agent 跑 env | grep MY_VAR;输出为空说明根本没加载。
4. 长输出被截断,agent 看到的是错误的那一段
Cursor 会限制交给模型的 stdout 量,而且截至 2026 年是从开头截——你会看到类似 [Terminal output truncated: ~85KB dropped from beginning] 的横幅。test 跑了 5000 行时,模型可能保住了尾部却丢了顶部那段 failing 汇总,反过来也可能(取决于工具)。无论哪种,它都是在用一份不完整的日志做判断。
如何判断: 让它打印真实输出的 tail -50(或 head -50),对比你自己跑命令时看到的内容。
5. 后台进程污染 terminal
之前 agent 起了 npm run dev 又没杀掉,新命令的输出和还在刷的 dev server 日志混在一起,agent 就把 dev server 的行当成新命令的结果读了。
如何判断: lsof -i :3000 或 ps aux | grep node 看有没有遗留。
6. 命令成功 ≠ 业务正确
npm install 退出码 0、git push 报 “Everything up-to-date”、build “成功了”却没产出任何文件——agent 把退出码当成功的证明,不去检查真实结果。
如何判断: agent 说成功后,你手动验证后果(curl 接口、刷页面、查数据库、列产物)。对不上,就是它没真正验证。
7. .zshrc 主题把 agent 终端卡死或弄乱
这一类被严重漏诊。agent 跑命令的那个 shell 仍会加载你的 ~/.zshrc,而那些重型交互配置——Powerlevel10k、oh-my-zsh、异步 prompt、动态图标——会吐出控制字符和 prompt 重绘,agent 的输出解析器对不上号。结果就是命令看起来一直挂着(agent 永远检测不到结束)、输出乱码,或者命令”跑了”但捕获到的输出是空的。
如何判断: 同一条命令在你正常的终端里秒回,给 agent 却卡住或返回乱码。Cursor 会往 agent shell 注入这些环境变量,可以据此识别:PAGER=head -n 10000 | cat、COMPOSER_NO_INTERACTION=1、PIP_NO_INPUT=true(以及 TERM_PROGRAM=cursor)。见 Step 8。
动手前先确认
- 区分是 Composer agent 自动跑的命令,还是你手动在 Cursor 终端跑的——只有前者走的是非交互式的 agent shell。
- 复现前先 commit 一次或开 branch,避免错命令污染仓库。
- 记下 Cursor 版本(Cursor → About)、当前模型、是 agent 还是 chat。
需要收集的信息
- agent 跑的命令全文、它显示的输出、以及它下的结论。
- 你手动跑同命令的真实输出。
- 仓库的 lock 文件类型(
pnpm-lock.yaml等)。 - 是否用 direnv /
.envrc。 - 是否有 background process 残留。
- 你的
~/.zshrc是否加载了重型主题/插件管理器。
最短修复路径
顺序是:先验证状态,再纠正用法,最后加固配置。
Step 1:让 agent 在每条命令前自己核验状态
把 agent 跑命令的标准前缀固定下来:
Before running any command, first run and report:
1. `pwd` — confirm working directory
2. `which pnpm npm yarn bun` — confirm package manager available
3. `cat package.json | grep '"name"'` — confirm correct package
Only proceed if all three match the expected target.
Step 2:显式指定包管理器 + 路径
Run this exact command, do NOT substitute:
cd packages/web && pnpm test -- --run
--run 一类 flag 能避免挂在 watch 模式里。永远 cd 进目标目录,别依赖继承来的 cwd。
Step 3:把 env 显式 source
direnv 项目里:
Before running anything that needs env vars, source it explicitly:
source .envrc && env | grep DATABASE_URL
Confirm the var is set, then run the actual command.
dotenv 项目改用 set -a && . .env && set +a。或者把需要的变量直接写进规则,让模型一开始就知道(见 Step 7)。
Step 4:让 agent 拿到真实的测试输出
因为 Cursor 会截断,所以管道写文件,再读你关心的那一段:
After running the tests, capture full output and read the summary:
pnpm test > /tmp/test-output.log 2>&1; tail -200 /tmp/test-output.log
# 如果 failing 汇总在顶部,改用:head -200 /tmp/test-output.log
哪怕内联预览被截断,文件里始终是完整日志。
Step 5:清理 background process
# 找到占端口的进程
lsof -i :3000
# 杀掉
kill -9 <PID>
# 或一次性清掉残留的 node
pkill -f node
agent 重启 dev server 之前,先让它跑 lsof -i :3000。
Step 6:让 agent 验证结果,而不是退出码
After `pnpm install`, verify by:
ls node_modules | wc -l # should be > 100
cat node_modules/.package-lock.json | jq '.packages | length'
After `git push`, verify by:
git log origin/main --oneline | head -3 # should show your commit
Step 7:把规则迁到 .cursor/rules/*.mdc,别再用 .cursorrules
这是截至 2026 年 6 月最重要的更新。仓库根目录那个单文件 .cursorrules 是旧格式,在 Agent 模式下会被静默忽略——也就是说你为上面这些问题写的规则可能根本没加载。Cursor 现在的格式是 .cursor/rules/ 目录里一个个 .mdc 文件,每个带 YAML frontmatter(description、globs、alwaysApply)。
新建 .cursor/rules/terminal.mdc:
---
description: Shell command discipline for the agent terminal
alwaysApply: true
---
- Always run `pwd` and confirm the working directory before any command.
- This repo uses pnpm. Never run npm or yarn. Run `cd <pkg> && pnpm ...`.
- Required env vars: DATABASE_URL, REDIS_URL, STRIPE_SECRET_KEY.
Load them with `source .envrc` (direnv) before any DB/API command and verify with `env | grep`.
- After install/build/push, verify the real outcome, not the exit code.
- Capture long output to a file and read head/tail; do not trust the inline preview.
alwaysApply: true 会把这条规则注入每个 agent session。如果某条规则只该在 monorepo 的一部分生效,就改用 globs(例如 packages/web/**)。迁移期间可以暂时保留原来的 .cursorrules(非 agent 场景 Cursor 还会读它),但凡是你在 Agent 模式里依赖的东西,都必须放进 .cursor/rules/。
Step 8:别让 ~/.zshrc 搞坏 agent shell
如果命令卡住或返回乱码(原因 7),就给你的交互式配置加个守卫,让它在 agent 里被跳过。在 ~/.zshrc 的最顶部附近加上:
# Skip heavy interactive setup inside Cursor's agent / VS Code shell
if [[ "$TERM_PROGRAM" == "cursor" || "$TERM_PROGRAM" == "vscode" \
|| "$COMPOSER_NO_INTERACTION" == "1" ]]; then
return
fi
这样正常终端里你的完整主题照旧,agent 拿到的是一个干净 shell。如果你确实需要 agent shell 里有 PATH 或某些 env 变量,就放进 ~/.zshenv——这个文件会被非交互式 shell 读取,正好补上原因 3 的那个缺口。
怎么确认已经修好
- 让 agent 重跑那条失败命令,并报出
pwd、包管理器、以及一次真实的结果校验(不是只说”done”)。 - 重启 Cursor 后再复现一次,确认不是会话内的临时状态。
- 切到另一个仓库 / 另一台机器复现,区分是 Cursor 配置问题还是项目本身问题。
- 让同事打开同一个仓库重试,确认不是只有你的本地缓存被修好。
如果还是没修好
- 把复现缩到最小:一条命令 + 一次
pwd。 - 回滚最近一次
.cursor/rules或settings.json改动。 - 在 forum.cursor.com 搜 “agent terminal wrong dir” / “agent didn’t see env” / “terminal output truncated”,附上你的 prompt 和输出。
- 抓 View → Output → Cursor 的 agent 日志贴到 Bug Reports。
常见问题
为什么测试明明失败了,agent 却说通过?
通常是 working directory 不对(原因 1)或输出被截断(原因 4):它要么对着错误的包跑了测试,要么只读到了不含 failing 那段的日志。强制它先 pwd,并把输出管道写文件。
我的 .cursorrules 以前能用,现在好像被无视了——发生了什么?
2026 年起,老的单文件 .cursorrules 在 Agent 模式下会被静默忽略。把内容迁进 .cursor/rules/*.mdc 并设 alwaysApply: true。见 Step 7。
agent 终端跑个简单命令也永远卡着。
你的 ~/.zshrc 在加载交互式主题(Powerlevel10k / oh-my-zsh),agent 的解析器对不上,于是永远检测不到命令结束。加上 Step 8 里那段 TERM_PROGRAM / COMPOSER_NO_INTERACTION 守卫。
为什么只有 agent 那边 env 变量是 undefined?
agent 的 shell 是非交互式的,不会 source ~/.zshrc / ~/.zprofile,所以 direnv 和 dotenv 的 hook 从没跑过。要么每条命令前显式 source,要么把 PATH/env 放进 ~/.zshenv。
怎么让 agent 在 pnpm 仓库里别再用 npm?
在一条 always-apply 的 .cursor/rules 文件里写上 This repo uses pnpm. Never run npm or yarn.,并把命令都走 package.json scripts,让 agent 跑 pnpm test 而不是 vitest run。
预防建议
- 终端规则放进
.cursor/rules/*.mdc(alwaysApply: true):“命令前必先pwd”、包管理器名、env 加载方式。 - 一个仓库只用一个包管理器;删掉多余的 lock 文件。
- 复杂命令一律走
package.jsonscripts,让 agent 跑pnpm test而不是自己拼底层命令。 - 后台 dev server 用
tmux/screen/ VS Code 独立 task 跑,别留在 agent terminal 里。 - 给
~/.zshrc加上针对 agent shell 的守卫,PATH/env 放进~/.zshenv。 - agent 说”完成”后,prompt 它做业务级验证(接口 / 数据 / 文件存在),不只是退出码。