fix(adopt): detect Cursor agent sessions and fix adopt-session uptime/liveness reporting#99
Conversation
|
Note on the Cursor Agent's I verified this with fresh launches for The implementation treats |
a18f98a to
e472465
Compare
Allow /adopt discovery to recognize cursor-agent processes as Cursor sessions and treat the generic agent binary as Cursor only when a Cursor bot is filtering candidates. This keeps broad scans from adopting unrelated agent processes while enabling Cursor-backed bots to attach to locally started Cursor Agent sessions. Tests cover tmux, zellij, and herdr discovery paths for the new aliases. Co-authored-by: Cursor <cursoragent@cursor.com>
Tmux adoption previously checked only /proc/<pid>/comm when walking a pane's process tree. Cursor Agent can report comm as MainThread while the real executable lives in argv[0], so Cursor-backed /adopt still missed locally started agent processes. Move comm+argv CLI detection into the shared session discovery module and reuse it from zellij discovery to keep both multiplexer paths consistent. Co-authored-by: Cursor <cursoragent@cursor.com>
e472465 to
d0632e6
Compare
…de CLIs The adopt picker card only showed an uptime for Claude (read from ~/.claude/sessions/<pid>.json); cursor/codex/coco/gemini etc. always rendered "unknown". Add readProcessStartTime — Linux reads /proc/<pid>/stat starttime + /proc/stat btime, other Unix falls back to `ps -o lstart=` — and use it as the startedAt fallback on both the tmux and zellij discovery paths. Also call sessionStore.updateSessionPid in forkAdoptWorker, mirroring forkWorker. Adopt sessions previously kept pid=null, so `botmux list` and killStalePids judged liveness by "process dead AND no bmx-* tmux"; adopt attaches to the user's own pane, so the session was misjudged unrecoverable and auto-pruned right after /adopt. The stored pid is botmux's bridge worker, never the user's CLI. Co-authored-by: Cursor <cursoragent@cursor.com>
…ession Triggering /adopt from Lark without picking a target leaves a scratch placeholder session (adopt_select needs it in memory to attach adoptedFrom). It never forked a worker, yet `botmux list`'s prune reported it as "process dead and no tmux session" and warned about it — misleading, since no CLI ever ran there. cmdList now splits the prune by whether a real CLI ever ran (cliId / lastCliInput / adoptedFrom, matching isRelayableRealSession): scratch placeholders are closed silently, genuinely dead sessions keep the original warning. Co-authored-by: Cursor <cursoragent@cursor.com>
75cdfa9 to
4e625a5
Compare
|
已审阅通过,正在合并,感谢贡献 🙏 合并时在你的改动之上追加了一处小修复(reviewer 提交),先同步给你: 问题:adopt 的「点击接管前二次校验」与「daemon 重启恢复确认」这两步之前重走了无 filter 的识别路径,而本 PR 新增的「以通用名 修复:给 影响面: |
…/liveness 合入 #99(作者 LucasIcarus/凡辞):/adopt 识别 Cursor agent 会话、为非 Claude CLI 补齐 adopt-session 运行时长与 worker pid、不再把未确认的 /adopt scratch 误报为崩溃会话。 reviewer 追加修复:adopt 二次校验与 daemon 重启恢复透传 cliId,修复以通用名 agent 安装的 Cursor 会话能被发现却在接管/恢复时误判已退出的问题(Codex 复审确认)。
|
Correction to my previous comment: no separate follow-up PR is needed. Upstream independently landed an equivalent fix in |
Summary
Make
/adoptwork end-to-end for Cursor Agent sessions, and fix two adopt-session bugs surfaced along the way.Cursor detection
cursor-agentprocesses as Cursor sessions during/adoptdiscovery.agentbinary as Cursor only when a Cursor bot is filtering candidates, so broad scans don't adopt unrelated agent processes./proc/<pid>/comm) when walking a pane's process tree — Cursor Agent can report comm asMainThreadwhile the real executable lives in argv[0]. Detection now lives in the shared session-discovery module and is reused by the tmux, zellij, and Herdr discovery paths.Adopt-session uptime & liveness
startedAtfor every CLI, not just Claude: addreadProcessStartTime(Linux/proc/<pid>/statstarttime +/proc/statbtime,ps -o lstart=fallback) so the adopt picker stops rendering "unknown" uptime for cursor/codex/coco/gemini.forkAdoptWorker, mirroringforkWorker. Adopt sessions keptpid=null, sobotmux list/killStalePidsjudged them by "process dead AND nobmx-*tmux" and pruned them right after/adopt. The stored pid is botmux's bridge worker, never the user's CLI.botmux listoutput/adoptscratch placeholder as a crashed session.cmdListnow distinguishes sessions that ever ran a real CLI (cliId/lastCliInput/adoptedFrom, matchingisRelayableRealSession) from never-activated scratches: scratches are closed silently, genuinely dead sessions keep the original warning.Validation
pnpm vitest run test/session-discovery.test.ts test/zellij-cli-detection.test.ts test/herdr-session-discovery.test.ts test/session-store.test.tspnpm buildNotes