@kaitranntt/ccs 8.8.1-dev.21 → 8.8.1-dev.22

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 (35) hide show
  1. package/dist/auth/auth-commands.js +3 -3
  2. package/dist/auth/auth-commands.js.map +1 -1
  3. package/dist/config/schemas/auth.d.ts +2 -2
  4. package/dist/config/schemas/auth.d.ts.map +1 -1
  5. package/dist/management/instance-directory.d.ts +19 -0
  6. package/dist/management/instance-directory.d.ts.map +1 -1
  7. package/dist/management/instance-directory.js +130 -7
  8. package/dist/management/instance-directory.js.map +1 -1
  9. package/dist/management/instance-manager.d.ts +2 -5
  10. package/dist/management/instance-manager.d.ts.map +1 -1
  11. package/dist/management/instance-manager.js +26 -27
  12. package/dist/management/instance-manager.js.map +1 -1
  13. package/dist/management/shared-manager/canonical-first-file-claims.d.ts +6 -0
  14. package/dist/management/shared-manager/canonical-first-file-claims.d.ts.map +1 -0
  15. package/dist/management/shared-manager/canonical-first-file-claims.js +143 -0
  16. package/dist/management/shared-manager/canonical-first-file-claims.js.map +1 -0
  17. package/dist/management/shared-manager/canonical-first-file-reconciler.d.ts +15 -0
  18. package/dist/management/shared-manager/canonical-first-file-reconciler.d.ts.map +1 -0
  19. package/dist/management/shared-manager/canonical-first-file-reconciler.js +131 -0
  20. package/dist/management/shared-manager/canonical-first-file-reconciler.js.map +1 -0
  21. package/dist/management/shared-manager/plugin-layout-internals.d.ts +1 -1
  22. package/dist/management/shared-manager/plugin-layout-internals.d.ts.map +1 -1
  23. package/dist/management/shared-manager/plugin-layout-internals.js +25 -9
  24. package/dist/management/shared-manager/plugin-layout-internals.js.map +1 -1
  25. package/dist/management/shared-manager/shared-dir-linker.d.ts +1 -1
  26. package/dist/management/shared-manager/shared-dir-linker.d.ts.map +1 -1
  27. package/dist/management/shared-manager/shared-dir-linker.js +140 -107
  28. package/dist/management/shared-manager/shared-dir-linker.js.map +1 -1
  29. package/dist/management/shared-manager/types.d.ts +12 -1
  30. package/dist/management/shared-manager/types.d.ts.map +1 -1
  31. package/dist/management/shared-manager/types.js +12 -1
  32. package/dist/management/shared-manager/types.js.map +1 -1
  33. package/dist/types/config.d.ts +2 -2
  34. package/dist/types/config.d.ts.map +1 -1
  35. package/package.json +1 -1
