jean-claude 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.
- package/README.md +71 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +56 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +139 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/index.d.ts +5 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +5 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +69 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/pull.d.ts +3 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +48 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/push.d.ts +3 -0
- package/dist/commands/push.d.ts.map +1 -0
- package/dist/commands/push.js +73 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +81 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/git.d.ts +21 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +137 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/paths.d.ts +7 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +43 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/scaffold.d.ts +2 -0
- package/dist/lib/scaffold.d.ts.map +1 -0
- package/dist/lib/scaffold.js +77 -0
- package/dist/lib/scaffold.js.map +1 -0
- package/dist/lib/sync.d.ts +16 -0
- package/dist/lib/sync.d.ts.map +1 -0
- package/dist/lib/sync.js +229 -0
- package/dist/lib/sync.js.map +1 -0
- package/dist/types/index.d.ts +57 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +24 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +32 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/logo.d.ts +2 -0
- package/dist/utils/logo.d.ts.map +1 -0
- package/dist/utils/logo.js +39 -0
- package/dist/utils/logo.js.map +1 -0
- package/dist/utils/prompts.d.ts +7 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +35 -0
- package/dist/utils/prompts.js.map +1 -0
- package/package.json +58 -0
- package/templates/CLAUDE.md +33 -0
- package/templates/settings.json +2 -0
package/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# JEAN-CLAUDE
|
|
2
|
+
|
|
3
|
+
**A companion for syncing Claude Code configuration across machines**
|
|
4
|
+
|
|
5
|
+
## Why?
|
|
6
|
+
|
|
7
|
+
You've spent hours crafting the perfect `CLAUDE.md`. Your hooks are *chef's kiss*. Your settings are dialed in just right.
|
|
8
|
+
|
|
9
|
+
Then you sit down at another machine and... nothing. Back to square one.
|
|
10
|
+
|
|
11
|
+
**Jean-Claude fixes that.** It syncs your Claude Code configuration across all your machines using Git.
|
|
12
|
+
|
|
13
|
+
## What gets synced?
|
|
14
|
+
|
|
15
|
+
- `CLAUDE.md` - Your custom instructions
|
|
16
|
+
- `settings.json` - Your preferences
|
|
17
|
+
- `hooks/` - Your automation scripts
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install -g jean-claude
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### First time setup
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
jean-claude init
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
You'll be asked for a Git repository URL. Create an empty private repo on GitHub/GitLab/etc and paste the URL.
|
|
34
|
+
|
|
35
|
+
### Push your config
|
|
36
|
+
|
|
37
|
+
Made changes to your Claude Code setup? Push them:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
jean-claude push
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Pull on another machine
|
|
44
|
+
|
|
45
|
+
On a new machine, initialize with the same repo:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
jean-claude init
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Then pull the latest:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
jean-claude pull
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Check status
|
|
58
|
+
|
|
59
|
+
See what's in sync:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
jean-claude status
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## That's it!
|
|
66
|
+
|
|
67
|
+
Four commands. No options. No complexity. Just sync.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
*Named after the famous Belgian martial artist and philosopher, because your config deserves to do the splits across multiple machines.*
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,wBAAgB,aAAa,IAAI,OAAO,CAkBvC;AAED,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkCvD"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { initCommand, pullCommand, pushCommand, statusCommand, } from './commands/index.js';
|
|
4
|
+
import { JeanClaudeError } from './types/index.js';
|
|
5
|
+
import { printLogo } from './utils/logo.js';
|
|
6
|
+
const VERSION = '0.1.0';
|
|
7
|
+
export function createProgram() {
|
|
8
|
+
const program = new Command();
|
|
9
|
+
program
|
|
10
|
+
.name('jean-claude')
|
|
11
|
+
.description('Sync Claude Code configuration across machines using Git')
|
|
12
|
+
.version(VERSION)
|
|
13
|
+
.addHelpText('before', () => {
|
|
14
|
+
printLogo();
|
|
15
|
+
return '';
|
|
16
|
+
});
|
|
17
|
+
program.addCommand(initCommand);
|
|
18
|
+
program.addCommand(pullCommand);
|
|
19
|
+
program.addCommand(pushCommand);
|
|
20
|
+
program.addCommand(statusCommand);
|
|
21
|
+
return program;
|
|
22
|
+
}
|
|
23
|
+
export async function run(argv) {
|
|
24
|
+
const program = createProgram();
|
|
25
|
+
// Global error handling
|
|
26
|
+
program.exitOverride();
|
|
27
|
+
try {
|
|
28
|
+
await program.parseAsync(argv);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
if (err instanceof JeanClaudeError) {
|
|
32
|
+
console.error(chalk.red('error') + ' ' + err.message);
|
|
33
|
+
if (err.suggestion) {
|
|
34
|
+
console.log('\n' + chalk.dim('Suggestion: ') + err.suggestion);
|
|
35
|
+
}
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
// Commander errors (like --help, --version)
|
|
39
|
+
if (err && typeof err === 'object' && 'code' in err) {
|
|
40
|
+
const code = err.code;
|
|
41
|
+
if (code === 'commander.helpDisplayed' || code === 'commander.version' || code === 'commander.help') {
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Unexpected error
|
|
46
|
+
console.error(chalk.red('error') + ' An unexpected error occurred');
|
|
47
|
+
if (process.env.DEBUG) {
|
|
48
|
+
console.error(err);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
console.log(chalk.dim('Run with DEBUG=1 for more details'));
|
|
52
|
+
}
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EACL,WAAW,EACX,WAAW,EACX,WAAW,EACX,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,aAAa,CAAC;SACnB,WAAW,CAAC,0DAA0D,CAAC;SACvE,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,QAAQ,EAAE,GAAG,EAAE;QAC1B,SAAS,EAAE,CAAC;QACZ,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;IAEL,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IAChC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IAChC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAElC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc;IACtC,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAEhC,wBAAwB;IACxB,OAAO,CAAC,YAAY,EAAE,CAAC;IAEvB,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;YACnC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;YACtD,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;gBACnB,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;YACjE,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,4CAA4C;QAC5C,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YACpD,MAAM,IAAI,GAAI,GAAwB,CAAC,IAAI,CAAC;YAC5C,IAAI,IAAI,KAAK,yBAAyB,IAAI,IAAI,KAAK,mBAAmB,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBACpG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,mBAAmB;QACnB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,+BAA+B,CAAC,CAAC;QACpE,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuHpC,eAAO,MAAM,aAAa,SAkCtB,CAAC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { logger, formatPath } from '../utils/logger.js';
|
|
5
|
+
import { getConfigPaths } from '../lib/paths.js';
|
|
6
|
+
import { isGitRepo, getGitStatus, hasMergeConflicts } from '../lib/git.js';
|
|
7
|
+
import { readMetaJson } from '../lib/sync.js';
|
|
8
|
+
async function runChecks() {
|
|
9
|
+
const checks = [];
|
|
10
|
+
const { jeanClaudeDir, claudeConfigDir } = getConfigPaths();
|
|
11
|
+
// Check 1: Directory exists
|
|
12
|
+
const dirExists = fs.existsSync(jeanClaudeDir);
|
|
13
|
+
checks.push({
|
|
14
|
+
name: 'Jean-Claude directory exists',
|
|
15
|
+
passed: dirExists,
|
|
16
|
+
message: dirExists
|
|
17
|
+
? formatPath(jeanClaudeDir)
|
|
18
|
+
: `${formatPath(jeanClaudeDir)} not found`,
|
|
19
|
+
suggestion: dirExists ? undefined : 'Run "jean-claude init" to set up.',
|
|
20
|
+
});
|
|
21
|
+
if (!dirExists) {
|
|
22
|
+
return checks; // Can't continue without directory
|
|
23
|
+
}
|
|
24
|
+
// Check 2: Is Git repo
|
|
25
|
+
const isRepo = await isGitRepo(jeanClaudeDir);
|
|
26
|
+
checks.push({
|
|
27
|
+
name: 'Is a Git repository',
|
|
28
|
+
passed: isRepo,
|
|
29
|
+
message: isRepo ? 'Yes' : 'Not a Git repository',
|
|
30
|
+
suggestion: isRepo
|
|
31
|
+
? undefined
|
|
32
|
+
: 'Run "git init" in ~/.jean-claude or re-run "jean-claude init".',
|
|
33
|
+
});
|
|
34
|
+
if (!isRepo) {
|
|
35
|
+
return checks; // Can't continue without Git
|
|
36
|
+
}
|
|
37
|
+
// Check 3: Remote configured
|
|
38
|
+
const gitStatus = await getGitStatus(jeanClaudeDir);
|
|
39
|
+
checks.push({
|
|
40
|
+
name: 'Git remote configured',
|
|
41
|
+
passed: !!gitStatus.remote,
|
|
42
|
+
message: gitStatus.remote || 'No remote',
|
|
43
|
+
suggestion: gitStatus.remote
|
|
44
|
+
? undefined
|
|
45
|
+
: 'Add a remote: git -C ~/.jean-claude remote add origin <url>',
|
|
46
|
+
});
|
|
47
|
+
// Check 4: No merge conflicts
|
|
48
|
+
const hasConflicts = await hasMergeConflicts(jeanClaudeDir);
|
|
49
|
+
checks.push({
|
|
50
|
+
name: 'No merge conflicts',
|
|
51
|
+
passed: !hasConflicts,
|
|
52
|
+
message: hasConflicts ? 'Conflicts detected!' : 'Clean',
|
|
53
|
+
suggestion: hasConflicts
|
|
54
|
+
? 'Resolve conflicts in ~/.jean-claude before continuing.'
|
|
55
|
+
: undefined,
|
|
56
|
+
});
|
|
57
|
+
// Check 5: Claude config directory exists
|
|
58
|
+
const claudeExists = fs.existsSync(claudeConfigDir);
|
|
59
|
+
checks.push({
|
|
60
|
+
name: 'Claude Code config directory exists',
|
|
61
|
+
passed: claudeExists,
|
|
62
|
+
message: claudeExists
|
|
63
|
+
? formatPath(claudeConfigDir)
|
|
64
|
+
: `${formatPath(claudeConfigDir)} not found`,
|
|
65
|
+
suggestion: claudeExists
|
|
66
|
+
? undefined
|
|
67
|
+
: 'Run "jean-claude pull" to create it, or start Claude Code once.',
|
|
68
|
+
});
|
|
69
|
+
// Check 6: meta.json is valid
|
|
70
|
+
const meta = await readMetaJson(jeanClaudeDir);
|
|
71
|
+
checks.push({
|
|
72
|
+
name: 'meta.json is valid',
|
|
73
|
+
passed: !!meta,
|
|
74
|
+
message: meta ? `Machine: ${meta.machineId}` : 'Invalid or missing',
|
|
75
|
+
suggestion: meta
|
|
76
|
+
? undefined
|
|
77
|
+
: 'Run "jean-claude init" again to regenerate meta.json.',
|
|
78
|
+
});
|
|
79
|
+
// Check 7: Required files exist
|
|
80
|
+
const claudeMdExists = fs.existsSync(`${jeanClaudeDir}/CLAUDE.md`);
|
|
81
|
+
checks.push({
|
|
82
|
+
name: 'CLAUDE.md exists',
|
|
83
|
+
passed: claudeMdExists,
|
|
84
|
+
message: claudeMdExists ? 'Present' : 'Missing',
|
|
85
|
+
suggestion: claudeMdExists
|
|
86
|
+
? undefined
|
|
87
|
+
: 'Create CLAUDE.md in ~/.jean-claude with your configuration.',
|
|
88
|
+
});
|
|
89
|
+
// Check 8: Permissions
|
|
90
|
+
let permissionsOk = true;
|
|
91
|
+
try {
|
|
92
|
+
fs.accessSync(jeanClaudeDir, fs.constants.R_OK | fs.constants.W_OK);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
permissionsOk = false;
|
|
96
|
+
}
|
|
97
|
+
checks.push({
|
|
98
|
+
name: 'Directory permissions',
|
|
99
|
+
passed: permissionsOk,
|
|
100
|
+
message: permissionsOk ? 'OK (read/write)' : 'Permission denied',
|
|
101
|
+
suggestion: permissionsOk
|
|
102
|
+
? undefined
|
|
103
|
+
: `Fix permissions: chmod -R u+rw ${formatPath(jeanClaudeDir)}`,
|
|
104
|
+
});
|
|
105
|
+
return checks;
|
|
106
|
+
}
|
|
107
|
+
export const doctorCommand = new Command('doctor')
|
|
108
|
+
.description('Diagnose common issues')
|
|
109
|
+
.option('--json', 'Output as JSON')
|
|
110
|
+
.action(async (options) => {
|
|
111
|
+
const checks = await runChecks();
|
|
112
|
+
if (options.json) {
|
|
113
|
+
console.log(JSON.stringify({ checks }, null, 2));
|
|
114
|
+
const allPassed = checks.every((c) => c.passed);
|
|
115
|
+
process.exit(allPassed ? 0 : 1);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
logger.heading('Jean-Claude Doctor');
|
|
119
|
+
console.log('');
|
|
120
|
+
let allPassed = true;
|
|
121
|
+
checks.forEach((check) => {
|
|
122
|
+
const icon = check.passed ? chalk.green('✓') : chalk.red('✗');
|
|
123
|
+
console.log(` ${icon} ${check.name}`);
|
|
124
|
+
console.log(` ${chalk.dim(check.message)}`);
|
|
125
|
+
if (!check.passed && check.suggestion) {
|
|
126
|
+
console.log(` ${chalk.yellow('→')} ${check.suggestion}`);
|
|
127
|
+
allPassed = false;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
console.log('');
|
|
131
|
+
if (allPassed) {
|
|
132
|
+
logger.success('All checks passed!');
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
logger.warn('Some checks failed. See suggestions above.');
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,eAAO,MAAM,WAAW,SAyEpB,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import { logger, formatPath } from '../utils/logger.js';
|
|
4
|
+
import { input } from '../utils/prompts.js';
|
|
5
|
+
import { getConfigPaths, ensureDir } from '../lib/paths.js';
|
|
6
|
+
import { isGitRepo, initRepo, addRemote, testRemoteConnection, cloneRepo } from '../lib/git.js';
|
|
7
|
+
import { createMetaJson, writeMetaJson, syncFromClaudeConfig, } from '../lib/sync.js';
|
|
8
|
+
import { JeanClaudeError, ErrorCode } from '../types/index.js';
|
|
9
|
+
import { printLogo } from '../utils/logo.js';
|
|
10
|
+
export const initCommand = new Command('init')
|
|
11
|
+
.description('Initialize Jean-Claude on this machine')
|
|
12
|
+
.action(async () => {
|
|
13
|
+
const { jeanClaudeDir, claudeConfigDir } = getConfigPaths();
|
|
14
|
+
printLogo();
|
|
15
|
+
logger.heading('Setup');
|
|
16
|
+
// Check if already initialized
|
|
17
|
+
if (fs.existsSync(jeanClaudeDir)) {
|
|
18
|
+
const isRepo = await isGitRepo(jeanClaudeDir);
|
|
19
|
+
if (isRepo) {
|
|
20
|
+
logger.success(`Already initialized at ${formatPath(jeanClaudeDir)}`);
|
|
21
|
+
logger.dim('Run "jean-claude status" to see current state.');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
throw new JeanClaudeError(`${formatPath(jeanClaudeDir)} exists but is not a Git repository`, ErrorCode.NOT_GIT_REPO, 'Remove the directory and run init again.');
|
|
25
|
+
}
|
|
26
|
+
// Get repository URL
|
|
27
|
+
const repoUrl = await input('Enter your Git repository URL:');
|
|
28
|
+
// Test connection to remote
|
|
29
|
+
logger.step(1, 4, 'Testing connection to repository...');
|
|
30
|
+
const canConnect = await testRemoteConnection(repoUrl);
|
|
31
|
+
if (!canConnect) {
|
|
32
|
+
throw new JeanClaudeError('Cannot connect to repository', ErrorCode.NETWORK_ERROR, 'Check that the URL is correct and you have access.');
|
|
33
|
+
}
|
|
34
|
+
logger.success('Connection successful');
|
|
35
|
+
// Try to clone (will work if repo has content) or init fresh (if empty)
|
|
36
|
+
logger.step(2, 4, 'Setting up local repository...');
|
|
37
|
+
try {
|
|
38
|
+
await cloneRepo(repoUrl, jeanClaudeDir);
|
|
39
|
+
logger.success('Cloned existing config from repository');
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Repo is empty, init locally and add remote
|
|
43
|
+
ensureDir(jeanClaudeDir);
|
|
44
|
+
await initRepo(jeanClaudeDir);
|
|
45
|
+
await addRemote(jeanClaudeDir, repoUrl);
|
|
46
|
+
logger.success('Initialized new repository');
|
|
47
|
+
}
|
|
48
|
+
// Create meta.json
|
|
49
|
+
const meta = createMetaJson(claudeConfigDir);
|
|
50
|
+
await writeMetaJson(jeanClaudeDir, meta);
|
|
51
|
+
// Sync from ~/.claude to ~/.jean-claude
|
|
52
|
+
logger.step(3, 4, `Syncing from ${formatPath(claudeConfigDir)}...`);
|
|
53
|
+
const syncResults = await syncFromClaudeConfig(claudeConfigDir, jeanClaudeDir);
|
|
54
|
+
const synced = syncResults.filter((r) => r.action !== 'skipped');
|
|
55
|
+
if (synced.length > 0) {
|
|
56
|
+
logger.success(`Synced ${synced.length} file(s)`);
|
|
57
|
+
}
|
|
58
|
+
// Done
|
|
59
|
+
logger.step(4, 4, 'Done!');
|
|
60
|
+
console.log('');
|
|
61
|
+
logger.success('Jean-Claude initialized!');
|
|
62
|
+
console.log('');
|
|
63
|
+
logger.dim('Next steps:');
|
|
64
|
+
logger.list([
|
|
65
|
+
'Run "jean-claude push" to push your config to Git',
|
|
66
|
+
'Run "jean-claude pull" on other machines to sync',
|
|
67
|
+
]);
|
|
68
|
+
});
|
|
69
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,WAAW,SA8DpB,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { logger, formatPath } from '../utils/logger.js';
|
|
5
|
+
import { getConfigPaths } from '../lib/paths.js';
|
|
6
|
+
import { isGitRepo, pull, getGitStatus, hasMergeConflicts, resetHard } from '../lib/git.js';
|
|
7
|
+
import { syncToClaudeConfig, updateLastSync } from '../lib/sync.js';
|
|
8
|
+
import { JeanClaudeError, ErrorCode } from '../types/index.js';
|
|
9
|
+
export const pullCommand = new Command('pull')
|
|
10
|
+
.description('Pull latest config from Git and apply to Claude Code')
|
|
11
|
+
.action(async () => {
|
|
12
|
+
const { jeanClaudeDir, claudeConfigDir } = getConfigPaths();
|
|
13
|
+
// Verify initialized
|
|
14
|
+
if (!fs.existsSync(jeanClaudeDir)) {
|
|
15
|
+
throw new JeanClaudeError('Jean-Claude is not initialized', ErrorCode.NOT_INITIALIZED, 'Run "jean-claude init" first.');
|
|
16
|
+
}
|
|
17
|
+
if (!(await isGitRepo(jeanClaudeDir))) {
|
|
18
|
+
throw new JeanClaudeError(`${formatPath(jeanClaudeDir)} is not a Git repository`, ErrorCode.NOT_GIT_REPO, 'Run "jean-claude init" to set up properly.');
|
|
19
|
+
}
|
|
20
|
+
// Check if remote is configured
|
|
21
|
+
const gitStatus = await getGitStatus(jeanClaudeDir);
|
|
22
|
+
if (!gitStatus.remote) {
|
|
23
|
+
throw new JeanClaudeError('No remote configured', ErrorCode.NO_REMOTE, 'Run "jean-claude init" to set up a remote repository.');
|
|
24
|
+
}
|
|
25
|
+
// Reset any local changes and pull
|
|
26
|
+
logger.step(1, 2, 'Pulling from Git...');
|
|
27
|
+
await resetHard(jeanClaudeDir);
|
|
28
|
+
const pullResult = await pull(jeanClaudeDir);
|
|
29
|
+
logger.success(pullResult.message);
|
|
30
|
+
// Check for merge conflicts (shouldn't happen after reset, but just in case)
|
|
31
|
+
if (await hasMergeConflicts(jeanClaudeDir)) {
|
|
32
|
+
throw new JeanClaudeError('Merge conflicts detected', ErrorCode.MERGE_CONFLICT, `Resolve conflicts in ${formatPath(jeanClaudeDir)} and run pull again.`);
|
|
33
|
+
}
|
|
34
|
+
// Apply to ~/.claude
|
|
35
|
+
logger.step(2, 2, `Applying to ${formatPath(claudeConfigDir)}...`);
|
|
36
|
+
const results = await syncToClaudeConfig(jeanClaudeDir, claudeConfigDir);
|
|
37
|
+
const applied = results.filter((r) => r.action !== 'skipped');
|
|
38
|
+
// Update last sync time
|
|
39
|
+
await updateLastSync(jeanClaudeDir);
|
|
40
|
+
// Summary
|
|
41
|
+
console.log('');
|
|
42
|
+
logger.success(`Applied ${applied.length} file(s)`);
|
|
43
|
+
applied.forEach((r) => {
|
|
44
|
+
const icon = r.action === 'created' ? chalk.green('+') : chalk.yellow('~');
|
|
45
|
+
console.log(` ${icon} ${r.file}`);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=pull.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,eAAO,MAAM,WAAW,SA2EpB,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { logger, formatPath } from '../utils/logger.js';
|
|
6
|
+
import { getConfigPaths } from '../lib/paths.js';
|
|
7
|
+
import { isGitRepo, getGitStatus, commitAndPush } from '../lib/git.js';
|
|
8
|
+
import { updateLastSync, syncFromClaudeConfig } from '../lib/sync.js';
|
|
9
|
+
import { JeanClaudeError, ErrorCode } from '../types/index.js';
|
|
10
|
+
function generateCommitMessage() {
|
|
11
|
+
const hostname = os.hostname();
|
|
12
|
+
const timestamp = new Date().toISOString().replace('T', ' ').slice(0, 19);
|
|
13
|
+
return `Update from ${hostname} at ${timestamp}`;
|
|
14
|
+
}
|
|
15
|
+
export const pushCommand = new Command('push')
|
|
16
|
+
.description('Commit and push config changes to Git')
|
|
17
|
+
.action(async () => {
|
|
18
|
+
const { jeanClaudeDir, claudeConfigDir } = getConfigPaths();
|
|
19
|
+
// Verify initialized
|
|
20
|
+
if (!fs.existsSync(jeanClaudeDir)) {
|
|
21
|
+
throw new JeanClaudeError('Jean-Claude is not initialized', ErrorCode.NOT_INITIALIZED, 'Run "jean-claude init" first.');
|
|
22
|
+
}
|
|
23
|
+
if (!(await isGitRepo(jeanClaudeDir))) {
|
|
24
|
+
throw new JeanClaudeError(`${formatPath(jeanClaudeDir)} is not a Git repository`, ErrorCode.NOT_GIT_REPO, 'Run "jean-claude init" to set up properly.');
|
|
25
|
+
}
|
|
26
|
+
// Step 1: Copy files from ~/.claude to ~/.jean-claude
|
|
27
|
+
logger.step(1, 2, `Syncing from ${formatPath(claudeConfigDir)}...`);
|
|
28
|
+
const syncResults = await syncFromClaudeConfig(claudeConfigDir, jeanClaudeDir);
|
|
29
|
+
const synced = syncResults.filter((r) => r.action !== 'skipped');
|
|
30
|
+
if (synced.length > 0) {
|
|
31
|
+
synced.forEach((r) => {
|
|
32
|
+
console.log(` ${chalk.blue('synced')} ${r.file}`);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
// Step 2: Check git status
|
|
36
|
+
const gitStatus = await getGitStatus(jeanClaudeDir);
|
|
37
|
+
if (gitStatus.isClean) {
|
|
38
|
+
logger.success('Nothing to push - everything is in sync.');
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
// Show changes
|
|
42
|
+
logger.dim('Changes to push:');
|
|
43
|
+
if (gitStatus.modified.length > 0) {
|
|
44
|
+
gitStatus.modified.forEach((f) => {
|
|
45
|
+
console.log(` ${chalk.yellow('modified')} ${f}`);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (gitStatus.untracked.length > 0) {
|
|
49
|
+
gitStatus.untracked.forEach((f) => {
|
|
50
|
+
console.log(` ${chalk.green('new file')} ${f}`);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
// Commit message
|
|
54
|
+
const commitMessage = generateCommitMessage();
|
|
55
|
+
// Commit and push
|
|
56
|
+
logger.step(2, 2, 'Committing and pushing...');
|
|
57
|
+
const result = await commitAndPush(jeanClaudeDir, commitMessage, true);
|
|
58
|
+
// Update last sync
|
|
59
|
+
await updateLastSync(jeanClaudeDir);
|
|
60
|
+
// Summary
|
|
61
|
+
console.log('');
|
|
62
|
+
if (result.committed) {
|
|
63
|
+
logger.success('Changes committed');
|
|
64
|
+
}
|
|
65
|
+
if (result.pushed) {
|
|
66
|
+
logger.success('Pushed to remote');
|
|
67
|
+
}
|
|
68
|
+
else if (!gitStatus.remote) {
|
|
69
|
+
logger.warn('No remote configured - changes committed locally only');
|
|
70
|
+
logger.dim('Add a remote with: git -C ~/.jean-claude remote add origin <url>');
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
//# sourceMappingURL=push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,aAAa,SAyFtB,CAAC"}
|