@xbzbing/dsh-git-panel 1.6.2 → 1.7.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.
@@ -72,6 +72,9 @@ export interface GitRemote {
72
72
  /** Known-host classification, for the status-bar icon. */
73
73
  readonly hostKind: RemoteHostKind;
74
74
  }
75
+ /** Why the change list is incomplete: capped at `maxChanges`, or the status
76
+ * stream itself was clipped (a lossy read drops the head). */
77
+ export type TruncationReason = 'cap' | 'lossy';
75
78
  /** Immutable snapshot of one repository's status at `checkedAt`. */
76
79
  export interface GitSnapshot {
77
80
  /** Realpath of the repository root (work tree top). */
@@ -97,8 +100,14 @@ export interface GitSnapshot {
97
100
  readonly changes: readonly GitChange[];
98
101
  /** Working-tree statistics for the changes-page header (single source). */
99
102
  readonly stats: WorktreeStats;
100
- /** True when the change list was capped at maxChanges. */
103
+ /** True when the change list is incomplete (capped or clipped). */
101
104
  readonly truncated: boolean;
105
+ /** Which limit produced `truncated`; absent on older hosts. */
106
+ readonly truncatedReason?: TruncationReason;
107
+ /** True when untracked files fell back to git's collapsed `?? dir/` entries
108
+ * because expanding them would overflow `maxChanges` (or the status stream).
109
+ * Older hosts never set it. */
110
+ readonly untrackedCollapsed?: boolean;
102
111
  /** Polling interval the client should use after this snapshot (0 = off). */
103
112
  readonly refreshIntervalMs: number;
104
113
  /** Whether the input-bar git marker pill should render (user preference). */
@@ -109,6 +118,9 @@ export interface GitSnapshot {
109
118
  readonly graphStyle: GraphStyle;
110
119
  /** Whether the commit box shows the AI-suggest button (user preference). */
111
120
  readonly suggestEnabled: boolean;
121
+ /** SHA-256 of the final business snapshot, excluding checkedAt and itself.
122
+ * Optional for compatibility with hosts that do not provide fingerprints. */
123
+ readonly stateFingerprint?: string;
112
124
  /** Epoch millis of the snapshot. */
113
125
  readonly checkedAt: number;
114
126
  }
@@ -119,9 +131,15 @@ export interface GitCommit {
119
131
  readonly author: string;
120
132
  readonly dateIso: string;
121
133
  }
122
- /** A commit with parent links and ref decorations (graph rendering). */
123
- export interface GraphCommit extends GitCommit {
134
+ /** One node of the commit graph's raw ancestry: a full hash and its raw parent
135
+ * hashes. `parents` is empty for a true root — and equally for a shallow
136
+ * boundary, which git cannot tell apart from a root. */
137
+ export interface GitGraphNode {
138
+ readonly hash: string;
124
139
  readonly parents: readonly string[];
140
+ }
141
+ /** A commit with parent links and ref decorations (graph rendering). */
142
+ export interface GraphCommit extends GitCommit, GitGraphNode {
125
143
  readonly refs: readonly GitRef[];
126
144
  }
127
145
  export interface GitRef {
@@ -210,7 +228,7 @@ export type GitAction = {
210
228
  /** `git reset` modes, from least to most destructive. Single source so the
211
229
  * client dialog and the command builder cannot drift. */
212
230
  export type ResetMode = 'soft' | 'mixed' | 'hard';
213
- export type GitErrorCode = 'cwd-unavailable' | 'not-a-git-repo' | 'git-unavailable' | 'invalid-path' | 'invalid-name' | 'invalid-index' | 'git-error' | 'timeout' | 'cancelled' | 'empty-message' | 'local-changes-block' | 'not-ff' | 'push-rejected' | 'auth-failed' | 'conflict' | 'revert-conflict' | 'revert-stuck' | 'revert-merge' | 'not-found' | 'branch-in-use' | 'stash-switch-failed' | 'index-busy' | 'empty-diff' | 'llm-unavailable' | 'llm-error' | 'llm-output' | 'suggest-disabled';
231
+ export type GitErrorCode = 'cwd-unavailable' | 'not-a-git-repo' | 'git-unavailable' | 'invalid-path' | 'invalid-name' | 'invalid-index' | 'git-error' | 'timeout' | 'cancelled' | 'empty-message' | 'local-changes-block' | 'not-ff' | 'push-rejected' | 'auth-failed' | 'conflict' | 'revert-conflict' | 'revert-stuck' | 'revert-merge' | 'not-found' | 'branch-in-use' | 'stash-switch-failed' | 'index-busy' | 'nested-repo' | 'nested-repo-partial' | 'empty-diff' | 'llm-unavailable' | 'llm-error' | 'llm-output' | 'suggest-disabled';
214
232
  export type GitActionResult = {
215
233
  readonly ok: true;
216
234
  readonly snapshot: GitSnapshot;
@@ -226,6 +244,16 @@ export interface GitActionRequest {
226
244
  readonly sessionId: string;
227
245
  readonly action: GitAction;
228
246
  }
247
+ /**
248
+ * True when a history `search` is a commit-hash prefix jump rather than a
249
+ * message regex: 7–40 hex chars after trimming.
250
+ */
251
+ export declare function isHistoryHashSearch(search: string): boolean;
252
+ /** Whether Git's effective content filters hide commits; hash jumps ignore them.
253
+ * Shared with clients receiving history from a host that omits topology. */
254
+ export declare function isHistoryFiltered(query: Pick<Extract<GitQuery, {
255
+ kind: 'history';
256
+ }>, 'search' | 'author' | 'since'>): boolean;
229
257
  export type GitQuery = {
230
258
  readonly kind: 'history';
231
259
  readonly limit: number;
@@ -357,6 +385,11 @@ export type GitQueryResult = {
357
385
  readonly kind: 'history';
358
386
  readonly commits: readonly GraphCommit[];
359
387
  readonly total: number;
388
+ /** Raw ancestry for a filtered page: the page's commits plus the ancestors
389
+ * an effective search/author/since filter hid from the page itself. Absent
390
+ * when no effective filter is active (or on a hash jump); `[]` means the
391
+ * bounded auxiliary walk failed, so the graph is incomplete. */
392
+ readonly topology?: readonly GitGraphNode[];
360
393
  }
361
394
  /**
362
395
  * Unified diff text plus the new-side line count. The count is the fact the
@@ -481,6 +514,14 @@ export type GitQueryResult = {
481
514
  /** Modification time (epoch ms) from the same stat (all variants). */
482
515
  readonly mtimeMs?: number;
483
516
  };
517
+ /**
518
+ * Byte envelope of the file browser's "copy file content" action: a text
519
+ * document is copyable strictly below this size. Shared by both halves —
520
+ * the host floors its text read here (so every copyable document can
521
+ * actually load) and the client hides the copy button at/above it, keeping
522
+ * one boundary for load and copy.
523
+ */
524
+ export declare const FILE_COPY_MAX_BYTES: number;
484
525
  export type GitQueryResponse = {
485
526
  readonly ok: true;
486
527
  readonly value: GitQueryResult;
package/lib/host/types.js CHANGED
@@ -2,8 +2,16 @@ const DIFF_CONTEXT_DEFAULT = 3;
2
2
  const DIFF_CONTEXT_MAX = 1e5;
3
3
  const DIFF_EXPAND_CONTEXT = 2e3;
4
4
  const DIFF_COUNT_READ_MAX = 8 * 1024 * 1024;
5
+ function isHistoryHashSearch(search) {
6
+ return /^[0-9a-fA-F]{7,40}$/.test(search.trim());
7
+ }
8
+ function isHistoryFiltered(query) {
9
+ const search = query.search?.trim() ?? "";
10
+ return !isHistoryHashSearch(search) && (search !== "" || (query.author ?? "") !== "" || (query.since ?? "") !== "");
11
+ }
12
+ const FILE_COPY_MAX_BYTES = 10 * 1024 * 1024;
5
13
  const SUGGEST_LIMITS = {
6
- maxBytes: { min: 16 * 1024, max: 512 * 1024, default: 128 * 1024 },
14
+ maxBytes: { min: 16 * 1024, max: 512 * 1024, default: 200 * 1024 },
7
15
  maxOutputTokens: { min: 256, max: 16384, default: 4096 },
8
16
  timeoutMs: { min: 5e3, max: 12e4, default: 15e3 }
9
17
  };
@@ -32,9 +40,12 @@ export {
32
40
  DIFF_CONTEXT_MAX,
33
41
  DIFF_COUNT_READ_MAX,
34
42
  DIFF_EXPAND_CONTEXT,
43
+ FILE_COPY_MAX_BYTES,
35
44
  IMAGE_MIME,
36
45
  SUGGEST_LANGUAGES,
37
46
  SUGGEST_LANGUAGE_DEFAULT,
38
47
  SUGGEST_LIMITS,
39
- imageMimeFor
48
+ imageMimeFor,
49
+ isHistoryFiltered,
50
+ isHistoryHashSearch
40
51
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xbzbing/dsh-git-panel",
3
- "version": "1.6.2",
3
+ "version": "1.7.0",
4
4
  "description": "DeepSeek Harness (dsh) plugin: an IDE-style Git panel in the Web GUI — branch/history overview, uncommitted changes with commit & amend, diff stats, and a zsh-style branch marker in the input bar.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -43,7 +43,7 @@
43
43
  "build": "node build.mjs",
44
44
  "typecheck": "tsc -p tsconfig.json --noEmit",
45
45
  "test:unit": "node build.mjs && node --test --test-force-exit test/unit/*.test.mjs",
46
- "test:e2e": "node build.mjs && node test/e2e/setup.mjs && node test/e2e/run.mjs && node test/e2e/run2.mjs && node test/e2e/run3.mjs && node test/e2e/run4.mjs && node test/e2e/run5.mjs",
46
+ "test:e2e": "node build.mjs && node test/e2e/setup.mjs && node test/e2e/all.mjs",
47
47
  "test": "npm run test:unit && npm run test:e2e",
48
48
  "check": "npm run typecheck && npm run test && git diff --exit-code -- lib/"
49
49
  },