@kodrunhq/claudefy 1.3.3 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +135 -111
  2. package/dist/claude-json-sync/claude-json-sync.d.ts +12 -0
  3. package/dist/claude-json-sync/claude-json-sync.js +129 -0
  4. package/dist/claude-json-sync/claude-json-sync.js.map +1 -0
  5. package/dist/commands/doctor.js +9 -5
  6. package/dist/commands/doctor.js.map +1 -1
  7. package/dist/commands/init.js +64 -60
  8. package/dist/commands/init.js.map +1 -1
  9. package/dist/commands/join.js +62 -55
  10. package/dist/commands/join.js.map +1 -1
  11. package/dist/commands/override.js +32 -28
  12. package/dist/commands/override.js.map +1 -1
  13. package/dist/commands/pull.d.ts +1 -0
  14. package/dist/commands/pull.js +234 -186
  15. package/dist/commands/pull.js.map +1 -1
  16. package/dist/commands/push.d.ts +1 -0
  17. package/dist/commands/push.js +149 -80
  18. package/dist/commands/push.js.map +1 -1
  19. package/dist/commands/restore.js +31 -27
  20. package/dist/commands/restore.js.map +1 -1
  21. package/dist/config/config-manager.js +1 -0
  22. package/dist/config/config-manager.js.map +1 -1
  23. package/dist/config/defaults.d.ts +7 -1
  24. package/dist/config/defaults.js +20 -0
  25. package/dist/config/defaults.js.map +1 -1
  26. package/dist/config/types.d.ts +16 -0
  27. package/dist/lockfile/lockfile.d.ts +8 -0
  28. package/dist/lockfile/lockfile.js +101 -0
  29. package/dist/lockfile/lockfile.js.map +1 -0
  30. package/dist/merger/merger.js +19 -4
  31. package/dist/merger/merger.js.map +1 -1
  32. package/dist/path-mapper/path-mapper.js +1 -1
  33. package/dist/path-mapper/path-mapper.js.map +1 -1
  34. package/dist/secret-scanner/scanner.d.ts +7 -0
  35. package/dist/secret-scanner/scanner.js +17 -3
  36. package/dist/secret-scanner/scanner.js.map +1 -1
  37. package/dist/sync-filter/sync-filter.js +5 -0
  38. package/dist/sync-filter/sync-filter.js.map +1 -1
  39. package/package.json +1 -1
@@ -6,6 +6,7 @@ import { PushCommand } from "./push.js";
6
6
  import { HookManager } from "../hook-manager/hook-manager.js";
7
7
  import { output } from "../output.js";
8
8
  import { promptPassphraseSetup } from "../encryptor/passphrase.js";
