Skip to content

fix: /status 权限行改传活 Session(宿主 current(session) 契约自 0.1.2-alpha.2 起变更 → 整行静默消失) - #5

Merged
pan17 merged 1 commit into
pan17:mainfrom
PerryLink:fix/permission-preset-session-shape
Sep 10, 2026
Merged

pan17 merged 1 commit into
pan17:mainfrom
PerryLink:fix/permission-preset-session-shape

Conversation

@PerryLink

Copy link
Copy Markdown
Contributor

症状

/status 的「• 权限:」行在受支持的宿主上永不出现,且无任何报错;/perm list 的「◀ 当前会话」标记同样失效(两处都走同一个 safeCurrent())。

根因:宿主契约已换,本仓调用形状没跟上

  • 宿主 packages/interaction/permission-presets/src/index.ts:308 是 current(session: Session): string;内部 permissionState(session)(同文件 :295-299)走 ctx.sessionProjections.stateOf(session, "permissions"),必须传 Session,否则抛 permission: permissions session projection is not registered。
  • 该契约由宿主 1a72ae202a(2026-08-19,refactor(session): migrate host state reads to projections)从「事件数组」改为「Session」,随 tag dsh-v0.1.2-alpha.2 起生效(0.1.2-alpha.2/3/4/5、rc.1、0.1.3-alpha.1/2、0.1.5-alpha.1/2、0.1.5-rc.1 全含)。
  • 本仓 src/dsh/ops.ts:174 仍声明 current(events: readonly SessionEventLike[]),src/bridge/bridge.ts:3389-3396 的 safeCurrent() 传的是 sessionEvents(agent.session)。
  • 失败链:current(<数组>) → stateOf(<数组>, "permissions") → session-projection/src/index.ts:615-629 的 cellFor() 读 session.header / session.inheritedEventCount / session.snapshotEvents() → TypeError → 被 safeCurrent() 的 try/catch 吞掉 → 返回 undefined → 渲染处 ...(permission ? ["• 权限: …"] : [])(bridge.ts:3494-3496)整行不输出。
  • 本仓 engines.dsh = ">=0.1.5-rc.1",即受支持的宿主 100% 命中该路径。

改法(3 个文件)

  • src/dsh/ops.ts:删除 SessionEventLike;签名改为 current(session: unknown),注释写明宿主契约与失败症状。
  • src/bridge/bridge.ts:safeCurrent() 直接传 agent.session(去掉事件数组那一跳);异常仍降级为 undefined,使「会话没有权限投影」保持原静默行为。
  • tests/status-colors.test.ts:mock 按宿主契约收紧(收到事件数组即抛错)并记录实参;新增回归用例断言 current() 收到的是活 Session。

验证(本仓原生门禁,Node 22)

  • npm run build 通过;npm test 421/421 全绿(33 文件)。
  • 反向验证:把 src/ 还原成改动前、仅保留新测试 → tests/status-colors.test.ts 2 failed(新增用例 + 原「权限 danger-*」用例),证明该测试确实复现了症状而不是空跑。

兼容性说明(请你定夺)

按现 engines(>=0.1.5-rc.1)直接切 Session 形状即可,无需回退。如果你仍想覆盖 0.1.2-alpha.2 之前的宿主,可改成 try { current(session) } catch { current(events) } 的双形状回退——我倾向不保留(单一契约更干净),这一条听你的。

(本 PR 只动这一处形状,未夹带任何格式化或无关改动。)

Since dsh 0.1.2-alpha.2 the host folds `sessionProjections.stateOf(session, "permissions")`,
so `current()` takes a Session — not an event array. This bridge still passed
`sessionEvents(agent.session)`, which makes the host throw and `safeCurrent()` silently
swallow it: the `/status` permission row never rendered, and `/perm` list lost its
"current session" marker.

- ops.ts: drop `SessionEventLike`; `current(session: unknown)` now documents the host
  contract and the exact failure symptom.
- bridge.ts: `safeCurrent()` passes `agent.session` (the event-array hop is gone);
  exceptions still degrade to `undefined`.
- status-colors.test.ts: the mock enforces the host contract (an event array throws)
  and records the argument; a regression case asserts the live Session is passed.

Verified with the repo's own gates on Node 22: `npm run build` clean, `npm test`
421/421 passing.
@pan17
pan17 merged commit 12e0c90 into pan17:main Sep 10, 2026
1 check passed
@PerryLink
PerryLink deleted the fix/permission-preset-session-shape branch September 10, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants