repo-do 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 (71) hide show
  1. package/README.md +331 -0
  2. package/bin/repo-do.js +2 -0
  3. package/dist/commands/add.d.ts +4 -0
  4. package/dist/commands/add.d.ts.map +1 -0
  5. package/dist/commands/add.js +35 -0
  6. package/dist/commands/add.js.map +1 -0
  7. package/dist/commands/config.d.ts +6 -0
  8. package/dist/commands/config.d.ts.map +1 -0
  9. package/dist/commands/config.js +41 -0
  10. package/dist/commands/config.js.map +1 -0
  11. package/dist/commands/find.d.ts +2 -0
  12. package/dist/commands/find.d.ts.map +1 -0
  13. package/dist/commands/find.js +23 -0
  14. package/dist/commands/find.js.map +1 -0
  15. package/dist/commands/init.d.ts +2 -0
  16. package/dist/commands/init.d.ts.map +1 -0
  17. package/dist/commands/init.js +51 -0
  18. package/dist/commands/init.js.map +1 -0
  19. package/dist/commands/list.d.ts +4 -0
  20. package/dist/commands/list.d.ts.map +1 -0
  21. package/dist/commands/list.js +27 -0
  22. package/dist/commands/list.js.map +1 -0
  23. package/dist/commands/remove.d.ts +2 -0
  24. package/dist/commands/remove.d.ts.map +1 -0
  25. package/dist/commands/remove.js +53 -0
  26. package/dist/commands/remove.js.map +1 -0
  27. package/dist/constants/index.d.ts +15 -0
  28. package/dist/constants/index.d.ts.map +1 -0
  29. package/dist/constants/index.js +23 -0
  30. package/dist/constants/index.js.map +1 -0
  31. package/dist/core/cache-manager.d.ts +14 -0
  32. package/dist/core/cache-manager.d.ts.map +1 -0
  33. package/dist/core/cache-manager.js +140 -0
  34. package/dist/core/cache-manager.js.map +1 -0
  35. package/dist/core/config-manager.d.ts +12 -0
  36. package/dist/core/config-manager.d.ts.map +1 -0
  37. package/dist/core/config-manager.js +76 -0
  38. package/dist/core/config-manager.js.map +1 -0
  39. package/dist/core/git-url-parser.d.ts +3 -0
  40. package/dist/core/git-url-parser.d.ts.map +1 -0
  41. package/dist/core/git-url-parser.js +55 -0
  42. package/dist/core/git-url-parser.js.map +1 -0
  43. package/dist/core/path-generator.d.ts +10 -0
  44. package/dist/core/path-generator.d.ts.map +1 -0
  45. package/dist/core/path-generator.js +29 -0
  46. package/dist/core/path-generator.js.map +1 -0
  47. package/dist/core/repository-manager.d.ts +10 -0
  48. package/dist/core/repository-manager.d.ts.map +1 -0
  49. package/dist/core/repository-manager.js +82 -0
  50. package/dist/core/repository-manager.js.map +1 -0
  51. package/dist/index.d.ts +3 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +57 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/types/index.d.ts +45 -0
  56. package/dist/types/index.d.ts.map +1 -0
  57. package/dist/types/index.js +13 -0
  58. package/dist/types/index.js.map +1 -0
  59. package/dist/utils/clipboard.d.ts +5 -0
  60. package/dist/utils/clipboard.d.ts.map +1 -0
  61. package/dist/utils/clipboard.js +22 -0
  62. package/dist/utils/clipboard.js.map +1 -0
  63. package/dist/utils/git-executor.d.ts +12 -0
  64. package/dist/utils/git-executor.d.ts.map +1 -0
  65. package/dist/utils/git-executor.js +59 -0
  66. package/dist/utils/git-executor.js.map +1 -0
  67. package/dist/utils/logger.d.ts +9 -0
  68. package/dist/utils/logger.d.ts.map +1 -0
  69. package/dist/utils/logger.js +27 -0
  70. package/dist/utils/logger.js.map +1 -0
  71. package/package.json +46 -0