@@ -0,0 +1,15 @@
1
+ interface CanonicalFirstRoots {
2
+ claudeDir: string;
3
+ sharedDir: string;
4
+ instancesDir: string;
5
+ }
6
+ /**
7
+ * Reconcile a canonical-first shared file before any seed or symlink mutation.
8
+ * Existing canonical content always wins. With no canonical, one unique byte
9
+ * variant is adopted; conflicting variants are all quarantined for recovery.
10
+ */
11
+ export declare function reconcileCanonicalFirstFile(roots: CanonicalFirstRoots, fileName: string): void;
12
+ /** Preserve a later divergent copy without allowing it to replace canonical content. */
13
+ export declare function preserveCanonicalFirstDivergence(divergedPath: string, canonicalPath: string): boolean;
14
+ export {};
15
+ //# sourceMappingURL=canonical-first-file-reconciler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-first-file-reconciler.d.ts","sourceRoot":"","sources":["../../../src/management/shared-manager/canonical-first-file-reconciler.ts"],"names":[],"mappings":"AAmBA,UAAU,mBAAmB;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AA6CD;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAiD9F;AAED,wFAAwF;AACxF,wBAAgB,gCAAgC,CAC9C,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,GACpB,OAAO,CAaT"}
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.preserveCanonicalFirstDivergence = exports.reconcileCanonicalFirstFile = void 0;
30
+ const fs = __importStar(require("fs"));
31
+ const path = __importStar(require("path"));
32
+ const ui_1 = require("../../utils/ui");
33
+ const profile_registry_1 = __importDefault(require("../../auth/profile-registry"));
34
+ const shared_resource_policy_1 = require("../../auth/shared-resource-policy");
35
+ const instance_directory_1 = require("../instance-directory");
36
+ const diverged_file_adopter_1 = require("./diverged-file-adopter");
37
+ const fs_helpers_1 = require("./fs-helpers");
38
+ const canonical_first_file_claims_1 = require("./canonical-first-file-claims");
39
+ function candidatePaths(roots, fileName) {
40
+ const profiles = new profile_registry_1.default().getAllProfilesMerged();
41
+ const profilesByInstanceName = new Map();
42
+ for (const [profileName, profile] of Object.entries(profiles)) {
43
+ const instanceName = (0, instance_directory_1.normalizeAccountInstanceName)(profileName);
44
+ const matches = profilesByInstanceName.get(instanceName) ?? [];
45
+ matches.push(profile);
46
+ profilesByInstanceName.set(instanceName, matches);
47
+ }
48
+ return [
49
+ path.join(roots.sharedDir, fileName),
50
+ ...(0, instance_directory_1.listAccountInstancePaths)(roots.instancesDir)
51
+ .filter((instancePath) => {
52
+ const instanceName = (0, instance_directory_1.normalizeAccountInstanceName)(path.basename(instancePath));
53
+ const matches = profilesByInstanceName.get(instanceName) ?? [];
54
+ if (matches.length > 1)
55
+ return false;
56
+ return matches.length === 0 || !(0, shared_resource_policy_1.isProfileLocalSharedResourceMode)(matches[0]);
57
+ })
58
+ .map((instancePath) => path.join(instancePath, fileName)),
59
+ ];
60
+ }
61
+ function reconcileCandidatesAgainstCanonical(canonicalPath, candidates) {
62
+ let canonicalContent = null;
63
+ try {
64
+ canonicalContent = fs.readFileSync(canonicalPath);
65
+ }
66
+ catch {
67
+ // A present but unreadable or dangling canonical path still owns precedence.
68
+ }
69
+ for (const candidatePath of candidates) {
70
+ (0, canonical_first_file_claims_1.claimCanonicalFirstCopy)(candidatePath, canonicalContent, `Canonical ${path.basename(canonicalPath)} wins over divergent copy at ${candidatePath}`);
71
+ }
72
+ }
73
+ /**
74
+ * Reconcile a canonical-first shared file before any seed or symlink mutation.
75
+ * Existing canonical content always wins. With no canonical, one unique byte
76
+ * variant is adopted; conflicting variants are all quarantined for recovery.
77
+ */
78
+ function reconcileCanonicalFirstFile(roots, fileName) {
79
+ const canonicalPath = path.join(roots.claudeDir, fileName);
80
+ const candidates = candidatePaths(roots, fileName);
81
+ for (const candidatePath of candidates) {
82
+ if (candidatePath !== path.join(roots.sharedDir, fileName)) {
83
+ const instancePath = path.dirname(candidatePath);
84
+ if (!(0, instance_directory_1.isSafeAccountInstancePath)(roots.instancesDir, instancePath))
85
+ continue;
86
+ }
87
+ (0, canonical_first_file_claims_1.recoverInterruptedClaims)(candidatePath);
88
+ }
89
+ if ((0, fs_helpers_1.getLstatSync)(canonicalPath)) {
90
+ reconcileCandidatesAgainstCanonical(canonicalPath, candidates);
91
+ return;
92
+ }
93
+ const variants = [];
94
+ for (const candidatePath of candidates) {
95
+ const content = (0, canonical_first_file_claims_1.readRegularFileContent)(candidatePath);
96
+ if (content)
97
+ variants.push({ path: candidatePath, content });
98
+ }
99
+ if (variants.length === 0)
100
+ return;
101
+ const uniqueContents = [];
102
+ for (const variant of variants) {
103
+ if (!uniqueContents.some((content) => content.equals(variant.content))) {
104
+ uniqueContents.push(variant.content);
105
+ }
106
+ }
107
+ if (uniqueContents.length === 1) {
108
+ (0, diverged_file_adopter_1.adoptDivergedFileContent)(variants[0].path, canonicalPath);
109
+ reconcileCandidatesAgainstCanonical(canonicalPath, candidates);
110
+ console.log((0, ui_1.info)(`Adopted the only existing ${fileName} variant as canonical content`));
111
+ return;
112
+ }
113
+ for (const variant of variants) {
114
+ (0, canonical_first_file_claims_1.claimCanonicalFirstCopy)(variant.path, null, `Conflicting ${fileName} variants found while no canonical file exists`);
115
+ }
116
+ console.log((0, ui_1.warn)(`No ${fileName} variant was selected; recover one of the .ccs-shared-conflict files explicitly`));
117
+ }
118
+ exports.reconcileCanonicalFirstFile = reconcileCanonicalFirstFile;
119
+ /** Preserve a later divergent copy without allowing it to replace canonical content. */
120
+ function preserveCanonicalFirstDivergence(divergedPath, canonicalPath) {
121
+ let canonicalContent = null;
122
+ try {
123
+ canonicalContent = fs.readFileSync(canonicalPath);
124
+ }
125
+ catch {
126
+ // Preserve the divergence when canonical cannot be compared safely.
127
+ }
128
+ return (0, canonical_first_file_claims_1.claimCanonicalFirstCopy)(divergedPath, canonicalContent, `Canonical ${path.basename(canonicalPath)} wins over divergent copy at ${divergedPath}`);
129
+ }
130
+ exports.preserveCanonicalFirstDivergence = preserveCanonicalFirstDivergence;
131
+ //# sourceMappingURL=canonical-first-file-reconciler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-first-file-reconciler.js","sourceRoot":"","sources":["../../../src/management/shared-manager/canonical-first-file-reconciler.ts"],"names":[],"mappings":"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"}
@@ -25,7 +25,7 @@ export declare function ensureSharedPluginLayoutDefaults(claudeDir: string): voi
25
25
  * Link shared plugins directory entries into an instance, creating the
