Back to home@flykit-cc

dsh-flykit

flykit for DeepSeek Harness — explorer with live file watch, agent terminals (Claude Code, Pi, Codex), DSH agent tools, a searchable model picker and a Claude-Code-style status line. Fly your agents.

Stars
0
Language
TypeScript
Created
Sep 4, 2026
Updated
Sep 5, 2026
GitHub repo

Introduction

dsh-flykit

Fly your agents.

A plugin for DeepSeek Harness that turns the dsh web GUI into an agent cockpit: a file explorer with an editor, real coding-agent terminals, a searchable model picker, and a status line under the composer.

The dsh web window with the flykit panel open: file tree above, Markdown preview below, status line under the composer

What you get

Explorer — the session's file list (git ls-files, or a plain walk outside a repo), a CodeMirror editor that saves back to disk, Markdown and HTML/SVG preview, and a live fs.watch that refreshes the tree, dots changed files, and reloads an open file when it changes on disk (dirty files keep your edits and show a notice instead).

Explorer tab with a TypeScript file open in the editor

Agents — real PTY terminals in the session's workspace: Claude Code, Pi, Codex, or a plain shell, in an xterm view. A chime and a dot mark the tab when an agent stops printing after a burst of output; per-terminal mute. Claude subscription usage bars appear above a Claude Code terminal.

Agents tab running Claude Code with the Claude usage bars above it

Stage view — the focused agent fills the panel, the others sit under it as live thumbnails.

Stage view: focused Claude Code terminal with a Shell thumbnail below

Split mode — Agents stacked above Explorer, so a running terminal and an open file are visible at once. The panel also maximises to the full window.

Split mode: Agents above, Explorer below

Model picker — replaces the shell's model seat with a search box over the same directory /model uses, so both stay one state. Provider pills, favourites, recents, reasoning badges, an effort row for reasoning models, and a button that refreshes the OpenRouter catalog live.

Model picker filtered to "qwen", with provider pills and grouped results

Status line — idle / thinking / running tool, a turn timer, the session's git branch and dirty count. It also recolours the shell's context ring as the window fills.

The composer with the flykit status line under it

Agent tools — seven flykit_agent_* tools that let the DSH agent itself open, drive and read those terminals. See the table below.

Install

Not on npm yet. Install from GitHub:

dsh plugin --profile web add github:flykit-cc/dsh-flykit

Or from a checkout:

git clone https://github.com/flykit-cc/dsh-flykit
cd dsh-flykit
npm install && npm run build
dsh plugin --profile web add .

Check the layer landed, then start the GUI:

dsh --profile web --dump-config | grep flykit
dsh web

Remove it with dsh plugin --profile web remove dsh-flykit.

Requirements

  • Node ≥ 22
  • DSH 0.1.2-rc.1
  • macOS or Linux. The Agents tab uses node-pty, a native module; there is no Windows build here.
  • git on PATH for the branch segment and the Explorer's file list (without it, a plain directory walk).
  • claude, pi or codex on PATH for the terminals that run them. A missing binary just makes that terminal exit.

How it works

One package, two halves:

  • Host half (lib/index.js, a Cordis plugin) runs in the dsh process. It registers routes on DSH's web server under /api/flykit/*: git, files, file (GET/PUT), watch (SSE), terms, term/input, term/resize, term/screen, term/stream (SSE), claude-usage and catalog-sync. It also registers the seven agent tools, if the tool registry is present.
  • Client half (lib/client.js) is a CommonJS bundle the shell loads in the browser. It injects React components into the shell's slots and reaches the host over those routes with fetch and EventSource. Everything outside the shell's own platform modules is inlined, so the bundle is large.

The routes have no authentication. DSH's web server binds to loopback, and that is the only thing keeping them private — anything that can reach the port can call them, and term/input writes to a live shell. Two limits do apply: the working directory always comes from the session header, never from the request, and file reads and writes are confined below it. Do not expose dsh web on a public interface with this plugin installed.

Catalog sync writes your settings. If llm-pi-ai already has an openrouter provider configured, flykit fetches openrouter.ai's live model list three seconds after boot and once a day after that, and writes it to llm-pi-ai.providers.openrouter.models through the settings service — replacing whatever list is there. A short answer (under 50 models) is discarded rather than written, but there is no undo and no backup: backing up your settings is your job. With no openrouter provider configured, nothing is written.

Agent tools

Available to the DSH agent when dsh-tools is in the composition. Every tool is scoped to the calling session — one session never reaches another's terminals.

ToolWhat it does
flykit_agent_startOpen claude, pi, codex or shell in the session's workspace; returns once the TUI has drawn itself, so the first send is not swallowed.
flykit_agent_sendType text into a running terminal; presses Enter unless enter: false.
flykit_agent_readRead a terminal as plain text, colours and redraws resolved. sinceSeq returns only what is new.
flykit_agent_waitWait for the terminal to go quiet, then return what it printed. This is how an answer is collected.
flykit_agent_listList this session's terminals, running or exited.
flykit_agent_stopKill a terminal and remove it from the panel.
flykit_agent_runOne headless question to claude or pi in this workspace; no terminal, no follow-up.

Privacy

The usage bars read the Claude Code login already on this machine — the macOS Keychain entry Claude Code-credentials, or ~/.claude/.credentials.json elsewhere — and call Anthropic's usage endpoint from the host process. The OAuth token never leaves that process and is never sent to the browser; the browser receives only the plan name, the percentages and their reset times. With no Claude Code login present, the bars stay hidden.

The only other network call flykit makes is the OpenRouter catalog fetch described above. File contents, terminal output and git status stay between the dsh host process and your browser.

Development

npm install
npm run dev                         # tsdown --watch: client bundle hot-reloads
dsh plugin --profile web add .      # once
dsh web --port 3080 --no-open

Client bundle edits reload in the browser; host-half edits need dsh web restarted. npm run typecheck and npm test cover both halves — the test run also verifies the client bundle registers exactly one module and pulls in no non-platform imports.

Status

0.1.0, and rough in places:

  • Not published to npm yet; install from GitHub.
  • The routes are unauthenticated (see above).
  • Terminals live in the host process. Restarting dsh web kills them; scrollback is capped at 256 KiB per terminal.
  • The Agents tab polls the terminal list every two seconds rather than streaming it.
  • The file list stops at 5,000 entries and the editor refuses files over 2 MiB.
  • The editor is CodeMirror with syntax highlighting only: no language server, no diff view.
  • The model picker shadows the shell's shipped model seat. Removing the plugin restores it.

License

MIT. flykit.cc