grf-cli 1.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 (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +503 -0
  3. package/README.zh-CN.md +503 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +74 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands/add.d.ts +7 -0
  9. package/dist/commands/add.d.ts.map +1 -0
  10. package/dist/commands/add.js +92 -0
  11. package/dist/commands/add.js.map +1 -0
  12. package/dist/commands/clean.d.ts +7 -0
  13. package/dist/commands/clean.d.ts.map +1 -0
  14. package/dist/commands/clean.js +171 -0
  15. package/dist/commands/clean.js.map +1 -0
  16. package/dist/commands/config.d.ts +7 -0
  17. package/dist/commands/config.d.ts.map +1 -0
  18. package/dist/commands/config.js +170 -0
  19. package/dist/commands/config.js.map +1 -0
  20. package/dist/commands/list.d.ts +7 -0
  21. package/dist/commands/list.d.ts.map +1 -0
  22. package/dist/commands/list.js +149 -0
  23. package/dist/commands/list.js.map +1 -0
  24. package/dist/commands/load.d.ts +8 -0
  25. package/dist/commands/load.d.ts.map +1 -0
  26. package/dist/commands/load.js +239 -0
  27. package/dist/commands/load.js.map +1 -0
  28. package/dist/commands/unload.d.ts +7 -0
  29. package/dist/commands/unload.d.ts.map +1 -0
  30. package/dist/commands/unload.js +738 -0
  31. package/dist/commands/unload.js.map +1 -0
  32. package/dist/commands/update.d.ts +7 -0
  33. package/dist/commands/update.d.ts.map +1 -0
  34. package/dist/commands/update.js +471 -0
  35. package/dist/commands/update.js.map +1 -0
  36. package/dist/commands/use.d.ts +8 -0
  37. package/dist/commands/use.d.ts.map +1 -0
  38. package/dist/commands/use.js +224 -0
  39. package/dist/commands/use.js.map +1 -0
  40. package/dist/core/config.d.ts +55 -0
  41. package/dist/core/config.d.ts.map +1 -0
  42. package/dist/core/config.js +179 -0
  43. package/dist/core/config.js.map +1 -0
  44. package/dist/core/filesystem.d.ts +74 -0
  45. package/dist/core/filesystem.d.ts.map +1 -0
  46. package/dist/core/filesystem.js +300 -0
  47. package/dist/core/filesystem.js.map +1 -0
  48. package/dist/core/git.d.ts +75 -0
  49. package/dist/core/git.d.ts.map +1 -0
  50. package/dist/core/git.js +169 -0
  51. package/dist/core/git.js.map +1 -0
  52. package/dist/core/loading.d.ts +85 -0
  53. package/dist/core/loading.d.ts.map +1 -0
  54. package/dist/core/loading.js +224 -0
  55. package/dist/core/loading.js.map +1 -0
  56. package/dist/core/repository.d.ts +120 -0
  57. package/dist/core/repository.d.ts.map +1 -0
  58. package/dist/core/repository.js +374 -0
  59. package/dist/core/repository.js.map +1 -0
  60. package/dist/core/sync.d.ts +72 -0
  61. package/dist/core/sync.d.ts.map +1 -0
  62. package/dist/core/sync.js +226 -0
  63. package/dist/core/sync.js.map +1 -0
  64. package/dist/types/index.d.ts +135 -0
  65. package/dist/types/index.d.ts.map +1 -0
  66. package/dist/types/index.js +63 -0
  67. package/dist/types/index.js.map +1 -0
  68. package/package.json +59 -0
@@ -0,0 +1,300 @@
1
+ "use strict";
2
+ /**
3
+ * FileSystem 模块
4
+ * 封装文件系统操作,提供复制、删除等功能
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.copyDir = copyDir;
11
+ exports.copyFile = copyFile;
12
+ exports.removeDir = removeDir;
13
+ exports.exists = exists;
14
+ exports.ensureDir = ensureDir;
15
+ exports.updateGitignore = updateGitignore;
16
+ exports.readDir = readDir;
17
+ exports.isDirectory = isDirectory;
18
+ exports.removeFromGitignore = removeFromGitignore;
19
+ const fs_extra_1 = __importDefault(require("fs-extra"));
20
+ const path_1 = __importDefault(require("path"));
21
+ const index_js_1 = require("../types/index.js");
22
+ /**
23
+ * 复制目录
24
+ * @param src 源目录路径
25
+ * @param dest 目标目录路径
26
+ * @param options 复制选项
27
+ */
28
+ async function copyDir(src, dest, options) {
29
+ try {
30
+ await fs_extra_1.default.copy(src, dest, {
31
+ overwrite: options?.overwrite ?? true,
32
+ filter: (srcPath) => {
33
+ const basename = path_1.default.basename(srcPath);
34
+ return !options?.exclude?.includes(basename);
35
+ },
36
+ });
37
+ }
38
+ catch (error) {
39
+ const err = error;
40
+ if (err.code === "ENOENT") {
41
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_PATH_NOT_FOUND, `源路径不存在: ${src}`, err);
42
+ }
43
+ if (err.code === "EACCES" || err.code === "EPERM") {
44
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_PERMISSION_DENIED, `权限被拒绝: ${src} -> ${dest}`, err);
45
+ }
46
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_COPY_FAILED, `复制目录失败: ${src} -> ${dest}`, err);
47
+ }
48
+ }
49
+ /**
50
+ * 复制单个文件
51
+ * @param src 源文件路径
52
+ * @param dest 目标文件路径
53
+ */
54
+ async function copyFile(src, dest) {
55
+ try {
56
+ // 确保目标目录存在
57
+ await fs_extra_1.default.ensureDir(path_1.default.dirname(dest));
58
+ await fs_extra_1.default.copy(src, dest);
59
+ }
60
+ catch (error) {
61
+ const err = error;
62
+ if (err.code === "ENOENT") {
63
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_PATH_NOT_FOUND, `源文件不存在: ${src}`, err);
64
+ }
65
+ if (err.code === "EACCES" || err.code === "EPERM") {
66
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_PERMISSION_DENIED, `权限被拒绝: ${src} -> ${dest}`, err);
67
+ }
68
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_COPY_FAILED, `复制文件失败: ${src} -> ${dest}`, err);
69
+ }
70
+ }
71
+ /**
72
+ * 删除目录(递归删除)
73
+ * @param dirPath 要删除的目录路径
74
+ */
75
+ async function removeDir(dirPath) {
76
+ try {
77
+ await fs_extra_1.default.remove(dirPath);
78
+ }
79
+ catch (error) {
80
+ const err = error;
81
+ if (err.code === "EACCES" || err.code === "EPERM") {
82
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_PERMISSION_DENIED, `权限被拒绝,无法删除: ${dirPath}`, err);
83
+ }
84
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_COPY_FAILED, `删除目录失败: ${dirPath}`, err);
85
+ }
86
+ }
87
+ /**
88
+ * 检查路径是否存在
89
+ * @param filePath 要检查的路径
90
+ * @returns 路径是否存在
91
+ */
92
+ async function exists(filePath) {
93
+ return fs_extra_1.default.pathExists(filePath);
94
+ }
95
+ /**
96
+ * 确保目录存在(不存在则创建)
97
+ * @param dirPath 目录路径
98
+ */
99
+ async function ensureDir(dirPath) {
100
+ try {
101
+ await fs_extra_1.default.ensureDir(dirPath);
102
+ }
103
+ catch (error) {
104
+ const err = error;
105
+ if (err.code === "EACCES" || err.code === "EPERM") {
106
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_PERMISSION_DENIED, `权限被拒绝,无法创建目录: ${dirPath}`, err);
107
+ }
108
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_COPY_FAILED, `创建目录失败: ${dirPath}`, err);
109
+ }
110
+ }
111
+ /**
112
+ * 更新 .gitignore 文件
113
+ * 如果指定条目不存在,则追加到文件末尾
114
+ * 优化:将所有 gitreference 管理的条目放在同一个注释块下
115
+ * @param dir 目录路径
116
+ * @param entry 要添加的条目
117
+ */
118
+ async function updateGitignore(dir, entry) {
119
+ const GITREFERENCE_COMMENT = "# Added by gitreference";
120
+ try {
121
+ const gitignorePath = path_1.default.join(dir, ".gitignore");
122
+ let content = "";
123
+ if (await fs_extra_1.default.pathExists(gitignorePath)) {
124
+ content = await fs_extra_1.default.readFile(gitignorePath, "utf-8");
125
+ }
126
+ const lines = content.split("\n");
127
+ const trimmedEntry = entry.trim();
128
+ // 检查条目是否已存在(按行检查,避免部分匹配)
129
+ const trimmedLines = lines.map((line) => line.trim());
130
+ if (trimmedLines.includes(trimmedEntry)) {
131
+ return; // 条目已存在,无需添加
132
+ }
133
+ // 查找现有的 gitreference 注释块
134
+ let commentIndex = -1;
135
+ let lastGitrefEntryIndex = -1;
136
+ for (let i = 0; i < lines.length; i++) {
137
+ const trimmedLine = lines[i].trim();
138
+ if (trimmedLine === GITREFERENCE_COMMENT) {
139
+ if (commentIndex === -1) {
140
+ commentIndex = i;
141
+ }
142
+ lastGitrefEntryIndex = i;
143
+ }
144
+ else if (commentIndex !== -1 &&
145
+ trimmedLine !== "" &&
146
+ !trimmedLine.startsWith("#")) {
147
+ // 在注释块后找到非空、非注释行,更新最后条目位置
148
+ lastGitrefEntryIndex = i;
149
+ }
150
+ else if (commentIndex !== -1 && trimmedLine === "") {
151
+ // 遇到空行,检查是否是 gitreference 块的结束
152
+ // 继续查找,可能有多个 gitreference 块需要合并
153
+ }
154
+ }
155
+ if (commentIndex !== -1) {
156
+ // 找到现有的 gitreference 块,在最后一个条目后插入新条目
157
+ // 首先需要找到该块的实际结束位置
158
+ let insertIndex = lastGitrefEntryIndex + 1;
159
+ // 在现有块后插入新条目
160
+ lines.splice(insertIndex, 0, trimmedEntry);
161
+ // 写回文件
162
+ await fs_extra_1.default.writeFile(gitignorePath, lines.join("\n"), "utf-8");
163
+ }
164
+ else {
165
+ // 没有找到现有块,追加新块
166
+ const newEntry = `\n${GITREFERENCE_COMMENT}\n${trimmedEntry}\n`;
167
+ await fs_extra_1.default.appendFile(gitignorePath, newEntry);
168
+ }
169
+ }
170
+ catch (error) {
171
+ const err = error;
172
+ if (err.code === "EACCES" || err.code === "EPERM") {
173
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_PERMISSION_DENIED, `权限被拒绝,无法更新 .gitignore: ${dir}`, err);
174
+ }
175
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_COPY_FAILED, `更新 .gitignore 失败: ${dir}`, err);
176
+ }
177
+ }
178
+ /**
179
+ * 读取目录内容
180
+ * @param dirPath 目录路径
181
+ * @returns 文件/目录名数组
182
+ */
183
+ async function readDir(dirPath) {
184
+ try {
185
+ return await fs_extra_1.default.readdir(dirPath);
186
+ }
187
+ catch (error) {
188
+ const err = error;
189
+ if (err.code === "ENOENT") {
190
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_PATH_NOT_FOUND, `目录不存在: ${dirPath}`, err);
191
+ }
192
+ if (err.code === "EACCES" || err.code === "EPERM") {
193
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_PERMISSION_DENIED, `权限被拒绝,无法读取目录: ${dirPath}`, err);
194
+ }
195
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_COPY_FAILED, `读取目录失败: ${dirPath}`, err);
196
+ }
197
+ }
198
+ /**
199
+ * 检查路径是否为目录
200
+ * @param filePath 要检查的路径
201
+ * @returns 是否为目录
202
+ */
203
+ async function isDirectory(filePath) {
204
+ try {
205
+ const stat = await fs_extra_1.default.stat(filePath);
206
+ return stat.isDirectory();
207
+ }
208
+ catch (error) {
209
+ const err = error;
210
+ if (err.code === "ENOENT") {
211
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_PATH_NOT_FOUND, `路径不存在: ${filePath}`, err);
212
+ }
213
+ if (err.code === "EACCES" || err.code === "EPERM") {
214
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_PERMISSION_DENIED, `权限被拒绝,无法访问: ${filePath}`, err);
215
+ }
216
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_COPY_FAILED, `获取文件信息失败: ${filePath}`, err);
217
+ }
218
+ }
219
+ /**
220
+ * 从 .gitignore 文件中移除指定条目
221
+ * @param dir 目录路径(包含 .gitignore 的目录)
222
+ * @param entry 要移除的条目
223
+ * @param options 移除选项
224
+ * @returns 是否成功移除(条目存在并被移除返回 true)
225
+ */
226
+ async function removeFromGitignore(dir, entry, options) {
227
+ const removeComment = options?.removeComment ?? true;
228
+ const gitignorePath = path_1.default.join(dir, ".gitignore");
229
+ try {
230
+ // 检查 .gitignore 文件是否存在
231
+ if (!(await fs_extra_1.default.pathExists(gitignorePath))) {
232
+ return false;
233
+ }
234
+ // 读取文件内容
235
+ const content = await fs_extra_1.default.readFile(gitignorePath, "utf-8");
236
+ const lines = content.split("\n");
237
+ // 标记要删除的行索引
238
+ const linesToDelete = new Set();
239
+ const trimmedEntry = entry.trim();
240
+ let found = false;
241
+ // 遍历每一行,查找匹配的条目
242
+ for (let i = 0; i < lines.length; i++) {
243
+ const trimmedLine = lines[i].trim();
244
+ if (trimmedLine === trimmedEntry) {
245
+ found = true;
246
+ linesToDelete.add(i);
247
+ // 如果 removeComment 为 true,检查上一行是否为注释
248
+ if (removeComment && i > 0) {
249
+ const prevLine = lines[i - 1].trim();
250
+ if (prevLine === "# Added by gitreference") {
251
+ linesToDelete.add(i - 1);
252
+ }
253
+ }
254
+ }
255
+ }
256
+ // 如果没有找到匹配的行,返回 false
257
+ if (!found) {
258
+ return false;
259
+ }
260
+ // 过滤掉标记为删除的行
261
+ const filteredLines = lines.filter((_, index) => !linesToDelete.has(index));
262
+ // 清理多余的空行(连续多个空行合并为一个)
263
+ const cleanedLines = [];
264
+ let prevLineEmpty = false;
265
+ for (const line of filteredLines) {
266
+ const isEmpty = line.trim() === "";
267
+ if (isEmpty) {
268
+ if (!prevLineEmpty) {
269
+ cleanedLines.push(line);
270
+ }
271
+ prevLineEmpty = true;
272
+ }
273
+ else {
274
+ cleanedLines.push(line);
275
+ prevLineEmpty = false;
276
+ }
277
+ }
278
+ // 移除开头和结尾的空行
279
+ while (cleanedLines.length > 0 && cleanedLines[0].trim() === "") {
280
+ cleanedLines.shift();
281
+ }
282
+ while (cleanedLines.length > 0 &&
283
+ cleanedLines[cleanedLines.length - 1].trim() === "") {
284
+ cleanedLines.pop();
285
+ }
286
+ // 写回文件
287
+ const newContent = cleanedLines.length > 0 ? cleanedLines.join("\n") + "\n" : "";
288
+ await fs_extra_1.default.writeFile(gitignorePath, newContent, "utf-8");
289
+ return true;
290
+ }
291
+ catch (error) {
292
+ const err = error;
293
+ if (err.code === "EACCES" || err.code === "EPERM") {
294
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.FS_PERMISSION_DENIED, `权限被拒绝,无法更新 .gitignore: ${dir}`, err);
295
+ }
296
+ // 其他错误静默处理,返回 false
297
+ return false;
298
+ }
299
+ }
300
+ //# sourceMappingURL=filesystem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../src/core/filesystem.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Git 模块
3
+ * 封装所有 Git 命令的执行,提供类型安全的接口
4
+ */
5
+ /**
6
+ * Git 克隆选项
7
+ */
8
+ export interface CloneOptions {
9
+ /** 指定分支 */
10
+ branch?: string;
11
+ /** 浅克隆深度 */
12
+ depth?: number;
13
+ /** 是否浅克隆 */
14
+ shallow?: boolean;
15
+ }
16
+ /**
17
+ * 克隆 Git 仓库
18
+ * @param url 仓库 URL
19
+ * @param dest 目标路径
20
+ * @param options 克隆选项
21
+ */
22
+ export declare function clone(url: string, dest: string, options?: CloneOptions): Promise<void>;
23
+ /**
24
+ * 拉取远程更新
25
+ * @param repoPath 仓库路径
26
+ */
27
+ export declare function pull(repoPath: string): Promise<void>;
28
+ /**
29
+ * 获取当前 commit ID
30
+ * @param repoPath 仓库路径
31
+ * @returns 完整的 40 字符 SHA
32
+ */
33
+ export declare function getCurrentCommit(repoPath: string): Promise<string>;
34
+ /**
35
+ * 获取远程仓库 URL
36
+ * @param repoPath 仓库路径
37
+ * @returns 远程 URL
38
+ */
39
+ export declare function getRemoteUrl(repoPath: string): Promise<string>;
40
+ /**
41
+ * 检查是否有远程更新
42
+ * @param repoPath 仓库路径
43
+ * @returns 是否有更新
44
+ */
45
+ export declare function hasUpdates(repoPath: string): Promise<boolean>;
46
+ /**
47
+ * 获取当前分支名
48
+ * @param repoPath 仓库路径
49
+ * @returns 分支名称
50
+ */
51
+ export declare function getBranch(repoPath: string): Promise<string>;
52
+ /**
53
+ * 检查路径是否是 Git 仓库
54
+ * @param path 要检查的路径
55
+ * @returns 是否是 Git 仓库
56
+ */
57
+ export declare function isGitRepo(path: string): Promise<boolean>;
58
+ /**
59
+ * 获取远程更新(不合并)
60
+ * @param repoPath 仓库路径
61
+ */
62
+ export declare function fetch(repoPath: string): Promise<void>;
63
+ /**
64
+ * 切换到指定分支
65
+ * @param repoPath 仓库路径
66
+ * @param branch 目标分支名
67
+ */
68
+ export declare function checkout(repoPath: string, branch: string): Promise<void>;
69
+ /**
70
+ * 获取所有远程分支列表
71
+ * @param repoPath 仓库路径
72
+ * @returns 分支名称数组
73
+ */
74
+ export declare function listRemoteBranches(repoPath: string): Promise<string[]>;
75
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/core/git.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,WAAW;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAmCD;;;;;GAKG;AACH,wBAAsB,KAAK,CACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED;;;GAGG;AACH,wBAAsB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1D;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMxE;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMpE;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA6BnE;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMjE;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAW9D;AAED;;;GAGG;AACH,wBAAsB,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3D;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CA6Bf;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAa5E"}
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ /**
3
+ * Git 模块
4
+ * 封装所有 Git 命令的执行,提供类型安全的接口
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.clone = clone;
8
+ exports.pull = pull;
9
+ exports.getCurrentCommit = getCurrentCommit;
10
+ exports.getRemoteUrl = getRemoteUrl;
11
+ exports.hasUpdates = hasUpdates;
12
+ exports.getBranch = getBranch;
13
+ exports.isGitRepo = isGitRepo;
14
+ exports.fetch = fetch;
15
+ exports.checkout = checkout;
16
+ exports.listRemoteBranches = listRemoteBranches;
17
+ const child_process_1 = require("child_process");
18
+ const util_1 = require("util");
19
+ const index_js_1 = require("../types/index.js");
20
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
21
+ /**
22
+ * 执行 Git 命令的内部函数
23
+ * @param args Git 命令参数数组
24
+ * @param options 执行选项
25
+ * @param errorCode 失败时使用的错误码
26
+ * @returns 命令输出(已去除首尾空白)
27
+ */
28
+ async function execGit(args, options, errorCode = index_js_1.ErrorCode.GIT_CLONE_FAILED) {
29
+ const command = `git ${args.join(" ")}`;
30
+ try {
31
+ const { stdout } = await execAsync(command, { cwd: options?.cwd });
32
+ return stdout.trim();
33
+ }
34
+ catch (error) {
35
+ throw new index_js_1.GrfError(errorCode, `Git command failed: ${command}`, error);
36
+ }
37
+ }
38
+ /**
39
+ * 克隆 Git 仓库
40
+ * @param url 仓库 URL
41
+ * @param dest 目标路径
42
+ * @param options 克隆选项
43
+ */
44
+ async function clone(url, dest, options) {
45
+ const args = ["clone"];
46
+ // 处理浅克隆选项
47
+ if (options?.shallow || options?.depth) {
48
+ const depth = options.depth ?? 1;
49
+ args.push("--depth", depth.toString());
50
+ }
51
+ // 处理分支选项
52
+ if (options?.branch) {
53
+ args.push("--branch", options.branch);
54
+ }
55
+ args.push(url, dest);
56
+ await execGit(args, undefined, index_js_1.ErrorCode.GIT_CLONE_FAILED);
57
+ }
58
+ /**
59
+ * 拉取远程更新
60
+ * @param repoPath 仓库路径
61
+ */
62
+ async function pull(repoPath) {
63
+ await execGit(["pull"], { cwd: repoPath }, index_js_1.ErrorCode.GIT_PULL_FAILED);
64
+ }
65
+ /**
66
+ * 获取当前 commit ID
67
+ * @param repoPath 仓库路径
68
+ * @returns 完整的 40 字符 SHA
69
+ */
70
+ async function getCurrentCommit(repoPath) {
71
+ return execGit(["rev-parse", "HEAD"], { cwd: repoPath }, index_js_1.ErrorCode.GIT_CLONE_FAILED);
72
+ }
73
+ /**
74
+ * 获取远程仓库 URL
75
+ * @param repoPath 仓库路径
76
+ * @returns 远程 URL
77
+ */
78
+ async function getRemoteUrl(repoPath) {
79
+ return execGit(["remote", "get-url", "origin"], { cwd: repoPath }, index_js_1.ErrorCode.GIT_CLONE_FAILED);
80
+ }
81
+ /**
82
+ * 检查是否有远程更新
83
+ * @param repoPath 仓库路径
84
+ * @returns 是否有更新
85
+ */
86
+ async function hasUpdates(repoPath) {
87
+ // 先获取远程更新
88
+ await fetch(repoPath);
89
+ // 获取当前分支
90
+ const branch = await getBranch(repoPath);
91
+ // 比较本地和远程的差异
92
+ try {
93
+ const count = await execGit(["rev-list", `HEAD..origin/${branch}`, "--count"], { cwd: repoPath }, index_js_1.ErrorCode.GIT_CLONE_FAILED);
94
+ return parseInt(count, 10) > 0;
95
+ }
96
+ catch {
97
+ // 如果比较失败(例如远程分支不存在),尝试使用 origin/HEAD
98
+ try {
99
+ const count = await execGit(["rev-list", "HEAD..origin/HEAD", "--count"], { cwd: repoPath }, index_js_1.ErrorCode.GIT_CLONE_FAILED);
100
+ return parseInt(count, 10) > 0;
101
+ }
102
+ catch {
103
+ // 如果都失败了,假设没有更新
104
+ return false;
105
+ }
106
+ }
107
+ }
108
+ /**
109
+ * 获取当前分支名
110
+ * @param repoPath 仓库路径
111
+ * @returns 分支名称
112
+ */
113
+ async function getBranch(repoPath) {
114
+ return execGit(["rev-parse", "--abbrev-ref", "HEAD"], { cwd: repoPath }, index_js_1.ErrorCode.GIT_CLONE_FAILED);
115
+ }
116
+ /**
117
+ * 检查路径是否是 Git 仓库
118
+ * @param path 要检查的路径
119
+ * @returns 是否是 Git 仓库
120
+ */
121
+ async function isGitRepo(path) {
122
+ try {
123
+ await execGit(["rev-parse", "--git-dir"], { cwd: path }, index_js_1.ErrorCode.GIT_CLONE_FAILED);
124
+ return true;
125
+ }
126
+ catch {
127
+ return false;
128
+ }
129
+ }
130
+ /**
131
+ * 获取远程更新(不合并)
132
+ * @param repoPath 仓库路径
133
+ */
134
+ async function fetch(repoPath) {
135
+ await execGit(["fetch"], { cwd: repoPath }, index_js_1.ErrorCode.GIT_CLONE_FAILED);
136
+ }
137
+ /**
138
+ * 切换到指定分支
139
+ * @param repoPath 仓库路径
140
+ * @param branch 目标分支名
141
+ */
142
+ async function checkout(repoPath, branch) {
143
+ try {
144
+ // 1. 修改 fetch 配置以支持获取所有分支(解决浅克隆问题)
145
+ await execGit(["config", "remote.origin.fetch", "+refs/heads/*:refs/remotes/origin/*"], { cwd: repoPath }, index_js_1.ErrorCode.GIT_CHECKOUT_FAILED);
146
+ // 2. 获取指定分支
147
+ await execGit(["fetch", "origin", branch], { cwd: repoPath }, index_js_1.ErrorCode.GIT_CHECKOUT_FAILED);
148
+ // 3. 切换到指定分支
149
+ await execGit(["checkout", branch], { cwd: repoPath }, index_js_1.ErrorCode.GIT_CHECKOUT_FAILED);
150
+ }
151
+ catch (error) {
152
+ throw new index_js_1.GrfError(index_js_1.ErrorCode.GIT_CHECKOUT_FAILED, `Git command failed: git checkout ${branch}\n Branch "${branch}" may not exist. Use git branch -r to list available branches.`, error);
153
+ }
154
+ }
155
+ /**
156
+ * 获取所有远程分支列表
157
+ * @param repoPath 仓库路径
158
+ * @returns 分支名称数组
159
+ */
160
+ async function listRemoteBranches(repoPath) {
161
+ const output = await execGit(["branch", "-r"], { cwd: repoPath }, index_js_1.ErrorCode.GIT_CLONE_FAILED);
162
+ // 解析输出,每行一个分支,格式如 " origin/main" 或 " origin/HEAD -> origin/main"
163
+ return output
164
+ .split("\n")
165
+ .map((line) => line.trim())
166
+ .filter((line) => line && !line.includes("->")) // 过滤空行和 HEAD 指针
167
+ .map((line) => line.replace(/^origin\//, "")); // 移除 origin/ 前缀
168
+ }
169
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/core/git.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AA2DH,sBAqBC;AAMD,oBAEC;AAOD,4CAMC;AAOD,oCAMC;AAOD,gCA6BC;AAOD,8BAMC;AAOD,8BAWC;AAMD,sBAEC;AAOD,4BAgCC;AAOD,gDAaC;AAtPD,iDAAqC;AACrC,+BAAiC;AACjC,gDAAwD;AAExD,MAAM,SAAS,GAAG,IAAA,gBAAS,EAAC,oBAAI,CAAC,CAAC;AAsBlC;;;;;;GAMG;AACH,KAAK,UAAU,OAAO,CACpB,IAAc,EACd,OAAqB,EACrB,YAAuB,oBAAS,CAAC,gBAAgB;IAEjD,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IACxC,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QACnE,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,mBAAQ,CAChB,SAAS,EACT,uBAAuB,OAAO,EAAE,EAChC,KAAc,CACf,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,KAAK,CACzB,GAAW,EACX,IAAY,EACZ,OAAsB;IAEtB,MAAM,IAAI,GAAa,CAAC,OAAO,CAAC,CAAC;IAEjC,UAAU;IACV,IAAI,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,KAAK,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,SAAS;IACT,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAErB,MAAM,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,oBAAS,CAAC,gBAAgB,CAAC,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,IAAI,CAAC,QAAgB;IACzC,MAAM,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,oBAAS,CAAC,eAAe,CAAC,CAAC;AACxE,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,gBAAgB,CAAC,QAAgB;IACrD,OAAO,OAAO,CACZ,CAAC,WAAW,EAAE,MAAM,CAAC,EACrB,EAAE,GAAG,EAAE,QAAQ,EAAE,EACjB,oBAAS,CAAC,gBAAgB,CAC3B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,OAAO,OAAO,CACZ,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,EAC/B,EAAE,GAAG,EAAE,QAAQ,EAAE,EACjB,oBAAS,CAAC,gBAAgB,CAC3B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,UAAU;IACV,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;IAEtB,SAAS;IACT,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;IAEzC,aAAa;IACb,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,OAAO,CACzB,CAAC,UAAU,EAAE,gBAAgB,MAAM,EAAE,EAAE,SAAS,CAAC,EACjD,EAAE,GAAG,EAAE,QAAQ,EAAE,EACjB,oBAAS,CAAC,gBAAgB,CAC3B,CAAC;QACF,OAAO,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,qCAAqC;QACrC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,OAAO,CACzB,CAAC,UAAU,EAAE,mBAAmB,EAAE,SAAS,CAAC,EAC5C,EAAE,GAAG,EAAE,QAAQ,EAAE,EACjB,oBAAS,CAAC,gBAAgB,CAC3B,CAAC;YACF,OAAO,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB;YAChB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,SAAS,CAAC,QAAgB;IAC9C,OAAO,OAAO,CACZ,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,EACrC,EAAE,GAAG,EAAE,QAAQ,EAAE,EACjB,oBAAS,CAAC,gBAAgB,CAC3B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,SAAS,CAAC,IAAY;IAC1C,IAAI,CAAC;QACH,MAAM,OAAO,CACX,CAAC,WAAW,EAAE,WAAW,CAAC,EAC1B,EAAE,GAAG,EAAE,IAAI,EAAE,EACb,oBAAS,CAAC,gBAAgB,CAC3B,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,KAAK,CAAC,QAAgB;IAC1C,MAAM,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,oBAAS,CAAC,gBAAgB,CAAC,CAAC;AAC1E,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,QAAQ,CAC5B,QAAgB,EAChB,MAAc;IAEd,IAAI,CAAC;QACH,mCAAmC;QACnC,MAAM,OAAO,CACX,CAAC,QAAQ,EAAE,qBAAqB,EAAE,qCAAqC,CAAC,EACxE,EAAE,GAAG,EAAE,QAAQ,EAAE,EACjB,oBAAS,CAAC,mBAAmB,CAC9B,CAAC;QAEF,YAAY;QACZ,MAAM,OAAO,CACX,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,EAC3B,EAAE,GAAG,EAAE,QAAQ,EAAE,EACjB,oBAAS,CAAC,mBAAmB,CAC9B,CAAC;QAEF,aAAa;QACb,MAAM,OAAO,CACX,CAAC,UAAU,EAAE,MAAM,CAAC,EACpB,EAAE,GAAG,EAAE,QAAQ,EAAE,EACjB,oBAAS,CAAC,mBAAmB,CAC9B,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,mBAAQ,CAChB,oBAAS,CAAC,mBAAmB,EAC7B,oCAAoC,MAAM,eAAe,MAAM,gEAAgE,EAC/H,KAAc,CACf,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,kBAAkB,CAAC,QAAgB;IACvD,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,CAAC,QAAQ,EAAE,IAAI,CAAC,EAChB,EAAE,GAAG,EAAE,QAAQ,EAAE,EACjB,oBAAS,CAAC,gBAAgB,CAC3B,CAAC;IAEF,mEAAmE;IACnE,OAAO,MAAM;SACV,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB;SAC/D,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,gBAAgB;AACnE,CAAC"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * loading.json 管理模块
3
+ * 用于追踪已加载的参考代码仓库
4
+ */
5
+ import type { LoadingEntry, LoadingConfig } from "../types/index.js";
6
+ /**
7
+ * 获取 loading.json 文件路径
8
+ * @param projectRoot 项目根目录,默认为当前工作目录
9
+ * @returns loading.json 的绝对路径
10
+ */
11
+ export declare function getLoadingFilePath(projectRoot?: string): string;
12
+ /**
13
+ * 读取 loading.json 配置
14
+ * @param projectRoot 项目根目录
15
+ * @returns 加载配置,如果文件不存在则返回空配置
16
+ */
17
+ export declare function readLoadingConfig(projectRoot?: string): Promise<LoadingConfig>;
18
+ /**
19
+ * 写入 loading.json 配置
20
+ * @param config 加载配置
21
+ * @param projectRoot 项目根目录
22
+ */
23
+ export declare function writeLoadingConfig(config: LoadingConfig, projectRoot?: string): Promise<void>;
24
+ /**
25
+ * 添加加载条目
26
+ * @param entry 加载条目(不含 id 和 loadedAt)
27
+ * @param projectRoot 项目根目录
28
+ * @returns 添加的完整条目
29
+ */
30
+ export declare function addEntry(entry: Omit<LoadingEntry, "id" | "loadedAt">, projectRoot?: string): Promise<LoadingEntry>;
31
+ /**
32
+ * 获取所有加载条目
33
+ * @param projectRoot 项目根目录
34
+ * @returns 加载条目列表
35
+ */
36
+ export declare function getEntries(projectRoot?: string): Promise<LoadingEntry[]>;
37
+ /**
38
+ * 根据 ID 获取加载条目
39
+ * @param id 条目 ID
40
+ * @param projectRoot 项目根目录
41
+ * @returns 加载条目,如果不存在则返回 undefined
42
+ */
43
+ export declare function getEntryById(id: string, projectRoot?: string): Promise<LoadingEntry | undefined>;
44
+ /**
45
+ * 根据目标路径获取加载条目
46
+ * @param targetPath 目标路径
47
+ * @param projectRoot 项目根目录
48
+ * @returns 加载条目,如果不存在则返回 undefined
49
+ */
50
+ export declare function getEntryByTargetPath(targetPath: string, projectRoot?: string): Promise<LoadingEntry | undefined>;
51
+ /**
52
+ * 根据仓库名称获取加载条目
53
+ * @param repoName 仓库名称
54
+ * @param projectRoot 项目根目录
55
+ * @returns 匹配的加载条目列表
56
+ */
57
+ export declare function getEntriesByRepoName(repoName: string, projectRoot?: string): Promise<LoadingEntry[]>;
58
+ /**
59
+ * 删除加载条目
60
+ * @param id 条目 ID
61
+ * @param projectRoot 项目根目录
62
+ * @returns 是否成功删除
63
+ */
64
+ export declare function removeEntry(id: string, projectRoot?: string): Promise<boolean>;
65
+ /**
66
+ * 根据目标路径删除加载条目
67
+ * @param targetPath 目标路径
68
+ * @param projectRoot 项目根目录
69
+ * @returns 被删除的条目,如果不存在则返回 undefined
70
+ */
71
+ export declare function removeEntryByTargetPath(targetPath: string, projectRoot?: string): Promise<LoadingEntry | undefined>;
72
+ /**
73
+ * 清空所有加载条目
74
+ * @param projectRoot 项目根目录
75
+ */
76
+ export declare function clearAllEntries(projectRoot?: string): Promise<void>;
77
+ /**
78
+ * 更新加载条目
79
+ * @param id 条目 ID
80
+ * @param updates 要更新的字段
81
+ * @param projectRoot 项目根目录
82
+ * @returns 更新后的条目,如果不存在则返回 undefined
83
+ */
84
+ export declare function updateEntry(id: string, updates: Partial<Omit<LoadingEntry, "id" | "loadedAt">>, projectRoot?: string): Promise<LoadingEntry | undefined>;
85
+ //# sourceMappingURL=loading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loading.d.ts","sourceRoot":"","sources":["../../src/core/loading.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAWrE;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,GAAE,MAAsB,GAClC,MAAM,CAER;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,aAAa,CAAC,CAaxB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,aAAa,EACrB,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,UAAU,CAAC,EAC5C,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,YAAY,CAAC,CAavB;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,YAAY,EAAE,CAAC,CAGzB;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,MAAM,EACV,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAGnC;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAOnC;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,YAAY,EAAE,CAAC,CAGzB;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,EAAE,EAAE,MAAM,EACV,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,MAAM,EAClB,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAenC;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,UAAU,CAAC,CAAC,EACvD,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAiBnC"}