dsh-diff-approval 0.30.1 → 0.32.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.
Files changed (36) hide show
  1. package/README.md +11 -23
  2. package/README.zh.md +9 -21
  3. package/assets/fonts/README.md +10 -8
  4. package/assets/fonts/manifest.json +1 -1
  5. package/lib/client.js +2791 -894
  6. package/lib/index.js +1755 -269
  7. package/lib/types/annotate-skill.d.ts +1 -1
  8. package/lib/types/annotate-tool.d.ts +11 -0
  9. package/lib/types/annotate.d.ts +28 -0
  10. package/lib/types/client/PendingPanel.d.ts +31 -21
  11. package/lib/types/client/category-color.d.ts +62 -0
  12. package/lib/types/client/chords.d.ts +70 -17
  13. package/lib/types/client/discussion.d.ts +10 -3
  14. package/lib/types/client/dock.d.ts +8 -3
  15. package/lib/types/client/dsh-icons.d.ts +39 -1
  16. package/lib/types/client/header-entry.d.ts +8 -7
  17. package/lib/types/client/locales.d.ts +52 -12
  18. package/lib/types/client/panel-memory.d.ts +24 -6
  19. package/lib/types/client/path-match.d.ts +50 -0
  20. package/lib/types/client/port.d.ts +29 -2
  21. package/lib/types/client/produced-diff.d.ts +83 -6
  22. package/lib/types/client/reference.d.ts +0 -2
  23. package/lib/types/client/remap-sync.d.ts +18 -1
  24. package/lib/types/client/session-seat.d.ts +47 -7
  25. package/lib/types/client/settings.d.ts +40 -14
  26. package/lib/types/client/slots.d.ts +115 -3
  27. package/lib/types/client/store.d.ts +50 -0
  28. package/lib/types/client/whole-file-diff.d.ts +42 -0
  29. package/lib/types/comment-ask.d.ts +47 -20
  30. package/lib/types/comments.d.ts +141 -33
  31. package/lib/types/index.d.ts +1 -1
  32. package/lib/types/pending.d.ts +30 -4
  33. package/lib/types/types.d.ts +186 -4
  34. package/lib/types/vcs.d.ts +35 -1
  35. package/lib/types/version.d.ts +162 -0
  36. package/package.json +4 -2
