@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.
- package/README.md +135 -111
- package/dist/claude-json-sync/claude-json-sync.d.ts +12 -0
- package/dist/claude-json-sync/claude-json-sync.js +129 -0
- package/dist/claude-json-sync/claude-json-sync.js.map +1 -0
- package/dist/commands/doctor.js +9 -5
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.js +64 -60
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/join.js +62 -55
- package/dist/commands/join.js.map +1 -1
- package/dist/commands/override.js +32 -28
- package/dist/commands/override.js.map +1 -1
- package/dist/commands/pull.d.ts +1 -0
- package/dist/commands/pull.js +234 -186
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/push.d.ts +1 -0
- package/dist/commands/push.js +149 -80
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/restore.js +31 -27
- package/dist/commands/restore.js.map +1 -1
- package/dist/config/config-manager.js +1 -0
- package/dist/config/config-manager.js.map +1 -1
- package/dist/config/defaults.d.ts +7 -1
- package/dist/config/defaults.js +20 -0
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/types.d.ts +16 -0
- package/dist/lockfile/lockfile.d.ts +8 -0
- package/dist/lockfile/lockfile.js +101 -0
- package/dist/lockfile/lockfile.js.map +1 -0
- package/dist/merger/merger.js +19 -4
- package/dist/merger/merger.js.map +1 -1
- package/dist/path-mapper/path-mapper.js +1 -1
- package/dist/path-mapper/path-mapper.js.map +1 -1
- package/dist/secret-scanner/scanner.d.ts +7 -0
- package/dist/secret-scanner/scanner.js +17 -3
- package/dist/secret-scanner/scanner.js.map +1 -1
- package/dist/sync-filter/sync-filter.js +5 -0
- package/dist/sync-filter/sync-filter.js.map +1 -1
- package/package.json +1 -1
package/dist/commands/init.js
CHANGED
|
@@ -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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
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
|
-
|
|
48
|
-
|
|
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(
|
|
61
|
+
output.info(`Initialized claudefy with machine ID: ${config.machineId}`);
|
|
80
62
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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":"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;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/join.js
CHANGED
|
@@ -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
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (
|
|
37
|
-
const
|
|
38
|
-
if (
|
|
39
|
-
|
|
40
|
-
|
|
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.
|
|
78
|
+
output.success("Join complete. Your Claude config has been synced from remote.");
|
|
72
79
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClD,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,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAUjG,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,aAAa,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
await gitAdapter.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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;
|
|
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"}
|
package/dist/commands/pull.d.ts
CHANGED
|
@@ -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
|