Back to home

omdsh-plugins

omdsh-status

Current project and its git state at a glance for the DeepSeek Harness web GUI: the project name with its branch and change counts, at the top-right corner of the Work window's conversation header

Stars
0
Language
TypeScript
Created
Aug 16, 2026
Updated
Aug 16, 2026

Introduction

omdsh-status

English | 中文

Which project, which branch, how much has moved — at a glance. This plugin puts the current conversation's project name and its git state in the conversation header of the DeepSeek Harness web GUI's Work window, just left of the Session log export button:

  omdsh-plugins   ⎇ main ↑1 +2 ~3 ?1    export

The project name is the title of the workspace the conversation lives in (the group heading you already read in the sidebar). Beside it: the checked-out branch, and whichever of ahead/behind, staged, modified, untracked, and conflicts are non-zero. A clean tree shows the branch alone; conflicts are the one count drawn in the alarm colour, because a row where every glyph shouts says nothing. The tooltip carries the full directory, every count in words, and why the figures are stale when a refresh failed.

What it adds

SurfaceWhere it comes from
The readout left of the Session log button in the conversation headerconversation.session.header.utilities, ui-conversation's trailing row — order: -1 keeps it left of the harness's default-order utilities
GET /omdsh-status/statuswebServer, behind the same browser-trust fence as the /api gateway

There is no settings namespace. Nothing here needs a person's decision — the project name is the workspace's own title, the git counts are the working directory's own state, and the poll cadence is fixed.

How the readout is assembled

Each half reads from whoever already knows:

  • The browser derives the project name. The page already holds the live workspace and session lists: find the workspace accounting for the current session, and its title is the project. Nothing is guessed or stored — the lists move, the readout follows.
  • The host runs git. A browser cannot read .git, so the host half resolves the session's working directory and runs git status --porcelain=v1 --branch --no-optional-locks, then answers with the parsed counts as JSON. No path list, no diff, no branch graph ever reaches the browser — only the handful of numbers it draws — and the route sits behind the same trust check as /api.

The poll is kept cheap: one directory's git answer is shared across every open page for two seconds, a visible page re-asks every four seconds, background tabs ask nothing, and cold sessions resolve their directory through the cached persistence listing.

When pieces are missing

  • The directory is not in a repository, git is not installed, or the command times out. The readout shows the project name alone, and the tooltip says "not a git repository". None of these are errors — "no git here" is the honest answer.
  • No conversation is selected, or it belongs to no workspace. The readout renders nothing; the blank state has no project to name yet.
  • Code mode has replaced the conversation column with a terminal. The header is gone, so the readout is too — it lives on the header, it does not chase windows. Switch back to Work and it returns.

Install

dsh plugin --profile web add @omdsh-plugins/omdsh-status

Or from a checkout — the form an unpublished build needs:

pnpm install && pnpm run build
dsh plugin --profile web add "$PWD"

Remove it the same way:

dsh plugin --profile web remove @omdsh-plugins/omdsh-status

Nothing here is a precondition. Every service either half injects — webServer, webRuntime, sessions on the host; slots, sessions, workspaces, locale on the page — is a harness service, and the seat registers through slots.inject. A profile with only this plugin installed starts and works: without a git repository it shows the project name alone, and without a conversation it shows nothing. Removing it takes the readout, the route, and the poll with it — the harness itself is untouched.

Commands

pnpm install
pnpm run build                                  # tsdown bundles the host and browser halves
pnpm run typecheck
pnpm run test
pnpm run harness:local <path-to-harness-checkout>   # while developing against a checkout
pnpm run harness:npm                                # back to the registry pin before committing
pnpm run check:harness-pin                          # fails while any harness dep is still linked

The pure logic (porcelain parsing, project derivation, polling rules, route behaviour) tests under plain node; the browser-side slot registration cannot run against a published harness pin because published packages ship no sources — that half is exercised under harness:local.

Known limitations

  • The seat is borrowed. The readout lives on the conversation header's trailing row, which the harness hides while a conversation is still blank and which Code mode replaces with a terminal. In both states the readout is simply not drawn — it degrades to nothing rather than to something wrong.
  • The counts are a poll, not a stream. A change shows up on the next poll, so the badge can be up to a few seconds behind the index, and a poll that fails keeps the previous figures dimmed until one succeeds.
  • "No git" is one wide net. Git not installed, a repository it refuses to touch (dubious ownership), or a git status that outlives its timeout all read as "not a git repository" — the tooltip does not distinguish them.