dsh-git-ui 0.1.0 → 0.1.2

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.
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Host 端点契约:纯业务逻辑,零框架依赖。
3
+ *
4
+ * 将 `snapshotForSession` / `runAction` / `runQuery` 聚合为统一的
5
+ * `HostEndpoints` 接口——宿主适配层(Cordis/typert 或其他框架)只需调用
6
+ * `createHostEndpoints(deps, config)` 即可获得全部端点方法,再以任何
7
+ * RPC 机制暴露。业务层对此一无所知。
8
+ */
9
+ import { type GitStatusConfig, type SnapshotDeps } from '../host/core.ts';
10
+ import type { GitActionRequest, GitActionResult, GitQueryRequest, GitQueryResponse, GitSnapshotRequest, GitSnapshotResult } from '../host/types.ts';
11
+ /**
12
+ * 业务端点集合:三个 RPC 方法的纯函数实现。
13
+ * 每个方法接收 wire 请求、可选取消信号,返回 wire 响应。
14
+ */
15
+ export interface HostEndpoints {
16
+ snapshot(request: GitSnapshotRequest, signal?: AbortSignal): Promise<GitSnapshotResult>;
17
+ run(request: GitActionRequest, signal?: AbortSignal): Promise<GitActionResult>;
18
+ query(request: GitQueryRequest, signal?: AbortSignal): Promise<GitQueryResponse>;
19
+ }
20
+ /**
21
+ * 构造业务端点实例。
22
+ *
23
+ * `deps` 携带全部宿主能力(子进程、会话查找、文件系统);`config` 携带
24
+ * 运行参数。两者均为结构化接口,与任何框架无关。返回的端点对象可直接
25
+ * 绑定到 RPC 装饰器、HTTP 路由、或测试桩。
26
+ */
27
+ export declare function createHostEndpoints(deps: SnapshotDeps, config: GitStatusConfig): HostEndpoints;
@@ -1,28 +1,36 @@
1
1
  /**
2
- * dsh-git-ui host half: the `gitInfo` Remote service.
2
+ * dsh-git-ui host 适配层:Cordis/typert 壳。
3
3
  *
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
9
- * discovery (`typertRemote` binding + `@Remote` marker).
4
+ * 本文件是 host 端**唯一** import `@deepseek-ai/*` 的地方。职责:
5
+ * 1. Cordis 服务(subprocess / sessions / sessionPersistence)适配为
6
+ * 结构化 `SnapshotDeps` 接口;
7
+ * 2. 调用 `createHostEndpoints(deps, config)` 获得纯业务端点;
8
+ * 3. `@Remote` 装饰器将端点暴露给 typert Gateway。
9
+ *
10
+ * 业务逻辑全部在 `contracts/host-endpoints.ts` → `host/core.ts` /
11
+ * `host/actions.ts` / `host/queries.ts`,与框架无关。
10
12
  */
11
13
  import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
12
14
  import type { Context } from '@deepseek-ai/cordis';
13
- import type { GitActionResult, GitActionRequest, GitQueryRequest, GitQueryResponse, GitSnapshotRequest, GitSnapshotResult } from './types.ts';
15
+ import type { GitActionRequest, GitActionResult, GitQueryRequest, GitQueryResponse, GitSnapshotRequest, GitSnapshotResult } from './types.ts';
14
16
  export type { GitSnapshot, GitSnapshotResult, GitSnapshotFailure, GitSnapshotRequest, GitCommit, GitChange, GitAction, GitActionResult, GitActionRequest, GitQuery, GitQueryResult, GitQueryRequest, GitQueryResponse, GitBranch, GitFileStat, GitRef } from './types.ts';
15
17
  export { normalizeConfig, DEFAULT_CONFIG } from './core.ts';
16
18
  export { parseStatusOutput, parseLogOutput, parseBranchOutput, parseNameStatusOutput } from './parser.ts';
17
19
  export { isSafePath, isValidBranchName, runAction } from './actions.ts';
18
20
  export { runQuery } from './queries.ts';
19
- /** The `gitInfo` service: `snapshot` (read) and `run` (management) endpoints. */
21
+ export { createHostEndpoints, type HostEndpoints } from '../contracts/host-endpoints.ts';
22
+ /**
23
+ * gitInfo Remote 服务:Cordis 壳。
24
+ *
25
+ * 构造时从 Cordis Context 取出宿主服务,适配为 `SnapshotDeps`,再调用
26
+ * `createHostEndpoints` 获得纯业务端点。三个 `@Remote` 方法仅做委托。
27
+ */
20
28
  export declare class GitStatusService extends TypertRemoteService {
21
29
  static inject: string[];
22
- private readonly config;
30
+ private readonly endpoints;
23
31
  constructor(ctx: Context, config: unknown);
24
- /** Adapter face shared by both endpoints (injected services + runner). */
25
- private deps;
32
+ /** Cordis 服务适配为结构化 SnapshotDeps。 */
33
+ private buildDeps;
26
34
  snapshot(request: GitSnapshotRequest, signal?: AbortSignal): Promise<GitSnapshotResult>;
27
35
  run(request: GitActionRequest, signal?: AbortSignal): Promise<GitActionResult>;
28
36
  query(request: GitQueryRequest, signal?: AbortSignal): Promise<GitQueryResponse>;
package/lib/host/index.js CHANGED
@@ -739,62 +739,82 @@ function gitError(label, stderr, stdout) {
739
739
  };
740
740
  }
741
741
 
