omniwire 2.0.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 (90) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +316 -0
  3. package/dist/claude/integration.d.ts +12 -0
  4. package/dist/claude/integration.js +157 -0
  5. package/dist/claude/integration.js.map +1 -0
  6. package/dist/commands/browser.d.ts +2 -0
  7. package/dist/commands/browser.js +23 -0
  8. package/dist/commands/browser.js.map +1 -0
  9. package/dist/commands/builtins.d.ts +4 -0
  10. package/dist/commands/builtins.js +309 -0
  11. package/dist/commands/builtins.js.map +1 -0
  12. package/dist/commands/router.d.ts +2 -0
  13. package/dist/commands/router.js +174 -0
  14. package/dist/commands/router.js.map +1 -0
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.js +198 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/mcp/index.d.ts +2 -0
  19. package/dist/mcp/index.js +71 -0
  20. package/dist/mcp/index.js.map +1 -0
  21. package/dist/mcp/rest.d.ts +3 -0
  22. package/dist/mcp/rest.js +98 -0
  23. package/dist/mcp/rest.js.map +1 -0
  24. package/dist/mcp/server.d.ts +4 -0
  25. package/dist/mcp/server.js +419 -0
  26. package/dist/mcp/server.js.map +1 -0
  27. package/dist/mcp/sse.d.ts +2 -0
  28. package/dist/mcp/sse.js +43 -0
  29. package/dist/mcp/sse.js.map +1 -0
  30. package/dist/mcp/sync-tools.d.ts +5 -0
  31. package/dist/mcp/sync-tools.js +124 -0
  32. package/dist/mcp/sync-tools.js.map +1 -0
  33. package/dist/nodes/manager.d.ts +28 -0
  34. package/dist/nodes/manager.js +341 -0
  35. package/dist/nodes/manager.js.map +1 -0
  36. package/dist/nodes/realtime.d.ts +13 -0
  37. package/dist/nodes/realtime.js +46 -0
  38. package/dist/nodes/realtime.js.map +1 -0
  39. package/dist/nodes/shell.d.ts +17 -0
  40. package/dist/nodes/shell.js +137 -0
  41. package/dist/nodes/shell.js.map +1 -0
  42. package/dist/nodes/transfer.d.ts +22 -0
  43. package/dist/nodes/transfer.js +244 -0
  44. package/dist/nodes/transfer.js.map +1 -0
  45. package/dist/nodes/tunnel.d.ts +12 -0
  46. package/dist/nodes/tunnel.js +49 -0
  47. package/dist/nodes/tunnel.js.map +1 -0
  48. package/dist/protocol/config.d.ts +9 -0
  49. package/dist/protocol/config.js +133 -0
  50. package/dist/protocol/config.js.map +1 -0
  51. package/dist/protocol/paths.d.ts +3 -0
  52. package/dist/protocol/paths.js +19 -0
  53. package/dist/protocol/paths.js.map +1 -0
  54. package/dist/protocol/types.d.ts +106 -0
  55. package/dist/protocol/types.js +3 -0
  56. package/dist/protocol/types.js.map +1 -0
  57. package/dist/sync/db.d.ts +53 -0
  58. package/dist/sync/db.js +212 -0
  59. package/dist/sync/db.js.map +1 -0
  60. package/dist/sync/engine.d.ts +23 -0
  61. package/dist/sync/engine.js +251 -0
  62. package/dist/sync/engine.js.map +1 -0
  63. package/dist/sync/hasher.d.ts +2 -0
  64. package/dist/sync/hasher.js +25 -0
  65. package/dist/sync/hasher.js.map +1 -0
  66. package/dist/sync/index.d.ts +6 -0
  67. package/dist/sync/index.js +155 -0
  68. package/dist/sync/index.js.map +1 -0
  69. package/dist/sync/manifest.d.ts +4 -0
  70. package/dist/sync/manifest.js +105 -0
  71. package/dist/sync/manifest.js.map +1 -0
  72. package/dist/sync/memory-bridge.d.ts +7 -0
  73. package/dist/sync/memory-bridge.js +84 -0
  74. package/dist/sync/memory-bridge.js.map +1 -0
  75. package/dist/sync/paths.d.ts +6 -0
  76. package/dist/sync/paths.js +53 -0
  77. package/dist/sync/paths.js.map +1 -0
  78. package/dist/sync/schema.d.ts +2 -0
  79. package/dist/sync/schema.js +72 -0
  80. package/dist/sync/schema.js.map +1 -0
  81. package/dist/sync/types.d.ts +83 -0
  82. package/dist/sync/types.js +11 -0
  83. package/dist/sync/types.js.map +1 -0
  84. package/dist/sync/watcher.d.ts +21 -0
  85. package/dist/sync/watcher.js +87 -0
  86. package/dist/sync/watcher.js.map +1 -0
  87. package/dist/ui/format.d.ts +24 -0
  88. package/dist/ui/format.js +108 -0
  89. package/dist/ui/format.js.map +1 -0
  90. package/package.json +72 -0
