dsh-git-badge 0.14.1 → 0.16.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,171 @@ npm. 0.6.0 is the first release recorded here.
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [0.16.0] - 2026-09-16
14
+
15
+ ### Added
16
+
17
+ - **A session now tells the badge which checkout it is working in.** dsh cannot
18
+ supply that fact — a session's `cwd` is immutable creation metadata and always
19
+ the main checkout — so the agent registers it explicitly:
20
+ `npx dsh-git-badge-checkout <path>` (shipped bin), run by the `git-worktree`
21
+ skill after `git worktree add` and by `/gh checkout` when a switch lands in or
22
+ out of a linked worktree. The node half prefers the registration, and
23
+ validates it: git's own worktree list must know the path, the entry expires
24
+ after 24h, and the name/branch come from git, never from the file. The
25
+ registration is self-clearing — removing it (or letting it expire) retires the
26
+ extra watcher and the badge returns to the session's own directory.
27
+
28
+ - **A settings card for the ranking order: Settings → Plugins → Git Badge.**
29
+ The order now lives in this plugin's own `git-badge` settings namespace —
30
+ declared with a schema, validated and stored by the host, observed live — and
31
+ the card reorders the seven categories with up/down controls, Save/Discard,
32
+ and Reset to default. No file polling, no restart: a change applies to the
33
+ next status read. A pre-existing `~/.dsh/git-badge-next.json` seeds the
34
+ namespace as its base (and remains the fallback on hosts without the settings
35
+ stack), so an order configured before the card existed survives the upgrade.
36
+ `/gh order` still works for agent-driven changes.
37
+
38
+ ### Changed
39
+
40
+ - **The ranking card sits in an expander, like the host's other plugin cards.**
41
+ Collapsed by default with the title and a one-line description; the list,
42
+ reorder controls, and Save/Discard/Reset live in the body, which auto-collapses
43
+ once a save settles clean. The card chrome reproduces the host's plugin-card
44
+ values inline (its CSS module is not exported to plugins), so it reads as one
45
+ of the set rather than loose content between it.
46
+
47
+ - **PR inference is gone.** The badge no longer guesses a worktree from the
48
+ branch with an open pull request. The guess was invisible to the session that
49
+ made it and silently wrong whenever two trees were in play; a `worktreeInferred`
50
+ marker, the repository-wide `gh pr list` read that powered it, and the
51
+ inference wording in the hover all go with it. A session follows its
52
+ registration or stays on its own checkout — nothing else.
53
+
54
+ ## [0.15.0] - 2026-09-15
55
+
56
+ ### Changed
57
+
58
+ - **Internal polish, no behaviour change:** the `detail=1` hover reads run in
59
+ one parallel batch (hover latency is the longest call, not the sum of seven
60
+ serial git spawns), the path-shortening and remote-URL conversion moved into
61
+ named helpers, and the three hover bodies share one row builder.
62
+
63
+ ### Added
64
+
65
+ - **Merge-blocker phrasing in the branch hover.** A `BLOCKED` verdict says why
66
+ — `blocked: review required`, `blocked: checks failing`, `blocked: draft` —
67
+ combined with the ahead/behind-main counts when both apply, so a dead-end
68
+ word names the next action. CLEAN stays silent: the action row already
69
+ offers `/gh merge`.
70
+
71
+ - **Staged names in the count's hover.** The stacked column gains a `staged:`
72
+ section above `unstaged` and `untracked`, completing the ✎n story — and
73
+ pairing with `/gh commit` when work is already staged.
74
+
75
+ - **Two new `gh` verbs:** `/gh stash pop` (shows the top stash's subject,
76
+ confirms, and on conflict reports that the stash was NOT dropped) and
77
+ `/gh checkout <branch>` (states what is dirty and confirms when work would
78
+ carry over).
79
+
80
+ ### Added
81
+
82
+ - **Unstaged names join the count's hover.** The ✎n tooltip stacks one column
83
+ with two sub-headers — `unstaged` (tracked, edited files; valid regardless of
84
+ the collapsed-untracked retry) above `untracked` — each capped at 20 with the
85
+ same last-two-segments shortening and "… and k more" arithmetic. The picker
86
+ question "what are these?" now answers for both halves of the count.
87
+
88
+ - **The branch hover gains a merge-state row.** `main: N ahead, M behind`
89
+ against `origin/main` — in words, deliberately distinct from the upstream
90
+ sync arrows: "3 ahead, 0 behind" reads as "this is the PR's content";
91
+ "0 ahead, 5 behind" as "stale, rebase first". Absent entirely when in sync.
92
+
93
+ - **The branch hover's commit list is signed and base-relative.** One mixed
94
+ list from `main...HEAD`: entries marked `+` are only on this branch (the
95
+ PR's content), `\u2212` only on main (what a rebase/merge brings in) — git's
96
+ own left-right verdict mapped onto the diff convention, sign before the
97
+ hash. Capped at 10 with the total from the same base; without a default
98
+ branch it degrades to the plain last 10, unsigned.
99
+
100
+ - **A commits hover on the branch name.** Hovering the branch lists the
101
+ COMMITS THIS BRANCH ADDS (`log <upstream>..HEAD`) — hash + subject + age,
102
+ capped at 10 with the total from one `rev-list --count` so "… and k more" is
103
+ arithmetic — not the card's last-three-overall list. Hover-gated with the
104
+ rest of `detail=1`; absent when the branch adds nothing (no tooltip rather
105
+ than an empty one) and when there is no upstream (the publish suggestion
106
+ covers that case).
107
+
108
+ ### Changed
109
+
110
+ - **The hover surfaces have one information architecture.** The branch name's
111
+ hover is the branch's LINEAGE and always renders: `upstream`, `sync` (in
112
+ words, "in sync with upstream" when clean), the commits this branch adds,
113
+ and the pull request when one exists. The status card loses its branch,
114
+ upstream, sync and pull-request rows — the branch name is the chip's own
115
+ text, and lineage facts belong beside the lineage surface — keeping action,
116
+ files, operation, worktree, checkout and stash.
117
+
118
+ - **The status card no longer repeats what the other hovers own.** Its commits
119
+ row and untracked-names row are gone — commit listings live on the branch
120
+ name's hover, untracked names on the count's hover, and the server stopped
121
+ fetching the unused last-three-commits on every detail read. The card keeps
122
+ action, branch, upstream, sync, files, operation, PR, worktree, checkout,
123
+ stash.
124
+
125
+ ### Added
126
+
127
+ - **A names-only hover on the ✎n count.** The count gets its own tooltip —
128
+ just the untracked list (one name per line, "… and k more"), no action row —
129
+ while the full card stays on the status mark. It shares the mark's lazy
130
+ detail fetch (resting on either triggers it once) and degrades to a plain
131
+ count without the Tooltip primitive or when nothing is untracked.
132
+
133
+ ### Added
134
+
135
+ - **Untracked file names in the hover card.** The `✎n` count becomes
136
+ answerable — "what did I create here?" — with a `untracked:` row listing the
137
+ names, hover-gated with the rest of `detail=1` (computed when the card opens,
138
+ refreshed by the existing SSE invalidation; no per-edit cost). Posture: the
139
+ plugin's never-display-a-path rule is relaxed by an inch, not a mile —
140
+ RELATIVE names only, truncated to the last two path segments, capped at 20
141
+ with the total carried separately so "… and k more" is arithmetic, not a
142
+ guess. Collapsed-count payloads (huge untracked trees) omit the field
143
+ entirely rather than under-report with directory names.
144
+
145
+ ### Changed
146
+
147
+ - **A smarter next-action state machine.** `nextStep` now ranks rule
148
+ candidates by category instead of first-match, and two new rules join the
149
+ table: a **diverged** branch (ahead AND behind) suggests `/gh sync` —
150
+ rebase-then-push, with the force-push confirmed by you — instead of a plain
151
+ pull that would discard the local-commit context; and a **merge-ready** PR
152
+ (GitHub's own `mergeState: CLEAN`, or checks passing + review approved)
153
+ suggests `/gh merge <n>` — the endgame action the old table could never see.
154
+ - **Configurable ranking via `/gh order`.** The category order is one line of
155
+ JSON at `~/.dsh/git-badge-next.json`
156
+ (`{"order": ["operation","unmerged","sync","publish","merge","commit","checks"]}`);
157
+ any subset in any order, unlisted categories rank after in default order.
158
+ The `gh` skill gains the `sync`, `merge <n>` and `order` verbs — say
159
+ "/gh order commit first" and the agent edits the file. The server's ranked
160
+ `next` now carries the skill `args` directly, so the hover card and the (+)
161
+ picker lead with exactly what the server decided and only add secondary
162
+ actions around it.
163
+
164
+ ## [0.14.1] - 2026-09-15
165
+
166
+ - **Skill alignment:** the `gh` skill gains an explicit handoff — one verb per
167
+ invocation is its whole job; the multi-step PR lifecycle (review, merge,
168
+ verify, cleanup) belongs to the `gh-pr` skill. The `gh-pr` skill states the
169
+ mirror scope: one-shot verbs are `gh`'s, lifecycle is its own. The catalog
170
+ stays global-only; repo conventions stay in `AGENTS.md`.
171
+
172
+ - **The hover card is 33% wider** (360px → 480px) and its `action:` row now
173
+ carries a trailing what-comment in git-comment convention — e.g.
174
+ `action: /gh push # push local commits to the remote` — so the row says
175
+ what the invocation does, not just which invocation it is. The picker in the
176
+ (+) menu shares the same descriptions.
177
+
13
178
  ## [0.14.1] - 2026-09-15
14
179
 
15
180
  ### Changed
package/README.md CHANGED
@@ -5,13 +5,13 @@ Git status badges for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek
5
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.
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 three commits, and the stash. Fetched only on hover, so the everyday badge pays nothing for it. Works on every install.
7
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. When exactly one linked worktree of that repository has an open pull request, 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, says it was inferred, and adds a `checkout` row with the conversation's own directory, so the main checkout's branch and dirty state stay one hover away. One candidate only — two open PRs across worktrees is a reason to say nothing rather than guess — and a session row always reports the checkout that session is working in.
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
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. Requires the `sidebar.workspaces.sessionRow` seam; without it the plugin degrades to chip-only and logs what's active to the browser console.
10
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.
11
11
 
12
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.)
13
13
 
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 that is only inferred. 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 ~90s and one repository-wide open-PR list per ~90s. 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.
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 ~90s. 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
 
16
16
  Diagrams, the hover card's full field list and a walkthrough for git newcomers live
17
17
  in the [repo README](https://github.com/Kevin-McIsaac/dsh-workspace-git-badge) —