borgmcp 0.2.0-beta.1
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 +250 -0
- package/dist/auth.d.ts +24 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +223 -0
- package/dist/auth.js.map +1 -0
- package/dist/config-utils.d.ts +17 -0
- package/dist/config-utils.d.ts.map +1 -0
- package/dist/config-utils.js +54 -0
- package/dist/config-utils.js.map +1 -0
- package/dist/config.d.ts +33 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +65 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +157 -0
- package/dist/index.js.map +1 -0
- package/dist/postinstall.d.ts +9 -0
- package/dist/postinstall.d.ts.map +1 -0
- package/dist/postinstall.js +19 -0
- package/dist/postinstall.js.map +1 -0
- package/dist/remote-client.d.ts +27 -0
- package/dist/remote-client.d.ts.map +1 -0
- package/dist/remote-client.js +165 -0
- package/dist/remote-client.js.map +1 -0
- package/dist/setup.d.ts +11 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +196 -0
- package/dist/setup.js.map +1 -0
- package/dist/sync.d.ts +57 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +196 -0
- package/dist/sync.js.map +1 -0
- package/dist/types.d.ts +37 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +62 -0
package/dist/setup.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Borg MCP Setup Wizard
|
|
4
|
+
*
|
|
5
|
+
* Interactive setup flow:
|
|
6
|
+
* 1. Configure Claude Code MCP settings
|
|
7
|
+
* 2. Google OAuth authentication
|
|
8
|
+
* 3. Subscription setup (web dashboard or Stripe)
|
|
9
|
+
*/
|
|
10
|
+
import prompts from 'prompts';
|
|
11
|
+
import chalk from 'chalk';
|
|
12
|
+
import open from 'open';
|
|
13
|
+
import which from 'which';
|
|
14
|
+
import { authenticateWithGoogle } from './auth.js';
|
|
15
|
+
import { checkSubscriptionStatus, createSubscription } from './remote-client.js';
|
|
16
|
+
import { addMcpServer } from './config-utils.js';
|
|
17
|
+
import { isAuthenticated } from './config.js';
|
|
18
|
+
/**
|
|
19
|
+
* Main setup wizard
|
|
20
|
+
*/
|
|
21
|
+
async function main() {
|
|
22
|
+
console.log(chalk.blue.bold('\nš§ Borg MCP Setup Wizard'));
|
|
23
|
+
console.log(chalk.blue('ā'.repeat(40)) + '\n');
|
|
24
|
+
// Step 0: Check if Claude CLI exists
|
|
25
|
+
let claudeCliPath;
|
|
26
|
+
try {
|
|
27
|
+
claudeCliPath = which.sync('claude');
|
|
28
|
+
console.log(chalk.gray(`Found Claude CLI: ${claudeCliPath}\n`));
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error(chalk.red('ā Claude CLI not found\n'));
|
|
32
|
+
console.error(chalk.yellow('Please install Claude Code first:'));
|
|
33
|
+
console.error(chalk.gray(' https://claude.ai/download\n'));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
// Step 1: MCP Configuration
|
|
37
|
+
console.log(chalk.blue('š¦ MCP Server Configuration'));
|
|
38
|
+
const { confirmConfig } = await prompts({
|
|
39
|
+
type: 'confirm',
|
|
40
|
+
name: 'confirmConfig',
|
|
41
|
+
message: 'Add borgmcp to Claude Code?',
|
|
42
|
+
initial: true
|
|
43
|
+
});
|
|
44
|
+
if (!confirmConfig) {
|
|
45
|
+
console.log(chalk.red('\nā Setup cancelled\n'));
|
|
46
|
+
process.exit(0);
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
addMcpServer();
|
|
50
|
+
console.log(chalk.green('ā borgmcp added to Claude Code\n'));
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error(chalk.red(`\nā Failed to add MCP server: ${error.message}\n`));
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
// Step 2: Authentication
|
|
57
|
+
console.log(chalk.blue('š Google Authentication'));
|
|
58
|
+
const authed = await isAuthenticated();
|
|
59
|
+
if (!authed) {
|
|
60
|
+
try {
|
|
61
|
+
await authenticateWithGoogle();
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error(chalk.red(`\nā Authentication failed: ${error.message}\n`));
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
console.log(chalk.green('ā Already authenticated\n'));
|
|
70
|
+
}
|
|
71
|
+
// Step 3: Subscription
|
|
72
|
+
console.log(chalk.blue('š³ Subscription Check'));
|
|
73
|
+
let status;
|
|
74
|
+
try {
|
|
75
|
+
status = await checkSubscriptionStatus();
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
console.error(chalk.red(`\nā Failed to check subscription: ${error.message}\n`));
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
if (!status.hasAccess) {
|
|
82
|
+
console.log(chalk.yellow('ā No active subscription found'));
|
|
83
|
+
console.log(chalk.gray('š° $2/month with 7-day free trial\n'));
|
|
84
|
+
const { subscribeMethod } = await prompts({
|
|
85
|
+
type: 'select',
|
|
86
|
+
name: 'subscribeMethod',
|
|
87
|
+
message: 'How would you like to subscribe?',
|
|
88
|
+
choices: [
|
|
89
|
+
{
|
|
90
|
+
title: 'š Open web dashboard (recommended)',
|
|
91
|
+
value: 'web',
|
|
92
|
+
description: 'Full onboarding experience with features & pricing'
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
title: 'ā” Quick Stripe checkout',
|
|
96
|
+
value: 'stripe',
|
|
97
|
+
description: 'Fast checkout in browser'
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
title: 'ā I already subscribed',
|
|
101
|
+
value: 'recheck',
|
|
102
|
+
description: 'Check subscription status again'
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
title: 'ā Skip for now',
|
|
106
|
+
value: 'skip',
|
|
107
|
+
description: 'Tools will not work until you subscribe'
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
});
|
|
111
|
+
switch (subscribeMethod) {
|
|
112
|
+
case 'web':
|
|
113
|
+
console.log(chalk.blue('\nš Opening: https://borgmcp.ai/subscribe'));
|
|
114
|
+
try {
|
|
115
|
+
await open('https://borgmcp.ai/subscribe');
|
|
116
|
+
console.log(chalk.gray('ā³ Waiting for subscription (checking every 5s for 2 min)...\n'));
|
|
117
|
+
await pollForSubscription();
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
console.error(chalk.yellow(`\nā ${error.message}`));
|
|
121
|
+
}
|
|
122
|
+
break;
|
|
123
|
+
case 'stripe':
|
|
124
|
+
try {
|
|
125
|
+
const checkoutUrl = await createSubscription();
|
|
126
|
+
console.log(chalk.blue(`\nā” Opening Stripe: ${checkoutUrl}`));
|
|
127
|
+
await open(checkoutUrl);
|
|
128
|
+
console.log(chalk.gray('ā³ Waiting for subscription...\n'));
|
|
129
|
+
await pollForSubscription();
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
console.error(chalk.red(`\nā Failed to create checkout: ${error.message}\n`));
|
|
133
|
+
}
|
|
134
|
+
break;
|
|
135
|
+
case 'recheck':
|
|
136
|
+
try {
|
|
137
|
+
const recheckStatus = await checkSubscriptionStatus();
|
|
138
|
+
if (recheckStatus.hasAccess) {
|
|
139
|
+
console.log(chalk.green('\nā Subscription found!\n'));
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
console.log(chalk.yellow('\nā No subscription found\n'));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
console.error(chalk.red(`\nā Failed to recheck: ${error.message}\n`));
|
|
147
|
+
}
|
|
148
|
+
break;
|
|
149
|
+
case 'skip':
|
|
150
|
+
console.log(chalk.yellow('\nā Skipped subscription - tools will not work until you subscribe\n'));
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
console.log(chalk.green('ā Active subscription found'));
|
|
156
|
+
if (status.expiresAt) {
|
|
157
|
+
const expiresAt = new Date(status.expiresAt);
|
|
158
|
+
console.log(chalk.gray(` Expires: ${expiresAt.toLocaleDateString()}\n`));
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
console.log('');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Success message
|
|
165
|
+
console.log(chalk.green.bold('š Setup complete!\n'));
|
|
166
|
+
console.log(chalk.gray('Next steps:'));
|
|
167
|
+
console.log(chalk.gray('1. Use borg:regen tool in Claude Code'));
|
|
168
|
+
console.log(chalk.gray('2. Manage context at: https://borgmcp.ai/dashboard\n'));
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Poll for subscription activation
|
|
172
|
+
* Checks every 5 seconds for 2 minutes (24 attempts)
|
|
173
|
+
*/
|
|
174
|
+
async function pollForSubscription() {
|
|
175
|
+
const maxAttempts = 24;
|
|
176
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
177
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
178
|
+
try {
|
|
179
|
+
const status = await checkSubscriptionStatus();
|
|
180
|
+
if (status.hasAccess) {
|
|
181
|
+
console.log(chalk.green('ā Subscription activated!\n'));
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
// Continue polling even on errors
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
throw new Error('Timeout - Run setup again after subscribing');
|
|
190
|
+
}
|
|
191
|
+
// Run wizard
|
|
192
|
+
main().catch((error) => {
|
|
193
|
+
console.error(chalk.red(`\nā Setup failed: ${error.message}\n`));
|
|
194
|
+
process.exit(1);
|
|
195
|
+
});
|
|
196
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
|
package/dist/sync.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File sync logic with conflict detection
|
|
3
|
+
*
|
|
4
|
+
* Addresses consensus finding: Last-write-wins causes silent data loss
|
|
5
|
+
* Solution: Track both local and remote timestamps, detect conflicts explicitly
|
|
6
|
+
*/
|
|
7
|
+
import type { FileMetadata, ConflictInfo } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Calculate SHA-256 hash of file content
|
|
10
|
+
*/
|
|
11
|
+
export declare function hashContent(content: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Load sync metadata from disk
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadMetadata(): Promise<FileMetadata | null>;
|
|
16
|
+
/**
|
|
17
|
+
* Save sync metadata to disk
|
|
18
|
+
*/
|
|
19
|
+
export declare function saveMetadata(metadata: FileMetadata): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Read local CLAUDE.md file
|
|
22
|
+
*/
|
|
23
|
+
export declare function readLocalFile(): Promise<string | null>;
|
|
24
|
+
/**
|
|
25
|
+
* Write content to local CLAUDE.md file
|
|
26
|
+
*/
|
|
27
|
+
export declare function writeLocalFile(content: string): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Get local file modification time
|
|
30
|
+
*/
|
|
31
|
+
export declare function getLocalMtime(): Promise<number | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Detect if there's a sync conflict
|
|
34
|
+
*
|
|
35
|
+
* Conflict occurs when:
|
|
36
|
+
* 1. Both local and remote have changed since last sync
|
|
37
|
+
* 2. Changes are different (different content hashes)
|
|
38
|
+
*/
|
|
39
|
+
export declare function detectConflict(localContent: string, remoteContent: string, metadata: FileMetadata | null): Promise<ConflictInfo | null>;
|
|
40
|
+
/**
|
|
41
|
+
* Handle sync conflict by creating a conflict file
|
|
42
|
+
*
|
|
43
|
+
* Strategy: Create CLAUDE.md.conflict with remote content
|
|
44
|
+
* Keep local file unchanged, let user resolve manually
|
|
45
|
+
*/
|
|
46
|
+
export declare function handleConflict(conflict: ConflictInfo): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Determine sync action based on file states
|
|
49
|
+
*
|
|
50
|
+
* Returns: 'push' | 'pull' | 'conflict' | 'skip'
|
|
51
|
+
*/
|
|
52
|
+
export declare function determineSyncAction(localContent: string | null, remoteContent: string | null, metadata: FileMetadata | null): Promise<'push' | 'pull' | 'conflict' | 'skip'>;
|
|
53
|
+
/**
|
|
54
|
+
* Update metadata after successful sync
|
|
55
|
+
*/
|
|
56
|
+
export declare function updateMetadataAfterSync(content: string): Promise<void>;
|
|
57
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAK7D;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAUD;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAUjE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAGxE;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAS5D;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAInE;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAU5D;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,YAAY,GAAG,IAAI,GAC5B,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAgC9B;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAc1E;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,QAAQ,EAAE,YAAY,GAAG,IAAI,GAC5B,OAAO,CAAC,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC,CAkDhD;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS5E"}
|
package/dist/sync.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File sync logic with conflict detection
|
|
3
|
+
*
|
|
4
|
+
* Addresses consensus finding: Last-write-wins causes silent data loss
|
|
5
|
+
* Solution: Track both local and remote timestamps, detect conflicts explicitly
|
|
6
|
+
*/
|
|
7
|
+
import * as crypto from 'crypto';
|
|
8
|
+
import * as fs from 'fs/promises';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import { homedir } from 'os';
|
|
11
|
+
const METADATA_FILE = path.join(homedir(), '.borg-mcp', 'sync-metadata.json');
|
|
12
|
+
const CLAUDE_MD_PATH = path.join(homedir(), '.claude', 'CLAUDE.md');
|
|
13
|
+
/**
|
|
14
|
+
* Calculate SHA-256 hash of file content
|
|
15
|
+
*/
|
|
16
|
+
export function hashContent(content) {
|
|
17
|
+
return crypto.createHash('sha256').update(content, 'utf8').digest('hex');
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Ensure metadata directory exists
|
|
21
|
+
*/
|
|
22
|
+
async function ensureMetadataDir() {
|
|
23
|
+
const dir = path.dirname(METADATA_FILE);
|
|
24
|
+
await fs.mkdir(dir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Load sync metadata from disk
|
|
28
|
+
*/
|
|
29
|
+
export async function loadMetadata() {
|
|
30
|
+
try {
|
|
31
|
+
const data = await fs.readFile(METADATA_FILE, 'utf8');
|
|
32
|
+
return JSON.parse(data);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
if (error.code === 'ENOENT') {
|
|
36
|
+
return null; // File doesn't exist yet
|
|
37
|
+
}
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Save sync metadata to disk
|
|
43
|
+
*/
|
|
44
|
+
export async function saveMetadata(metadata) {
|
|
45
|
+
await ensureMetadataDir();
|
|
46
|
+
await fs.writeFile(METADATA_FILE, JSON.stringify(metadata, null, 2), 'utf8');
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Read local CLAUDE.md file
|
|
50
|
+
*/
|
|
51
|
+
export async function readLocalFile() {
|
|
52
|
+
try {
|
|
53
|
+
return await fs.readFile(CLAUDE_MD_PATH, 'utf8');
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
if (error.code === 'ENOENT') {
|
|
57
|
+
return null; // File doesn't exist
|
|
58
|
+
}
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Write content to local CLAUDE.md file
|
|
64
|
+
*/
|
|
65
|
+
export async function writeLocalFile(content) {
|
|
66
|
+
const dir = path.dirname(CLAUDE_MD_PATH);
|
|
67
|
+
await fs.mkdir(dir, { recursive: true });
|
|
68
|
+
await fs.writeFile(CLAUDE_MD_PATH, content, 'utf8');
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get local file modification time
|
|
72
|
+
*/
|
|
73
|
+
export async function getLocalMtime() {
|
|
74
|
+
try {
|
|
75
|
+
const stats = await fs.stat(CLAUDE_MD_PATH);
|
|
76
|
+
return stats.mtimeMs;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
if (error.code === 'ENOENT') {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Detect if there's a sync conflict
|
|
87
|
+
*
|
|
88
|
+
* Conflict occurs when:
|
|
89
|
+
* 1. Both local and remote have changed since last sync
|
|
90
|
+
* 2. Changes are different (different content hashes)
|
|
91
|
+
*/
|
|
92
|
+
export async function detectConflict(localContent, remoteContent, metadata) {
|
|
93
|
+
// No conflict if no metadata (first sync)
|
|
94
|
+
if (!metadata) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const localHash = hashContent(localContent);
|
|
98
|
+
const remoteHash = hashContent(remoteContent);
|
|
99
|
+
// No conflict if content is identical
|
|
100
|
+
if (localHash === remoteHash) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
// Check if both have changed since last sync
|
|
104
|
+
const localChanged = localHash !== metadata.lastSyncHash;
|
|
105
|
+
const remoteChanged = remoteHash !== metadata.lastSyncHash;
|
|
106
|
+
if (localChanged && remoteChanged) {
|
|
107
|
+
// CONFLICT: Both local and remote changed since last sync
|
|
108
|
+
const localMtime = await getLocalMtime();
|
|
109
|
+
return {
|
|
110
|
+
localContent,
|
|
111
|
+
remoteContent,
|
|
112
|
+
localMtime: localMtime || Date.now(),
|
|
113
|
+
remoteMtime: Date.now(), // Remote doesn't track mtime, use current time
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// No conflict - only one side changed
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Handle sync conflict by creating a conflict file
|
|
121
|
+
*
|
|
122
|
+
* Strategy: Create CLAUDE.md.conflict with remote content
|
|
123
|
+
* Keep local file unchanged, let user resolve manually
|
|
124
|
+
*/
|
|
125
|
+
export async function handleConflict(conflict) {
|
|
126
|
+
const conflictPath = `${CLAUDE_MD_PATH}.conflict`;
|
|
127
|
+
// Write remote content to conflict file
|
|
128
|
+
await fs.writeFile(conflictPath, conflict.remoteContent, 'utf8');
|
|
129
|
+
// Log conflict to stderr for user visibility
|
|
130
|
+
console.error('\nā ļø SYNC CONFLICT DETECTED');
|
|
131
|
+
console.error('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
132
|
+
console.error('Both local and remote CLAUDE.md have been modified.');
|
|
133
|
+
console.error(`Local file: ${CLAUDE_MD_PATH}`);
|
|
134
|
+
console.error(`Remote backup: ${conflictPath}\n`);
|
|
135
|
+
console.error('Please resolve manually by choosing one version or merging them.');
|
|
136
|
+
console.error('Delete the .conflict file once resolved.\n');
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Determine sync action based on file states
|
|
140
|
+
*
|
|
141
|
+
* Returns: 'push' | 'pull' | 'conflict' | 'skip'
|
|
142
|
+
*/
|
|
143
|
+
export async function determineSyncAction(localContent, remoteContent, metadata) {
|
|
144
|
+
// Case 1: Neither exists - skip
|
|
145
|
+
if (!localContent && !remoteContent) {
|
|
146
|
+
return 'skip';
|
|
147
|
+
}
|
|
148
|
+
// Case 2: Only remote exists - pull
|
|
149
|
+
if (!localContent && remoteContent) {
|
|
150
|
+
return 'pull';
|
|
151
|
+
}
|
|
152
|
+
// Case 3: Only local exists - push
|
|
153
|
+
if (localContent && !remoteContent) {
|
|
154
|
+
return 'push';
|
|
155
|
+
}
|
|
156
|
+
// Case 4: Both exist - check for conflicts
|
|
157
|
+
if (localContent && remoteContent) {
|
|
158
|
+
const conflict = await detectConflict(localContent, remoteContent, metadata);
|
|
159
|
+
if (conflict) {
|
|
160
|
+
return 'conflict';
|
|
161
|
+
}
|
|
162
|
+
// No conflict - determine direction based on content hash
|
|
163
|
+
const localHash = hashContent(localContent);
|
|
164
|
+
const remoteHash = hashContent(remoteContent);
|
|
165
|
+
if (localHash === remoteHash) {
|
|
166
|
+
return 'skip'; // Identical content
|
|
167
|
+
}
|
|
168
|
+
// One side changed - sync in that direction
|
|
169
|
+
if (metadata) {
|
|
170
|
+
const localChanged = localHash !== metadata.lastSyncHash;
|
|
171
|
+
const remoteChanged = remoteHash !== metadata.lastSyncHash;
|
|
172
|
+
if (localChanged) {
|
|
173
|
+
return 'push';
|
|
174
|
+
}
|
|
175
|
+
if (remoteChanged) {
|
|
176
|
+
return 'pull';
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// No metadata - default to push (local is source of truth for first sync)
|
|
180
|
+
return 'push';
|
|
181
|
+
}
|
|
182
|
+
return 'skip';
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Update metadata after successful sync
|
|
186
|
+
*/
|
|
187
|
+
export async function updateMetadataAfterSync(content) {
|
|
188
|
+
const metadata = {
|
|
189
|
+
localMtime: await getLocalMtime() || Date.now(),
|
|
190
|
+
remoteMtime: Date.now(),
|
|
191
|
+
lastSyncHash: hashContent(content),
|
|
192
|
+
lastSyncTime: Date.now(),
|
|
193
|
+
};
|
|
194
|
+
await saveMetadata(metadata);
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=sync.js.map
|
package/dist/sync.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for Borg MCP Client
|
|
3
|
+
*/
|
|
4
|
+
export interface FileMetadata {
|
|
5
|
+
localMtime: number;
|
|
6
|
+
remoteMtime: number;
|
|
7
|
+
lastSyncHash: string;
|
|
8
|
+
lastSyncTime: number;
|
|
9
|
+
}
|
|
10
|
+
export interface SyncState {
|
|
11
|
+
inProgress: boolean;
|
|
12
|
+
lastSync: number;
|
|
13
|
+
pendingChanges: PendingChange[];
|
|
14
|
+
}
|
|
15
|
+
export interface PendingChange {
|
|
16
|
+
operation: 'set' | 'delete';
|
|
17
|
+
content?: string;
|
|
18
|
+
timestamp: number;
|
|
19
|
+
retryCount: number;
|
|
20
|
+
}
|
|
21
|
+
export interface GoogleOAuthTokens {
|
|
22
|
+
id_token: string;
|
|
23
|
+
refresh_token?: string;
|
|
24
|
+
expires_at: number;
|
|
25
|
+
}
|
|
26
|
+
export interface RemoteResponse {
|
|
27
|
+
success: boolean;
|
|
28
|
+
data?: any;
|
|
29
|
+
error?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface ConflictInfo {
|
|
32
|
+
localContent: string;
|
|
33
|
+
remoteContent: string;
|
|
34
|
+
localMtime: number;
|
|
35
|
+
remoteMtime: number;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "borgmcp",
|
|
3
|
+
"version": "0.2.0-beta.1",
|
|
4
|
+
"description": "Centralized context storage for Claude - install once, sync everywhere",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"borgmcp": "dist/index.js",
|
|
9
|
+
"borgmcp-setup": "dist/setup.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"dev": "tsc --watch",
|
|
14
|
+
"start": "node dist/index.js",
|
|
15
|
+
"postinstall": "node dist/postinstall.js || true",
|
|
16
|
+
"prepublishOnly": "npm run build"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"keywords": [
|
|
24
|
+
"mcp",
|
|
25
|
+
"claude",
|
|
26
|
+
"ai",
|
|
27
|
+
"context",
|
|
28
|
+
"sync",
|
|
29
|
+
"anthropic",
|
|
30
|
+
"claude-code",
|
|
31
|
+
"borg"
|
|
32
|
+
],
|
|
33
|
+
"author": "Theodor Storm <theodor@byteventures.se>",
|
|
34
|
+
"license": "Apache-2.0",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/theodorstorm/borg-mcp",
|
|
38
|
+
"directory": "client"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://borgmcp.ai",
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/theodorstorm/borg-mcp/issues"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
46
|
+
"chalk": "^5.3.0",
|
|
47
|
+
"keytar": "^7.9.0",
|
|
48
|
+
"open": "^10.0.0",
|
|
49
|
+
"prompts": "^2.4.2",
|
|
50
|
+
"which": "^4.0.0",
|
|
51
|
+
"zod": "^3.24.1"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/node": "^22.10.2",
|
|
55
|
+
"@types/prompts": "^2.4.9",
|
|
56
|
+
"@types/which": "^3.0.4",
|
|
57
|
+
"typescript": "^5.7.2"
|
|
58
|
+
},
|
|
59
|
+
"publishConfig": {
|
|
60
|
+
"access": "public"
|
|
61
|
+
}
|
|
62
|
+
}
|