26
26
  * instance plugins directory first if needed.
27
27
  */
28
- export declare function linkInstancePlugins(roots: PluginLayoutRoots, instancePath: string): void;
28
+ export declare function linkInstancePlugins(roots: PluginLayoutRoots, instancePath: string, assertInstanceIdentity?: () => void): void;
29
29
  /**
30
30
  * Build the list of plugin entries to link from the shared plugins dir.
31
31
  * Always includes the default SHARED_PLUGIN_ENTRIES; adds any additional
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-layout-internals.d.ts","sourceRoot":"","sources":["../../../src/management/shared-manager/plugin-layout-internals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAiBH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAOxE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAEpD;;;;GAIG;AACH,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAyBxE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAmExF;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE,CAyCxE;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAgD9F"}
1
+ {"version":3,"file":"plugin-layout-internals.d.ts","sourceRoot":"","sources":["../../../src/management/shared-manager/plugin-layout-internals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAiBH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAOxE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAcpD;;;;GAIG;AACH,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAyBxE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,iBAAiB,EACxB,YAAY,EAAE,MAAM,EACpB,sBAAsB,CAAC,EAAE,MAAM,IAAI,GAClC,IAAI,CAsFN;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE,CAyCxE;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAgD9F"}
@@ -42,6 +42,15 @@ const diverged_file_adopter_1 = require("./diverged-file-adopter");
42
42
  const fs_helpers_1 = require("./fs-helpers");
43
43
  const plugin_metadata_normalizer_1 = require("./plugin-metadata-normalizer");
44
44
  const types_1 = require("./types");
45
+ function runGuardedInstanceMutation(assertInstanceIdentity, operation) {
46
+ assertInstanceIdentity?.();
47
+ try {
48
+ return operation();
49
+ }
50
+ finally {
51
+ assertInstanceIdentity?.();
52
+ }
53
+ }
45
54
  /**
46
55
  * Ensure the plugin layout default directories (cache, marketplaces) and
47
56
  * registry files (installed_plugins.json, known_marketplaces.json) exist
@@ -74,7 +83,7 @@ exports.ensureSharedPluginLayoutDefaults = ensureSharedPluginLayoutDefaults;
74
83
  * Link shared plugins directory entries into an instance, creating the
75
84
  * instance plugins directory first if needed.
76
85
  */
