Host half (src/index.ts): /sidebar/api JSON API (session cwd, fs tree/read/ write, git status/diff/stage/commit/branch/log/show), /sidebar/file media route, /sidebar/ws/terminal WebSocket over node-pty; routes share the /api trust fence (Host-header loopback or connection.trustedHosts). Client half (src/client): portal-mounted right panel with a per-session split-pane workbench (recursive row/col splits, draggable dividers, tab drag-move), tab bar with max-width 160px + plus-menu (explorer/git/terminal multi-open rules), lazy file explorer rooted at the session cwd, editable text editor (dirty dot, Ctrl/Cmd+S), image + Markdown preview, xterm terminal with reconnect, and a VSCode-style git panel. Per-session state persists to localStorage (dsh-sidebar:v1:<sessionId>). Intercepts the chat turn-tail produced-files row (priority -1 chain entry) to open files in the sidebar. UI styled with the dsh --dsw-* theme tokens and ui-primitives. Build: tsdown emits the host lib plus the __ModuleLoader__ client bundle (externals = module table words; xterm/css inlined). Tests: 19 unit + smoke specs (pure state/tree/git parsers + real git/fs integration).
37 lines
1.2 KiB
TypeScript
37 lines
1.2 KiB
TypeScript
/**
|
|
* Client half of dsh-better-sidebar: mounts the right sidebar portal and
|
|
* registers the turn-tail interception. Requires the runtime's slots and
|
|
* sessions services; the bundle itself is a module-table consumer only
|
|
* (react + ui-primitives + xterm, all provided or inlined).
|
|
*/
|
|
import { createRoot } from 'react-dom/client'
|
|
import type { Context } from '../context-types.ts'
|
|
import { Sidebar } from './Sidebar.tsx'
|
|
import { registerTurnTailInterception } from './intercept.tsx'
|
|
|
|
/** Services required before mounting (provided by the client runtime). */
|
|
export const inject = ['slots', 'sessions']
|
|
|
|
/**
|
|
* Client plugin body.
|
|
* @param ctx - the client cordis context (slots, sessions).
|
|
*/
|
|
export function apply(ctx: Context): void {
|
|
ctx.effect(() => {
|
|
const host = document.createElement('div')
|
|
host.setAttribute('data-dsh-better-sidebar', '')
|
|
document.body.appendChild(host)
|
|
const root = createRoot(host)
|
|
root.render(<Sidebar ctx={ctx} />)
|
|
return () => {
|
|
root.unmount()
|
|
host.remove()
|
|
}
|
|
}, 'dsh-better-sidebar: sidebar mount')
|
|
|
|
ctx.effect(
|
|
() => registerTurnTailInterception(ctx),
|
|
'dsh-better-sidebar: turn-tail interception',
|
|
)
|
|
}
|