dsh-git-worktree 0.9.0 → 0.9.2

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 (42) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.en.md +4 -3
  3. package/README.md +4 -3
  4. package/lib/adapters/git-options.d.ts +9 -0
  5. package/lib/adapters/git-options.js +19 -0
  6. package/lib/adapters/git-options.js.map +1 -0
  7. package/lib/adapters/git.d.ts +4 -1
  8. package/lib/adapters/git.js +87 -21
  9. package/lib/adapters/git.js.map +1 -1
  10. package/lib/adapters/project-skill-io.d.ts +12 -0
  11. package/lib/adapters/project-skill-io.js +96 -0
  12. package/lib/adapters/project-skill-io.js.map +1 -0
  13. package/lib/adapters/project-skill-provider.d.ts +25 -0
  14. package/lib/adapters/project-skill-provider.js +137 -0
  15. package/lib/adapters/project-skill-provider.js.map +1 -0
  16. package/lib/adapters/project-skills.d.ts +40 -0
  17. package/lib/adapters/project-skills.js +285 -0
  18. package/lib/adapters/project-skills.js.map +1 -0
  19. package/lib/adapters/registry.js +13 -2
  20. package/lib/adapters/registry.js.map +1 -1
  21. package/lib/adapters/worktree-creation.d.ts +11 -0
  22. package/lib/adapters/worktree-creation.js +321 -0
  23. package/lib/adapters/worktree-creation.js.map +1 -0
  24. package/lib/console-host/control-plane.js +12 -8
  25. package/lib/console-host/control-plane.js.map +1 -1
  26. package/lib/console-host/review-diff.d.ts +2 -1
  27. package/lib/console-host/review-diff.js +23 -2
  28. package/lib/console-host/review-diff.js.map +1 -1
  29. package/lib/creation-failure.d.ts +5 -0
  30. package/lib/creation-failure.js +10 -0
  31. package/lib/creation-failure.js.map +1 -0
  32. package/lib/index.d.ts +31 -2
  33. package/lib/index.js +12 -12
  34. package/lib/index.js.map +1 -1
  35. package/lib/ports.d.ts +15 -1
  36. package/lib/session-checkout-apply.d.ts +2 -0
  37. package/lib/session-checkout-apply.js +52 -36
  38. package/lib/session-checkout-apply.js.map +1 -1
  39. package/lib/session-checkout-module.js +58 -4
  40. package/lib/session-checkout-module.js.map +1 -1
  41. package/package.json +8 -2
  42. package/scripts/check-publish.mjs +3 -0
