Skip to main content
E

dsh-session-bridge

elfgzp/dsh-session-bridge

Gives an agent tools to open foreground sessions, prompt them in queue or steer mode, read the transcript back, cancel a turn, and get the authenticated URL of the local web app.

Install

dsh plugin --profile web add github:elfgzp/dsh-session-bridge

README

dsh-session-bridge

Let a DeepSeek Harness agent open foreground sessions, drive them, and read the result back — and hand out the authenticated URL of the local web app.

Why

The Host already has everything needed: ctx.sessionController can create, prompt, inspect and cancel a session, and ctx.connection.authenticatedUrl() returns the web app URL carrying a launch token. None of it is reachable from a model tool.

Without this plugin, an agent that wants to verify something in a real foreground session has to:

  1. dig a dsh-auth-* cookie out of Chromium's cookie store — and guess which one matches the current port, because the token encodes authority: 127.0.0.1:<port>;
  2. reverse-engineer the /api/* RPC envelope and its _request argument shape;
  3. poke the DOM to get text into the composer, then read the rendered transcript.

Each of those is one tool call here.

Tools

ToolWhat it does
dsh_web_urlThe local web GUI URL. Masks the launch token by default; pass includeToken: true to get a browser-usable URL (requires the danger-full-access preset).
dsh_session_createCreate a foreground session. Returns its id.
dsh_session_promptSend a prompt to a session (queue or steer).
dsh_session_readRead a session's transcript. waitMs waits for the current turn to finish.
dsh_session_cancelCancel a session's running turn.

Token handling in dsh_web_url

The launch token minted by connection.authenticatedUrl() is a live credential: any browser that opens the URL gets an authenticated session. A tool result also lands in the conversation transcript, and from there into logs, exports and any copy of the chat.

So the default is maskToken: the tool returns origin plus a URL whose token is reduced to its first and last four characters. Pass includeToken: true only when something actually needs to open a browser, and do not persist or paste the result.

includeToken: true is gated on the caller's permission preset. The tool asks the permissionPresets service for the calling session's preset (current(session)) and resolves it to { sandbox, approval }. The plain token is only handed out when sandbox === "danger-full-access"; every other preset gets insufficient-permission plus the masked URL instead.

The gate fails closed. If permissionPresets is missing (older or headless deployments), if current() returns custom that resolve() cannot handle, if either call throws, or if execution.agent.session is unavailable, the answer is "no token" — never "allow".

Tests

npm test        # node --test test/*.test.mjs

lib/format.js holds the pure functions (maskToken, clip, reasonLabel, transcribe, waitForTurn); it imports nothing from the Host, so the suite runs on plain Node 20 with no dependencies. test/web-url.test.mjs wires a fake ctx through apply() to cover the permission gate, including all the fail-closed paths.

Foreground vs delegated

This is the part that matters. A foreground session is a root agent: it has the userQuestions service, so a plugin that needs human consent can actually ask. A delegated task (a subagent, a workflow agent) does not, and gets:

APP_APPROVAL_UNAVAILABLE: Application approval is unavailable in delegated tasks; ask the main task to perform this operation

So plugins like dsh-cua-macos can only be exercised end to end from a foreground session — which is exactly what these tools create.

Install

dsh plugin --profile <profile> add github:elfgzp/dsh-session-bridge

Restart DSH afterwards. The plugin has no dependencies.

Example

你手上有一个只能在前台会话里验证的功能。请:
1. 用 dsh_session_create 建一个会话
2. 用 dsh_session_prompt 让它做那件事
3. 用 dsh_session_read(waitMs=120000)把结果读回来

Notes

  • dsh_session_read truncates long text and returns at most maxMessages messages (default 40). Read a long session in pieces.
  • The transcript includes tool calls and their results, so a session that used other tools is still auditable from here.
  • dsh_web_url needs the webApp service; a headless deployment has none and the tool says so instead of failing.

License

MIT — see LICENSE.

Related plugins