@cerbur/clutch-dsh-worktree 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.
Files changed (114) hide show
  1. package/README.md +136 -0
  2. package/cordis.patch.yml +5 -0
  3. package/lib/client/WorktreeModeAction.d.ts +11 -0
  4. package/lib/client/WorktreeModeAction.d.ts.map +1 -0
  5. package/lib/client/WorktreeModeAction.js +14 -0
  6. package/lib/client/WorktreeModeAction.js.map +1 -0
  7. package/lib/client/WorktreeSurface.d.ts +33 -0
  8. package/lib/client/WorktreeSurface.d.ts.map +1 -0
  9. package/lib/client/WorktreeSurface.js +834 -0
  10. package/lib/client/WorktreeSurface.js.map +1 -0
  11. package/lib/client/entry.d.ts +18 -0
  12. package/lib/client/entry.d.ts.map +1 -0
  13. package/lib/client/entry.js +100 -0
  14. package/lib/client/entry.js.map +1 -0
  15. package/lib/client/index.d.ts +7 -0
  16. package/lib/client/index.d.ts.map +1 -0
  17. package/lib/client/index.js +6 -0
  18. package/lib/client/index.js.map +1 -0
  19. package/lib/client/navigation.d.ts +7 -0
  20. package/lib/client/navigation.d.ts.map +1 -0
  21. package/lib/client/navigation.js +5 -0
  22. package/lib/client/navigation.js.map +1 -0
  23. package/lib/client/overlay-bounds.d.ts +11 -0
  24. package/lib/client/overlay-bounds.d.ts.map +1 -0
  25. package/lib/client/overlay-bounds.js +9 -0
  26. package/lib/client/overlay-bounds.js.map +1 -0
  27. package/lib/client/sidebar-overlay-geometry.d.ts +10 -0
  28. package/lib/client/sidebar-overlay-geometry.d.ts.map +1 -0
  29. package/lib/client/sidebar-overlay-geometry.js +96 -0
  30. package/lib/client/sidebar-overlay-geometry.js.map +1 -0
  31. package/lib/client/view-mode-store.d.ts +5 -0
  32. package/lib/client/view-mode-store.d.ts.map +1 -0
  33. package/lib/client/view-mode-store.js +15 -0
  34. package/lib/client/view-mode-store.js.map +1 -0
  35. package/lib/client/view-mode.d.ts +52 -0
  36. package/lib/client/view-mode.d.ts.map +1 -0
  37. package/lib/client/view-mode.js +76 -0
  38. package/lib/client/view-mode.js.map +1 -0
  39. package/lib/client/virtual-workspace-membership.d.ts +27 -0
  40. package/lib/client/virtual-workspace-membership.d.ts.map +1 -0
  41. package/lib/client/virtual-workspace-membership.js +95 -0
  42. package/lib/client/virtual-workspace-membership.js.map +1 -0
  43. package/lib/client/worktree-connection.d.ts +42 -0
  44. package/lib/client/worktree-connection.d.ts.map +1 -0
  45. package/lib/client/worktree-connection.js +139 -0
  46. package/lib/client/worktree-connection.js.map +1 -0
  47. package/lib/client/worktree-view.d.ts +63 -0
  48. package/lib/client/worktree-view.d.ts.map +1 -0
  49. package/lib/client/worktree-view.js +116 -0
  50. package/lib/client/worktree-view.js.map +1 -0
  51. package/lib/client.js +1952 -0
  52. package/lib/client.js.map +1 -0
  53. package/lib/contract/index.contract.d.ts +2 -0
  54. package/lib/contract/index.contract.d.ts.map +1 -0
  55. package/lib/contract/index.contract.js +51 -0
  56. package/lib/contract/index.contract.js.map +1 -0
  57. package/lib/contract/index.d.ts +181 -0
  58. package/lib/contract/index.d.ts.map +1 -0
  59. package/lib/contract/index.js +45 -0
  60. package/lib/contract/index.js.map +1 -0
  61. package/lib/host/dsh-read-adapter.d.ts +58 -0
  62. package/lib/host/dsh-read-adapter.d.ts.map +1 -0
  63. package/lib/host/dsh-read-adapter.js +59 -0
  64. package/lib/host/dsh-read-adapter.js.map +1 -0
  65. package/lib/host/index.d.ts +16 -0
  66. package/lib/host/index.d.ts.map +1 -0
  67. package/lib/host/index.js +14 -0
  68. package/lib/host/index.js.map +1 -0
  69. package/lib/host/remote.d.ts +16 -0
  70. package/lib/host/remote.d.ts.map +1 -0
  71. package/lib/host/remote.js +61 -0
  72. package/lib/host/remote.js.map +1 -0
  73. package/lib/host/service.d.ts +58 -0
  74. package/lib/host/service.d.ts.map +1 -0
  75. package/lib/host/service.js +121 -0
  76. package/lib/host/service.js.map +1 -0
  77. package/lib/index.d.ts +23 -0
  78. package/lib/index.d.ts.map +1 -0
  79. package/lib/index.js +22 -0
  80. package/lib/index.js.map +1 -0
  81. package/lib/manage/index.d.ts +9 -0
  82. package/lib/manage/index.d.ts.map +1 -0
  83. package/lib/manage/index.js +8 -0
  84. package/lib/manage/index.js.map +1 -0
  85. package/lib/manage/manager.d.ts +86 -0
  86. package/lib/manage/manager.d.ts.map +1 -0
  87. package/lib/manage/manager.js +584 -0
  88. package/lib/manage/manager.js.map +1 -0
  89. package/lib/manage/types.d.ts +41 -0
  90. package/lib/manage/types.d.ts.map +1 -0
  91. package/lib/manage/types.js +2 -0
  92. package/lib/manage/types.js.map +1 -0
  93. package/lib/provider/git.d.ts +42 -0
  94. package/lib/provider/git.d.ts.map +1 -0
  95. package/lib/provider/git.js +222 -0
  96. package/lib/provider/git.js.map +1 -0
  97. package/lib/provider/index.d.ts +13 -0
  98. package/lib/provider/index.d.ts.map +1 -0
  99. package/lib/provider/index.js +12 -0
  100. package/lib/provider/index.js.map +1 -0
  101. package/lib/provider/sidecar.d.ts +85 -0
  102. package/lib/provider/sidecar.d.ts.map +1 -0
  103. package/lib/provider/sidecar.js +410 -0
  104. package/lib/provider/sidecar.js.map +1 -0
  105. package/lib/provider/types.d.ts +126 -0
  106. package/lib/provider/types.d.ts.map +1 -0
  107. package/lib/provider/types.js +46 -0
  108. package/lib/provider/types.js.map +1 -0
  109. package/lib/typert.host.d.ts +3 -0
  110. package/lib/typert.host.js +290 -0
  111. package/lib/typert.remote-client.d.ts +32 -0
  112. package/lib/typert.remote-client.d.ts.map +1 -0
  113. package/lib/typert.remote-client.js +284 -0
  114. package/package.json +118 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/manage/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,YAAY,EACb,MAAM,sBAAsB,CAAC;AAE9B;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAEhC;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,MAAM,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAuB,SAAQ,eAAe;IAC7D;;;OAGG;IACH,iBAAiB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/manage/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ import type { GitWorktreeAdapter, GitWorktreeInfo } from './types.js';
