dsh-git-worktree 0.8.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.
- package/CHANGELOG.md +69 -0
- package/README.en.md +8 -5
- package/README.md +8 -5
- package/lib/adapters/git-options.d.ts +9 -0
- package/lib/adapters/git-options.js +19 -0
- package/lib/adapters/git-options.js.map +1 -0
- package/lib/adapters/git.d.ts +4 -1
- package/lib/adapters/git.js +171 -32
- package/lib/adapters/git.js.map +1 -1
- package/lib/adapters/initial-commit.d.ts +16 -0
- package/lib/adapters/initial-commit.js +112 -0
- package/lib/adapters/initial-commit.js.map +1 -0
- package/lib/adapters/lookup.js +21 -0
- package/lib/adapters/lookup.js.map +1 -1
- package/lib/adapters/project-skill-io.d.ts +12 -0
- package/lib/adapters/project-skill-io.js +96 -0
- package/lib/adapters/project-skill-io.js.map +1 -0
- package/lib/adapters/project-skill-provider.d.ts +25 -0
- package/lib/adapters/project-skill-provider.js +137 -0
- package/lib/adapters/project-skill-provider.js.map +1 -0
- package/lib/adapters/project-skills.d.ts +40 -0
- package/lib/adapters/project-skills.js +285 -0
- package/lib/adapters/project-skills.js.map +1 -0
- package/lib/adapters/registry.js +13 -2
- package/lib/adapters/registry.js.map +1 -1
- package/lib/adapters/worktree-creation.d.ts +11 -0
- package/lib/adapters/worktree-creation.js +321 -0
- package/lib/adapters/worktree-creation.js.map +1 -0
- package/lib/client/WorktreeCreateRow.js +2 -1
- package/lib/client/WorktreeCreateRow.js.map +1 -1
- package/lib/client/WorktreeReviewRow.d.ts +1 -1
- package/lib/client/WorktreeReviewRow.js +2 -2
- package/lib/client/WorktreeReviewRow.js.map +1 -1
- package/lib/client/actions.d.ts +1 -5
- package/lib/client/actions.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/pre-session/PreSessionWorktreeToggle.d.ts +2 -2
- package/lib/client/pre-session/PreSessionWorktreeToggle.js +92 -79
- package/lib/client/pre-session/PreSessionWorktreeToggle.js.map +1 -1
- package/lib/client/pre-session/controller.d.ts +3 -0
- package/lib/client/pre-session/controller.js +16 -4
- package/lib/client/pre-session/controller.js.map +1 -1
- package/lib/client/pre-session/harness-input.d.ts +13 -0
- package/lib/client/pre-session/harness-input.js +18 -0
- package/lib/client/pre-session/harness-input.js.map +1 -0
- package/lib/client/pre-session/index.d.ts +3 -3
- package/lib/client/pre-session/index.js +4 -3
- package/lib/client/pre-session/index.js.map +1 -1
- package/lib/client/review-console/PreflightStatus.js +3 -2
- package/lib/client/review-console/PreflightStatus.js.map +1 -1
- package/lib/client/review-console/ReviewActions.d.ts +4 -1
- package/lib/client/review-console/ReviewActions.js +73 -53
- package/lib/client/review-console/ReviewActions.js.map +1 -1
- package/lib/client/review-console/ReviewDetailsModal.d.ts +12 -0
- package/lib/client/review-console/ReviewDetailsModal.js +56 -0
- package/lib/client/review-console/ReviewDetailsModal.js.map +1 -0
- package/lib/client/review-console/ReviewIcon.d.ts +35 -0
- package/lib/client/review-console/ReviewIcon.js +14 -0
- package/lib/client/review-console/ReviewIcon.js.map +1 -0
- package/lib/client/review-console/WorktreeReviewPanel.d.ts +3 -7
- package/lib/client/review-console/WorktreeReviewPanel.js +8 -73
- package/lib/client/review-console/WorktreeReviewPanel.js.map +1 -1
- package/lib/client/review-console/review-console.styles.js +101 -23
- package/lib/client/review-console/review-console.styles.js.map +1 -1
- package/lib/client/styles.js +13 -10
- package/lib/client/styles.js.map +1 -1
- package/lib/client/target-console/TargetStatusAction.js +65 -46
- package/lib/client/target-console/TargetStatusAction.js.map +1 -1
- package/lib/client/target-console/WorktreeConsoleView.d.ts +2 -1
- package/lib/client/target-console/WorktreeConsoleView.js +5 -4
- package/lib/client/target-console/WorktreeConsoleView.js.map +1 -1
- package/lib/client/target-console/WorktreeManagerModal.js +1 -1
- package/lib/client/target-console/WorktreeManagerModal.js.map +1 -1
- package/lib/client/target-console/WorktreeReviewStatus.js +36 -81
- package/lib/client/target-console/WorktreeReviewStatus.js.map +1 -1
- package/lib/client/target-console/current-polling.d.ts +11 -0
- package/lib/client/target-console/current-polling.js +104 -0
- package/lib/client/target-console/current-polling.js.map +1 -0
- package/lib/client/target-console/target-console.styles.js +8 -0
- package/lib/client/target-console/target-console.styles.js.map +1 -1
- package/lib/client/workspace-sidebar/index.js +5 -2
- package/lib/client/workspace-sidebar/index.js.map +1 -1
- package/lib/client/workspace-sidebar/model.d.ts +3 -0
- package/lib/client/workspace-sidebar/model.js +83 -10
- package/lib/client/workspace-sidebar/model.js.map +1 -1
- package/lib/client.js +5608 -4004
- package/lib/console-contract.d.ts +20 -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 +117 -23
- package/lib/console-host/control-plane.js.map +1 -1
- package/lib/console-host/review-diff.d.ts +2 -1
- package/lib/console-host/review-diff.js +23 -2
- package/lib/console-host/review-diff.js.map +1 -1
- package/lib/console-host/service.d.ts +3 -1
- package/lib/console-host/service.js +12 -0
- package/lib/console-host/service.js.map +1 -1
- package/lib/console-remote/descriptors.js +3 -1
- package/lib/console-remote/descriptors.js.map +1 -1
- package/lib/console-remote/remote.d.ts +3 -1
- package/lib/console-remote/remote.js.map +1 -1
- package/lib/console-remote/schemas.d.ts +10 -2
- package/lib/console-remote/schemas.js +7 -0
- package/lib/console-remote/schemas.js.map +1 -1
- package/lib/creation-failure.d.ts +5 -0
- package/lib/creation-failure.js +10 -0
- package/lib/creation-failure.js.map +1 -0
- package/lib/i18n/client-messages.d.ts +168 -20
- package/lib/i18n/client-messages.js +71 -34
- package/lib/i18n/client-messages.js.map +1 -1
- package/lib/i18n/host-messages.d.ts +32 -0
- package/lib/i18n/host-messages.js +11 -0
- package/lib/i18n/host-messages.js.map +1 -1
- package/lib/index.d.ts +31 -2
- package/lib/index.js +12 -12
- package/lib/index.js.map +1 -1
- package/lib/ports.d.ts +30 -1
- package/lib/session-checkout-apply.d.ts +2 -0
- package/lib/session-checkout-apply.js +52 -36
- package/lib/session-checkout-apply.js.map +1 -1
- package/lib/session-checkout-module.js +60 -4
- package/lib/session-checkout-module.js.map +1 -1
- package/package.json +9 -2
- package/scripts/check-publish.mjs +4 -1
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/ports.d.ts
CHANGED
|
@@ -19,7 +19,14 @@ export interface SessionCheckoutProjectRecord {
|
|
|
19
19
|
name: string;
|
|
20
20
|
root: string;
|
|
21
21
|
}
|
|
22
|
+
export interface SidebarDirectoryMembership {
|
|
23
|
+
managedRoot: string;
|
|
24
|
+
workspaceIds: string[];
|
|
25
|
+
sessionIds: string[];
|
|
26
|
+
}
|
|
22
27
|
export interface SessionCheckoutLookupPort {
|
|
28
|
+
/** Read-only navigation evidence; never used to authorize a checkout operation. */
|
|
29
|
+
getSidebarMemberships?(managedRoots: readonly string[]): Promise<SidebarDirectoryMembership[]>;
|
|
23
30
|
getSession(sessionId: string): SessionCheckoutSessionRecord | undefined;
|
|
24
31
|
getProject(projectId: string): SessionCheckoutProjectRecord | undefined;
|
|
25
32
|
}
|
|
@@ -31,14 +38,22 @@ export interface GitCheckoutSnapshot {
|
|
|
31
38
|
headOid: string;
|
|
32
39
|
headRef: string;
|
|
33
40
|
}
|
|
41
|
+
export interface InitialCommitPreflight {
|
|
42
|
+
kind: 'ready' | 'empty' | 'files';
|
|
43
|
+
fingerprint: string;
|
|
44
|
+
snapshot: GitCheckoutSnapshot;
|
|
45
|
+
}
|
|
34
46
|
export interface SessionCheckoutGitPort {
|
|
47
|
+
/** Optional for third-party ports; unsupported ports must not initialize. */
|
|
48
|
+
preflightInitialCommit?(root: string): Promise<InitialCommitPreflight>;
|
|
49
|
+
initializeEmptyRepository?(root: string, fingerprint: string, assertAuthorized?: () => Promise<void>): Promise<string>;
|
|
35
50
|
inspect(root: string): Promise<GitCheckoutSnapshot | null>;
|
|
36
51
|
/** Top-level of the Git checkout containing the directory; does not require a HEAD. */
|
|
37
52
|
findContainingWorktreeRoot(root: string): Promise<string | null>;
|
|
38
53
|
status(root: string): Promise<{
|
|
39
54
|
dirty: boolean;
|
|
40
55
|
}>;
|
|
41
|
-
createDetachedWorktree(localRoot: string, managedRoot: string, baseOid: string): Promise<void>;
|
|
56
|
+
createDetachedWorktree(localRoot: string, managedRoot: string, baseOid: string, saveEvidence?: (evidence: WorktreeCreationEvidence) => void): Promise<void>;
|
|
42
57
|
/** Deletion after the host verified checkout identity and the full fingerprint including untracked. */
|
|
43
58
|
removeWorktree(localRoot: string, managedRoot: string): Promise<void>;
|
|
44
59
|
retainApplyBase(localRoot: string, checkoutId: string, oid: string): Promise<void>;
|
|
@@ -84,9 +99,23 @@ interface ManagedCheckoutJournalBase {
|
|
|
84
99
|
operationId: string;
|
|
85
100
|
startedAt: number;
|
|
86
101
|
}
|
|
102
|
+
export interface WorktreeCreationEvidence {
|
|
103
|
+
root: string;
|
|
104
|
+
rootIdentity: DirectoryIdentity;
|
|
105
|
+
parentIdentity: DirectoryIdentity;
|
|
106
|
+
commonDir: string;
|
|
107
|
+
commonIdentity: DirectoryIdentity;
|
|
108
|
+
lockReason: string;
|
|
109
|
+
gitDir?: string;
|
|
110
|
+
gitIdentity?: DirectoryIdentity;
|
|
111
|
+
metadataFingerprint?: string;
|
|
112
|
+
indexFingerprint?: string;
|
|
113
|
+
quarantinePath?: string;
|
|
114
|
+
}
|
|
87
115
|
export interface ManagedCheckoutCreateJournal extends ManagedCheckoutJournalBase {
|
|
88
116
|
operation: 'create';
|
|
89
117
|
step: 'creating_worktree';
|
|
118
|
+
creation?: WorktreeCreationEvidence;
|
|
90
119
|
}
|
|
91
120
|
export interface ManagedCheckoutMutationJournal extends ManagedCheckoutJournalBase {
|
|
92
121
|
operation: 'apply' | 'preview' | 'checkpoint' | 'rollback_preview' | 'finish' | 'finalize_preview' | 'cleanup';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ProjectSkillStore } from './adapters/project-skills.js';
|
|
1
2
|
import type { ApplyBaseStrategy } from './types.js';
|
|
2
3
|
export interface ApplyPlanInput {
|
|
3
4
|
baseOid: string;
|
|
@@ -227,6 +228,7 @@ export interface SessionCheckoutApplyEngine {
|
|
|
227
228
|
}): Promise<FinishResult>;
|
|
228
229
|
}
|
|
229
230
|
export interface SessionCheckoutApplyEngineOptions {
|
|
231
|
+
projectSkills?: ProjectSkillStore;
|
|
230
232
|
/** 测试/宿主 seam:在最后一次 Local fingerprint 校验前执行。 */
|
|
231
233
|
beforeFinalLocalValidation?(): Promise<void> | void;
|
|
232
234
|
/** 测试/宿主 seam:在 Local 写入完成、独立写后验证开始前执行。 */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { trackedSkillPaths } from './adapters/project-skills.js';
|
|
1
2
|
import { hostMessage } from './i18n/host.js';
|
|
2
3
|
import { spawn } from 'node:child_process';
|
|
3
4
|
import { createHash, randomUUID } from 'node:crypto';
|
|
@@ -18,7 +19,11 @@ const GIT_TIMEOUT_MS = 30_000;
|
|
|
18
19
|
const OID_PATTERN = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/i;
|
|
19
20
|
async function runGit(cwd, args, options = {}) {
|
|
20
21
|
return await new Promise((resolveResult, reject) => {
|
|
21
|
-
|
|
22
|
+
// Review/delivery must support the same Windows paths as initial creation.
|
|
23
|
+
const child = spawn('git', [
|
|
24
|
+
...(process.platform === 'win32' ? ['-c', 'core.longpaths=true'] : []),
|
|
25
|
+
'-c', 'core.quotePath=false', ...args,
|
|
26
|
+
], {
|
|
22
27
|
cwd,
|
|
23
28
|
env: {
|
|
24
29
|
...process.env,
|
|
@@ -145,7 +150,7 @@ function snapshotFingerprint(headOid, headRef, indexEntries, treeOid) {
|
|
|
145
150
|
.update(treeOid)
|
|
146
151
|
.digest('hex');
|
|
147
152
|
}
|
|
148
|
-
async function captureSnapshot(checkoutPath, indexPath, objectDirectory, sourceObjects) {
|
|
153
|
+
async function captureSnapshot(checkoutPath, indexPath, objectDirectory, sourceObjects, projectSkills) {
|
|
149
154
|
const headOid = stdoutText(await runGit(checkoutPath, ['rev-parse', 'HEAD']));
|
|
150
155
|
const headTreeOid = stdoutText(await runGit(checkoutPath, ['rev-parse', `${headOid}^{tree}`]));
|
|
151
156
|
const symbolic = await runGit(checkoutPath, ['symbolic-ref', '--quiet', 'HEAD'], { allowedExitCodes: [0, 1] });
|
|
@@ -176,8 +181,16 @@ async function captureSnapshot(checkoutPath, indexPath, objectDirectory, sourceO
|
|
|
176
181
|
const indexTreeOid = stdoutText(await runGit(checkoutPath, ['write-tree'], { env }));
|
|
177
182
|
// 先还原真实 index 的 staged 语义,再叠加 working tree,得到完整最终状态。
|
|
178
183
|
await runGit(checkoutPath, ['add', '-A', '--', '.'], { env });
|
|
184
|
+
let carried = null;
|
|
185
|
+
if (await projectSkills?.paths(checkoutPath)) {
|
|
186
|
+
const headPaths = (await runGit(checkoutPath, ['ls-tree', '-r', '--name-only', '-z', headOid])).stdout;
|
|
187
|
+
carried = await projectSkills.state(checkoutPath, trackedSkillPaths(indexEntries, headPaths));
|
|
188
|
+
if (carried?.paths.length)
|
|
189
|
+
await runGit(checkoutPath, ['update-index', '--force-remove', '-z', '--stdin'], { env, input: Buffer.from(carried.paths.join('\0') + '\0') });
|
|
190
|
+
}
|
|
179
191
|
const treeOid = stdoutText(await runGit(checkoutPath, ['write-tree'], { env }));
|
|
180
|
-
const
|
|
192
|
+
const primaryFingerprint = snapshotFingerprint(headOid, headRef, indexEntries, treeOid);
|
|
193
|
+
const fingerprint = carried?.paths.length ? createHash('sha256').update(primaryFingerprint).update(carried.fingerprint).digest('hex') : primaryFingerprint;
|
|
181
194
|
return { fingerprint, headOid, headRef, headTreeOid, indexTreeOid, treeOid, indexEntries };
|
|
182
195
|
}
|
|
183
196
|
async function createSnapshotCommit(checkoutPath, treeOid, parentOid, objectDirectory, sourceObjects, label) {
|
|
@@ -527,6 +540,9 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
527
540
|
constructor(options) {
|
|
528
541
|
this.options = options;
|
|
529
542
|
}
|
|
543
|
+
captureSnapshot(checkoutPath, indexPath, objectDirectory, sourceObjects) {
|
|
544
|
+
return captureSnapshot(checkoutPath, indexPath, objectDirectory, sourceObjects, this.options.projectSkills);
|
|
545
|
+
}
|
|
530
546
|
async checkpoint(input) {
|
|
531
547
|
const commitMessage = input.commitMessage.trim();
|
|
532
548
|
if (!commitMessage || commitMessage.length > 500 || !OID_PATTERN.test(input.expectedHeadOid) || !input.expectedFingerprint.trim()) {
|
|
@@ -543,7 +559,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
543
559
|
if (projectPathPrefix === null) {
|
|
544
560
|
return { status: 'error', error: { code: 'invalid_input', message: hostMessage('theCheckpointProjectDirectoryDoesNotBelongToThe') } };
|
|
545
561
|
}
|
|
546
|
-
const snapshot = await captureSnapshot(isolatedGitRoot, join(tempRoot, 'checkpoint.index'), null, null);
|
|
562
|
+
const snapshot = await this.captureSnapshot(isolatedGitRoot, join(tempRoot, 'checkpoint.index'), null, null);
|
|
547
563
|
if (snapshot.headRef !== null) {
|
|
548
564
|
return { status: 'error', error: { code: 'operation_not_allowed', message: hostMessage('checkpointCanOnlyWriteToADetachedManagedWorktree') } };
|
|
549
565
|
}
|
|
@@ -571,7 +587,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
571
587
|
await indexLock.close();
|
|
572
588
|
await copyFile(finalIndexPath, adjacentIndex);
|
|
573
589
|
await this.options.beforeFinalIsolatedValidation?.();
|
|
574
|
-
const finalSnapshot = await captureSnapshot(isolatedGitRoot, join(tempRoot, 'final-checkpoint.index'), null, null);
|
|
590
|
+
const finalSnapshot = await this.captureSnapshot(isolatedGitRoot, join(tempRoot, 'final-checkpoint.index'), null, null);
|
|
575
591
|
if (finalSnapshot.headOid !== snapshot.headOid || finalSnapshot.fingerprint !== snapshot.fingerprint) {
|
|
576
592
|
return { status: 'error', error: { code: 'stale_isolated', message: hostMessage('worktreeChangedBeforeSavingTheCheckpointPrepareTheReview') } };
|
|
577
593
|
}
|
|
@@ -612,7 +628,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
612
628
|
}
|
|
613
629
|
try {
|
|
614
630
|
await this.options.afterIsolatedWriteBeforeVerification?.();
|
|
615
|
-
const completed = await captureSnapshot(isolatedGitRoot, join(tempRoot, 'completed.index'), null, null);
|
|
631
|
+
const completed = await this.captureSnapshot(isolatedGitRoot, join(tempRoot, 'completed.index'), null, null);
|
|
616
632
|
if (completed.headOid !== commitOid
|
|
617
633
|
|| completed.headRef !== null
|
|
618
634
|
|| completed.headTreeOid !== snapshot.treeOid
|
|
@@ -676,7 +692,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
676
692
|
const targetTreeOid = stdoutText(await runGit(isolatedGitRoot, ['rev-parse', `${input.commitOid}^{tree}`]));
|
|
677
693
|
const existingLock = await inspectIndexFileTree(isolatedGitRoot, indexLockPath);
|
|
678
694
|
const markerOwned = await checkpointLockMarkerOwned(indexLockMarker, input.commitOid);
|
|
679
|
-
const snapshot = await captureSnapshot(isolatedGitRoot, join(tempRoot, 'current.index'), null, null);
|
|
695
|
+
const snapshot = await this.captureSnapshot(isolatedGitRoot, join(tempRoot, 'current.index'), null, null);
|
|
680
696
|
if (snapshot.headRef !== null) {
|
|
681
697
|
return { status: 'error', error: { code: 'stale_isolated', message: hostMessage('worktreeNoLongerHasADetachedHEAD') } };
|
|
682
698
|
}
|
|
@@ -720,7 +736,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
720
736
|
await copyFile(cleanIndexPath, indexLockPath);
|
|
721
737
|
}
|
|
722
738
|
await this.options.beforeFinalIsolatedValidation?.();
|
|
723
|
-
const lockedSnapshot = await captureSnapshot(isolatedGitRoot, join(tempRoot, 'locked-current.index'), null, null);
|
|
739
|
+
const lockedSnapshot = await this.captureSnapshot(isolatedGitRoot, join(tempRoot, 'locked-current.index'), null, null);
|
|
724
740
|
if (lockedSnapshot.headOid !== snapshot.headOid
|
|
725
741
|
|| lockedSnapshot.fingerprint !== snapshot.fingerprint
|
|
726
742
|
|| (lockedSnapshot.indexTreeOid !== input.expectedIndexTreeOid && lockedSnapshot.indexTreeOid !== lockedSnapshot.headTreeOid)) {
|
|
@@ -730,7 +746,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
730
746
|
ownedIndexLock = null;
|
|
731
747
|
await removeBestEffort(indexLockMarker);
|
|
732
748
|
ownedLockMarker = null;
|
|
733
|
-
const completed = await captureSnapshot(isolatedGitRoot, join(tempRoot, 'completed.index'), null, null);
|
|
749
|
+
const completed = await this.captureSnapshot(isolatedGitRoot, join(tempRoot, 'completed.index'), null, null);
|
|
734
750
|
if (completed.headOid !== input.commitOid
|
|
735
751
|
|| completed.headRef !== null
|
|
736
752
|
|| completed.indexTreeOid !== completed.headTreeOid
|
|
@@ -771,7 +787,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
771
787
|
return { status: 'error', error: { code: 'invalid_input', message: hostMessage('theLocalAndIsolatedProjectSubdirectoriesDoNotMatch') } };
|
|
772
788
|
}
|
|
773
789
|
await runGit(localGitRoot, ['cat-file', '-e', `${input.baseOid}^{commit}`]);
|
|
774
|
-
const isolated = await captureSnapshot(isolatedGitRoot, join(tempRoot, 'isolated.index'), objectDirectory, localObjects);
|
|
790
|
+
const isolated = await this.captureSnapshot(isolatedGitRoot, join(tempRoot, 'isolated.index'), objectDirectory, localObjects);
|
|
775
791
|
const changedFiles = await changedTreePaths(isolatedGitRoot, input.baseOid, isolated.treeOid, objectDirectory, localObjects);
|
|
776
792
|
if (changedFiles.some((path) => !isProjectPath(path, localPrefix))) {
|
|
777
793
|
return { status: 'error', error: { code: 'invalid_input', message: hostMessage('isolatedContainsChangesOutsideTheProjectRootAReview') } };
|
|
@@ -819,8 +835,8 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
819
835
|
return { status: 'error', error: { code: 'invalid_input', message: hostMessage('theLocalAndIsolatedProjectSubdirectoriesDoNotMatch') } };
|
|
820
836
|
}
|
|
821
837
|
await runGit(localGitRoot, ['cat-file', '-e', `${input.baseOid}^{commit}`]);
|
|
822
|
-
const local = await captureSnapshot(localGitRoot, join(tempRoot, 'local.index'), objectDirectory, localObjects);
|
|
823
|
-
const isolated = await captureSnapshot(isolatedGitRoot, join(tempRoot, 'isolated.index'), objectDirectory, localObjects);
|
|
838
|
+
const local = await this.captureSnapshot(localGitRoot, join(tempRoot, 'local.index'), objectDirectory, localObjects);
|
|
839
|
+
const isolated = await this.captureSnapshot(isolatedGitRoot, join(tempRoot, 'isolated.index'), objectDirectory, localObjects);
|
|
824
840
|
const effectiveBase = await selectEffectiveApplyBase(localGitRoot, input.baseOid, local.headOid, isolated.headOid);
|
|
825
841
|
const isolatedChangedPaths = await changedTreePaths(isolatedGitRoot, effectiveBase.oid, isolated.treeOid, objectDirectory, localObjects);
|
|
826
842
|
if (isolatedChangedPaths.some((path) => !isProjectPath(path, localPrefix))) {
|
|
@@ -892,23 +908,23 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
892
908
|
if (!pathsMatch(sourceObjects, stored.scope.sourceObjects)) {
|
|
893
909
|
return { status: 'error', error: { code: 'invalid_plan', message: hostMessage('theApplyPlanSGitRepositoryIdentityHasChanged') } };
|
|
894
910
|
}
|
|
895
|
-
const local = await captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'local.index'), objectDirectory, sourceObjects);
|
|
911
|
+
const local = await this.captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'local.index'), objectDirectory, sourceObjects);
|
|
896
912
|
if (local.headOid !== stored.plan.localHeadOid || local.fingerprint !== stored.plan.localFingerprint) {
|
|
897
913
|
return { status: 'error', error: { code: 'stale_local', message: hostMessage('localChangedAfterPlanningRecalculateThePlan') } };
|
|
898
914
|
}
|
|
899
|
-
const isolated = await captureSnapshot(stored.scope.isolatedGitRoot, join(tempRoot, 'isolated.index'), objectDirectory, sourceObjects);
|
|
915
|
+
const isolated = await this.captureSnapshot(stored.scope.isolatedGitRoot, join(tempRoot, 'isolated.index'), objectDirectory, sourceObjects);
|
|
900
916
|
if (isolated.headOid !== stored.plan.isolatedHeadOid || isolated.fingerprint !== stored.plan.isolatedFingerprint) {
|
|
901
917
|
return { status: 'error', error: { code: 'stale_isolated', message: hostMessage('isolatedChangedAfterPlanningRecalculateThePlan') } };
|
|
902
918
|
}
|
|
903
919
|
// 将已审核的 Isolated 最终状态写成无 ref 的内部 commit,供同一 checkout 后续 Apply 去重。
|
|
904
920
|
// 使用独立 index,不改变 Isolated 的真实 staged/working tree。
|
|
905
|
-
const persistentIsolated = await captureSnapshot(stored.scope.isolatedGitRoot, join(tempRoot, 'persistent-isolated.index'), null, null);
|
|
921
|
+
const persistentIsolated = await this.captureSnapshot(stored.scope.isolatedGitRoot, join(tempRoot, 'persistent-isolated.index'), null, null);
|
|
906
922
|
if (persistentIsolated.fingerprint !== stored.plan.isolatedFingerprint) {
|
|
907
923
|
return { status: 'error', error: { code: 'stale_isolated', message: hostMessage('isolatedChangedAfterPlanningRecalculateThePlan') } };
|
|
908
924
|
}
|
|
909
925
|
const nextBaseOid = await createSnapshotCommit(stored.scope.isolatedGitRoot, persistentIsolated.treeOid, stored.plan.effectiveBaseOid, null, null, 'Applied Isolated snapshot');
|
|
910
926
|
await this.options.beforeFinalLocalValidation?.();
|
|
911
|
-
const finalLocal = await captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'final-local.index'), objectDirectory, sourceObjects);
|
|
927
|
+
const finalLocal = await this.captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'final-local.index'), objectDirectory, sourceObjects);
|
|
912
928
|
if (finalLocal.headOid !== stored.plan.localHeadOid || finalLocal.fingerprint !== stored.plan.localFingerprint) {
|
|
913
929
|
return {
|
|
914
930
|
status: 'error',
|
|
@@ -946,18 +962,18 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
946
962
|
if (!pathsMatch(sourceObjects, stored.scope.sourceObjects)) {
|
|
947
963
|
return { status: 'error', error: { code: 'invalid_plan', message: hostMessage('thePreviewPlanSGitRepositoryIdentityHasChanged') } };
|
|
948
964
|
}
|
|
949
|
-
const local = await captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'local.index'), objectDirectory, sourceObjects);
|
|
965
|
+
const local = await this.captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'local.index'), objectDirectory, sourceObjects);
|
|
950
966
|
if (local.headOid !== stored.plan.localHeadOid
|
|
951
967
|
|| local.headRef !== stored.plan.localHeadRef
|
|
952
968
|
|| local.fingerprint !== stored.plan.localFingerprint) {
|
|
953
969
|
return { status: 'error', error: { code: 'stale_local', message: hostMessage('localChangedAfterPlanningRecalculateThePlan') } };
|
|
954
970
|
}
|
|
955
|
-
const isolated = await captureSnapshot(stored.scope.isolatedGitRoot, join(tempRoot, 'isolated.index'), objectDirectory, sourceObjects);
|
|
971
|
+
const isolated = await this.captureSnapshot(stored.scope.isolatedGitRoot, join(tempRoot, 'isolated.index'), objectDirectory, sourceObjects);
|
|
956
972
|
if (isolated.headOid !== stored.plan.isolatedHeadOid || isolated.fingerprint !== stored.plan.isolatedFingerprint) {
|
|
957
973
|
return { status: 'error', error: { code: 'stale_isolated', message: hostMessage('isolatedChangedAfterPlanningRecalculateThePlan') } };
|
|
958
974
|
}
|
|
959
|
-
const persistentLocal = await captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'persistent-local.index'), null, null);
|
|
960
|
-
const persistentIsolated = await captureSnapshot(stored.scope.isolatedGitRoot, join(tempRoot, 'persistent-isolated.index'), null, null);
|
|
975
|
+
const persistentLocal = await this.captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'persistent-local.index'), null, null);
|
|
976
|
+
const persistentIsolated = await this.captureSnapshot(stored.scope.isolatedGitRoot, join(tempRoot, 'persistent-isolated.index'), null, null);
|
|
961
977
|
if (persistentLocal.fingerprint !== stored.plan.localFingerprint
|
|
962
978
|
|| persistentIsolated.fingerprint !== stored.plan.isolatedFingerprint) {
|
|
963
979
|
return { status: 'error', error: { code: 'invalid_plan', message: hostMessage('thePersistentPreviewSnapshotDoesNotMatchTheReviewed') } };
|
|
@@ -985,7 +1001,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
985
1001
|
changedFiles: [...stored.plan.changedFiles],
|
|
986
1002
|
};
|
|
987
1003
|
await this.options.beforeFinalLocalValidation?.();
|
|
988
|
-
const finalLocal = await captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'final-local.index'), objectDirectory, sourceObjects);
|
|
1004
|
+
const finalLocal = await this.captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'final-local.index'), objectDirectory, sourceObjects);
|
|
989
1005
|
if (finalLocal.headOid !== stored.plan.localHeadOid || finalLocal.fingerprint !== stored.plan.localFingerprint) {
|
|
990
1006
|
return { status: 'error', error: { code: 'stale_local', message: hostMessage('localChangedBeforePreviewWroteItsChangesRecalculateThe') } };
|
|
991
1007
|
}
|
|
@@ -993,7 +1009,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
993
1009
|
if (stored.patch.length > 0) {
|
|
994
1010
|
await runGit(stored.scope.localGitRoot, ['apply', '--binary', '--whitespace=nowarn'], { input: stored.patch });
|
|
995
1011
|
}
|
|
996
|
-
const previewedLocal = await captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'previewed-local.index'), null, null);
|
|
1012
|
+
const previewedLocal = await this.captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'previewed-local.index'), null, null);
|
|
997
1013
|
if (previewedLocal.treeOid !== previewWorkingTreeOid) {
|
|
998
1014
|
return {
|
|
999
1015
|
status: 'error',
|
|
@@ -1023,7 +1039,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
1023
1039
|
const objectDirectory = join(tempRoot, 'objects');
|
|
1024
1040
|
await mkdir(objectDirectory, { recursive: true });
|
|
1025
1041
|
const sourceObjects = await sourceObjectDirectory(localGitRoot);
|
|
1026
|
-
const current = await captureSnapshot(localGitRoot, join(tempRoot, 'current.index'), objectDirectory, sourceObjects);
|
|
1042
|
+
const current = await this.captureSnapshot(localGitRoot, join(tempRoot, 'current.index'), objectDirectory, sourceObjects);
|
|
1027
1043
|
const rollback = await prepareRollbackAssessment(tempRoot, sourceObjects, objectDirectory, localGitRoot, current, input.receipt);
|
|
1028
1044
|
const finalize = await prepareFinalizeAssessment(tempRoot, sourceObjects, objectDirectory, localGitRoot, current, input.receipt);
|
|
1029
1045
|
return {
|
|
@@ -1053,7 +1069,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
1053
1069
|
const objectDirectory = join(tempRoot, 'objects');
|
|
1054
1070
|
await mkdir(objectDirectory, { recursive: true });
|
|
1055
1071
|
const sourceObjects = await sourceObjectDirectory(localGitRoot);
|
|
1056
|
-
const current = await captureSnapshot(localGitRoot, join(tempRoot, 'current.index'), objectDirectory, sourceObjects);
|
|
1072
|
+
const current = await this.captureSnapshot(localGitRoot, join(tempRoot, 'current.index'), objectDirectory, sourceObjects);
|
|
1057
1073
|
const assessment = await prepareRollbackAssessment(tempRoot, sourceObjects, objectDirectory, localGitRoot, current, input.receipt);
|
|
1058
1074
|
if (assessment.status === 'blocked') {
|
|
1059
1075
|
return { status: 'error', error: { code: assessment.code, message: assessment.message } };
|
|
@@ -1063,7 +1079,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
1063
1079
|
// final Local CAS. From the snapshot below to git apply there is no callback/yield seam.
|
|
1064
1080
|
await input.beforeWrite?.();
|
|
1065
1081
|
await this.options.beforeFinalLocalValidation?.();
|
|
1066
|
-
const finalLocal = await captureSnapshot(localGitRoot, join(tempRoot, 'final-local.index'), objectDirectory, sourceObjects);
|
|
1082
|
+
const finalLocal = await this.captureSnapshot(localGitRoot, join(tempRoot, 'final-local.index'), objectDirectory, sourceObjects);
|
|
1067
1083
|
if (finalLocal.fingerprint !== current.fingerprint
|
|
1068
1084
|
|| finalLocal.headOid !== current.headOid
|
|
1069
1085
|
|| finalLocal.headRef !== current.headRef) {
|
|
@@ -1075,7 +1091,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
1075
1091
|
let rolledBack;
|
|
1076
1092
|
try {
|
|
1077
1093
|
await this.options.afterLocalWriteBeforeVerification?.();
|
|
1078
|
-
rolledBack = await captureSnapshot(localGitRoot, join(tempRoot, 'rolled-back.index'), null, null);
|
|
1094
|
+
rolledBack = await this.captureSnapshot(localGitRoot, join(tempRoot, 'rolled-back.index'), null, null);
|
|
1079
1095
|
}
|
|
1080
1096
|
catch (error) {
|
|
1081
1097
|
return {
|
|
@@ -1127,7 +1143,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
1127
1143
|
const objectDirectory = join(tempRoot, 'objects');
|
|
1128
1144
|
await mkdir(objectDirectory, { recursive: true });
|
|
1129
1145
|
const sourceObjects = await sourceObjectDirectory(localGitRoot);
|
|
1130
|
-
const current = await captureSnapshot(localGitRoot, join(tempRoot, 'current.index'), objectDirectory, sourceObjects);
|
|
1146
|
+
const current = await this.captureSnapshot(localGitRoot, join(tempRoot, 'current.index'), objectDirectory, sourceObjects);
|
|
1131
1147
|
const realIndexPath = await resolveIndexPath(localGitRoot);
|
|
1132
1148
|
const originalIndexBytes = await readFile(realIndexPath);
|
|
1133
1149
|
const assessment = await prepareFinalizeAssessment(tempRoot, sourceObjects, objectDirectory, localGitRoot, current, input.receipt);
|
|
@@ -1136,7 +1152,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
1136
1152
|
}
|
|
1137
1153
|
if (!assessment.commitRequired) {
|
|
1138
1154
|
await this.options.beforeFinalLocalValidation?.();
|
|
1139
|
-
const finalLocal = await captureSnapshot(localGitRoot, join(tempRoot, 'final-empty.index'), objectDirectory, sourceObjects);
|
|
1155
|
+
const finalLocal = await this.captureSnapshot(localGitRoot, join(tempRoot, 'final-empty.index'), objectDirectory, sourceObjects);
|
|
1140
1156
|
if (finalLocal.headOid !== current.headOid
|
|
1141
1157
|
|| finalLocal.headRef !== current.headRef
|
|
1142
1158
|
|| finalLocal.fingerprint !== current.fingerprint) {
|
|
@@ -1183,7 +1199,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
1183
1199
|
}
|
|
1184
1200
|
throw error;
|
|
1185
1201
|
}
|
|
1186
|
-
const finalLocal = await captureSnapshot(localGitRoot, join(tempRoot, 'final-local.index'), objectDirectory, sourceObjects);
|
|
1202
|
+
const finalLocal = await this.captureSnapshot(localGitRoot, join(tempRoot, 'final-local.index'), objectDirectory, sourceObjects);
|
|
1187
1203
|
const finalIndexBytes = await readFile(realIndexPath);
|
|
1188
1204
|
if (finalLocal.headOid !== current.headOid
|
|
1189
1205
|
|| finalLocal.headRef !== current.headRef
|
|
@@ -1207,7 +1223,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
1207
1223
|
if (!writeError) {
|
|
1208
1224
|
try {
|
|
1209
1225
|
await this.options.afterLocalWriteBeforeVerification?.();
|
|
1210
|
-
const committed = await captureSnapshot(localGitRoot, join(tempRoot, 'committed.index'), null, null);
|
|
1226
|
+
const committed = await this.captureSnapshot(localGitRoot, join(tempRoot, 'committed.index'), null, null);
|
|
1211
1227
|
const committedIndexBytes = await readFile(realIndexPath);
|
|
1212
1228
|
if (committed.headOid === commitOid
|
|
1213
1229
|
&& committed.headRef === branchRef
|
|
@@ -1272,7 +1288,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
1272
1288
|
let restored = false;
|
|
1273
1289
|
if (rollbackErrors.length === 0) {
|
|
1274
1290
|
try {
|
|
1275
|
-
const restoredLocal = await captureSnapshot(localGitRoot, join(tempRoot, 'restored.index'), null, null);
|
|
1291
|
+
const restoredLocal = await this.captureSnapshot(localGitRoot, join(tempRoot, 'restored.index'), null, null);
|
|
1276
1292
|
const restoredIndexBytes = await readFile(realIndexPath);
|
|
1277
1293
|
restored = restoredLocal.headOid === current.headOid
|
|
1278
1294
|
&& restoredLocal.headRef === current.headRef
|
|
@@ -1344,13 +1360,13 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
1344
1360
|
if (!pathsMatch(sourceObjects, stored.scope.sourceObjects)) {
|
|
1345
1361
|
return { status: 'error', error: { code: 'invalid_plan', message: hostMessage('theFinishPlanSGitRepositoryIdentityHasChanged') } };
|
|
1346
1362
|
}
|
|
1347
|
-
const local = await captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'local.index'), objectDirectory, sourceObjects);
|
|
1363
|
+
const local = await this.captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'local.index'), objectDirectory, sourceObjects);
|
|
1348
1364
|
if (local.headOid !== stored.plan.localHeadOid
|
|
1349
1365
|
|| local.headRef !== stored.plan.localHeadRef
|
|
1350
1366
|
|| local.fingerprint !== stored.plan.localFingerprint) {
|
|
1351
1367
|
return { status: 'error', error: { code: 'stale_local', message: hostMessage('localChangedAfterPlanningRecalculateThePlan') } };
|
|
1352
1368
|
}
|
|
1353
|
-
const isolated = await captureSnapshot(stored.scope.isolatedGitRoot, join(tempRoot, 'isolated.index'), objectDirectory, sourceObjects);
|
|
1369
|
+
const isolated = await this.captureSnapshot(stored.scope.isolatedGitRoot, join(tempRoot, 'isolated.index'), objectDirectory, sourceObjects);
|
|
1354
1370
|
if (isolated.headOid !== stored.plan.isolatedHeadOid || isolated.fingerprint !== stored.plan.isolatedFingerprint) {
|
|
1355
1371
|
return { status: 'error', error: { code: 'stale_isolated', message: hostMessage('isolatedChangedAfterPlanningRecalculateThePlan') } };
|
|
1356
1372
|
}
|
|
@@ -1365,14 +1381,14 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
1365
1381
|
|| merge.changedFiles.some((path, index) => path !== stored.plan.changedFiles[index])) {
|
|
1366
1382
|
return { status: 'error', error: { code: 'invalid_plan', message: hostMessage('theFileSetChangedDuringFinishRevalidation') } };
|
|
1367
1383
|
}
|
|
1368
|
-
const persistentIsolated = await captureSnapshot(stored.scope.isolatedGitRoot, join(tempRoot, 'persistent-isolated.index'), null, null);
|
|
1384
|
+
const persistentIsolated = await this.captureSnapshot(stored.scope.isolatedGitRoot, join(tempRoot, 'persistent-isolated.index'), null, null);
|
|
1369
1385
|
if (persistentIsolated.fingerprint !== stored.plan.isolatedFingerprint) {
|
|
1370
1386
|
return { status: 'error', error: { code: 'stale_isolated', message: hostMessage('isolatedChangedAfterPlanningRecalculateThePlan') } };
|
|
1371
1387
|
}
|
|
1372
1388
|
const nextBaseOid = await createSnapshotCommit(stored.scope.isolatedGitRoot, persistentIsolated.treeOid, stored.plan.effectiveBaseOid, null, null, 'Finished Isolated snapshot');
|
|
1373
1389
|
if (merge.changedFiles.length === 0) {
|
|
1374
1390
|
await this.options.beforeFinalLocalValidation?.();
|
|
1375
|
-
const finalLocal = await captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'final-local.index'), objectDirectory, sourceObjects);
|
|
1391
|
+
const finalLocal = await this.captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'final-local.index'), objectDirectory, sourceObjects);
|
|
1376
1392
|
if (finalLocal.fingerprint !== stored.plan.localFingerprint) {
|
|
1377
1393
|
return { status: 'error', error: { code: 'stale_local', message: hostMessage('localChangedBeforeFinishRecalculateThePlan') } };
|
|
1378
1394
|
}
|
|
@@ -1409,7 +1425,7 @@ class DefaultSessionCheckoutApplyEngine {
|
|
|
1409
1425
|
const finalIndexPath = join(tempRoot, 'preserved-local.index');
|
|
1410
1426
|
await prepareIndexFromPatch(stored.scope.localGitRoot, finalIndexPath, commitOid, finalIndexPatch);
|
|
1411
1427
|
await this.options.beforeFinalLocalValidation?.();
|
|
1412
|
-
const finalLocal = await captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'final-local-validation.index'), objectDirectory, sourceObjects);
|
|
1428
|
+
const finalLocal = await this.captureSnapshot(stored.scope.localGitRoot, join(tempRoot, 'final-local-validation.index'), objectDirectory, sourceObjects);
|
|
1413
1429
|
if (finalLocal.headOid !== stored.plan.localHeadOid
|
|
1414
1430
|
|| finalLocal.headRef !== stored.plan.localHeadRef
|
|
1415
1431
|
|| finalLocal.fingerprint !== stored.plan.localFingerprint) {
|