@xbzbing/dsh-git-panel 0.1.1 → 0.3.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.
@@ -1,7 +1,7 @@
1
1
  import type { SnapshotDeps, GitPanelConfig } from './core.ts';
2
+ import { isSafePath } from './validate.ts';
2
3
  import type { GitAction, GitActionRequest, GitActionResult, GitErrorCode } from './types.ts';
3
- /** A repository-relative path is safe when it stays inside the work tree. */
4
- export declare function isSafePath(path: string): boolean;
4
+ export { isSafePath };
5
5
  interface CommandPlan {
6
6
  readonly argv: readonly (readonly string[])[];
7
7
  }
@@ -13,4 +13,3 @@ type PlanResult = CommandPlan | {
13
13
  export declare function planAction(action: GitAction, unborn: boolean): PlanResult;
14
14
  /** Execute a management action, returning the fresh snapshot on success. */
15
15
  export declare function runAction(deps: SnapshotDeps, config: GitPanelConfig, request: GitActionRequest): Promise<GitActionResult>;
16
- export {};
@@ -1,5 +1,5 @@
1
1
  import type { GitRunner } from './git.ts';
2
- import type { GitChange, GitSnapshotResult } from './types.ts';
2
+ import type { DiffViewMode, GitChange, GitErrorCode, GitSnapshotResult } from './types.ts';
3
3
  export interface GitPanelConfig {
4
4
  readonly timeoutMs: number;
5
5
  /** Per-command stdout cap; also the per-side image-diff payload cap. */
@@ -8,9 +8,13 @@ export interface GitPanelConfig {
8
8
  readonly refreshIntervalMs: number;
9
9
  /** Whether the input-bar git marker pill is shown. */
10
10
  readonly showInputPill: boolean;
11
+ /** Default diff layout the views open with (user can switch per-diff). */
12
+ readonly defaultDiffView: DiffViewMode;
11
13
  }
12
14
  export declare const DEFAULT_CONFIG: GitPanelConfig;
13
15
  export declare function normalizeConfig(raw: unknown): GitPanelConfig;
16
+ /** Read the default-diff-view field, unwrapping a schemastery volatile ref. */
17
+ export declare function readDiffView(value: unknown, fallback: DiffViewMode): DiffViewMode;
14
18
  /**
15
19
  * Read a boolean config field, unwrapping a schemastery volatile reference
16
20
  * (`{ get() }`) so a live-editable toggle reflects the latest value. Absent or
@@ -28,6 +32,11 @@ export interface SnapshotDeps {
28
32
  }>;
29
33
  /** Raw bytes (no encoding) — image sides for the image-diff query. */
30
34
  readFile(path: string): Promise<Buffer>;
35
+ /** One directory's entries (name + is-directory) — the file browser. */
36
+ readdir(path: string): Promise<ReadonlyArray<{
37
+ name: string;
38
+ isDirectory: boolean;
39
+ }>>;
31
40
  /** Best-effort unlink (force) — temp-blob cleanup. */
32
41
  remove(path: string): Promise<void>;
33
42
  };
@@ -45,6 +54,13 @@ export interface SnapshotDeps {
45
54
  * distinct cwd (a session's cwd is effectively stable).
46
55
  */
47
56
  readonly rootCache?: Map<string, string>;
57
+ /**
58
+ * Optional negative cache (cwd → expiry epoch ms) for non-repo cwds, so a
59
+ * session whose directory is not a git repo does not spawn `rev-parse` on
60
+ * every 30s poll. Short-lived (see NEG_CACHE_MS) so a repo created under the
61
+ * cwd is picked up soon after.
62
+ */
63
+ readonly rootNegCache?: Map<string, number>;
48
64
  }
49
65
  export type WorkspaceResolution = {
50
66
  readonly ok: true;
@@ -55,14 +71,43 @@ export type WorkspaceResolution = {
55
71
  ok: false;
56
72
  };
57
73
  };
74
+ /**
75
+ * Resolve a directory root for the file browser, which must work outside a git
76
+ * repository too. Inside a repo it is the work-tree top; otherwise it falls
77
+ * back to the session's cwd (realpath'd) so directory listing / file preview
78
+ * still function. Only a missing cwd is a hard failure.
79
+ */
80
+ export declare function resolveBrowseRoot(deps: SnapshotDeps, sessionId: string): Promise<{
81
+ ok: true;
82
+ root: string;
83
+ isGitRepo: boolean;
84
+ } | {
85
+ ok: false;
86
+ error: {
87
+ code: GitErrorCode;
88
+ message?: string;
89
+ };
90
+ }>;
58
91
  /** Resolve the git work-tree root for a session's cwd. */
59
92
  export declare function resolveWorkspace(deps: SnapshotDeps, sessionId: string): Promise<WorkspaceResolution>;
60
93
  /** Run one git command; a spawn-level failure returns { failure }. */
61
- export declare function runCommand(runner: GitRunner, argv: readonly string[], cwd: string, _label: string, signal?: AbortSignal): Promise<{
94
+ export declare function runCommand(runner: GitRunner, argv: readonly string[], cwd: string, _label: string, signal?: AbortSignal, stdinData?: string): Promise<{
62
95
  run: Awaited<ReturnType<GitRunner['run']>>;
63
96
  } | {
64
97
  failure: unknown;
65
98
  }>;
99
+ /**
100
+ * Collapse a workspace-resolution failure into the `{ code, message }` shape
101
+ * the run/query endpoints return. `GitFailure` already carries only endpoint
102
+ * codes, so no membership test is needed (the previous per-endpoint ternary
103
+ * that re-listed every code was always true — dead). `detail` becomes message.
104
+ */
105
+ export declare function mapWorkspaceFailure(failure: GitSnapshotResult & {
106
+ ok: false;
107
+ }): {
108
+ code: GitErrorCode;
109
+ message?: string;
110
+ };
66
111
  /** Produce a full snapshot for a session. */
67
112
  export declare function snapshotForSession(deps: SnapshotDeps, config: GitPanelConfig, sessionId: string): Promise<GitSnapshotResult>;
68
113
  /** Max mtime among changed files (epoch ms), capped for large sets. */
package/lib/host/git.d.ts CHANGED
@@ -10,7 +10,9 @@ interface SpawnSpec {
10
10
  readonly argv: readonly string[];
11
11
  readonly cwd: string;
12
12
  readonly stdio: {
13
- readonly stdin: 'ignore';
13
+ readonly stdin: 'ignore' | {
14
+ readonly data: string;
15
+ };
14
16
  readonly stdout: CollectDisposition;
15
17
  readonly stderr: CollectDisposition;
16
18
  };
@@ -45,12 +47,15 @@ export interface GitRunResult {
45
47
  readonly stdout: string;
46
48
  readonly stderr: string;
47
49
  readonly timedOut: boolean;
50
+ /** The caller's own signal aborted the run (navigation/reset), not our timeout. */
51
+ readonly cancelled: boolean;
48
52
  readonly stdoutLossy: boolean;
49
53
  }
50
54
  export interface GitRunner {
51
55
  run(argv: readonly string[], opts: {
52
56
  readonly cwd: string;
53
57
  readonly signal?: AbortSignal;
58
+ readonly stdinData?: string;
54
59
  }): Promise<GitRunResult>;
55
60
  }
56
61
  /**
@@ -10,7 +10,7 @@ import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
10
10
  import type { Context } from '@deepseek-ai/cordis';
11
11
  import Schema from '@deepseek-ai/schemastery';
12
12
  import type { GitActionRequest, GitActionResult, GitQueryRequest, GitQueryResponse, GitSnapshotRequest, GitSnapshotResult, GitVersionInfo, GitVersionRequest } from './types.ts';
13
- export type { GitSnapshot, GitSnapshotResult, GitSnapshotRequest, GitFailure, GitCommit, GraphCommit, GitRef, GitChange, GitChangeStatus, GitAction, GitActionRequest, GitActionResult, GitErrorCode, GitQuery, GitQueryRequest, GitQueryResponse, GitQueryResult, GitBranch, GitFileStat, WorktreeStats, GitVersionRequest, GitVersionInfo, } from './types.ts';
13
+ export type { GitSnapshot, GitSnapshotResult, GitSnapshotRequest, GitFailure, GitCommit, GraphCommit, GitRef, GitChange, GitChangeStatus, GitAction, GitActionRequest, GitActionResult, GitErrorCode, GitQuery, GitQueryRequest, GitQueryResponse, GitQueryResult, GitBranch, GitFileStat, WorktreeStats, GitVersionRequest, GitVersionInfo, DiffViewMode, DirEntry, } from './types.ts';
14
14
  export { normalizeConfig, DEFAULT_CONFIG, snapshotForSession, resolveWorkspace } from './core.ts';
15
15
  export { createGitRunner } from './git.ts';
16
16
  export { parseStatus, parseGraphLog, parseBranches, parseNameStatus, sumNumstat } from './parser.ts';
@@ -20,14 +20,17 @@ export { readVersionInfo, checkLatestVersion, compareVersions, parseRepository }
20
20
  export declare class GitPanelService extends TypertRemoteService {
21
21
  static inject: string[];
22
22
  /**
23
- * Config schema surfaced on the plugin detail page. Only `showInputPill` is
24
- * `.volatile()`, so the settings host renders it as a live-editable toggle;
25
- * the operational limits stay profile-only and out of the UI form.
23
+ * Config schema surfaced on the plugin detail page. `showInputPill` and
24
+ * `defaultDiffView` are `.volatile()`, so the settings host renders them as
25
+ * live-editable controls; the operational limits stay profile-only and out
26
+ * of the UI form.
26
27
  */
27
28
  static Config: Schema<Schemastery.ObjectS<NoInfer<{
28
29
  showInputPill: Schema<boolean, boolean, "volatile-defined">;
30
+ defaultDiffView: Schema<"split" | "unified", "split" | "unified", "volatile-defined">;
29
31
  }>>, Schemastery.ObjectT<NoInfer<{
30
32
  showInputPill: Schema<boolean, boolean, "volatile-defined">;
33
+ defaultDiffView: Schema<"split" | "unified", "split" | "unified", "volatile-defined">;
31
34
  }>>, "plain">;
32
35
  private readonly deps;
33
36
  private config;