dsh-git-badge 0.19.0 → 0.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,155 @@ npm. 0.6.0 is the first release recorded here.
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [0.20.1] - 2026-10-13
14
+
15
+ ### Fixed
16
+
17
+ - **The row's token survives a status dot.** Upstream mounts the leading seat
18
+ only while a row's primary state is idle, and gives the 16px cell to its own
19
+ solid status dot otherwise: green for an unread completion, orange for a
20
+ pending interaction. A busy session that went idle therefore showed the dot
21
+ until the session was opened, while its checkout already had something to say.
22
+ The plugin now rides the row-action strip — the one per-row seat React mounts
23
+ in every state, hidden by CSS rather than unmounted — and paints the node
24
+ half's token over the dot from that marker plus one injected stylesheet. The
25
+ cell still decides: the fallback appears only when a solid dot occupies it, a
26
+ running spinner is left alone, `in sync` never replaces the dot, and the mark
27
+ is removed the moment the real seat returns. No upstream byte changes.
28
+
29
+ ## [0.20.0] - 2026-10-13
30
+
31
+ ### Added
32
+
33
+ - **The session row shows its token as a leading glyph.** The node-half token
34
+ renders as a single glyph in the row's 16px leading cell, with the word as its
35
+ accessible name. It asks the same question the row card does (`pr=1`), so the
36
+ PR tokens `merge`, `review` and `fix CI` reach it too — not only the local
37
+ ones — and the two share one cache entry. With no token (clean and in sync) the
38
+ cell keeps the shared status mark. The seat is upstream's own
39
+ (`sidebar.session.row.leading`) — no patch and no install step.
40
+ - **The leading glyph explains itself on the row's hover card.** The node half
41
+ attaches the winning rule's reason as `rowTokenWhy`, and the session-row hover
42
+ card renders the action as a label/value row — the glyph, the word and the
43
+ reason (for example `↑ push — no upstream configured`) — beside the checkout
44
+ and the pull request. The chip card renders the SAME `action` row from one
45
+ shared helper, so the two cannot describe the icon differently.
46
+ - **New row tokens** for states the earlier table could not name: `resume` (a
47
+ paused operation), `resolve` (a PR that conflicts with its base), `review`
48
+ (changes requested, or a review required), `sync` (diverged), `update` (the
49
+ PR is behind its base) and `commit` (dirty work).
50
+ - **Two ranking categories: `conflict` and `review`.** Both are row-only —
51
+ no `/gh` verb covers them — so they triage the row without entering the
52
+ action list the picker offers. They join the Settings → Plugins → Git Badge
53
+ order card.
54
+
55
+ ### Changed
56
+
57
+ - **The session-row hover card leads with the action and names dirty work.** The
58
+ `action` label/value row is now the same header the chip card uses, and a
59
+ `changes` row appears when the checkout is dirty — so a higher-ranked token
60
+ (`push`, `review`, `merge`) can no longer hide uncommitted work. A clean row
61
+ keeps its short card. The `checkout` and `pull request` rows are unchanged.
62
+
63
+ - **The chip's hover card leads with the action and splits the merge row.** The
64
+ checkout verdict is now a heading (the token glyph, the word and the reason)
65
+ instead of an `action` label/value row, the server's suggestion is named
66
+ `next step` with a `▸` marker, `files` is renamed `changes`, and the merge row
67
+ is split into `state` (the pull-request verdict) and `base` (the ahead/behind
68
+ counts). A labelled `branch` divider separates the checkout rows from the
69
+ branch rows. Both cards still share one action sentence.
70
+
71
+ - **The node half is the single authority for the row's word.** `nextActions`
72
+ now returns `rowToken` alongside `actions` and `next`, and the route attaches
73
+ it to every status response. The client row reads that token instead of
74
+ re-deriving the rules, so the chip, the picker and the row cannot drift.
75
+ A stored order that predates the two new categories keeps its ranking, with
76
+ them appended (they rank last until reordered in Settings).
77
+ - **The node half is also the single authority for the icon's COLOUR.**
78
+ `nextActions` returns `rowSeverity` (`error`, `warn`, `success` or `business`)
79
+ with the token, and the route attaches it to every token-bearing response. The
80
+ client holds one severity-to-colour map instead of a token-to-colour map, so
81
+ the chip and the row agree about how loud a state is. No pixel changes: the
82
+ severity of each token keeps the colour that token had.
83
+ - **The glyph is the ONLY icon.** The drawn disc/tree mark is gone. Both surfaces
84
+ show the node half's token icon: the input chip at the head of its leading
85
+ cluster, the sidebar row in its 16px leading cell. A checkout with no token —
86
+ clean and in sync — draws NOTHING, because there is no action to name. The four
87
+ hairline tokens (`push`, `pull`, `sync`, `update`) are DRAWN as 12x12 arrows in
88
+ `currentColor`, because `↑ ↓ ⇄ ↻` are hairline strokes in the shell's font and no
89
+ weight makes them as solid as `✚ ✓ ✗ ◆`. The six text glyphs sit at 13px, and the
90
+ card's action-row glyph is bold for every token.
91
+ - **A session is never iconless: the `in sync` disc.** With no rule at all, the
92
+ node half returns `rowToken: "in sync"` plus a reason and a colour role, so the
93
+ chip and the row draw a disc and the card explains it. The colour carries the
94
+ merge fact: `success` (green) when no commit is ahead of the base, `warn` (amber)
95
+ when some are — so a clean but unmerged feature branch no longer reads as all
96
+ clear. Only a non-repository still returns null.
97
+ - **The idle disc's colour matches on every surface.** `mainAhead`/`mainBehind`
98
+ were detail-only, so the chip and the session row read a GREEN disc while the
99
+ chip's hover card read AMBER for the same checkout. The branch-vs-base relation
100
+ is cached (like the default branch) and attached to every response. The first
101
+ read may answer without it; the next one carries it.
102
+ - **The merge icon is Remix Icon `git-merge-line`.** `merge` no longer renders
103
+ the text check `✓`, which read as "done" rather than "merge". Unicode has no
104
+ merge glyph, so the icon is Remix Icon's artwork, vendored verbatim as inline
105
+ SVG and rendered at 16px — the branch-into-a-trunk shape that GitHub, VS Code,
106
+ Font Awesome and Material all use. No icon font is involved.
107
+ - **The chip card is ONE card.** The retired mark was the card's only anchor, so
108
+ the checkout's verdict rows and the branch's lineage rows merged into one card
109
+ on the leading cluster (glyph and branch together). Hovering either opens it,
110
+ and a clean checkout opens it from the branch name.
111
+ - **The PR token's state glyph is coloured.** The `✓`/`✗`/`…` that follows
112
+ `PR#142` takes the CI colour (green passing, red failing, amber running). The
113
+ number and the link keep the chip's own muted colour, so only the state shouts.
114
+ - **The install has one step again.** The session row no longer uses a patched
115
+ seat, so there is no `npx dsh-git-badge apply` and no `postinstall` hook. The
116
+ leading glyph and the hover card are upstream's own seats.
117
+ - **The chip card's picker row is `next`.** The `/gh` invocation moved out of the
118
+ `action` row, which now mirrors the icon. The chip's own-checkout row is
119
+ `own checkout`, so `checkout` names what a session-row card describes.
120
+ - **One word per action: `publish` is gone.** The no-upstream rule uses the
121
+ picker's verb `push`, so the chip and the row say the same word. The `publish`
122
+ RANKING CATEGORY keeps its name.
123
+
124
+ ### Fixed
125
+
126
+ - **The `push` suggestion no longer offers a command git refuses.** A branch
127
+ created from `origin/main` tracks `origin/main`, so a bare `git push` is
128
+ refused under the default `push.default=simple` because the upstream branch
129
+ name does not match the local branch name. The push rule now detects that
130
+ case and suggests `git push -u <remote> <branch>`, which publishes under the
131
+ branch's own name and repairs the upstream in one step. The `/gh push` skill
132
+ gained the same case.
133
+
134
+ ### Removed
135
+
136
+ - **The drawn status mark.** `StatusMark`, `badgeStatus`, `MARK_FILL` and
137
+ `STATUS_LABEL` are gone from the client, with the disc/tree geometry, the
138
+ three-state colour rule and the `git: <status>` accessible names. Worktree-ness
139
+ is named in the card's `worktree` row rather than drawn. With it went the
140
+ `mark`, `markShape` and `markFill` test helpers.
141
+ - **The seam patcher.** `seam/anchors.js`, `seam/patch.js`, `seam/stub-index.js`
142
+ and the patch half of `seam/apply.js` are gone, together with the repo's
143
+ `seam/` snapshots and its `apply.sh` / `make-patch.sh` wrappers. The package's
144
+ only CLI verb is `checkout` (`seam/cli.js` + `seam/checkout.js`): there is no
145
+ `apply`, `status` or `revert` to run.
146
+ - **The `dsh-git-badge-seam` bin.** No patcher answers to that name.
147
+ - **The `sidebar.workspaces.sessionRow` word pill.** It was the patch's only
148
+ consumer. The row now shows the token glyph in its leading cell on every
149
+ install, so there is no second surface and no seam to maintain.
150
+ - **The restart-pending marker** (`seamRestartPending` on the status response).
151
+ It existed only to tell the running UI that a patch had changed DSH files on
152
+ disk.
153
+ - **The `postinstall` script.** It applied the patch at install time; with no
154
+ patch needed it would only churn the user's DSH package.
155
+
156
+ ### Migration
157
+
158
+ - An install that an older version patched still works. To restore pristine
159
+ bytes, reinstall DSH (`npm i -g @deepseek-ai/dsh@latest`); the plugin has no
160
+ command for it any more. Nothing in the plugin needs the patch.
161
+
13
162
  ## [0.19.0] - 2026-10-12
