dsh-git-worktree 0.2.0 → 0.3.1

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 (49) hide show
  1. package/CHANGELOG.md +52 -2
  2. package/README.en.md +334 -0
  3. package/README.md +300 -65
  4. package/lib/adapters/lookup.d.ts +4 -2
  5. package/lib/adapters/lookup.js +31 -3
  6. package/lib/adapters/lookup.js.map +1 -1
  7. package/lib/adapters/registry.js +1 -0
  8. package/lib/adapters/registry.js.map +1 -1
  9. package/lib/client/console-remote/adapter.js +2 -0
  10. package/lib/client/console-remote/adapter.js.map +1 -1
  11. package/lib/client/review-console/ReviewActions.js +20 -5
  12. package/lib/client/review-console/ReviewActions.js.map +1 -1
  13. package/lib/client/review-console/review-console.styles.js +2 -1
  14. package/lib/client/review-console/review-console.styles.js.map +1 -1
  15. package/lib/client/styles.js +1 -0
  16. package/lib/client/styles.js.map +1 -1
  17. package/lib/client/target-console/WorktreeReviewStatus.js +34 -0
  18. package/lib/client/target-console/WorktreeReviewStatus.js.map +1 -1
  19. package/lib/client.js +100 -9
  20. package/lib/commands.js +17 -2
  21. package/lib/commands.js.map +1 -1
  22. package/lib/console-contract.d.ts +17 -0
  23. package/lib/console-contract.js.map +1 -1
  24. package/lib/console-host/control-plane.d.ts +3 -1
  25. package/lib/console-host/control-plane.js +65 -6
  26. package/lib/console-host/control-plane.js.map +1 -1
  27. package/lib/console-host/projection.js +5 -0
  28. package/lib/console-host/projection.js.map +1 -1
  29. package/lib/console-host/service.d.ts +2 -0
  30. package/lib/console-host/service.js +12 -0
  31. package/lib/console-host/service.js.map +1 -1
  32. package/lib/console-remote/descriptors.js +9 -0
  33. package/lib/console-remote/descriptors.js.map +1 -1
  34. package/lib/console-remote/remote.d.ts +2 -0
  35. package/lib/console-remote/schemas.js +2 -0
  36. package/lib/console-remote/schemas.js.map +1 -1
  37. package/lib/index.d.ts +4 -2
  38. package/lib/index.js.map +1 -1
  39. package/lib/ports.d.ts +2 -0
  40. package/lib/session-checkout-module.js +250 -8
  41. package/lib/session-checkout-module.js.map +1 -1
  42. package/lib/tools.d.ts +2 -1
  43. package/lib/tools.js +80 -1
  44. package/lib/tools.js.map +1 -1
  45. package/package.json +1 -1
  46. package/scripts/check-publish.mjs +1 -1
  47. package/scripts/dev-dsh-lib.mjs +83 -27
  48. package/scripts/dev-dsh.mjs +18 -12
  49. package/README.zh.md +0 -115
package/lib/tools.d.ts CHANGED
@@ -2,7 +2,8 @@
2
2
  * Model-facing worktree tools. Destructive delivery actions are deliberately
3
3
  * absent: Finish/Discard/Remove are human commands surfaced by the client
4
4
  * ToolView. The model can reserve a real target session, inspect its own
5
- * scoped worktrees, and stop at Ready for Review.
5
+ * scoped worktrees, invalidate an unsynced review before further file edits,
6
+ * safely begin a cleaned same-session iteration, and stop at Ready for Review.
6
7
  * @module dsh-git-worktree/tools
7
8
  */
8
9
  import type { Context } from '@deepseek-ai/cordis';
package/lib/tools.js CHANGED
@@ -2,7 +2,8 @@
2
2
  * Model-facing worktree tools. Destructive delivery actions are deliberately
3
3
  * absent: Finish/Discard/Remove are human commands surfaced by the client
4
4
  * ToolView. The model can reserve a real target session, inspect its own
5
- * scoped worktrees, and stop at Ready for Review.
5
+ * scoped worktrees, invalidate an unsynced review before further file edits,
6
+ * safely begin a cleaned same-session iteration, and stop at Ready for Review.
6
7
  * @module dsh-git-worktree/tools
7
8
  */
8
9
  import { randomUUID } from 'node:crypto';
@@ -107,6 +108,83 @@ export function registerTools(ctx, module) {
107
108
  },