2
+ /**
3
+ * 本地 Git worktree adapter:所有命令都以 DSH Workspace 根目录为 cwd,并仅使用固定的
4
+ * 本地子命令;不使用 `--force`,也不访问 remote。
5
+ *
6
+ * Local Git worktree adapter: every command runs with the DSH Workspace root as
7
+ * cwd and uses a fixed local-only subcommand; it never uses `--force` or accesses
8
+ * remotes.
9
+ */
10
+ export declare class LocalGitAdapter implements GitWorktreeAdapter {
11
+ /**
12
+ * 分开验证“位于非 bare working tree”和“已有可解析的首个 commit”,以返回不同修复语义。
13
+ * Separately verifies “inside a non-bare working tree” and “has a resolvable
14
+ * initial commit” so callers receive distinct repair semantics.
15
+ */
16
+ validateRepository(workspaceRoot: string): Promise<void>;
17
+ /**
18
+ * 仅列出 `refs/heads/` 下的本地分支;NUL 分隔避免依赖面向人的展示格式或空白切分。
19
+ * Lists local branches under `refs/heads/` only; NUL delimiting avoids
20
+ * depending on human-facing formatting or whitespace tokenization.
21
+ */
22
+ listBranches(workspaceRoot: string): Promise<readonly string[]>;
23
+ /**
24
+ * 使用 porcelain 输出枚举已注册 Worktree;无法映射到本地 branch 的条目不会被丢弃。
25
+ * Enumerates registered Worktrees through porcelain output; entries that do
26
+ * not map to a local branch are not discarded.
27
+ */
28
+ listWorktrees(workspaceRoot: string): Promise<readonly GitWorktreeInfo[]>;
29
+ /**
30
+ * 执行 `git worktree add`;传入 newBranch 时使用 `-b` 从 base branch 创建本地分支。
31
+ * Executes `git worktree add`; when newBranch is supplied, `-b` creates a local
32
+ * branch from the selected base branch.
33
+ */
34
+ createWorktree(workspaceRoot: string, targetPath: string, branch: string, newBranch?: string): Promise<void>;
35
+ /**
36
+ * 仅执行非强制 `git worktree remove <targetPath>`;Git 的安全拒绝会原样升级为显式错误。
37
+ * Executes non-forced `git worktree remove <targetPath>` only; Git safety
38
+ * refusals are surfaced as explicit errors.
39
+ */
40
+ removeWorktree(workspaceRoot: string, targetPath: string): Promise<void>;
41
+ }
42
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/provider/git.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA8JtE;;;;;;;GAOG;AACH,qBAAa,eAAgB,YAAW,kBAAkB;IACxD;;;;OAIG;IACG,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiC9D;;;;OAIG;IACG,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC;IAerE;;;;OAIG;IACG,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC;IAS/E;;;;OAIG;IACG,cAAc,CAClB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAWhB;;;;OAIG;IACG,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAO/E"}
@@ -0,0 +1,222 @@
1
+ import { execFile as execFileCallback } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { providerError } from './types.js';
4
+ const execFile = promisify(execFileCallback);
5
+ // Git 的原始进程证据只在本模块内流转;对外统一转换为稳定的 Provider 错误词汇。
6
+ // Raw Git process evidence stays inside this module and is normalized to the
7
+ // stable Provider error vocabulary at the public boundary.
8
+ class GitCommandError extends Error {
9
+ args;
10
+ cwd;
11
+ stdout;
12
+ stderr;
13
+ exitCode;
14
+ constructor(args, cwd, stdout, stderr, exitCode) {
15
+ super(stderr || stdout || `git exited with ${String(exitCode)}`);
16
+ this.name = 'GitCommandError';
17
+ this.args = args;
18
+ this.cwd = cwd;
19
+ this.stdout = stdout;
20
+ this.stderr = stderr;
21
+ this.exitCode = exitCode;
22
+ }
23
+ }
24
+ /*
25
+ * 所有 Git 调用都使用参数数组和固定 executable,不经过 shell;因此路径或分支中的 shell
26
+ * 元字符不会被解释。参数的业务合法性仍由上层 Manage 校验。
27
+ *
28
+ * Every Git call uses an argument vector and a fixed executable without a
29
+ * shell, so shell metacharacters in paths or branches are never evaluated.
30
+ * Semantic validation of those values remains the responsibility of Manage.
31
+ */
32
+ async function runGit(args, cwd) {
33
+ try {
34
+ const result = await execFile('git', [...args], {
35
+ cwd,
36
+ encoding: 'utf8',
37
+ maxBuffer: 4 * 1024 * 1024,
38
+ });
39
+ return { stdout: result.stdout, stderr: result.stderr };
40
+ }
41
+ catch (error) {
42
+ const commandError = error;
43
+ throw new GitCommandError(args, cwd, commandError.stdout ?? '', commandError.stderr ?? '', commandError.code ?? null);
44
+ }
45
+ }
46
+ // 保留 cwd、参数、stdout、stderr 和退出码,避免稳定错误 code 丢失现场诊断信息。
47
+ // Preserve cwd, arguments, stdout, stderr, and exit code so a stable error code
48
+ // does not discard the evidence needed for diagnosis.
49
+ function gitDetails(error) {
50
+ return {
51
+ workspaceRoot: error.cwd,
52
+ gitArgs: error.args,
53
+ gitStdout: error.stdout,
54
+ gitStderr: error.stderr,
55
+ gitExitCode: typeof error.exitCode === 'number' ? error.exitCode : String(error.exitCode),
56
+ };
57
+ }
58
+ /*
59
+ * 普通 Git 子命令失败统一归一化为 `GIT_OPERATION_FAILED`;仓库无效和缺少首个 commit
60
+ * 则由 `validateRepository` 使用更具体、可操作的错误 code。
61
+ *
62
+ * Ordinary Git subcommand failures normalize to `GIT_OPERATION_FAILED`;
63
+ * `validateRepository` reserves more actionable codes for an invalid
64
+ * repository and a missing initial commit.
65
+ */
66
+ function operationError(operation, workspaceRoot, targetPath, branch, error) {
67
+ if (!(error instanceof GitCommandError)) {
68
+ return providerError('GIT_OPERATION_FAILED', `Git ${operation} failed: ${String(error)}`, {
69
+ workspaceRoot,
70
+ ...(targetPath ? { targetPath } : {}),
71
+ ...(branch ? { branch } : {}),
72
+ });
73
+ }
74
+ const message = error.stderr.trim() || error.stdout.trim() || error.message;
75
+ return providerError('GIT_OPERATION_FAILED', `Git ${operation} failed for ${workspaceRoot}${targetPath ? ` -> ${targetPath}` : ''}: ${message}`, {
76
+ ...gitDetails(error),
77
+ ...(targetPath ? { targetPath } : {}),
78
+ ...(branch ? { branch } : {}),
79
+ operation,
80
+ });
81
+ }
82
+ /*
83
+ * 只解析 Git 保证稳定的 porcelain 字段。没有 `branch refs/heads/` 的条目仍被保留,
84
+ * 其 branch 为 undefined,以正确表示 detached HEAD 等状态。
85
+ *
86
+ * Parse only Git's stable porcelain fields. Entries without
87
+ * `branch refs/heads/` are retained with an undefined branch so states such as
88
+ * detached HEAD remain visible.
89
+ */
90
+ function parseWorktrees(output) {
91
+ const worktrees = [];
92
+ let current = {};
93
+ const flush = () => {
94
+ if (current.absolutePath) {
95
+ worktrees.push({
96
+ absolutePath: current.absolutePath,
97
+ ...(current.branch ? { branch: current.branch } : {}),
98
+ });
99
+ }
100
+ current = {};
101
+ };
102
+ for (const line of output.split('\n')) {
103
+ if (line.length === 0) {
104
+ flush();
105
+ continue;
106
+ }
107
+ if (line.startsWith('worktree ')) {
108
+ flush();
109
+ current.absolutePath = line.slice('worktree '.length);
110
+ continue;
111
+ }
112
+ if (line.startsWith('branch refs/heads/')) {
113
+ current.branch = line.slice('branch refs/heads/'.length);
114
+ }
115
+ }
116
+ flush();
117
+ return worktrees;
118
+ }
119
+ /**
120
+ * 本地 Git worktree adapter:所有命令都以 DSH Workspace 根目录为 cwd,并仅使用固定的
121
+ * 本地子命令;不使用 `--force`,也不访问 remote。
122
+ *
123
+ * Local Git worktree adapter: every command runs with the DSH Workspace root as
124
+ * cwd and uses a fixed local-only subcommand; it never uses `--force` or accesses
125
+ * remotes.
126
+ */
127
+ export class LocalGitAdapter {
128
+ /**
129
+ * 分开验证“位于非 bare working tree”和“已有可解析的首个 commit”,以返回不同修复语义。
130
+ * Separately verifies “inside a non-bare working tree” and “has a resolvable
131
+ * initial commit” so callers receive distinct repair semantics.
132
+ */
133
+ async validateRepository(workspaceRoot) {
134
+ let result;
135
+ try {
136
+ result = await runGit(['rev-parse', '--is-inside-work-tree'], workspaceRoot);
137
+ }
138
+ catch (error) {
139
+ if (error instanceof GitCommandError) {
140
+ throw providerError('WORKSPACE_NOT_GIT_REPOSITORY', `Workspace is not a Git repository: ${workspaceRoot}`, {
141
+ ...gitDetails(error),
142
+ });
143
+ }
144
+ throw error;
145
+ }
146
+ if (result.stdout.trim() !== 'true') {
147
+ throw providerError('WORKSPACE_NOT_GIT_REPOSITORY', `Workspace is not a Git work tree: ${workspaceRoot}`, {
148
+ workspaceRoot,
149
+ });
150
+ }
151
+ try {
152
+ await runGit(['rev-parse', '--verify', 'HEAD^{commit}'], workspaceRoot);
153
+ }
154
+ catch (error) {
155
+ if (error instanceof GitCommandError) {
156
+ throw providerError('WORKTREE_REQUIRES_INITIAL_COMMIT', `Workspace has no initial commit: ${workspaceRoot}`, { ...gitDetails(error) });
157
+ }
158
+ throw error;
159
+ }
160
+ }
161
+ /**
162
+ * 仅列出 `refs/heads/` 下的本地分支;NUL 分隔避免依赖面向人的展示格式或空白切分。
163
+ * Lists local branches under `refs/heads/` only; NUL delimiting avoids
164
+ * depending on human-facing formatting or whitespace tokenization.
165
+ */
166
+ async listBranches(workspaceRoot) {
167
+ try {
168
+ const result = await runGit(['for-each-ref', '--format=%(refname:short)%00', 'refs/heads/'], workspaceRoot);
169
+ return result.stdout
170
+ .split('\0')
171
+ .map((branch) => branch.replace(/^\r?\n/, '').replace(/\r?\n$/, ''))
172
+ .filter((branch) => branch.length > 0);
173
+ }
174
+ catch (error) {
175
+ throw operationError('list branches', workspaceRoot, undefined, undefined, error);
176
+ }
177
+ }
178
+ /**
179
+ * 使用 porcelain 输出枚举已注册 Worktree;无法映射到本地 branch 的条目不会被丢弃。
180
+ * Enumerates registered Worktrees through porcelain output; entries that do
181
+ * not map to a local branch are not discarded.
182
+ */
183
+ async listWorktrees(workspaceRoot) {
184
+ try {
185
+ const result = await runGit(['worktree', 'list', '--porcelain'], workspaceRoot);
186
+ return parseWorktrees(result.stdout);
187
+ }
188
+ catch (error) {
189
+ throw operationError('list worktrees', workspaceRoot, undefined, undefined, error);
190
+ }
191
+ }
192
+ /**
193
+ * 执行 `git worktree add`;传入 newBranch 时使用 `-b` 从 base branch 创建本地分支。
194
+ * Executes `git worktree add`; when newBranch is supplied, `-b` creates a local
195
+ * branch from the selected base branch.
196
+ */
197
+ async createWorktree(workspaceRoot, targetPath, branch, newBranch) {
198
+ try {
199
+ const args = newBranch
200
+ ? ['worktree', 'add', '-b', newBranch, targetPath, branch]
201
+ : ['worktree', 'add', targetPath, branch];
202
+ await runGit(args, workspaceRoot);
203
+ }
204
+ catch (error) {
205
+ throw operationError('create worktree', workspaceRoot, targetPath, newBranch ?? branch, error);
206
+ }
207
+ }
208
+ /**
209
+ * 仅执行非强制 `git worktree remove <targetPath>`;Git 的安全拒绝会原样升级为显式错误。
210
+ * Executes non-forced `git worktree remove <targetPath>` only; Git safety
211
+ * refusals are surfaced as explicit errors.
212
+ */
213
+ async removeWorktree(workspaceRoot, targetPath) {
214
+ try {
215
+ await runGit(['worktree', 'remove', targetPath], workspaceRoot);
216
+ }
217
+ catch (error) {
218
+ throw operationError('remove worktree', workspaceRoot, targetPath, undefined, error);
219
+ }
220
+ }
221
+ }
222
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/provider/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,EAAyB,aAAa,EAAE,MAAM,YAAY,CAAC;AAElE,MAAM,QAAQ,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAAC;AAO7C,gDAAgD;AAChD,6EAA6E;AAC7E,2DAA2D;AAC3D,MAAM,eAAgB,SAAQ,KAAK;IACxB,IAAI,CAAoB;IACxB,GAAG,CAAS;IACZ,MAAM,CAAS;IACf,MAAM,CAAS;IACf,QAAQ,CAAyB;IAE1C,YACE,IAAuB,EACvB,GAAW,EACX,MAAc,EACd,MAAc,EACd,QAAgC;QAEhC,KAAK,CAAC,MAAM,IAAI,MAAM,IAAI,mBAAmB,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACjE,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,MAAM,CAAC,IAAuB,EAAE,GAAW;IACxD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE;YAC9C,GAAG;YACH,QAAQ,EAAE,MAAM;YAChB,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;SAC3B,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;IAC1D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,GAAG,KAIpB,CAAC;QACF,MAAM,IAAI,eAAe,CACvB,IAAI,EACJ,GAAG,EACH,YAAY,CAAC,MAAM,IAAI,EAAE,EACzB,YAAY,CAAC,MAAM,IAAI,EAAE,EACzB,YAAY,CAAC,IAAI,IAAI,IAAI,CAC1B,CAAC;IACJ,CAAC;AACH,CAAC;AAED,qDAAqD;AACrD,gFAAgF;AAChF,sDAAsD;AACtD,SAAS,UAAU,CAAC,KAAsB;IACxC,OAAO;QACL,aAAa,EAAE,KAAK,CAAC,GAAG;QACxB,OAAO,EAAE,KAAK,CAAC,IAAI;QACnB,SAAS,EAAE,KAAK,CAAC,MAAM;QACvB,SAAS,EAAE,KAAK,CAAC,MAAM;QACvB,WAAW,EAAE,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;KAC1F,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CACrB,SAAiB,EACjB,aAAqB,EACrB,UAA8B,EAC9B,MAA0B,EAC1B,KAAc;IAEd,IAAI,CAAC,CAAC,KAAK,YAAY,eAAe,CAAC,EAAE,CAAC;QACxC,OAAO,aAAa,CAAC,sBAAsB,EAAE,OAAO,SAAS,YAAY,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE;YACxF,aAAa;YACb,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC;IAC5E,OAAO,aAAa,CAClB,sBAAsB,EACtB,OAAO,SAAS,eAAe,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,EAAE,EAClG;QACE,GAAG,UAAU,CAAC,KAAK,CAAC;QACpB,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7B,SAAS;KACV,CACF,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CAAC,MAAc;IACpC,MAAM,SAAS,GAAsB,EAAE,CAAC;IACxC,IAAI,OAAO,GAA+C,EAAE,CAAC;IAE7D,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACzB,SAAS,CAAC,IAAI,CAAC;gBACb,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACtD,CAAC,CAAC;QACL,CAAC;QACD,OAAO,GAAG,EAAE,CAAC;IACf,CAAC,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,KAAK,EAAE,CAAC;YACR,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACjC,KAAK,EAAE,CAAC;YACR,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACtD,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAC1C,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IACD,KAAK,EAAE,CAAC;IACR,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,eAAe;IAC1B;;;;OAIG;IACH,KAAK,CAAC,kBAAkB,CAAC,aAAqB;QAC5C,IAAI,MAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,MAAM,CAAC,CAAC,WAAW,EAAE,uBAAuB,CAAC,EAAE,aAAa,CAAC,CAAC;QAC/E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;gBACrC,MAAM,aAAa,CAAC,8BAA8B,EAAE,sCAAsC,aAAa,EAAE,EAAE;oBACzG,GAAG,UAAU,CAAC,KAAK,CAAC;iBACrB,CAAC,CAAC;YACL,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;YACpC,MAAM,aAAa,CAAC,8BAA8B,EAAE,qCAAqC,aAAa,EAAE,EAAE;gBACxG,aAAa;aACd,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,eAAe,CAAC,EAAE,aAAa,CAAC,CAAC;QAC1E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;gBACrC,MAAM,aAAa,CACjB,kCAAkC,EAClC,oCAAoC,aAAa,EAAE,EACnD,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,CACzB,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,YAAY,CAAC,aAAqB;QACtC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CACzB,CAAC,cAAc,EAAE,8BAA8B,EAAE,aAAa,CAAC,EAC/D,aAAa,CACd,CAAC;YACF,OAAO,MAAM,CAAC,MAAM;iBACjB,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;iBACnE,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,cAAc,CAAC,eAAe,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,aAAa,CAAC,aAAqB;QACvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC;YAChF,OAAO,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,cAAc,CAAC,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,cAAc,CAClB,aAAqB,EACrB,UAAkB,EAClB,MAAc,EACd,SAAkB;QAElB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,SAAS;gBACpB,CAAC,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC;gBAC1D,CAAC,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;YAC5C,MAAM,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,cAAc,CAAC,iBAAiB,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,IAAI,MAAM,EAAE,KAAK,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,cAAc,CAAC,aAAqB,EAAE,UAAkB;QAC5D,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,aAAa,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,cAAc,CAAC,iBAAiB,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Provider 层公共入口:仅暴露底层 Git、sidecar、DSH 只读端口及统一错误词汇;
3
+ * Worktree/Session 生命周期编排和业务冲突判断仍属于 Manage 层。
4
+ *
5
+ * Provider public surface: only low-level Git, sidecar, read-only DSH ports, and
6
+ * the shared error vocabulary are exported here; Worktree/Session lifecycle
7
+ * orchestration and policy conflicts remain the responsibility of Manage.
8
+ */
9
+ export { LocalGitAdapter } from './git.js';
10
+ export { WorkspaceShardedSidecarRepository, validateSidecarSnapshot, } from './sidecar.js';
11
+ export { SIDECAR_SCHEMA_VERSION, WorktreeProviderError, isWorktreeProviderError, providerError, } from './types.js';
12
+ export type { DshReadAdapter, DshSessionSummary, DshWorkspaceSummary, GitWorktreeAdapter, GitWorktreeInfo, SidecarMutation, SidecarSnapshot, SidecarStore, } from './types.js';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/provider/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EACL,iCAAiC,EACjC,uBAAuB,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,eAAe,EACf,YAAY,GACb,MAAM,YAAY,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Provider 层公共入口:仅暴露底层 Git、sidecar、DSH 只读端口及统一错误词汇;
3
+ * Worktree/Session 生命周期编排和业务冲突判断仍属于 Manage 层。
4
+ *
5
+ * Provider public surface: only low-level Git, sidecar, read-only DSH ports, and
6
+ * the shared error vocabulary are exported here; Worktree/Session lifecycle
7
+ * orchestration and policy conflicts remain the responsibility of Manage.
8
+ */
9
+ export { LocalGitAdapter } from './git.js';
10
+ export { WorkspaceShardedSidecarRepository, validateSidecarSnapshot, } from './sidecar.js';
11
+ export { SIDECAR_SCHEMA_VERSION, WorktreeProviderError, isWorktreeProviderError, providerError, } from './types.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/provider/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EACL,iCAAiC,EACjC,uBAAuB,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,aAAa,GACd,MAAM,YAAY,CAAC"}
@@ -0,0 +1,85 @@
1
+ import type { SessionBinding, WorktreeRecord } from '../contract/index.js';
2
+ import { type SidecarMutation, type SidecarSnapshot, type SidecarStore } from './types.js';
3
+ /**
4
+ * 校验完整 sidecar 快照及跨记录不变量:shard Workspace 身份一致、Worktree ID 唯一、
5
+ * 每个 Session 至多一个 active binding,且 active binding 必须指向 active Worktree。
6
+ *
7
+ * Validates a complete sidecar snapshot and its cross-record invariants: one
8
+ * Workspace identity per shard, unique Worktree IDs, at most one active binding
9
+ * per Session, and every active binding targeting an active Worktree.
10
+ *
11
+ * 提供 `generatedWorktreeRoot` 时,还要求 Provider 生成的 ID 合法且路径精确等于
12
+ * `<generatedWorktreeRoot>/<worktreeId>`。detached binding 可继续指向 removed 记录,
13
+ * 以保留删除后的关系历史。
14
+ *
15
+ * When `generatedWorktreeRoot` is supplied, Provider-generated IDs must be
16
+ * valid and paths must equal `<generatedWorktreeRoot>/<worktreeId>` exactly.
17
+ * Detached bindings may continue to reference removed records so relationships
18
+ * survive Worktree removal.
19
+ */
20
+ export declare function validateSidecarSnapshot(value: unknown, pathname: string, generatedWorktreeRoot?: string): SidecarSnapshot;
21
+ /**
22
+ * 位于 DSH Home 下、按 Workspace 分 shard 的 sidecar repository;它只持久化外部
23
+ * Worktree/Session 关系,不读取或写入 DSH 原始数据及 Workspace 业务文件。
24
+ *
25
+ * Workspace-sharded sidecar repository under DSH Home; it persists only the
26
+ * external Worktree/Session relationship and never reads or writes DSH-owned
27
+ * data or Workspace business files.
28
+ *
29
+ * 同一实例内的 mutation 按 Workspace 串行化,并通过同目录临时文件加 rename 提供完整旧版或
30
+ * 完整新版的原子可见性;这不等同于跨进程锁,也不承诺 fsync 级崩溃持久性。
31
+ *
32
+ * Mutations are serialized per Workspace within one instance, and a temporary
33
+ * file plus same-directory rename provides complete-old-or-complete-new atomic
34
+ * visibility. This is neither a cross-process lock nor an fsync-level crash
35
+ * durability guarantee.
36
+ */
37
+ export declare class WorkspaceShardedSidecarRepository implements SidecarStore {
38
+ readonly pluginRoot: string;
39
+ readonly worktreeRoot: string;
40
+ readonly workspaceRoot: string;
41
+ private readonly dshHome;
42
+ private readonly mutex;
43
+ constructor({ dshHome }: {
44
+ readonly dshHome: string;
45
+ });
46
+ /**
47
+ * 将 Workspace ID 编码为单个稳定文件名,所有 shard 都限定在 Provider 自有目录中。
48
+ * Encodes a Workspace ID into one stable filename, keeping every shard under
49
+ * the Provider-owned directory.
50
+ */
51
+ getShardPath(workspaceId: string): string;
52
+ /**
53
+ * 读取并完整校验 shard;文件不存在表示尚无关系并返回空快照,损坏内容绝不自动修复。
54
+ * Reads and fully validates a shard; a missing file means no relationships yet
55
+ * and returns an empty snapshot, while corrupt content is never auto-repaired.
56
+ */
57
+ read(workspaceId: string): Promise<SidecarSnapshot>;
58
+ /**
59
+ * 在 Workspace 互斥区内重新读取最新快照、应用转换、复验全部不变量,再决定是否原子写入。
60
+ * Re-reads the latest snapshot inside the Workspace mutex, applies the
61
+ * transition, revalidates every invariant, and only then decides whether to
62
+ * write atomically.
63
+ *
64
+ * mutation 抛错、返回非法快照或改变 Workspace 身份时,已有 shard 不会被本方法替换。
65
+ * If the mutation throws, returns an invalid snapshot, or changes Workspace
66
+ * identity, this method does not replace the existing shard.
67
+ */
68
+ mutate<T>(workspaceId: string, mutation: (snapshot: SidecarSnapshot) => SidecarMutation<T> | Promise<SidecarMutation<T>>): Promise<T>;
69
+ /**
70
+ * 按 Worktree ID 幂等插入;完全相同的记录直接复用,同一 ID 的不同 metadata 被视为损坏。
71
+ * Idempotently inserts by Worktree ID; an identical record is reused, while
72
+ * different metadata under the same ID is treated as corruption.
73
+ */
74
+ upsertWorktree(record: WorktreeRecord): Promise<WorktreeRecord>;
75
+ /**
76
+ * 按 Session ID 幂等插入 binding;完全相同的关系直接复用,任何既有不同关系都返回冲突。
77
+ * Idempotently inserts a binding by Session ID; an identical relationship is
78
+ * reused, while any different existing relationship returns a conflict.
79
+ */
80
+ upsertBinding(binding: SessionBinding): Promise<SessionBinding>;
81
+ private readFromDisk;
82
+ private writeToDisk;
83
+ private assertStorageBoundary;
84
+ }
85
+ //# sourceMappingURL=sidecar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidecar.d.ts","sourceRoot":"","sources":["../../src/provider/sidecar.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3E,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,YAAY,EAGlB,MAAM,YAAY,CAAC;AAyDpB;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,qBAAqB,CAAC,EAAE,MAAM,GAC7B,eAAe,CAqEjB;AA4DD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,iCAAkC,YAAW,YAAY;IACpE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAE/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;gBAE9B,EAAE,OAAO,EAAE,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAUrD;;;;OAIG;IACH,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAIzC;;;;OAIG;IACG,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAIzD;;;;;;;;;OASG;IACG,MAAM,CAAC,CAAC,EACZ,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,eAAe,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GACxF,OAAO,CAAC,CAAC,CAAC;IAab;;;;OAIG;IACG,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAsBrE;;;;OAIG;IACG,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;YAmBvD,YAAY;YAiCZ,WAAW;YA8CX,qBAAqB;CAuBpC"}