@@ -0,0 +1,162 @@
1
+ /**
2
+ * "Is a newer release published?" — the host's half of the panel's update notice.
3
+ *
4
+ * The check lives on the host because the browser cannot make it: `registry.npmjs.org`
5
+ * sends no CORS header, and only the host knows which version of this package is
6
+ * actually installed (it reads its own `package.json`). The client asks once through
7
+ * this plugin's existing channel and renders whatever comes back.
8
+ *
9
+ * Everything here FAILS SOFT: a timeout, a refused connection, a registry answer that
10
+ * is not JSON, a package with no `version` — all of them end as `undefined`, never as a
11
+ * throw. A reader on a plane must not see a network error in their review panel, and the
12
+ * panel must never wait on this to draw.
13
+ *
14
+ * The dialog shows NOTHING but the versions and a button, so this module asks for nothing
15
+ * but the version: there is no changelog to slice and no URL to hand over.
16
+ *
17
+ * @module dsh-diff-approval/version
18
+ */
19
+ import type { DiffApprovalUpdateValue } from './types.ts';
20
+ /** The published name this check asks the registry about. */
21
+ export declare const UPDATE_PACKAGE = "dsh-diff-approval";
22
+ /** The registry's "latest" document for this package: `{ version, … }`. */
23
+ export declare const UPDATE_REGISTRY = "https://registry.npmjs.org/dsh-diff-approval/latest";
24
+ /**
25
+ * How long the request may take. Short on purpose: this is a nicety in a status bar,
26
+ * and the client-side request is issued in the background — but the host's own worker
27
+ * should not be held by a hanging socket either.
28
+ */
29
+ export declare const UPDATE_TIMEOUT_MS = 3000;
30
+ /**
31
+ * How long a registry answer may be reused before asking again: TEN MINUTES.
32
+ *
33
+ * The cache exists for the network cost of the REMOTE answer only (see {@link createUpdateCheck}), so this is
34
+ * the one staleness a reader can be shown. Ten minutes because a release cadence is measured in days: the
35
+ * figure is far shorter than any release gap, so a genuinely new release reaches an already-running host
36
+ * without a restart, and far longer than a page load, so reloading a page — or opening a second seat — does
37
+ * not hammer a public registry. It is deliberately NOT permanent: the process-lifetime memo this replaced
38
+ * kept serving a verdict computed before an upgrade, which is exactly how a reader saw "a new version" for a
39
+ * version they had already installed.
40
+ */
41
+ export declare const UPDATE_CACHE_TTL_MS: number;
42
+ /** A parsed `major.minor.patch`. */
43
+ export type Version = readonly [number, number, number];
44
+ /** One HTTP answer, as much of it as this module reads. */
45
+ export interface FetchResponseFace {
46
+ readonly ok: boolean;
47
+ readonly status: number;
48
+ text(): Promise<string>;
49
+ }
50
+ /** The one call this module makes on the network, injected so tests need no socket. */
51
+ export type FetchFace = (url: string, init: {
52
+ signal: AbortSignal;
53
+ headers: Record<string, string>;
54
+ }) => Promise<FetchResponseFace>;
55
+ /** Where to ask, and how. Every field has a production default. */
56
+ export interface UpdateProbe {
57
+ /** Registry `latest` document. */
58
+ registryUrl?: string;
59
+ /** Per-request budget, in ms. */
60
+ timeoutMs?: number;
61
+ /** The transport; defaults to the runtime's global `fetch`. */
62
+ fetchImpl?: FetchFace;
63
+ }
64
+ /** How {@link createUpdateCheck} reads and asks; every field has a production default. */
65
+ export interface UpdateCheckOptions {
66
+ /** The manifest the INSTALLED version is read from; the package's own `package.json` by default. */
67
+ manifestUrl?: URL;
68
+ /** Registry `latest` document. */
69
+ registryUrl?: string;
70
+ /** Per-request budget, in ms. */
71
+ timeoutMs?: number;
72
+ /** The transport; defaults to the runtime's global `fetch`. */
73
+ fetchImpl?: FetchFace;
74
+ /** How long a fetched registry answer may be reused, in ms; {@link UPDATE_CACHE_TTL_MS} by default. */
75
+ ttlMs?: number;
76
+ /**
77
+ * The clock, in ms since the epoch; `Date.now` by default. Injected so a test can age the cached REMOTE
78
+ * answer without waiting ten real minutes — the TTL is the one thing here a test cannot otherwise reach.
79
+ */
80
+ now?: () => number;
81
+ }
82
+ /**
83
+ * Parse `major.minor.patch`, and NOTHING else.
84
+ *
85
+ * Deliberately strict, because the alternative is a bogus "newer": a pre-release
86
+ * (`0.31.0-rc.1`), a range (`^0.31.0`), a dist-tag (`latest`) or a stray suffix all
87
+ * answer `undefined`, and an unparsable side of a comparison is never allowed to look
88
+ * newer. A leading `v` is tolerated because tags carry one.
89
+ *
90
+ * @param text - the candidate, from a registry document or a `package.json`.
91
+ * @returns the three numbers, or `undefined` when the text is not exactly that shape.
92
+ */
93
+ export declare function parseVersion(text: unknown): Version | undefined;
94
+ /**
95
+ * Is `latest` strictly newer than `current`?
96
+ *
97
+ * Strictly: equal versions are NOT newer, and neither side parsing means NOT newer —
98
+ * the rule the code above exists to make safe. Comparison is component-wise on the
99
+ * three numbers, so `0.9.0` precedes `0.10.0` (string comparison would get that wrong).
100
+ *
101
+ * @param latest - the published version.
102
+ * @param current - the installed version.
103
+ * @returns whether a notice is warranted.
104
+ */
105
+ export declare function isNewerVersion(latest: unknown, current: unknown): boolean;
106
+ /**
107
+ * Compare two already-parsed versions.
108
+ *
109
+ * Component-wise, because a string comparison gets `0.9.0` vs `0.10.0` wrong — the reason both
110
+ * callers go through here rather than comparing something textual.
111
+ *
112
+ * @param left - one version.
113
+ * @param right - the other.
114
+ * @returns negative, zero or positive, as a comparator should.
115
+ */
116
+ export declare function compareVersions(left: Version, right: Version): number;
117
+ /**
118
+ * The version installed in this package, read from the `package.json` beside the built
119
+ * `lib/` — the only authority on what the reader is running, and the value the registry
120
+ * answer is compared against.
121
+ *
122
+ * Resolved relative to this module, so it holds for the bundled `lib/index.js`
123
+ * (`../package.json` is the package root) and for the source under test (`../package.json`
124
+ * is the repository root) alike.
125
+ *
126
+ * @param manifestUrl - the manifest to read; the package's own `package.json` unless a caller
127
+ * says otherwise. It is a parameter because a test runner can serve modules over a non-file
128
+ * URL, where the default cannot be resolved — the production path is the default, and the
129
+ * end-to-end case is what proves the default itself.
130
+ * @returns the version, or `undefined` when the file is missing or has none.
131
+ */
132
+ export declare function installedVersion(manifestUrl?: URL): Promise<string | undefined>;
133
+ /**
134
+ * Ask the registry for the published version.
135
+ *
136
+ * @param probe - where to ask and how; every field defaults (see {@link UpdateProbe}).
137
+ * @returns the version, or `undefined` on any failure — including an answer that is not
138
+ * a version, which must never become a notice.
139
+ */
140
+ export declare function fetchLatestVersion(probe?: UpdateProbe): Promise<string | undefined>;
141
+ /**
142
+ * Build the answer behind the `update-check` endpoint: one function a host calls per request.
143
+ *
144
+ * WHAT IS CACHED, AND FOR HOW LONG — the whole point of this factory:
145
+ *
146
+ * - The REMOTE answer (the registry's latest version) is cached, because that is the network cost. It is held
147
+ * for {@link UPDATE_CACHE_TTL_MS} and then fetched again, so a release published while the host is running
148
+ * still reaches the reader without a restart. A FAILED fetch is not cached at all: remembering a failure
149
+ * would hide the notice for the whole TTL after one offline moment, and there is no network cost to save.
150
+ * - The INSTALLED version is read from the manifest on EVERY call. It is a file read, not a request, and it is
151
+ * the side that changes when the reader upgrades — so a verdict computed before that upgrade must never be
152
+ * replayed. Caching it was a real defect: a host that answered while an older version was installed kept
153
+ * announcing "a newer release" to every page until it was restarted.
154
+ *
155
+ * `newer` is therefore decided afresh on every call, from today's manifest against the cached registry answer.
156
+ * NEVER THROWS: every failure — no manifest, an unreachable registry, a nonsense answer — ends as "nothing to
157
+ * say" (`newer: false`), so a network problem can never become an error in the reader's status bar.
158
+ *
159
+ * @param options - where to read and how; every field defaults (see {@link UpdateCheckOptions}).
160
+ * @returns the check itself; call it as often as you like.
161
+ */
162
+ export declare function createUpdateCheck(options?: UpdateCheckOptions): () => Promise<DiffApprovalUpdateValue>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-diff-approval",
3
- "version": "0.30.1",
3
+ "version": "0.32.0",
4
4
  "description": "DeepSeek Harness plugin: pending-edit review with whole-file diff and Keep/Revert",
5
5
  "packageManager": "pnpm@11.21.0",
6
6
  "author": "Wu Zhiwei",
@@ -60,10 +60,12 @@
60
60
  "test": "vitest run",
61
61
  "e2e": "playwright test",
62
62
  "compat": "node scripts/dsh-compat.mjs",
63
+ "compat:newer": "node scripts/dsh-compat.mjs --newer",
64
+ "verify:release": "node scripts/verify-release.mjs",
63
65
  "fonts:check": "python -m scripts.fonts.build --check",
64
66
  "fonts:plan": "python -m scripts.fonts.build --plan",
65
67
  "prepare": "tsc -b tsconfig.json && tsdown --env.DSH_BUILD_FACE client",
66
- "release": "release-it"
68
+ "release": "release-it && node scripts/verify-release.mjs"
67
69
  },
68
70
  "license": "MIT",
69
71
  "dependencies": {