dsh-git-badge 0.17.2 → 0.17.4
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 +37 -1
- package/README.md +1 -1
- package/lib/index.js +16 -1
- package/package.json +2 -1
- package/seam/apply.js +21 -6
- package/seam/checkout.js +7 -3
- package/skill/gh/SKILL.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,41 @@ npm. 0.6.0 is the first release recorded here.
|
|
|
10
10
|
|
|
11
11
|
## [Unreleased]
|
|
12
12
|
|
|
13
|
+
## [0.17.4] - 2026-09-18
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **The documented patcher command finally runs.** Every prompt the product
|
|
18
|
+
shows — the input-chip tooltip, the postinstall hint, the README — says
|
|
19
|
+
`npx dsh-git-badge apply`, and every one of them failed with
|
|
20
|
+
"could not determine executable to run": npm's npx auto-runs a bin only when
|
|
21
|
+
the bin's name matches the package name, and the package shipped two bins
|
|
22
|
+
(`dsh-git-badge-seam`, `dsh-git-badge-checkout`) that did not match. The
|
|
23
|
+
0.9.1 note below claimed npx runs a package's single bin under its own name —
|
|
24
|
+
wrong npm behavior, shipped untested; `npx dsh-git-badge-seam` fared no
|
|
25
|
+
better (404 — no *package* carries that name; npx resolves package names,
|
|
26
|
+
then looks up a bin inside them). The fix is the alias the prompts always
|
|
27
|
+
assumed: bin `"dsh-git-badge": "seam/apply.js"`. The alias also multiplexes
|
|
28
|
+
the checkout bin (`npx dsh-git-badge checkout <path|--clear>` dispatches to
|
|
29
|
+
`seam/checkout.js`), because npx cannot reach a package's second bin by
|
|
30
|
+
name at all — so the gh skill, the README and checkout's own usage text now
|
|
31
|
+
name the working form everywhere the old `dsh-git-badge-checkout` spelling
|
|
32
|
+
appeared. The legacy bins stay for direct invocation.
|
|
33
|
+
|
|
34
|
+
## [0.17.3] - 2026-09-17
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- **The default branch is now detected when `refs/remotes/origin/HEAD` is
|
|
39
|
+
missing.** `defaultBranchFor` read only that symref, so in a repo that has
|
|
40
|
+
none — `git clone --branch <x>`, a pruned ref, or any repo that was only ever
|
|
41
|
+
pushed to — it answered "no default branch" forever. Every default-branch rule
|
|
42
|
+
was therefore silently inert: the 0.17.2 merge row on `main` still said
|
|
43
|
+
`no pull request`, and the node half still suggested opening a pull request
|
|
44
|
+
FROM the default branch. The lookup now falls back, network-free, to the base
|
|
45
|
+
branch this module already probes (`origin/main`, then `origin/master`); a
|
|
46
|
+
repo whose default is neither still answers `undefined`, exactly as before.
|
|
47
|
+
|
|
13
48
|
## [0.17.2] - 2026-09-17
|
|
14
49
|
|
|
15
50
|
### Fixed
|
|
@@ -722,7 +757,8 @@ npm. 0.6.0 is the first release recorded here.
|
|
|
722
757
|
- `detail=1` is annotated as having no consumer yet (the hover card remains
|
|
723
758
|
pending). Its comment previously claimed `log -1` while the code ran `log -3`.
|
|
724
759
|
|
|
725
|
-
[Unreleased]: https://github.com/Kevin-McIsaac/dsh-workspace-git-badge/compare/v0.17.
|
|
760
|
+
[Unreleased]: https://github.com/Kevin-McIsaac/dsh-workspace-git-badge/compare/v0.17.3...HEAD
|
|
761
|
+
[0.17.3]: https://github.com/Kevin-McIsaac/dsh-workspace-git-badge/releases/tag/v0.17.3
|
|
726
762
|
[0.17.2]: https://github.com/Kevin-McIsaac/dsh-workspace-git-badge/releases/tag/v0.17.2
|
|
727
763
|
[0.17.1]: https://github.com/Kevin-McIsaac/dsh-workspace-git-badge/releases/tag/v0.17.1
|
|
728
764
|
[0.17.0]: https://github.com/Kevin-McIsaac/dsh-workspace-git-badge/releases/tag/v0.17.0
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ 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 ten 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. The session registers its checkout (`npx dsh-git-badge
|
|
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. 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; 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
|
|
package/lib/index.js
CHANGED
|
@@ -263,7 +263,22 @@ function defaultBranchFor(toplevel, notify) {
|
|
|
263
263
|
serve: (state) => state.value
|
|
264
264
|
}, async (record) => {
|
|
265
265
|
const out = await runGit(toplevel, ["symbolic-ref", "--short", "refs/remotes/origin/HEAD"]);
|
|
266
|
-
|
|
266
|
+
let name = out.stdout === null ? "" : out.stdout.trim().replace(/^origin\//u, "");
|
|
267
|
+
if (name === "") {
|
|
268
|
+
// `refs/remotes/origin/HEAD` is absent far more often than not: `git
|
|
269
|
+
// clone --branch <x>`, a pruned ref, or any repo that was only ever
|
|
270
|
+
// pushed to never gets one. Reading the symref alone therefore answered
|
|
271
|
+
// "no default branch" forever, which silently disabled EVERY
|
|
272
|
+
// default-branch rule — the merge row's base-branch wording on `main`,
|
|
273
|
+
// and the node half's own "no pull-request suggestion on main". Fall
|
|
274
|
+
// back, network-free, to the same base branch this module already
|
|
275
|
+
// probes for its ahead/behind row. A repository whose default branch is
|
|
276
|
+
// neither main nor master still answers undefined, exactly as before.
|
|
277
|
+
for (const candidate of ["main", "master"]) {
|
|
278
|
+
const probe = await runGit(toplevel, ["rev-parse", "--verify", "--quiet", "refs/remotes/origin/" + candidate]);
|
|
279
|
+
if (probe.stdout !== null && probe.stdout.trim() !== "") { name = candidate; break; }
|
|
280
|
+
}
|
|
281
|
+
}
|
|
267
282
|
const value = name === "" ? void 0 : name;
|
|
268
283
|
if (record.value !== value) notify?.();
|
|
269
284
|
return value;
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-git-badge",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.4",
|
|
4
4
|
"description": "Git status badges for DeepSeek Harness: an input-row chip on every install, plus sidebar session-row badges (git status, PR/CI action tokens) after one manual step: `npx dsh-git-badge apply`, then restart dsh web. Event-driven freshness over SSE.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"bin": {
|
|
8
|
+
"dsh-git-badge": "seam/apply.js",
|
|
8
9
|
"dsh-git-badge-seam": "seam/apply.js",
|
|
9
10
|
"dsh-git-badge-checkout": "seam/checkout.js"
|
|
10
11
|
},
|
package/seam/apply.js
CHANGED
|
@@ -37,7 +37,15 @@
|
|
|
37
37
|
* a stable, user-level store shared by every way this tool
|
|
38
38
|
* can run. See seam/store.js for the restart marker.
|
|
39
39
|
*
|
|
40
|
-
*
|
|
40
|
+
* The package also declares this file under the package's own name
|
|
41
|
+
* (bin "dsh-git-badge"), because npx only auto-runs a bin whose name matches
|
|
42
|
+
* the package name: `npx dsh-git-badge apply` resolves, while
|
|
43
|
+
* `npx dsh-git-badge-seam` 404s (no PACKAGE carries that name). The alias
|
|
44
|
+
* multiplexes the checkout bin too — npx cannot reach a second bin by name,
|
|
45
|
+
* so the checkout verb dispatches here:
|
|
46
|
+
*
|
|
47
|
+
* Usage: npx dsh-git-badge apply | revert | status | checkout <path|--clear>
|
|
48
|
+
* (equivalently apply.js <verb>; checkout delegates to checkout.js)
|
|
41
49
|
*/
|
|
42
50
|
import { copyFileSync, existsSync, readFileSync } from "node:fs";
|
|
43
51
|
import { MARKER } from "./anchors.js";
|
|
@@ -45,6 +53,16 @@ import { backupState, doPatch, doRestore, installPaths, inspect, KNOWN_GOOD_HASH
|
|
|
45
53
|
import { installSkill } from "./skill.js";
|
|
46
54
|
import { writeRestartMarker } from "./store.js";
|
|
47
55
|
|
|
56
|
+
const VERDICT_EXIT_1 = new Set(["drift", "unreadable", "missing", "ours-corrupt"]);
|
|
57
|
+
|
|
58
|
+
const verb = process.argv[2];
|
|
59
|
+
if (verb === "checkout") {
|
|
60
|
+
// alias-bin multiplex: strip the verb so checkout.js sees argv[2] = <path|--clear>
|
|
61
|
+
process.argv.splice(2, 1);
|
|
62
|
+
await import("./checkout.js");
|
|
63
|
+
process.exit(0); // checkout's success path returns; every failure path exits inside
|
|
64
|
+
}
|
|
65
|
+
|
|
48
66
|
const paths = installPaths();
|
|
49
67
|
if (paths === null) {
|
|
50
68
|
console.error("ERROR: cannot locate the DSH package. Set DSH_INSTALL to its root");
|
|
@@ -53,11 +71,8 @@ if (paths === null) {
|
|
|
53
71
|
}
|
|
54
72
|
const CLIENT = paths.client;
|
|
55
73
|
|
|
56
|
-
const VERDICT_EXIT_1 = new Set(["drift", "unreadable", "missing", "ours-corrupt"]);
|
|
57
|
-
|
|
58
|
-
const verb = process.argv[2];
|
|
59
74
|
if (!verb || !["apply", "revert", "status"].includes(verb)) {
|
|
60
|
-
console.error("usage:
|
|
75
|
+
console.error("usage: dsh-git-badge apply|revert|status (or: dsh-git-badge checkout <path|--clear>)");
|
|
61
76
|
process.exit(1);
|
|
62
77
|
}
|
|
63
78
|
|
|
@@ -152,7 +167,7 @@ if (verb === "apply") {
|
|
|
152
167
|
console.error("REFUSING: anchor drift — nothing was written.");
|
|
153
168
|
console.error(` anchor: ${name} (found ${count} times, need exactly 1)`);
|
|
154
169
|
console.error("Upstream changed code this patch anchors on. Update the matching entry");
|
|
155
|
-
console.error("in anchors.js, then re-run: dsh-git-badge
|
|
170
|
+
console.error("in anchors.js, then re-run: dsh-git-badge status && dsh-git-badge apply");
|
|
156
171
|
process.exit(1);
|
|
157
172
|
}
|
|
158
173
|
case "ours-corrupt":
|
package/seam/checkout.js
CHANGED
|
@@ -13,8 +13,12 @@
|
|
|
13
13
|
* The registration is advisory and self-expiring (24h) — never let it fail the
|
|
14
14
|
* work that earned it:
|
|
15
15
|
*
|
|
16
|
-
* usage: npx dsh-git-badge
|
|
17
|
-
* npx dsh-git-badge
|
|
16
|
+
* usage: npx dsh-git-badge checkout <path> register this session
|
|
17
|
+
* npx dsh-git-badge checkout --clear forget this session
|
|
18
|
+
*
|
|
19
|
+
* (npx can only reach the bin named after the package; the checkout verb
|
|
20
|
+
* dispatches to this file from apply.js. The legacy bin name
|
|
21
|
+
* dsh-git-badge-checkout still works when invoked directly.)
|
|
18
22
|
*
|
|
19
23
|
* The path is validated as a real worktree of its repository before it is
|
|
20
24
|
* written, so a typo cannot point the badge at an unrelated directory.
|
|
@@ -26,7 +30,7 @@ import { clearSessionCheckout, writeSessionCheckout } from "./store.js";
|
|
|
26
30
|
|
|
27
31
|
function usage(message) {
|
|
28
32
|
if (message !== void 0) console.error(message);
|
|
29
|
-
console.error("usage: dsh-git-badge
|
|
33
|
+
console.error("usage: dsh-git-badge checkout <path> | --clear");
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
/** Worktree paths git lists for the repo containing `dir` — the node half's parser. */
|
package/skill/gh/SKILL.md
CHANGED
|
@@ -81,7 +81,7 @@ unstaged / untracked / unmerged), plus any in-progress operation marker
|
|
|
81
81
|
|
|
82
82
|
If the switch lands you in — or out of — a linked worktree, register where you
|
|
83
83
|
are so the session badge follows the right checkout:
|
|
84
|
-
`npx dsh-git-badge
|
|
84
|
+
`npx dsh-git-badge checkout "$(git rev-parse --show-toplevel)"` (best effort;
|
|
85
85
|
ignore failure). Clearing back to the main checkout is the same command run
|
|
86
86
|
against the main worktree — the badge treats the main checkout as the default.
|
|
87
87
|
A session's cwd is fixed at creation, so this registration is the ONLY signal
|