@@ -0,0 +1,321 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { createReadStream } from 'node:fs';
3
+ import { lstat, mkdir, readdir, readFile, realpath, rmdir, readlink } from 'node:fs/promises';
4
+ import { dirname, join, resolve, relative, isAbsolute } from 'node:path';
5
+ import { WorktreeCreationFailure } from '../creation-failure.js';
6
+ import { createNodeFilesPort } from './files.js';
7
+ const files = createNodeFilesPort();
8
+ const samePath = (a, b) => process.platform === 'win32'
9
+ ? resolve(a).toLowerCase() === resolve(b).toLowerCase() : resolve(a) === resolve(b);
10
+ const sameIdentity = (a, b) => a !== null && JSON.stringify(a) === JSON.stringify(b);
11
+ /** Registration is short; the expensive checkout runs only after its ownership proof is durable. */
12
+ export async function createWorktree(localRoot, target, baseOid, run, saveEvidence = () => { }) {
13
+ let evidence;
14
+ let failure;
15
+ let registered = false;
16
+ let claimed = false;
17
+ let originalMetadata = [];
18
+ const checked = async (cwd, args, creating = true) => {
19
+ const result = await run(cwd, args, creating);
20
+ if (result.code !== 0) {
21
+ failure = result;
22
+ throw new Error(result.stderr || `git ${args.join(' ')} failed`);
23
+ }
24
+ return result.stdout;
25
+ };
26
+ try {
27
+ const commonDir = await realpath(await checked(localRoot, ['rev-parse', '--path-format=absolute', '--git-common-dir']));
28
+ const parent = await realpath(dirname(target));
29
+ if (!samePath(parent, dirname(target)))
30
+ throw new Error('Worktree parent path changed');
31
+ const parentIdentity = await files.inspectDirectoryIdentity(parent);
32
+ const commonIdentity = await files.inspectDirectoryIdentity(commonDir);
33
+ if (!parentIdentity || !commonIdentity)
34
+ throw new Error('Worktree parent identity cannot be verified');
35
+ try {
36
+ originalMetadata = (await readdir(join(commonDir, 'worktrees'))).sort();
37
+ }
38
+ catch (error) {
39
+ if (error.code !== 'ENOENT')
40
+ throw error;
41
+ }
42
+ await mkdir(target); // Exclusive: an existing directory, including an empty one, is not this attempt's.
43
+ claimed = true;
44
+ const rootIdentity = await files.inspectDirectoryIdentity(target);
45
+ if (!rootIdentity)
46
+ throw new Error('Worktree directory identity cannot be verified');
47
+ evidence = { root: target, rootIdentity, parentIdentity, commonDir, commonIdentity, lockReason: `dsh-create-${randomUUID()}` };
48
+ saveEvidence(evidence);
49
+ await checked(localRoot, ['worktree', 'add', '--detach', '--no-checkout', '--lock', '--reason', evidence.lockReason, target, baseOid]);
50
+ const gitDir = await realpath(await checked(target, ['rev-parse', '--absolute-git-dir']));
51
+ const gitIdentity = await files.inspectDirectoryIdentity(gitDir);
52
+ if (!gitIdentity)
53
+ throw new Error('Worktree metadata identity cannot be verified');
54
+ evidence = { ...evidence, gitDir, gitIdentity, metadataFingerprint: await metadataFingerprint(gitDir) };
55
+ saveEvidence(evidence);
56
+ registered = true;
57
+ await verifyIdentity(evidence, baseOid);
58
+ // read-tree publishes a complete index before any worktree file is written.
59
+ // checkout-index without -f never overwrites a file supplied by another writer.
60
+ const sparse = await checked(target, ['config', '--bool', '--get', 'core.sparseCheckout']).catch(error => {
61
+ if (failure?.code === 1) {
62
+ failure = undefined;
63
+ return 'false';
64
+ }
65
+ throw error;
66
+ });
67
+ if (sparse === 'true') {
68
+ // Match native worktree add's sparse checkout semantics. A failed reset
69
+ // may retain an index lock and therefore cannot be automatically removed.
70
+ await checked(target, ['reset', '--hard', '--no-recurse-submodules', baseOid]);
71
+ }
72
+ else {
73
+ await checked(target, ['read-tree', baseOid]);
74
+ evidence = { ...evidence, indexFingerprint: createHash('sha256').update(await readFile(join(gitDir, 'index'))).digest('hex') };
75
+ await saveEvidence(evidence);
76
+ await checked(target, ['checkout-index', '--all']);
77
+ }
78
+ await verifyIdentity(evidence, baseOid);
79
+ await checked(localRoot, ['worktree', 'unlock', target]);
80
+ }
81
+ catch (error) {
82
+ const message = error instanceof Error ? error.message : String(error);
83
+ if (!claimed)
84
+ throw new WorktreeCreationFailure(message, true);
85
+ if (evidence && !registered && failure?.quiescent === true) {
86
+ try {
87
+ const listed = await run(localRoot, ['worktree', 'list', '--porcelain', '-z']);
88
+ let metadata = [];
89
+ try {
90
+ metadata = (await readdir(join(evidence.commonDir, 'worktrees'))).sort();
91
+ }
92
+ catch (error) {
93
+ if (error.code !== 'ENOENT')
94
+ throw error;
95
+ }
96
+ const registeredRoot = listed.stdout.split('\0').some(part => part.startsWith('worktree ') && samePath(part.slice(9), target));
97
+ if (listed.code === 0 && !registeredRoot && JSON.stringify(metadata) === JSON.stringify(originalMetadata)
98
+ && sameIdentity(await files.inspectDirectoryIdentity(target), evidence.rootIdentity)
99
+ && sameIdentity(await files.inspectDirectoryIdentity(dirname(target)), evidence.parentIdentity)
100
+ && sameIdentity(await files.inspectDirectoryIdentity(evidence.commonDir), evidence.commonIdentity)
101
+ && (await readdir(target)).length === 0) {
102
+ await rmdir(target);
103
+ throw new WorktreeCreationFailure(message, true);
104
+ }
105
+ }
106
+ catch (cleanupError) {
107
+ if (cleanupError instanceof WorktreeCreationFailure)
108
+ throw cleanupError;
109
+ }
110
+ }
111
+ // A timeout in registration (including Git's initializing/index locks), a lost
112
+ // process-tree observation or missing durable identity is never deletion authority.
113
+ if (evidence && registered && failure?.quiescent === true) {
114
+ try {
115
+ await verifyIdentity(evidence, baseOid);
116
+ await verifyRollbackMetadata(evidence, baseOid);
117
+ await verifyUnmodified(evidence.root, baseOid, run);
118
+ const quarantinePath = `${target}.failed-${randomUUID()}`;
119
+ evidence = { ...evidence, quarantinePath };
120
+ saveEvidence(evidence);
121
+ // Unlike worktree repair (which also scans other registrations), move
122
+ // updates only this checkout's backlink and keeps its directory object.
123
+ const moved = await run(localRoot, ['worktree', 'move', '--force', '--force', target, quarantinePath]);
124
+ if (moved.code !== 0)
125
+ throw new Error(moved.stderr);
126
+ evidence = { ...evidence, root: quarantinePath, indexFingerprint: createHash('sha256').update(await readFile(join(evidence.gitDir, 'index'))).digest('hex') };
127
+ saveEvidence(evidence);
128
+ await verifyIdentity(evidence, baseOid);
129
+ await verifyRollbackMetadata(evidence, baseOid);
130
+ await verifyUnmodified(quarantinePath, baseOid, run);
131
+ await verifyIdentity(evidence, baseOid);
132
+ await verifyRollbackMetadata(evidence, baseOid);
133
+ const removed = await run(localRoot, ['worktree', 'remove', '--force', '--force', quarantinePath]);
134
+ if (removed.code !== 0)
135
+ throw new Error(removed.stderr);
136
+ if (files.exists(quarantinePath) || files.exists(evidence.gitDir))
137
+ throw new Error('Worktree rollback incomplete');
138
+ throw new WorktreeCreationFailure(message, true);
139
+ }
140
+ catch (rollbackError) {
141
+ if (rollbackError instanceof WorktreeCreationFailure)
142
+ throw rollbackError;
143
+ throw new WorktreeCreationFailure(`${message}; ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`, false);
144
+ }
145
+ }
146
+ throw new WorktreeCreationFailure(`${message}${evidence?.quarantinePath ? ` (${evidence.quarantinePath})` : ''}`, false);
147
+ }
148
+ }
149
+ async function verifyIdentity(e, baseOid) {
150
+ const fail = () => { throw new Error('Failed creation identity changed; residue preserved'); };
151
+ if (!e.gitDir || !e.gitIdentity)
152
+ return fail();
153
+ if (!sameIdentity(await files.inspectDirectoryIdentity(e.root), e.rootIdentity)
154
+ || !sameIdentity(await files.inspectDirectoryIdentity(dirname(e.root)), e.parentIdentity)
155
+ || !sameIdentity(await files.inspectDirectoryIdentity(e.commonDir), e.commonIdentity)
156
+ || !sameIdentity(await files.inspectDirectoryIdentity(e.gitDir), e.gitIdentity))
157
+ return fail();
158
+ const child = relative(join(e.commonDir, 'worktrees'), e.gitDir);
159
+ if (!child || child.includes('..') || isAbsolute(child) || child.includes('/') || child.includes('\\'))
160
+ return fail();
161
+ const text = async (path) => {
162
+ const stat = await lstat(path);
163
+ if (!stat.isFile() || stat.isSymbolicLink())
164
+ return fail();
165
+ return (await readFile(path, 'utf8')).trim();
166
+ };
167
+ const pointer = await text(join(e.root, '.git'));
168
+ if (!pointer.startsWith('gitdir: ') || !samePath(resolve(e.root, pointer.slice(8)), e.gitDir)
169
+ || !samePath(await text(join(e.gitDir, 'gitdir')), join(e.root, '.git'))
170
+ || !samePath(resolve(e.gitDir, await text(join(e.gitDir, 'commondir'))), e.commonDir)
171
+ || await text(join(e.gitDir, 'HEAD')) !== baseOid
172
+ || await text(join(e.gitDir, 'locked')) !== e.lockReason)
173
+ return fail();
174
+ // Never break an index lock, including an interrupted read-tree's lock.
175
+ if ((await readdir(e.gitDir)).some(name => name.endsWith('.lock')))
176
+ return fail();
177
+ }
178
+ async function verifyRollbackMetadata(e, baseOid) {
179
+ if (!e.gitDir || !e.metadataFingerprint || await metadataFingerprint(e.gitDir) !== e.metadataFingerprint)
180
+ throw new Error('Creation metadata changed');
181
+ if (!e.indexFingerprint || createHash('sha256').update(await readFile(join(e.gitDir, 'index'))).digest('hex') !== e.indexFingerprint)
182
+ throw new Error(`Creation index bytes changed at ${e.root}`);
183
+ for (const name of ['index', 'ORIG_HEAD']) {
184
+ try {
185
+ const path = join(e.gitDir, name), stat = await lstat(path);
186
+ if (!stat.isFile() || stat.isSymbolicLink())
187
+ throw new Error('Unexpected creation metadata object');
188
+ if (name === 'ORIG_HEAD' && (await readFile(path, 'utf8')).trim() !== baseOid)
189
+ throw new Error('Creation ORIG_HEAD changed');
190
+ }
191
+ catch (error) {
192
+ if (error.code !== 'ENOENT')
193
+ throw error;
194
+ }
195
+ }
196
+ }
197
+ async function metadataFingerprint(gitDir) {
198
+ const hash = createHash('sha256');
199
+ async function walk(path, prefix = '') {
200
+ for (const name of (await readdir(path)).sort()) {
201
+ // Git updates these during checkout or single-target move. Their semantic
202
+ // contents and pointer are checked separately; every other byte is immutable.
203
+ if (!prefix && ['index', 'gitdir', 'ORIG_HEAD'].includes(name))
204
+ continue;
205
+ const entry = join(path, name);
206
+ const stat = await lstat(entry);
207
+ const key = `${prefix}${name}`;
208
+ const allowed = stat.isDirectory() ? ['refs', 'logs', 'info'] : ['HEAD', 'commondir', 'locked', 'config.worktree', 'logs/HEAD', 'info/sparse-checkout'];
209
+ if (!allowed.includes(key))
210
+ throw new Error('Unknown creation metadata');
211
+ hash.update(`${key}\0`);
212
+ if (stat.isSymbolicLink())
213
+ throw new Error('Unexpected metadata symlink');
214
+ if (stat.isDirectory()) {
215
+ hash.update('directory\0');
216
+ await walk(entry, `${prefix}${name}/`);
217
+ }
218
+ else if (stat.isFile() && stat.size <= 1_048_576) {
219
+ hash.update(`file:${stat.size}\0`);
220
+ hash.update(await readFile(entry));
221
+ }
222
+ else
223
+ throw new Error('Unexpected metadata object');
224
+ }
225
+ }
226
+ await walk(gitDir);
227
+ return hash.digest('hex');
228
+ }
229
+ async function verifyUnmodified(root, baseOid, run) {
230
+ const checked = async (args) => {
231
+ const result = await run(root, args);
232
+ if (result.code !== 0)
233
+ throw new Error(result.stderr);
234
+ return result.stdout;
235
+ };
236
+ // The complete index must still equal the authorized base. No skip-worktree / assume-unchanged shortcuts.
237
+ const entries = await checked(['ls-files', '--stage', '-z']);
238
+ if (entries.split('\0').some(line => line.startsWith('160000 ')))
239
+ throw new Error('Submodule creation residue must be preserved');
240
+ // Clean filters and working-tree encodings may discard bytes while comparing.
241
+ // Such a semantic comparison cannot authorize deleting a failed checkout.
242
+ const paths = entries.split('\0').filter(Boolean).map(line => line.slice(line.indexOf('\t') + 1));
243
+ const tracked = new Set(paths);
244
+ const directories = new Set();
245
+ for (const path of paths) {
246
+ const segments = path.split('/');
247
+ for (let i = 1; i < segments.length; i++)
248
+ directories.add(segments.slice(0, i).join('/'));
249
+ }
250
+ const inspectEntries = async (directory, prefix = '') => {
251
+ for (const entry of await readdir(directory, { withFileTypes: true })) {
252
+ if (!prefix && entry.name === '.git')
253
+ continue;
254
+ const path = `${prefix}${entry.name}`;
255
+ if (entry.isDirectory()) {
256
+ if (!directories.has(path))
257
+ throw new Error('Unknown creation directory; preserved');
258
+ await inspectEntries(join(directory, entry.name), `${path}/`);
259
+ }
260
+ else if (!tracked.has(path))
261
+ throw new Error('Unknown creation contents; preserved');
262
+ }
263
+ };
264
+ await inspectEntries(root);
265
+ for (let i = 0; i < paths.length; i += 100) {
266
+ const attributes = await checked(['check-attr', '-z', 'filter', 'working-tree-encoding', '--', ...paths.slice(i, i + 100)]);
267
+ const fields = attributes.split('\0');
268
+ for (let j = 2; j < fields.length; j += 3) {
269
+ if (fields[j] !== 'unspecified' && fields[j] !== 'unset')
270
+ throw new Error('Checkout conversions require preservation');
271
+ }
272
+ }
273
+ for (const line of entries.split('\0').filter(Boolean)) {
274
+ const match = /^(\d+) ([0-9a-f]+) 0\t([\s\S]+)$/.exec(line);
275
+ if (!match)
276
+ throw new Error('Unexpected creation index entry');
277
+ const [, mode, oid, path] = match;
278
+ const absolute = resolve(root, path);
279
+ if (!absolute.startsWith(`${resolve(root)}${process.platform === 'win32' ? '\\' : '/'}`))
280
+ throw new Error('Invalid checkout path');
281
+ try {
282
+ const stat = await lstat(absolute);
283
+ const hash = createHash(oid.length === 64 ? 'sha256' : 'sha1');
284
+ if (mode === '120000' && stat.isSymbolicLink()) {
285
+ const bytes = Buffer.from(await readlink(absolute));
286
+ hash.update(`blob ${bytes.length}\0`).update(bytes);
287
+ }
288
+ else if (stat.isFile() && !stat.isSymbolicLink()) {
289
+ hash.update(`blob ${stat.size}\0`);
290
+ let size = 0;
291
+ for await (const chunk of createReadStream(absolute)) {
292
+ hash.update(chunk);
293
+ size += chunk.length;
294
+ }
295
+ if (size !== stat.size)
296
+ throw new Error('Checkout file changed while checking');
297
+ }
298
+ else
299
+ throw new Error('Unexpected checkout filesystem object');
300
+ if (hash.digest('hex') !== oid)
301
+ throw new Error('Checkout bytes require preservation');
302
+ }
303
+ catch (error) {
304
+ if (error.code !== 'ENOENT')
305
+ throw error;
306
+ }
307
+ }
308
+ const staged = await checked(['diff-index', '--cached', '--name-only', baseOid, '--']);
309
+ const flags = await checked(['ls-files', '-v', '-z']);
310
+ if (staged || flags.split('\0').some(line => line && !line.startsWith('H ')))
311
+ throw new Error(`Creation index entries changed: ${staged} / ${flags}`);
312
+ const unknown = await checked(['ls-files', '--others', '-z']); // includes ignored files
313
+ const changed = await checked(['diff', '--no-ext-diff', '--no-textconv', '--name-status', '-z', baseOid, '--']);
314
+ if (unknown)
315
+ throw new Error('Unknown creation contents; preserved');
316
+ const parts = changed.split('\0').filter(Boolean);
317
+ for (let i = 0; i < parts.length; i += 2)
318
+ if (parts[i] !== 'D' || !parts[i + 1])
319
+ throw new Error('Modified creation contents; preserved');
320
+ }
321
+ //# sourceMappingURL=worktree-creation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-creation.js","sourceRoot":"","sources":["../../src/adapters/worktree-creation.ts"],"names":[],"mappings":"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"}
@@ -147,8 +147,10 @@ export function createWorktreeConsoleControlPlane(options) {
147
147
  throw domainError('project_mismatch', hostMessage('theCurrentSessionCwdDoesNotMatchTheWorktree'));
148
148
  }