77
- function linkInstancePlugins(roots, instancePath) {
86
+ function linkInstancePlugins(roots, instancePath, assertInstanceIdentity) {
78
87
  const linkPath = path.join(instancePath, 'plugins');
79
88
  const targetPath = path.join(roots.sharedDir, 'plugins');
80
89
  let linkStats = null;
@@ -86,35 +95,41 @@ function linkInstancePlugins(roots, instancePath) {
86
95
  throw err;
87
96
  }
88
97
  }
98
+ assertInstanceIdentity?.();
89
99
  if (linkStats?.isSymbolicLink() || (linkStats && !linkStats.isDirectory())) {
90
- (0, fs_helpers_1.removeExistingPath)(linkPath, linkStats.isDirectory() ? 'directory' : 'file');
100
+ const existingType = linkStats.isDirectory() ? 'directory' : 'file';
101
+ runGuardedInstanceMutation(assertInstanceIdentity, () => (0, fs_helpers_1.removeExistingPath)(linkPath, existingType));
91
102
  }
92
103
  if (!linkStats || !linkStats.isDirectory()) {
93
- fs.mkdirSync(linkPath, { recursive: true, mode: 0o700 });
104
+ runGuardedInstanceMutation(assertInstanceIdentity, () => fs.mkdirSync(linkPath, { recursive: true, mode: 0o700 }));
94
105
  }
95
- for (const item of getSharedPluginLinkItems(roots.sharedDir)) {
106
+ const linkItems = getSharedPluginLinkItems(roots.sharedDir);
107
+ assertInstanceIdentity?.();
108
+ for (const item of linkItems) {
96
109
  const targetEntryPath = path.join(targetPath, item.name);
97
110
  const linkEntryPath = path.join(linkPath, item.name);
98
111
  let adoption = 'not-claimed';
99
112
  if (item.type === 'file') {
100
- adoption = (0, diverged_file_adopter_1.adoptDivergedFileContent)(linkEntryPath, path.join(roots.claudeDir, 'plugins', item.name));
113
+ adoption = runGuardedInstanceMutation(assertInstanceIdentity, () => (0, diverged_file_adopter_1.adoptDivergedFileContent)(linkEntryPath, path.join(roots.claudeDir, 'plugins', item.name)));
101
114
  if (adoption === 'not-claimed') {
102
- (0, fs_helpers_1.removeExistingPath)(linkEntryPath, item.type);
115
+ runGuardedInstanceMutation(assertInstanceIdentity, () => (0, fs_helpers_1.removeExistingPath)(linkEntryPath, item.type));
103
116
  }
104
117
  }
105
118
  else {
106
- (0, fs_helpers_1.removeExistingPath)(linkEntryPath, item.type);
119
+ runGuardedInstanceMutation(assertInstanceIdentity, () => (0, fs_helpers_1.removeExistingPath)(linkEntryPath, item.type));
107
120
  }
108
121
  (0, diverged_file_adopter_1.assertAdoptionPathAbsent)(linkEntryPath, adoption);
109
122
  if ((0, fs_helpers_1.getLstatSync)(linkEntryPath)) {
110
123
  console.log((0, ui_1.warn)(`Skipping plugins/${item.name}: path reappeared during reconciliation`));
111
124
  continue;
112
125
  }
126
+ assertInstanceIdentity?.();
113
127
  try {
114
128
  const symlinkType = item.type === 'directory' ? 'dir' : 'file';
115
129
  fs.symlinkSync(targetEntryPath, linkEntryPath, symlinkType);
116
130
  }
117
131
  catch (_err) {
132
+ assertInstanceIdentity?.();
118
133
  (0, diverged_file_adopter_1.assertAdoptionPathAbsent)(linkEntryPath, adoption);
119
134
  if ((0, fs_helpers_1.getLstatSync)(linkEntryPath)) {
120
135
  console.log((0, ui_1.warn)(`Skipping plugins/${item.name}: path reappeared during reconciliation`));
@@ -122,10 +137,10 @@ function linkInstancePlugins(roots, instancePath) {
122
137
  }
123
138
  if (process.platform === 'win32') {
124
139
  if (item.type === 'directory') {
125
- (0, fs_helpers_1.copyDirectoryFallback)(targetEntryPath, linkEntryPath);
140
+ runGuardedInstanceMutation(assertInstanceIdentity, () => (0, fs_helpers_1.copyDirectoryFallback)(targetEntryPath, linkEntryPath));
126
141
  }
127
142
  else {
128
- fs.copyFileSync(targetEntryPath, linkEntryPath, fs.constants.COPYFILE_EXCL);
143
+ runGuardedInstanceMutation(assertInstanceIdentity, () => fs.copyFileSync(targetEntryPath, linkEntryPath, fs.constants.COPYFILE_EXCL));
129
144
  }
130
145
  console.log((0, ui_1.warn)(`Symlink failed for plugins/${item.name}, copied instead (enable Developer Mode)`));
131
146
  }
@@ -133,6 +148,7 @@ function linkInstancePlugins(roots, instancePath) {
133
148
  throw _err;
134
149
  }
135
150
  }
151
+ assertInstanceIdentity?.();
136
152
  }
137
153
  }
138
154
  exports.linkInstancePlugins = linkInstancePlugins;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-layout-internals.js","sourceRoot":"","sources":["../../../src/management/shared-manager/plugin-layout-internals.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin-layout-internals.js","sourceRoot":"","sources":["../../../src/management/shared-manager/plugin-layout-internals.ts"],"names":[],"mappings":"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"}
@@ -28,7 +28,7 @@ export declare function detectCircularSymlink(target: string, sharedDir: string)
28
28
  * Ensure shared directories exist as symlinks to ~/.claude/ and that the
29
29
  * plugin layout default directories and registry files are present.
30
30
  */
31
- export declare function ensureSharedDirectories(roots: LinkerRoots): void;
31
+ export declare function ensureSharedDirectories(roots: LinkerRoots, assertInstanceIdentity?: () => void): void;
32
32
  /**
33
33
  * Link shared directories into a specific instance path.
34
34
  */
@@ -1 +1 @@
1
- {"version":3,"file":"shared-dir-linker.d.ts","sourceRoot":"","sources":["../../../src/management/shared-manager/shared-dir-linker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAmBH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAYxE;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,mBAAmB,CAAC;AAE9C;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAsChF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CA6FhE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CA2DpF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAyBtF"}
1
+ {"version":3,"file":"shared-dir-linker.d.ts","sourceRoot":"","sources":["../../../src/management/shared-manager/shared-dir-linker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAuBH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAgBxE;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,mBAAmB,CAAC;AAc9C;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAsChF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,WAAW,EAClB,sBAAsB,CAAC,EAAE,MAAM,IAAI,GAClC,IAAI,CA2GN;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CA0EpF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAyBtF"}
@@ -42,11 +42,22 @@ exports.detachSharedDirectories = exports.linkSharedDirectories = exports.ensure
42
42
  const fs = __importStar(require("fs"));
43
43
  const path = __importStar(require("path"));
44
44
  const ui_1 = require("../../utils/ui");
45
+ const instance_directory_1 = require("../instance-directory");
45
46
  const diverged_file_adopter_1 = require("./diverged-file-adopter");
46
47
  const fs_helpers_1 = require("./fs-helpers");
47
48
  const plugin_metadata_normalizer_1 = require("./plugin-metadata-normalizer");
48
49
  const plugin_layout_internals_1 = require("./plugin-layout-internals");
50
+ const canonical_first_file_reconciler_1 = require("./canonical-first-file-reconciler");
49
51
  const types_1 = require("./types");
52
+ function runInstanceMutationStage(assertInstanceIdentity, operation) {
53
+ assertInstanceIdentity?.();
54
+ try {
55
+ return operation();
56
+ }
57
+ finally {
58
+ assertInstanceIdentity?.();
59
+ }
60
+ }
50
61
  /**
51
62
  * Detect a circular symlink before creation. A symlink is circular when its
52
63
  * target (raw or canonical) points back inside the shared root.
@@ -91,90 +102,102 @@ exports.detectCircularSymlink = detectCircularSymlink;
91
102
  * Ensure shared directories exist as symlinks to ~/.claude/ and that the
92
103
  * plugin layout default directories and registry files are present.
93
104
  */
94
- function ensureSharedDirectories(roots) {
105
+ function ensureSharedDirectories(roots, assertInstanceIdentity) {
95
106
  const claudeDir = roots.claudeDir;
96
107
  const sharedDir = roots.sharedDir;
97
- if (!(0, fs_helpers_1.getLstatSync)(claudeDir)) {
98
- console.log((0, ui_1.info)('Creating ~/.claude/ directory structure'));
99
- fs.mkdirSync(claudeDir, { recursive: true, mode: 0o700 });
100
- }
101
- if (!(0, fs_helpers_1.getLstatSync)(sharedDir)) {
102
- fs.mkdirSync(sharedDir, { recursive: true, mode: 0o700 });
103
- }
104
- (0, plugin_layout_internals_1.ensureSharedPluginLayoutDefaults)(claudeDir);
105
- for (const item of types_1.SHARED_ITEMS) {
106
- const claudePath = path.join(claudeDir, item.name);
107
- const sharedPath = path.join(sharedDir, item.name);
108
- if (item.type === 'file') {
109
- (0, diverged_file_adopter_1.recoverOrphanedCanonicalClaim)(claudePath);
108
+ runInstanceMutationStage(assertInstanceIdentity, () => {
109
+ if (!(0, fs_helpers_1.getLstatSync)(claudeDir)) {
110
+ console.log((0, ui_1.info)('Creating ~/.claude/ directory structure'));
111
+ fs.mkdirSync(claudeDir, { recursive: true, mode: 0o700 });
110
112
  }
111
- if (!(0, fs_helpers_1.getLstatSync)(claudePath)) {
112
- if (item.type === 'directory') {
113
- fs.mkdirSync(claudePath, { recursive: true, mode: 0o700 });
114
- }
115
- else if (item.type === 'file') {
116
- fs.writeFileSync(claudePath, JSON.stringify({}, null, 2), 'utf8');
117
- }
113
+ });
114
+ runInstanceMutationStage(assertInstanceIdentity, () => {
115
+ if (!(0, fs_helpers_1.getLstatSync)(sharedDir)) {
116
+ fs.mkdirSync(sharedDir, { recursive: true, mode: 0o700 });
118
117
  }
119
- if (detectCircularSymlink(claudePath, sharedDir)) {
120
- console.log((0, ui_1.warn)(`Skipping ${item.name}: circular symlink detected`));
121
- continue;
122
- }
123
- let sharedAdoption = 'not-claimed';
124
- if ((0, fs_helpers_1.getLstatSync)(sharedPath)) {
125
- let removeExisting = true;
126
- try {
127
- const stats = fs.lstatSync(sharedPath);
128
- if (stats.isSymbolicLink()) {
129
- const currentTarget = fs.readlinkSync(sharedPath);
130
- const resolvedTarget = path.resolve(path.dirname(sharedPath), currentTarget);
131
- if (resolvedTarget === claudePath) {
132
- continue;
133
- }
134
- }
118
+ });
119
+ runInstanceMutationStage(assertInstanceIdentity, () => (0, plugin_layout_internals_1.ensureSharedPluginLayoutDefaults)(claudeDir));
120
+ for (const item of types_1.SHARED_ITEMS) {
121
+ runInstanceMutationStage(assertInstanceIdentity, () => {
122
+ const claudePath = path.join(claudeDir, item.name);
123
+ const sharedPath = path.join(sharedDir, item.name);
124
+ if (item.type === 'file') {
125
+ (0, diverged_file_adopter_1.recoverOrphanedCanonicalClaim)(claudePath);
135
126
  }
136
- catch (_err) {
137
- // Continue to recreate
127
+ if (item.type === 'file' && item.divergencePolicy === 'canonical-first') {
128
+ (0, canonical_first_file_reconciler_1.reconcileCanonicalFirstFile)(roots, item.name);
138
129
  }
139
- if (item.type === 'file') {
140
- sharedAdoption = (0, diverged_file_adopter_1.adoptDivergedFileContent)(sharedPath, claudePath);
141
- removeExisting = sharedAdoption === 'not-claimed';
130
+ if (!(0, fs_helpers_1.getLstatSync)(claudePath)) {
131
+ if (item.type === 'directory') {
132
+ fs.mkdirSync(claudePath, { recursive: true, mode: 0o700 });
133
+ }
134
+ else if (item.type === 'file') {
135
+ fs.writeFileSync(claudePath, item.seedContent, 'utf8');
136
+ }
142
137
  }
143
- if (item.type === 'directory' && removeExisting) {
144
- fs.rmSync(sharedPath, { recursive: true, force: true });
138
+ if (detectCircularSymlink(claudePath, sharedDir)) {
139
+ console.log((0, ui_1.warn)(`Skipping ${item.name}: circular symlink detected`));
140
+ return;
145
141
  }
146
- else if (removeExisting) {
147
- fs.unlinkSync(sharedPath);
142
+ let sharedAdoption = 'not-claimed';
143
+ if ((0, fs_helpers_1.getLstatSync)(sharedPath)) {
144
+ let removeExisting = true;
145
+ try {
146
+ const stats = fs.lstatSync(sharedPath);
147
+ if (stats.isSymbolicLink()) {
148
+ const currentTarget = fs.readlinkSync(sharedPath);
149
+ const resolvedTarget = path.resolve(path.dirname(sharedPath), currentTarget);
150
+ if (resolvedTarget === claudePath) {
151
+ return;
152
+ }
153
+ }
154
+ }
155
+ catch (_err) {
156
+ // Continue to recreate
157
+ }
158
+ if (item.type === 'file' && item.divergencePolicy === 'canonical-first') {
159
+ removeExisting = !(0, canonical_first_file_reconciler_1.preserveCanonicalFirstDivergence)(sharedPath, claudePath);
160
+ }
161
+ else if (item.type === 'file') {
162
+ sharedAdoption = (0, diverged_file_adopter_1.adoptDivergedFileContent)(sharedPath, claudePath);
163
+ removeExisting = sharedAdoption === 'not-claimed';
164
+ }
165
+ if (item.type === 'directory' && removeExisting) {
166
+ fs.rmSync(sharedPath, { recursive: true, force: true });
167
+ }
168
+ else if (removeExisting) {
169
+ fs.unlinkSync(sharedPath);
170
+ }
171
+ (0, diverged_file_adopter_1.assertAdoptionPathAbsent)(sharedPath, sharedAdoption);
148
172
  }
149
- (0, diverged_file_adopter_1.assertAdoptionPathAbsent)(sharedPath, sharedAdoption);
150
- }
151
- if ((0, fs_helpers_1.getLstatSync)(sharedPath)) {
152
- console.log((0, ui_1.warn)(`Skipping ${item.name}: path reappeared during reconciliation`));
153
- continue;
154
- }
155
- try {
156
- const symlinkType = item.type === 'directory' ? 'dir' : 'file';
157
- fs.symlinkSync(claudePath, sharedPath, symlinkType);
158
- }
159
- catch (_err) {
160
- (0, diverged_file_adopter_1.assertAdoptionPathAbsent)(sharedPath, sharedAdoption);
161
173
  if ((0, fs_helpers_1.getLstatSync)(sharedPath)) {
162
174
  console.log((0, ui_1.warn)(`Skipping ${item.name}: path reappeared during reconciliation`));
163
- continue;
175
+ return;
164
176
  }
165
- if (process.platform === 'win32') {
166
- if (item.type === 'directory') {
167
- (0, fs_helpers_1.copyDirectoryFallback)(claudePath, sharedPath);
177
+ try {
178
+ const symlinkType = item.type === 'directory' ? 'dir' : 'file';
179
+ fs.symlinkSync(claudePath, sharedPath, symlinkType);
180
+ }
181
+ catch (_err) {
182
+ (0, diverged_file_adopter_1.assertAdoptionPathAbsent)(sharedPath, sharedAdoption);
183
+ if ((0, fs_helpers_1.getLstatSync)(sharedPath)) {
184
+ console.log((0, ui_1.warn)(`Skipping ${item.name}: path reappeared during reconciliation`));
185
+ return;
168
186
  }
169
- else if (item.type === 'file') {
170
- fs.copyFileSync(claudePath, sharedPath, fs.constants.COPYFILE_EXCL);
187
+ if (process.platform === 'win32') {
188
+ if (item.type === 'directory') {
189
+ (0, fs_helpers_1.copyDirectoryFallback)(claudePath, sharedPath);
190
+ }
191
+ else if (item.type === 'file') {
192
+ fs.copyFileSync(claudePath, sharedPath, fs.constants.COPYFILE_EXCL);
193
+ }
194
+ console.log((0, ui_1.warn)(`Symlink failed for ${item.name}, copied instead (enable Developer Mode)`));
195
+ }
196
+ else {
197
+ throw _err;
171
198
  }
172
- console.log((0, ui_1.warn)(`Symlink failed for ${item.name}, copied instead (enable Developer Mode)`));
173
- }
174
- else {
175
- throw _err;
176
199
  }
177
- }
200
+ });
178
201
  }
179
202
  }
180
203
  exports.ensureSharedDirectories = ensureSharedDirectories;
@@ -182,59 +205,69 @@ exports.ensureSharedDirectories = ensureSharedDirectories;
182
205
  * Link shared directories into a specific instance path.
183
206
  */
184
207
  function linkSharedDirectories(roots, instancePath) {
185
- ensureSharedDirectories(roots);
208
+ const instanceIdentity = (0, instance_directory_1.captureSafeAccountInstanceIdentity)(roots.instancesDir, instancePath);
209
+ const assertInstanceIdentity = () => (0, instance_directory_1.assertAccountInstanceIdentity)(roots.instancesDir, instancePath, instanceIdentity);
210
+ ensureSharedDirectories(roots, assertInstanceIdentity);
211
+ assertInstanceIdentity();
186
212
  const sharedDir = roots.sharedDir;
187
213
  for (const item of types_1.SHARED_ITEMS) {
188
- if (item.name === 'plugins') {
189
- (0, plugin_layout_internals_1.linkInstancePlugins)(roots, instancePath);
190
- continue;
191
- }
192
- const linkPath = path.join(instancePath, item.name);
193
- const targetPath = path.join(sharedDir, item.name);
194
- let adoption = 'not-claimed';
195
- if (item.type === 'file') {
196
- adoption = (0, diverged_file_adopter_1.adoptDivergedFileContent)(linkPath, path.join(roots.claudeDir, item.name));
197
- if (adoption === 'not-claimed') {
214
+ runInstanceMutationStage(assertInstanceIdentity, () => {
215
+ if (item.name === 'plugins') {
216
+ (0, plugin_layout_internals_1.linkInstancePlugins)(roots, instancePath, assertInstanceIdentity);
217
+ return;
218
+ }
219
+ const linkPath = path.join(instancePath, item.name);
220
+ const targetPath = path.join(sharedDir, item.name);
221
+ let adoption = 'not-claimed';
222
+ if (item.type === 'file' && item.divergencePolicy === 'canonical-first') {
223
+ if (!(0, canonical_first_file_reconciler_1.preserveCanonicalFirstDivergence)(linkPath, path.join(roots.claudeDir, item.name))) {
224
+ (0, fs_helpers_1.removeExistingPath)(linkPath, item.type);
225
+ }
226
+ }
227
+ else if (item.type === 'file') {
228
+ adoption = (0, diverged_file_adopter_1.adoptDivergedFileContent)(linkPath, path.join(roots.claudeDir, item.name));
229
+ if (adoption === 'not-claimed') {
230
+ (0, fs_helpers_1.removeExistingPath)(linkPath, item.type);
231
+ }
232
+ }
233
+ else {
198
234
  (0, fs_helpers_1.removeExistingPath)(linkPath, item.type);
199
235
  }
200
- }
201
- else {
202
- (0, fs_helpers_1.removeExistingPath)(linkPath, item.type);
203
- }
204
- (0, diverged_file_adopter_1.assertAdoptionPathAbsent)(linkPath, adoption);
205
- if ((0, fs_helpers_1.getLstatSync)(linkPath)) {
206
- console.log((0, ui_1.warn)(`Skipping ${item.name}: path reappeared during reconciliation`));
207
- continue;
208
- }
209
- try {
210
- const symlinkType = item.type === 'directory' ? 'dir' : 'file';
211
- fs.symlinkSync(targetPath, linkPath, symlinkType);
212
- }
213
- catch (_err) {
214
236
  (0, diverged_file_adopter_1.assertAdoptionPathAbsent)(linkPath, adoption);
215
237
  if ((0, fs_helpers_1.getLstatSync)(linkPath)) {
216
238
  console.log((0, ui_1.warn)(`Skipping ${item.name}: path reappeared during reconciliation`));
217
- continue;
239
+ return;
218
240
  }
219
- if (process.platform === 'win32') {
220
- if (item.type === 'directory') {
221
- (0, fs_helpers_1.copyDirectoryFallback)(targetPath, linkPath);
241
+ try {
242
+ const symlinkType = item.type === 'directory' ? 'dir' : 'file';
243
+ fs.symlinkSync(targetPath, linkPath, symlinkType);
244
+ }
245
+ catch (_err) {
246
+ (0, diverged_file_adopter_1.assertAdoptionPathAbsent)(linkPath, adoption);
247
+ if ((0, fs_helpers_1.getLstatSync)(linkPath)) {
248
+ console.log((0, ui_1.warn)(`Skipping ${item.name}: path reappeared during reconciliation`));
249
+ return;
222
250
  }
223
- else if (item.type === 'file') {
224
- fs.copyFileSync(targetPath, linkPath, fs.constants.COPYFILE_EXCL);
251
+ if (process.platform === 'win32') {
252
+ if (item.type === 'directory') {
253
+ (0, fs_helpers_1.copyDirectoryFallback)(targetPath, linkPath);
254
+ }
255
+ else if (item.type === 'file') {
256
+ fs.copyFileSync(targetPath, linkPath, fs.constants.COPYFILE_EXCL);
257
+ }
258
+ console.log((0, ui_1.warn)(`Symlink failed for ${item.name}, copied instead (enable Developer Mode)`));
259
+ }
260
+ else {
261
+ throw _err;
225
262
  }
226
- console.log((0, ui_1.warn)(`Symlink failed for ${item.name}, copied instead (enable Developer Mode)`));
227
- }
228
- else {
229
- throw _err;
230
263
  }
231
- }
264
+ });
232
265
  }
233
266
  // Preserve original behavior: linkSharedDirectories always concludes by
234
267
  // normalizing plugin + marketplace metadata for the freshly linked
235
268
  // instance. migrateFromV311 relies on this side effect.
236
- (0, plugin_metadata_normalizer_1.normalizePluginRegistryPaths)(roots, instancePath);
237
- (0, plugin_metadata_normalizer_1.normalizeMarketplaceRegistryPaths)(roots, instancePath);
269
+ runInstanceMutationStage(assertInstanceIdentity, () => (0, plugin_metadata_normalizer_1.normalizePluginRegistryPaths)(roots, instancePath));
270
+ runInstanceMutationStage(assertInstanceIdentity, () => (0, plugin_metadata_normalizer_1.normalizeMarketplaceRegistryPaths)(roots, instancePath));
238
271
  }
239
272
  exports.linkSharedDirectories = linkSharedDirectories;
240
273
  /**