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.
- package/CHANGELOG.md +34 -0
- package/README.md +133 -61
- package/README.zh.md +132 -60
- package/lib/adapters/lookup.d.ts +4 -2
- package/lib/adapters/lookup.js +31 -3
- package/lib/adapters/lookup.js.map +1 -1
- package/lib/adapters/registry.js +1 -0
- package/lib/adapters/registry.js.map +1 -1
- package/lib/client/console-remote/adapter.js +2 -0
- package/lib/client/console-remote/adapter.js.map +1 -1
- package/lib/client/review-console/ReviewActions.js +20 -5
- package/lib/client/review-console/ReviewActions.js.map +1 -1
- package/lib/client/target-console/WorktreeReviewStatus.js +34 -0
- package/lib/client/target-console/WorktreeReviewStatus.js.map +1 -1
- package/lib/client.js +97 -8
- package/lib/commands.js +17 -2
- package/lib/commands.js.map +1 -1
- package/lib/console-contract.d.ts +17 -0
- package/lib/console-contract.js.map +1 -1
- package/lib/console-host/control-plane.d.ts +3 -1
- package/lib/console-host/control-plane.js +65 -6
- package/lib/console-host/control-plane.js.map +1 -1
- package/lib/console-host/projection.js +5 -0
- package/lib/console-host/projection.js.map +1 -1
- package/lib/console-host/service.d.ts +2 -0
- package/lib/console-host/service.js +12 -0
- package/lib/console-host/service.js.map +1 -1
- package/lib/console-remote/descriptors.js +9 -0
- package/lib/console-remote/descriptors.js.map +1 -1
- package/lib/console-remote/remote.d.ts +2 -0
- package/lib/console-remote/schemas.js +2 -0
- package/lib/console-remote/schemas.js.map +1 -1
- package/lib/index.d.ts +4 -2
- package/lib/index.js.map +1 -1
- package/lib/ports.d.ts +2 -0
- package/lib/session-checkout-module.js +250 -8
- package/lib/session-checkout-module.js.map +1 -1
- package/lib/tools.d.ts +2 -1
- package/lib/tools.js +80 -1
- package/lib/tools.js.map +1 -1
- package/package.json +1 -1
- package/scripts/check-publish.mjs +1 -1
- package/scripts/dev-dsh-lib.mjs +82 -26
- 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,
|
|
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,
|
|
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":"AAAA
|
|
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.
|
|
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
|
}
|
package/scripts/dev-dsh-lib.mjs
CHANGED
|
@@ -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
|
|
214
|
-
|
|
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
|
|
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
|
|
229
|
-
cwd
|
|
241
|
+
args,
|
|
242
|
+
cwd,
|
|
230
243
|
source: false,
|
|
231
244
|
}
|
|
232
245
|
}
|
|
233
|
-
|
|
234
|
-
|
|
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',
|
|
258
|
+
'--dir', harnessRoot,
|
|
240
259
|
'exec', 'node', '--import', 'tsx/esm',
|
|
241
260
|
join(options.projectRoot, 'scripts', 'dsh-source-runner.mjs'),
|
|
242
|
-
|
|
243
|
-
join(
|
|
244
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
434
|
-
|
|
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
|
-
|
|
446
|
-
const dump =
|
|
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
|
}
|
package/scripts/dev-dsh.mjs
CHANGED
|
@@ -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.
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
|
|
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(
|
|
64
|
+
smokeLocalSnapshot(runtime)
|
|
58
65
|
console.log(`Profile "${options.profile}" composes dsh-git-worktree.`)
|
|
59
66
|
} else if (options.mode === 'remove') {
|
|
60
|
-
removeLocalSnapshot({
|
|
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
|
-
|
|
65
|
-
profile: options.profile,
|
|
71
|
+
...runtime,
|
|
66
72
|
cacheRoot,
|
|
67
73
|
})
|
|
68
74
|
const fixture = ensureDevFixture(options.repo, { explicit: options.repoExplicit })
|