149
149
  }
150
- async function authorize(sessionId, checkoutId) {
151
- const caller = await options.module.inspect(sessionId);
150
+ async function authorize(sessionId, checkoutId, observedCaller) {
151
+ // Only read endpoints pass a caller observed in this request. Mutations
152
+ // always perform fresh inspection before their own transactional checks.
153
+ const caller = observedCaller ?? await options.module.inspect(sessionId);
152
154
  const record = recordOf(options.registry, checkoutId);
153
155
  if (record.ownerSessionId !== sessionId && record.sourceSessionId !== sessionId) {
154
156
  throw domainError('not_owner', hostMessage('theCurrentSessionIsNotAllowedToAccessThis'));
@@ -166,10 +168,10 @@ export function createWorktreeConsoleControlPlane(options) {
166
168
  }
167
169
  return record;
168
170
  }
169
- async function linkedReadAccess(sessionId, checkoutId) {
171
+ async function linkedReadAccess(sessionId, checkoutId, observedCaller) {
170
172
  const requested = recordOf(options.registry, checkoutId);
171
173
  if (requested.ownerSessionId === sessionId || requested.sourceSessionId === sessionId) {
172
- return { record: await authorize(sessionId, checkoutId), linkedRead: false };
174
+ return { record: await authorize(sessionId, checkoutId, observedCaller), linkedRead: false };
173
175
  }
174
176
  const caller = await callerTarget(sessionId);
175
177
  if (caller.checkout.kind !== 'isolated') {
@@ -219,6 +221,8 @@ export function createWorktreeConsoleControlPlane(options) {
219
221
  async function observe(record) {
220
222
  if (record.phase === 'discarded')
221
223
  return { managedRoot: null };
224
+ if (options.module.observeManagedCheckout)
225
+ return options.module.observeManagedCheckout(record.checkoutId);
222
226
  const managedRoot = await options.module.resolveManagedRoot(record.checkoutId);
223
227
  const snapshot = await options.git.inspect(managedRoot);
224
228
  if (snapshot === null)
@@ -270,8 +274,8 @@ export function createWorktreeConsoleControlPlane(options) {
270
274
  changedFiles: [...delivery.proof.changedFiles],
271
275
  };
272
276
  }
273
- async function details(sessionId, checkoutId, observedDeliveryProof) {
274
- const access = await linkedReadAccess(sessionId, checkoutId);
277
+ async function details(sessionId, checkoutId, observedDeliveryProof, observedCaller) {
278
+ const access = await linkedReadAccess(sessionId, checkoutId, observedCaller);
275
279
  const observed = await observe(access.record);
276
280
  let projectedRecord = access.record;
277
281
  if (access.acceptanceAnchorCheckoutId !== undefined) {
@@ -416,7 +420,7 @@ export function createWorktreeConsoleControlPlane(options) {
416
420
  if (target.checkout.kind === 'local')
417
421
  return { target: projectLocal(target, sessionId) };
418
422
  return {
419
- target: await details(sessionId, target.checkout.id, deliveryProofFromTarget(target)),
423
+ target: await details(sessionId, target.checkout.id, deliveryProofFromTarget(target), target),
420
424
  };
421
425
  }),
422
426
  list: request => outcome(async () => {
@@ -424,7 +428,7 @@ export function createWorktreeConsoleControlPlane(options) {
424
428
  let sourceSessionId = request.sessionId;
425
429
  let localRoot;
426
430
  if (caller.checkout.kind === 'isolated') {
427
- const anchor = await authorize(request.sessionId, caller.checkout.id);
431
+ const anchor = await authorize(request.sessionId, caller.checkout.id, caller);
428
432
  sourceSessionId = anchor.sourceSessionId ?? anchor.ownerSessionId;
429
433
  localRoot = anchor.localRoot;
430
434
  }