@kodrunhq/claudefy 0.1.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 (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +147 -0
  3. package/dist/backup-manager/backup-manager.d.ts +6 -0
  4. package/dist/backup-manager/backup-manager.js +27 -0
  5. package/dist/backup-manager/backup-manager.js.map +1 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.js +296 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/commands/config.d.ts +8 -0
  10. package/dist/commands/config.js +56 -0
  11. package/dist/commands/config.js.map +1 -0
  12. package/dist/commands/doctor.d.ts +14 -0
  13. package/dist/commands/doctor.js +64 -0
  14. package/dist/commands/doctor.js.map +1 -0
  15. package/dist/commands/hooks.d.ts +7 -0
  16. package/dist/commands/hooks.js +18 -0
  17. package/dist/commands/hooks.js.map +1 -0
  18. package/dist/commands/init.d.ts +13 -0
  19. package/dist/commands/init.js +66 -0
  20. package/dist/commands/init.js.map +1 -0
  21. package/dist/commands/join.d.ts +12 -0
  22. package/dist/commands/join.js +51 -0
  23. package/dist/commands/join.js.map +1 -0
  24. package/dist/commands/link.d.ts +12 -0
  25. package/dist/commands/link.js +34 -0
  26. package/dist/commands/link.js.map +1 -0
  27. package/dist/commands/machines.d.ts +6 -0
  28. package/dist/commands/machines.js +25 -0
  29. package/dist/commands/machines.js.map +1 -0
  30. package/dist/commands/override.d.ts +12 -0
  31. package/dist/commands/override.js +44 -0
  32. package/dist/commands/override.js.map +1 -0
  33. package/dist/commands/pull.d.ts +17 -0
  34. package/dist/commands/pull.js +220 -0
  35. package/dist/commands/pull.js.map +1 -0
  36. package/dist/commands/push.d.ts +14 -0
  37. package/dist/commands/push.js +175 -0
  38. package/dist/commands/push.js.map +1 -0
  39. package/dist/commands/status.d.ts +14 -0
  40. package/dist/commands/status.js +50 -0
  41. package/dist/commands/status.js.map +1 -0
  42. package/dist/config/config-manager.d.ts +22 -0
  43. package/dist/config/config-manager.js +118 -0
  44. package/dist/config/config-manager.js.map +1 -0
  45. package/dist/config/defaults.d.ts +7 -0
  46. package/dist/config/defaults.js +33 -0
  47. package/dist/config/defaults.js.map +1 -0
  48. package/dist/config/types.d.ts +25 -0
  49. package/dist/config/types.js +2 -0
  50. package/dist/config/types.js.map +1 -0
  51. package/dist/encryptor/encryptor.d.ts +10 -0
  52. package/dist/encryptor/encryptor.js +68 -0
  53. package/dist/encryptor/encryptor.js.map +1 -0
  54. package/dist/encryptor/passphrase.d.ts +7 -0
  55. package/dist/encryptor/passphrase.js +34 -0
  56. package/dist/encryptor/passphrase.js.map +1 -0
  57. package/dist/git-adapter/git-adapter.d.ts +19 -0
  58. package/dist/git-adapter/git-adapter.js +104 -0
  59. package/dist/git-adapter/git-adapter.js.map +1 -0
  60. package/dist/git-adapter/types.d.ts +14 -0
  61. package/dist/git-adapter/types.js +2 -0
  62. package/dist/git-adapter/types.js.map +1 -0
  63. package/dist/hook-manager/hook-manager.d.ts +11 -0
  64. package/dist/hook-manager/hook-manager.js +110 -0
  65. package/dist/hook-manager/hook-manager.js.map +1 -0
  66. package/dist/index.d.ts +2 -0
  67. package/dist/index.js +4 -0
  68. package/dist/index.js.map +1 -0
  69. package/dist/machine-registry/machine-registry.d.ts +16 -0
  70. package/dist/machine-registry/machine-registry.js +65 -0
  71. package/dist/machine-registry/machine-registry.js.map +1 -0
  72. package/dist/merger/merger.d.ts +10 -0
  73. package/dist/merger/merger.js +15 -0
  74. package/dist/merger/merger.js.map +1 -0
  75. package/dist/output.d.ts +8 -0
  76. package/dist/output.js +10 -0
  77. package/dist/output.js.map +1 -0
  78. package/dist/path-mapper/git-identity.d.ts +8 -0
  79. package/dist/path-mapper/git-identity.js +35 -0
  80. package/dist/path-mapper/git-identity.js.map +1 -0
  81. package/dist/path-mapper/path-mapper.d.ts +19 -0
  82. package/dist/path-mapper/path-mapper.js +101 -0
  83. package/dist/path-mapper/path-mapper.js.map +1 -0
  84. package/dist/repo-creator/repo-creator.d.ts +6 -0
  85. package/dist/repo-creator/repo-creator.js +52 -0
  86. package/dist/repo-creator/repo-creator.js.map +1 -0
  87. package/dist/secret-scanner/scanner.d.ts +10 -0
  88. package/dist/secret-scanner/scanner.js +48 -0
  89. package/dist/secret-scanner/scanner.js.map +1 -0
  90. package/dist/sync-filter/sync-filter.d.ts +8 -0
  91. package/dist/sync-filter/sync-filter.js +37 -0
  92. package/dist/sync-filter/sync-filter.js.map +1 -0
  93. package/dist/sync-filter/types.d.ts +13 -0
  94. package/dist/sync-filter/types.js +2 -0
  95. package/dist/sync-filter/types.js.map +1 -0
  96. package/package.json +72 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../src/config/config-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,EACL,YAAY,EACZ,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAEvB,MAAM,OAAO,aAAa;IAChB,OAAO,CAAS;IAChB,SAAS,CAAS;IAE1B,YAAY,OAAe;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,UAAkB;QACjC,IAAI,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;QAC5F,CAAC;QAED,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAElE,MAAM,SAAS,GAAG,GAAG,QAAQ,EAAE,IAAI,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;QAC5E,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE,SAAS,CAAC,CAAC;QAElE,MAAM,MAAM,GAAmB;YAC7B,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE;YACzC,UAAU,EAAE;gBACV,OAAO,EAAE,IAAI;gBACb,WAAW,EAAE,KAAK;gBAClB,aAAa,EAAE,GAAG;aACnB;YACD,SAAS;SACV,CAAC;QAEF,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC9B,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACzB,MAAM,IAAI,CAAC,cAAc,CAAC,EAAE,GAAG,mBAAmB,EAAE,CAAC,CAAC;QAEtD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAc;QACnC,MAAM,cAAc,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClC,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,GAAG,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,GAAG,GAA4B,MAA4C,CAAC;QAChF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3B,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACpE,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;YACnF,CAAC;YACD,GAAG,GAAG,IAA+B,CAAC;QACxC,CAAC;QACD,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;QACrC,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,OAAO,CACX,KAAa,EACb,SAAiB,EACjB,IAAuD;QAEvD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpC,KAAK,CAAC,KAAK,CAAC,GAAG;YACb,SAAS;YACT,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACrC,CAAC;QACF,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAa;QAC5B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC;QACpB,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC9C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,GAAG,mBAAmB,EAAE,CAAC;QACzD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,IAAY,EAAE,IAAsB;QAC1D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC1C,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAC5D,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAC9D,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QACD,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,aAAa;QACX,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,MAAsB;QAC7C,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACtF,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,KAAkB;QACxC,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACpF,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,MAAwB;QACnD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3F,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import type { SyncFilterConfig } from "./types.js";
2
+ export declare const DEFAULT_SYNC_FILTER: SyncFilterConfig;
3
+ export declare const CLAUDEFY_DIR = ".claudefy";
4
+ export declare const CONFIG_FILE = "config.json";
5
+ export declare const LINKS_FILE = "links.json";
6
+ export declare const SYNC_FILTER_FILE = "sync-filter.json";
7
+ export declare const MACHINE_ID_FILE = "machine-id";
@@ -0,0 +1,33 @@
1
+ export const DEFAULT_SYNC_FILTER = {
2
+ allowlist: [
3
+ "commands",
4
+ "agents",
5
+ "skills",
6
+ "hooks",
7
+ "rules",
8
+ "plans",
9
+ "plugins",
10
+ "agent-memory",
11
+ "projects",
12
+ "settings.json",
13
+ "history.jsonl",
14
+ "package.json",
15
+ ],
16
+ denylist: [
17
+ "cache",
18
+ "backups",
19
+ "file-history",
20
+ "shell-snapshots",
21
+ "paste-cache",
22
+ "session-env",
23
+ "tasks",
24
+ ".credentials.json",
25
+ "mcp-needs-auth-cache.json",
26
+ ],
27
+ };
28
+ export const CLAUDEFY_DIR = ".claudefy";
29
+ export const CONFIG_FILE = "config.json";
30
+ export const LINKS_FILE = "links.json";
31
+ export const SYNC_FILTER_FILE = "sync-filter.json";
32
+ export const MACHINE_ID_FILE = "machine-id";
33
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,mBAAmB,GAAqB;IACnD,SAAS,EAAE;QACT,UAAU;QACV,QAAQ;QACR,QAAQ;QACR,OAAO;QACP,OAAO;QACP,OAAO;QACP,SAAS;QACT,cAAc;QACd,UAAU;QACV,eAAe;QACf,eAAe;QACf,cAAc;KACf;IACD,QAAQ,EAAE;QACR,OAAO;QACP,SAAS;QACT,cAAc;QACd,iBAAiB;QACjB,aAAa;QACb,aAAa;QACb,OAAO;QACP,mBAAmB;QACnB,2BAA2B;KAC5B;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;AACxC,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;AACzC,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC;AACvC,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AACnD,MAAM,CAAC,MAAM,eAAe,GAAG,YAAY,CAAC"}
@@ -0,0 +1,25 @@
1
+ export interface ClaudefyConfig {
2
+ version: number;
3
+ backend: {
4
+ type: "git";
5
+ url: string;
6
+ };
7
+ encryption: {
8
+ enabled: boolean;
9
+ useKeychain: boolean;
10
+ cacheDuration: string;
11
+ };
12
+ machineId: string;
13
+ }
14
+ export interface LinksConfig {
15
+ [alias: string]: {
16
+ localPath: string;
17
+ canonicalId: string;
18
+ gitRemote: string | null;
19
+ detectedAt: string;
20
+ };
21
+ }
22
+ export interface SyncFilterConfig {
23
+ allowlist: string[];
24
+ denylist: string[];
25
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ export declare class Encryptor {
2
+ private passphrase;
3
+ constructor(passphrase: string);
4
+ encryptFile(inputPath: string, outputPath: string): Promise<void>;
5
+ decryptFile(inputPath: string, outputPath: string): Promise<void>;
6
+ encryptString(input: string): Promise<string>;
7
+ decryptString(base64Input: string): Promise<string>;
8
+ encryptDirectory(dirPath: string): Promise<void>;
9
+ decryptDirectory(dirPath: string): Promise<void>;
10
+ }
@@ -0,0 +1,68 @@
1
+ import { Encrypter, Decrypter } from "age-encryption";
2
+ import { readFile, readdir, rm, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ export class Encryptor {
5
+ passphrase;
6
+ constructor(passphrase) {
7
+ this.passphrase = passphrase;
8
+ }
9
+ async encryptFile(inputPath, outputPath) {
10
+ const data = await readFile(inputPath);
11
+ const e = new Encrypter();
12
+ e.setPassphrase(this.passphrase);
13
+ const encrypted = await e.encrypt(data);
14
+ await writeFile(outputPath, encrypted);
15
+ }
16
+ async decryptFile(inputPath, outputPath) {
17
+ const data = await readFile(inputPath);
18
+ const d = new Decrypter();
19
+ d.addPassphrase(this.passphrase);
20
+ const decrypted = await d.decrypt(data, "uint8array");
21
+ await writeFile(outputPath, decrypted);
22
+ }
23
+ async encryptString(input) {
24
+ const e = new Encrypter();
25
+ e.setPassphrase(this.passphrase);
26
+ const encrypted = await e.encrypt(new TextEncoder().encode(input));
27
+ return Buffer.from(encrypted).toString("base64");
28
+ }
29
+ async decryptString(base64Input) {
30
+ const data = new Uint8Array(Buffer.from(base64Input, "base64"));
31
+ const d = new Decrypter();
32
+ d.addPassphrase(this.passphrase);
33
+ const decrypted = await d.decrypt(data, "uint8array");
34
+ return new TextDecoder().decode(decrypted);
35
+ }
36
+ async encryptDirectory(dirPath) {
37
+ const entries = await readdir(dirPath, { withFileTypes: true });
38
+ for (const entry of entries) {
39
+ if (entry.isSymbolicLink())
40
+ continue;
41
+ const fullPath = join(dirPath, entry.name);
42
+ if (entry.isDirectory()) {
43
+ await this.encryptDirectory(fullPath);
44
+ }
45
+ else if (!entry.name.endsWith(".age")) {
46
+ await this.encryptFile(fullPath, fullPath + ".age");
47
+ await rm(fullPath);
48
+ }
49
+ }
50
+ }
51
+ async decryptDirectory(dirPath) {
52
+ const entries = await readdir(dirPath, { withFileTypes: true });
53
+ for (const entry of entries) {
54
+ if (entry.isSymbolicLink())
55
+ continue;
56
+ const fullPath = join(dirPath, entry.name);
57
+ if (entry.isDirectory()) {
58
+ await this.decryptDirectory(fullPath);
59
+ }
60
+ else if (entry.name.endsWith(".age")) {
61
+ const outputPath = fullPath.replace(/\.age$/, "");
62
+ await this.decryptFile(fullPath, outputPath);
63
+ await rm(fullPath);
64
+ }
65
+ }
66
+ }
67
+ }
68
+ //# sourceMappingURL=encryptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryptor.js","sourceRoot":"","sources":["../../src/encryptor/encryptor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export type PassphraseSource = "env" | "keychain" | "prompt" | "none";
2
+ export interface PassphraseResult {
3
+ passphrase: string;
4
+ source: PassphraseSource;
5
+ }
6
+ export declare function resolvePassphrase(useKeychain: boolean): Promise<PassphraseResult | null>;
7
+ export declare function storePassphraseInKeychain(passphrase: string): Promise<boolean>;
@@ -0,0 +1,34 @@
1
+ import { env } from "node:process";
2
+ import { createRequire } from "node:module";
3
+ export async function resolvePassphrase(useKeychain) {
4
+ const envPassphrase = env.CLAUDEFY_PASSPHRASE;
5
+ if (envPassphrase) {
6
+ return { passphrase: envPassphrase, source: "env" };
7
+ }
8
+ if (useKeychain) {
9
+ try {
10
+ const require = createRequire(import.meta.url);
11
+ const keytar = require("keytar");
12
+ const stored = await keytar.getPassword("claudefy", "passphrase");
13
+ if (stored) {
14
+ return { passphrase: stored, source: "keychain" };
15
+ }
16
+ }
17
+ catch {
18
+ // keytar not available, fall through
19
+ }
20
+ }
21
+ return null;
22
+ }
23
+ export async function storePassphraseInKeychain(passphrase) {
24
+ try {
25
+ const require = createRequire(import.meta.url);
26
+ const keytar = require("keytar");
27
+ await keytar.setPassword("claudefy", "passphrase", passphrase);
28
+ return true;
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ //# sourceMappingURL=passphrase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passphrase.js","sourceRoot":"","sources":["../../src/encryptor/passphrase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAS5C,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,WAAoB;IAC1D,MAAM,aAAa,GAAG,GAAG,CAAC,mBAAmB,CAAC;IAC9C,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACtD,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;YACjC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;YAClE,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;YACpD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,qCAAqC;QACvC,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,UAAkB;IAChE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QACjC,MAAM,MAAM,CAAC,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,19 @@
1
+ export interface OverrideMarker {
2
+ machine: string;
3
+ timestamp: string;
4
+ }
5
+ export declare class GitAdapter {
6
+ private baseDir;
7
+ private storePath;
8
+ private git;
9
+ constructor(baseDir: string);
10
+ initStore(remoteUrl: string): Promise<void>;
11
+ commitAndPush(message: string): Promise<void>;
12
+ pull(): Promise<void>;
13
+ writeOverrideMarker(machineId: string): Promise<void>;
14
+ checkOverrideMarker(): Promise<OverrideMarker | null>;
15
+ removeOverrideMarker(): Promise<void>;
16
+ wipeAndPush(machineId: string): Promise<void>;
17
+ getStorePath(): string;
18
+ private ensureInitialized;
19
+ }
@@ -0,0 +1,104 @@
1
+ import { simpleGit } from "simple-git";
2
+ import { readFile, writeFile, rm, mkdir, readdir } from "node:fs/promises";
3
+ import { existsSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ export class GitAdapter {
6
+ baseDir;
7
+ storePath;
8
+ git = null;
9
+ constructor(baseDir) {
10
+ this.baseDir = baseDir;
11
+ this.storePath = join(baseDir, "store");
12
+ }
13
+ async initStore(remoteUrl) {
14
+ if (existsSync(this.storePath)) {
15
+ this.git = simpleGit(this.storePath);
16
+ return;
17
+ }
18
+ try {
19
+ await simpleGit(this.baseDir).clone(remoteUrl, "store");
20
+ }
21
+ catch (error) {
22
+ // Check if remote is empty (no refs) — only then initialize locally
23
+ const refs = await simpleGit(this.baseDir)
24
+ .listRemote([remoteUrl])
25
+ .catch(() => "");
26
+ if (refs.trim()) {
27
+ throw new Error(`Failed to clone non-empty remote '${remoteUrl}': ${error.message}`, { cause: error });
28
+ }
29
+ await mkdir(this.storePath, { recursive: true });
30
+ const git = simpleGit(this.storePath);
31
+ await git.init();
32
+ await git.addRemote("origin", remoteUrl);
33
+ await writeFile(join(this.storePath, ".gitkeep"), "");
34
+ await git.add(".").commit("initial claudefy store");
35
+ await git.push(["-u", "origin", "main"]);
36
+ }
37
+ this.git = simpleGit(this.storePath);
38
+ }
39
+ async commitAndPush(message) {
40
+ this.ensureInitialized();
41
+ await this.git.add(".");
42
+ const status = await this.git.status();
43
+ if (!status.isClean()) {
44
+ await this.git.commit(message);
45
+ await this.git.push();
46
+ }
47
+ }
48
+ async pull() {
49
+ this.ensureInitialized();
50
+ await this.git.pull();
51
+ }
52
+ async writeOverrideMarker(machineId) {
53
+ this.ensureInitialized();
54
+ const marker = {
55
+ machine: machineId,
56
+ timestamp: new Date().toISOString(),
57
+ };
58
+ await writeFile(join(this.storePath, ".override"), JSON.stringify(marker, null, 2));
59
+ }
60
+ async checkOverrideMarker() {
61
+ this.ensureInitialized();
62
+ const path = join(this.storePath, ".override");
63
+ if (!existsSync(path))
64
+ return null;
65
+ const content = await readFile(path, "utf-8");
66
+ try {
67
+ return JSON.parse(content);
68
+ }
69
+ catch (error) {
70
+ if (error instanceof SyntaxError)
71
+ return null;
72
+ throw error;
73
+ }
74
+ }
75
+ async removeOverrideMarker() {
76
+ this.ensureInitialized();
77
+ const path = join(this.storePath, ".override");
78
+ if (existsSync(path)) {
79
+ await rm(path);
80
+ }
81
+ }
82
+ async wipeAndPush(machineId) {
83
+ this.ensureInitialized();
84
+ const entries = await readdir(this.storePath);
85
+ for (const entry of entries) {
86
+ if (entry === ".git")
87
+ continue;
88
+ await rm(join(this.storePath, entry), { recursive: true, force: true });
89
+ }
90
+ await this.writeOverrideMarker(machineId);
91
+ await this.git.add(".");
92
+ await this.git.commit(`override: ${machineId} at ${new Date().toISOString()}`);
93
+ await this.git.push(["--force"]);
94
+ }
95
+ getStorePath() {
96
+ return this.storePath;
97
+ }
98
+ ensureInitialized() {
99
+ if (!this.git) {
100
+ throw new Error("GitAdapter not initialized. Call initStore() first.");
101
+ }
102
+ }
103
+ }
104
+ //# sourceMappingURL=git-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-adapter.js","sourceRoot":"","sources":["../../src/git-adapter/git-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface StoreStatus {
2
+ isClean: boolean;
3
+ ahead: number;
4
+ behind: number;
5
+ modified: string[];
6
+ added: string[];
7
+ deleted: string[];
8
+ }
9
+ export interface SyncMetadata {
10
+ machineId: string;
11
+ hostname: string;
12
+ os: string;
13
+ lastSync: string;
14
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/git-adapter/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ export declare class HookManager {
2
+ private settingsPath;
3
+ constructor(settingsPath: string);
4
+ install(): Promise<void>;
5
+ remove(): Promise<void>;
6
+ isInstalled(): Promise<boolean>;
7
+ private hasClaudefyHook;
8
+ private isClaudefyHookEntry;
9
+ private loadSettings;
10
+ private saveSettings;
11
+ }
@@ -0,0 +1,110 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { dirname } from "node:path";
3
+ export class HookManager {
4
+ settingsPath;
5
+ constructor(settingsPath) {
6
+ this.settingsPath = settingsPath;
7
+ }
8
+ async install() {
9
+ const settings = await this.loadSettings();
10
+ if (typeof settings.hooks !== "object" ||
11
+ settings.hooks === null ||
12
+ Array.isArray(settings.hooks)) {
13
+ settings.hooks = {};
14
+ }
15
+ // SessionStart -> pull
16
+ if (!Array.isArray(settings.hooks.SessionStart))
17
+ settings.hooks.SessionStart = [];
18
+ if (!this.hasClaudefyHook(settings.hooks.SessionStart)) {
19
+ settings.hooks.SessionStart.push({
20
+ hooks: [
21
+ {
22
+ type: "command",
23
+ command: "claudefy pull --quiet",
24
+ },
25
+ ],
26
+ });
27
+ }
28
+ // SessionEnd -> push
29
+ if (!Array.isArray(settings.hooks.SessionEnd))
30
+ settings.hooks.SessionEnd = [];
31
+ if (!this.hasClaudefyHook(settings.hooks.SessionEnd)) {
32
+ settings.hooks.SessionEnd.push({
33
+ hooks: [
34
+ {
35
+ type: "command",
36
+ command: "claudefy push --quiet",
37
+ },
38
+ ],
39
+ });
40
+ }
41
+ await this.saveSettings(settings);
42
+ }
43
+ async remove() {
44
+ const settings = await this.loadSettings();
45
+ if (settings.hooks) {
46
+ for (const event of Object.keys(settings.hooks)) {
47
+ if (!Array.isArray(settings.hooks[event]))
48
+ continue;
49
+ settings.hooks[event] = settings.hooks[event].filter((h) => !this.isClaudefyHookEntry(h));
50
+ if (settings.hooks[event].length === 0) {
51
+ delete settings.hooks[event];
52
+ }
53
+ }
54
+ if (Object.keys(settings.hooks).length === 0) {
55
+ delete settings.hooks;
56
+ }
57
+ }
58
+ await this.saveSettings(settings);
59
+ }
60
+ async isInstalled() {
61
+ const settings = await this.loadSettings();
62
+ if (!settings.hooks)
63
+ return false;
64
+ const startHooks = Array.isArray(settings.hooks.SessionStart)
65
+ ? settings.hooks.SessionStart
66
+ : [];
67
+ const endHooks = Array.isArray(settings.hooks.SessionEnd) ? settings.hooks.SessionEnd : [];
68
+ return this.hasClaudefyHook(startHooks) && this.hasClaudefyHook(endHooks);
69
+ }
70
+ hasClaudefyHook(hookArray) {
71
+ return hookArray.some((h) => this.isClaudefyHookEntry(h));
72
+ }
73
+ isClaudefyHookEntry(hookEntry) {
74
+ if (!Array.isArray(hookEntry.hooks))
75
+ return false;
76
+ return hookEntry.hooks.some((h) => {
77
+ const command = typeof h.command === "string" ? h.command.trim() : "";
78
+ return command.startsWith("claudefy pull") || command.startsWith("claudefy push");
79
+ });
80
+ }
81
+ async loadSettings() {
82
+ try {
83
+ const content = await readFile(this.settingsPath, "utf-8");
84
+ if (content.trim() === "")
85
+ return {};
86
+ try {
87
+ return JSON.parse(content);
88
+ }
89
+ catch (err) {
90
+ if (err instanceof SyntaxError) {
91
+ throw new Error(`Invalid JSON in settings file "${this.settingsPath}": ${err.message}`, {
92
+ cause: err,
93
+ });
94
+ }
95
+ throw err;
96
+ }
97
+ }
98
+ catch (err) {
99
+ if (err.code === "ENOENT") {
100
+ return {};
101
+ }
102
+ throw err;
103
+ }
104
+ }
105
+ async saveSettings(settings) {
106
+ await mkdir(dirname(this.settingsPath), { recursive: true });
107
+ await writeFile(this.settingsPath, JSON.stringify(settings, null, 2));
108
+ }
109
+ }
110
+ //# sourceMappingURL=hook-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-manager.js","sourceRoot":"","sources":["../../src/hook-manager/hook-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { program } from "./cli.js";
3
+ program.parse();
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface MachineEntry {
2
+ machineId: string;
3
+ hostname: string;
4
+ os: string;
5
+ lastSync: string;
6
+ registeredAt: string;
7
+ }
8
+ export declare class MachineRegistry {
9
+ private manifestPath;
10
+ constructor(manifestPath: string);
11
+ register(machineId: string, hostname: string, os: string): Promise<void>;
12
+ updateLastSync(machineId: string): Promise<void>;
13
+ list(): Promise<MachineEntry[]>;
14
+ private loadManifest;
15
+ private saveManifest;
16
+ }
@@ -0,0 +1,65 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { existsSync } from "node:fs";
3
+ import { dirname } from "node:path";
4
+ export class MachineRegistry {
5
+ manifestPath;
6
+ constructor(manifestPath) {
7
+ this.manifestPath = manifestPath;
8
+ }
9
+ async register(machineId, hostname, os) {
10
+ const manifest = await this.loadManifest();
11
+ const existing = manifest.machines.find((m) => m.machineId === machineId);
12
+ if (existing) {
13
+ existing.hostname = hostname;
14
+ existing.os = os;
15
+ existing.lastSync = new Date().toISOString();
16
+ }
17
+ else {
18
+ manifest.machines.push({
19
+ machineId,
20
+ hostname,
21
+ os,
22
+ lastSync: new Date().toISOString(),
23
+ registeredAt: new Date().toISOString(),
24
+ });
25
+ }
26
+ await this.saveManifest(manifest);
27
+ }
28
+ async updateLastSync(machineId) {
29
+ const manifest = await this.loadManifest();
30
+ const machine = manifest.machines.find((m) => m.machineId === machineId);
31
+ if (machine) {
32
+ machine.lastSync = new Date().toISOString();
33
+ await this.saveManifest(manifest);
34
+ }
35
+ }
36
+ async list() {
37
+ const manifest = await this.loadManifest();
38
+ return manifest.machines;
39
+ }
40
+ async loadManifest() {
41
+ if (!existsSync(this.manifestPath)) {
42
+ return { version: 1, machines: [] };
43
+ }
44
+ const raw = await readFile(this.manifestPath, "utf-8");
45
+ if (raw.trim() === "") {
46
+ return { version: 1, machines: [] };
47
+ }
48
+ try {
49
+ return JSON.parse(raw);
50
+ }
51
+ catch (err) {
52
+ if (err instanceof SyntaxError) {
53
+ throw new Error(`Invalid manifest JSON in "${this.manifestPath}": ${err.message}`, {
54
+ cause: err,
55
+ });
56
+ }
57
+ throw err;
58
+ }
59
+ }
60
+ async saveManifest(manifest) {
61
+ await mkdir(dirname(this.manifestPath), { recursive: true });
62
+ await writeFile(this.manifestPath, JSON.stringify(manifest, null, 2));
63
+ }
64
+ }
65
+ //# sourceMappingURL=machine-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-registry.js","sourceRoot":"","sources":["../../src/machine-registry/machine-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare class Merger {
2
+ deepMergeJson(local: Record<string, any>, remote: Record<string, any>): Record<string, any>;
3
+ lastWriteWins(local: {
4
+ content: string;
5
+ mtime: number;
6
+ }, remote: {
7
+ content: string;
8
+ mtime: number;
9
+ }): string;
10
+ }
@@ -0,0 +1,15 @@
1
+ import deepmerge from "deepmerge";
2
+ export class Merger {
3
+ deepMergeJson(local, remote) {
4
+ return deepmerge(local, remote, {
5
+ // Remote wins on array conflicts (replace, don't concatenate)
6
+ arrayMerge: (_target, source) => source,
7
+ });
8
+ }
9
+ lastWriteWins(local, remote) {
10
+ if (local.mtime > remote.mtime)
11
+ return local.content;
12
+ return remote.content;
13
+ }
14
+ }
15
+ //# sourceMappingURL=merger.js.map