@@ -0,0 +1,251 @@
1
+ // CyberSync — Sync engine: push, pull, reconcile, conflict resolution
2
+ //
3
+ // SECURITY NOTE: All remote command execution in this file uses NodeManager.exec()
4
+ // which routes through SSH2's client.exec() over authenticated, encrypted channels.
5
+ // No child_process.exec() is used anywhere in this file.
6
+ import { readFile, writeFile, mkdir, access, readdir } from 'node:fs/promises';
7
+ import { dirname, join } from 'node:path';
8
+ import picomatch from 'picomatch';
9
+ import { hashBuffer, hashFile } from './hasher.js';
10
+ import { categorizeFile } from './manifest.js';
11
+ import { adaptPathsForNode, getToolBaseDir, isJsonFile, normalizeRelPath } from './paths.js';
12
+ import { allNodes } from '../protocol/config.js';
13
+ const HASH_BATCH_SIZE = 50;
14
+ export class SyncEngine {
15
+ db;
16
+ config;
17
+ manager;
18
+ transfer;
19
+ constructor(db, config, manager, transfer) {
20
+ this.db = db;
21
+ this.config = config;
22
+ this.manager = manager;
23
+ this.transfer = transfer;
24
+ }
25
+ // Push a local file to the database
26
+ async pushFile(tool, relPath, absPath, opts) {
27
+ const data = await readFile(absPath);
28
+ const hash = hashBuffer(data);
29
+ const item = await this.db.upsertItem({
30
+ tool,
31
+ category: categorizeFile(relPath),
32
+ relPath,
33
+ contentHash: hash,
34
+ content: data,
35
+ contentSize: data.length,
36
+ metadata: {},
37
+ updatedByNode: this.config.nodeId,
38
+ });
39
+ await this.db.upsertNodeSync(this.config.nodeId, item.id, hash);
40
+ if (!opts?.skipRemotePush) {
41
+ await this.pushToRemoteNodes(item);
42
+ }
43
+ }
44
+ // Delete a file from the database
45
+ async deleteFile(tool, relPath) {
46
+ await this.db.markDeleted(tool, relPath, this.config.nodeId);
47
+ await this.db.logEvent(null, this.config.nodeId, 'delete', `Deleted ${tool}:${relPath}`);
48
+ }
49
+ // Pull pending items from DB to local filesystem
50
+ async pullPending() {
51
+ const pending = await this.db.getPendingItems(this.config.nodeId);
52
+ let pulled = 0;
53
+ for (const item of pending) {
54
+ if (!item.content)
55
+ continue;
56
+ // Skip .git internals and other non-syncable paths
57
+ if (shouldSkipPath(item.relPath))
58
+ continue;
59
+ const localNode = allNodes().find((n) => n.id === this.config.nodeId);
60
+ const os = localNode?.os ?? 'windows';
61
+ const baseDir = getToolBaseDir(item.tool, os);
62
+ const absPath = join(baseDir, item.relPath);
63
+ let content = item.content;
64
+ if (isJsonFile(item.relPath)) {
65
+ const text = content.toString('utf-8');
66
+ const adapted = adaptPathsForNode(text, os);
67
+ content = Buffer.from(adapted, 'utf-8');
68
+ }
69
+ try {
70
+ await mkdir(dirname(absPath), { recursive: true });
71
+ await writeFile(absPath, content);
72
+ }
73
+ catch {
74
+ // Permission denied or path issue, skip
75
+ continue;
76
+ }
77
+ await this.db.upsertNodeSync(this.config.nodeId, item.id, item.contentHash);
78
+ await this.db.logEvent(item.id, this.config.nodeId, 'pull', `Pulled ${item.relPath}`);
79
+ pulled++;
80
+ }
81
+ return pulled;
82
+ }
83
+ // Full reconciliation: scan all manifests, push new/changed, pull missing
84
+ async reconcile(manifests) {
85
+ let pushed = 0;
86
+ let conflicts = 0;
87
+ for (const manifest of manifests) {
88
+ try {
89
+ await access(manifest.baseDir);
90
+ }
91
+ catch {
92
+ continue;
93
+ }
94
+ const baseNormalized = manifest.baseDir.replaceAll('\\', '/');
95
+ let allFiles;
96
+ try {
97
+ allFiles = await walkDir(baseNormalized);
98
+ }
99
+ catch {
100
+ continue;
101
+ }
102
+ // Pre-compile glob matchers (picomatch is much faster than regex)
103
+ const isIncluded = picomatch(manifest.syncGlobs);
104
+ const isExcluded = manifest.excludeGlobs.length > 0
105
+ ? picomatch(manifest.excludeGlobs)
106
+ : () => false;
107
+ // Preload all existing items for this tool (1 query instead of N)
108
+ const existingItems = await this.db.getItemsByTool(manifest.tool);
109
+ const itemMap = new Map(existingItems.map((i) => [i.relPath, i]));
110
+ // Filter files first, then hash in parallel batches
111
+ const candidates = allFiles
112
+ .map((absPath) => ({
113
+ absPath,
114
+ relPath: normalizeRelPath(absPath.slice(baseNormalized.length + 1)),
115
+ }))
116
+ .filter(({ relPath }) => isIncluded(relPath) && !isExcluded(relPath));
117
+ // Parallel hashing in batches of HASH_BATCH_SIZE
118
+ for (let i = 0; i < candidates.length; i += HASH_BATCH_SIZE) {
119
+ const batch = candidates.slice(i, i + HASH_BATCH_SIZE);
120
+ const results = await Promise.allSettled(batch.map(async ({ absPath, relPath }) => {
121
+ const localHash = await hashFile(absPath);
122
+ return { absPath, relPath, localHash };
123
+ }));
124
+ for (const result of results) {
125
+ if (result.status === 'rejected')
126
+ continue;
127
+ const { absPath, relPath, localHash } = result.value;
128
+ const existing = itemMap.get(relPath);
129
+ if (!existing) {
130
+ await this.pushFile(manifest.tool, relPath, absPath, { skipRemotePush: true });
131
+ pushed++;
132
+ }
133
+ else if (existing.contentHash !== localHash) {
134
+ // Node-ownership conflict resolution:
135
+ // - We own it (last updated by us) → push
136
+ // - Remote owns it and is newer → skip (will be pulled)
137
+ // - True conflict → log and defer to remote (safer)
138
+ if (existing.updatedByNode === this.config.nodeId) {
139
+ await this.pushFile(manifest.tool, relPath, absPath, { skipRemotePush: true });
140
+ pushed++;
141
+ }
142
+ else {
143
+ conflicts++;
144
+ await this.db.logEvent(existing.id, this.config.nodeId, 'conflict', `Diverged: ${relPath} (local=${localHash.slice(0, 8)}, remote=${existing.contentHash.slice(0, 8)}, owner=${existing.updatedByNode})`);
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
150
+ const pulled = await this.pullPending();
151
+ const allItems = await this.db.getAllItems();
152
+ const pendingItems = await this.db.getPendingItems(this.config.nodeId);
153
+ await this.db.heartbeat(this.config.nodeId, allItems.length, pendingItems.length);
154
+ // Prune old events periodically
155
+ await this.db.pruneEvents(5000);
156
+ await this.db.logEvent(null, this.config.nodeId, 'reconcile', `Reconciled: pushed=${pushed}, pulled=${pulled}, conflicts=${conflicts}`);
157
+ return { pushed, pulled, conflicts };
158
+ }
159
+ // Get diff between local and DB
160
+ async getDiff(manifests) {
161
+ const diffs = [];
162
+ const dbItems = await this.db.getAllItems();
163
+ for (const item of dbItems) {
164
+ const localNode = allNodes().find((n) => n.id === this.config.nodeId);
165
+ const os = localNode?.os ?? 'windows';
166
+ const baseDir = getToolBaseDir(item.tool, os);
167
+ const absPath = join(baseDir, item.relPath);
168
+ let localHash = null;
169
+ try {
170
+ localHash = await hashFile(absPath);
171
+ }
172
+ catch {
173
+ // File doesn't exist locally
174
+ }
175
+ if (localHash !== item.contentHash) {
176
+ diffs.push({
177
+ itemId: item.id,
178
+ relPath: item.relPath,
179
+ tool: item.tool,
180
+ localHash,
181
+ remoteHash: item.contentHash,
182
+ direction: localHash === null ? 'pull' : item.updatedByNode === this.config.nodeId ? 'push' : 'conflict',
183
+ });
184
+ }
185
+ }
186
+ return diffs;
187
+ }
188
+ // Push item content to online remote nodes in parallel via SSH2 + TransferEngine
189
+ async pushToRemoteNodes(item) {
190
+ if (!item.content)
191
+ return;
192
+ const onlineNodes = this.manager.getOnlineNodes().filter((id) => id !== this.config.nodeId);
193
+ await Promise.allSettled(onlineNodes.map(async (nodeId) => {
194
+ try {
195
+ const node = allNodes().find((n) => n.id === nodeId);
196
+ if (!node)
197
+ return;
198
+ const baseDir = getToolBaseDir(item.tool, node.os);
199
+ const remotePath = `${baseDir}/${item.relPath}`;
200
+ let content = item.content.toString('utf-8');
201
+ if (isJsonFile(item.relPath)) {
202
+ content = adaptPathsForNode(content, node.os);
203
+ }
204
+ // Write file via TransferEngine (SFTP or base64 fallback)
205
+ await this.transfer.writeFile(nodeId, remotePath, content);
206
+ await this.db.upsertNodeSync(nodeId, item.id, item.contentHash);
207
+ }
208
+ catch {
209
+ await this.db.logEvent(item.id, nodeId, 'error', `Failed to push ${item.relPath} to ${nodeId}`);
210
+ }
211
+ }));
212
+ }
213
+ }
214
+ // Paths containing these segments should never be synced
215
+ const SKIP_SEGMENTS = ['.git/', 'node_modules/', '.cache/', '__pycache__/'];
216
+ function shouldSkipPath(relPath) {
217
+ const normalized = relPath.replaceAll('\\', '/');
218
+ return SKIP_SEGMENTS.some((seg) => normalized.includes(seg) || normalized.startsWith(seg.slice(0, -1)));
219
+ }
220
+ // Recursively walk a directory, returning all file paths (normalized with /)
221
+ const SKIP_DIRS = new Set(['.git', 'node_modules', '.cache', '__pycache__', '.DS_Store']);
222
+ async function walkDir(dir) {
223
+ const results = [];
224
+ let entries;
225
+ try {
226
+ entries = await readdir(dir, { withFileTypes: true });
227
+ }
228
+ catch {
229
+ return results;
230
+ }
231
+ for (const entry of entries) {
232
+ if (SKIP_DIRS.has(entry.name))
233
+ continue;
234
+ const fullPath = `${dir}/${entry.name}`;
235
+ try {
236
+ if (entry.isDirectory()) {
237
+ const sub = await walkDir(fullPath);
238
+ results.push(...sub);
239
+ }
240
+ else if (entry.isFile()) {
241
+ results.push(fullPath.replaceAll('\\', '/'));
242
+ }
243
+ }
244
+ catch {
245
+ // Permission denied or broken symlink, skip
246
+ }
247
+ }
248
+ return results;
249
+ }
250
+ // matchesAnyGlob/globMatch replaced by picomatch (pre-compiled in reconcile)
251
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/sync/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function hashBuffer(data: Buffer): string;
2
+ export declare function hashFile(filePath: string): Promise<string>;
@@ -0,0 +1,25 @@
1
+ // CyberSync — SHA-256 content hashing (streaming for large files)
2
+ import { createHash } from 'node:crypto';
3
+ import { readFile, stat } from 'node:fs/promises';
4
+ import { createReadStream } from 'node:fs';
5
+ const STREAM_THRESHOLD = 1_048_576; // 1MB — stream hash above this
6
+ export function hashBuffer(data) {
7
+ return createHash('sha256').update(data).digest('hex');
8
+ }
9
+ export async function hashFile(filePath) {
10
+ const info = await stat(filePath);
11
+ // Small files: buffer hash (faster for <1MB, single syscall)
12
+ if (info.size < STREAM_THRESHOLD) {
13
+ const data = await readFile(filePath);
14
+ return hashBuffer(data);
15
+ }
16
+ // Large files: streaming hash (constant memory)
17
+ return new Promise((resolve, reject) => {
18
+ const hash = createHash('sha256');
19
+ const stream = createReadStream(filePath);
20
+ stream.on('data', (chunk) => hash.update(chunk));
21
+ stream.on('end', () => resolve(hash.digest('hex')));
22
+ stream.on('error', reject);
23
+ });
24
+ }
25
+ //# sourceMappingURL=hasher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasher.js","sourceRoot":"","sources":["../../src/sync/hasher.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAElE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C,MAAM,gBAAgB,GAAG,SAAS,CAAC,CAAC,+BAA+B;AAEnE,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB;IAC7C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;IAElC,6DAA6D;IAC7D,IAAI,IAAI,CAAC,IAAI,GAAG,gBAAgB,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACtC,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,gDAAgD;IAChD,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC7C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAC1C,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAsB,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAClE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { SyncDB } from './db.js';
2
+ export { SyncEngine } from './engine.js';
3
+ export { MemoryBridge } from './memory-bridge.js';
4
+ export { getManifests } from './manifest.js';
5
+ export type { SyncConfig } from './types.js';
6
+ export { DEFAULT_SYNC_CONFIG } from './types.js';
@@ -0,0 +1,155 @@
1
+ // CyberSync — Daemon entrypoint
2
+ // Watches tool directories, syncs to PostgreSQL, bridges memory.db
3
+ //
4
+ // Usage:
5
+ // node dist/sync/index.js --node windows # run daemon
6
+ // node dist/sync/index.js --node windows --once # single reconcile
7
+ // node dist/sync/index.js --node windows --ingest-only # memory.db only
8
+ import { SyncDB } from './db.js';
9
+ import { SyncEngine } from './engine.js';
10
+ import { SyncWatcher } from './watcher.js';
11
+ import { MemoryBridge } from './memory-bridge.js';
12
+ import { getManifests } from './manifest.js';
13
+ import { NodeManager } from '../nodes/manager.js';
14
+ import { TransferEngine } from '../nodes/transfer.js';
15
+ import { allNodes } from '../protocol/config.js';
16
+ import { DEFAULT_SYNC_CONFIG } from './types.js';
17
+ function parseArgs(argv) {
18
+ const nodeIdx = argv.indexOf('--node');
19
+ const nodeId = nodeIdx !== -1 && argv[nodeIdx + 1] ? argv[nodeIdx + 1] : detectNodeId();
20
+ const once = argv.includes('--once');
21
+ const ingestOnly = argv.includes('--ingest-only');
22
+ return { nodeId, once, ingestOnly };
23
+ }
24
+ function detectNodeId() {
25
+ if (process.platform === 'win32')
26
+ return 'windows';
27
+ return process.env.OMNIWIRE_NODE_ID ?? process.env.HOSTNAME ?? 'local';
28
+ }
29
+ async function main() {
30
+ const { nodeId, once, ingestOnly } = parseArgs(process.argv.slice(2));
31
+ const node = allNodes().find((n) => n.id === nodeId);
32
+ if (!node) {
33
+ process.stderr.write(`Unknown node: ${nodeId}\n`);
34
+ process.exit(1);
35
+ }
36
+ const config = { ...DEFAULT_SYNC_CONFIG, nodeId };
37
+ process.stderr.write(`CyberSync starting on ${nodeId} (${node.os})\n`);
38
+ // Connect to PostgreSQL
39
+ const db = new SyncDB(config);
40
+ await db.init();
41
+ process.stderr.write(`PostgreSQL connected (${config.pgHost}:${config.pgPort}/${config.pgDatabase})\n`);
42
+ // Connect mesh nodes
43
+ const manager = new NodeManager();
44
+ await manager.connectAll();
45
+ const transferEngine = new TransferEngine(manager);
46
+ const os = node.os;
47
+ const manifests = getManifests(os);
48
+ // Memory bridge (SQLite -> PostgreSQL)
49
+ const bridge = new MemoryBridge(db, nodeId);
50
+ if (ingestOnly) {
51
+ const claudeManifest = manifests.find((m) => m.tool === 'claude-code');
52
+ if (claudeManifest?.ingestDb) {
53
+ const count = await bridge.ingest(claudeManifest.ingestDb);
54
+ process.stderr.write(`Ingested ${count} memory entries\n`);
55
+ }
56
+ await db.close();
57
+ manager.disconnect();
58
+ return;
59
+ }
60
+ // Sync engine
61
+ const engine = new SyncEngine(db, config, manager, transferEngine);
62
+ if (once) {
63
+ // Single reconciliation pass
64
+ const result = await engine.reconcile(manifests);
65
+ process.stderr.write(`Reconcile: pushed=${result.pushed}, pulled=${result.pulled}, conflicts=${result.conflicts}\n`);
66
+ // Also ingest memory.db
67
+ const claudeManifest = manifests.find((m) => m.tool === 'claude-code');
68
+ if (claudeManifest?.ingestDb) {
69
+ const count = await bridge.ingest(claudeManifest.ingestDb);
70
+ process.stderr.write(`Ingested ${count} memory entries\n`);
71
+ }
72
+ await db.close();
73
+ manager.disconnect();
74
+ return;
75
+ }
76
+ // Daemon mode: watcher + periodic reconcile
77
+ const watcher = new SyncWatcher(manifests, config.watchDebounceMs, async (event) => {
78
+ try {
79
+ if (event.type === 'unlink') {
80
+ await engine.deleteFile(event.tool, event.relPath);
81
+ process.stderr.write(`[sync] deleted ${event.tool}:${event.relPath}\n`);
82
+ }
83
+ else {
84
+ await engine.pushFile(event.tool, event.relPath, event.absPath);
85
+ process.stderr.write(`[sync] pushed ${event.tool}:${event.relPath}\n`);
86
+ }
87
+ }
88
+ catch (err) {
89
+ process.stderr.write(`[sync] error: ${err.message}\n`);
90
+ }
91
+ });
92
+ watcher.start();
93
+ process.stderr.write(`Watchers started for ${manifests.filter((m) => m.syncGlobs.length > 0).length} tools\n`);
94
+ // Initial reconcile
95
+ const initial = await engine.reconcile(manifests);
96
+ process.stderr.write(`Initial reconcile: pushed=${initial.pushed}, pulled=${initial.pulled}, conflicts=${initial.conflicts}\n`);
97
+ // Ingest memory.db on startup
98
+ const claudeManifest = manifests.find((m) => m.tool === 'claude-code');
99
+ if (claudeManifest?.ingestDb) {
100
+ const count = await bridge.ingest(claudeManifest.ingestDb);
101
+ process.stderr.write(`Ingested ${count} memory entries\n`);
102
+ }
103
+ // Periodic reconciliation
104
+ const reconcileInterval = setInterval(async () => {
105
+ try {
106
+ const result = await engine.reconcile(manifests);
107
+ if (result.pushed > 0 || result.pulled > 0 || result.conflicts > 0) {
108
+ process.stderr.write(`[reconcile] pushed=${result.pushed}, pulled=${result.pulled}, conflicts=${result.conflicts}\n`);
109
+ }
110
+ // heartbeat is already updated inside engine.reconcile() with real counts
111
+ }
112
+ catch (err) {
113
+ process.stderr.write(`[reconcile] error: ${err.message}\n`);
114
+ }
115
+ }, config.reconcileIntervalMs);
116
+ // Periodic memory.db ingestion (every 15 min)
117
+ const memoryInterval = setInterval(async () => {
118
+ if (claudeManifest?.ingestDb) {
119
+ try {
120
+ await bridge.ingest(claudeManifest.ingestDb);
121
+ }
122
+ catch {
123
+ // Silent fail for memory ingestion
124
+ }
125
+ }
126
+ }, 15 * 60 * 1000);
127
+ // Graceful shutdown
128
+ const shutdown = async () => {
129
+ process.stderr.write('CyberSync shutting down...\n');
130
+ clearInterval(reconcileInterval);
131
+ clearInterval(memoryInterval);
132
+ await watcher.stop();
133
+ await db.close();
134
+ manager.disconnect();
135
+ process.exit(0);
136
+ };
137
+ process.on('SIGINT', shutdown);
138
+ process.on('SIGTERM', shutdown);
139
+ process.stderr.write(`CyberSync daemon running (reconcile every ${config.reconcileIntervalMs / 1000}s)\n`);
140
+ }
141
+ // Export engine creation for MCP tools
142
+ export { SyncDB } from './db.js';
143
+ export { SyncEngine } from './engine.js';
144
+ export { MemoryBridge } from './memory-bridge.js';
145
+ export { getManifests } from './manifest.js';
146
+ export { DEFAULT_SYNC_CONFIG } from './types.js';
147
+ // Run if executed directly
148
+ const isDirectRun = process.argv[1]?.endsWith('sync/index.js') || process.argv[1]?.endsWith('sync\\index.js');
149
+ if (isDirectRun) {
150
+ main().catch((err) => {
151
+ process.stderr.write(`Fatal: ${err.message}\n`);
152
+ process.exit(1);
153
+ });
154
+ }
155
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ToolManifest, ToolName } from './types.js';
2
+ export declare function getManifests(os: 'windows' | 'linux'): readonly ToolManifest[];
3
+ export declare function categorizeFile(relPath: string): string;
4
+ export declare const ALL_TOOLS: readonly ToolName[];
@@ -0,0 +1,105 @@
1
+ // CyberSync — Tool manifests defining what to sync per AI tool
2
+ import { getToolBaseDir } from './paths.js';
3
+ function manifest(tool, os, sync, exclude, ingestDb) {
4
+ return {
5
+ tool,
6
+ baseDir: getToolBaseDir(tool, os),
7
+ syncGlobs: sync,
8
+ excludeGlobs: exclude,
9
+ ingestDb,
10
+ };
11
+ }
12
+ export function getManifests(os) {
13
+ const home = os === 'windows'
14
+ ? (process.env.USERPROFILE ?? process.env.HOME ?? '').replaceAll('\\', '/')
15
+ : (process.env.HOME ?? '/root');
16
+ return [
17
+ manifest('claude-code', os, [
18
+ 'agents/**/*.md',
19
+ 'skills/**/*',
20
+ 'commands/**/*.md',
21
+ 'rules/**/*.md',
22
+ 'hooks/**/*',
23
+ 'plugins/**/*.json',
24
+ 'memory/**/*',
25
+ 'settings.json',
26
+ 'settings.local.json',
27
+ 'keybindings.json',
28
+ 'CLAUDE.md',
29
+ 'scripts/**/*',
30
+ ], [
31
+ '.credentials.json',
32
+ 'history.jsonl',
33
+ 'logs/**',
34
+ 'cache/**',
35
+ 'sessions/**',
36
+ 'session-env/**',
37
+ 'file-history/**',
38
+ 'paste-cache/**',
39
+ 'downloads/**',
40
+ 'backups/**',
41
+ 'telemetry/**',
42
+ 'security_warnings_*',
43
+ 'shell-snapshots/**',
44
+ 'plans/**',
45
+ 'projects/**',
46
+ ], `${home}/.claude/memory.db`),
47
+ manifest('opencode', os, [
48
+ 'opencode.json',
49
+ 'oh-my-opencode.json',
50
+ 'package.json',
51
+ '.gitignore',
52
+ 'skills/**/*',
53
+ 'agents/**/*',
54
+ 'teams/**/*',
55
+ ], [
56
+ 'node_modules/**',
57
+ 'bun.lock',
58
+ ]),
59
+ manifest('openclaw', os, [
60
+ 'agents/**/*',
61
+ 'memory/**/*',
62
+ 'workspace/**/*',
63
+ 'openclaw.json',
64
+ 'identity/**/*',
65
+ 'cron/**/*',
66
+ ], [
67
+ 'gateway.log',
68
+ 'update-check.json',
69
+ 'canvas/**',
70
+ 'telegram/**',
71
+ 'devices/**',
72
+ ]),
73
+ manifest('codex', os, [
74
+ 'config.toml',
75
+ 'AGENTS.md',
76
+ 'skills/**/*',
77
+ 'memories/**/*',
78
+ ], []),
79
+ manifest('gemini', os, [
80
+ 'settings.json',
81
+ 'projects.json',
82
+ ], []),
83
+ manifest('paperclip', os, [
84
+ 'config.json',
85
+ 'agents/**/*',
86
+ ], []),
87
+ ];
88
+ }
89
+ export function categorizeFile(relPath) {
90
+ const parts = relPath.split('/');
91
+ if (parts.length > 1)
92
+ return parts[0];
93
+ const ext = relPath.split('.').pop()?.toLowerCase() ?? '';
94
+ if (ext === 'json' || ext === 'jsonc')
95
+ return 'config';
96
+ if (ext === 'md')
97
+ return 'docs';
98
+ if (ext === 'toml' || ext === 'yaml' || ext === 'yml')
99
+ return 'config';
100
+ return 'other';
101
+ }
102
+ export const ALL_TOOLS = [
103
+ 'claude-code', 'opencode', 'openclaw', 'codex', 'gemini', 'paperclip',
104
+ ];
105
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/sync/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { SyncDB } from './db.js';
2
+ export declare class MemoryBridge {
3
+ private db;
4
+ private nodeId;
5
+ constructor(db: SyncDB, nodeId: string);
6
+ ingest(dbPath: string): Promise<number>;
7
+ }