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/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":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAInD,SAAS,WAAW,CAAC,KAAc;IACjC,MAAM,OAAO,GAAI,KAAmD,EAAE,OAAO,CAAA;IAC7E,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;IACnD,CAAC;IACD,OAAO,OAAO,CAAC,EAAE,CAAA;AACnB,CAAC;AAED,kFAAkF;AAClF,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;AACxD,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,aAAa,CAAC,GAAY,EAAE,MAA6B;IACvE,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC5B,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,2PAA2P;QACxQ,UAAU,EAAE,EAAE;QACd,MAAM,EAAE;YACN,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,oBAAoB,EAAE,KAAK;gBAC3B,UAAU,EAAE;oBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBACxC,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC9C,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBACnD,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC/C,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBACzC,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC9C,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;iBACpD;aACF;YACD,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;SAC5C;QACD,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI;YACvB,MAAM,eAAe,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YAC/C,MAAM,eAAe,GAAG,UAAU,EAAE,CAAA;YACpC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,eAAe,EAAE,eAAe,CAAC,CAAA;YAClF,OAAO;gBACL,IAAI,EAAE,yBAAyB;gBAC/B,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;gBACrC,eAAe;gBACf,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK;gBACnC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG;gBACrC,eAAe;aAChB,CAAA;QACH,CAAC;QACD,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,gCAAgC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;KAC/G,CAAC,CAAC,CAAA;IAEH,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC5B,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,kJAAkJ;QAC/J,UAAU,EAAE,EAAE;QACd,MAAM,EAAE;YACN,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,oBAAoB,EAAE,KAAK;gBAC3B,UAAU,EAAE;oBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBACxC,SAAS,EAAE;wBACT,IAAI,EAAE,OAAO;wBACb,QAAQ,EAAE,IAAI;wBACd,KAAK,EAAE;4BACL,IAAI,EAAE,QAAQ;4BACd,oBAAoB,EAAE,KAAK;4BAC3B,UAAU,EAAE;gCACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;gCAC9C,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;gCAC/C,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;gCAClD,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;gCAC7C,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;gCACzC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;gCACzC,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE;gCAC1C,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;6BAC9B;yBACF;qBACF;iBACF;aACF;YACD,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;SAC5C;QACD,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI;YACvB,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACzC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,SAAS,CAAC,CAAA;YACxE,OAAO;gBACL,IAAI,EAAE,eAAe;gBACrB,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;oBACrC,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI;oBACjC,cAAc,EAAE,OAAO,CAAC,cAAc;oBACtC,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS;iBAC1C,CAAC,CAAC;aACJ,CAAA;QACH,CAAC;QACD,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,wBAAwB,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;KACvG,CAAC,CAAC,CAAA;IAEH,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC5B,IAAI,EAAE,0BAA0B;QAChC,WAAW,EAAE,gKAAgK;QAC7K,UAAU,EAAE,EAAE;QACd,MAAM,EAAE;YACN,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,oBAAoB,EAAE,KAAK;gBAC3B,UAAU,EAAE;oBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBACxC,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC9C,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC7C,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC5C,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBACzC,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;iBAC9C;aACF;YACD,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;SAC5C;QACD,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI;YACvB,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACzC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YAC/C,IAAI,OAAO,CAAC,QAAQ,EAAE,KAAK,KAAK,kBAAkB,EAAE,CAAC;gBACnD,MAAM,IAAI,KAAK,CAAC,iCAAiC,OAAO,CAAC,QAAQ,EAAE,KAAK,IAAI,SAAS,EAAE,CAAC,CAAA;YAC1F,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CACxC,SAAS,EACT,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CACjC,CAAA;YACD,IAAI,MAAM,CAAC,QAAQ,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;gBACzC,MAAM,IAAI,KAAK,CAAC,6BAA6B,MAAM,CAAC,QAAQ,EAAE,KAAK,IAAI,SAAS,EAAE,CAAC,CAAA;YACrF,CAAC;YACD,OAAO;gBACL,IAAI,EAAE,2BAA2B;gBACjC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE;gBAC9B,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS;gBACpC,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK;gBAC5B,SAAS;aACV,CAAA;QACH,CAAC;QACD,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,0BAA0B,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;KACzG,CAAC,CAAC,CAAA;IAEH,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC5B,IAAI,EAAE,+BAA+B;QACrC,WAAW,EAAE,iKAAiK;QAC9K,UAAU,EAAE,EAAE;QACd,MAAM,EAAE;YACN,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,oBAAoB,EAAE,KAAK;gBAC3B,UAAU,EAAE;oBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBACxC,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC9C,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC7C,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBACzC,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC9C,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;iBAC9C;aACF;YACD,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;SAC5C;QACD,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI;YACvB,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACzC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YAC/C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;YAC3E,IAAI,MAAM,CAAC,QAAQ,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;gBACzC,MAAM,IAAI,KAAK,CAAC,gCAAgC,MAAM,CAAC,QAAQ,EAAE,KAAK,IAAI,SAAS,EAAE,CAAC,CAAA;YACxF,CAAC;YACD,OAAO;gBACL,IAAI,EAAE,iCAAiC;gBACvC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE;gBAC9B,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS;gBACpC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK;gBAC5B,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG;gBAC9B,SAAS;aACV,CAAA;QACH,CAAC;QACD,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,+BAA+B,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;KAC9G,CAAC,CAAC,CAAA;IAEH,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC5B,IAAI,EAAE,2BAA2B;QACjC,WAAW,EAAE,8IAA8I;QAC3J,UAAU,EAAE;YACV,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,iDAAiD;aAC/D;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,mDAAmD;aACjE;YACD,gBAAgB,EAAE;gBAChB,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC;aACjD;YACD,iBAAiB,EAAE;gBACjB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,uCAAuC;aACrD;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,oBAAoB,EAAE,KAAK;oBAC3B,UAAU,EAAE;wBACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;wBAC3C,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE;wBACjF,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;qBAC5B;iBACF;aACF;YACD,sBAAsB,EAAE;gBACtB,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,2DAA2D;aACzE;SACF;QACD,MAAM,EAAE;YACN,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,oBAAoB,EAAE,KAAK;gBAC3B,UAAU,EAAE;oBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBACxC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBACzC,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC5C,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC5C,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC7C,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;iBAC3E;aACF;YACD,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;SAC5C;QACD,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI;YACtB,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACzC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,SAAS,EAAE;gBACxD,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,eAAe,EAAE,IAAI,CAAC,OAAO;gBAC7B,gBAAgB,EAAE,IAAI,CAAC,gBAA4C;gBACnE,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;gBACzC,KAAK,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBACvC,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,MAAM,EAAE,IAAI,CAAC,MAAyC;oBACtD,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACnD,CAAC,CAAC;gBACH,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;aACpD,CAAC,CAAA;YACF,IAAI,MAAM,CAAC,QAAQ,EAAE,KAAK,KAAK,kBAAkB,EAAE,CAAC;gBAClD,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,CAAC,QAAQ,EAAE,KAAK,IAAI,SAAS,EAAE,CAAC,CAAA;YAC9E,CAAC;YACD,OAAO;gBACL,IAAI,EAAE,2BAA2B;gBACjC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK;gBAC5B,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ;gBACzC,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS;gBAC3C,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY;aAClD,CAAA;QACH,CAAC;QACD,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,2BAA2B,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;KAC1G,CAAC,CAAC,CAAA;AACL,CAAC"}
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.0",
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'))) {
@@ -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 })