14
163
 
15
164
  ### Fixed
package/README.md CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  Git status badges for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness):
4
4
 
5
- - **Input-row chip** — `● main ↑0 ↓2 ✎3` next to the access picker, showing the git state of the workspace the current conversation is attached to. Works on every install.
5
+ - **Input-row chip** — `✚ main ↑0 ↓2 ✎3` next to the access picker, showing the git state of the workspace the current conversation is attached to. The leading glyph is the action the node half picked; with no action the chip starts at the branch name. Works on every install.
6
6
  - **Hover card** — rest a pointer on the chip for what won't fit: the file breakdown (`✎3` split into staged / unstaged / untracked), the last ten commits, and the stash. Fetched only on hover, so the everyday badge pays nothing for it. Works on every install.
7
- - **PR / CI token** — `● main ↑0 ↓2 PR#142 ✗` when the branch has a GitHub pull request, read through your own `gh` CLI (the plugin never handles a credential). The token **links to the PR** — it opens in a new tab, and underlines when you hover or focus it. Invisible when `gh` cannot answer: not installed, not logged in, no GitHub remote, offline or rate-limited all render the unchanged chip, and a token with no URL to link to stays plain text.
8
- - **Worktree-aware** — a conversation's directory is fixed when it is created, so a conversation that does its work in a linked `git worktree` would otherwise keep reporting the main checkout. The session registers its checkout (`npx dsh-git-badge checkout <path>`, run by the git-worktree and `/gh checkout` paths), and the badge describes **that worktree** instead — its branch, counts, tree mark and PR/CI token (`🌳 chore/global-skills-tiering ↑0 ↓2 PR#391 ✓` rather than `● main`). The hover card names the tree in a `worktree` row and adds a `checkout` row with the conversation's own directory, so the main checkout's branch and dirty state stay one hover away. Registrations are advisory: git's own worktree list validates the path, entries expire after 24h, and a workspace-targeted row always reports the checkout the registry owns.
9
- - **Sidebar session-row action token** — each session row shows the ONE thing that conversation needs from you, or nothing at all: `merge`, `fix CI`, `review`, `resolve`, `pull`, `push`. It is triage rather than status: `merge` appears only when GitHub itself reports `mergeStateStatus: CLEAN`, and every waiting state (draft, blocked, behind, checks still running) stays silent. Hovering the row adds a line naming the checkout and the pull request the action refers to. The token floats to the right of the row, is set heavier than the timestamp beside it, and is coloured by how much it needs you — red for a conflict or a failing build, amber for a requested review, green for `merge`, quiet grey for routine sync. It appears only when the session is **idle** — while a turn is running the row stays quiet, because the checkout is still moving and a suggestion would describe a state that is about to change. Requires the `sidebar.workspaces.sessionRow` seam for the row token itself; without it the row stays bare and the plugin logs what's active to the browser console. The hover-card line does **not** need the patch — it renders through upstream's own `sidebar.session.row.hover` seat.
10
- - **Nothing on workspace rows.** A workspace cannot know which worktree its conversations are using, so a per-workspace badge could only guess or report the main checkout. The seam is on the session row for that reason.
7
+ - **PR / CI token** — `✚ main ↑0 ↓2 PR#142 ✓` when the branch has a GitHub pull request, read through your own `gh` CLI (the plugin never handles a credential). The token **links to the PR** — it opens in a new tab, and underlines when you hover or focus it. Invisible when `gh` cannot answer: not installed, not logged in, no GitHub remote, offline or rate-limited all render the unchanged chip, and a token with no URL to link to stays plain text.
8
+ - **Worktree-aware** — a conversation's directory is fixed when it is created, so a conversation that does its work in a linked `git worktree` would otherwise keep reporting the main checkout. The session registers its checkout (`npx dsh-git-badge checkout <path>`, run by the git-worktree and `/gh checkout` paths), and the badge describes **that worktree** instead — its branch, counts and PR/CI token (`chore/global-skills-tiering ↑0 ↓2 PR#391 ✓` rather than `main`). The hover card names the tree in a `worktree` row and adds an `own checkout` row with the conversation's own directory, so the main checkout's branch and dirty state stay one hover away. Registrations are advisory: git's own worktree list validates the path, entries expire after 24h, and a workspace-targeted row always reports the checkout the registry owns.
9
+ - **Sidebar session-row action glyph** — each session row shows the ONE thing that conversation needs from you: `resume`, `resolve`, `sync`, `pull`, `update`, `push`, `merge`, `commit`, `review`, `fix CI`, or `in sync` when there is nothing to do. The node half is the single authority: it ranks the rules and attaches a `rowToken` and its `rowSeverity` to every status response, so the chip, the picker and the row cannot drift. It is triage rather than status: `merge` appears only when GitHub itself reports `mergeStateStatus: CLEAN`, and every waiting state (draft, blocked, checks still running) stays silent. The token renders as a single coloured icon, in the row's 16px leading cell and at the head of the input chip: red for a conflict, a paused operation or a failing build, amber for a requested review, green for `merge`, quiet blue for routine sync, and amber for the `in sync` disc when commits are not yet merged. It appears only when the session is **idle** — while a turn is running upstream shows its own status dots there, because the checkout is still moving and a suggestion would describe a state that is about to change. With nothing to do the node emits `in sync`, so a session is never iconless: a disc in both surfaces, green when the branch is the default branch or its work is merged, amber when commits are not yet merged. The same hover card explains it. Hovering the row opens the row's usual hover card, which renders the action as a label/value row — the icon, the word and the reason (`↑ push — no upstream configured`) — beside the checkout and the pull request. **No patch and no install step:** the glyph rides upstream's own `sidebar.session.row.leading` seat, and the explanation rides `sidebar.session.row.hover`, so both work on a pristine install.
10
+ - **Nothing on workspace rows.** A workspace cannot know which worktree its conversations are using, so a per-workspace badge could only guess or report the main checkout. The token is on the session row for that reason.
11
11
 
