@kodrunhq/claudefy 1.1.3 → 1.2.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 +46 -4
- package/dist/commands/init.js +1 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/join.js +9 -5
- package/dist/commands/join.js.map +1 -1
- package/dist/commands/override.js +1 -0
- package/dist/commands/override.js.map +1 -1
- package/dist/commands/pull.d.ts +6 -0
- package/dist/commands/pull.js +185 -140
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/push.js +128 -100
- package/dist/commands/push.js.map +1 -1
- package/dist/encryptor/encryptor.d.ts +5 -2
- package/dist/encryptor/encryptor.js +34 -23
- package/dist/encryptor/encryptor.js.map +1 -1
- package/dist/encryptor/file-encryptor.d.ts +8 -0
- package/dist/encryptor/file-encryptor.js +30 -0
- package/dist/encryptor/file-encryptor.js.map +1 -0
- package/dist/encryptor/key-derivation.d.ts +2 -0
- package/dist/encryptor/key-derivation.js +20 -0
- package/dist/encryptor/key-derivation.js.map +1 -0
- package/dist/encryptor/line-encryptor.d.ts +10 -0
- package/dist/encryptor/line-encryptor.js +41 -0
- package/dist/encryptor/line-encryptor.js.map +1 -0
- package/dist/git-adapter/git-adapter.d.ts +11 -1
- package/dist/git-adapter/git-adapter.js +117 -3
- package/dist/git-adapter/git-adapter.js.map +1 -1
- package/dist/machine-registry/machine-registry.d.ts +1 -0
- package/dist/machine-registry/machine-registry.js +21 -0
- package/dist/machine-registry/machine-registry.js.map +1 -1
- package/package.json +3 -2
package/dist/commands/push.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cp, mkdir, readdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
2
|
+
import { join, relative, resolve } from "node:path";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import { hostname, platform } from "node:os";
|
|
5
5
|
import { ConfigManager } from "../config/config-manager.js";
|
|
@@ -35,120 +35,148 @@ export class PushCommand {
|
|
|
35
35
|
`${classification.unknown.length} ${unknownLabel}, ` +
|
|
36
36
|
`${classification.denylist.length} denied`);
|
|
37
37
|
}
|
|
38
|
-
// 2. Initialize git adapter
|
|
38
|
+
// 2. Initialize git adapter + per-machine branch
|
|
39
39
|
const gitAdapter = new GitAdapter(join(this.homeDir, ".claudefy"));
|
|
40
40
|
await gitAdapter.initStore(config.backend.url);
|
|
41
|
+
await gitAdapter.ensureMachineBranch(config.machineId);
|
|
41
42
|
try {
|
|
42
|
-
await gitAdapter.
|
|
43
|
+
await gitAdapter.pullAndMergeMain();
|
|
43
44
|
}
|
|
44
45
|
catch {
|
|
45
|
-
|
|
46
|
+
if (!options.quiet) {
|
|
47
|
+
output.info("Warning: Unable to pull latest changes from remote; proceeding with local state only.");
|
|
48
|
+
}
|
|
46
49
|
}
|
|
47
50
|
const storePath = gitAdapter.getStorePath();
|
|
51
|
+
const stagingDir = join(storePath, ".staging");
|
|
48
52
|
const configDir = join(storePath, "config");
|
|
49
53
|
const unknownDir = join(storePath, "unknown");
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
await
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const src = join(this.claudeDir, item.name);
|
|
62
|
-
const dest = join(configDir, item.name);
|
|
63
|
-
await cp(src, dest, { recursive: true });
|
|
64
|
-
}
|
|
65
|
-
// 5. Copy unknown items
|
|
66
|
-
for (const item of classification.unknown) {
|
|
67
|
-
const src = join(this.claudeDir, item.name);
|
|
68
|
-
const dest = join(unknownDir, item.name);
|
|
69
|
-
await cp(src, dest, { recursive: true });
|
|
70
|
-
}
|
|
71
|
-
// 6. Normalize paths in known files
|
|
72
|
-
const links = await this.configManager.getLinks();
|
|
73
|
-
const pathMapper = new PathMapper(links);
|
|
74
|
-
// settings.json
|
|
75
|
-
const settingsPath = join(configDir, "settings.json");
|
|
76
|
-
if (existsSync(settingsPath)) {
|
|
77
|
-
const settings = JSON.parse(await readFile(settingsPath, "utf-8"));
|
|
78
|
-
const normalized = pathMapper.normalizeSettingsPaths(settings, this.claudeDir);
|
|
79
|
-
await writeFile(settingsPath, JSON.stringify(normalized, null, 2));
|
|
80
|
-
}
|
|
81
|
-
// installed_plugins.json
|
|
82
|
-
const pluginsJsonPath = join(configDir, "plugins", "installed_plugins.json");
|
|
83
|
-
if (existsSync(pluginsJsonPath)) {
|
|
84
|
-
const plugins = JSON.parse(await readFile(pluginsJsonPath, "utf-8"));
|
|
85
|
-
const normalized = pathMapper.normalizePluginPaths(plugins, this.claudeDir);
|
|
86
|
-
await writeFile(pluginsJsonPath, JSON.stringify(normalized, null, 2));
|
|
87
|
-
}
|
|
88
|
-
// known_marketplaces.json
|
|
89
|
-
const marketplacesPath = join(configDir, "plugins", "known_marketplaces.json");
|
|
90
|
-
if (existsSync(marketplacesPath)) {
|
|
91
|
-
const mp = JSON.parse(await readFile(marketplacesPath, "utf-8"));
|
|
92
|
-
const normalized = pathMapper.normalizePluginPaths(mp, this.claudeDir);
|
|
93
|
-
await writeFile(marketplacesPath, JSON.stringify(normalized, null, 2));
|
|
94
|
-
}
|
|
95
|
-
// history.jsonl
|
|
96
|
-
const historyPath = join(configDir, "history.jsonl");
|
|
97
|
-
if (existsSync(historyPath)) {
|
|
98
|
-
const content = await readFile(historyPath, "utf-8");
|
|
99
|
-
const normalized = content
|
|
100
|
-
.split("\n")
|
|
101
|
-
.filter(Boolean)
|
|
102
|
-
.map((line) => pathMapper.normalizeJsonlLine(line))
|
|
103
|
-
.join("\n") + "\n";
|
|
104
|
-
await writeFile(historyPath, normalized);
|
|
105
|
-
}
|
|
106
|
-
// projects/ directory renaming
|
|
107
|
-
const projectsDir = join(configDir, "projects");
|
|
108
|
-
if (existsSync(projectsDir)) {
|
|
109
|
-
const projectDirs = await readdir(projectsDir);
|
|
110
|
-
for (const dirName of projectDirs) {
|
|
111
|
-
const canonicalId = pathMapper.normalizeDirName(dirName);
|
|
112
|
-
if (canonicalId) {
|
|
113
|
-
await rename(join(projectsDir, dirName), join(projectsDir, canonicalId));
|
|
114
|
-
}
|
|
54
|
+
try {
|
|
55
|
+
// 3. Clean staging dir
|
|
56
|
+
if (existsSync(stagingDir))
|
|
57
|
+
await rm(stagingDir, { recursive: true });
|
|
58
|
+
await mkdir(join(stagingDir, "config"), { recursive: true });
|
|
59
|
+
await mkdir(join(stagingDir, "unknown"), { recursive: true });
|
|
60
|
+
// 4. Copy allowlisted items to staging
|
|
61
|
+
for (const item of classification.allowlist) {
|
|
62
|
+
const src = join(this.claudeDir, item.name);
|
|
63
|
+
const dest = join(stagingDir, "config", item.name);
|
|
64
|
+
await cp(src, dest, { recursive: true });
|
|
115
65
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
66
|
+
// 5. Copy unknown items to staging
|
|
67
|
+
for (const item of classification.unknown) {
|
|
68
|
+
const src = join(this.claudeDir, item.name);
|
|
69
|
+
const dest = join(stagingDir, "unknown", item.name);
|
|
70
|
+
await cp(src, dest, { recursive: true });
|
|
71
|
+
}
|
|
72
|
+
// 6. Normalize paths in staging
|
|
73
|
+
const links = await this.configManager.getLinks();
|
|
74
|
+
const pathMapper = new PathMapper(links);
|
|
75
|
+
// settings.json
|
|
76
|
+
const settingsPath = join(stagingDir, "config", "settings.json");
|
|
77
|
+
if (existsSync(settingsPath)) {
|
|
78
|
+
const settings = JSON.parse(await readFile(settingsPath, "utf-8"));
|
|
79
|
+
const normalized = pathMapper.normalizeSettingsPaths(settings, this.claudeDir);
|
|
80
|
+
await writeFile(settingsPath, JSON.stringify(normalized, null, 2));
|
|
81
|
+
}
|
|
82
|
+
// installed_plugins.json
|
|
83
|
+
const pluginsJsonPath = join(stagingDir, "config", "plugins", "installed_plugins.json");
|
|
84
|
+
if (existsSync(pluginsJsonPath)) {
|
|
85
|
+
const plugins = JSON.parse(await readFile(pluginsJsonPath, "utf-8"));
|
|
86
|
+
const normalized = pathMapper.normalizePluginPaths(plugins, this.claudeDir);
|
|
87
|
+
await writeFile(pluginsJsonPath, JSON.stringify(normalized, null, 2));
|
|
88
|
+
}
|
|
89
|
+
// known_marketplaces.json
|
|
90
|
+
const marketplacesPath = join(stagingDir, "config", "plugins", "known_marketplaces.json");
|
|
91
|
+
if (existsSync(marketplacesPath)) {
|
|
92
|
+
const mp = JSON.parse(await readFile(marketplacesPath, "utf-8"));
|
|
93
|
+
const normalized = pathMapper.normalizePluginPaths(mp, this.claudeDir);
|
|
94
|
+
await writeFile(marketplacesPath, JSON.stringify(normalized, null, 2));
|
|
95
|
+
}
|
|
96
|
+
// history.jsonl
|
|
97
|
+
const historyPath = join(stagingDir, "config", "history.jsonl");
|
|
98
|
+
if (existsSync(historyPath)) {
|
|
99
|
+
const content = await readFile(historyPath, "utf-8");
|
|
100
|
+
const normalized = content
|
|
101
|
+
.split("\n")
|
|
102
|
+
.filter(Boolean)
|
|
103
|
+
.map((line) => pathMapper.normalizeJsonlLine(line))
|
|
104
|
+
.join("\n") + "\n";
|
|
105
|
+
await writeFile(historyPath, normalized);
|
|
106
|
+
}
|
|
107
|
+
// projects/ directory renaming with path traversal check
|
|
108
|
+
const projectsDir = join(stagingDir, "config", "projects");
|
|
109
|
+
if (existsSync(projectsDir)) {
|
|
110
|
+
const projectDirs = await readdir(projectsDir);
|
|
111
|
+
for (const dirName of projectDirs) {
|
|
112
|
+
const canonicalId = pathMapper.normalizeDirName(dirName);
|
|
113
|
+
if (canonicalId) {
|
|
114
|
+
const destPath = resolve(join(projectsDir, canonicalId));
|
|
115
|
+
const rel = relative(resolve(projectsDir), destPath);
|
|
116
|
+
if (rel.startsWith("..") || resolve(destPath) === resolve(projectsDir)) {
|
|
117
|
+
if (!options.quiet) {
|
|
118
|
+
output.warn(`Skipping directory rename "${dirName}": path escapes projects directory`);
|
|
119
|
+
}
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
await rename(join(projectsDir, dirName), destPath);
|
|
139
123
|
}
|
|
140
124
|
}
|
|
141
|
-
|
|
142
|
-
|
|
125
|
+
}
|
|
126
|
+
// 7. Scan for secrets and encrypt files that contain them (in staging)
|
|
127
|
+
if (!options.skipSecretScan) {
|
|
128
|
+
const scanner = new SecretScanner();
|
|
129
|
+
const allFiles = [
|
|
130
|
+
...(await this.collectFiles(join(stagingDir, "config"))),
|
|
131
|
+
...(await this.collectFiles(join(stagingDir, "unknown"))),
|
|
132
|
+
];
|
|
133
|
+
const findings = await scanner.scanFiles(allFiles);
|
|
134
|
+
if (findings.length > 0) {
|
|
135
|
+
if (!config.encryption.enabled || options.skipEncryption) {
|
|
136
|
+
const details = findings.map((f) => ` ${f.file}:${f.line} [${f.pattern}]`).join("\n");
|
|
137
|
+
throw new Error(`Secret scan detected ${findings.length} potential secret(s):\n${details}\n\nEnable encryption or use --skip-secret-scan to bypass scanning.`);
|
|
138
|
+
}
|
|
139
|
+
if (!options.passphrase) {
|
|
140
|
+
throw new Error("Secrets detected and encryption is enabled but no passphrase found. Set CLAUDEFY_PASSPHRASE or store it in your OS keychain via 'claudefy init'.");
|
|
141
|
+
}
|
|
142
|
+
const encryptor = new Encryptor(options.passphrase);
|
|
143
|
+
const filesToEncrypt = new Set(findings.map((f) => f.file));
|
|
144
|
+
for (const filePath of filesToEncrypt) {
|
|
145
|
+
if (existsSync(filePath) && !filePath.endsWith(".age")) {
|
|
146
|
+
await encryptor.encryptFile(filePath, filePath + ".age");
|
|
147
|
+
await rm(filePath);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (!options.quiet) {
|
|
151
|
+
output.info(`Encrypted ${filesToEncrypt.size} file(s) containing potential secrets.`);
|
|
152
|
+
}
|
|
143
153
|
}
|
|
144
154
|
}
|
|
145
|
-
|
|
146
|
-
|
|
155
|
+
// 8. Swap staging into real dirs
|
|
156
|
+
if (existsSync(configDir))
|
|
157
|
+
await rm(configDir, { recursive: true });
|
|
158
|
+
if (existsSync(unknownDir))
|
|
159
|
+
await rm(unknownDir, { recursive: true });
|
|
160
|
+
await rename(join(stagingDir, "config"), configDir);
|
|
161
|
+
await rename(join(stagingDir, "unknown"), unknownDir);
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
if (existsSync(stagingDir))
|
|
165
|
+
await rm(stagingDir, { recursive: true });
|
|
166
|
+
}
|
|
167
|
+
// 9. Conditional manifest update
|
|
168
|
+
const hasRealChanges = !(await gitAdapter.isClean());
|
|
147
169
|
const registry = new MachineRegistry(join(storePath, "manifest.json"));
|
|
148
|
-
await registry.
|
|
149
|
-
// 10. Commit and push
|
|
150
|
-
await gitAdapter.commitAndPush(`sync: push from ${config.machineId}
|
|
170
|
+
await registry.conditionalRegister(config.machineId, hostname(), platform(), hasRealChanges);
|
|
171
|
+
// 10. Commit and push with branch support
|
|
172
|
+
const commitResult = await gitAdapter.commitAndPush(`sync: push from ${config.machineId}`, config.machineId);
|
|
151
173
|
if (!options.quiet) {
|
|
174
|
+
if (commitResult.committed && !commitResult.pushed) {
|
|
175
|
+
output.warn("Changes were committed locally, but pushing to the remote failed. Retry with 'claudefy push'.");
|
|
176
|
+
}
|
|
177
|
+
if (commitResult.pushed && !commitResult.mergedToMain) {
|
|
178
|
+
output.warn("Unable to merge machine branch into main. You may need to resolve conflicts.");
|
|
179
|
+
}
|
|
152
180
|
output.success("Push complete.");
|
|
153
181
|
}
|
|
154
182
|
}
|
|
@@ -162,7 +190,7 @@ export class PushCommand {
|
|
|
162
190
|
if (entry.isDirectory()) {
|
|
163
191
|
results.push(...(await this.collectFiles(fullPath)));
|
|
164
192
|
}
|
|
165
|
-
else {
|
|
193
|
+
else if (!entry.isSymbolicLink()) {
|
|
166
194
|
results.push(fullPath);
|
|
167
195
|
}
|
|
168
196
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
export declare class Encryptor {
|
|
2
|
-
private
|
|
2
|
+
private lineEncryptor;
|
|
3
|
+
private fileEncryptor;
|
|
3
4
|
constructor(passphrase: string);
|
|
5
|
+
private isJsonlFile;
|
|
6
|
+
private isOriginallyJsonl;
|
|
4
7
|
encryptFile(inputPath: string, outputPath: string): Promise<void>;
|
|
5
8
|
decryptFile(inputPath: string, outputPath: string): Promise<void>;
|
|
6
9
|
encryptString(input: string): Promise<string>;
|
|
7
|
-
decryptString(
|
|
10
|
+
decryptString(encrypted: string): Promise<string>;
|
|
8
11
|
encryptDirectory(dirPath: string): Promise<void>;
|
|
9
12
|
decryptDirectory(dirPath: string): Promise<void>;
|
|
10
13
|
}
|
|
@@ -1,37 +1,48 @@
|
|
|
1
|
-
import { Encrypter, Decrypter } from "age-encryption";
|
|
2
1
|
import { readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
3
2
|
import { join } from "node:path";
|
|
3
|
+
import { LineEncryptor } from "./line-encryptor.js";
|
|
4
|
+
import { FileEncryptor } from "./file-encryptor.js";
|
|
4
5
|
export class Encryptor {
|
|
5
|
-
|
|
6
|
+
lineEncryptor;
|
|
7
|
+
fileEncryptor;
|
|
6
8
|
constructor(passphrase) {
|
|
7
|
-
this.
|
|
9
|
+
this.lineEncryptor = new LineEncryptor(passphrase);
|
|
10
|
+
this.fileEncryptor = new FileEncryptor(passphrase);
|
|
11
|
+
}
|
|
12
|
+
isJsonlFile(filePath) {
|
|
13
|
+
return filePath.endsWith(".jsonl");
|
|
14
|
+
}
|
|
15
|
+
isOriginallyJsonl(agePath) {
|
|
16
|
+
return agePath.endsWith(".jsonl.age");
|
|
8
17
|
}
|
|
9
18
|
async encryptFile(inputPath, outputPath) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
if (this.isJsonlFile(inputPath)) {
|
|
20
|
+
const content = await readFile(inputPath, "utf-8");
|
|
21
|
+
const encrypted = this.lineEncryptor.encryptFileContent(content);
|
|
22
|
+
await writeFile(outputPath, encrypted);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const data = await readFile(inputPath);
|
|
26
|
+
const encrypted = this.fileEncryptor.encrypt(new Uint8Array(data));
|
|
27
|
+
await writeFile(outputPath, encrypted);
|
|
28
|
+
}
|
|
15
29
|
}
|
|
16
30
|
async decryptFile(inputPath, outputPath) {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
31
|
+
const content = await readFile(inputPath, "utf-8");
|
|
32
|
+
if (this.isOriginallyJsonl(inputPath)) {
|
|
33
|
+
const decrypted = this.lineEncryptor.decryptFileContent(content);
|
|
34
|
+
await writeFile(outputPath, decrypted);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
const decrypted = this.fileEncryptor.decrypt(content);
|
|
38
|
+
await writeFile(outputPath, decrypted);
|
|
39
|
+
}
|
|
22
40
|
}
|
|
23
41
|
async encryptString(input) {
|
|
24
|
-
|
|
25
|
-
e.setPassphrase(this.passphrase);
|
|
26
|
-
const encrypted = await e.encrypt(new TextEncoder().encode(input));
|
|
27
|
-
return Buffer.from(encrypted).toString("base64");
|
|
42
|
+
return this.fileEncryptor.encryptString(input);
|
|
28
43
|
}
|
|
29
|
-
async decryptString(
|
|
30
|
-
|
|
31
|
-
const d = new Decrypter();
|
|
32
|
-
d.addPassphrase(this.passphrase);
|
|
33
|
-
const decrypted = await d.decrypt(data, "uint8array");
|
|
34
|
-
return new TextDecoder().decode(decrypted);
|
|
44
|
+
async decryptString(encrypted) {
|
|
45
|
+
return this.fileEncryptor.decryptString(encrypted);
|
|
35
46
|
}
|
|
36
47
|
async encryptDirectory(dirPath) {
|
|
37
48
|
const entries = await readdir(dirPath, { withFileTypes: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encryptor.js","sourceRoot":"","sources":["../../src/encryptor/encryptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"encryptor.js","sourceRoot":"","sources":["../../src/encryptor/encryptor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { aessiv } from "@noble/ciphers/aes.js";
|
|
2
|
+
import { deriveFileKey } from "./key-derivation.js";
|
|
3
|
+
export class FileEncryptor {
|
|
4
|
+
key;
|
|
5
|
+
constructor(passphrase) {
|
|
6
|
+
this.key = deriveFileKey(passphrase);
|
|
7
|
+
}
|
|
8
|
+
encrypt(data) {
|
|
9
|
+
const cipher = aessiv(this.key, new Uint8Array(0));
|
|
10
|
+
const encrypted = cipher.encrypt(data);
|
|
11
|
+
return Buffer.from(encrypted).toString("base64");
|
|
12
|
+
}
|
|
13
|
+
decrypt(encoded) {
|
|
14
|
+
const cipher = aessiv(this.key, new Uint8Array(0));
|
|
15
|
+
const encrypted = new Uint8Array(Buffer.from(encoded, "base64"));
|
|
16
|
+
return cipher.decrypt(encrypted);
|
|
17
|
+
}
|
|
18
|
+
encryptString(text) {
|
|
19
|
+
if (text === "")
|
|
20
|
+
return "";
|
|
21
|
+
return this.encrypt(new TextEncoder().encode(text));
|
|
22
|
+
}
|
|
23
|
+
decryptString(encoded) {
|
|
24
|
+
if (encoded === "")
|
|
25
|
+
return "";
|
|
26
|
+
const decrypted = this.decrypt(encoded);
|
|
27
|
+
return new TextDecoder().decode(decrypted);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=file-encryptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-encryptor.js","sourceRoot":"","sources":["../../src/encryptor/file-encryptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,OAAO,aAAa;IAChB,GAAG,CAAa;IAExB,YAAY,UAAkB;QAC5B,IAAI,CAAC,GAAG,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,IAAgB;QACtB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvC,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,CAAC,OAAe;QACrB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjE,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAED,aAAa,CAAC,IAAY;QACxB,IAAI,IAAI,KAAK,EAAE;YAAE,OAAO,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,aAAa,CAAC,OAAe;QAC3B,IAAI,OAAO,KAAK,EAAE;YAAE,OAAO,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { pbkdf2 } from "@noble/hashes/pbkdf2.js";
|
|
2
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
3
|
+
const LINE_SALT = "claudefy-line-v1";
|
|
4
|
+
const FILE_SALT = "claudefy-file-v1";
|
|
5
|
+
const PBKDF2_ITERATIONS = 100_000;
|
|
6
|
+
const KEY_LENGTH_BYTES = 32;
|
|
7
|
+
function deriveKey(passphrase, salt) {
|
|
8
|
+
const encoder = new TextEncoder();
|
|
9
|
+
return pbkdf2(sha256, encoder.encode(passphrase), encoder.encode(salt), {
|
|
10
|
+
c: PBKDF2_ITERATIONS,
|
|
11
|
+
dkLen: KEY_LENGTH_BYTES,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export function deriveLineKey(passphrase) {
|
|
15
|
+
return deriveKey(passphrase, LINE_SALT);
|
|
16
|
+
}
|
|
17
|
+
export function deriveFileKey(passphrase) {
|
|
18
|
+
return deriveKey(passphrase, FILE_SALT);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=key-derivation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-derivation.js","sourceRoot":"","sources":["../../src/encryptor/key-derivation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,MAAM,SAAS,GAAG,kBAAkB,CAAC;AACrC,MAAM,SAAS,GAAG,kBAAkB,CAAC;AACrC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAClC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAE5B,SAAS,SAAS,CAAC,UAAkB,EAAE,IAAY;IACjD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,OAAO,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QACtE,CAAC,EAAE,iBAAiB;QACpB,KAAK,EAAE,gBAAgB;KACxB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,UAAkB;IAC9C,OAAO,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,UAAkB;IAC9C,OAAO,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare class LineEncryptor {
|
|
2
|
+
private key;
|
|
3
|
+
constructor(passphrase: string);
|
|
4
|
+
encryptLine(line: string): string;
|
|
5
|
+
decryptLine(encoded: string): string;
|
|
6
|
+
encryptLines(lines: string[]): string[];
|
|
7
|
+
decryptLines(encrypted: string[]): string[];
|
|
8
|
+
encryptFileContent(content: string): string;
|
|
9
|
+
decryptFileContent(content: string): string;
|
|
10
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { aessiv } from "@noble/ciphers/aes.js";
|
|
2
|
+
import { deriveLineKey } from "./key-derivation.js";
|
|
3
|
+
export class LineEncryptor {
|
|
4
|
+
key;
|
|
5
|
+
constructor(passphrase) {
|
|
6
|
+
this.key = deriveLineKey(passphrase);
|
|
7
|
+
}
|
|
8
|
+
encryptLine(line) {
|
|
9
|
+
const cipher = aessiv(this.key, new Uint8Array(0));
|
|
10
|
+
const plaintext = new TextEncoder().encode(line);
|
|
11
|
+
const encrypted = cipher.encrypt(plaintext);
|
|
12
|
+
return Buffer.from(encrypted).toString("base64");
|
|
13
|
+
}
|
|
14
|
+
decryptLine(encoded) {
|
|
15
|
+
const cipher = aessiv(this.key, new Uint8Array(0));
|
|
16
|
+
const encrypted = new Uint8Array(Buffer.from(encoded, "base64"));
|
|
17
|
+
const decrypted = cipher.decrypt(encrypted);
|
|
18
|
+
return new TextDecoder().decode(decrypted);
|
|
19
|
+
}
|
|
20
|
+
encryptLines(lines) {
|
|
21
|
+
return lines.map((line) => this.encryptLine(line));
|
|
22
|
+
}
|
|
23
|
+
decryptLines(encrypted) {
|
|
24
|
+
return encrypted.map((line) => this.decryptLine(line));
|
|
25
|
+
}
|
|
26
|
+
encryptFileContent(content) {
|
|
27
|
+
if (content === "")
|
|
28
|
+
return "";
|
|
29
|
+
const lines = content.endsWith("\n") ? content.slice(0, -1).split("\n") : content.split("\n");
|
|
30
|
+
const encrypted = this.encryptLines(lines);
|
|
31
|
+
return encrypted.join("\n") + "\n";
|
|
32
|
+
}
|
|
33
|
+
decryptFileContent(content) {
|
|
34
|
+
if (content === "" || content.trim() === "")
|
|
35
|
+
return "";
|
|
36
|
+
const lines = content.endsWith("\n") ? content.slice(0, -1).split("\n") : content.split("\n");
|
|
37
|
+
const decrypted = this.decryptLines(lines);
|
|
38
|
+
return decrypted.join("\n") + "\n";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=line-encryptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line-encryptor.js","sourceRoot":"","sources":["../../src/encryptor/line-encryptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,OAAO,aAAa;IAChB,GAAG,CAAa;IAExB,YAAY,UAAkB;QAC5B,IAAI,CAAC,GAAG,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAED,WAAW,CAAC,IAAY;QACtB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC5C,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IAED,WAAW,CAAC,OAAe;QACzB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjE,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC5C,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;IAED,YAAY,CAAC,KAAe;QAC1B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,YAAY,CAAC,SAAmB;QAC9B,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,kBAAkB,CAAC,OAAe;QAChC,IAAI,OAAO,KAAK,EAAE;YAAE,OAAO,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9F,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC3C,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACrC,CAAC;IAED,kBAAkB,CAAC,OAAe;QAChC,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,EAAE,CAAC;QACvD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9F,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC3C,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACrC,CAAC;CACF"}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
export interface CommitResult {
|
|
2
|
+
committed: boolean;
|
|
3
|
+
pushed: boolean;
|
|
4
|
+
mergedToMain: boolean;
|
|
5
|
+
}
|
|
1
6
|
export interface OverrideMarker {
|
|
2
7
|
machine: string;
|
|
3
8
|
timestamp: string;
|
|
@@ -9,13 +14,18 @@ export declare class GitAdapter {
|
|
|
9
14
|
private ghAuthCache;
|
|
10
15
|
constructor(baseDir: string);
|
|
11
16
|
initStore(remoteUrl: string): Promise<void>;
|
|
12
|
-
|
|
17
|
+
ensureMachineBranch(machineId: string): Promise<void>;
|
|
18
|
+
getCurrentBranch(): Promise<string>;
|
|
19
|
+
commitAndPush(message: string, machineId?: string): Promise<CommitResult>;
|
|
20
|
+
isClean(): Promise<boolean>;
|
|
13
21
|
pull(): Promise<void>;
|
|
22
|
+
pullAndMergeMain(): Promise<void>;
|
|
14
23
|
writeOverrideMarker(machineId: string): Promise<void>;
|
|
15
24
|
checkOverrideMarker(): Promise<OverrideMarker | null>;
|
|
16
25
|
removeOverrideMarker(): Promise<void>;
|
|
17
26
|
wipeAndPush(machineId: string): Promise<void>;
|
|
18
27
|
getStorePath(): string;
|
|
28
|
+
private ensureMainBranch;
|
|
19
29
|
private ensureInitialized;
|
|
20
30
|
private configureCredentialHelper;
|
|
21
31
|
private gitWithCredentials;
|