omdsh-status
其他 活跃维护

omdsh-status

omdsh-plugins/omdsh-status

它是网页GUI工作窗口的常驻状态组件,固定于右上角展示当前项目名称、所在分支、代码变更数量等核心Git状态信息,无需跳转页面即可快速掌握项目基础状态,无冗余操作负担,信息获取高效直接。

0
Stars 标星
0
Forks 分支
0
Watchers 关注
0
Open Issues
TypeScript
主要语言
MIT
开源协议
243 KB
仓库大小
1 个月前
最后推送
一键安装扩展 / 插件指令
dsh plugin --profile web add github:omdsh-plugins/omdsh-status
git clone https://github.com/omdsh-plugins/omdsh-status.git
git clone git@github.com:omdsh-plugins/omdsh-status.git
README.md main

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.

A conversation that has not started yet has no header at all — the harness
hides it — so the same readout holds that row's own corner from the frame's
floating layer, on the same pixels, and hands them back the moment the header
returns:

                                    demo-project  ⎇ main ~1 ?1    ✦  Files  Terminal
                 Into the Unknown

        📁 demo-project ⌄   ⚙ Standard mode ⌄
  ┌──────────────────────────────────────────────┐
  │ Describe what you want to build              │

What it adds

Surface Where it comes from
The readout left of the Session log button in the conversation header conversation.session.header.utilities, ui-conversation's trailing row — order: -1 keeps it left of the harness's default-order utilities
The same readout holding that row's corner on a new session shell.overlay, ui-layout's frame-wide floating layer — the stand-in, for the conversations whose header the harness is not drawing
GET /omdsh-status/status webServer, 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 --no-optional-locks -C <dir> status --porcelain=v1 --branch, 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.
  • A new session gets the same answer, in the same place. The harness hides
    the whole session header while a conversation is still blank — which is
    exactly when the branch is worth knowing, since you are about to say what to
    do in this project. So a second entry stands in for that row from the frame's
    floating layer: the column's top-right corner, inset by the header's own
    measured padding, at the same row height, so the readout does not move when
    the header comes and goes. It stands down the moment the header entry
    announces itself, so the two never show at once — and that is read off the
    header entry's own mount rather than off "is the conversation blank", which
    is ui-conversation's rule to change, not this plugin's to copy.
  • That corner is shared, and packed without a registry.
    omdsh-sidepanel's switches hold its outer end and omdsh-sidechat's summon
    icon tucks in beside them; this readout is the utility row's leftmost entry,
    so its stand-in measures the occupant that has already tucked itself furthest
    IN and goes inboard of that. The neighbour measures the opposite end, so the
    dependency runs one way and the row settles in a single pass. Only boxes are
    read — never another plugin's code, state, or identity — and an empty corner
    is measured as empty: the readout takes the header's own padding.
  • A chat is not a project. When a mode system is composed
    (@omdsh-plugins/omdsh-basemode with @omdsh-plugins/omdsh-chatmode), a
    conversation it classifies as a chat gets no readout and no poll: its
    workspace is the managed one under the harness's own home, which is a
    directory the harness keeps rather than one anybody chose. The rule is read
    from sessionModes rather than re-derived, so the readout and the mode
    switch cannot disagree.

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. Both entries
    render nothing; there is no project to name yet.
  • Chat mode. The readout renders nothing and the poll stops: a chat names
    no project. Switch to Work and both return.
  • No mode system is composed. Nothing is a chat, so nothing hides — the
    readout behaves exactly as it did before the rule existed. sessionModes is
    read on a restricted fiber and never injected, so its absence costs this
    behaviour and nothing else.
  • Code mode has replaced the conversation column with a terminal. The
    header goes with it, and the stand-in declines rather than taking a corner
    that is now the terminal's own banner. No readout beats a readout over
    someone else's control; switch back to Work and it returns.

Install

npx @omdsh-plugins/omdsh-plughub add omdsh-status

That is the plugin hub's
installer with argv where the button was. It resolves this plugin from the
collection's registry, installs it
from its GitHub repository, and writes the pnpm build-allowlist entry a bare
dsh plugin add github:… would leave to you — the entry carries the commit pnpm
resolved, so it can be copied out of a failure and never written down in
advance.

dsh plugin --profile web add @omdsh-plugins/omdsh-status is not that command yet:
this package is not on npm, and pnpm answers ERR_PNPM_FETCH_404. The same
install is also a button, on this plugin's card in Settings → Plugins → Plugin
hub
, once the hub itself is in the profile.

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 both seats
register through slots.inject. The one companion service it reads,
sessionModes, is reached on a restricted fiber inside apply, so a profile
without a mode system boots normally and simply hides nothing. 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, the chat gate, polling
rules, route behaviour, and the corner arithmetic the stand-in places itself
by) 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.

tests/git.run.spec.ts is the one spec that spawns git, in a throwaway
repository it creates itself. It earns the milliseconds: a parser spec cannot
ask whether git accepts the command being run, and the released argv put
--no-optional-locks — an option of git, not of git status — after the
subcommand, so every read exited 129 and every repository read as "no git".

Known limitations

  • Both seats are borrowed. The readout lives on the conversation header's
    trailing row and, while that row is away, on the pixels it would occupy. Code
    mode replaces the whole column with a terminal and takes both with it; there
    the readout is simply not drawn, which degrades to nothing rather than to
    something wrong.
  • The stand-in lands where the row's live occupants are, not where the
    header's would be.
    The Session log export button sits between this readout
    and its neighbours in the drawn header, and that button has no stand-in of
    its own — it has nothing to export yet. So on a new session the readout sits
    the width of that button further right than it will once the header returns.
    Reserving space for a control nobody is drawing would be a guess; holding the
    row's height and corner is a measurement.
  • 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.