dsh-git-ui 0.0.1 → 0.1.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/README.md +41 -16
- package/README.zh.md +42 -17
- package/cordis.patch.yml +1 -1
- package/lib/client.js +36 -35
- package/lib/client.js.map +4 -4
- package/lib/host/actions.d.ts +34 -0
- package/lib/host/core.d.ts +31 -1
- package/lib/host/index.d.ts +15 -8
- package/lib/host/index.js +464 -23
- package/lib/host/index.js.map +4 -4
- package/lib/host/parser.d.ts +37 -1
- package/lib/host/queries.d.ts +17 -0
- package/lib/host/types.d.ts +174 -0
- package/package.json +1 -1
- package/src/client/GitCenter.tsx +1524 -0
- package/src/client/GitPill.tsx +303 -54
- package/src/client/changes-diff.ts +63 -0
- package/src/client/controller.ts +83 -1
- package/src/client/error-text.ts +21 -0
- package/src/client/file-tree.ts +101 -0
- package/src/client/git-graph.ts +188 -0
- package/src/client/icons.tsx +292 -0
- package/src/client/index.ts +4 -2
- package/src/client/locales.ts +162 -0
- package/src/client/popup-close.ts +19 -0
- package/src/client/remote.ts +140 -0
- package/src/client/select-menu.tsx +113 -0
- package/src/client/side-by-side.ts +150 -0
- package/src/client/styles.ts +1488 -46
- package/src/client/time-format.ts +32 -0
- package/src/host/actions.ts +178 -0
- package/src/host/core.ts +39 -13
- package/src/host/index.ts +45 -17
- package/src/host/parser.ts +155 -12
- package/src/host/queries.ts +289 -0
- package/src/host/types.ts +143 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { resolveWorkspace, type GitStatusConfig, type SnapshotDeps } from './core.ts';
|
|
2
|
+
import type { GitAction, GitActionResult, GitActionRequest, GitOperationErrorCode } from './types.ts';
|
|
3
|
+
/**
|
|
4
|
+
* A branch name is valid when it matches git's ref-name grammar at the level
|
|
5
|
+
* we care about: non-empty, ASCII ref chars only, no leading `-` (option
|
|
6
|
+
* injection guard, though argv never shells out), no `..` (path traversal of
|
|
7
|
+
* refs), no trailing `/`, and no double slashes.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isValidBranchName(name: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* A path is safe when it is repo-relative and stays inside the work tree:
|
|
12
|
+
* reject absolute paths, drive letters / backslashes, and `..` escapes
|
|
13
|
+
* (checked via path resolution against the realpath'd root).
|
|
14
|
+
*/
|
|
15
|
+
export declare function isSafePath(path: string, root: string): boolean;
|
|
16
|
+
/** Map a snapshot-flow failure (which may carry git-unavailable) onto the operation error shape. */
|
|
17
|
+
export declare function operationError(failure: Extract<Awaited<ReturnType<typeof resolveWorkspace>>, {
|
|
18
|
+
ok: false;
|
|
19
|
+
}>['error']): GitActionResult & {
|
|
20
|
+
ok: false;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* 把 git 命令失败归类为可预期的业务错误(其余保持 git-error)。
|
|
24
|
+
* 切分支被工作区未提交变更阻止是最常见的可预期失败:git 输出
|
|
25
|
+
* "would be overwritten by checkout"(或中文本地化 "将被 checkout 覆盖"),
|
|
26
|
+
* 归一化为 local-changes-block,client 据此给友好提示 + 处理变更引导。
|
|
27
|
+
*/
|
|
28
|
+
export declare function classifyOperationError(kind: GitAction['kind'], message: string): GitOperationErrorCode;
|
|
29
|
+
/**
|
|
30
|
+
* Execute one management action against the session's repository and return
|
|
31
|
+
* the refreshed snapshot on success (the caller re-renders from it, so the
|
|
32
|
+
* UI never waits for the next poll).
|
|
33
|
+
*/
|
|
34
|
+
export declare function runAction(deps: SnapshotDeps, config: GitStatusConfig, request: GitActionRequest): Promise<GitActionResult>;
|
package/lib/host/core.d.ts
CHANGED
|
@@ -40,6 +40,30 @@ export interface SnapshotDeps {
|
|
|
40
40
|
export declare const DEFAULT_CONFIG: GitStatusConfig;
|
|
41
41
|
/** Coerce a raw patch config value into a validated GitStatusConfig. */
|
|
42
42
|
export declare function normalizeConfig(raw: unknown): GitStatusConfig;
|
|
43
|
+
/** Run one command, mapping a spawn-level failure to a snapshot failure. */
|
|
44
|
+
export declare function runCommand(runner: GitRunner, argv: readonly string[], cwd: string, label: string, signal?: AbortSignal): Promise<{
|
|
45
|
+
readonly run: Awaited<ReturnType<GitRunner['run']>>;
|
|
46
|
+
} | {
|
|
47
|
+
readonly failure: Extract<GitSnapshotResult, {
|
|
48
|
+
ok: false;
|
|
49
|
+
}>['error'];
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* Resolve a session's repository workspace: cwd (live or persisted), the
|
|
53
|
+
* realpath'd directory, and the git work-tree root via `rev-parse
|
|
54
|
+
* --show-toplevel`. Shared by the snapshot flow and the operation runner.
|
|
55
|
+
*/
|
|
56
|
+
export type WorkspaceResolution = {
|
|
57
|
+
readonly ok: true;
|
|
58
|
+
readonly cwd: string;
|
|
59
|
+
readonly root: string;
|
|
60
|
+
} | {
|
|
61
|
+
readonly ok: false;
|
|
62
|
+
readonly error: Extract<GitSnapshotResult, {
|
|
63
|
+
ok: false;
|
|
64
|
+
}>['error'];
|
|
65
|
+
};
|
|
66
|
+
export declare function resolveWorkspace(deps: SnapshotDeps, sessionId: string): Promise<WorkspaceResolution>;
|
|
43
67
|
/**
|
|
44
68
|
* Build one frozen GitSnapshot for a session working directory.
|
|
45
69
|
* Command sequence (all read-only; every command after the first runs with
|
|
@@ -47,7 +71,13 @@ export declare function normalizeConfig(raw: unknown): GitStatusConfig;
|
|
|
47
71
|
* 1. `git rev-parse --show-toplevel` — repo detection (exit 128 → not-a-git-repo)
|
|
48
72
|
* 2. `git branch --show-current` — null when detached
|
|
49
73
|
* 3. `git rev-parse --short HEAD` — null + unborn when the repo has no commits
|
|
50
|
-
* 4. `git status --porcelain=v1 -z --branch`
|
|
74
|
+
* 4. `git status --porcelain=v1 -z --branch --untracked-files=all`
|
|
51
75
|
* 5. `git log -n 5 --format=%H%x1f%h%x1f%s%x1f%an%x1f%aI`
|
|
76
|
+
*
|
|
77
|
+
* --untracked-files=all:git 默认 normal 模式会把整目录未跟踪折叠为单条
|
|
78
|
+
* `?? dir/`(尾斜杠)且不枚举其内部文件——隐藏目录(.agent/.tianqi 等)的
|
|
79
|
+
* 变更因此从不进入变更清单。`all` 强制逐文件枚举(与 IDEA / VSCode 一致),
|
|
80
|
+
* 内部文件得以展示;maxChanges 截断列表、maxStatusBytes spill 保计数精确,
|
|
81
|
+
* 超大未跟踪树(如未 gitignore 的构建产物)经此路径优雅降级。
|
|
52
82
|
*/
|
|
53
83
|
export declare function snapshotForSession(deps: SnapshotDeps, config: GitStatusConfig, sessionId: string): Promise<GitSnapshotResult>;
|
package/lib/host/index.d.ts
CHANGED
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* dsh-git-ui host half: the `gitInfo` Remote service.
|
|
3
3
|
*
|
|
4
|
-
* Cordis shell only — every behavior lives in `core.ts
|
|
5
|
-
* structural faces, so tests never need a
|
|
6
|
-
* plugin in its own right (class form),
|
|
7
|
-
* the package name; the gateway exposes
|
|
4
|
+
* Cordis shell only — every behavior lives in `core.ts`/`actions.ts`/
|
|
5
|
+
* `queries.ts` behind injected structural faces, so tests never need a
|
|
6
|
+
* cordis runtime. The class is a plugin in its own right (class form),
|
|
7
|
+
* mounted by the bundle patch row with the package name; the gateway exposes
|
|
8
|
+
* `gitInfo/snapshot`, `gitInfo/run` and `gitInfo/query` through SRC
|
|
8
9
|
* discovery (`typertRemote` binding + `@Remote` marker).
|
|
9
10
|
*/
|
|
10
11
|
import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
11
12
|
import type { Context } from '@deepseek-ai/cordis';
|
|
12
|
-
import type { GitSnapshotRequest, GitSnapshotResult } from './types.ts';
|
|
13
|
-
export type { GitSnapshot, GitSnapshotResult, GitSnapshotFailure, GitSnapshotRequest, GitCommit, GitChange } from './types.ts';
|
|
13
|
+
import type { GitActionResult, GitActionRequest, GitQueryRequest, GitQueryResponse, GitSnapshotRequest, GitSnapshotResult } from './types.ts';
|
|
14
|
+
export type { GitSnapshot, GitSnapshotResult, GitSnapshotFailure, GitSnapshotRequest, GitCommit, GitChange, GitAction, GitActionResult, GitActionRequest, GitQuery, GitQueryResult, GitQueryRequest, GitQueryResponse, GitBranch, GitFileStat, GitRef } from './types.ts';
|
|
14
15
|
export { normalizeConfig, DEFAULT_CONFIG } from './core.ts';
|
|
15
|
-
export { parseStatusOutput, parseLogOutput, parseBranchOutput } from './parser.ts';
|
|
16
|
-
|
|
16
|
+
export { parseStatusOutput, parseLogOutput, parseBranchOutput, parseNameStatusOutput } from './parser.ts';
|
|
17
|
+
export { isSafePath, isValidBranchName, runAction } from './actions.ts';
|
|
18
|
+
export { runQuery } from './queries.ts';
|
|
19
|
+
/** The `gitInfo` service: `snapshot` (read) and `run` (management) endpoints. */
|
|
17
20
|
export declare class GitStatusService extends TypertRemoteService {
|
|
18
21
|
static inject: string[];
|
|
19
22
|
private readonly config;
|
|
20
23
|
constructor(ctx: Context, config: unknown);
|
|
24
|
+
/** Adapter face shared by both endpoints (injected services + runner). */
|
|
25
|
+
private deps;
|
|
21
26
|
snapshot(request: GitSnapshotRequest, signal?: AbortSignal): Promise<GitSnapshotResult>;
|
|
27
|
+
run(request: GitActionRequest, signal?: AbortSignal): Promise<GitActionResult>;
|
|
28
|
+
query(request: GitQueryRequest, signal?: AbortSignal): Promise<GitQueryResponse>;
|
|
22
29
|
}
|
|
23
30
|
export default GitStatusService;
|