742
+ // src/contracts/host-endpoints.ts
743
+ function createHostEndpoints(deps, config) {
744
+ return {
745
+ snapshot(request, signal) {
746
+ const merged = mergeSignals(deps.signal, signal);
747
+ const effectiveDeps = merged === deps.signal ? deps : { ...deps, signal: merged };
748
+ return snapshotForSession(effectiveDeps, config, request.sessionId);
749
+ },
750
+ run(request, signal) {
751
+ const merged = mergeSignals(deps.signal, signal);
752
+ const effectiveDeps = merged === deps.signal ? deps : { ...deps, signal: merged };
753
+ return runAction(effectiveDeps, config, request);
754
+ },
755
+ query(request, signal) {
756
+ const merged = mergeSignals(deps.signal, signal);
757
+ const effectiveDeps = merged === deps.signal ? deps : { ...deps, signal: merged };
758
+ return runQuery(effectiveDeps, config, request);
759
+ }
760
+ };
761
+ }
762
+ function mergeSignals(a, b) {
763
+ if (a === void 0) return b;
764
+ if (b === void 0) return a;
765
+ return AbortSignal.any([a, b]);
766
+ }
767
+
742
768
  // src/host/index.ts
743
769
  var _query_dec, _run_dec, _snapshot_dec, _a, _init;
744
770
  var GitStatusService = class extends (_a = TypertRemoteService, _snapshot_dec = [Remote("snapshot")], _run_dec = [Remote("run")], _query_dec = [Remote("query")], _a) {
745
771
  constructor(ctx, config) {
746
772
  super(ctx, "gitInfo");
747
773
  __runInitializers(_init, 5, this);
748
- __publicField(this, "config");
749
- this.config = normalizeConfig(config);
750
- }
751
- /** Adapter face shared by both endpoints (injected services + runner). */
752
- deps(signal) {
753
- const subprocess = this.ctx.get("subprocess");
774
+ __publicField(this, "endpoints");
775
+ const normalizedConfig = normalizeConfig(config);
776
+ const deps = this.buildDeps(ctx, normalizedConfig);
777
+ this.endpoints = createHostEndpoints(deps, normalizedConfig);
778
+ }
779
+ /** Cordis 服务适配为结构化 SnapshotDeps。 */
780
+ buildDeps(ctx, config) {
781
+ const subprocess = ctx.get("subprocess");
754
782
  if (subprocess === void 0) {
755
- return { failure: { code: "git-unavailable", detail: "subprocess service unavailable" } };
783
+ return {
784
+ run: { run: async () => {
785
+ throw new Error("subprocess service unavailable");
786
+ } },
787
+ fs: { realpath, stat },
788
+ sessions: { liveCwd: () => void 0, persistedMeta: async () => void 0 }
789
+ };
756
790
  }
757
- const sessions = this.ctx.get("sessions");
758
- const persistence = this.ctx.get("sessionPersistence");
759
- const runner = createGitRunner(subprocess, this.config.timeoutMs, this.config.maxStatusBytes);
791
+ const sessions = ctx.get("sessions");
792
+ const persistence = ctx.get("sessionPersistence");
760
793
  return {
761
- deps: {
762
- run: runner,
763
- fs: { realpath, stat },
764
- sessions: {
765
- liveCwd: (id) => sessions?.get(id)?.header?.cwd,
766
- persistedMeta: async (id) => {
767
- if (persistence === void 0) return void 0;
768
- try {
769
- const inspection = await persistence.inspect(id);
770
- return { cwd: inspection.meta.cwd };
771
- } catch {
772
- return void 0;
773
- }
794
+ run: createGitRunner(subprocess, config.timeoutMs, config.maxStatusBytes),
795
+ fs: { realpath, stat },
796
+ sessions: {
797
+ liveCwd: (id) => sessions?.get(id)?.header?.cwd,
798
+ persistedMeta: async (id) => {
799
+ if (persistence === void 0) return void 0;
800
+ try {
801
+ const inspection = await persistence.inspect(id);
802
+ return { cwd: inspection.meta.cwd };
803
+ } catch {
804
+ return void 0;
774
805
  }
775
- },
776
- signal
806
+ }
777
807
  }
778
808
  };
779
809
  }
780
810
  async snapshot(request, signal) {
781
- const adapted = this.deps(signal);
782
- if ("failure" in adapted) return { ok: false, error: adapted.failure };
783
- return snapshotForSession(adapted.deps, this.config, request.sessionId);
811
+ return this.endpoints.snapshot(request, signal);
784
812
  }
785
813
  async run(request, signal) {
786
- const adapted = this.deps(signal);
787
- if ("failure" in adapted) {
788
- return { ok: false, error: { code: "git-error", message: adapted.failure.detail } };
789
- }
790
- return runAction(adapted.deps, this.config, request);
814
+ return this.endpoints.run(request, signal);
791
815
  }
792
816
  async query(request, signal) {
793
- const adapted = this.deps(signal);
794
- if ("failure" in adapted) {
795
- return { ok: false, error: { code: "git-error", message: adapted.failure.detail } };
796
- }
797
- return runQuery(adapted.deps, this.config, request);
817
+ return this.endpoints.query(request, signal);
798
818
  }
799
819
  };
800
820
  _init = __decoratorStart(_a);
@@ -807,6 +827,7 @@ var index_default = GitStatusService;
807
827
  export {
808
828
  DEFAULT_CONFIG,
809
829
  GitStatusService,
830
+ createHostEndpoints,
810
831
  index_default as default,
811
832
  isSafePath,
812
833
  isValidBranchName,