@tengx5383/aitool-sync-cli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/cli.js +4 -4
- package/dist/cli.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +13 -16
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +71 -26
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list.js +1 -1
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +9 -10
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +39 -22
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +15 -8
- package/dist/commands/status.js.map +1 -1
- package/dist/config/config-file.js +1 -1
- package/dist/config/config-file.js.map +1 -1
- package/dist/config/schema.d.ts +3 -3
- package/dist/config/schema.js +1 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/core/backup.d.ts.map +1 -1
- package/dist/core/backup.js +41 -13
- package/dist/core/backup.js.map +1 -1
- package/dist/core/file-collector.js +70 -1
- package/dist/core/file-collector.js.map +1 -1
- package/dist/core/manifest.d.ts.map +1 -1
- package/dist/core/sync-engine.d.ts +7 -14
- package/dist/core/sync-engine.d.ts.map +1 -1
- package/dist/core/sync-engine.js +192 -140
- package/dist/core/sync-engine.js.map +1 -1
- package/dist/git/github-api.d.ts +14 -0
- package/dist/git/github-api.d.ts.map +1 -0
- package/dist/git/github-api.js +38 -0
- package/dist/git/github-api.js.map +1 -0
- package/dist/git/repo-client.d.ts +17 -0
- package/dist/git/repo-client.d.ts.map +1 -0
- package/dist/git/repo-client.js +40 -0
- package/dist/git/repo-client.js.map +1 -0
- package/dist/presets/claude-code.d.ts.map +1 -1
- package/dist/presets/claude-code.js +5 -0
- package/dist/presets/claude-code.js.map +1 -1
- package/dist/types/config.d.ts +2 -2
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/git.d.ts +5 -0
- package/dist/types/git.d.ts.map +1 -0
- package/dist/types/git.js +2 -0
- package/dist/types/git.js.map +1 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +10 -3
- package/.claude/settings.local.json +0 -8
- package/tests/integration/encryption-flow.test.ts +0 -142
- package/tests/integration/init-flow.test.ts +0 -69
- package/tests/integration/push-pull-flow.test.ts +0 -183
- package/tests/integration/status-flow.test.ts +0 -149
package/dist/core/sync-engine.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
2
3
|
import path from 'node:path';
|
|
4
|
+
import { simpleGit } from 'simple-git';
|
|
3
5
|
import { collectFiles } from './file-collector.js';
|
|
4
|
-
import { createManifest,
|
|
6
|
+
import { createManifest, parseManifest } from './manifest.js';
|
|
5
7
|
import { diffManifests } from '../utils/diff.js';
|
|
6
|
-
import { buildSyncPackage, parseSyncPackage } from './sync-package.js';
|
|
7
8
|
import { createBackup } from './backup.js';
|
|
8
9
|
import { expandPath } from './path-expander.js';
|
|
9
10
|
import { writeConfig } from '../config/config-file.js';
|
|
10
|
-
import {
|
|
11
|
-
const
|
|
11
|
+
import { getRepoWorkDir } from '../git/repo-client.js';
|
|
12
|
+
const MANIFEST_FILE = 'manifest.json';
|
|
12
13
|
/**
|
|
13
14
|
* Build a local Manifest from the current file system state.
|
|
14
15
|
*/
|
|
@@ -21,65 +22,117 @@ export function buildLocalManifest(config) {
|
|
|
21
22
|
return createManifest(entries);
|
|
22
23
|
}
|
|
23
24
|
/**
|
|
24
|
-
*
|
|
25
|
+
* Read the manifest stored in the repo working copy.
|
|
25
26
|
*/
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
function readRepoManifest(workDir) {
|
|
28
|
+
const manifestPath = path.join(workDir, MANIFEST_FILE);
|
|
29
|
+
if (!fs.existsSync(manifestPath))
|
|
30
|
+
return null;
|
|
31
|
+
try {
|
|
32
|
+
return parseManifest(fs.readFileSync(manifestPath, 'utf-8'));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
30
37
|
}
|
|
31
38
|
/**
|
|
32
|
-
*
|
|
39
|
+
* Write manifest to the repo working copy.
|
|
33
40
|
*/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
function writeRepoManifest(workDir, manifest) {
|
|
42
|
+
fs.writeFileSync(path.join(workDir, MANIFEST_FILE), JSON.stringify(manifest, null, 2), 'utf-8');
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Copy collected files into the repo working directory.
|
|
46
|
+
* Structure: workDir/<sourceName>/<relativePath>
|
|
47
|
+
*/
|
|
48
|
+
function copyFilesToRepo(config, workDir) {
|
|
49
|
+
const manifest = buildLocalManifest(config);
|
|
50
|
+
// Clear repo work dir (except .git)
|
|
51
|
+
for (const item of fs.readdirSync(workDir)) {
|
|
52
|
+
if (item === '.git')
|
|
53
|
+
continue;
|
|
54
|
+
const p = path.join(workDir, item);
|
|
55
|
+
fs.rmSync(p, { recursive: true, force: true });
|
|
39
56
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
57
|
+
for (const entry of manifest.entries) {
|
|
58
|
+
const syncPath = config.syncPaths.find((sp) => sp.name === entry.sourceName);
|
|
59
|
+
if (!syncPath)
|
|
60
|
+
continue;
|
|
61
|
+
const expandedBase = expandPath(syncPath.path);
|
|
62
|
+
const baseIsFile = (() => {
|
|
63
|
+
try {
|
|
64
|
+
return fs.statSync(expandedBase).isFile();
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
})();
|
|
70
|
+
let srcPath;
|
|
71
|
+
if (baseIsFile) {
|
|
72
|
+
srcPath = expandedBase;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
srcPath = path.join(expandedBase, entry.relativePath);
|
|
47
76
|
}
|
|
77
|
+
const destDir = path.join(workDir, entry.sourceName);
|
|
78
|
+
const destPath = path.join(destDir, entry.relativePath);
|
|
79
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
80
|
+
fs.copyFileSync(srcPath, destPath);
|
|
48
81
|
}
|
|
49
|
-
|
|
50
|
-
|
|
82
|
+
writeRepoManifest(workDir, manifest);
|
|
83
|
+
return manifest;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Push local files to the remote git repo.
|
|
87
|
+
*/
|
|
88
|
+
export async function pushSync(config, repoClient, force) {
|
|
89
|
+
const errors = [];
|
|
90
|
+
if (!config.repoUrl) {
|
|
91
|
+
return { success: false, action: 'push', filesUploaded: 0, filesDownloaded: 0, errors: ['No repo configured. Run `aitool-sync init` first.'] };
|
|
51
92
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
// If remote exists, check for conflicts
|
|
55
|
-
if (remoteManifest) {
|
|
56
|
-
const diff = diffManifests(localManifest, remoteManifest, lastKnown);
|
|
57
|
-
if (diff.hasConflicts && !force) {
|
|
58
|
-
return {
|
|
59
|
-
success: false,
|
|
60
|
-
action: 'push',
|
|
61
|
-
filesUploaded: 0,
|
|
62
|
-
filesDownloaded: 0,
|
|
63
|
-
errors: ['Conflicts detected. Use --force to overwrite remote.'],
|
|
64
|
-
};
|
|
65
|
-
}
|
|
93
|
+
if (!config.githubToken) {
|
|
94
|
+
return { success: false, action: 'push', filesUploaded: 0, filesDownloaded: 0, errors: ['GitHub token is required.'] };
|
|
66
95
|
}
|
|
67
|
-
|
|
68
|
-
const syncPackage = await buildSyncPackage(localManifest, config, encryptFn);
|
|
69
|
-
const packageJson = JSON.stringify(syncPackage, null, 2);
|
|
70
|
-
// Upload to Gist
|
|
96
|
+
const workDir = getRepoWorkDir();
|
|
71
97
|
try {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
98
|
+
// Clone or pull remote
|
|
99
|
+
await repoClient.cloneOrPull(config.repoUrl, workDir, config.githubToken);
|
|
100
|
+
// Check for remote changes (conflict detection)
|
|
101
|
+
const remoteManifest = readRepoManifest(workDir);
|
|
102
|
+
if (remoteManifest && !force) {
|
|
103
|
+
const localManifest = buildLocalManifest(config);
|
|
104
|
+
const lastKnown = config.lastKnownManifest ? parseManifest(config.lastKnownManifest) : null;
|
|
105
|
+
const diff = diffManifests(localManifest, remoteManifest, lastKnown);
|
|
106
|
+
if (diff.hasConflicts) {
|
|
107
|
+
return {
|
|
108
|
+
success: false,
|
|
109
|
+
action: 'push',
|
|
110
|
+
filesUploaded: 0,
|
|
111
|
+
filesDownloaded: 0,
|
|
112
|
+
errors: ['Conflicts detected. Use --force to overwrite remote.'],
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Create local backup before push
|
|
117
|
+
createBackup(config);
|
|
118
|
+
// Copy local files into repo and write manifest
|
|
119
|
+
const localManifest = copyFilesToRepo(config, workDir);
|
|
120
|
+
// Git add, commit, push
|
|
121
|
+
const hostname = os.hostname();
|
|
122
|
+
const git = simpleGit(workDir);
|
|
123
|
+
await git.addConfig('user.email', 'aitool-sync@localhost');
|
|
124
|
+
await git.addConfig('user.name', hostname);
|
|
125
|
+
await git.add('.');
|
|
126
|
+
const date = new Date().toISOString().replace('T', ' ').slice(0, 19);
|
|
127
|
+
await git.commit(`sync: ${localManifest.entries.length} file(s) from ${hostname} at ${date}`);
|
|
128
|
+
await git.push('origin', 'main');
|
|
75
129
|
// Update config
|
|
76
|
-
config.lastKnownManifest = serializeManifest(localManifest);
|
|
77
130
|
config.lastPushAt = new Date().toISOString();
|
|
78
131
|
writeConfig(config);
|
|
79
132
|
return {
|
|
80
133
|
success: true,
|
|
81
134
|
action: force ? 'force-push' : 'push',
|
|
82
|
-
filesUploaded:
|
|
135
|
+
filesUploaded: localManifest.entries.length,
|
|
83
136
|
filesDownloaded: 0,
|
|
84
137
|
errors: [],
|
|
85
138
|
};
|
|
@@ -90,117 +143,116 @@ export async function pushSync(config, gistClient, force, encryptFn) {
|
|
|
90
143
|
action: 'push',
|
|
91
144
|
filesUploaded: 0,
|
|
92
145
|
filesDownloaded: 0,
|
|
93
|
-
errors: [`
|
|
146
|
+
errors: [`Push failed: ${e.message}`],
|
|
94
147
|
};
|
|
95
148
|
}
|
|
96
149
|
}
|
|
97
150
|
/**
|
|
98
|
-
* Pull remote files from
|
|
151
|
+
* Pull remote files from git repo to local.
|
|
99
152
|
*/
|
|
100
|
-
export async function pullSync(config,
|
|
153
|
+
export async function pullSync(config, repoClient, force) {
|
|
101
154
|
const errors = [];
|
|
102
|
-
if (!config.
|
|
103
|
-
return { success: false, action: 'pull', filesUploaded: 0, filesDownloaded: 0, errors: ['No
|
|
155
|
+
if (!config.repoUrl) {
|
|
156
|
+
return { success: false, action: 'pull', filesUploaded: 0, filesDownloaded: 0, errors: ['No repo configured.'] };
|
|
157
|
+
}
|
|
158
|
+
if (!config.githubToken) {
|
|
159
|
+
return { success: false, action: 'pull', filesUploaded: 0, filesDownloaded: 0, errors: ['GitHub token is required.'] };
|
|
104
160
|
}
|
|
105
|
-
|
|
106
|
-
let gist;
|
|
161
|
+
const workDir = getRepoWorkDir();
|
|
107
162
|
try {
|
|
108
|
-
|
|
163
|
+
// Clone or pull remote
|
|
164
|
+
await repoClient.cloneOrPull(config.repoUrl, workDir, config.githubToken);
|
|
165
|
+
const remoteManifest = readRepoManifest(workDir);
|
|
166
|
+
if (!remoteManifest) {
|
|
167
|
+
return { success: false, action: 'pull', filesUploaded: 0, filesDownloaded: 0, errors: ['No manifest found in remote repo.'] };
|
|
168
|
+
}
|
|
169
|
+
// Check conflicts
|
|
170
|
+
if (!force) {
|
|
171
|
+
const localManifest = buildLocalManifest(config);
|
|
172
|
+
const lastKnown = config.lastKnownManifest ? parseManifest(config.lastKnownManifest) : null;
|
|
173
|
+
const diff = diffManifests(localManifest, remoteManifest, lastKnown);
|
|
174
|
+
if (diff.hasConflicts) {
|
|
175
|
+
return {
|
|
176
|
+
success: false,
|
|
177
|
+
action: 'pull',
|
|
178
|
+
filesUploaded: 0,
|
|
179
|
+
filesDownloaded: 0,
|
|
180
|
+
errors: ['Conflicts detected. Use --force to overwrite local files.'],
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Create backup before overwriting
|
|
185
|
+
createBackup(config);
|
|
186
|
+
// Write remote files to local destinations
|
|
187
|
+
let filesDownloaded = 0;
|
|
188
|
+
for (const entry of remoteManifest.entries) {
|
|
189
|
+
const syncPath = config.syncPaths.find((sp) => sp.name === entry.sourceName);
|
|
190
|
+
if (!syncPath) {
|
|
191
|
+
errors.push(`No matching sync path for source "${entry.sourceName}"`);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
const expandedBase = expandPath(syncPath.path);
|
|
195
|
+
let fullPath;
|
|
196
|
+
const baseStat = (() => {
|
|
197
|
+
try {
|
|
198
|
+
return fs.statSync(expandedBase);
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
})();
|
|
204
|
+
if (baseStat?.isFile()) {
|
|
205
|
+
fullPath = expandedBase;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
fullPath = path.join(expandedBase, entry.relativePath);
|
|
209
|
+
}
|
|
210
|
+
const repoFilePath = path.join(workDir, entry.sourceName, entry.relativePath);
|
|
211
|
+
if (!fs.existsSync(repoFilePath)) {
|
|
212
|
+
errors.push(`File not found in repo: ${entry.relativePath}`);
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
|
216
|
+
fs.copyFileSync(repoFilePath, fullPath);
|
|
217
|
+
filesDownloaded++;
|
|
218
|
+
}
|
|
219
|
+
// Update config
|
|
220
|
+
config.lastKnownManifest = JSON.stringify(remoteManifest);
|
|
221
|
+
config.lastPullAt = new Date().toISOString();
|
|
222
|
+
writeConfig(config);
|
|
223
|
+
return {
|
|
224
|
+
success: true,
|
|
225
|
+
action: force ? 'force-pull' : 'pull',
|
|
226
|
+
filesUploaded: 0,
|
|
227
|
+
filesDownloaded,
|
|
228
|
+
errors,
|
|
229
|
+
};
|
|
109
230
|
}
|
|
110
231
|
catch (e) {
|
|
111
|
-
return { success: false, action: 'pull', filesUploaded: 0, filesDownloaded: 0, errors: [`Failed to fetch Gist: ${e.message}`] };
|
|
112
|
-
}
|
|
113
|
-
const pkgFile = gist.files.find((f) => f.filename === PACKAGE_FILENAME);
|
|
114
|
-
if (!pkgFile) {
|
|
115
|
-
return { success: false, action: 'pull', filesUploaded: 0, filesDownloaded: 0, errors: ['No sync package found in Gist.'] };
|
|
116
|
-
}
|
|
117
|
-
const remotePackage = parseSyncPackage(pkgFile.content);
|
|
118
|
-
if (!remotePackage) {
|
|
119
|
-
return { success: false, action: 'pull', filesUploaded: 0, filesDownloaded: 0, errors: ['Failed to parse remote sync package.'] };
|
|
120
|
-
}
|
|
121
|
-
const remoteManifest = remotePackage.manifest;
|
|
122
|
-
const localManifest = buildLocalManifest(config);
|
|
123
|
-
const lastKnown = config.lastKnownManifest ? parseManifest(config.lastKnownManifest) : null;
|
|
124
|
-
// Check conflicts
|
|
125
|
-
const diff = diffManifests(localManifest, remoteManifest, lastKnown);
|
|
126
|
-
if (diff.hasConflicts && !force) {
|
|
127
232
|
return {
|
|
128
233
|
success: false,
|
|
129
234
|
action: 'pull',
|
|
130
235
|
filesUploaded: 0,
|
|
131
236
|
filesDownloaded: 0,
|
|
132
|
-
errors: [
|
|
237
|
+
errors: [`Pull failed: ${e.message}`],
|
|
133
238
|
};
|
|
134
239
|
}
|
|
135
|
-
// Create backup before overwriting
|
|
136
|
-
createBackup(config);
|
|
137
|
-
// Write files locally
|
|
138
|
-
const writeErrors = await writeRemoteFiles(remotePackage, config, decryptFn);
|
|
139
|
-
for (const e of writeErrors) {
|
|
140
|
-
errors.push(e);
|
|
141
|
-
}
|
|
142
|
-
// Update config
|
|
143
|
-
config.lastKnownManifest = serializeManifest(remoteManifest);
|
|
144
|
-
config.lastPullAt = new Date().toISOString();
|
|
145
|
-
writeConfig(config);
|
|
146
|
-
return {
|
|
147
|
-
success: true,
|
|
148
|
-
action: force ? 'force-pull' : 'pull',
|
|
149
|
-
filesUploaded: 0,
|
|
150
|
-
filesDownloaded: remotePackage.files.length,
|
|
151
|
-
errors,
|
|
152
|
-
};
|
|
153
240
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
// Check if the base path is a file or directory
|
|
170
|
-
const baseStat = (() => {
|
|
171
|
-
try {
|
|
172
|
-
return fs.statSync(expandedBase);
|
|
173
|
-
}
|
|
174
|
-
catch {
|
|
175
|
-
return null;
|
|
176
|
-
}
|
|
177
|
-
})();
|
|
178
|
-
if (baseStat?.isFile()) {
|
|
179
|
-
fullPath = expandedBase;
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
fullPath = path.join(expandedBase, file.relativePath);
|
|
183
|
-
}
|
|
184
|
-
// Ensure directory exists
|
|
185
|
-
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
|
186
|
-
let content;
|
|
187
|
-
if (file.encrypted && decryptFn) {
|
|
188
|
-
try {
|
|
189
|
-
// Content is base64(encrypted_payload), so decode outer base64 first
|
|
190
|
-
const decoded = Buffer.from(file.content, 'base64').toString('utf-8');
|
|
191
|
-
content = decryptFn(decoded);
|
|
192
|
-
}
|
|
193
|
-
catch (e) {
|
|
194
|
-
errors.push(`Failed to decrypt ${file.relativePath}: ${e.message}`);
|
|
195
|
-
continue;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
// Content is base64 encoded in the package
|
|
200
|
-
content = Buffer.from(file.content, 'base64').toString('utf-8');
|
|
201
|
-
}
|
|
202
|
-
fs.writeFileSync(fullPath, content, 'utf-8');
|
|
241
|
+
export async function buildRemoteDiff(config, repoClient) {
|
|
242
|
+
if (!config.repoUrl || !config.githubToken)
|
|
243
|
+
return null;
|
|
244
|
+
try {
|
|
245
|
+
const workDir = getRepoWorkDir();
|
|
246
|
+
await repoClient.cloneOrPull(config.repoUrl, workDir, config.githubToken);
|
|
247
|
+
const remoteManifest = readRepoManifest(workDir);
|
|
248
|
+
if (!remoteManifest)
|
|
249
|
+
return null;
|
|
250
|
+
const localManifest = buildLocalManifest(config);
|
|
251
|
+
const lastKnown = config.lastKnownManifest ? parseManifest(config.lastKnownManifest) : null;
|
|
252
|
+
return diffManifests(localManifest, remoteManifest, lastKnown);
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
return null;
|
|
203
256
|
}
|
|
204
|
-
return errors;
|
|
205
257
|
}
|
|
206
258
|
//# sourceMappingURL=sync-engine.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-engine.js","sourceRoot":"","sources":["../../src/core/sync-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-engine.js","sourceRoot":"","sources":["../../src/core/sync-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub API client for repo management.
|
|
3
|
+
*/
|
|
4
|
+
export declare class GitHubApiClient {
|
|
5
|
+
private octokit;
|
|
6
|
+
constructor(token: string);
|
|
7
|
+
/** Create a new private repo, returns the clone URL */
|
|
8
|
+
createRepo(name: string): Promise<string>;
|
|
9
|
+
/** Check if a repo exists and is accessible */
|
|
10
|
+
repoExists(owner: string, repo: string): Promise<boolean>;
|
|
11
|
+
/** Get authenticated user info */
|
|
12
|
+
getUsername(): Promise<string>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=github-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-api.d.ts","sourceRoot":"","sources":["../../src/git/github-api.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAU;gBAEb,KAAK,EAAE,MAAM;IAIzB,uDAAuD;IACjD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAW/C,+CAA+C;IACzC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS/D,kCAAkC;IAC5B,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;CAIrC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Octokit } from '@octokit/rest';
|
|
2
|
+
import { debug } from '../utils/logger.js';
|
|
3
|
+
/**
|
|
4
|
+
* GitHub API client for repo management.
|
|
5
|
+
*/
|
|
6
|
+
export class GitHubApiClient {
|
|
7
|
+
octokit;
|
|
8
|
+
constructor(token) {
|
|
9
|
+
this.octokit = new Octokit({ auth: token });
|
|
10
|
+
}
|
|
11
|
+
/** Create a new private repo, returns the clone URL */
|
|
12
|
+
async createRepo(name) {
|
|
13
|
+
debug(`Creating GitHub repo: ${name}`);
|
|
14
|
+
const response = await this.octokit.repos.createForAuthenticatedUser({
|
|
15
|
+
name,
|
|
16
|
+
private: true,
|
|
17
|
+
description: 'AI agent tool configs synced by aitool-sync',
|
|
18
|
+
auto_init: false,
|
|
19
|
+
});
|
|
20
|
+
return response.data.clone_url;
|
|
21
|
+
}
|
|
22
|
+
/** Check if a repo exists and is accessible */
|
|
23
|
+
async repoExists(owner, repo) {
|
|
24
|
+
try {
|
|
25
|
+
await this.octokit.repos.get({ owner, repo });
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Get authenticated user info */
|
|
33
|
+
async getUsername() {
|
|
34
|
+
const response = await this.octokit.users.getAuthenticated();
|
|
35
|
+
return response.data.login;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=github-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-api.js","sourceRoot":"","sources":["../../src/git/github-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C;;GAEG;AACH,MAAM,OAAO,eAAe;IAClB,OAAO,CAAU;IAEzB,YAAY,KAAa;QACvB,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,uDAAuD;IACvD,KAAK,CAAC,UAAU,CAAC,IAAY;QAC3B,KAAK,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC;YACnE,IAAI;YACJ,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,6CAA6C;YAC1D,SAAS,EAAE,KAAK;SACjB,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;IACjC,CAAC;IAED,+CAA+C;IAC/C,KAAK,CAAC,UAAU,CAAC,KAAa,EAAE,IAAY;QAC1C,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9C,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,KAAK,CAAC,WAAW;QACf,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAC7D,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;IAC7B,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { RepoClientInterface } from '../types/git.js';
|
|
2
|
+
/**
|
|
3
|
+
* Git repository client for GitHub-based sync storage.
|
|
4
|
+
* Clones the config repo to a local temp directory and provides
|
|
5
|
+
* an interface for the sync engine to interact with it.
|
|
6
|
+
*/
|
|
7
|
+
export declare class GitRepoClient implements RepoClientInterface {
|
|
8
|
+
/**
|
|
9
|
+
* Clone (if not exists) or pull (if exists) the repo.
|
|
10
|
+
*/
|
|
11
|
+
cloneOrPull(repoUrl: string, localPath: string, token: string): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Get the local working directory path for a given repo URL.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getRepoWorkDir(): string;
|
|
17
|
+
//# sourceMappingURL=repo-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-client.d.ts","sourceRoot":"","sources":["../../src/git/repo-client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D;;;;GAIG;AACH,qBAAa,aAAc,YAAW,mBAAmB;IACvD;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAkBpF;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { simpleGit } from 'simple-git';
|
|
5
|
+
import { debug } from '../utils/logger.js';
|
|
6
|
+
/**
|
|
7
|
+
* Git repository client for GitHub-based sync storage.
|
|
8
|
+
* Clones the config repo to a local temp directory and provides
|
|
9
|
+
* an interface for the sync engine to interact with it.
|
|
10
|
+
*/
|
|
11
|
+
export class GitRepoClient {
|
|
12
|
+
/**
|
|
13
|
+
* Clone (if not exists) or pull (if exists) the repo.
|
|
14
|
+
*/
|
|
15
|
+
async cloneOrPull(repoUrl, localPath, token) {
|
|
16
|
+
// Build authenticated URL
|
|
17
|
+
const url = new URL(repoUrl);
|
|
18
|
+
url.username = token;
|
|
19
|
+
url.password = 'x-oauth-basic';
|
|
20
|
+
const authUrl = url.toString();
|
|
21
|
+
if (fs.existsSync(localPath) && fs.existsSync(path.join(localPath, '.git'))) {
|
|
22
|
+
debug(`Pulling existing repo: ${repoUrl}`);
|
|
23
|
+
const git = simpleGit(localPath);
|
|
24
|
+
await git.raw(['remote', 'set-url', 'origin', authUrl]);
|
|
25
|
+
await git.pull('origin', 'main');
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
debug(`Cloning repo: ${repoUrl}`);
|
|
29
|
+
fs.mkdirSync(localPath, { recursive: true });
|
|
30
|
+
await simpleGit().clone(authUrl, localPath, ['--depth', '1']);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get the local working directory path for a given repo URL.
|
|
36
|
+
*/
|
|
37
|
+
export function getRepoWorkDir() {
|
|
38
|
+
return path.join(os.tmpdir(), 'aitool-sync-repo');
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=repo-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-client.js","sourceRoot":"","sources":["../../src/git/repo-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C;;;;GAIG;AACH,MAAM,OAAO,aAAa;IACxB;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,SAAiB,EAAE,KAAa;QACjE,0BAA0B;QAC1B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7B,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAC;QACrB,GAAG,CAAC,QAAQ,GAAG,eAAe,CAAC;QAC/B,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAE/B,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;YAC5E,KAAK,CAAC,0BAA0B,OAAO,EAAE,CAAC,CAAC;YAC3C,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;YACjC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;YACxD,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;YAClC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,MAAM,SAAS,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/presets/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,eAAO,MAAM,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/presets/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,eAAO,MAAM,gBAAgB,EAAE,UA8B9B,CAAC"}
|
|
@@ -18,6 +18,11 @@ export const claudeCodePreset = {
|
|
|
18
18
|
path: '~/.claude/claude.json',
|
|
19
19
|
enabled: true,
|
|
20
20
|
},
|
|
21
|
+
{
|
|
22
|
+
name: 'claude-code-skills',
|
|
23
|
+
path: '~/.claude/skills/',
|
|
24
|
+
enabled: true,
|
|
25
|
+
},
|
|
21
26
|
],
|
|
22
27
|
defaultExclusions: [
|
|
23
28
|
{ pattern: '**/.claude/credentials.json' },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/presets/claude-code.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,EAAE,EAAE,aAAa;IACjB,IAAI,EAAE,aAAa;IACnB,WAAW,EAAE,8CAA8C;IAC3D,YAAY,EAAE;QACZ;YACE,IAAI,EAAE,sBAAsB;YAC5B,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EAAE,IAAI;SACd;QACD;YACE,IAAI,EAAE,iBAAiB;YACvB,IAAI,EAAE,oBAAoB;YAC1B,OAAO,EAAE,IAAI;SACd;QACD;YACE,IAAI,EAAE,yBAAyB;YAC/B,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,IAAI;SACd;KACF;IACD,iBAAiB,EAAE;QACjB,EAAE,OAAO,EAAE,6BAA6B,EAAE;QAC1C,EAAE,OAAO,EAAE,kBAAkB,EAAE;KAChC;CACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/presets/claude-code.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,EAAE,EAAE,aAAa;IACjB,IAAI,EAAE,aAAa;IACnB,WAAW,EAAE,8CAA8C;IAC3D,YAAY,EAAE;QACZ;YACE,IAAI,EAAE,sBAAsB;YAC5B,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EAAE,IAAI;SACd;QACD;YACE,IAAI,EAAE,iBAAiB;YACvB,IAAI,EAAE,oBAAoB;YAC1B,OAAO,EAAE,IAAI;SACd;QACD;YACE,IAAI,EAAE,yBAAyB;YAC/B,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,IAAI;SACd;QACD;YACE,IAAI,EAAE,oBAAoB;YAC1B,IAAI,EAAE,mBAAmB;YACzB,OAAO,EAAE,IAAI;SACd;KACF;IACD,iBAAiB,EAAE;QACjB,EAAE,OAAO,EAAE,6BAA6B,EAAE;QAC1C,EAAE,OAAO,EAAE,kBAAkB,EAAE;KAChC;CACF,CAAC"}
|
package/dist/types/config.d.ts
CHANGED
|
@@ -25,8 +25,8 @@ export interface ToolPreset {
|
|
|
25
25
|
export interface AppConfig {
|
|
26
26
|
/** Config file version (for schema migration) */
|
|
27
27
|
version: 1;
|
|
28
|
-
/** GitHub
|
|
29
|
-
|
|
28
|
+
/** GitHub repository URL for sync storage (e.g. https://github.com/user/configs) */
|
|
29
|
+
repoUrl: string | null;
|
|
30
30
|
/** GitHub personal access token (stored locally, never synced) */
|
|
31
31
|
githubToken: string | null;
|
|
32
32
|
/** Paths to sync */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,YAAY,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,aAAa,EAAE,CAAC;IAC9B,iBAAiB,EAAE,aAAa,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,SAAS;IACxB,iDAAiD;IACjD,OAAO,EAAE,CAAC,CAAC;IACX,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,YAAY,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,aAAa,EAAE,CAAC;IAC9B,iBAAiB,EAAE,aAAa,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,SAAS;IACxB,iDAAiD;IACjD,OAAO,EAAE,CAAC,CAAC;IACX,oFAAoF;IACpF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,kEAAkE;IAClE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,oBAAoB;IACpB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,8BAA8B;IAC9B,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,+BAA+B;IAC/B,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,iEAAiE;IACjE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,wCAAwC;IACxC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,wCAAwC;IACxC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/types/git.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/E"}
|