dsh-git-worktree 0.2.0 → 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.
Files changed (44) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +133 -61
  3. package/README.zh.md +132 -60
  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/target-console/WorktreeReviewStatus.js +34 -0
  14. package/lib/client/target-console/WorktreeReviewStatus.js.map +1 -1
  15. package/lib/client.js +97 -8
  16. package/lib/commands.js +17 -2
  17. package/lib/commands.js.map +1 -1
  18. package/lib/console-contract.d.ts +17 -0
  19. package/lib/console-contract.js.map +1 -1
  20. package/lib/console-host/control-plane.d.ts +3 -1
  21. package/lib/console-host/control-plane.js +65 -6
  22. package/lib/console-host/control-plane.js.map +1 -1
  23. package/lib/console-host/projection.js +5 -0
  24. package/lib/console-host/projection.js.map +1 -1
  25. package/lib/console-host/service.d.ts +2 -0
  26. package/lib/console-host/service.js +12 -0
  27. package/lib/console-host/service.js.map +1 -1
  28. package/lib/console-remote/descriptors.js +9 -0
  29. package/lib/console-remote/descriptors.js.map +1 -1
  30. package/lib/console-remote/remote.d.ts +2 -0
  31. package/lib/console-remote/schemas.js +2 -0
  32. package/lib/console-remote/schemas.js.map +1 -1
  33. package/lib/index.d.ts +4 -2
  34. package/lib/index.js.map +1 -1
  35. package/lib/ports.d.ts +2 -0
  36. package/lib/session-checkout-module.js +250 -8
  37. package/lib/session-checkout-module.js.map +1 -1
  38. package/lib/tools.d.ts +2 -1
  39. package/lib/tools.js +80 -1
  40. package/lib/tools.js.map +1 -1
  41. package/package.json +1 -1
  42. package/scripts/check-publish.mjs +1 -1
  43. package/scripts/dev-dsh-lib.mjs +82 -26
  44. package/scripts/dev-dsh.mjs +18 -12
package/CHANGELOG.md CHANGED
@@ -2,6 +2,39 @@
2
2
 
3
3
  本项目的显著变更记录在此文件中。版本号遵循 Semantic Versioning;在 `0.x` 阶段,minor 版本可能包含需要迁移的公开能力调整。
4
4
 
5
+ ## [0.3.0] - 2026-08-17
6
+
7
+ `0.3.0` 完善同一 isolated Session 的连续修改体验:未同步 Review 可以安全恢复编辑,成功交付并 cleanup 后也能保留 Session ID、immutable cwd 与完整对话开始下一轮。
8
+
9
+ ### Added
10
+
11
+ - cleanup 后在原 isolated Session 中开始 iteration + 1;新 checkout 从最新 Local HEAD 创建,并通过 `predecessorCheckoutId` 保留上一轮交付记录与迭代血缘。
12
+ - delivered composer dock 增加“开始下一轮修改”,模型增加 `worktree_begin_next_iteration`,人工命令增加 `/worktree next`。
13
+ - Host、strict Typert Remote、Client Adapter 与 Console Contract 增加 `beginNextIteration`;Remote 方法总数由 13 个增加到 14 个。
14
+ - cleanup 后 Harness 过滤缺失 cwd 的 Session 时,lookup adapter 可通过当前 live Session 的 immutable header cwd 恢复精确且唯一的 Workspace 身份。
15
+ - 新增 `worktree_resume_revision`、`/worktree continue` 与 Ready 更多菜单“继续修改”,在不写入 Local 的情况下使未同步 Review 失效并恢复同一 iteration。
16
+ - Worktree Console Contract、Host、strict Typert Remote 与 Client Adapter 增加 `resumeRevision`;Remote 方法总数由 14 个增加到 15 个。
17
+
18
+ ### Fixed
19
+
20
+ - 修复 `worktree_ready_for_review` 输出 Schema,使其符合 Harness 工具结果契约。
21
+ - 发布产物门禁同步校验新增的 `beginNextIteration` 与 `resumeRevision` Remote 方法。
22
+ - 完善并稳定本地开发 Harness 的源码预览、验收输出提取、命令失败诊断与跨平台路径处理。
23
+
24
+ ### Safety
25
+
26
+ - 下一轮仅允许已成功清理的 delivered owner,并校验 caller、Workspace、revision、Local Git common dir、managed path 与 predecessor lineage。
27
+ - 如果上一轮 managed path 已重新出现或包含未知内容,拒绝覆盖;retained、cleanup-pending 与 recovery 状态必须先完成清理或恢复。
28
+ - 创建中断且尚未形成 Worktree 时,reconcile 恢复 predecessor binding;存在无法确认的残留时进入 recovery 并保留现场。
29
+ - live Session cwd fallback 对 cold、无 cwd、路径不匹配或歧义映射继续 fail closed。
30
+ - resume-revision 严格校验 live owner Session、expected revision、expected review ID、Workspace/checkout 身份;转换只更新 registry delivery state,不修改 Local、Worktree bytes 或 Git refs。
31
+
32
+ ### Changed
33
+
34
+ - Ready for Review 不再阻断普通对话:讨论类 follow-up 保持当前 Review;新的代码或文件修改由模型自动恢复 Working,不要求用户先同步或点击恢复编辑。
35
+ - 重写中英文 README,补充当前 Session Target 流程、安全边界、命令、模型工具和已知限制。
36
+ - `SessionCheckoutModule.beginNextIteration` 现在要求调用方传入 `expectedRevision`,避免基于过期 delivered 状态创建下一轮。
37
+
5
38
  ## [0.2.0] - 2026-08-17
