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 +165 -0
- package/README.md +2 -2
- package/lib/client.js +604 -72
- package/lib/index.js +387 -187
- package/package.json +8 -3
- package/seam/checkout.js +82 -0
- package/seam/store.js +66 -1
- package/skill/gh/SKILL.md +46 -0
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.
|
|
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
|
|
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) —
|