dsh-git-badge 0.19.0 → 0.20.0

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,139 @@ npm. 0.6.0 is the first release recorded here.
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [0.20.0] - 2026-10-13
14
+
15
+ ### Added
16
+
17
+ - **The session row shows its token as a leading glyph.** The node-half token
18
+ renders as a single glyph in the row's 16px leading cell, with the word as its
19
+ accessible name. It asks the same question the row card does (`pr=1`), so the
20
+ PR tokens `merge`, `review` and `fix CI` reach it too — not only the local
21
+ ones — and the two share one cache entry. With no token (clean and in sync) the
22
+ cell keeps the shared status mark. The seat is upstream's own
23
+ (`sidebar.session.row.leading`) — no patch and no install step.
24
+ - **The leading glyph explains itself on the row's hover card.** The node half
25
+ attaches the winning rule's reason as `rowTokenWhy`, and the session-row hover
26
+ card renders the action as a label/value row — the glyph, the word and the
27
+ reason (for example `↑ push — no upstream configured`) — beside the checkout
28
+ and the pull request. The chip card renders the SAME `action` row from one
29
+ shared helper, so the two cannot describe the icon differently.
30
+ - **New row tokens** for states the earlier table could not name: `resume` (a
31
+ paused operation), `resolve` (a PR that conflicts with its base), `review`
32
+ (changes requested, or a review required), `sync` (diverged), `update` (the
33
+ PR is behind its base) and `commit` (dirty work).
34
+ - **Two ranking categories: `conflict` and `review`.** Both are row-only —
35
+ no `/gh` verb covers them — so they triage the row without entering the
36
+ action list the picker offers. They join the Settings → Plugins → Git Badge
37
+ order card.
38
+
39
+ ### Changed
40
+
41
+ - **The session-row hover card leads with the action and names dirty work.** The
42
+ `action` label/value row is now the same header the chip card uses, and a
43
+ `changes` row appears when the checkout is dirty — so a higher-ranked token
44
+ (`push`, `review`, `merge`) can no longer hide uncommitted work. A clean row
45
+ keeps its short card. The `checkout` and `pull request` rows are unchanged.
46
+
47
+ - **The chip's hover card leads with the action and splits the merge row.** The
48
+ checkout verdict is now a heading (the token glyph, the word and the reason)
49
+ instead of an `action` label/value row, the server's suggestion is named
50
+ `next step` with a `▸` marker, `files` is renamed `changes`, and the merge row
51
+ is split into `state` (the pull-request verdict) and `base` (the ahead/behind
52
+ counts). A labelled `branch` divider separates the checkout rows from the
53
+ branch rows. Both cards still share one action sentence.
54
+
55
+ - **The node half is the single authority for the row's word.** `nextActions`
56
+ now returns `rowToken` alongside `actions` and `next`, and the route attaches
57
+ it to every status response. The client row reads that token instead of
58
+ re-deriving the rules, so the chip, the picker and the row cannot drift.
59
+ A stored order that predates the two new categories keeps its ranking, with
60
+ them appended (they rank last until reordered in Settings).
61
+ - **The node half is also the single authority for the icon's COLOUR.**
62
+ `nextActions` returns `rowSeverity` (`error`, `warn`, `success` or `business`)
63
+ with the token, and the route attaches it to every token-bearing response. The
64
+ client holds one severity-to-colour map instead of a token-to-colour map, so
65
+ the chip and the row agree about how loud a state is. No pixel changes: the
66
+ severity of each token keeps the colour that token had.
67
+ - **The glyph is the ONLY icon.** The drawn disc/tree mark is gone. Both surfaces
68
+ show the node half's token icon: the input chip at the head of its leading
69
+ cluster, the sidebar row in its 16px leading cell. A checkout with no token —
70
+ clean and in sync — draws NOTHING, because there is no action to name. The four
71
+ hairline tokens (`push`, `pull`, `sync`, `update`) are DRAWN as 12x12 arrows in
72
+ `currentColor`, because `↑ ↓ ⇄ ↻` are hairline strokes in the shell's font and no
73
+ weight makes them as solid as `✚ ✓ ✗ ◆`. The six text glyphs sit at 13px, and the
74
+ card's action-row glyph is bold for every token.
75
+ - **A session is never iconless: the `in sync` disc.** With no rule at all, the
76
+ node half returns `rowToken: "in sync"` plus a reason and a colour role, so the
77
+ chip and the row draw a disc and the card explains it. The colour carries the
78
+ merge fact: `success` (green) when no commit is ahead of the base, `warn` (amber)
79
+ when some are — so a clean but unmerged feature branch no longer reads as all
80
+ clear. Only a non-repository still returns null.
81
+ - **The idle disc's colour matches on every surface.** `mainAhead`/`mainBehind`
82
+ were detail-only, so the chip and the session row read a GREEN disc while the
83
+ chip's hover card read AMBER for the same checkout. The branch-vs-base relation
84
+ is cached (like the default branch) and attached to every response. The first
85
+ read may answer without it; the next one carries it.
86
+ - **The merge icon is Remix Icon `git-merge-line`.** `merge` no longer renders
87
+ the text check `✓`, which read as "done" rather than "merge". Unicode has no
88
+ merge glyph, so the icon is Remix Icon's artwork, vendored verbatim as inline
89
+ SVG and rendered at 16px — the branch-into-a-trunk shape that GitHub, VS Code,
90
+ Font Awesome and Material all use. No icon font is involved.
91
+ - **The chip card is ONE card.** The retired mark was the card's only anchor, so
92
+ the checkout's verdict rows and the branch's lineage rows merged into one card
93
+ on the leading cluster (glyph and branch together). Hovering either opens it,
94
+ and a clean checkout opens it from the branch name.
95
+ - **The PR token's state glyph is coloured.** The `✓`/`✗`/`…` that follows
96
+ `PR#142` takes the CI colour (green passing, red failing, amber running). The
97
+ number and the link keep the chip's own muted colour, so only the state shouts.
98
+ - **The install has one step again.** The session row no longer uses a patched
99
+ seat, so there is no `npx dsh-git-badge apply` and no `postinstall` hook. The
100
+ leading glyph and the hover card are upstream's own seats.
101
+ - **The chip card's picker row is `next`.** The `/gh` invocation moved out of the
102
+ `action` row, which now mirrors the icon. The chip's own-checkout row is
103
+ `own checkout`, so `checkout` names what a session-row card describes.
104
+ - **One word per action: `publish` is gone.** The no-upstream rule uses the
105
+ picker's verb `push`, so the chip and the row say the same word. The `publish`
106
+ RANKING CATEGORY keeps its name.
107
+
108
+ ### Fixed
109
+
110
+ - **The `push` suggestion no longer offers a command git refuses.** A branch
111
+ created from `origin/main` tracks `origin/main`, so a bare `git push` is
112
+ refused under the default `push.default=simple` because the upstream branch
113
+ name does not match the local branch name. The push rule now detects that
114
+ case and suggests `git push -u <remote> <branch>`, which publishes under the
115
+ branch's own name and repairs the upstream in one step. The `/gh push` skill
116
+ gained the same case.
117
+
118
+ ### Removed
119
+
120
+ - **The drawn status mark.** `StatusMark`, `badgeStatus`, `MARK_FILL` and
121
+ `STATUS_LABEL` are gone from the client, with the disc/tree geometry, the
122
+ three-state colour rule and the `git: <status>` accessible names. Worktree-ness
123
+ is named in the card's `worktree` row rather than drawn. With it went the
124
+ `mark`, `markShape` and `markFill` test helpers.
125
+ - **The seam patcher.** `seam/anchors.js`, `seam/patch.js`, `seam/stub-index.js`
126
+ and the patch half of `seam/apply.js` are gone, together with the repo's
127
+ `seam/` snapshots and its `apply.sh` / `make-patch.sh` wrappers. The package's
128
+ only CLI verb is `checkout` (`seam/cli.js` + `seam/checkout.js`): there is no
129
+ `apply`, `status` or `revert` to run.
130
+ - **The `dsh-git-badge-seam` bin.** No patcher answers to that name.
131
+ - **The `sidebar.workspaces.sessionRow` word pill.** It was the patch's only
132
+ consumer. The row now shows the token glyph in its leading cell on every
133
+ install, so there is no second surface and no seam to maintain.
134
+ - **The restart-pending marker** (`seamRestartPending` on the status response).
135
+ It existed only to tell the running UI that a patch had changed DSH files on
136
+ disk.
137
+ - **The `postinstall` script.** It applied the patch at install time; with no
138
+ patch needed it would only churn the user's DSH package.
139
+
140
+ ### Migration
141
+
142
+ - An install that an older version patched still works. To restore pristine
143
+ bytes, reinstall DSH (`npm i -g @deepseek-ai/dsh@latest`); the plugin has no
144
+ command for it any more. Nothing in the plugin needs the patch.
145
+
13
146
  ## [0.19.0] - 2026-10-12
14
147
 
15
148
  ### 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