fix(client): session jump must navigate through uiWorkspace, not the removed sessions.open - #37
Merged
Conversation
…ions.open DSH 0.1.6 removed the 'sessions' service's open() selector — the ISessions contract now reads 'navigation belongs to view owners', and the only supported navigation entry is uiWorkspace.openSession(target). Every jump on a 0.1.7 runtime therefore read an undefined method and called it; the TypeError was swallowed by the jumper's catch into a bare 'unavailable' verdict, so the '🤖 跳转会话' button silently did nothing on every recent DSH. - session-jump: resolve the navigation entry structurally — uiWorkspace first (0.1.6+), legacy sessions.open only while it actually exists, 'unavailable' only when neither is present. sessions.open is now declared optional. - client entry: pass the uiWorkspace accessor (still resolved per click, so a late-provided service cannot be captured as undefined). - tests: regression guard that drives the jumper against a runtime-shaped sessions service with no open() key and asserts it still opens. Verified end to end: 352/352 suite, tsc clean, and the bundle the running GUI actually serves was extracted from its HTTP response and exercised against both runtime shapes (0.1.7 and legacy 0.1.5).
1254087415
pushed a commit
to 1254087415/dsh-taskboard
that referenced
this pull request
Sep 26, 2026
上游 8 个 commit(v0.8.1 → v0.8.3): - cloader#33 执行开场注入改用看板自身的 source kind(适配 DSH 0.1.7-rc.2 的 v4 会话格式) - cloader#35 定期任务完成策略(默认「完成后新建待办」) - cloader#37 会话跳转改走 uiWorkspace.openSession(sessions.open 在 DSH 0.1.6+ 已移除) - cloader#38 台账写入拒绝用旧快照覆盖新文件;cloader#39/cloader#40 结算与认领超时判定修正 - devDeps 升到 0.1.7-rc.2 冲突解决(仅 2 处源码,其余 lib/* 由 npm run build 覆盖): - src/client/index.ts:保留本 fork 的 mountSessionCardLinks 接线,同时引入上游的 UiWorkspaceFace / getUiWorkspace - src/shared/version.ts:采用上游 0.8.3 本地 5 项增强逐项核对保留:会话自动跟踪、会话导入、会话↔卡双向跳转、 侧边栏 4 数字统计、Agent 协议纪律 9/10。 测试:360/360 通过(本机 Node 26 需 NODE_OPTIONS=--localstorage-file 才不会被 Node 自带的 localStorage 全局遮住 jsdom 实现)。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On every dsh runtime since 0.1.6 (including the current
0.1.7-rc.2), the🤖 跳转会话 ↗button and the session-jump affordances on cards, chips, and execution rows do nothing. The click reports:…even though the session is live and visible in the sidebar.
Root cause
src/client/session-jump.tsresolves the runtimesessionsservice and callssessions.open(id). That selector no longer exists: the ISessions contract in 0.1.7-rc.2 statesVerified across releases:
@deepseek-ai/dsh-api-session-controllerISessions.open(id)open(id: SessionId): void("Select a session as current.")Reading a method the service no longer ships yields
undefined, and calling it throws. The jumper's owntry { … } catch { return 'unavailable' }then swallows the TypeError into a bare "navigation unavailable" verdict — so the removal degraded silently instead of failing loud.The supported navigation entry is
uiWorkspace.openSession(target)("Select a Session and show its Conversation as one UI navigation action").Fix
Resolve the navigation entry structurally instead of assuming a method exists:
SessionsServiceFace.openis now optional, andgetUiWorkspaceis an optional accessor, so existing callers (and the existing tests that inject only two accessors) keep compiling. The legacy path is retained for older runtimes rather than dropped.unavailablenow means "this runtime provides no navigation entry" — a real verdict, not a swallowed exception.applymust not be captured asundefined).lib/client.jsrebuilt.Verification
sessionsservice that has noopenkey at all. Before the fix it fails withexpected 'unavailable' to be 'opened'; after, it passes.npm test: 352/352 pass (24 files).tsc --noEmitclean.npm ci && npm run build && npm test(the CI pipeline) run on a clean clone: build reproduces the committedlib/client.jsbyte-for-byte, leaves the tree clean, tests green.mainproven to be exactly two edits — thenavigate()helper and the third accessor at the call site — nothing incidental.open,uiWorkspacepresent → opens; legacy:sessions.openonly → opens) plus the archived/missing/unavailable verdicts.Note for older runtimes
The legacy
sessions.openbranch is deliberately kept, so this fix is additive for 0.1.5-era hosts and is not a breaking change for thedshReleasescompatibility matrix.