fix(client): address CI and review findings on blank-session reuse
- docs: fix cross-class note links (../feature/...), mirror the membership reuse criterion in README.zh.md and the connectWorkspace architecture note (EN/ZH/sidecars re-recorded) - test(client): stray + member blank at the same path — the scan skips the stray and reuses the member - test(web): re-registration after delete now mints a fresh blank session (the old cwd-only reuse is gone), so the account is no longer empty; assert the retained seeded session is still not re-adopted
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/runtime/README.md
|
||||
README.md: dd780369a1d888dde2579e436afe2ce1e6dcfdd1
|
||||
README.zh.md: 5574ad6452c6a2d94fb63da7e53b98e8d074f1c9
|
||||
README.md: adcc9595bbf6865f1a01eedf9eead1da5d4b5657
|
||||
README.zh.md: 5857b929e5a2535420a46b6933ec0497fb1ff117
|
||||
|
||||
@@ -20,7 +20,7 @@ SlotsService 分别为 renderer 提供 `useSessions` 与 `useWorkspaces` 的裸
|
||||
|
||||
## New Session 与 blank 镜像
|
||||
|
||||
`WorkspacesService.connectWorkspace(workspaceId)` 解析 New Session 流程最终落入的会话:先在列表镜像中复用该 workspace 的既有空会话(`blank && cwd == workspace.path`),未命中则调用 `session.create({workspaceId})`,返回会话 id 由调用方 open。`SessionSummary.blank` 镜像主机派生的空日志位,在客户端只降不升:由 `session.list`/`host/session-added` 帧播种,本地首次获 Host 接受的 `prompt()`(RPC 成功响应时——受理即证明用户消息已入主机日志;首讯被拒则会话保持 blank、保持可复用)与任何 `running: true` 状态帧翻为 false,每次列表重拉重新对齐。列表界面隐藏 blank 行;store 保留全部行。`SessionsService.create` 接受可选的、由调用方预先分配的 SessionId,失败时抛出 `SessionCreateError`(携带 `requestedSessionId`)。
|
||||
`WorkspacesService.connectWorkspace(workspaceId)` 解析 New Session 流程最终落入的会话:先在列表镜像中复用该 workspace 的既有空会话(`blank && cwd == workspace.path && sessionIds.includes(id)`——host 自己的成员规则,绝不只按 cwd,避免劫持 cwd 匹配但未入账的空白会话),未命中则调用 `session.create({workspaceId})`,返回会话 id 由调用方 open。`SessionSummary.blank` 镜像主机派生的空日志位,在客户端只降不升:由 `session.list`/`host/session-added` 帧播种,本地首次获 Host 接受的 `prompt()`(RPC 成功响应时——受理即证明用户消息已入主机日志;首讯被拒则会话保持 blank、保持可复用)与任何 `running: true` 状态帧翻为 false,每次列表重拉重新对齐。列表界面隐藏 blank 行;store 保留全部行。`SessionsService.create` 接受可选的、由调用方预先分配的 SessionId,失败时抛出 `SessionCreateError`(携带 `requestedSessionId`)。
|
||||
|
||||
## 待处理队列投影
|
||||
|
||||
|
||||
@@ -159,8 +159,12 @@ describe('WorkspacesService', () => {
|
||||
}))
|
||||
api.onList = () => Promise.resolve(ok({
|
||||
items: [
|
||||
// Blank session already parked in alpha (cwd == workspace path canon
|
||||
// AND accounted under alpha): the reuse hit.
|
||||
// Stray blank at alpha's path but NOT accounted under alpha (a CLI
|
||||
// session birthed at the host cwd), sorted before the member blank:
|
||||
// the scan must skip it and keep looking for a member hit.
|
||||
{ sessionId: sid('s-stray-alpha'), updatedAt: 1, running: false, blank: true, cwd: '/w/alpha' },
|
||||
// Blank session parked in alpha (cwd == workspace path canon AND
|
||||
// accounted under alpha): the reuse hit.
|
||||
{ sessionId: sid('s-blank'), updatedAt: 2, running: false, blank: true, cwd: '/w/alpha' },
|
||||
// Non-blank sibling in beta must never be reused.
|
||||
{ sessionId: sid('s-active'), updatedAt: 3, running: false, blank: false, cwd: '/w/beta' },
|
||||
@@ -174,7 +178,8 @@ describe('WorkspacesService', () => {
|
||||
await Promise.all([workspaces.refresh(), sessions.refresh()])
|
||||
await Promise.resolve()
|
||||
|
||||
// Hit: same workspace → the parked blank session comes back, no create RPC.
|
||||
// Hit: same workspace → the parked member blank comes back (the earlier
|
||||
// cwd-matching non-member stray is skipped), no create RPC.
|
||||
await expect(workspaces.connectWorkspace(wid('alpha'))).resolves.toBe('s-blank')
|
||||
expect(api.callsOf('session.create')).toEqual([])
|
||||
// Resolution guarantee: the id is binding-resolvable synchronously.
|
||||
|
||||
Reference in New Issue
Block a user