12
- The leading **mark** belongs to the input chip: a circle filled with the status colour, or a **tree** when the checkout is a linked `git worktree`. The sidebar row deliberately carries no mark — see the row bullet above, where one word does the job a colour cannot. (`●`/`🌳` stand in for it here — it is a drawn SVG so that it can take the theme's status colours.)
12
+ There is no drawn status mark: the leading **icon** is the node half's action token, and its colour is the severity. The same icon leads the input chip and the session row's 16px cell. Four tokens are drawn arrows, the idle verdict is a drawn disc, and the rest are text glyphs. The card's `worktree` row names a linked checkout.
13
13
 
14
14
  Event-driven freshness: working trees are watched and updates push over SSE — badges flip within ~1s of any commit, stage, or edit, including inside a linked worktree the session registered. One `git status --porcelain=v2` per sample, shared by every surface pointing at the same checkout, plus at most one `gh` read per repository-and-branch per ~20s. The status API takes **no path**: the caller passes a session id (chip and sidebar rows) or a workspace id, and the server resolves the directory itself.
15
15
 
@@ -25,7 +25,15 @@ dsh plugin --profile web add dsh-git-badge
25
25
 
26
26
  Restart the web process, refresh the browser. Requires Node ≥ 20 and `git` on PATH. `gh`, on PATH and authenticated, is optional — it only enables the PR/CI token.
27
27
 
28
- Seam details: [github.com/Kevin-McIsaac/dsh-workspace-git-badge](https://github.com/Kevin-McIsaac/dsh-workspace-git-badge) (SEAM.md / PR.md).
28
+ **No seam patch.** `npx dsh-git-badge checkout <path>` (or the
29
+ `dsh-git-badge-checkout` bin) is the only CLI verb: it registers the checkout a
30
+ session is working in, so the badge follows a linked worktree.
31
+
32
+ ## Sidebar technical details
33
+
34
+ Both surfaces ride upstream seats: the status icon on
35
+ `sidebar.session.row.leading` (a 16px, idle-only cell), the hover card on
36
+ `sidebar.session.row.hover`.
29
37
 
30
38
  ## Changelog
31
39