9
+ import { withLock } from "../lockfile/lockfile.js";
9
10
  const LFS_GITATTRIBUTES = [
10
11
  "projects/**/*.jsonl filter=lfs diff=lfs merge=lfs -text",
11
12
  "projects/**/*.jsonl.age filter=lfs diff=lfs merge=lfs -text",
@@ -17,71 +18,74 @@ export class InitCommand {
17
18
  this.homeDir = homeDir;
18
19
  }
19
20
  async execute(options) {
20
- let backend = options.backend;
21
- if (!backend && options.createRepo) {
22
- const { RepoCreator } = await import("../repo-creator/repo-creator.js");
23
- const creator = new RepoCreator();
24
- const repoName = "claude-sync";
25
- backend = await creator.create(repoName);
26
- if (!options.quiet) {
27
- output.info(`Created remote repository: ${backend}`);
21
+ const claudefyDir = join(this.homeDir, ".claudefy");
22
+ await withLock("init", !!options.quiet, claudefyDir, async () => {
23
+ let backend = options.backend;
24
+ if (!backend && options.createRepo) {
25
+ const { RepoCreator } = await import("../repo-creator/repo-creator.js");
26
+ const creator = new RepoCreator();
27
+ const repoName = "claude-sync";
28
+ backend = await creator.create(repoName);
29
+ if (!options.quiet) {
30
+ output.info(`Created remote repository: ${backend}`);
31
+ }
28
32
  }
29
- }
30
- if (!backend) {
31
- throw new Error("Either --backend <url> or --create-repo is required.");
32
- }
33
- const configManager = new ConfigManager(this.homeDir);
34
- if (configManager.isInitialized()) {
35
- throw new Error("claudefy is already initialized. Use 'claudefy push' to sync.");
36
- }
37
- // Prompt for passphrase if not provided and not skipping encryption
38
- let passphrase = options.passphrase;
39
- let useKeychain = false;
40
- let skipEncryption = options.skipEncryption ?? false;
41
- if (!passphrase && !skipEncryption && process.stdin.isTTY) {
42
- const setup = await promptPassphraseSetup();
43
- if (setup) {
44
- passphrase = setup.passphrase;
45
- useKeychain = setup.storedInKeychain;
33
+ if (!backend) {
34
+ throw new Error("Either --backend <url> or --create-repo is required.");
46
35
  }
47
- else {
48
- skipEncryption = true;
36
+ const configManager = new ConfigManager(this.homeDir);
37
+ if (configManager.isInitialized()) {
38
+ throw new Error("claudefy is already initialized. Use 'claudefy push' to sync.");
39
+ }
40
+ // Prompt for passphrase if not provided and not skipping encryption
41
+ let passphrase = options.passphrase;
42
+ let useKeychain = false;
43
+ let skipEncryption = options.skipEncryption ?? false;
44
+ if (!passphrase && !skipEncryption && process.stdin.isTTY) {
45
+ const setup = await promptPassphraseSetup();
46
+ if (setup) {
47
+ passphrase = setup.passphrase;
48
+ useKeychain = setup.storedInKeychain;
49
+ }
50
+ else {
51
+ skipEncryption = true;
52
+ }
53
+ }
54
+ // 1. Initialize config
55
+ const config = await configManager.initialize(backend, { useKeychain });
56
+ if (skipEncryption) {
57
+ config.encryption.enabled = false;
58
+ await configManager.set("encryption.enabled", false);
49
59
  }
50
- }
51
- // 1. Initialize config
52
- const config = await configManager.initialize(backend, { useKeychain });
53
- if (skipEncryption) {
54
- config.encryption.enabled = false;
55
- await configManager.set("encryption.enabled", false);
56
- }
57
- if (!options.quiet) {
58
- output.info(`Initialized claudefy with machine ID: ${config.machineId}`);
59
- }
60
- // 2. Initialize git store
61
- const gitAdapter = new GitAdapter(join(this.homeDir, ".claudefy"));
62
- await gitAdapter.initStore(backend);
63
- await gitAdapter.ensureMachineBranch(config.machineId);
64
- // 3. Write .gitattributes for LFS tracking of large session files
65
- await writeFile(join(gitAdapter.getStorePath(), ".gitattributes"), LFS_GITATTRIBUTES);
66
- // 4. Run initial push
67
- const pushCommand = new PushCommand(this.homeDir);
68
- await pushCommand.execute({
69
- quiet: options.quiet,
70
- skipEncryption,
71
- skipSecretScan: options.skipSecretScan,
72
- passphrase,
73
- });
74
- // 5. Install hooks if requested
75
- if (options.installHooks) {
76
- const hookManager = new HookManager(join(this.homeDir, ".claude", "settings.json"));
77
- await hookManager.install();
78
60
  if (!options.quiet) {
79
- output.info("Auto-sync hooks installed.");
61
+ output.info(`Initialized claudefy with machine ID: ${config.machineId}`);
80
62
  }
81
- }
82
- if (!options.quiet) {
83
- output.success("Setup complete. Your Claude config is now synced.");
84
- }
63
+ // 2. Initialize git store
64
+ const gitAdapter = new GitAdapter(join(this.homeDir, ".claudefy"));
65
+ await gitAdapter.initStore(backend);
66
+ await gitAdapter.ensureMachineBranch(config.machineId);
67
+ // 3. Write .gitattributes for LFS tracking of large session files
68
+ await writeFile(join(gitAdapter.getStorePath(), ".gitattributes"), LFS_GITATTRIBUTES);
69
+ // 4. Run initial push
70
+ const pushCommand = new PushCommand(this.homeDir);
71
+ await pushCommand.execute({
72
+ quiet: options.quiet,
73
+ skipEncryption,
74
+ skipSecretScan: options.skipSecretScan,
75
+ passphrase,
76
+ });
77
+ // 5. Install hooks if requested
78
+ if (options.installHooks) {
79
+ const hookManager = new HookManager(join(this.homeDir, ".claude", "settings.json"));
80
+ await hookManager.install();
81
+ if (!options.quiet) {
82
+ output.info("Auto-sync hooks installed.");
83
+ }
84
+ }
85
+ if (!options.quiet) {
86
+ output.success("Setup complete. Your Claude config is now synced.");
87
+ }
88
+ });
85
89
  }
86
90
  }
87
91
  //# sourceMappingURL=init.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,MAAM,iBAAiB,GAAG;IACxB,yDAAyD;IACzD,6DAA6D;IAC7D,EAAE;CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAYb,MAAM,OAAO,WAAW;IACd,OAAO,CAAS;IAExB,YAAY,OAAe;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAoB;QAChC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACpD,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,IAAI,EAAE;YAC9D,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;YAE9B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;gBACnC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAC;gBACxE,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;gBAClC,MAAM,QAAQ,GAAG,aAAa,CAAC;gBAC/B,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACzC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;oBACnB,MAAM,CAAC,IAAI,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC;YAED,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;YAC1E,CAAC;YAED,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAEtD,IAAI,aAAa,CAAC,aAAa,EAAE,EAAE,CAAC;gBAClC,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;YACnF,CAAC;YAED,oEAAoE;YACpE,IAAI,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;YACpC,IAAI,WAAW,GAAG,KAAK,CAAC;YACxB,IAAI,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,KAAK,CAAC;YAErD,IAAI,CAAC,UAAU,IAAI,CAAC,cAAc,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBAC1D,MAAM,KAAK,GAAG,MAAM,qBAAqB,EAAE,CAAC;gBAC5C,IAAI,KAAK,EAAE,CAAC;oBACV,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;oBAC9B,WAAW,GAAG,KAAK,CAAC,gBAAgB,CAAC;gBACvC,CAAC;qBAAM,CAAC;oBACN,cAAc,GAAG,IAAI,CAAC;gBACxB,CAAC;YACH,CAAC;YAED,uBAAuB;YACvB,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;YAExE,IAAI,cAAc,EAAE,CAAC;gBACnB,MAAM,CAAC,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC;gBAClC,MAAM,aAAa,CAAC,GAAG,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;YACvD,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACnB,MAAM,CAAC,IAAI,CAAC,yCAAyC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;YAC3E,CAAC;YAED,0BAA0B;YAC1B,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;YACnE,MAAM,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACpC,MAAM,UAAU,CAAC,mBAAmB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAEvD,kEAAkE;YAClE,MAAM,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,EAAE,gBAAgB,CAAC,EAAE,iBAAiB,CAAC,CAAC;YAEtF,sBAAsB;YACtB,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAClD,MAAM,WAAW,CAAC,OAAO,CAAC;gBACxB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,cAAc;gBACd,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,UAAU;aACX,CAAC,CAAC;YAEH,gCAAgC;YAChC,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACzB,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;gBACpF,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;gBAC5B,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;oBACnB,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACnB,MAAM,CAAC,OAAO,CAAC,mDAAmD,CAAC,CAAC;YACtE,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -8,6 +8,7 @@ import { MachineRegistry } from "../machine-registry/machine-registry.js";
8
8
  import { hostname, platform } from "node:os";
9
9
  import { output } from "../output.js";
10
10
  import { promptExistingPassphrase } from "../encryptor/passphrase.js";
11
+ import { withLock } from "../lockfile/lockfile.js";
11
12
  import { STORE_CONFIG_DIR, STORE_UNKNOWN_DIR, STORE_MANIFEST_FILE } from "../config/defaults.js";
12
13
  export class JoinCommand {
13
14
  homeDir;
@@ -15,65 +16,71 @@ export class JoinCommand {
15
16
  this.homeDir = homeDir;
16
17
  }
17
18
  async execute(options) {
18
- const configManager = new ConfigManager(this.homeDir);
19
- if (configManager.isInitialized()) {
20
- throw new Error("claudefy is already initialized. Use 'claudefy pull' to sync.");
21
- }
22
- // 1. Initialize config
23
- const config = await configManager.initialize(options.backend);
24
- if (!options.quiet) {
25
- output.info(`Joined sync with machine ID: ${config.machineId}`);
26
- }
27
- // 2. Initialize git store and pull
28
- const gitAdapter = new GitAdapter(join(this.homeDir, ".claudefy"));
29
- await gitAdapter.initStore(options.backend);
30
- await gitAdapter.ensureMachineBranch(config.machineId);
31
- // 3. Prompt for passphrase if the store has encrypted files and none was provided
32
- let passphrase = options.passphrase;
33
- let useKeychain = false;
34
- if (!passphrase && !options.skipEncryption) {
35
- const hasEncrypted = await this.storeHasAgeFiles(gitAdapter.getStorePath());
36
- if (hasEncrypted && process.stdin.isTTY) {
37
- const setup = await promptExistingPassphrase();
38
- if (setup) {
39
- passphrase = setup.passphrase;
40
- useKeychain = setup.storedInKeychain;
19
+ const claudefyDir = join(this.homeDir, ".claudefy");
20
+ await withLock("join", !!options.quiet, claudefyDir, async () => {
21
+ const configManager = new ConfigManager(this.homeDir);
22
+ if (configManager.isInitialized()) {
23
+ throw new Error("claudefy is already initialized. Use 'claudefy pull' to sync.");
24
+ }
25
+ // 1. Initialize config
26
+ const config = await configManager.initialize(options.backend);
27
+ if (!options.quiet) {
28
+ output.info(`Joined sync with machine ID: ${config.machineId}`);
29
+ }
30
+ // 2. Initialize git store and pull
31
+ const gitAdapter = new GitAdapter(join(this.homeDir, ".claudefy"));
32
+ await gitAdapter.initStore(options.backend);
33
+ await gitAdapter.ensureMachineBranch(config.machineId);
34
+ // 3. Prompt for passphrase if the store has encrypted files and none was provided
35
+ let passphrase = options.passphrase;
36
+ let useKeychain = false;
37
+ if (!passphrase && !options.skipEncryption) {
38
+ const hasEncrypted = await this.storeHasAgeFiles(gitAdapter.getStorePath());
39
+ if (hasEncrypted && process.stdin.isTTY) {
40
+ const setup = await promptExistingPassphrase();
41
+ if (setup) {
42
+ passphrase = setup.passphrase;
43
+ useKeychain = setup.storedInKeychain;
44
+ }
45
+ }
46
+ }
47
+ if (useKeychain) {
48
+ await configManager.set("encryption.useKeychain", true);
49
+ }
50
+ // 4. Run pull to get remote config
51
+ const pullCommand = new PullCommand(this.homeDir);
52
+ await pullCommand.execute({
53
+ quiet: options.quiet,
54
+ skipEncryption: options.skipEncryption,
55
+ passphrase,
56
+ });
57
+ // 4b. Detect encryption state from store
58
+ if (!options.skipEncryption && !passphrase) {
59
+ // No passphrase was needed/provided — store is not encrypted
60
+ await configManager.set("encryption.enabled", false);
61
+ }
62
+ // 5. Register this machine and commit
63
+ const registry = new MachineRegistry(join(gitAdapter.getStorePath(), STORE_MANIFEST_FILE));
64
+ await registry.register(config.machineId, hostname(), platform());
65
+ const commitResult = await gitAdapter.commitAndPush(`sync: ${config.machineId} joined`, config.machineId);
66
+ if (!commitResult.pushed && !options.quiet) {
67
+ output.warn("Machine registry update could not be pushed to the remote. Check your connection and try 'claudefy push'.");
68
+ }
69
+ // 6. Install hooks if requested
70
+ if (options.installHooks) {
71
+ const hookManager = new HookManager(join(this.homeDir, ".claude", "settings.json"));
72
+ await hookManager.install();
73
+ if (!options.quiet) {
74
+ output.info("Auto-sync hooks installed.");
41
75
  }
42
76
  }
43
- }
44
- if (useKeychain) {
45
- await configManager.set("encryption.useKeychain", true);
46
- }
47
- // 4. Run pull to get remote config
48
- const pullCommand = new PullCommand(this.homeDir);
49
- await pullCommand.execute({
50
- quiet: options.quiet,
51
- skipEncryption: options.skipEncryption,
52
- passphrase,
53
- });
54
- // 4b. Detect encryption state from store
55
- if (!options.skipEncryption && !passphrase) {
56
- // No passphrase was needed/provided — store is not encrypted
57
- await configManager.set("encryption.enabled", false);
58
- }
59
- // 5. Register this machine and commit
60
- const registry = new MachineRegistry(join(gitAdapter.getStorePath(), STORE_MANIFEST_FILE));
61
- await registry.register(config.machineId, hostname(), platform());
62
- const commitResult = await gitAdapter.commitAndPush(`sync: ${config.machineId} joined`, config.machineId);
63
- if (!commitResult.pushed && !options.quiet) {
64
- output.warn("Machine registry update could not be pushed to the remote. Check your connection and try 'claudefy push'.");
65
- }
66
- // 6. Install hooks if requested
67
- if (options.installHooks) {
68
- const hookManager = new HookManager(join(this.homeDir, ".claude", "settings.json"));
69
- await hookManager.install();
70
77
  if (!options.quiet) {
71
- output.info("Auto-sync hooks installed.");
78
+ output.success("Join complete. Your Claude config has been synced from remote.");
72
79
  }
73
- }
74
- if (!options.quiet) {
75
- output.success("Join complete. Your Claude config has been synced from remote.");
76
- }
80
+ if (!options.installHooks && !options.quiet) {
81
+ output.dim("Tip: run 'claudefy hooks install' to enable auto-sync on this machine");
82
+ }
83
+ });
77
84
  }
78
85
  async storeHasAgeFiles(storePath) {
79
86
  const configDir = join(storePath, STORE_CONFIG_DIR);
@@ -1 +1 @@
1
- {"version":3,"file":"join.js","sourceRoot":"","sources":["../../src/commands/join.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"join.js","sourceRoot":"","sources":["../../src/commands/join.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ import { ConfigManager } from "../config/config-manager.js";
3
3
  import { GitAdapter } from "../git-adapter/git-adapter.js";
4
4
  import { PushCommand } from "./push.js";
5
5
  import { output } from "../output.js";
6
+ import { withLock } from "../lockfile/lockfile.js";
6
7
  export class OverrideCommand {
7
8
  homeDir;
8
9
  configManager;
@@ -11,35 +12,38 @@ export class OverrideCommand {
11
12
  this.configManager = new ConfigManager(homeDir);
12
13
  }
13
14
  async execute(options) {
14
- if (!options.confirm) {
15
- throw new Error("Override requires --confirm flag. This will wipe the remote store and replace it with your local config.");
16
- }
17
- const config = await this.configManager.load();
18
- if (!options.quiet) {
19
- output.warn(`Overriding remote store as machine: ${config.machineId}`);
20
- }
21
- // 1. Initialize git adapter
22
- const gitAdapter = new GitAdapter(join(this.homeDir, ".claudefy"));
23
- await gitAdapter.initStore(config.backend.url);
24
- await gitAdapter.ensureMachineBranch(config.machineId);
25
- try {
26
- await gitAdapter.pullAndMergeMain();
27
- }
28
- catch {
29
- // Fresh store with no remote history yet
30
- }
31
- // 2. Wipe remote and write override marker
32
- await gitAdapter.wipeAndPush(config.machineId);
33
- // 3. Run full push pipeline to repopulate store
34
- const pushCommand = new PushCommand(this.homeDir);
35
- await pushCommand.execute({
36
- quiet: options.quiet,
37
- skipEncryption: options.skipEncryption,
38
- passphrase: options.passphrase,
15
+ const claudefyDir = join(this.homeDir, ".claudefy");
16
+ await withLock("override", !!options.quiet, claudefyDir, async () => {
17
+ if (!options.confirm) {
18
+ throw new Error("Override requires --confirm flag. This will wipe the remote store and replace it with your local config.");
19
+ }
20
+ const config = await this.configManager.load();
21
+ if (!options.quiet) {
22
+ output.warn(`Overriding remote store as machine: ${config.machineId}`);
23
+ }
24
+ // 1. Initialize git adapter
25
+ const gitAdapter = new GitAdapter(join(this.homeDir, ".claudefy"));
26
+ await gitAdapter.initStore(config.backend.url);
27
+ await gitAdapter.ensureMachineBranch(config.machineId);
28
+ try {
29
+ await gitAdapter.pullAndMergeMain();
30
+ }
31
+ catch {
32
+ // Fresh store with no remote history yet
33
+ }
34
+ // 2. Wipe remote and write override marker
35
+ await gitAdapter.wipeAndPush(config.machineId);
36
+ // 3. Run full push pipeline to repopulate store
37
+ const pushCommand = new PushCommand(this.homeDir);
38
+ await pushCommand.execute({
39
+ quiet: options.quiet,
40
+ skipEncryption: options.skipEncryption,
41
+ passphrase: options.passphrase,
42
+ });
43
+ if (!options.quiet) {
44
+ output.success("Override complete. All other machines will receive your config on next pull.");
45
+ }
39
46
  });
40
- if (!options.quiet) {
41
- output.success("Override complete. All other machines will receive your config on next pull.");
42
- }
43
47
  }
44
48
  }
45
49
  //# sourceMappingURL=override.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"override.js","sourceRoot":"","sources":["../../src/commands/override.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAStC,MAAM,OAAO,eAAe;IAClB,OAAO,CAAS;IAChB,aAAa,CAAgB;IAErC,YAAY,OAAe;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAwB;QACpC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACb,0GAA0G,CAC3G,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QAE/C,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC,uCAAuC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QACzE,CAAC;QAED,4BAA4B;QAC5B,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;QACnE,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,UAAU,CAAC,mBAAmB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,CAAC;YACH,MAAM,UAAU,CAAC,gBAAgB,EAAE,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,yCAAyC;QAC3C,CAAC;QAED,2CAA2C;QAC3C,MAAM,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAE/C,gDAAgD;QAChD,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,WAAW,CAAC,OAAO,CAAC;YACxB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,CAAC,OAAO,CACZ,8EAA8E,CAC/E,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"override.js","sourceRoot":"","sources":["../../src/commands/override.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AASnD,MAAM,OAAO,eAAe;IAClB,OAAO,CAAS;IAChB,aAAa,CAAgB;IAErC,YAAY,OAAe;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAwB;QACpC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACpD,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,IAAI,EAAE;YAClE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CACb,0GAA0G,CAC3G,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;YAE/C,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACnB,MAAM,CAAC,IAAI,CAAC,uCAAuC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;YACzE,CAAC;YAED,4BAA4B;YAC5B,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;YACnE,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC/C,MAAM,UAAU,CAAC,mBAAmB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACvD,IAAI,CAAC;gBACH,MAAM,UAAU,CAAC,gBAAgB,EAAE,CAAC;YACtC,CAAC;YAAC,MAAM,CAAC;gBACP,yCAAyC;YAC3C,CAAC;YAED,2CAA2C;YAC3C,MAAM,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAE/C,gDAAgD;YAChD,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAClD,MAAM,WAAW,CAAC,OAAO,CAAC;gBACxB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,UAAU,EAAE,OAAO,CAAC,UAAU;aAC/B,CAAC,CAAC;YAEH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACnB,MAAM,CAAC,OAAO,CACZ,8EAA8E,CAC/E,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -14,6 +14,7 @@ export declare class PullCommand {
14
14
  private configManager;
15
15
  constructor(homeDir: string);
16
16
  execute(options: PullOptions): Promise<PullResult>;
17
+ private executeLocked;
17
18
  /**
18
19
  * Check for an override marker. First checks current branch, then checks
19
20
  * the main branch (override markers may not survive merge into machine branch