dsh-git-badge 0.9.0 → 0.10.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 +34 -1
- package/lib/client.js +27 -1
- package/package.json +6 -9
- package/seam/apply.js +1 -1
- package/seam/postinstall.js +85 -0
package/CHANGELOG.md
CHANGED
|
@@ -8,13 +8,46 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|
|
8
8
|
Versions before 0.6.0 predate this file; their history is in `git log` and on
|
|
9
9
|
npm. 0.6.0 is the first release recorded here.
|
|
10
10
|
|
|
11
|
+
## [Unreleased]
|
|
12
|
+
|
|
13
|
+
## [0.10.0] - 2026-09-14
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **The install flow now tells you about the one manual step, everywhere it can.**
|
|
18
|
+
A market install activates the input chip immediately, but the sidebar
|
|
19
|
+
session-row badges additionally need the seam patch — and nothing said so.
|
|
20
|
+
Now: the market-listing description names the step; the README leads with the
|
|
21
|
+
two-command install order; a guarded `postinstall` applies the seam at
|
|
22
|
+
install time **when pnpm allows it** (opt-in via `allowBuilds` — DSH's plugin
|
|
23
|
+
installer prints that instruction whenever pnpm blocks a build) and only ever
|
|
24
|
+
in the one safe state (pristine upstream, all anchors resolving — anything
|
|
25
|
+
else just prints, and the hook can never fail an install); and when the seam
|
|
26
|
+
is still absent ~5s after boot, every input chip gains a tooltip naming the
|
|
27
|
+
command — the first message visible in the product rather than the console.
|
|
28
|
+
Restart stays manual by design: an install script restarting the host that is
|
|
29
|
+
installing it is not safe to automate.
|
|
30
|
+
|
|
31
|
+
## [0.9.1] - 2026-09-14
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- **The shipped patcher is reachable with npx.** `peerDependencies` named
|
|
36
|
+
`@deepseek-ai/dsh-client-runtime`, a DSH-internal package that is not on the
|
|
37
|
+
npm registry, so every `npx` invocation of the patcher died resolving peers
|
|
38
|
+
(pnpm inside a DSH profile only tolerated it because DSH itself provides the
|
|
39
|
+
runtime). The peers are removed — DSH supplies the runtime through the
|
|
40
|
+
`dsh.client.inject` declaration regardless — and the documented command is
|
|
41
|
+
`npx dsh-git-badge <verb>`: npx runs a package's single bin under the
|
|
42
|
+
package's own name. The boot hint and all docs now say that.
|
|
43
|
+
|
|
11
44
|
## [0.9.0] - 2026-09-14
|
|
12
45
|
|
|
13
46
|
### Added
|
|
14
47
|
|
|
15
48
|
- **The seam patcher ships in the package** as the `dsh-git-badge-seam` bin, so a
|
|
16
49
|
market install can add the sidebar session-row badges without cloning the
|
|
17
|
-
repository: `npx dsh-git-badge
|
|
50
|
+
repository: `npx dsh-git-badge apply`, then restart. Pure Node (no
|
|
18
51
|
python3), anchor-based like the repo tooling it replaces, with the same
|
|
19
52
|
refusal semantics: it writes nothing unless every anchor resolves exactly
|
|
20
53
|
once, upgrades its own older artifacts by marker revision, and reverts to the
|
package/lib/client.js
CHANGED
|
@@ -695,6 +695,14 @@ window.__ModuleLoader__.load({
|
|
|
695
695
|
* always, `detail=1` on hover), because it is the only one that renders
|
|
696
696
|
* them — see targetQuery.
|
|
697
697
|
*/
|
|
698
|
+
/**
|
|
699
|
+
* Set LATE (see apply) — never at apply() time, because the workspace
|
|
700
|
+
* browser may not have declared the seam yet and a hint set then would
|
|
701
|
+
* lie to patched installs for the whole session. Every chip render reads
|
|
702
|
+
* it, so it reaches the DOM on the next refresh after it is set.
|
|
703
|
+
*/
|
|
704
|
+
let seamHint = null;
|
|
705
|
+
|
|
698
706
|
function ComposerGitChip({ sessionId }) {
|
|
699
707
|
const target = sessionId === void 0 ? void 0 : { kind: "session", id: sessionId };
|
|
700
708
|
// the PR/CI token is always on the chip, so its fetch is not gated
|
|
@@ -730,6 +738,11 @@ window.__ModuleLoader__.load({
|
|
|
730
738
|
whiteSpace: "nowrap",
|
|
731
739
|
cursor: "default"
|
|
732
740
|
},
|
|
741
|
+
// the only in-product message a market user gets when the seam is
|
|
742
|
+
// absent: hover the chip you CAN see to learn the one command that
|
|
743
|
+
// turns on the rows you cannot. null until the delayed check in
|
|
744
|
+
// apply() proves the seam never appeared.
|
|
745
|
+
title: seamHint === null ? undefined : seamHint,
|
|
733
746
|
// the card is fetched for a pointer that RESTS here, not one that
|
|
734
747
|
// merely crosses the chip
|
|
735
748
|
onPointerEnter: () => setHovered(true),
|
|
@@ -849,8 +862,21 @@ window.__ModuleLoader__.load({
|
|
|
849
862
|
: // discoverability: the chip works everywhere, but the session rows
|
|
850
863
|
// need the seam patch, and on a market install nothing else says so.
|
|
851
864
|
// The patcher ships IN this package — no clone needed.
|
|
852
|
-
"off (seam absent) — run `npx dsh-git-badge
|
|
865
|
+
"off (seam absent) — run `npx dsh-git-badge apply` to add them, then restart dsh web.")
|
|
853
866
|
);
|
|
867
|
+
// The chip tooltip can only be set LATE. At apply() time the workspace
|
|
868
|
+
// browser may not have declared the seam yet (the boot race documented
|
|
869
|
+
// above), so claiming absence here would lie to patched installs for the
|
|
870
|
+
// whole session — the exact mistake that made the old one-shot line
|
|
871
|
+
// claim "sidebar rows = off" while five row badges were rendering. Give
|
|
872
|
+
// the composed graph a beat to settle; only a seam that is STILL absent
|
|
873
|
+
// earns the hint, and every chip render after that carries it.
|
|
874
|
+
setTimeout(() => {
|
|
875
|
+
if (rowsReported) return; // seam present; badges rendered — nothing to hint about
|
|
876
|
+
if (ctx.slots.spec("sidebar.workspaces.sessionRow") !== void 0) return;
|
|
877
|
+
seamHint =
|
|
878
|
+
"Session-row badges are off: run `npx dsh-git-badge apply`, then restart dsh web. (Input-chip badges are unaffected.)";
|
|
879
|
+
}, 5000);
|
|
854
880
|
// The hover card depends on a primitive the SHELL seeds, not on anything
|
|
855
881
|
// this plugin declares. Report the outcome rather than letting a missing
|
|
856
882
|
// seed look like a missing feature: the try/catch above deliberately keeps
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-git-badge",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Git status badges for DeepSeek Harness: sidebar session
|
|
3
|
+
"version": "0.10.0",
|
|
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": {
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"./package.json": "./package.json"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
|
-
"test": "node --test"
|
|
16
|
+
"test": "node --test",
|
|
17
|
+
"postinstall": "node seam/postinstall.js"
|
|
17
18
|
},
|
|
18
19
|
"dsh": {
|
|
19
20
|
"bundle": {
|
|
@@ -50,16 +51,12 @@
|
|
|
50
51
|
"lib/client.js",
|
|
51
52
|
"seam/apply.js",
|
|
52
53
|
"seam/anchors.js",
|
|
54
|
+
"seam/postinstall.js",
|
|
53
55
|
"seam/stub-index.js",
|
|
54
56
|
"cordis.patch.yml",
|
|
55
57
|
"package.json",
|
|
56
58
|
"README.md",
|
|
57
59
|
"CHANGELOG.md",
|
|
58
60
|
"LICENSE"
|
|
59
|
-
]
|
|
60
|
-
"peerDependencies": {
|
|
61
|
-
"@deepseek-ai/cordis": ">=4",
|
|
62
|
-
"@deepseek-ai/dsh-client-runtime": ">=0.1",
|
|
63
|
-
"react": ">=18"
|
|
64
|
-
}
|
|
61
|
+
]
|
|
65
62
|
}
|
package/seam/apply.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* install needs no clone:
|
|
11
11
|
*
|
|
12
12
|
* dsh plugin --profile web add dsh-git-badge
|
|
13
|
-
* npx dsh-git-badge
|
|
13
|
+
* npx dsh-git-badge apply # then restart the dsh web process
|
|
14
14
|
*
|
|
15
15
|
* HOW PATCHING WORKS — anchors, not hashes. The patch is defined once in
|
|
16
16
|
* anchors.js as [name, old, new] triples. `apply` locates each `old` block in
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* postinstall hook — best-effort seam apply at plugin-install time.
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS EXISTS: a market install activates the input chip immediately, but
|
|
6
|
+
* the sidebar session-row badges additionally need the seam patch on the DSH
|
|
7
|
+
* package itself, and nothing in the install flow told the user so. When pnpm
|
|
8
|
+
* allows this script (the user approves it under `allowBuilds` — DSH's plugin
|
|
9
|
+
* installer prints exactly that instruction when pnpm blocks it), the seam is
|
|
10
|
+
* applied right here; otherwise the plugin's boot log and the chip tooltip name
|
|
11
|
+
* the same one manual command.
|
|
12
|
+
*
|
|
13
|
+
* GUARDRAILS — this script may never break an install:
|
|
14
|
+
* - it runs ONLY when the installed DSH client.js is pristine upstream AND
|
|
15
|
+
* every anchor resolves exactly once (`patchable`); any other state —
|
|
16
|
+
* already patched, drifted, upstream-landed, DSH not found — just prints
|
|
17
|
+
* - it never throws: every failure path prints the manual command and exits 0
|
|
18
|
+
* - it cannot restart dsh web; the printed message says to
|
|
19
|
+
*
|
|
20
|
+
* The restart is deliberately manual: the running dsh web process rebuilds its
|
|
21
|
+
* client bundle at boot, and an install script restarting the host that is
|
|
22
|
+
* installing it is not safe to automate.
|
|
23
|
+
*/
|
|
24
|
+
import { execSync } from "node:child_process";
|
|
25
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
26
|
+
import { dirname, join } from "node:path";
|
|
27
|
+
import { fileURLToPath } from "node:url";
|
|
28
|
+
import { applyPatch, firstFailure, isOurs, seamPresent } from "./anchors.js";
|
|
29
|
+
|
|
30
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
31
|
+
const HINT = "Sidebar session-row badges need one manual step: `npx dsh-git-badge apply`, then restart dsh web.";
|
|
32
|
+
|
|
33
|
+
function dshClientPath() {
|
|
34
|
+
try {
|
|
35
|
+
const root = process.env.DSH_INSTALL || join(execSync("npm root -g", { encoding: "utf8" }).trim(), "@deepseek-ai", "dsh");
|
|
36
|
+
return join(root, "node_modules", "@deepseek-ai", "dsh-client-ui-workspace", "lib", "client.js");
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function main() {
|
|
43
|
+
const client = dshClientPath();
|
|
44
|
+
if (client === null || !existsSync(client)) {
|
|
45
|
+
console.log(`[dsh-git-badge] DSH install not found; skipping seam setup. ${HINT}`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
// the index stub is copied with the client on apply (see apply.js)
|
|
49
|
+
const index = join(dirname(client), "index.js");
|
|
50
|
+
const text = readFileSync(client, "utf8");
|
|
51
|
+
|
|
52
|
+
// Already ours (any rev): nothing to do here; apply.js upgrade rules govern.
|
|
53
|
+
if (isOurs(text)) {
|
|
54
|
+
console.log("[dsh-git-badge] seam already applied — sidebar session-row badges active after restart.");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Upstream landed the seam: the patch is retired.
|
|
58
|
+
if (seamPresent(text)) {
|
|
59
|
+
console.log("[dsh-git-badge] DSH declares the seam itself — no patch needed.");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// Pristine, but the anchors no longer resolve: a DSH update moved anchored
|
|
63
|
+
// code. Never patch half of anything — print, and let a patched anchors.js
|
|
64
|
+
// do it.
|
|
65
|
+
const fail = firstFailure(text);
|
|
66
|
+
if (fail !== null) {
|
|
67
|
+
console.log(`[dsh-git-badge] DSH build drifted from the patch anchors (${fail.name}); skipping. ${HINT}`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// The one state we act on: pristine upstream, anchors resolve.
|
|
71
|
+
mkdirSync(HERE, { recursive: true });
|
|
72
|
+
copyFileSync(client, join(HERE, "backup-client.js"));
|
|
73
|
+
copyFileSync(index, join(HERE, "backup-index.js"));
|
|
74
|
+
writeFileSync(client, applyPatch(text));
|
|
75
|
+
copyFileSync(join(HERE, "stub-index.js"), index);
|
|
76
|
+
console.log("[dsh-git-badge] seam applied — RESTART dsh web to get sidebar session-row badges.");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
main();
|
|
81
|
+
} catch (error) {
|
|
82
|
+
// An install hook must never fail the install over the seam.
|
|
83
|
+
console.log(`[dsh-git-badge] seam setup skipped (${String(error && error.message ? error.message : error)}). ${HINT}`);
|
|
84
|
+
}
|
|
85
|
+
process.exit(0);
|