mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-23 08:45:50 +00:00
fix: listSessions 严格按 cwd 过滤并移除 session/load 过严校验
- listSessions: 客户端省略 cwd 时回退到 getOriginalCwd(),并对每个候选会话的 存储 cwd 做 canonicalizePath 规范化后与请求 cwd 严格匹配,确保只返回真正属 于当前工作区的会话(符合 session-list.mdx "Only sessions with a matching cwd are returned") - sessionLifecycle: 移除 getOrCreateSession 中审计 2.2 添加的 cwd 一致性校验, 它会拒绝 resolveSessionFilePath worktree fallback 找到的合法会话加载 - 补充 listSessions 的 5 个测试用例覆盖 cwd 透传/fallback/分页拒绝/无 cwd 过滤 Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
This commit is contained in:
@@ -49,7 +49,11 @@ import { unlink } from 'node:fs/promises'
|
||||
import type { Message } from '../../../types/message.js'
|
||||
import { sanitizeTitle } from '../utils.js'
|
||||
import { listSessionsImpl } from '../../../utils/listSessionsImpl.js'
|
||||
import { resolveSessionFilePath } from '../../../utils/sessionStoragePortable.js'
|
||||
import {
|
||||
resolveSessionFilePath,
|
||||
canonicalizePath,
|
||||
} from '../../../utils/sessionStoragePortable.js'
|
||||
import { getOriginalCwd } from '../../../bootstrap/state.js'
|
||||
import type { AcpSession } from './sessionTypes.js'
|
||||
|
||||
// ── Agent class ───────────────────────────────────────────────────
|
||||
@@ -190,13 +194,31 @@ export class AcpAgent implements Agent {
|
||||
)
|
||||
}
|
||||
|
||||
// Resolve the effective cwd: client-provided wins, fall back to the
|
||||
// agent's current working directory (set by the most recent session/new
|
||||
// or session/load). Standard ACP clients (e.g. Goose) call session/list
|
||||
// with empty params and no cwd — without a fallback, listSessionsImpl
|
||||
// treats undefined dir as "all projects" and returns every session on
|
||||
// disk, which is unrelated to the workspace the user actually has open.
|
||||
const requestedCwd = params.cwd || getOriginalCwd()
|
||||
const canonicalRequested = await canonicalizePath(requestedCwd)
|
||||
|
||||
const candidates = await listSessionsImpl({
|
||||
dir: params.cwd ?? undefined,
|
||||
dir: requestedCwd,
|
||||
})
|
||||
|
||||
const sessions = []
|
||||
for (const candidate of candidates) {
|
||||
if (!candidate.cwd) continue
|
||||
// Per session-list.mdx: "Only sessions with a matching cwd are
|
||||
// returned." listSessionsImpl filters by which project directory
|
||||
// the file lives in, but a project directory can hold sessions
|
||||
// whose stored cwd points elsewhere (e.g. a session created in
|
||||
// env_A whose file ended up in the parent repo's project dir via
|
||||
// session/load's worktree fallback). Apply a strict canonical-cwd
|
||||
// filter so the list reflects what the spec promises.
|
||||
const canonicalCandidate = await canonicalizePath(candidate.cwd)
|
||||
if (canonicalCandidate !== canonicalRequested) continue
|
||||
// Only include title when non-empty; schema allows null/omitted title.
|
||||
const title = sanitizeTitle(candidate.summary ?? '')
|
||||
sessions.push({
|
||||
|
||||
Reference in New Issue
Block a user