6
39
 
7
40
  `0.2.0` 将插件从单一 Worktree 管理器升级为 DeepSeek Harness 中完整、可验收、可撤回的 Worktree Session Target。
@@ -55,5 +88,6 @@
55
88
 
56
89
  - 发布初版 Domi-grade Worktree 管理、基础 apply/finish/discard 生命周期和安全清理。
57
90
 
91
+ [0.3.0]: https://github.com/wloops/dsh-git-worktree/compare/v0.2.0...v0.3.0
58
92
  [0.2.0]: https://github.com/wloops/dsh-git-worktree/compare/v0.1.2...v0.2.0
59
93
  [0.1.2]: https://github.com/wloops/dsh-git-worktree/releases/tag/v0.1.2
package/README.md CHANGED
@@ -1,115 +1,187 @@
1
1
  # dsh-git-worktree
2
2
 
3
- An **experimental** Git worktree Session Target plugin for DeepSeek Harness. It ports Domi's hardened checkout/apply engine and adapts the product flow to Harness's authoritative Workspace/Session cwd model.
3
+ [![npm](https://img.shields.io/npm/v/dsh-git-worktree)](https://www.npmjs.com/package/dsh-git-worktree)
4
+ [![CI](https://github.com/wloops/dsh-git-worktree/actions/workflows/ci.yml/badge.svg)](https://github.com/wloops/dsh-git-worktree/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
4
6
 
5
- > Current scope: real isolated Sessions, a Harness-native Session Target/Worktree Console, reversible Local Preview, accept/rollback/direct-finish flows, a project-scoped acceptance slot, durable recovery receipts, retention, crash recovery, fingerprint CAS, and conservative cleanup. It is not yet Domi's cross-project global Worktree Manager.
7
+ **Run coding tasks in real Git worktrees, review the result in Local, and commit only after explicit human approval.**
6
8
 
7
- ## How it works
9
+ `dsh-git-worktree` is an experimental [DeepSeek Harness](https://github.com/deepseek-ai/DeepSeek-Harness) plugin that turns a Git worktree into an isolated Session Target. The agent works in a separate checkout and Session; the original Local checkout stays under human control.
8
10
 
9
- 1. On a blank/new Local Session, clicking the **Worktree** switch first opens a confirmation dialog. Cancel creates nothing; confirm freezes the Local composer, creates the isolated target, transfers the unsent text/image draft, and opens the target. The user still sends the first prompt through the target's native composer, so no prompt is admitted to Local.
10
- 2. Existing Local Sessions can also create a target through the model-owned `worktree_create` ToolView. The former project-scoped **Worktree** tab is temporarily not mounted while the primary flow is stabilised.
11
- 3. The plugin creates a unique detached Worktree in a sibling container (with a plugin-state fallback) and reserves a distinct target Session ID. The source Session stays Local.
12
- 4. Harness registers the Worktree path as a Workspace, creates the exact Host-reserved Session, and opens it. Its persisted Session header cwd is the authoritative Session Target.
13
- 5. The agent changes and validates code only in that isolated cwd, then calls `worktree_ready_for_review` as its final model action.
14
- 6. A Domi-style status strip stays visible above the target composer when the Worktree is ready. Its compact Chinese Review card shows only the summary, validation state, file count, and collapsed test evidence—no Diff/Inspect controls or expanded retention buttons.
15
- 7. The Ready primary action is **同步到 Local 验收**. The Host runs a read-only preflight and then creates an uncommitted, reversible Local Preview of the exact review. While Preview is active, the primary action becomes **验收通过并提交** and the More menu can roll the Preview back and resume Worktree editing. Ready's More menu also offers **跳过验收,直接提交** and Discard.
16
- 8. Preview, rollback, and finalize are bound to revision/review/HEAD/fingerprint CAS. One canonical Local project can hold only one active Preview. Discard must roll an active Preview back first. Rollback may cross a same-branch fast-forward only when tree proofs show that it can remove Preview alone while preserving the new commit and prior Local layers; branch changes, rewritten history, committed Preview bytes, and content conflicts still fail closed with the Worktree and receipt preserved.
11
+ [中文文档](README.zh.md)
17
12
 
18
- ## Surface
13
+ ## Why use it?
14
+
15
+ A normal agent session can modify the same working tree you are using. This plugin separates execution from acceptance:
16
+
17
+ - **Real isolation** — each task gets a distinct Git worktree, Workspace, cwd, and Session ID.
18
+ - **Human-gated delivery** — the model can prepare a review, but it cannot commit, discard, or clean up by itself.
19
+ - **Reversible Local Preview** — inspect the exact change in Local before committing, then accept it or roll it back.
20
+ - **Local changes are preserved** — staged, unstaged, and untracked Local state is kept separate from the task change.
21
+ - **Fail-closed recovery** — stale reviews, conflicting edits, changed branches, and uncertain cleanup stop instead of overwriting data.
22
+
23
+ > The project is still experimental. It provides a project-scoped Worktree Session workflow, not a cross-project global worktree manager.
24
+
25
+ ## Workflow
26
+
27
+ ```text
28
+ Local Session
29
+ │
30
+ ├─ Create isolated Worktree Session
31
+ ▼
32
+ Agent edits and validates in the Worktree
33
+ │
34
+ ├─ worktree_ready_for_review
35
+ ▼
36
+ Ready for Review
37
+ │
38
+ ├─ Sync to Local Preview ── Accept and commit
39
+ │ └─ Roll back and continue editing
40
+ ├─ Skip Preview and commit directly
41
+ └─ Discard
42
+ │
43
+ └─ After cleanup: start iteration + 1 in the same Session
44
+ ```
45
+
46
+ 1. In a blank Local Session, turn on **Worktree** and confirm creation. The unsent text/image draft moves to the isolated Session; cancelling creates nothing.
47
+ 2. For an existing Local Session, the model can call `worktree_create`, after which you open the isolated Session from its ToolView.
48
+ 3. The agent edits and validates only inside the isolated cwd.
49
+ 4. The agent ends with `worktree_ready_for_review`, including changed files, validation evidence, and a suggested commit message.
50
+ 5. You choose what happens next:
51
+ - **Sync to Local for review**, then commit or roll the Preview back;
52
+ - **Skip review and commit directly**;
53
+ - **Discard** the task.
54
+ 6. After a successful commit and cleanup, the delivered Session can start the next iteration without losing its conversation. Harness keeps Session cwd immutable, so the plugin recreates only the previously cleaned, Host-owned managed path after strict identity checks.
55
+
56
+ All acceptance paths revalidate the review revision, Worktree HEAD/fingerprint, and Local state before writing. Retained or cleanup-pending environments must be cleaned first; starting another iteration never silently removes them.
57
+
58
+ ## Requirements
59
+
60
+ - Node.js 20 or newer
61
+ - DeepSeek Harness `0.1.0-rc.6` package line
62
+ - Harness Web client for the interactive Worktree controls
63
+ - A Git repository
64
+
65
+ ## Install
66
+
67
+ ```bash
68
+ # npm package
69
+ dsh plugin --profile web add dsh-git-worktree
70
+
71
+ # Git tag; prepare builds the Host and Client bundles
72
+ dsh plugin --profile web add github:wloops/dsh-git-worktree#v0.3.0
73
+ ```
74
+
75
+ With pnpm 10 or newer, a Git install may require this entry in the profile's `pnpm-workspace.yaml` before retrying:
76
+
77
+ ```yaml
78
+ allowBuilds:
79
+ dsh-git-worktree: true
80
+ ```
81
+
82
+ Start Harness normally after installation and open a Git repository as the workspace.
83
+
84
+ ## User and model controls
19
85
 
20
86
  ### Model tools
21
87
 
22
88
  | Tool | Purpose |
23
89
  | --- | --- |
24
- | `worktree_create` | Reserve a unique Worktree and distinct owner Session; does not mutate the current Session cwd |
25
- | `worktree_list` | List only Worktrees owned or created by the current Session in the original project |
26
- | `worktree_ready_for_review` | Persist the delivery report and stop for explicit human acceptance |
27
-
28
- Apply, Finish, Discard, and Remove are intentionally **not model tools**. A model parameter is not trusted user authorization.
90
+ | `worktree_create` | Create a managed Worktree and reserve a distinct target Session without changing the current Session cwd |
91
+ | `worktree_list` | List Worktrees visible to the current Session within the original project |
92
+ | `worktree_resume_revision` | Automatically invalidate an unsynced review before new code/file changes and resume the same iteration without touching Local |
93
+ | `worktree_begin_next_iteration` | Recreate a successfully cleaned delivered Session cwd for iteration + 1, preserving the same Session and conversation |
94
+ | `worktree_ready_for_review` | Save the delivery report and stop for explicit human acceptance |
29
95
 
30
- ### Harness-native Worktree Console
96
+ Finish, Discard, and Remove are deliberately excluded from the model tool surface. While an unsynced review is waiting, ordinary discussion continues without changing it; if a follow-up requests code or file changes, the model calls `worktree_resume_revision` automatically. The user does not need to synchronize Local or click a recovery control.
31
97
 
32
- The Client mounts the package-owned strict Typert Remote contribution through the official Gateway. A blank Local Session gets a compact **Worktree** switch in Harness's public composer tool row. Clicking it opens a confirmation dialog; only confirmation prepares the Host-allocated target and transfers the unsent text/image draft before navigation. The normal Harness Send path remains the only prompt path. Every persisted Session gets a read-only target capsule. When Ready, `conversation.input.dock` shows one compact acceptance strip with a single primary action and a More menu; the historical ToolView stays compact and replayable. The advanced `WorktreeConsoleView`, Host control plane, and strict Remote methods remain available internally, but the project-scoped `conversation.view` tab is intentionally not mounted in v0.2.0. List rows remain path-free; authorized paths are returned only by `current`, `create`, or `inspect`.
98
+ ### User controls
33
99
 
34
- ### Human command
100
+ The Web UI provides the normal create, Preview, rollback, commit, retention, and discard actions. The same Host-controlled operations are also available through `/worktree` commands:
35
101
 
36
102
  ```text
37
103
  /worktree status
38
104
  /worktree list
39
- /worktree finalize [cleanup|retain_24h|retain_3d|retain_manual]
40
- /worktree finish <custom commit message>
105
+ /worktree continue
106
+ /worktree next
107
+ /worktree finalize [<reviewId> <revision>] [cleanup|retain_24h|retain_3d|retain_manual]
108
+ /worktree finish <commit message>
41
109
  /worktree discard
42
110
  /worktree remove <checkoutId>
43
111
  ```
44
112
 
45
- The Client uses strict Remote `preflight`, `preview`, `rollbackPreview`, and `finalizePreview`; `finalize` is reserved for an explicitly selected direct-finish shortcut. Every path carries the exact review ID/revision, and commit paths also carry the user-confirmed 1–500 character Commit Message plus retention. The Host revalidates caller, project, managed cwd, review identity, HEAD/fingerprint, and Local CAS; stale cards, post-review edits, and Local drift fail closed.
113
+ `finalize` uses the suggested commit message from the active review. `finish` is the explicit direct-commit path with a custom message.
46
114
 
47
- ## Safety properties
115
+ ## Safety model
48
116
 
49
- - Source and target Sessions have different IDs; the source Session is never privately relabelled as isolated.
50
- - The switch confirmation creates no resources. After confirm, the pre-session transaction blocks the source composer and opens the target only after its managed Workspace, exact Session ID, draft transfer, and source draft-revision CAS succeed; failures leave the source draft untouched.
51
- - Target access fails closed unless its Harness Workspace path canonicalizes to the recorded managed root.
52
- - New paths use `<repo>--worktrees/<repo>--<checkout-short>--worktree`; identity expands on collision instead of overwriting unknown paths. Unsafe siblings fall back to `<stateDir>/worktrees/<repository-key>/`, while legacy registry paths remain manageable.
53
- - Legacy records that already used the old irreversible Apply path cannot automatically Finish or Discard; the user must first inspect Local.
54
- - Lists and management actions are caller-scoped. A recorded `ownerSessionId` is never used as authorization by itself.
55
- - A Preview receipt is persisted before Local writes and retains the prior working tree/index, Preview tree, and Isolated snapshot, so rollback/finalize can recover after Host restart. Same-branch fast-forward rollback first proves that the new HEAD does not contain Preview, then replays prior Local layers with pre-write and post-write CAS.
56
- - A canonical Local root has one acceptance slot. Detached Previews release the slot while retaining recovery evidence.
57
- - Finish preserves unrelated Local staged/working state and refuses stale Local or stale Isolated fingerprints. Discard of an active Preview must first roll it back safely.
58
- - Cleanup validates path, Git common-dir, git-dir, directory identity, and final fingerprint; uncertain residue is retained or quarantined.
117
+ The implementation ports Domi's hardened checkout/apply foundations to Harness's authoritative Workspace and Session cwd model. Important invariants include:
59
118
 
60
- ## Install
61
-
62
- ```bash
63
- # npm (recommended)
64
- dsh plugin --profile web add dsh-git-worktree
119
+ - The initial Local source and isolated target use different Session IDs; later iterations keep the same isolated Session ID.
120
+ - An active target is trusted only when its Harness Workspace resolves to the recorded managed root. A cleaned delivered target may temporarily reference its missing immutable cwd only when the Host path identity exactly matches the predecessor record.
121
+ - One canonical Local project can have only one active Preview.
122
+ - Preview receipts are persisted before Local writes so rollback/finalize can recover after a Host restart.
123
+ - Preview, commit, rollback, and resume-revision paths use revision and identity checks; review-based paths bind the review ID, and resume-revision changes only registry delivery state after validating the managed checkout.
124
+ - Cleanup verifies path identity, Git metadata, and the final fingerprint; uncertain residue is retained or quarantined.
125
+ - Next iteration creation only reuses an absent path from a successfully cleaned predecessor, creates a new checkout record, and preserves the predecessor as recovery evidence.
126
+ - Legacy records created by the old irreversible Apply flow are not automatically finished or discarded.
65
127
 
66
- # Git source (prepare builds Host + Client bundles)
67
- dsh plugin --profile web add github:wloops/dsh-git-worktree#v0.2.0
68
- ```
128
+ For the detailed boundary and recovery design, see [Porting notes](docs/PORTING.md) and [Worktree Console architecture](docs/WORKTREE-CONSOLE-ARCHITECTURE.md).
69
129
 
70
- On pnpm >= 10, Git installs may require `dsh-git-worktree: true` under `allowBuilds` in the profile's `pnpm-workspace.yaml` before retrying the add command.
130
+ ## Local development
71
131
 
72
- Requires the DeepSeek Harness `0.1.0-rc.6` package line and the Web client for interactive ToolViews.
132
+ Install dependencies and run the standard checks:
73
133
 
74
- ## One-command local development
134
+ ```bash
135
+ pnpm install
136
+ pnpm run typecheck
137
+ pnpm test
138
+ pnpm run build
139
+ pnpm run check:publish
140
+ ```
75
141
 
76
- For repeated iterations, run this from any current checkout, including a Domi managed Worktree:
142
+ For an end-to-end local Harness run:
77
143
 
78
144
  ```bash
79
145
  pnpm run dev:dsh
80
146
  ```
81
147
 
82
- The command runs typecheck/build, packs the **current checkout snapshot** into a local tarball under the OS temporary directory, installs it into the `web` profile, checks the composed config, creates or reuses a marker-protected disposable Git fixture, and finally starts `dsh web` from that fixture cwd (default `http://127.0.0.1:3081`). If a `DeepSeek/deepseek-harness` source checkout is found in the same development tree, it is preferred for launching DSH while the Session workspace remains the fixture; `DSH_HARNESS_ROOT` or `--harness <path>` can override it. The installed `dsh` on PATH is used only when no source checkout is available. The workflow never runs `npm publish`, pushes Git refs, or creates tags, and it does not leave a symlink pointing at a cleaned managed Worktree. The tarball currently referenced by the profile is retained; older local snapshots are cleaned after a successful install.
148
+ This command builds the current checkout, packs it into a temporary local tarball, installs it into the `web` profile, verifies the composed configuration, prepares a marker-protected disposable Git fixture, and starts `dsh web` at `http://127.0.0.1:3081` by default. It does not publish to npm or push Git refs.
83
149
 
84
- Useful entry points:
150
+ Useful variants:
85
151
 
86
152
  ```bash
87
- # Install and verify the current snapshot without starting Web
153
+ # Install and verify the snapshot without starting Web
88
154
  pnpm run dev:dsh:install
89
155
 
90
- # Check the already-installed profile only
156
+ # Verify the already-installed profile
91
157
  pnpm run dev:dsh:smoke
92
158
 
93
- # Use an existing Git repository or another port/profile
159
+ # Use an existing Git root, another port, or another profile
94
160
  pnpm run dev:dsh -- --repo G:/path/to/repo --port 4090 --profile web
95
161
 
96
- # Explicitly uninstall from the profile and clear local development tarballs
162
+ # Remove the development install and cached local archives
97
163
  pnpm run dev:dsh:remove
98
164
  ```
99
165
 
100
- The default fixture is `dsh-git-worktree-dev/fixture` under the OS temporary directory. The workflow initializes only an absent or empty directory. Reuse requires its plugin marker, the exact Git-root identity, a clean status, and no leftover linked Worktrees. Unknown files, dirty state, symlinks, or retained Worktrees fail closed; the script never resets or deletes repository content. An explicit `--repo` must already be a Git root and is validated without initialization or rewriting.
166
+ When nearby DeepSeek Harness source checkouts are found, `dev:dsh` prefers a runnable candidate with `node_modules/tsx` installed. Select a checkout in any other location with `DSH_HARNESS_ROOT` or `--harness <path>`. Once a source checkout is selected, plugin installation, config validation, removal, and Web startup all use that source CLI without requiring a globally installed `dsh`. If an explicitly selected checkout has not installed its dependencies, the workflow fails before building and prints the corresponding `pnpm --dir <path> install` command. Only runs without a source checkout fall back to `dsh` on PATH.
101
167
 
102
168
  ## Current limitations
103
169
 
104
- - The old direct `worktree_apply` surface remains disabled; public delivery is limited to explicit user Preview/rollback/finalize/direct-finish actions.
105
- - No cross-project global sidebar Manager yet. The project-scoped Worktree Console implementation is retained for recovery and future redesign, but its visible `conversation.view` tab is temporarily not mounted.
106
- - No automatic Workflow `agent({ isolation })`; Harness still defers that option.
107
- - Subagents inherit the parent Session cwd, so they are isolated only after the parent is a real Worktree Session.
108
- - Dependency snapshot/restore and complete collaborator handoff UI are deferred.
109
- - Finishing with immediate cleanup makes the isolated Session terminal because its cwd is removed; open a Local/new iteration Session for follow-up work.
170
+ - No cross-project global sidebar manager yet.
171
+ - The project-scoped Worktree Console implementation exists, but its visible `conversation.view` tab is not mounted in `v0.3.0` while the primary flow is stabilised.
172
+ - In the verified Harness `0.1.0-rc.6` line, Workflow `agent({ isolation })` integration is not available.
173
+ - In that Harness line, subagents inherit the parent Session cwd; they are isolated only when the parent is already a Worktree Session.
174
+ - Dependency snapshot/restore and the complete collaborator handoff UI are deferred.
175
+ - Immediate cleanup removes the isolated cwd, making that Session terminal; continue from Local or start a new iteration.
176
+
177
+ ## Documentation
110
178
 
111
- See [docs/PORTING.md](docs/PORTING.md) for the Domi-to-Harness boundary and [docs/RELEASE.md](docs/RELEASE.md) for release gates.
179
+ - [Porting from Domi to Harness](docs/PORTING.md)
180
+ - [Worktree Console architecture](docs/WORKTREE-CONSOLE-ARCHITECTURE.md)
181
+ - [UI development notes](docs/UI-DEVELOPMENT.md)
182
+ - [Release checklist](docs/RELEASE.md)
183
+ - [Changelog](CHANGELOG.md)
112
184
 
113
185
  ## License
114
186
 
115
- MIT
187
+ [MIT](LICENSE)
package/README.zh.md CHANGED
@@ -1,115 +1,187 @@
1
1
  # dsh-git-worktree
2
2
 
3
- 面向 DeepSeek Harness 的**实验性** Git Worktree Session Target 插件。它保留 Domi 中经过生产验证的 checkout / apply engine 安全核心,并按 Harness 的权威 Workspace / Session cwd 模型重做产品闭环。
3
+ [![npm](https://img.shields.io/npm/v/dsh-git-worktree)](https://www.npmjs.com/package/dsh-git-worktree)
4
+ [![CI](https://github.com/wloops/dsh-git-worktree/actions/workflows/ci.yml/badge.svg)](https://github.com/wloops/dsh-git-worktree/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
4
6
 
5
- > 当前范围:真实隔离 Session、Harness-native Session Target/Worktree Console、可撤回的 Local Preview、验收提交/撤回/跳过验收直接提交、项目级验收槽位、持久恢复凭据、保留策略、崩溃恢复、指纹 CAS 与保守清理。它还不是 Domi 的跨项目全局 Worktree Manager。
7
+ **让 Agent 在真实 Git Worktree 中完成任务,在 Local 中验收,并且只在用户明确确认后提交。**
8
+
9
+ `dsh-git-worktree` 是一个实验性的 [DeepSeek Harness](https://github.com/deepseek-ai/DeepSeek-Harness) 插件。它把 Git Worktree 变成独立的 Session Target:Agent 使用单独的 checkout 和 Session 工作,原始 Local 工作区始终由用户控制。
10
+
11
+ [English](README.md)
12
+
13
+ ## 为什么需要它?
14
+
15
+ 普通 Agent Session 可能直接修改你正在使用的工作区。本插件把“执行任务”和“接受结果”分开:
16
+
17
+ - **真实隔离**:每个任务都有独立的 Git Worktree、Workspace、cwd 和 Session ID。
18
+ - **用户掌握交付权**:模型可以准备验收报告,但不能自行提交、放弃或清理。
19
+ - **可撤回的 Local Preview**:提交前先在 Local 查看精确变更,可以验收提交,也可以撤回后继续修改。
20
+ - **保留 Local 现场**:Local 中已有的 staged、unstaged 和 untracked 内容不会被混入任务提交。
21
+ - **保守恢复**:历史验收卡、并发修改、分支变化或清理身份不确定时直接停止,不覆盖用户数据。
22
+
23
+ > 项目仍处于实验阶段。当前提供的是项目级 Worktree Session 工作流,还不是跨项目的全局 Worktree Manager。
6
24
 
7
25
  ## 工作流程
8
26
 
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 与恢复凭据,绝不覆盖用户修改。
27
+ ```text
28
+ Local Session
29
+ │
30
+ ├─ 创建隔离的 Worktree Session
31
+ ▼
32
+ Agent 在 Worktree 中修改并验证
33
+ │
34
+ ├─ worktree_ready_for_review
35
+ ▼
36
+ 等待验收
37
+ │
38
+ ├─ 同步到 Local Preview ── 验收并提交
39
+ │ └─ 撤回并继续修改
40
+ ├─ 跳过 Preview,直接提交
41
+ └─ 放弃任务
42
+ │
43
+ └─ cleanup 后在原 Session 开始 iteration + 1
44
+ ```
45
+
46
+ 1. 在 blank/new Local Session 中打开 **Worktree** 开关并确认。未发送的文字和图片草稿会迁移到隔离 Session;取消不会创建任何资源。
47
+ 2. 已存在的 Local Session 可以由模型调用 `worktree_create`,然后由用户从 ToolView 打开隔离 Session。
48
+ 3. Agent 只在隔离 cwd 中修改和验证代码。
49
+ 4. Agent 最后调用 `worktree_ready_for_review`,写入变更摘要、验证证据和建议 Commit Message,然后停止。
50
+ 5. 用户决定如何处理:
51
+ - **同步到 Local 验收**,再提交或撤回 Preview;
52
+ - **跳过验收,直接提交**;
53
+ - **放弃任务**。
54
+ 6. 成功提交并 cleanup 后,可以在原隔离 Session 中开始下一轮,不丢失现有对话。Harness 的 Session cwd 不可变,因此插件只会在严格身份校验后重建上一轮已经清理的 Host-owned managed path。
55
+
56
+ 所有验收路径在写入前都会重新校验 review revision、Worktree HEAD/fingerprint 和 Local 状态。Retained 或 cleanup-pending 环境必须先完成清理;开始下一轮不会静默删除这些环境。
57
+
58
+ ## 环境要求
59
+
60
+ - Node.js 20 或更高版本
61
+ - DeepSeek Harness `0.1.0-rc.6` 包线
62
+ - 使用 Harness Web Client 才能获得完整交互界面
63
+ - 当前 Workspace 必须是 Git 仓库
64
+
65
+ ## 安装
66
+
67
+ ```bash
68
+ # npm 包
69
+ dsh plugin --profile web add dsh-git-worktree
70
+
71
+ # Git tag;prepare 会构建 Host 和 Client bundle
72
+ dsh plugin --profile web add github:wloops/dsh-git-worktree#v0.3.0
73
+ ```
74
+
75
+ 使用 pnpm 10 或更高版本时,Git 源安装可能需要先在 profile 的 `pnpm-workspace.yaml` 中加入:
17
76
 
18
- ## 能力面
77
+ ```yaml
78
+ allowBuilds:
79
+ dsh-git-worktree: true
80
+ ```
81
+
82
+ 安装后正常启动 Harness,并以一个 Git 仓库作为 Workspace。
83
+
84
+ ## 用户与模型入口
19
85
 
20
86
  ### 模型工具
21
87
 
22
88
  | 工具 | 作用 |
23
89
  | --- | --- |
24
- | `worktree_create` | 预留唯一 Worktree 与独立 owner Session;不会修改当前 Session cwd |
25
- | `worktree_list` | 仅列出当前 Session 在原始项目中拥有或创建的 Worktree |
26
- | `worktree_ready_for_review` | 持久化完整交付报告并停止,等待用户验收 |
27
-
28
- Apply、Finish、Discard、Remove **不再作为模型工具**暴露。模型参数不能替代可信的用户授权。
90
+ | `worktree_create` | 创建 managed Worktree 并预留独立 target Session,不修改当前 Session cwd |
91
+ | `worktree_list` | 列出当前 Session 在原始项目中可见的 Worktree |
92
+ | `worktree_resume_revision` | 新的代码/文件修改前自动使未同步 Review 失效,在不触碰 Local 的情况下恢复同一 iteration |
93
+ | `worktree_begin_next_iteration` | 为已成功清理的 delivered Session 重建 iteration + 1,并保持同一 Session 与完整对话 |
94
+ | `worktree_ready_for_review` | 保存交付报告并停止,等待用户明确验收 |
29
95
 
30
- ### Harness-native Worktree Console
96
+ Finish、Discard、Remove 不向模型开放,避免用模型参数代替用户授权。未同步 Review 等待期间,普通讨论会直接继续且不改变验收稿;如果 follow-up 要求修改代码或文件,模型会自动调用 `worktree_resume_revision`。用户不需要先同步 Local,也不需要点击恢复编辑。
31
97
 
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。
98
+ ### 用户操作
33
99
 
34
- ### 用户命令
100
+ Web UI 提供创建、Preview、撤回、提交、保留和放弃等常用操作。Host 控制的同类能力也可以通过 `/worktree` 命令调用:
35
101
 
36
102
  ```text
37
103
  /worktree status
38
104
  /worktree list
39
- /worktree finalize [cleanup|retain_24h|retain_3d|retain_manual]
40
- /worktree finish <自定义 Commit Message>
105
+ /worktree continue
106
+ /worktree next
107
+ /worktree finalize [<reviewId> <revision>] [cleanup|retain_24h|retain_3d|retain_manual]
108
+ /worktree finish <Commit Message>
41
109
  /worktree discard
42
110
  /worktree remove <checkoutId>
43
111
  ```
44
112
 
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。
113
+ `finalize` 使用当前验收报告中的建议 Commit Message;`finish` 是由用户提供自定义消息的直接提交路径。
46
114
 
47
- ## 安全不变量
115
+ ## 安全模型
48
116
 
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。
117
+ 实现把 Domi 中经过生产验证的 checkout/apply 安全基础迁移到 Harness 的权威 Workspace / Session cwd 模型。关键不变量包括:
59
118
 
60
- ## 安装
61
-
62
- ```bash
63
- # npm(推荐)
64
- dsh plugin --profile web add dsh-git-worktree
119
+ - 初始 Local source 与 isolated target 使用不同的 Session ID;后续 iteration 保持同一个 isolated Session ID。
120
+ - 活动 target 的 Harness Workspace 必须解析到 Host 记录的 managed root。已清理的 delivered target 只在 Host Workspace 原始路径与 predecessor 记录精确一致时,才允许暂时引用缺失的 immutable cwd。
121
+ - 同一 canonical Local 项目同时只允许一个活动 Preview。
122
+ - 在写入 Local 前先持久化 Preview receipt,使 Host 重启后仍可恢复 rollback/finalize。
123
+ - Preview、Commit、rollback 与 resume-revision 路径都使用 revision 和身份校验;基于验收报告的路径绑定 review ID,resume-revision 在验证 managed checkout 后只改变 registry delivery state。
124
+ - 清理前验证路径身份、Git 元数据和最终 fingerprint;无法确认的残余会保留或 quarantine。
125
+ - 下一轮只复用已成功清理且当前不存在的 predecessor path,创建新的 checkout record,并保留上一轮记录作为恢复证据。
126
+ - 旧版不可逆 Apply 流程产生的历史记录不会被自动 Finish 或 Discard。
65
127
 
66
- # Git 源码安装(prepare 构建 Host + Client bundle)
67
- dsh plugin --profile web add github:wloops/dsh-git-worktree#v0.2.0
68
- ```
128
+ 详细边界与恢复设计见 [Domi 到 Harness 的迁移说明](docs/PORTING.md) 和 [Worktree Console 架构](docs/WORKTREE-CONSOLE-ARCHITECTURE.md)。
69
129
 
70
- pnpm >= 10 可能会拦截 Git 依赖的构建脚本;在 profile 的 `pnpm-workspace.yaml` 的 `allowBuilds` 下加入 `dsh-git-worktree: true` 后重试。
130
+ ## 本地开发
71
131
 
72
- 要求 DeepSeek Harness `0.1.0-rc.6` 包线;交互 ToolView 需要 Web Client。
132
+ 安装依赖并运行标准检查:
73
133
 
74
- ## 一键本地开发测试
134
+ ```bash
135
+ pnpm install
136
+ pnpm run typecheck
137
+ pnpm test
138
+ pnpm run build
139
+ pnpm run check:publish
140
+ ```
75
141
 
76
- 持续迭代时,在任意当前 checkout(包括 Domi managed Worktree)中运行:
142
+ 端到端启动本地 Harness:
77
143
 
78
144
  ```bash
79
145
  pnpm run dev:dsh
80
146
  ```
81
147
 
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。
148
+ 该命令会构建当前 checkout,将其打成临时本地 tarball,安装到 `web` profile,验证组合配置,准备受 marker 保护的临时 Git fixture,并默认在 `http://127.0.0.1:3081` 启动 `dsh web`。它不会发布 npm 包,也不会 push Git refs。
83
149
 
84
- 常用入口:
150
+ 常用变体:
85
151
 
86
152
  ```bash
87
- # 只安装当前快照并验证配置,不启动 Web
153
+ # 只安装并验证当前快照,不启动 Web
88
154
  pnpm run dev:dsh:install
89
155
 
90
- # 只检查已安装 profile
156
+ # 验证已经安装的 profile
91
157
  pnpm run dev:dsh:smoke
92
158
 
93
- # 使用现有 Git 仓库或其他端口/profile
159
+ # 使用现有 Git 根目录、其他端口或其他 profile
94
160
  pnpm run dev:dsh -- --repo G:/path/to/repo --port 4090 --profile web
95
161
 
96
- # 显式从 profile 卸载,并清理本地开发 tarball
162
+ # 移除开发安装和缓存的本地归档
97
163
  pnpm run dev:dsh:remove
98
164
  ```
99
165
 
100
- 默认 fixture 位于系统临时目录 `dsh-git-worktree-dev/fixture`。它只会初始化不存在或为空的目录;复用时必须具有插件 marker、Git 根身份正确、状态干净且没有遗留 linked Worktree。遇到未知文件、脏状态、符号链接或残留 Worktree 会 fail closed,脚本绝不会自动 reset 或删除内容。显式 `--repo` 必须指向已经存在的 Git 根,脚本只验证、不初始化或改写它。
166
+ 如果发现附近的 DeepSeek Harness 源码 checkout,`dev:dsh` 会优先选择已经安装 `node_modules/tsx`、可直接运行的候选;源码位于任意其他目录时,可以通过 `DSH_HARNESS_ROOT` 或 `--harness <path>` 指定。选择源码 checkout 后,插件安装、配置验证、移除和 Web 启动都会使用该源码 CLI,不再要求全局安装 `dsh`;显式指定的 checkout 尚未安装依赖时,脚本会在构建前提示对应的 `pnpm --dir <path> install` 命令。只有未选择源码 checkout 时才回退到 PATH 中的 `dsh`。
101
167
 
102
168
  ## 当前限制
103
169
 
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。
170
+ - 暂无跨项目全局侧栏 Manager。
171
+ - 项目级 Worktree Console 实现仍保留,但 `v0.3.0` 暂不挂载可见的 `conversation.view` 标签页,当前优先稳定主流程。
172
+ - 在已验证的 Harness `0.1.0-rc.6` 包线中,Workflow `agent({ isolation })` 集成尚不可用。
173
+ - 在该 Harness 包线中,子 Agent 继承父 Session cwd;只有父 Session 已经是 Worktree Session 时才处于隔离环境。
174
+ - dependency snapshot/restore 和完整 collaborator handoff UI 尚未实现。
175
+ - 选择立即清理后,隔离 cwd 会被删除,该 Session 随即进入终态;后续应回到 Local 或开始新一轮任务。
176
+
177
+ ## 文档
110
178
 
111
- Domi 与 Harness 的边界见 [docs/PORTING.md](docs/PORTING.md),发布门禁见 [docs/RELEASE.md](docs/RELEASE.md)。
179
+ - [Domi 到 Harness 的迁移说明](docs/PORTING.md)
180
+ - [Worktree Console 架构](docs/WORKTREE-CONSOLE-ARCHITECTURE.md)
181
+ - [UI 开发说明](docs/UI-DEVELOPMENT.md)
182
+ - [发布清单](docs/RELEASE.md)
183
+ - [变更记录](CHANGELOG.md)
112
184
 
113
185
  ## 许可证
114
186
 
115
- MIT
187
+ [MIT](LICENSE)
@@ -2,7 +2,9 @@
2
2
  * DSH lookup adapter: maps sessions and projects onto the harness's
3
3
  * `workspaceRegistry` service (retrieved dynamically, like the ecosystem's
4
4
  * plugins, because the published package version lags the rc.6 runtime). A
5
- * session's project is found by scanning workspace session accounts; a
5
+ * session's project is found by scanning workspace session accounts; when a
6
+ * cleaned immutable cwd makes Harness filter a still-live Session from that
7
+ * projection, the immutable live header may restore the exact mapping. A
6
8
  * project record maps to a workspace's `id`/`title`/`path`. Missing service or
7
9
  * records degrade to `undefined`, which the state machine treats as
8
10
  * recovery/orphan facts rather than failures.
@@ -24,5 +26,5 @@ export interface WorkspaceRegistryLike {
24
26
  create(path: string, title?: string): Promise<WorkspaceLike>;
25
27
  delete(id: string): Promise<boolean>;
26
28
  }
27
- /** Build the lookup port over the harness workspace registry (absent → all lookups miss). */
29
+ /** Build the lookup port over Harness workspace and live-session projections. */
28
30
  export declare function createDshLookupPort(ctx: Context): SessionCheckoutLookupPort;