The previous pass aligned the observation overlay with the dsh shell; the
product call is the opposite direction — the floating card should read as a
BrowserSkill surface, not a shell-native widget.
- Reuse @browser-skill/ui directly (Button, cn); status dots spec'd after the
extension popup's ConnectionStatusIndicator; Remix icons for
interrupt/pin/warn/pop-out.
- Compile the BSK tailwind utility sheet scoped under the .bsk-obs root class
(scripts/build-client-css.mjs + postcss-prefix-selector) and ship the oklch
design tokens on the same scope, so nothing leaks into the host shell and
the shell theme cannot bleed back. tsdown injects .nomodule.css verbatim
(minified, unhashed) alongside the hashed CSS modules.
- BSK ships no shared tooltip, so the one-time interrupt semantics hint is a
card-spec bubble (bg-card/border/12px radius), retired after first use.
- Tests: pin react/react-dom to this package's 18.x copies in vitest — the ui
package sources peer on react ^19 and would otherwise emit react-19
(transitional) elements that the react-18 renderer rejects. Production is
unaffected (react stays external, provided by the shell).
- stylelint: ignore the generated bsk-ui.nomodule.css.
Make the package dual-face: a dsh.client declaration (platform 'web')
plus an exports["./client"] bundle built in dsh's closure-factory shape
(window.__ModuleLoader__.load handoff, platform modules external,
everything else inlined, CSS Modules via lightningcss).
The client registers a keyed 'tool.call.toolview' view for
browser_screenshot that keeps the terminal block (command + output) and,
when the settled result carries an image block, resolves the durable
attachment through the client session's authorized readAttachment RPC
and renders it with the shared MessageImage thumbnail/lightbox atoms.
Path-only results render unchanged; every other browser_* tool keeps
the stock terminal card.
Tests: view-model derivation (running/ok/error, image vs path-only),
component rendering through @testing-library/react + happy-dom, and the
registration key. biome.json now excludes the package's lib/ build
output (same treatment as dist/).
Add a new monorepo package that registers BrowserSkill (bsk) browser
automation as model-visible tools in DeepSeek Harness (dsh):
- 11 tools mapping to bsk CLI --json commands: session start/stop/list,
navigate, snapshot, observe, click, fill, press, screenshot, emulate
- multi-session support: optional session arg with a current-session
pointer, session id echoed in every result, configurable concurrency
cap (default 5), and dispose-time cleanup of plugin-started sessions
- cancellation: exec.signal aborts kill the underlying bsk child process
- terminal-style UI cards (command line as the call card, output as the
result card); screenshots inline the PNG through the host attachment
store when the model route accepts image input, else return the path
- config: bskPath / defaultTimeoutMs / maxSessions via Schemastery schema
- install guidance when the bsk binary is missing; bsk JSON error
envelopes (code/message/hint) surfaced to the model
- unit tests mock the bsk runner (no real browser required); the root
lint script now also runs the package's typecheck + tests so the
existing CI frontend job covers the new package (a dedicated CI job
diff is provided in the PR; the pushing token lacks workflow scope)