package/README.md ADDED
@@ -0,0 +1,331 @@
1
+ <div align="center">
2
+
3
+ # repo-do
4
+
5
+ A unified CLI tool for managing git repositories with a structured directory layout.
6
+ Organize all your repositories in a consistent domain-based structure.
7
+ Fast search, clipboard integration, and cross-platform support.
8
+
9
+ English · [简体中文](./docs/README.zh-CN.md)
10
+
11
+ [![npm version](https://img.shields.io/npm/v/repo-do.svg?style=flat-square)](https://www.npmjs.com/package/repo-do)
12
+ [![license](https://img.shields.io/npm/l/repo-do.svg?style=flat-square)](https://github.com/STDSuperman/repo-do/blob/master/LICENSE)
13
+ [![node version](https://img.shields.io/node/v/repo-do.svg?style=flat-square)](https://nodejs.org)
14
+ [![downloads](https://img.shields.io/npm/dm/repo-do.svg?style=flat-square)](https://www.npmjs.com/package/repo-do)
15
+
16
+ </div>
17
+
18
+ ## Overview
19
+
20
+ `repo-do` helps you organize all your git repositories in a consistent, domain-based directory structure. It automatically clones repositories to organized paths and provides fast search capabilities to find and navigate to your projects.
21
+
22
+ ## Features
23
+
24
+ - **Structured Organization**: Clone repositories to `{baseDir}/{domain}/{group}/{repo}` structure
25
+ - **Fast Repository Search**: Quickly find repositories by name or path fragments
26
+ - **Clipboard Integration**: Automatically copy `cd` commands to clipboard
27
+ - **Cache-Based Performance**: Fast repository listing without repeated directory scans
28
+ - **Cross-Platform**: Works on Windows, macOS, and Linux
29
+ - **Git Clone Pass-through**: Support all git clone arguments (--depth, --branch, etc.)
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ npm install -g repo-do
35
+ ```
36
+
37
+ ## Quick Start
38
+
39
+ ### 1. Initialize Configuration
40
+
41
+ ```bash
42
+ repo-do init
43
+ ```
44
+
45
+ This prompts you to set a base directory for storing repositories (default: `~/.repo-do/repo`).
46
+
47
+ ### 2. Clone a Repository
48
+
49
+ ```bash
50
+ repo-do add git@github.com:STDSuperman/super-image-cropper.git
51
+ ```
52
+
53
+ The repository will be cloned to:
54
+ ```
55
+ {baseDir}/github.com/STDSuperman/super-image-cropper
56
+ ```
57
+
58
+ The `cd` command is automatically copied to your clipboard!
59
+
60
+ ### 3. Find a Repository
61
+
62
+ ```bash
63
+ repo-do find super-image
64
+ ```
65
+
66
+ Output:
67
+ ```
68
+ Found 1 repository:
69
+ 1. D:\Code\github.com\STDSuperman\super-image-cropper
70
+ ```
71
+
72
+ ### 4. List All Repositories
73
+
74
+ ```bash
75
+ repo-do list
76
+ ```
77
+
78
+ Output:
79
+ ```
80
+ github.com/STDSuperman/super-image-cropper
81
+ github.com/STDSuperman/NanoBanana-PPT-Skills
82
+ gitlab.com/myorg/internal-tool
83
+
84
+ Total: 3 repositories
85
+ ```
86
+
87
+ ## Commands
88
+
89
+ ### `repo-do init`
90
+
91
+ Initialize configuration and set the base directory for repositories.
92
+
93
+ ```bash
94
+ repo-do init
95
+ ```
96
+
97
+ ### `repo-do add <repo_url> [git-clone-args...]`
98
+
99
+ Clone a repository to the structured directory.
100
+
101
+ **Supported URL formats:**
102
+ - HTTPS: `https://github.com/user/repo.git` or `https://github.com/user/repo`
103
+ - SSH: `git@github.com:user/repo.git` or `ssh://git@github.com/user/repo.git`
104
+
105
+ **Examples:**
106
+
107
+ ```bash
108
+ # Basic clone
109
+ repo-do add git@github.com:STDSuperman/super-image-cropper.git
110
+
111
+ # Shallow clone
112
+ repo-do add https://github.com/STDSuperman/super-image-cropper.git --depth 1
113
+
114
+ # Clone specific branch
115
+ repo-do add https://github.com/STDSuperman/super-image-cropper.git --branch develop
116
+
117
+ # SSH clone
118
+ repo-do add git@github.com:STDSuperman/NanoBanana-PPT-Skills.git
119
+ ```
120
+
121
+ **Directory structure:**
122
+ ```
123
+ {baseDir}/
124
+ ├── github.com/
125
+ │ └── STDSuperman/
126
+ │ ├── super-image-cropper/
127
+ │ └── NanoBanana-PPT-Skills/
128
+ └── gitlab.com/
129
+ └── myorg/
130
+ └── internal-tool/
131
+ ```
132
+
133
+ ### `repo-do find <query>`
134
+
135
+ Search for repositories by name, group, or path fragment (case-insensitive).
136
+
137
+ ```bash
138
+ repo-do find super-image
139
+ repo-do find STDSuperman
140
+ repo-do find github.com
141
+ ```
142
+
143
+ **Output format:**
144
+ ```
145
+ Found 2 repositories:
146
+ 1. D:\Code\github.com\STDSuperman\super-image-cropper
147
+ 2. D:\Code\github.com\STDSuperman\NanoBanana-PPT-Skills
148
+ ```
149
+
150
+ Each result is prefixed with a number, followed by the absolute path.
151
+
152
+ ### `repo-do list [--refresh]`
153
+
154
+ List all managed repositories.
155
+
156
+ ```bash
157
+ # List from cache (fast)
158
+ repo-do list
159
+
160
+ # Force rebuild cache
161
+ repo-do list --refresh
162
+ ```
163
+
164
+ ### `repo-do remove <repo>`
165
+
166
+ Remove a repository from tracking (does not delete files).
167
+
168
+ ```bash
169
+ repo-do remove super-image
170
+ ```
171
+
172
+ If multiple matches are found, you'll be prompted to select which one to remove.
173
+
174
+ ### `repo-do config [options]`
175
+
176
+ View or modify configuration.
177
+
178
+ ```bash
179
+ # Show current config
180
+ repo-do config
181
+
182
+ # Get base directory
183
+ repo-do config --get baseDirectory
184
+
185
+ # Set base directory
186
+ repo-do config --set baseDirectory /path/to/repos
187
+ ```
188
+
189
+ ## Directory Structure
190
+
191
+ All repositories are organized in a consistent structure:
192
+
193
+ ```
194
+ {baseDirectory}/{domain}/{group}/{repository}
195
+ ```
196
+
197
+ **Examples:**
198
+
199
+ | Git URL | Cloned Path |
200
+ |---------|-------------|
201
+ | `git@github.com:STDSuperman/super-image-cropper.git` | `{baseDir}/github.com/STDSuperman/super-image-cropper` |
202
+ | `git@gitlab.com:myorg/myrepo.git` | `{baseDir}/gitlab.com/myorg/myrepo` |
203
+ | `https://github.com/STDSuperman/NanoBanana-PPT-Skills.git` | `{baseDir}/github.com/STDSuperman/NanoBanana-PPT-Skills` |
204
+
205
+ ## Configuration
206
+
207
+ Configuration is stored in `~/.repo-do/config.json`:
208
+
209
+ ```json
210
+ {
211
+ "baseDirectory": "D:\\Code",
212
+ "version": "1.0.0"
213
+ }
214
+ ```
215
+
216
+ ## Cache System
217
+
218
+ To improve performance, `repo-do` maintains a repository cache at `~/.repo-do/repo_cache.json`.
219
+
220
+ **Cache is automatically updated when:**
221
+ - Adding a new repository (`repo-do add`)
222
+ - Removing a repository (`repo-do remove`)
223
+ - Forcing refresh (`repo-do list --refresh`)
224
+
225
+ **Cache format:**
226
+ ```json
227
+ {
228
+ "repositories": [
229
+ {
230
+ "name": "super-image-cropper",
231
+ "fullPath": "D:\\Code\\github.com\\STDSuperman\\super-image-cropper",
232
+ "gitUrl": "git@github.com:STDSuperman/super-image-cropper.git",
233
+ "domain": "github.com",
234
+ "group": "STDSuperman",
235
+ "lastUpdated": "2026-01-11T12:00:00.000Z"
236
+ }
237
+ ],
238
+ "lastUpdated": "2026-01-11T12:00:00.000Z"
239
+ }
240
+ ```
241
+
242
+ ## Cross-Platform Support
243
+
244
+ ### Clipboard Support
245
+
246
+ - **macOS**: Uses `pbcopy`
247
+ - **Linux**: Uses `xclip` or `xsel` (may require installation)
248
+ - **Windows**: Uses `clip` command
249
+
250
+ If clipboard fails, the path is still displayed in the terminal.
251
+
252
+ ### Path Handling
253
+
254
+ All paths are handled using Node.js `path` module for cross-platform compatibility.
255
+
256
+ ## Requirements
257
+
258
+ - Node.js >= 18.0.0
259
+ - Git installed and available in PATH
260
+
261
+ ## Error Handling
262
+
263
+ `repo-do` provides clear error messages for common issues:
264
+
265
+ - **INVALID_URL**: Git URL format not recognized
266
+ - **CLONE_FAILED**: Git clone operation failed
267
+ - **CONFIG_ERROR**: Configuration file read/write error
268
+ - **NOT_FOUND**: Repository not found in cache
269
+ - **PERMISSION_DENIED**: File system permission error
270
+ - **GIT_NOT_INSTALLED**: Git is not installed
271
+
272
+ ## Development
273
+
274
+ ```bash
275
+ # Clone the repository
276
+ git clone https://github.com/your-username/repo-do.git
277
+ cd repo-do
278
+
279
+ # Install dependencies
280
+ npm install
281
+
282
+ # Run in development mode
283
+ npm run dev
284
+
285
+ # Build
286
+ npm run build
287
+
288
+ # Run tests
289
+ npm test
290
+ ```
291
+
292
+ ## Project Structure
293
+
294
+ ```
295
+ repo-do/
296
+ ├── src/
297
+ │ ├── commands/ # CLI command implementations
298
+ │ ├── core/ # Core business logic
299
+ │ ├── utils/ # Utility functions
300
+ │ ├── types/ # TypeScript type definitions
301
+ │ ├── constants/ # Constants
302
+ │ └── index.ts # CLI entry point
303
+ ├── bin/
304
+ │ └── repo-do.js # Executable entry
305
+ ├── dist/ # Compiled output
306
+ └── tests/ # Test files
307
+ ```
308
+
309
+ ## Dependencies
310
+
311
+ - **chalk**: Terminal text styling
312
+ - **clipboardy**: Cross-platform clipboard operations
313
+ - **commander**: CLI framework
314
+ - **inquirer**: Interactive command line prompts
315
+ - **ora**: Elegant terminal spinner
316
+
317
+ ## License
318
+
319
+ MIT
320
+
321
+ ## Contributing
322
+
323
+ Contributions are welcome! Please feel free to submit a Pull Request.
324
+
325
+ ## Changelog
326
+
327
+ ### 1.0.0
328
+ - Initial release
329
+ - Core functionality: init, add, list, find, remove, config
330
+ - Cross-platform support
331
+ - Cache system for fast repository listing
package/bin/repo-do.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ require('../dist/index.js');
@@ -0,0 +1,4 @@
1
+ export declare function addCommand(url: string, options: {
2
+ args?: string[];
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAKA,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BzF"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.addCommand = addCommand;
7
+ const repository_manager_1 = require("../core/repository-manager");
8
+ const clipboard_1 = require("../utils/clipboard");
9
+ const logger_1 = require("../utils/logger");
10
+ const ora_1 = __importDefault(require("ora"));
11
+ async function addCommand(url, options) {
12
+ const spinner = (0, ora_1.default)('Cloning repository...').start();
13
+ try {
14
+ const cloneArgs = options.args || [];
15
+ const result = await repository_manager_1.repositoryManager.cloneRepository(url, cloneArgs);
16
+ if (result.alreadyExists) {
17
+ spinner.warn(result.message);
18
+ return;
19
+ }
20
+ spinner.succeed('Repository cloned successfully!');
21
+ logger_1.logger.success(result.path);
22
+ const cdCommand = `cd ${result.path}`;
23
+ const copied = await clipboard_1.clipboardUtil.copy(cdCommand);
24
+ if (copied) {
25
+ logger_1.logger.info('Path copied to clipboard!');
26
+ }
27
+ console.log(`\n${cdCommand}`);
28
+ }
29
+ catch (error) {
30
+ spinner.fail('Failed to clone repository');
31
+ logger_1.logger.error(error.message);
32
+ process.exit(1);
33
+ }
34
+ }
35
+ //# sourceMappingURL=add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":";;;;;AAKA,gCA4BC;AAjCD,mEAA+D;AAC/D,kDAAmD;AACnD,4CAAyC;AACzC,8CAAsB;AAEf,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,OAA4B;IACxE,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,uBAAuB,CAAC,CAAC,KAAK,EAAE,CAAC;IAErD,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,sCAAiB,CAAC,eAAe,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAEvE,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;QACnD,eAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE5B,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,MAAM,yBAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEnD,IAAI,MAAM,EAAE,CAAC;YACX,eAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QAC3C,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC3C,eAAM,CAAC,KAAK,CAAE,KAAe,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare function configCommand(options: {
2
+ get?: string;
3
+ set?: string;
4
+ value?: string;
5
+ }): Promise<void>;
6
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAGA,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA6B1G"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configCommand = configCommand;
4
+ const config_manager_1 = require("../core/config-manager");
5
+ const logger_1 = require("../utils/logger");
6
+ async function configCommand(options) {
7
+ try {
8
+ if (options.get) {
9
+ const config = await config_manager_1.configManager.loadConfig();
10
+ if (options.get === 'baseDirectory') {
11
+ console.log(config.baseDirectory);
12
+ }
13
+ else {
14
+ logger_1.logger.error(`Unknown config key: ${options.get}`);
15
+ process.exit(1);
16
+ }
17
+ }
18
+ else if (options.set && options.value) {
19
+ if (options.set === 'baseDirectory') {
20
+ await config_manager_1.configManager.setBaseDirectory(options.value);
21
+ logger_1.logger.success('Configuration updated successfully!');
22
+ logger_1.logger.info(`Base directory: ${options.value}`);
23
+ }
24
+ else {
25
+ logger_1.logger.error(`Unknown config key: ${options.set}`);
26
+ process.exit(1);
27
+ }
28
+ }
29
+ else {
30
+ const config = await config_manager_1.configManager.loadConfig();
31
+ logger_1.logger.info('Current configuration:');
32
+ console.log(` Base directory: ${config.baseDirectory}`);
33
+ console.log(` Version: ${config.version}`);
34
+ }
35
+ }
36
+ catch (error) {
37
+ logger_1.logger.error(`Failed to manage config: ${error.message}`);
38
+ process.exit(1);
39
+ }
40
+ }
41
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":";;AAGA,sCA6BC;AAhCD,2DAAuD;AACvD,4CAAyC;AAElC,KAAK,UAAU,aAAa,CAAC,OAAuD;IACzF,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,MAAM,8BAAa,CAAC,UAAU,EAAE,CAAC;YAChD,IAAI,OAAO,CAAC,GAAG,KAAK,eAAe,EAAE,CAAC;gBACpC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,eAAM,CAAC,KAAK,CAAC,uBAAuB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;gBACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YACxC,IAAI,OAAO,CAAC,GAAG,KAAK,eAAe,EAAE,CAAC;gBACpC,MAAM,8BAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBACpD,eAAM,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC;gBACtD,eAAM,CAAC,IAAI,CAAC,mBAAmB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,eAAM,CAAC,KAAK,CAAC,uBAAuB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;gBACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,MAAM,8BAAa,CAAC,UAAU,EAAE,CAAC;YAChD,eAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YACtC,OAAO,CAAC,GAAG,CAAC,qBAAqB,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;YACzD,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,4BAA6B,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function findCommand(prefix: string): Promise<void>;
2
+ //# sourceMappingURL=find.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../src/commands/find.ts"],"names":[],"mappings":"AAGA,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB/D"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findCommand = findCommand;
4
+ const repository_manager_1 = require("../core/repository-manager");
5
+ const logger_1 = require("../utils/logger");
6
+ async function findCommand(prefix) {
7
+ try {
8
+ const repos = await repository_manager_1.repositoryManager.findRepositories(prefix);
9
+ if (repos.length === 0) {
10
+ logger_1.logger.warn(`No repositories found matching '${prefix}'`);
11
+ return;
12
+ }
13
+ logger_1.logger.success(`Found ${repos.length} repositories:`);
14
+ repos.forEach((repo, index) => {
15
+ console.log(`${index + 1}. ${repo.fullPath}`);
16
+ });
17
+ }
18
+ catch (error) {
19
+ logger_1.logger.error(`Failed to find repositories: ${error.message}`);
20
+ process.exit(1);
21
+ }
22
+ }
23
+ //# sourceMappingURL=find.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find.js","sourceRoot":"","sources":["../../src/commands/find.ts"],"names":[],"mappings":";;AAGA,kCAiBC;AApBD,mEAA+D;AAC/D,4CAAyC;AAElC,KAAK,UAAU,WAAW,CAAC,MAAc;IAC9C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,sCAAiB,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAE/D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,eAAM,CAAC,IAAI,CAAC,mCAAmC,MAAM,GAAG,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QAED,eAAM,CAAC,OAAO,CAAC,SAAS,KAAK,CAAC,MAAM,gBAAgB,CAAC,CAAC;QACtD,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,gCAAiC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function initCommand(): Promise<void>;
2
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAKA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA0CjD"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.initCommand = initCommand;
7
+ const inquirer_1 = __importDefault(require("inquirer"));
8
+ const config_manager_1 = require("../core/config-manager");
9
+ const logger_1 = require("../utils/logger");
10
+ const constants_1 = require("../constants");
11
+ async function initCommand() {
12
+ try {
13
+ const configExists = await config_manager_1.configManager.configExists();
14
+ if (configExists) {
15
+ const { confirm } = await inquirer_1.default.prompt([
16
+ {
17
+ type: 'confirm',
18
+ name: 'confirm',
19
+ message: 'Configuration already exists. Do you want to reconfigure?',
20
+ default: false,
21
+ },
22
+ ]);
23
+ if (!confirm) {
24
+ logger_1.logger.info('Initialization cancelled.');
25
+ return;
26
+ }
27
+ }
28
+ const { baseDirectory } = await inquirer_1.default.prompt([
29
+ {
30
+ type: 'input',
31
+ name: 'baseDirectory',
32
+ message: 'Enter the base directory for cloned repositories:',
33
+ default: constants_1.DEFAULT_BASE_DIR,
34
+ validate: (input) => {
35
+ if (!input || input.trim().length === 0) {
36
+ return 'Base directory cannot be empty';
37
+ }
38
+ return true;
39
+ },
40
+ },
41
+ ]);
42
+ await config_manager_1.configManager.setBaseDirectory(baseDirectory.trim());
43
+ logger_1.logger.success(`Configuration saved successfully!`);
44
+ logger_1.logger.info(`Base directory: ${baseDirectory.trim()}`);
45
+ }
46
+ catch (error) {
47
+ logger_1.logger.error(`Failed to initialize: ${error.message}`);
48
+ process.exit(1);
49
+ }
50
+ }
51
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":";;;;;AAKA,kCA0CC;AA/CD,wDAAgC;AAChC,2DAAuD;AACvD,4CAAyC;AACzC,4CAAgD;AAEzC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,8BAAa,CAAC,YAAY,EAAE,CAAC;QAExD,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC;gBACxC;oBACE,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE,2DAA2D;oBACpE,OAAO,EAAE,KAAK;iBACf;aACF,CAAC,CAAC;YAEH,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,eAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;gBACzC,OAAO;YACT,CAAC;QACH,CAAC;QAED,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC;YAC9C;gBACE,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,mDAAmD;gBAC5D,OAAO,EAAE,4BAAgB;gBACzB,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;oBAC1B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACxC,OAAO,gCAAgC,CAAC;oBAC1C,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;aACF;SACF,CAAC,CAAC;QAEH,MAAM,8BAAa,CAAC,gBAAgB,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3D,eAAM,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;QACpD,eAAM,CAAC,IAAI,CAAC,mBAAmB,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,yBAA0B,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function listCommand(options: {
2
+ refresh?: boolean;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAIA,wBAAsB,WAAW,CAAC,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB/E"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listCommand = listCommand;
4
+ const repository_manager_1 = require("../core/repository-manager");
5
+ const logger_1 = require("../utils/logger");
6
+ const config_manager_1 = require("../core/config-manager");
7
+ async function listCommand(options) {
8
+ try {
9
+ const refresh = options.refresh || false;
10
+ const repos = await repository_manager_1.repositoryManager.listRepositories(refresh);
11
+ if (repos.length === 0) {
12
+ logger_1.logger.warn('No repositories found.');
13
+ logger_1.logger.info('Use "git-go add <repo_url>" to add repositories.');
14
+ return;
15
+ }
16
+ const baseDir = await config_manager_1.configManager.getBaseDirectory();
17
+ repos.forEach(repo => {
18
+ console.log(`${repo.domain}/${repo.group}/${repo.name}`);
19
+ });
20
+ console.log(`\nTotal: ${repos.length} repositories`);
21
+ }
22
+ catch (error) {
23
+ logger_1.logger.error(`Failed to list repositories: ${error.message}`);
24
+ process.exit(1);
25
+ }
26
+ }
27
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":";;AAIA,kCAsBC;AA1BD,mEAA+D;AAC/D,4CAAyC;AACzC,2DAAuD;AAEhD,KAAK,UAAU,WAAW,CAAC,OAA8B;IAC9D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;QACzC,MAAM,KAAK,GAAG,MAAM,sCAAiB,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAEhE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,eAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YACtC,eAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;YAChE,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,8BAAa,CAAC,gBAAgB,EAAE,CAAC;QAEvD,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACnB,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,MAAM,eAAe,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,gCAAiC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function removeCommand(identifier: string): Promise<void>;
2
+ //# sourceMappingURL=remove.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAIA,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+CrE"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.removeCommand = removeCommand;
7
+ const inquirer_1 = __importDefault(require("inquirer"));
8
+ const repository_manager_1 = require("../core/repository-manager");
9
+ const logger_1 = require("../utils/logger");
10
+ async function removeCommand(identifier) {
11
+ try {
12
+ const repos = await repository_manager_1.repositoryManager.findRepositories(identifier);
13
+ if (repos.length === 0) {
14
+ logger_1.logger.error(`No repository found matching '${identifier}'`);
15
+ process.exit(1);
16
+ }
17
+ let targetRepo = repos[0];
18
+ if (repos.length > 1) {
19
+ const { selectedRepo } = await inquirer_1.default.prompt([
20
+ {
21
+ type: 'list',
22
+ name: 'selectedRepo',
23
+ message: 'Multiple repositories found. Select one to remove:',
24
+ choices: repos.map(repo => ({
25
+ name: `${repo.domain}/${repo.group}/${repo.name} (${repo.fullPath})`,
26
+ value: repo,
27
+ })),
28
+ },
29
+ ]);
30
+ targetRepo = selectedRepo;
31
+ }
32
+ const { confirm } = await inquirer_1.default.prompt([
33
+ {
34
+ type: 'confirm',
35
+ name: 'confirm',
36
+ message: `Remove ${targetRepo.name} from management? (files will not be deleted)`,
37
+ default: false,
38
+ },
39
+ ]);
40
+ if (!confirm) {
41
+ logger_1.logger.info('Operation cancelled.');
42
+ return;
43
+ }
44
+ await repository_manager_1.repositoryManager.removeRepository(targetRepo.fullPath);
45
+ logger_1.logger.success(`Removed ${targetRepo.name} from management`);
46
+ logger_1.logger.info(`Files at ${targetRepo.fullPath} were not deleted`);
47
+ }
48
+ catch (error) {
49
+ logger_1.logger.error(`Failed to remove repository: ${error.message}`);
50
+ process.exit(1);
51
+ }
52
+ }
53
+ //# sourceMappingURL=remove.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":";;;;;AAIA,sCA+CC;AAnDD,wDAAgC;AAChC,mEAA+D;AAC/D,4CAAyC;AAElC,KAAK,UAAU,aAAa,CAAC,UAAkB;IACpD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,sCAAiB,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAEnE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,eAAM,CAAC,KAAK,CAAC,iCAAiC,UAAU,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAE1B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC;gBAC7C;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,oDAAoD;oBAC7D,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;wBAC1B,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,GAAG;wBACpE,KAAK,EAAE,IAAI;qBACZ,CAAC,CAAC;iBACJ;aACF,CAAC,CAAC;YACH,UAAU,GAAG,YAAY,CAAC;QAC5B,CAAC;QAED,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC;YACxC;gBACE,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,UAAU,UAAU,CAAC,IAAI,+CAA+C;gBACjF,OAAO,EAAE,KAAK;aACf;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,eAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QAED,MAAM,sCAAiB,CAAC,gBAAgB,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC9D,eAAM,CAAC,OAAO,CAAC,WAAW,UAAU,CAAC,IAAI,kBAAkB,CAAC,CAAC;QAC7D,eAAM,CAAC,IAAI,CAAC,YAAY,UAAU,CAAC,QAAQ,mBAAmB,CAAC,CAAC;IAClE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,gCAAiC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ export declare const CONFIG_VERSION = "1.0.0";
2
+ export declare const CONFIG_DIR: string;
3
+ export declare const CONFIG_FILE: string;
4
+ export declare const CACHE_FILE: string;
5
+ export declare const DEFAULT_BASE_DIR: string;
6
+ export declare const ERROR_CODES: {
7
+ readonly INVALID_URL: "INVALID_URL";
8
+ readonly CLONE_FAILED: "CLONE_FAILED";
9
+ readonly CONFIG_ERROR: "CONFIG_ERROR";
10
+ readonly NOT_FOUND: "NOT_FOUND";
11
+ readonly PERMISSION_DENIED: "PERMISSION_DENIED";
12
+ readonly GIT_NOT_INSTALLED: "GIT_NOT_INSTALLED";
13
+ readonly CACHE_ERROR: "CACHE_ERROR";
14
+ };
15
+ //# sourceMappingURL=index.d.ts.map