108
109
  presentCall: () => ({ card: 'generic', title: 'List managed worktrees', kind: 'other', rawInput: {} }),
109
110
  }));
111
+ ctx.tools.register(defineTool({
112
+ name: 'worktree_resume_revision',
113
+ description: '当前 Isolated Session 处于尚未同步 Local 的 Ready for Review,且用户提出新的代码或文件修改时,必须先自动调用本工具使旧 Review 失效并恢复同一轮 Working,然后直接继续执行请求。纯讨论、问答或补充信息不要调用;不要要求用户点击恢复编辑,也不要先同步 Local。',
114
+ parameters: {},
115
+ output: {
116
+ schema: {
117
+ type: 'object',
118
+ additionalProperties: false,
119
+ properties: {
120
+ kind: { type: 'string', required: true },
121
+ checkoutId: { type: 'string', required: true },
122
+ iteration: { type: 'number', required: true },
123
+ revision: { type: 'number', required: true },
124
+ phase: { type: 'string', required: true },
125
+ sessionId: { type: 'string', required: true },
126
+ },
127
+ },
128
+ render: (_args, value) => renderJson(value),
129
+ },
130
+ async execute(_args, exec) {
131
+ const sessionId = sessionIdOf(exec.agent);
132
+ const current = await module.inspect(sessionId);
133
+ if (current.delivery?.state !== 'ready_for_review') {
134
+ throw new Error(`当前 Worktree 没有可恢复的未同步 Review: ${current.delivery?.state ?? 'unknown'}`);
135
+ }
136
+ const target = await module.resumeRevision(sessionId, current.revision, current.delivery.review.reviewId);
137
+ if (target.delivery?.state !== 'working') {
138
+ throw new Error(`Worktree 未恢复到 working 状态: ${target.delivery?.state ?? 'unknown'}`);
139
+ }
140
+ return {
141
+ kind: 'worktree_revision_resumed',
142
+ checkoutId: target.checkout.id,
143
+ iteration: target.delivery.iteration,
144
+ revision: target.revision,
145
+ phase: target.checkout.phase,
146
+ sessionId,
147
+ };
148
+ },
149
+ presentCall: () => ({ card: 'generic', title: 'Resume Worktree revision', kind: 'other', rawInput: {} }),
150
+ }));
151
+ ctx.tools.register(defineTool({
152
+ name: 'worktree_begin_next_iteration',
153
+ description: '当当前 Isolated Session 已交付并完成 cleanup,而用户在同一对话中提出新的代码或文件修改时,先调用本工具安全重建同一个 immutable cwd 并进入下一轮,然后继续执行用户请求。不要改用 worktree_create;retained 或 cleanup_pending 状态不能调用。',
154
+ parameters: {},
155
+ output: {
156
+ schema: {
157
+ type: 'object',
158
+ additionalProperties: false,
159
+ properties: {
160
+ kind: { type: 'string', required: true },
161
+ checkoutId: { type: 'string', required: true },
162
+ iteration: { type: 'number', required: true },
163
+ phase: { type: 'string', required: true },
164
+ currentOid: { type: 'string', required: true },
165
+ sessionId: { type: 'string', required: true },
166
+ },
167
+ },
168
+ render: (_args, value) => renderJson(value),
169
+ },
170
+ async execute(_args, exec) {
171
+ const sessionId = sessionIdOf(exec.agent);
172
+ const current = await module.inspect(sessionId);
173
+ const target = await module.beginNextIteration(sessionId, current.revision);
174
+ if (target.delivery?.state !== 'working') {
175
+ throw new Error(`下一轮 Worktree 未进入 working 状态: ${target.delivery?.state ?? 'unknown'}`);
176
+ }
177
+ return {
178
+ kind: 'worktree_next_iteration_started',
179
+ checkoutId: target.checkout.id,
180
+ iteration: target.delivery.iteration,
181
+ phase: target.checkout.phase,
182
+ currentOid: target.current.oid,
183
+ sessionId,
184
+ };
185
+ },
186
+ presentCall: () => ({ card: 'generic', title: 'Start next Worktree iteration', kind: 'other', rawInput: {} }),
187
+ }));
110
188
  ctx.tools.register(defineTool({
111
189
  name: 'worktree_ready_for_review',
112
190
  description: 'Isolated Session 的最后一个模型动作:把完整交付报告、验证证据和建议 Commit Message 仅写入本工具参数,然后立即停止。不要在调用前后用普通回复重复完整报告;最多用一句话提示用户通过底部验收条处理。用户会显式决定是否提交或放弃,模型不得自动提交或清理。',
@@ -157,6 +235,7 @@ export function registerTools(ctx, module) {
157
235
  state: { type: 'string', required: true },
158
236
  reviewId: { type: 'string', required: true },
159
237
  revision: { type: 'number', required: true },
238
+ iteration: { type: 'number', required: true },
160
239
  changedFiles: { type: 'array', required: true, items: { type: 'string' } },
161
240
  },
162
241
  },
package/lib/tools.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-git-worktree",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Experimental Git worktree Session Targets for DeepSeek Harness with real isolated sessions, review ToolViews, human-confirmed delivery, and safe cleanup.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -94,7 +94,7 @@ try {
94
94
  if (hostContribution?.package !== manifest.name || hostContribution.face !== 'host') fail('./typert has invalid package/face identity')
95
95
  if (remoteContribution?.package !== manifest.name) fail('./remote has invalid package identity')
96
96
  if (hostContribution.invocations !== remoteContribution.descriptors) fail('./typert and ./remote must share one descriptor array instance')
97
- const expectedRemoteMethods = ['current', 'list', 'create', 'inspect', 'reviewDiff', 'preflight', 'preview', 'rollbackPreview', 'discard', 'finalize', 'finalizePreview', 'setRetention', 'retryCleanup']
97
+ const expectedRemoteMethods = ['current', 'list', 'create', 'inspect', 'reviewDiff', 'preflight', 'preview', 'resumeRevision', 'rollbackPreview', 'discard', 'finalize', 'finalizePreview', 'setRetention', 'retryCleanup', 'beginNextIteration']
98
98
  if (JSON.stringify(hostContribution.invocations.map(value => value.method)) !== JSON.stringify(expectedRemoteMethods)) {
99
99
  fail(`manual Remote methods differ from the required surface: ${hostContribution.invocations.map(value => value.method).join(', ')}`)
100
100
  }
@@ -199,6 +199,11 @@ function isHarnessRoot(path) {
199
199
  && existsSync(join(path, 'apps', 'cli', 'src', 'bin.ts'))
200
200
  }
201
201
 
202
+ function isHarnessSourceReady(path) {
203
+ return isHarnessRoot(path)
204
+ && existsSync(join(path, 'node_modules', 'tsx', 'package.json'))
205
+ }
206
+
202
207
  export function discoverHarnessRoot(projectRoot, environment = process.env) {
203
208
  if (environment.DSH_HARNESS_ROOT) {
204
209
  const configured = resolve(environment.DSH_HARNESS_ROOT)
@@ -210,8 +215,14 @@ export function discoverHarnessRoot(projectRoot, environment = process.env) {
210
215
  try {
211
216
  const commonDir = git(projectRoot, ['rev-parse', '--path-format=absolute', '--git-common-dir'])
212
217
  const localProjectRoot = dirname(resolve(projectRoot, commonDir))
213
- const candidate = join(dirname(localProjectRoot), 'DeepSeek', 'deepseek-harness')
214
- return isHarnessRoot(candidate) ? candidate : undefined
218
+ const parent = dirname(localProjectRoot)
219
+ const candidates = [
220
+ join(parent, 'deepseek-harness'),
221
+ join(dirname(parent), 'deepseek-harness'),
222
+ join(parent, 'DeepSeek', 'deepseek-harness'),
223
+ ]
224
+ const validCandidates = candidates.filter(isHarnessRoot)
225
+ return validCandidates.find(isHarnessSourceReady) ?? validCandidates[0]
215
226
  } catch {
216
227
  return undefined
217
228
  }
@@ -221,34 +232,51 @@ export function executable(name, platform = process.platform) {
221
232
  return platform === 'win32' ? `${name}.cmd` : name
222
233
  }
223
234
 
224
- export function createDshLaunch(options) {
235
+ export function createDshInvocation(options) {
236
+ const cwd = options.cwd ?? options.projectRoot
237
+ const args = options.args ?? []
225
238
  if (!options.harnessRoot) {
226
239
  return {
227
240
  command: executable('dsh', options.platform),
228
- args: ['--profile', options.profile, '--port', String(options.port)],
229
- cwd: options.workspaceRoot,
241
+ args,
242
+ cwd,
230
243
  source: false,
231
244
  }
232
245
  }
233
- if (!isHarnessRoot(options.harnessRoot)) {
234
- throw new Error(`Harness source checkout is invalid: ${options.harnessRoot}`)
246
+ const harnessRoot = resolve(options.harnessRoot)
247
+ if (!isHarnessRoot(harnessRoot)) {
248
+ throw new Error(`Harness source checkout is invalid: ${harnessRoot}`)
249
+ }
250
+ if (!isHarnessSourceReady(harnessRoot)) {
251
+ throw new Error(
252
+ `Harness source checkout is not prepared: ${harnessRoot}. Run pnpm --dir "${harnessRoot}" install before dev preview.`,
253
+ )
235
254
  }
236
255
  return {
237
256
  command: executable('pnpm', options.platform),
238
257
  args: [
239
- '--dir', options.harnessRoot,
258
+ '--dir', harnessRoot,
240
259
  'exec', 'node', '--import', 'tsx/esm',
241
260
  join(options.projectRoot, 'scripts', 'dsh-source-runner.mjs'),
242
- options.workspaceRoot,
243
- join(options.harnessRoot, 'apps', 'cli', 'src', 'bin.ts'),
244
- '--profile', options.profile,
245
- '--port', String(options.port),
261
+ cwd,
262
+ join(harnessRoot, 'apps', 'cli', 'src', 'bin.ts'),
263
+ ...args,
246
264
  ],
247
265
  cwd: options.projectRoot,
248
266
  source: true,
249
267
  }
250
268
  }
251
269
 
270
+ export function createDshLaunch(options) {
271
+ return createDshInvocation({
272
+ projectRoot: options.projectRoot,
273
+ harnessRoot: options.harnessRoot,
274
+ platform: options.platform,
275
+ cwd: options.workspaceRoot,
276
+ args: ['--profile', options.profile, '--port', String(options.port)],
277
+ })
278
+ }
279
+
252
280
  function assertWindowsCommandSafe(command, args) {
253
281
  for (const value of [command, ...args]) {
254
282
  if (/[\0\r\n"&|<>^%!]/.test(value)) {
@@ -371,11 +399,46 @@ function repairMissingCurrentProfileArchive(options, archivePath) {
371
399
  copyFileSync(archivePath, previous)
372
400
  }
373
401
 
402
+ function assertDshRuntimeAvailable(options) {
403
+ if (options.harnessRoot) {
404
+ createDshInvocation({
405
+ projectRoot: options.projectRoot,
406
+ harnessRoot: options.harnessRoot,
407
+ platform: options.platform,
408
+ args: [],
409
+ })
410
+ return
411
+ }
412
+ if (options.run) return
413
+ try {
414
+ runProcess(executable('dsh', options.platform), ['--version'], { capture: true })
415
+ } catch (cause) {
416
+ throw new Error(
417
+ 'No Harness source checkout was selected and the installed dsh CLI is unavailable. Pass --harness <path>, set DSH_HARNESS_ROOT, or install dsh on PATH.',
418
+ { cause },
419
+ )
420
+ }
421
+ }
422
+
423
+ function runDsh(options, args, runOptions = {}) {
424
+ const invocation = createDshInvocation({
425
+ projectRoot: options.projectRoot,
426
+ harnessRoot: options.harnessRoot,
427
+ platform: options.platform,
428
+ cwd: runOptions.cwd ?? options.projectRoot,
429
+ args,
430
+ })
431
+ return (options.run ?? runProcess)(invocation.command, invocation.args, {
432
+ cwd: invocation.cwd,
433
+ ...(runOptions.capture === true ? { capture: true } : {}),
434
+ })
435
+ }
436
+
374
437
  /** Build, pack and install only the current local snapshot. No registry publish occurs. */
375
438
  export function installLocalSnapshot(options) {
376
439
  const run = options.run ?? runProcess
377
440
  const pnpm = executable('pnpm', options.platform)
378
- const dsh = executable('dsh', options.platform)
441
+ assertDshRuntimeAvailable(options)
379
442
  mkdirSync(options.cacheRoot, { recursive: true })
380
443
 
381
444
  if (!existsSync(join(options.projectRoot, 'node_modules'))) {
@@ -399,7 +462,7 @@ export function installLocalSnapshot(options) {
399
462
  scripts: {},
400
463
  }
401
464
  writeFileSync(join(stagingRoot, 'package.json'), `${JSON.stringify(stagedManifest, null, 2)}\n`)
402
- for (const entry of ['lib', 'cordis.patch.yml', 'README.md', 'README.zh.md', 'LICENSE']) {
465
+ for (const entry of ['lib', 'cordis.patch.yml', 'README.md', 'README.en.md', 'LICENSE']) {
403
466
  const source = join(options.projectRoot, entry)
404
467
  if (existsSync(source)) copyPackageEntry(source, join(stagingRoot, entry))
405
468
  }
@@ -413,15 +476,12 @@ export function installLocalSnapshot(options) {
413
476
  // replace it. Repair only our own missing cache path with the new snapshot;
414
477
  // after the add succeeds the obsolete recovery copy becomes collectible.
415
478
  repairMissingCurrentProfileArchive(options, archivePath)
416
- run(dsh, ['plugin', '--profile', options.profile, 'add', archivePath], { cwd: options.projectRoot })
479
+ runDsh(options, ['plugin', '--profile', options.profile, 'add', archivePath])
417
480
  const referencedArchive = profileArchiveReference(options)
418
481
  if (comparablePath(referencedArchive) !== comparablePath(archivePath)) {
419
482
  throw new Error(`DSH profile ${options.profile} still references ${referencedArchive}; preserving old and new archives for recovery.`)
420
483
  }
421
- const dump = run(dsh, ['--profile', options.profile, '--dump-config'], {
422
- cwd: options.projectRoot,
423
- capture: true,
424
- }).stdout
484
+ const dump = runDsh(options, ['--profile', options.profile, '--dump-config'], { capture: true }).stdout
425
485
  if (!dump.includes('dsh-git-worktree')) {
426
486
  throw new Error(`Profile ${options.profile} installed the tarball but did not compose dsh-git-worktree.`)
427
487
  }
@@ -430,10 +490,8 @@ export function installLocalSnapshot(options) {
430
490
  }
431
491
 
432
492
  export function removeLocalSnapshot(options) {
433
- const run = options.run ?? runProcess
434
- run(executable('dsh', options.platform), [
435
- 'plugin', '--profile', options.profile, 'remove', 'dsh-git-worktree',
436
- ], { cwd: options.projectRoot })
493
+ assertDshRuntimeAvailable(options)
494
+ runDsh(options, ['plugin', '--profile', options.profile, 'remove', 'dsh-git-worktree'])
437
495
  if (existsSync(options.cacheRoot)) {
438
496
  for (const entry of readdirSync(options.cacheRoot)) {
439
497
  if (/^dsh-git-worktree-\d+\.tgz$/.test(entry)) rmSync(join(options.cacheRoot, entry), { force: true })
@@ -442,10 +500,8 @@ export function removeLocalSnapshot(options) {
442
500
  }
443
501
 
444
502
  export function smokeLocalSnapshot(options) {
445
- const run = options.run ?? runProcess
446
- const dump = run(executable('dsh', options.platform), [
447
- '--profile', options.profile, '--dump-config',
448
- ], { cwd: options.projectRoot, capture: true }).stdout
503
+ assertDshRuntimeAvailable(options)
504
+ const dump = runDsh(options, ['--profile', options.profile, '--dump-config'], { capture: true }).stdout
449
505
  if (!dump.includes('dsh-git-worktree')) {
450
506
  throw new Error(`Profile ${options.profile} does not compose dsh-git-worktree.`)
451
507
  }
@@ -27,14 +27,17 @@ function printUsage() {
27
27
 
28
28
  Usage:
29
29
  pnpm run dev:dsh -- [--profile web] [--repo <git-root>] [--port 3081] [--harness <path>]
30
- pnpm run dev:dsh:install -- [--profile web]
31
- pnpm run dev:dsh:smoke -- [--profile web]
32
- pnpm run dev:dsh:remove -- [--profile web]
30
+ pnpm run dev:dsh:install -- [--profile web] [--harness <path>]
31
+ pnpm run dev:dsh:smoke -- [--profile web] [--harness <path>]
32
+ pnpm run dev:dsh:remove -- [--profile web] [--harness <path>]
33
33
 
34
34
  The install path is a local tarball under the OS temporary directory. Nothing is
35
- published to npm or pushed to Git. A sibling Harness source checkout is used
36
- when available; override with DSH_HARNESS_ROOT or --harness. Without --repo, a
37
- marker-protected disposable Git repository is created at:
35
+ published to npm or pushed to Git. Nearby Harness source checkouts are scanned
36
+ and a candidate with node_modules/tsx is preferred; an arbitrary checkout can be
37
+ selected with DSH_HARNESS_ROOT or --harness. Every profile and launch command
38
+ then uses that source CLI instead of a globally installed dsh executable. An
39
+ explicit checkout without dependencies fails early with its pnpm install command.
40
+ Without --repo, a marker-protected disposable Git repository is created at:
38
41
  ${defaults.repo}
39
42
  `)
40
43
  }
@@ -45,24 +48,27 @@ try {
45
48
  process.exitCode = 0
46
49
  } else {
47
50
  const options = parseDevDshArgs(process.argv.slice(2), defaults)
51
+ const runtime = {
52
+ projectRoot,
53
+ profile: options.profile,
54
+ harnessRoot: options.harnessRoot,
55
+ }
48
56
  if (options.mode === 'install') {
49
57
  const installed = installLocalSnapshot({
50
- projectRoot,
51
- profile: options.profile,
58
+ ...runtime,
52
59
  cacheRoot,
53
60
  })
54
61
  console.log(`\nLocal snapshot installed in profile "${options.profile}".`)
55
62
  console.log(`Archive retained for profile reproducibility: ${installed.archivePath}`)
56
63
  } else if (options.mode === 'smoke') {
57
- smokeLocalSnapshot({ projectRoot, profile: options.profile })
64
+ smokeLocalSnapshot(runtime)
58
65
  console.log(`Profile "${options.profile}" composes dsh-git-worktree.`)
59
66
  } else if (options.mode === 'remove') {
60
- removeLocalSnapshot({ projectRoot, profile: options.profile, cacheRoot })
67
+ removeLocalSnapshot({ ...runtime, cacheRoot })
61
68
  console.log(`Removed dsh-git-worktree from profile "${options.profile}" and cleared local archives.`)
62
69
  } else {
63
70
  const installed = installLocalSnapshot({
64
- projectRoot,
65
- profile: options.profile,
71
+ ...runtime,
66
72
  cacheRoot,
67
73
  })
68
74
  const fixture = ensureDevFixture(options.repo, { explicit: options.repoExplicit })
package/README.zh.md DELETED
@@ -1,115 +0,0 @@
1
- # dsh-git-worktree
2
-
3
- 面向 DeepSeek Harness 的**实验性** Git Worktree Session Target 插件。它保留 Domi 中经过生产验证的 checkout / apply engine 安全核心,并按 Harness 的权威 Workspace / Session cwd 模型重做产品闭环。
4
-
5
- > 当前范围:真实隔离 Session、Harness-native Session Target/Worktree Console、可撤回的 Local Preview、验收提交/撤回/跳过验收直接提交、项目级验收槽位、持久恢复凭据、保留策略、崩溃恢复、指纹 CAS 与保守清理。它还不是 Domi 的跨项目全局 Worktree Manager。
6
-
7
- ## 工作流程
8
-
9
- 1. 在 blank/new Local Session 中,用户点击 composer 工具栏的 **Worktree** 开关后先看到确认弹窗。取消不会创建任何资源;确认后插件才冻结 Local composer、创建 isolated target,把尚未发送的文本/图片草稿迁移过去并打开 target。首条消息仍由用户在 target 的原生 composer 中发送,任何 prompt 都不会先进入 Local。
10
- 2. 已存在的 Local Session 仍可通过模型拥有的 `worktree_create` ToolView 创建 target。主流程稳定前,原项目级 **Worktree** 标签页暂不挂载。
11
- 3. 插件在仓库同级容器中创建唯一 detached Worktree(不可用时回退到插件 stateDir),并预留一个独立 target Session ID;源 Session 始终保持 Local。
12
- 4. Harness 把 Worktree 路径注册为 Workspace,使用 Host 预留的精确 ID 创建并打开 Session。持久化 Session header 的 cwd 才是权威 Session Target。
13
- 5. Agent 只在该 isolated cwd 中修改和验证,完成后把 `worktree_ready_for_review` 作为最后一个模型操作。
14
- 6. Worktree Ready 后,target composer 上方常驻 Domi 式中文状态条;紧凑验收卡默认只展示摘要、验证状态、文件数量和折叠的测试证据,不再展示 Diff/Inspect 或平铺多个保留按钮。
15
- 7. Ready 主操作是**同步到 Local 验收**:Host 先执行只读 preflight,再把精确 review 增量同步成不提交、可撤回的 Local Preview。Preview active 后主操作变为**验收通过并提交**;更多菜单可撤回本次预览并让 Worktree 回到继续修改状态。Ready 更多菜单还提供**跳过验收,直接提交**与放弃任务。
16
- 8. Preview、rollback 和 finalize 都绑定 revision、review ID、HEAD 与 fingerprint CAS。同一 Local 项目同时只允许一个活动 Preview;放弃 active Preview 时必须先安全 rollback。rollback 可在分支未变且 HEAD 仅安全快进时,通过三方树证明只移除 Preview、保留新 Commit 与原 Local 层;切分支、改写历史、Preview 已进入 Commit 或内容冲突仍 fail closed,保留 Worktree 与恢复凭据,绝不覆盖用户修改。
17
-
18
- ## 能力面
19
-
20
- ### 模型工具
21
-
22
- | 工具 | 作用 |
23
- | --- | --- |
24
- | `worktree_create` | 预留唯一 Worktree 与独立 owner Session;不会修改当前 Session cwd |
25
- | `worktree_list` | 仅列出当前 Session 在原始项目中拥有或创建的 Worktree |
26
- | `worktree_ready_for_review` | 持久化完整交付报告并停止,等待用户验收 |
27
-
28
- Apply、Finish、Discard、Remove **不再作为模型工具**暴露。模型参数不能替代可信的用户授权。
29
-
30
- ### Harness-native Worktree Console
31
-
32
- Client 通过官方 Gateway 挂载本包拥有的 strict Typert Remote contribution。blank Local Session 会在 Harness 官方 `conversation.input.left` composer 工具栏 Slot 中显示紧凑的 **Worktree** 开关;点击只打开确认弹窗,确认后才准备 Host 分配的 target,并在导航前迁移尚未发送的文本/图片草稿,标准 Harness Send 仍是唯一 prompt 路径。每个持久 Session 都可看到只读 target 状态胶囊;Ready 后由 `conversation.input.dock` 显示始终可见的紧凑验收条,只保留一个主操作和“更多”菜单。高级 `WorktreeConsoleView`、Host 控制面和 strict Remote 方法仍完整保留,但 v0.2.0 暂不挂载项目级 `conversation.view` 标签页。列表行不包含路径;只有通过身份验证的 `current`、`create` 或 `inspect` 才返回 managed root。
33
-
34
- ### 用户命令
35
-
36
- ```text
37
- /worktree status
38
- /worktree list
39
- /worktree finalize [cleanup|retain_24h|retain_3d|retain_manual]
40
- /worktree finish <自定义 Commit Message>
41
- /worktree discard
42
- /worktree remove <checkoutId>
43
- ```
44
-
45
- Client 通过 strict Remote 调用 `preflight`、`preview`、`rollbackPreview`、`finalizePreview`,或在用户明确选择跳过验收时调用 `finalize`。所有路径携带精确 review ID/revision;提交路径还携带用户确认的 1–500 字符 Commit Message 与 retention。Host 会再次校验 caller、project、managed cwd、review、HEAD/fingerprint 和 Local CAS;历史卡片、Ready 后新增修改或 Local 漂移都 fail closed。
46
-
47
- ## 安全不变量
48
-
49
- - source 与 target 使用不同 Session ID;不会再用插件私有 registry 把 Local Session 伪装成 isolated。
50
- - Worktree 开关的确认弹窗不创建资源;用户确认后 Pre-session 事务才同步 block source composer。只有 managed Workspace、精确 target Session、草稿迁移与 source draft revision CAS 全部成功后才打开 target,失败时 source 草稿保持原样。
51
- - target Harness Workspace 必须 canonicalize 到记录的 managed root,否则访问 fail closed。
52
- - 新 Worktree 使用 `<repo>--worktrees/<repo>--<checkout-short>--worktree`;短 ID 冲突时扩展 identity,不覆盖未知目录。不安全 sibling 回退到 `<stateDir>/worktrees/<repository-key>/`,旧 registry 路径仍可管理。
53
- - 已走过旧版不可逆 Apply 的历史记录禁止自动 Finish / Discard,必须先人工核对 Local。
54
- - list 与 manage 都按真实 caller 作用域过滤;持久化 `ownerSessionId` 本身不是授权。
55
- - Preview receipt 在触碰 Local 前持久化并保留 Local working tree、index、Preview tree 与 Isolated snapshot;rollback/finalize 可在 Host 重启后恢复;同分支 fast-forward rollback 会先证明新 HEAD 未包含 Preview,再重放原 Local 层并做写前/写后 CAS。
56
- - 同一 canonical Local root 只有一个活动验收槽位;Preview detached 会释放槽位,但保留恢复证据。
57
- - Finish 保留 Local 无关 staged/working 状态,并拒绝 stale Local / stale Isolated;active Preview 的 Discard 必须先安全 rollback。
58
- - 清理前验证路径、Git common-dir、git-dir、目录身份和最终指纹;不确定残余会保留或 quarantine。
59
-
60
- ## 安装
61
-
62
- ```bash
63
- # npm(推荐)
64
- dsh plugin --profile web add dsh-git-worktree
65
-
66
- # Git 源码安装(prepare 构建 Host + Client bundle)
67
- dsh plugin --profile web add github:wloops/dsh-git-worktree#v0.2.0
68
- ```
69
-
70
- pnpm >= 10 可能会拦截 Git 依赖的构建脚本;在 profile 的 `pnpm-workspace.yaml` 的 `allowBuilds` 下加入 `dsh-git-worktree: true` 后重试。
71
-
72
- 要求 DeepSeek Harness `0.1.0-rc.6` 包线;交互 ToolView 需要 Web Client。
73
-
74
- ## 一键本地开发测试
75
-
76
- 持续迭代时,在任意当前 checkout(包括 Domi managed Worktree)中运行:
77
-
78
- ```bash
79
- pnpm run dev:dsh
80
- ```
81
-
82
- 该命令会自动执行 typecheck/build,把**当前 checkout 快照**打成 OS 临时目录中的本地 tarball,安装到 `web` profile,检查组合配置,创建或复用 marker 保护的临时 Git fixture,最后从 fixture cwd 启动 `dsh web`(默认 `http://127.0.0.1:3081`)。如果检测到同一开发目录下的 `DeepSeek/deepseek-harness` 源码 checkout,会优先用它启动 DSH,同时仍把 Session workspace 保持为 fixture;也可用 `DSH_HARNESS_ROOT` 或 `--harness <path>` 指定。找不到源码 checkout 时才使用 PATH 中已安装的 `dsh`。它不会运行 `npm publish`、Git push 或创建 tag,也不会留下指向已清理 managed Worktree 的软链接。profile 当前引用的 tarball 会保留,成功安装新快照后会清理旧 tarball。
83
-
84
- 常用入口:
85
-
86
- ```bash
87
- # 只安装当前快照并验证配置,不启动 Web
88
- pnpm run dev:dsh:install
89
-
90
- # 只检查已安装 profile
91
- pnpm run dev:dsh:smoke
92
-
93
- # 使用现有 Git 仓库或其他端口/profile
94
- pnpm run dev:dsh -- --repo G:/path/to/repo --port 4090 --profile web
95
-
96
- # 显式从 profile 卸载,并清理本地开发 tarball
97
- pnpm run dev:dsh:remove
98
- ```
99
-
100
- 默认 fixture 位于系统临时目录 `dsh-git-worktree-dev/fixture`。它只会初始化不存在或为空的目录;复用时必须具有插件 marker、Git 根身份正确、状态干净且没有遗留 linked Worktree。遇到未知文件、脏状态、符号链接或残留 Worktree 会 fail closed,脚本绝不会自动 reset 或删除内容。显式 `--repo` 必须指向已经存在的 Git 根,脚本只验证、不初始化或改写它。
101
-
102
- ## 当前限制
103
-
104
- - 旧 `worktree_apply` 入口仍禁用;公开交付路径只允许用户触发的 Preview/rollback/finalize/direct finish。
105
- - 尚无跨项目全局侧栏 Manager。项目级 Worktree Console 实现仍保留用于恢复与后续重做,但其可见 `conversation.view` 标签页暂不挂载。
106
- - Harness 仍未开放 Workflow `agent({ isolation })`。
107
- - 子 Agent 继承父 Session cwd;只有父 Session 已真实进入 Worktree 后才形成隔离。
108
- - dependency snapshot、完整 collaborator handoff UI 延后。
109
- - 选择立即清理后,isolated Session 的 cwd 会被删除,因此该 Session 视为终态;后续应回到 Local 或开启下一轮 Session。
110
-
111
- Domi 与 Harness 的边界见 [docs/PORTING.md](docs/PORTING.md),发布门禁见 [docs/RELEASE.md](docs/RELEASE.md)。
112
-
113
- ## 许可证
114
-
115
- MIT