Cursor agent 终端命令行为不符预期

Cursor agent 跑 shell 命令跑错了——working dir 不对、用错包管理器、env 没加载、输出被截断,或 .zshrc 把命令卡死。给出具体修法。

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
你写的规则像是完全没生效规则还放在老的 .cursorrulesStep 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 :3000ps 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 | catCOMPOSER_NO_INTERACTION=1PIP_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(descriptionglobsalwaysApply)。

新建 .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/rulessettings.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/*.mdcalwaysApply: true):“命令前必先 pwd”、包管理器名、env 加载方式。
  • 一个仓库只用一个包管理器;删掉多余的 lock 文件。
  • 复杂命令一律走 package.json scripts,让 agent 跑 pnpm test 而不是自己拼底层命令。
  • 后台 dev server 用 tmux / screen / VS Code 独立 task 跑,别留在 agent terminal 里。
  • ~/.zshrc 加上针对 agent shell 的守卫,PATH/env 放进 ~/.zshenv
  • agent 说”完成”后,prompt 它做业务级验证(接口 / 数据 / 文件存在),不只是退出码。

相关阅读

标签: #排查 #Cursor #排查 #终端