geeto 0.6.6 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/README.md +23 -9
  2. package/lib/api/copilot-adapter.d.ts +14 -5
  3. package/lib/api/copilot-adapter.d.ts.map +1 -1
  4. package/lib/api/copilot-adapter.js +15 -21
  5. package/lib/api/copilot-adapter.js.map +1 -1
  6. package/lib/api/copilot-sdk.d.ts +3 -16
  7. package/lib/api/copilot-sdk.d.ts.map +1 -1
  8. package/lib/api/copilot-sdk.js +186 -454
  9. package/lib/api/copilot-sdk.js.map +1 -1
  10. package/lib/api/copilot.d.ts +3 -4
  11. package/lib/api/copilot.d.ts.map +1 -1
  12. package/lib/api/copilot.js +28 -28
  13. package/lib/api/copilot.js.map +1 -1
  14. package/lib/api/gemini-sdk.d.ts.map +1 -1
  15. package/lib/api/gemini-sdk.js +11 -77
  16. package/lib/api/gemini-sdk.js.map +1 -1
  17. package/lib/api/gemini.d.ts +2 -2
  18. package/lib/api/gemini.d.ts.map +1 -1
  19. package/lib/api/gemini.js +24 -19
  20. package/lib/api/gemini.js.map +1 -1
  21. package/lib/api/gitlab.d.ts +80 -0
  22. package/lib/api/gitlab.d.ts.map +1 -0
  23. package/lib/api/gitlab.js +192 -0
  24. package/lib/api/gitlab.js.map +1 -0
  25. package/lib/api/openrouter-sdk.d.ts.map +1 -1
  26. package/lib/api/openrouter-sdk.js +11 -76
  27. package/lib/api/openrouter-sdk.js.map +1 -1
  28. package/lib/api/openrouter.d.ts.map +1 -1
  29. package/lib/api/openrouter.js +2 -16
  30. package/lib/api/openrouter.js.map +1 -1
  31. package/lib/api/platform.d.ts +78 -0
  32. package/lib/api/platform.d.ts.map +1 -0
  33. package/lib/api/platform.js +218 -0
  34. package/lib/api/platform.js.map +1 -0
  35. package/lib/cli/input.d.ts +2 -2
  36. package/lib/cli/input.d.ts.map +1 -1
  37. package/lib/cli/input.js +23 -27
  38. package/lib/cli/input.js.map +1 -1
  39. package/lib/cli/menu.d.ts +1 -1
  40. package/lib/cli/menu.d.ts.map +1 -1
  41. package/lib/cli/menu.js +123 -100
  42. package/lib/cli/menu.js.map +1 -1
  43. package/lib/core/copilot-setup.d.ts +9 -8
  44. package/lib/core/copilot-setup.d.ts.map +1 -1
  45. package/lib/core/copilot-setup.js +81 -264
  46. package/lib/core/copilot-setup.js.map +1 -1
  47. package/lib/core/gemini-setup.js +7 -7
  48. package/lib/core/gemini-setup.js.map +1 -1
  49. package/lib/core/gitlab-setup.d.ts +5 -0
  50. package/lib/core/gitlab-setup.d.ts.map +1 -0
  51. package/lib/core/gitlab-setup.js +85 -0
  52. package/lib/core/gitlab-setup.js.map +1 -0
  53. package/lib/core/openrouter-setup.d.ts.map +1 -1
  54. package/lib/core/openrouter-setup.js +17 -0
  55. package/lib/core/openrouter-setup.js.map +1 -1
  56. package/lib/index.js +518 -704
  57. package/lib/index.js.map +1 -1
  58. package/lib/types/index.d.ts +10 -6
  59. package/lib/types/index.d.ts.map +1 -1
  60. package/lib/utils/ai-provider-helpers.d.ts +5 -0
  61. package/lib/utils/ai-provider-helpers.d.ts.map +1 -0
  62. package/lib/utils/ai-provider-helpers.js +23 -0
  63. package/lib/utils/ai-provider-helpers.js.map +1 -0
  64. package/lib/utils/ai-text.d.ts +23 -0
  65. package/lib/utils/ai-text.d.ts.map +1 -0
  66. package/lib/utils/ai-text.js +57 -0
  67. package/lib/utils/ai-text.js.map +1 -0
  68. package/lib/utils/ai-workflow.d.ts +18 -0
  69. package/lib/utils/ai-workflow.d.ts.map +1 -0
  70. package/lib/utils/ai-workflow.js +66 -0
  71. package/lib/utils/ai-workflow.js.map +1 -0
  72. package/lib/utils/branch-naming.d.ts.map +1 -1
  73. package/lib/utils/branch-naming.js +1 -3
  74. package/lib/utils/branch-naming.js.map +1 -1
  75. package/lib/utils/config.d.ts +13 -1
  76. package/lib/utils/config.d.ts.map +1 -1
  77. package/lib/utils/config.js +38 -1
  78. package/lib/utils/config.js.map +1 -1
  79. package/lib/utils/display.d.ts.map +1 -1
  80. package/lib/utils/display.js +4 -3
  81. package/lib/utils/display.js.map +1 -1
  82. package/lib/utils/exec.d.ts.map +1 -1
  83. package/lib/utils/exec.js +10 -2
  84. package/lib/utils/exec.js.map +1 -1
  85. package/lib/utils/git-ai.js +13 -13
  86. package/lib/utils/git-ai.js.map +1 -1
  87. package/lib/utils/git-errors.d.ts.map +1 -1
  88. package/lib/utils/git-errors.js +2 -6
  89. package/lib/utils/git-errors.js.map +1 -1
  90. package/lib/utils/git.d.ts.map +1 -1
  91. package/lib/utils/git.js +5 -0
  92. package/lib/utils/git.js.map +1 -1
  93. package/lib/utils/github-helpers.d.ts +33 -0
  94. package/lib/utils/github-helpers.d.ts.map +1 -0
  95. package/lib/utils/github-helpers.js +101 -0
  96. package/lib/utils/github-helpers.js.map +1 -0
  97. package/lib/utils/prompt-loader.d.ts +9 -0
  98. package/lib/utils/prompt-loader.d.ts.map +1 -0
  99. package/lib/utils/prompt-loader.js +42 -0
  100. package/lib/utils/prompt-loader.js.map +1 -0
  101. package/lib/utils/prompts-embedded.d.ts +2 -0
  102. package/lib/utils/prompts-embedded.d.ts.map +1 -0
  103. package/lib/utils/prompts-embedded.js +255 -0
  104. package/lib/utils/prompts-embedded.js.map +1 -0
  105. package/lib/utils/scramble.d.ts +9 -86
  106. package/lib/utils/scramble.d.ts.map +1 -1
  107. package/lib/utils/scramble.js +27 -279
  108. package/lib/utils/scramble.js.map +1 -1
  109. package/lib/version.d.ts +1 -1
  110. package/lib/version.js +1 -1
  111. package/lib/workflows/alias.d.ts.map +1 -1
  112. package/lib/workflows/alias.js +1 -0
  113. package/lib/workflows/alias.js.map +1 -1
  114. package/lib/workflows/amend.d.ts.map +1 -1
  115. package/lib/workflows/amend.js +1 -5
  116. package/lib/workflows/amend.js.map +1 -1
  117. package/lib/workflows/branch-helpers.d.ts.map +1 -1
  118. package/lib/workflows/branch-helpers.js +0 -1
  119. package/lib/workflows/branch-helpers.js.map +1 -1
  120. package/lib/workflows/commit.d.ts.map +1 -1
  121. package/lib/workflows/commit.js +160 -187
  122. package/lib/workflows/commit.js.map +1 -1
  123. package/lib/workflows/doctor.d.ts +7 -0
  124. package/lib/workflows/doctor.d.ts.map +1 -0
  125. package/lib/workflows/doctor.js +284 -0
  126. package/lib/workflows/doctor.js.map +1 -0
  127. package/lib/workflows/issue.d.ts +1 -1
  128. package/lib/workflows/issue.d.ts.map +1 -1
  129. package/lib/workflows/issue.js +28 -115
  130. package/lib/workflows/issue.js.map +1 -1
  131. package/lib/workflows/main-helpers.d.ts +34 -0
  132. package/lib/workflows/main-helpers.d.ts.map +1 -0
  133. package/lib/workflows/main-helpers.js +346 -0
  134. package/lib/workflows/main-helpers.js.map +1 -0
  135. package/lib/workflows/main-steps.d.ts.map +1 -1
  136. package/lib/workflows/main-steps.js +9 -134
  137. package/lib/workflows/main-steps.js.map +1 -1
  138. package/lib/workflows/main.d.ts +2 -6
  139. package/lib/workflows/main.d.ts.map +1 -1
  140. package/lib/workflows/main.js +44 -381
  141. package/lib/workflows/main.js.map +1 -1
  142. package/lib/workflows/pr.d.ts +2 -2
  143. package/lib/workflows/pr.d.ts.map +1 -1
  144. package/lib/workflows/pr.js +49 -137
  145. package/lib/workflows/pr.js.map +1 -1
  146. package/lib/workflows/prune.d.ts.map +1 -1
  147. package/lib/workflows/prune.js +2 -10
  148. package/lib/workflows/prune.js.map +1 -1
  149. package/lib/workflows/pull.d.ts.map +1 -1
  150. package/lib/workflows/pull.js +2 -24
  151. package/lib/workflows/pull.js.map +1 -1
  152. package/lib/workflows/release-merge.d.ts +12 -0
  153. package/lib/workflows/release-merge.d.ts.map +1 -0
  154. package/lib/workflows/release-merge.js +593 -0
  155. package/lib/workflows/release-merge.js.map +1 -0
  156. package/lib/workflows/release-notes.d.ts +13 -0
  157. package/lib/workflows/release-notes.d.ts.map +1 -0
  158. package/lib/workflows/release-notes.js +141 -0
  159. package/lib/workflows/release-notes.js.map +1 -0
  160. package/lib/workflows/release-recover.d.ts +5 -0
  161. package/lib/workflows/release-recover.d.ts.map +1 -0
  162. package/lib/workflows/release-recover.js +137 -0
  163. package/lib/workflows/release-recover.js.map +1 -0
  164. package/lib/workflows/release-sync.d.ts +7 -0
  165. package/lib/workflows/release-sync.d.ts.map +1 -0
  166. package/lib/workflows/release-sync.js +378 -0
  167. package/lib/workflows/release-sync.js.map +1 -0
  168. package/lib/workflows/release-utils.d.ts +36 -0
  169. package/lib/workflows/release-utils.d.ts.map +1 -0
  170. package/lib/workflows/release-utils.js +150 -0
  171. package/lib/workflows/release-utils.js.map +1 -0
  172. package/lib/workflows/release.d.ts.map +1 -1
  173. package/lib/workflows/release.js +92 -719
  174. package/lib/workflows/release.js.map +1 -1
  175. package/lib/workflows/repo-settings.d.ts +2 -2
  176. package/lib/workflows/repo-settings.d.ts.map +1 -1
  177. package/lib/workflows/repo-settings.js +33 -24
  178. package/lib/workflows/repo-settings.js.map +1 -1
  179. package/lib/workflows/reword.d.ts.map +1 -1
  180. package/lib/workflows/reword.js +154 -151
  181. package/lib/workflows/reword.js.map +1 -1
  182. package/lib/workflows/security-gate.d.ts.map +1 -1
  183. package/lib/workflows/security-gate.js +15 -75
  184. package/lib/workflows/security-gate.js.map +1 -1
  185. package/lib/workflows/settings.d.ts +3 -1
  186. package/lib/workflows/settings.d.ts.map +1 -1
  187. package/lib/workflows/settings.js +319 -19
  188. package/lib/workflows/settings.js.map +1 -1
  189. package/lib/workflows/submodules.d.ts +6 -0
  190. package/lib/workflows/submodules.d.ts.map +1 -0
  191. package/lib/workflows/submodules.js +344 -0
  192. package/lib/workflows/submodules.js.map +1 -0
  193. package/lib/workflows/trello-menu.d.ts +2 -5
  194. package/lib/workflows/trello-menu.d.ts.map +1 -1
  195. package/lib/workflows/trello-menu.js +67 -228
  196. package/lib/workflows/trello-menu.js.map +1 -1
  197. package/package.json +4 -6
  198. package/prompts/branch-name-prompt.md +4 -0
  199. package/prompts/commit-message-prompt.md +12 -0
  200. package/prompts/issue-prompt.md +19 -0
  201. package/prompts/issue-review.with-context.prompt.yml +77 -0
  202. package/prompts/pr-prompt.md +14 -0
  203. package/prompts/release-notes-prompt.md +35 -0
  204. package/prompts/repo-description-prompt.md +1 -0
  205. package/prompts/security-gate-prompt.md +80 -0
package/lib/index.js CHANGED
@@ -1,732 +1,546 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * Geeto - Git flow automation CLI tool with AI-powered branch naming
4
- * Main entry point - delegates to modular workflows
4
+ * Main entry point - delegates to modular workflows via command registry
5
5
  */
6
- import path from 'node:path';
7
6
  import { VERSION } from './version.js';
8
- const version = VERSION;
9
- const { main } = await import('./workflows/main.js');
10
- // Parse simple CLI flags for quick step shortcuts
11
- const argv = process.argv.slice(2);
12
- let startAt;
13
- let fresh = false;
14
- let resume = false;
15
- let stageAll = false;
16
- let showVersion = false;
17
- let showHelp = false;
18
- let showCleanup = false;
19
- let showSwitch = false;
20
- let showCompare = false;
21
- let showCherryPick = false;
22
- let showPR = false;
23
- let showIssue = false;
24
- let showHistory = false;
25
- let showStash = false;
26
- let showAmend = false;
27
- let showStats = false;
28
- let showUndo = false;
29
- let showRelease = false;
30
- let showRepoSettings = false;
31
- let showTrello = false;
32
- let showTrelloLists = false;
33
- let showTrelloGenerate = false;
34
- let showAbort = false;
35
- let showPull = false;
36
- let showPrune = false;
37
- let showFetch = false;
38
- let showStatus = false;
39
- let showRevert = false;
40
- let showAlias = false;
41
- let showReword = false;
42
- let dryRunMode = false;
43
- let settingsAction;
44
- for (const arg of argv) {
45
- if (arg === '-c' || arg === '--commit') {
46
- startAt = 'commit';
47
- }
48
- if (arg === '-m' || arg === '--merge') {
49
- startAt = 'merge';
50
- }
51
- if (arg === '-b' || arg === '--branch') {
52
- startAt = 'branch';
53
- }
54
- if (arg === '-s' || arg === '--stage') {
55
- startAt = 'stage';
56
- }
57
- if (arg === '-sa' || arg === '-as') {
58
- startAt = 'stage';
59
- stageAll = true;
60
- }
61
- if (arg === '-p' || arg === '--push') {
62
- startAt = 'push';
63
- }
64
- if (arg === '-f' || arg === '--fresh') {
65
- fresh = true;
66
- }
67
- if (arg === '-r' || arg === '--resume') {
68
- resume = true;
69
- }
70
- if (arg === '-v' || arg === '--version') {
71
- showVersion = true;
72
- }
73
- if (arg === '-h' || arg === '--help') {
74
- showHelp = true;
75
- }
76
- if (arg === '--separator') {
77
- settingsAction = 'separator';
78
- }
79
- if (arg === '--sync-models') {
80
- settingsAction = 'models';
81
- }
82
- if (arg === '--change-model') {
83
- settingsAction = 'change-model';
84
- }
85
- if (arg === '--setup-gemini') {
86
- settingsAction = 'gemini';
87
- }
88
- if (arg === '--setup-openrouter') {
89
- settingsAction = 'openrouter';
90
- }
91
- if (arg === '--setup-trello') {
92
- settingsAction = 'trello';
93
- }
94
- if (arg === '--setup-github') {
95
- settingsAction = 'github';
96
- }
97
- if (arg === '--cleanup' || arg === '-cl') {
98
- showCleanup = true;
99
- }
100
- if (arg === '--switch' || arg === '-sw') {
101
- showSwitch = true;
102
- }
103
- if (arg === '--compare' || arg === '-cmp') {
104
- showCompare = true;
105
- }
106
- if (arg === '--cherry-pick' || arg === '-cp') {
107
- showCherryPick = true;
108
- }
109
- if (arg === '--pr' || arg === '-pr') {
110
- showPR = true;
111
- }
112
- if (arg === '--issue' || arg === '-i') {
113
- showIssue = true;
114
- }
115
- if (arg === '--log' || arg === '-lg') {
116
- showHistory = true;
117
- }
118
- if (arg === '--stash' || arg === '-sh') {
119
- showStash = true;
120
- }
121
- if (arg === '--amend' || arg === '-am') {
122
- showAmend = true;
123
- }
124
- if (arg === '--stats' || arg === '-sts') {
125
- showStats = true;
126
- }
127
- if (arg === '--undo' || arg === '-u') {
128
- showUndo = true;
129
- }
130
- if (arg === '--tag' || arg === '-t') {
131
- showRelease = true;
132
- }
133
- if (arg === '--repo' || arg === '-rp') {
134
- showRepoSettings = true;
135
- }
136
- if (arg === '--trello' || arg === '-tr') {
137
- showTrello = true;
138
- }
139
- if (arg === '--trello-list' || arg === '-tl') {
140
- showTrelloLists = true;
141
- }
142
- if (arg === '--trello-generate' || arg === '-tg') {
143
- showTrelloGenerate = true;
144
- }
145
- if (arg === '--abort') {
146
- showAbort = true;
147
- }
148
- if (arg === '--pull' || arg === '-pl') {
149
- showPull = true;
150
- }
151
- if (arg === '--prune') {
152
- showPrune = true;
153
- }
154
- if (arg === '--fetch' || arg === '-ft') {
155
- showFetch = true;
156
- }
157
- if (arg === '--status' || arg === '-st') {
158
- showStatus = true;
159
- }
160
- if (arg === '--revert' || arg === '-rv') {
161
- showRevert = true;
162
- }
163
- if (arg === '--alias' || arg === '-al') {
164
- showAlias = true;
165
- }
166
- if (arg === '--reword' || arg === '-rw') {
167
- showReword = true;
168
- }
169
- if (arg === '--dry-run' || arg === '-dr') {
170
- dryRunMode = true;
171
- }
172
- }
173
- // Validate unknown flags
174
- const validFlags = new Set([
175
- '-c',
176
- '--commit',
177
- '-m',
178
- '--merge',
179
- '-b',
180
- '--branch',
181
- '-s',
182
- '--stage',
183
- '-sa',
184
- '-as',
185
- '-p',
186
- '--push',
187
- '--cleanup',
188
- '-cl',
189
- '--switch',
190
- '-sw',
191
- '--compare',
192
- '-cmp',
193
- '--cherry-pick',
194
- '-cp',
195
- '--pr',
196
- '-pr',
197
- '--issue',
198
- '-i',
199
- '--log',
200
- '-lg',
201
- '--stash',
202
- '-sh',
203
- '--amend',
204
- '-am',
205
- '--stats',
206
- '-sts',
207
- '--undo',
208
- '-u',
209
- '--tag',
210
- '-t',
211
- '--repo',
212
- '-rp',
213
- '-f',
214
- '--fresh',
215
- '-r',
216
- '--resume',
217
- '-v',
218
- '--version',
219
- '-h',
220
- '--help',
221
- '--separator',
222
- '--sync-models',
223
- '--change-model',
224
- '--setup-gemini',
225
- '--setup-openrouter',
226
- '--setup-trello',
227
- '--setup-github',
228
- '--trello',
229
- '-tr',
230
- '--trello-list',
231
- '-tl',
232
- '--trello-generate',
233
- '-tg',
234
- '--abort',
235
- '--pull',
236
- '-pl',
237
- '--prune',
238
- '--fetch',
239
- '-ft',
240
- '--status',
241
- '-st',
242
- '--revert',
243
- '-rv',
244
- '--alias',
245
- '-al',
246
- '--reword',
247
- '-rw',
248
- '--dry-run',
249
- '-dr',
250
- ]);
251
- // Detect file path argument (non-flag arg → open in inline editor)
252
- let editFilePath;
253
- for (const arg of argv) {
254
- if (!arg.startsWith('-')) {
255
- editFilePath = arg;
256
- break;
257
- }
258
- }
259
- for (const arg of argv) {
260
- if (arg.startsWith('-') && !validFlags.has(arg)) {
261
- console.error(`Unknown flag: ${arg}`);
262
- console.error('Use --help to see available options');
263
- process.exit(1);
264
- }
7
+ /**
8
+ * Registry of all standalone commands.
9
+ * Order determines priority when multiple flags are passed.
10
+ */
11
+ const COMMAND_REGISTRY = [
12
+ // Git tools
13
+ {
14
+ flag: '--abort',
15
+ alias: undefined,
16
+ module: './workflows/abort.js',
17
+ handler: 'handleAbort',
18
+ errorLabel: 'Abort',
19
+ },
20
+ {
21
+ flag: '--pull',
22
+ alias: '-pl',
23
+ module: './workflows/pull.js',
24
+ handler: 'handlePull',
25
+ errorLabel: 'Pull',
26
+ },
27
+ {
28
+ flag: '--prune',
29
+ alias: undefined,
30
+ module: './workflows/prune.js',
31
+ handler: 'handlePrune',
32
+ errorLabel: 'Prune',
33
+ },
34
+ {
35
+ flag: '--fetch',
36
+ alias: '-ft',
37
+ module: './workflows/fetch.js',
38
+ handler: 'handleFetch',
39
+ errorLabel: 'Fetch',
40
+ },
41
+ {
42
+ flag: '--status',
43
+ alias: '-st',
44
+ module: './workflows/status.js',
45
+ handler: 'handleStatus',
46
+ errorLabel: 'Status',
47
+ },
48
+ {
49
+ flag: '--revert',
50
+ alias: '-rv',
51
+ module: './workflows/revert.js',
52
+ handler: 'handleRevert',
53
+ errorLabel: 'Revert',
54
+ },
55
+ {
56
+ flag: '--alias',
57
+ alias: '-al',
58
+ module: './workflows/alias.js',
59
+ handler: 'handleAlias',
60
+ errorLabel: 'Alias',
61
+ },
62
+ {
63
+ flag: '--reword',
64
+ alias: '-rw',
65
+ module: './workflows/reword.js',
66
+ handler: 'handleReword',
67
+ errorLabel: 'Reword',
68
+ },
69
+ {
70
+ flag: '--cleanup',
71
+ alias: '-cl',
72
+ module: './workflows/cleanup.js',
73
+ handler: 'handleInteractiveCleanup',
74
+ errorLabel: 'Cleanup',
75
+ },
76
+ {
77
+ flag: '--switch',
78
+ alias: '-sw',
79
+ module: './workflows/switch.js',
80
+ handler: 'handleBranchSwitch',
81
+ errorLabel: 'Switch',
82
+ },
83
+ {
84
+ flag: '--compare',
85
+ alias: '-cmp',
86
+ module: './workflows/compare.js',
87
+ handler: 'handleBranchCompare',
88
+ errorLabel: 'Compare',
89
+ },
90
+ {
91
+ flag: '--cherry-pick',
92
+ alias: '-cp',
93
+ module: './workflows/cherry-pick.js',
94
+ handler: 'handleCherryPick',
95
+ errorLabel: 'Cherry-pick',
96
+ },
97
+ {
98
+ flag: '--pr',
99
+ alias: '-pr',
100
+ module: './workflows/pr.js',
101
+ handler: 'handleCreatePR',
102
+ errorLabel: 'PR',
103
+ },
104
+ {
105
+ flag: '--issue',
106
+ alias: '-i',
107
+ module: './workflows/issue.js',
108
+ handler: 'handleCreateIssue',
109
+ errorLabel: 'Issue',
110
+ },
111
+ {
112
+ flag: '--log',
113
+ alias: '-lg',
114
+ module: './workflows/history.js',
115
+ handler: 'handleHistory',
116
+ errorLabel: 'History',
117
+ },
118
+ {
119
+ flag: '--stash',
120
+ alias: '-sh',
121
+ module: './workflows/stash.js',
122
+ handler: 'handleStash',
123
+ errorLabel: 'Stash',
124
+ },
125
+ {
126
+ flag: '--amend',
127
+ alias: '-am',
128
+ module: './workflows/amend.js',
129
+ handler: 'handleAmend',
130
+ errorLabel: 'Amend',
131
+ },
132
+ {
133
+ flag: '--stats',
134
+ alias: '-sts',
135
+ module: './workflows/stats.js',
136
+ handler: 'handleStats',
137
+ errorLabel: 'Stats',
138
+ },
139
+ {
140
+ flag: '--undo',
141
+ alias: '-u',
142
+ module: './workflows/undo.js',
143
+ handler: 'handleUndo',
144
+ errorLabel: 'Undo',
145
+ },
146
+ {
147
+ flag: '--tag',
148
+ alias: '-t',
149
+ module: './workflows/release.js',
150
+ handler: 'handleRelease',
151
+ errorLabel: 'Release',
152
+ },
153
+ {
154
+ flag: '--repo',
155
+ alias: '-rp',
156
+ module: './workflows/repo-settings.js',
157
+ handler: 'handleRepoSettings',
158
+ errorLabel: 'Repo settings',
159
+ },
160
+ // Trello
161
+ {
162
+ flag: '--submodules',
163
+ alias: '-sm',
164
+ module: './workflows/submodules.js',
165
+ handler: 'handleSubmodules',
166
+ errorLabel: 'Submodules',
167
+ },
168
+ {
169
+ flag: '--trello',
170
+ alias: '-tr',
171
+ module: './workflows/trello-menu.js',
172
+ handler: 'showTrelloMenu',
173
+ errorLabel: 'Trello menu',
174
+ },
175
+ {
176
+ flag: '--trello-generate',
177
+ alias: '-tg',
178
+ module: './workflows/trello-menu.js',
179
+ handler: 'handleGenerateTaskInstructions',
180
+ errorLabel: 'Trello generate',
181
+ },
182
+ // Settings
183
+ {
184
+ flag: '--separator',
185
+ alias: undefined,
186
+ module: './workflows/settings.js',
187
+ handler: 'handleSeparatorSetting',
188
+ errorLabel: 'Settings',
189
+ },
190
+ {
191
+ flag: '--sync-models',
192
+ alias: undefined,
193
+ module: './workflows/settings.js',
194
+ handler: 'handleModelResetSetting',
195
+ errorLabel: 'Settings',
196
+ },
197
+ {
198
+ flag: '--change-model',
199
+ alias: undefined,
200
+ module: './workflows/settings.js',
201
+ handler: 'handleChangeModelSetting',
202
+ errorLabel: 'Settings',
203
+ },
204
+ {
205
+ flag: '--setup-gemini',
206
+ alias: undefined,
207
+ module: './workflows/settings.js',
208
+ handler: 'handleGeminiSetting',
209
+ errorLabel: 'Settings',
210
+ },
211
+ {
212
+ flag: '--setup-openrouter',
213
+ alias: undefined,
214
+ module: './workflows/settings.js',
215
+ handler: 'handleOpenRouterSetting',
216
+ errorLabel: 'Settings',
217
+ },
218
+ {
219
+ flag: '--setup-trello',
220
+ alias: undefined,
221
+ module: './workflows/settings.js',
222
+ handler: 'handleTrelloSetting',
223
+ errorLabel: 'Settings',
224
+ },
225
+ {
226
+ flag: '--setup-copilot',
227
+ alias: undefined,
228
+ module: './workflows/settings.js',
229
+ handler: 'handleCopilotSetting',
230
+ errorLabel: 'Settings',
231
+ },
232
+ {
233
+ flag: '--setup-github',
234
+ alias: undefined,
235
+ module: './core/github-setup.js',
236
+ handler: 'setupGithubConfigInteractive',
237
+ errorLabel: 'Settings',
238
+ },
239
+ {
240
+ flag: '--setup-gitlab',
241
+ alias: undefined,
242
+ module: './core/gitlab-setup.js',
243
+ handler: 'setupGitlabConfigInteractive',
244
+ errorLabel: 'Settings',
245
+ },
246
+ // Doctor / Info
247
+ {
248
+ flag: '--uninstall',
249
+ alias: undefined,
250
+ module: './workflows/doctor.js',
251
+ handler: 'handleUninstall',
252
+ errorLabel: 'Uninstall',
253
+ },
254
+ {
255
+ flag: '--where',
256
+ alias: undefined,
257
+ module: './workflows/doctor.js',
258
+ handler: 'handleWhereInstalled',
259
+ errorLabel: 'Where',
260
+ },
261
+ ];
262
+ /** Flags that set the `startAt` step for the main workflow */
263
+ const START_AT_FLAGS = [
264
+ { flag: '--commit', alias: '-c', startAt: 'commit' },
265
+ { flag: '--merge', alias: '-m', startAt: 'merge' },
266
+ { flag: '--branch', alias: '-b', startAt: 'branch' },
267
+ { flag: '--stage', alias: '-s', startAt: 'stage' },
268
+ { flag: '--push', alias: '-p', startAt: 'push' },
269
+ ];
270
+ /** Modifier flags that don't trigger a command on their own */
271
+ const MODIFIER_FLAGS = [
272
+ { flag: '--fresh', alias: '-f' },
273
+ { flag: '--resume', alias: '-r' },
274
+ { flag: '--version', alias: '-v' },
275
+ { flag: '--help', alias: '-h' },
276
+ { flag: '--dry-run', alias: '-dr' },
277
+ ];
278
+ // ─── Valid Flags (auto-generated from registries) ────────────────────
279
+ function buildValidFlags() {
280
+ const flags = new Set();
281
+ for (const cmd of COMMAND_REGISTRY) {
282
+ flags.add(cmd.flag);
283
+ if (cmd.alias)
284
+ flags.add(cmd.alias);
285
+ }
286
+ for (const sf of START_AT_FLAGS) {
287
+ flags.add(sf.flag);
288
+ flags.add(sf.alias);
289
+ }
290
+ // Special compound aliases
291
+ flags.add('-sa');
292
+ flags.add('-as');
293
+ for (const mf of MODIFIER_FLAGS) {
294
+ flags.add(mf.flag);
295
+ flags.add(mf.alias);
296
+ }
297
+ return flags;
265
298
  }
266
- ;
267
- (async () => {
268
- if (showVersion) {
269
- console.log(`Geeto v${version}`);
270
- process.exit(0);
271
- }
272
- if (showHelp) {
273
- const C = '\u001B[36m'; // cyan
274
- const B = '\u001B[1m'; // bright/bold
275
- const G = '\u001B[90m'; // gray
276
- const R = '\u001B[0m'; // reset
277
- console.log('');
278
- console.log(` ${B}Geeto CLI${R} ${G}v${version}${R}`);
279
- console.log(` ${G}Git flow automation with AI-powered workflows${R}`);
280
- console.log('');
281
- console.log(` ${B}USAGE${R}`);
282
- console.log(` ${C}geeto${R} ${G}[command] [options]${R}`);
283
- console.log('');
284
- console.log(` ${B}WORKFLOW${R}`);
285
- console.log(` ${C}-s, --stage${R} Stage files interactively`);
286
- console.log(` ${C}-sa, -as${R} Stage all changes automatically`);
287
- console.log(` ${C}-c, --commit${R} Create a commit with AI message`);
288
- console.log(` ${C}-b, --branch${R} Create a branch with AI name`);
289
- console.log(` ${C}-p, --push${R} Push current branch to remote`);
290
- console.log(` ${C}-m, --merge${R} Merge branches interactively`);
291
- console.log('');
292
- console.log(` ${B}GIT TOOLS${R}`);
293
- console.log(` ${C}-cl, --cleanup${R} Clean up local & remote branches`);
294
- console.log(` ${C}-sw, --switch${R} Switch branches with fuzzy search`);
295
- console.log(` ${C}-cmp, --compare${R} Compare current branch with another`);
296
- console.log(` ${C}-cp, --cherry-pick${R} Cherry-pick from another branch`);
297
- console.log(` ${C}-lg, --log${R} View commit history with timeline`);
298
- console.log(` ${C}-sh, --stash${R} Manage stashes interactively`);
299
- console.log(` ${C}-am, --amend${R} Amend the last commit`);
300
- console.log(` ${C}-u, --undo${R} Undo the last git action safely`);
301
- console.log(` ${C}-rv, --revert${R} Revert the last commit (soft reset)`);
302
- console.log(` ${C}-al, --alias${R} Install shell aliases for geeto`);
303
- console.log(` ${C}-rw, --reword${R} Edit past commit messages`);
304
- console.log(` ${C}-sts, --stats${R} Repository statistics dashboard`);
305
- console.log(` ${C} --abort${R} Abort in-progress operation`);
306
- console.log(` ${C}-pl, --pull${R} Pull from remote interactively`);
307
- console.log(` ${C}-ft, --fetch${R} Fetch latest from remote`);
308
- console.log(` ${C} --prune${R} Remove stale remote branches`);
309
- console.log(` ${C}-st, --status${R} Pretty git status overview`);
310
- console.log('');
311
- console.log(` ${B}GITHUB${R}`);
312
- console.log(` ${C}-pr, --pr${R} Create a Pull Request`);
313
- console.log(` ${C}-i, --issue${R} Create an Issue`);
314
- console.log(` ${C}-t, --tag${R} Release & tag manager with semver`);
315
- console.log(` ${C}-rp, --repo${R} Update GitHub repo settings`);
316
- console.log('');
317
- console.log(` ${B}TRELLO${R}`);
318
- console.log(` ${C}-tr, --trello${R} Open Trello menu`);
319
- console.log(` ${C}-tl, --trello-list${R} List boards and lists`);
320
- console.log(` ${C}-tg, --trello-generate${R} Generate tasks from Trello`);
321
- console.log('');
322
- console.log(` ${B}SETTINGS${R}`);
323
- console.log(` ${C} --setup-gemini${R} Configure Gemini AI`);
324
- console.log(` ${C} --setup-openrouter${R} Configure OpenRouter AI`);
325
- console.log(` ${C} --setup-github${R} Configure GitHub token`);
326
- console.log(` ${C} --setup-trello${R} Configure Trello integration`);
327
- console.log(` ${C} --change-model${R} Switch AI provider / model`);
328
- console.log(` ${C} --sync-models${R} Fetch latest model list`);
329
- console.log(` ${C} --separator${R} Set branch name separator`);
330
- console.log('');
331
- console.log(` ${B}OPTIONS${R}`);
332
- console.log(` ${C}-f, --fresh${R} Start fresh (ignore checkpoint)`);
333
- console.log(` ${C}-r, --resume${R} Resume from last checkpoint`);
334
- console.log(` ${C}-dr, --dry-run${R} Simulate commands without executing`);
335
- console.log(` ${C}-v, --version${R} Show version`);
336
- console.log(` ${C}-h, --help${R} Show this help message`);
337
- console.log('');
338
- console.log(` ${B}EDITOR${R}`);
339
- console.log(` ${C}geeto <file>${R} Open file in inline editor`);
340
- console.log('');
341
- process.exit(0);
342
- }
343
- // Dry-run mode handling
344
- if (dryRunMode) {
345
- const { setDryRun, printDryRunBanner, printDryRunSummary } = await import('./utils/dry-run.js');
346
- const hasOtherCommand = startAt !== undefined ||
347
- showCleanup ||
348
- showSwitch ||
349
- showCompare ||
350
- showCherryPick ||
351
- showPR ||
352
- showIssue ||
353
- showHistory ||
354
- showStash ||
355
- showAmend ||
356
- showStats ||
357
- showUndo ||
358
- showRelease ||
359
- showRepoSettings ||
360
- showTrello ||
361
- showTrelloLists ||
362
- showTrelloGenerate ||
363
- showAbort ||
364
- showPull ||
365
- showPrune ||
366
- showFetch ||
367
- showStatus ||
368
- showRevert ||
369
- showAlias ||
370
- showReword ||
371
- settingsAction !== undefined;
372
- if (!hasOtherCommand) {
373
- // Standalone --dry-run: show interactive menu
374
- try {
375
- const { handleDryRunMenu } = await import('./workflows/dry-run.js');
376
- await handleDryRunMenu();
377
- process.exit(0);
378
- }
379
- catch (error) {
380
- console.error('Dry-run error:', error);
381
- process.exit(1);
299
+ const validFlags = buildValidFlags();
300
+ function parseArgs(argv) {
301
+ let startAt;
302
+ let fresh = false;
303
+ let resume = false;
304
+ let stageAll = false;
305
+ let dryRunMode = false;
306
+ let showVersion = false;
307
+ let showHelp = false;
308
+ const activeFlags = new Set();
309
+ for (const arg of argv) {
310
+ // Start-at flags (workflow step shortcuts)
311
+ for (const sf of START_AT_FLAGS) {
312
+ if (arg === sf.flag || arg === sf.alias) {
313
+ startAt = sf.startAt;
382
314
  }
383
315
  }
384
- // Combo mode: activate dry-run, let normal routing handle it
385
- setDryRun(true);
386
- printDryRunBanner();
387
- // Wrap process.exit to print summary before exiting
388
- const originalExit = process.exit;
389
- process.exit = ((code) => {
390
- printDryRunSummary();
391
- originalExit(code);
392
- });
393
- }
394
- // Inline file editor: geeto <filepath>
395
- if (editFilePath) {
396
- try {
397
- const fs = await import('node:fs');
398
- const resolved = path.resolve(editFilePath);
399
- let content = '';
400
- if (fs.existsSync(resolved)) {
401
- content = fs.readFileSync(resolved, 'utf8');
402
- }
403
- console.log(` \u001B[90mEditing: ${resolved}\u001B[0m`);
404
- const { editInline } = await import('./cli/input.js');
405
- const result = await editInline(content, path.basename(editFilePath), path.extname(editFilePath));
406
- if (result === null) {
407
- console.log(` \u001B[90m✗ Cancelled\u001B[0m`);
408
- }
409
- else {
410
- fs.writeFileSync(resolved, result + '\n', 'utf8');
411
- console.log(` \u001B[32m✓\u001B[0m Saved to ${editFilePath}`);
316
+ // Special compound: -sa / -as stage + stageAll
317
+ if (arg === '-sa' || arg === '-as') {
318
+ startAt = 'stage';
319
+ stageAll = true;
320
+ }
321
+ // Modifier flags
322
+ if (arg === '-f' || arg === '--fresh')
323
+ fresh = true;
324
+ if (arg === '-r' || arg === '--resume')
325
+ resume = true;
326
+ if (arg === '-v' || arg === '--version')
327
+ showVersion = true;
328
+ if (arg === '-h' || arg === '--help')
329
+ showHelp = true;
330
+ if (arg === '--dry-run' || arg === '-dr')
331
+ dryRunMode = true;
332
+ // Command registry lookup
333
+ for (const cmd of COMMAND_REGISTRY) {
334
+ if (arg === cmd.flag || arg === cmd.alias) {
335
+ activeFlags.add(cmd.flag);
412
336
  }
413
- process.exit(0);
414
- }
415
- catch (error) {
416
- console.error('Editor error:', error);
417
- process.exit(1);
418
- }
419
- }
420
- if (showAbort) {
421
- try {
422
- const { handleAbort } = await import('./workflows/abort.js');
423
- await handleAbort();
424
- process.exit(0);
425
- }
426
- catch (error) {
427
- console.error('Abort error:', error);
428
- process.exit(1);
429
- }
430
- }
431
- if (showPull) {
432
- try {
433
- const { handlePull } = await import('./workflows/pull.js');
434
- await handlePull();
435
- process.exit(0);
436
- }
437
- catch (error) {
438
- console.error('Pull error:', error);
439
- process.exit(1);
440
- }
441
- }
442
- if (showPrune) {
443
- try {
444
- const { handlePrune } = await import('./workflows/prune.js');
445
- await handlePrune();
446
- process.exit(0);
447
- }
448
- catch (error) {
449
- console.error('Prune error:', error);
450
- process.exit(1);
451
- }
452
- }
453
- if (showFetch) {
454
- try {
455
- const { handleFetch } = await import('./workflows/fetch.js');
456
- await handleFetch();
457
- process.exit(0);
458
- }
459
- catch (error) {
460
- console.error('Fetch error:', error);
461
- process.exit(1);
462
- }
463
- }
464
- if (showStatus) {
465
- try {
466
- const { handleStatus } = await import('./workflows/status.js');
467
- handleStatus();
468
- process.exit(0);
469
- }
470
- catch (error) {
471
- console.error('Status error:', error);
472
- process.exit(1);
473
- }
474
- }
475
- if (showRevert) {
476
- try {
477
- const { handleRevert } = await import('./workflows/revert.js');
478
- await handleRevert();
479
- process.exit(0);
480
- }
481
- catch (error) {
482
- console.error('Revert error:', error);
483
- process.exit(1);
484
- }
485
- }
486
- if (showAlias) {
487
- try {
488
- const { handleAlias } = await import('./workflows/alias.js');
489
- await handleAlias();
490
- process.exit(0);
491
- }
492
- catch (error) {
493
- console.error('Alias error:', error);
494
- process.exit(1);
495
- }
496
- }
497
- if (showReword) {
498
- try {
499
- const { handleReword } = await import('./workflows/reword.js');
500
- await handleReword();
501
- process.exit(0);
502
- }
503
- catch (error) {
504
- console.error('Reword error:', error);
505
- process.exit(1);
506
- }
507
- }
508
- if (showCleanup) {
509
- try {
510
- const { handleInteractiveCleanup } = await import('./workflows/cleanup.js');
511
- await handleInteractiveCleanup();
512
- process.exit(0);
513
337
  }
514
- catch (error) {
515
- console.error('Cleanup error:', error);
516
- process.exit(1);
517
- }
518
- }
519
- if (showSwitch) {
520
- try {
521
- const { handleBranchSwitch } = await import('./workflows/switch.js');
522
- await handleBranchSwitch();
523
- process.exit(0);
524
- }
525
- catch (error) {
526
- console.error('Switch error:', error);
527
- process.exit(1);
528
- }
529
- }
530
- if (showCompare) {
531
- try {
532
- const { handleBranchCompare } = await import('./workflows/compare.js');
533
- await handleBranchCompare();
534
- process.exit(0);
535
- }
536
- catch (error) {
537
- console.error('Compare error:', error);
538
- process.exit(1);
539
- }
540
- }
541
- if (showCherryPick) {
542
- try {
543
- const { handleCherryPick } = await import('./workflows/cherry-pick.js');
544
- await handleCherryPick();
545
- process.exit(0);
546
- }
547
- catch (error) {
548
- console.error('Cherry-pick error:', error);
549
- process.exit(1);
550
- }
551
- }
552
- if (showPR) {
553
- try {
554
- const { handleCreatePR } = await import('./workflows/pr.js');
555
- await handleCreatePR();
556
- process.exit(0);
557
- }
558
- catch (error) {
559
- console.error('PR error:', error);
560
- process.exit(1);
561
- }
562
- }
563
- if (showIssue) {
564
- try {
565
- const { handleCreateIssue } = await import('./workflows/issue.js');
566
- await handleCreateIssue();
567
- process.exit(0);
568
- }
569
- catch (error) {
570
- console.error('Issue error:', error);
571
- process.exit(1);
572
- }
573
- }
574
- if (showHistory) {
575
- try {
576
- const { handleHistory } = await import('./workflows/history.js');
577
- await handleHistory();
578
- process.exit(0);
579
- }
580
- catch (error) {
581
- console.error('History error:', error);
582
- process.exit(1);
583
- }
584
- }
585
- if (showStash) {
586
- try {
587
- const { handleStash } = await import('./workflows/stash.js');
588
- await handleStash();
589
- process.exit(0);
590
- }
591
- catch (error) {
592
- console.error('Stash error:', error);
593
- process.exit(1);
594
- }
595
- }
596
- if (showAmend) {
597
- try {
598
- const { handleAmend } = await import('./workflows/amend.js');
599
- await handleAmend();
600
- process.exit(0);
601
- }
602
- catch (error) {
603
- console.error('Amend error:', error);
604
- process.exit(1);
605
- }
606
- }
607
- if (showStats) {
608
- try {
609
- const { handleStats } = await import('./workflows/stats.js');
610
- handleStats();
611
- process.exit(0);
612
- }
613
- catch (error) {
614
- console.error('Stats error:', error);
615
- process.exit(1);
616
- }
617
- }
618
- if (showUndo) {
619
- try {
620
- const { handleUndo } = await import('./workflows/undo.js');
621
- await handleUndo();
622
- process.exit(0);
623
- }
624
- catch (error) {
625
- console.error('Undo error:', error);
626
- process.exit(1);
627
- }
628
- }
629
- if (showRelease) {
630
- try {
631
- const { handleRelease } = await import('./workflows/release.js');
632
- await handleRelease();
633
- process.exit(0);
634
- }
635
- catch (error) {
636
- console.error('Release error:', error);
637
- process.exit(1);
638
- }
639
- }
640
- if (showRepoSettings) {
338
+ // Non-flag argument → ignored
339
+ }
340
+ return {
341
+ startAt,
342
+ fresh,
343
+ resume,
344
+ stageAll,
345
+ dryRunMode,
346
+ showVersion,
347
+ showHelp,
348
+ activeFlags,
349
+ };
350
+ }
351
+ // ─── Help Display ────────────────────────────────────────────────────
352
+ function showHelpMessage() {
353
+ const C = '\u001B[36m'; // cyan
354
+ const B = '\u001B[1m'; // bright/bold
355
+ const G = '\u001B[90m'; // gray
356
+ const R = '\u001B[0m'; // reset
357
+ console.log('');
358
+ console.log(` ${B}Geeto CLI${R} ${G}v${VERSION}${R}`);
359
+ console.log(` ${G}Git flow automation with AI-powered workflows${R}`);
360
+ console.log('');
361
+ console.log(` ${B}USAGE${R}`);
362
+ console.log(` ${C}geeto${R} ${G}[command] [options]${R}`);
363
+ console.log('');
364
+ console.log(` ${B}WORKFLOW${R}`);
365
+ console.log(` ${C}-s, --stage${R} Stage files interactively`);
366
+ console.log(` ${C}-sa, -as${R} Stage all changes automatically`);
367
+ console.log(` ${C}-c, --commit${R} Create a commit with AI message`);
368
+ console.log(` ${C}-b, --branch${R} Create a branch with AI name`);
369
+ console.log(` ${C}-p, --push${R} Push current branch to remote`);
370
+ console.log(` ${C}-m, --merge${R} Merge branches interactively`);
371
+ console.log('');
372
+ console.log(` ${B}GIT TOOLS${R}`);
373
+ console.log(` ${C}-cl, --cleanup${R} Clean up local & remote branches`);
374
+ console.log(` ${C}-sw, --switch${R} Switch branches with fuzzy search`);
375
+ console.log(` ${C}-cmp, --compare${R} Compare current branch with another`);
376
+ console.log(` ${C}-cp, --cherry-pick${R} Cherry-pick from another branch`);
377
+ console.log(` ${C}-lg, --log${R} View commit history with timeline`);
378
+ console.log(` ${C}-sh, --stash${R} Manage stashes interactively`);
379
+ console.log(` ${C}-am, --amend${R} Amend the last commit`);
380
+ console.log(` ${C}-u, --undo${R} Undo the last git action safely`);
381
+ console.log(` ${C}-rv, --revert${R} Revert the last commit (soft reset)`);
382
+ console.log(` ${C}-al, --alias${R} Install shell aliases for geeto`);
383
+ console.log(` ${C}-rw, --reword${R} Edit past commit messages`);
384
+ console.log(` ${C}-sts, --stats${R} Repository statistics dashboard`);
385
+ console.log(` ${C}-sm, --submodules${R} Manage git submodules`);
386
+ console.log(` ${C} --abort${R} Abort in-progress operation`);
387
+ console.log(` ${C}-pl, --pull${R} Pull from remote interactively`);
388
+ console.log(` ${C}-ft, --fetch${R} Fetch latest from remote`);
389
+ console.log(` ${C} --prune${R} Remove stale remote branches`);
390
+ console.log(` ${C}-st, --status${R} Pretty git status overview`);
391
+ console.log('');
392
+ console.log(` ${B}GITHUB / GITLAB${R}`);
393
+ console.log(` ${C}-pr, --pr${R} Create a Pull Request / Merge Request`);
394
+ console.log(` ${C}-i, --issue${R} Create an Issue`);
395
+ console.log(` ${C}-t, --tag${R} Release & tag manager with semver`);
396
+ console.log(` ${C}-rp, --repo${R} Update repo settings`);
397
+ console.log('');
398
+ console.log(` ${B}TRELLO${R}`);
399
+ console.log(` ${C}-tr, --trello${R} Open Trello menu`);
400
+ console.log(` ${C}-tl, --trello-list${R} List boards and lists`);
401
+ console.log(` ${C}-tg, --trello-generate${R} Generate tasks from Trello`);
402
+ console.log('');
403
+ console.log(` ${B}SETTINGS${R}`);
404
+ console.log(` ${C} --setup-copilot${R} Configure GitHub Copilot`);
405
+ console.log(` ${C} --setup-gemini${R} Configure Gemini AI`);
406
+ console.log(` ${C} --setup-openrouter${R} Configure OpenRouter AI`);
407
+ console.log(` ${C} --setup-github${R} Configure GitHub token`);
408
+ console.log(` ${C} --setup-gitlab${R} Configure GitLab token`);
409
+ console.log(` ${C} --setup-trello${R} Configure Trello integration`);
410
+ console.log(` ${C} --change-model${R} Switch AI provider / model`);
411
+ console.log(` ${C} --sync-models${R} Fetch latest model list`);
412
+ console.log(` ${C} --separator${R} Set branch name separator`);
413
+ console.log('');
414
+ console.log(` ${B}OPTIONS${R}`);
415
+ console.log(` ${C}-f, --fresh${R} Start fresh (ignore checkpoint)`);
416
+ console.log(` ${C}-r, --resume${R} Resume from last checkpoint`);
417
+ console.log(` ${C}-dr, --dry-run${R} Simulate commands without executing`);
418
+ console.log(` ${C}-v, --version${R} Show version`);
419
+ console.log(` ${C}-h, --help${R} Show this help message`);
420
+ console.log('');
421
+ console.log(` ${B}INFO${R}`);
422
+ console.log(` ${C} --where${R} Show installation path & method`);
423
+ console.log(` ${C} --uninstall${R} Uninstall geeto CLI`);
424
+ console.log('');
425
+ }
426
+ // ─── Command Execution ───────────────────────────────────────────────
427
+ /**
428
+ * Static module map for compiled binary compatibility.
429
+ * Bun's compiler can only resolve string-literal dynamic imports — variable
430
+ * paths like `import(cmd.module)` won't be bundled. This map provides
431
+ * explicit string-literal imports that the compiler CAN resolve.
432
+ */
433
+ const MODULE_LOADERS = {
434
+ './workflows/abort.js': () => import('./workflows/abort.js'),
435
+ './workflows/pull.js': () => import('./workflows/pull.js'),
436
+ './workflows/prune.js': () => import('./workflows/prune.js'),
437
+ './workflows/fetch.js': () => import('./workflows/fetch.js'),
438
+ './workflows/status.js': () => import('./workflows/status.js'),
439
+ './workflows/revert.js': () => import('./workflows/revert.js'),
440
+ './workflows/alias.js': () => import('./workflows/alias.js'),
441
+ './workflows/reword.js': () => import('./workflows/reword.js'),
442
+ './workflows/cleanup.js': () => import('./workflows/cleanup.js'),
443
+ './workflows/switch.js': () => import('./workflows/switch.js'),
444
+ './workflows/compare.js': () => import('./workflows/compare.js'),
445
+ './workflows/cherry-pick.js': () => import('./workflows/cherry-pick.js'),
446
+ './workflows/pr.js': () => import('./workflows/pr.js'),
447
+ './workflows/issue.js': () => import('./workflows/issue.js'),
448
+ './workflows/history.js': () => import('./workflows/history.js'),
449
+ './workflows/stash.js': () => import('./workflows/stash.js'),
450
+ './workflows/amend.js': () => import('./workflows/amend.js'),
451
+ './workflows/stats.js': () => import('./workflows/stats.js'),
452
+ './workflows/undo.js': () => import('./workflows/undo.js'),
453
+ './workflows/release.js': () => import('./workflows/release.js'),
454
+ './workflows/repo-settings.js': () => import('./workflows/repo-settings.js'),
455
+ './workflows/submodules.js': () => import('./workflows/submodules.js'),
456
+ './workflows/trello-menu.js': () => import('./workflows/trello-menu.js'),
457
+ './workflows/settings.js': () => import('./workflows/settings.js'),
458
+ './core/github-setup.js': () => import('./core/github-setup.js'),
459
+ './core/gitlab-setup.js': () => import('./core/gitlab-setup.js'),
460
+ './workflows/doctor.js': () => import('./workflows/doctor.js'),
461
+ };
462
+ async function handleDryRunSetup(args) {
463
+ const { setDryRun, printDryRunBanner, printDryRunSummary } = await import('./utils/dry-run.js');
464
+ const hasOtherCommand = args.startAt !== undefined || args.activeFlags.size > 0;
465
+ if (!hasOtherCommand) {
466
+ // Standalone --dry-run: show interactive menu
641
467
  try {
642
- const { handleRepoSettings } = await import('./workflows/repo-settings.js');
643
- await handleRepoSettings();
468
+ const { handleDryRunMenu } = await import('./workflows/dry-run.js');
469
+ await handleDryRunMenu();
644
470
  process.exit(0);
645
471
  }
646
472
  catch (error) {
647
- console.error('Repo settings error:', error);
473
+ console.error('Dry-run error:', error);
648
474
  process.exit(1);
649
475
  }
650
476
  }
651
- if (showTrello) {
652
- try {
653
- const { showTrelloMenu } = await import('./workflows/trello-menu.js');
654
- await showTrelloMenu();
655
- process.exit(0);
656
- }
657
- catch (error) {
658
- console.error('Trello menu error:', error);
659
- process.exit(1);
660
- }
477
+ // Combo mode: activate dry-run, let normal routing handle it
478
+ setDryRun(true);
479
+ printDryRunBanner();
480
+ // Wrap process.exit to print summary before exiting
481
+ const originalExit = process.exit;
482
+ process.exit = ((code) => {
483
+ printDryRunSummary();
484
+ originalExit(code);
485
+ });
486
+ }
487
+ async function executeCommand(args) {
488
+ // 1. Version (instant, no imports)
489
+ if (args.showVersion) {
490
+ console.log(`Geeto v${VERSION}`);
491
+ process.exit(0);
661
492
  }
662
- if (showTrelloLists) {
663
- try {
664
- const { handleGetTrelloLists } = await import('./workflows/trello-menu.js');
665
- await handleGetTrelloLists();
666
- process.exit(0);
667
- }
668
- catch (error) {
669
- console.error('Trello list error:', error);
670
- process.exit(1);
671
- }
493
+ // 2. Help (instant, no imports)
494
+ if (args.showHelp) {
495
+ showHelpMessage();
496
+ process.exit(0);
672
497
  }
673
- if (showTrelloGenerate) {
674
- try {
675
- const { handleGenerateTaskInstructions } = await import('./workflows/trello-menu.js');
676
- await handleGenerateTaskInstructions();
677
- process.exit(0);
678
- }
679
- catch (error) {
680
- console.error('Trello generate error:', error);
681
- process.exit(1);
682
- }
498
+ // 3. Dry-run mode setup (must run before other commands)
499
+ if (args.dryRunMode) {
500
+ await handleDryRunSetup(args);
683
501
  }
684
- if (settingsAction) {
685
- try {
686
- const { handleSeparatorSetting, handleModelResetSetting, handleChangeModelSetting, handleGeminiSetting, handleOpenRouterSetting, handleTrelloSetting, } = await import('./workflows/settings.js');
687
- switch (settingsAction) {
688
- case 'separator': {
689
- await handleSeparatorSetting();
690
- break;
691
- }
692
- case 'models': {
693
- await handleModelResetSetting();
694
- break;
695
- }
696
- case 'change-model': {
697
- await handleChangeModelSetting();
698
- break;
699
- }
700
- case 'gemini': {
701
- await handleGeminiSetting();
702
- break;
703
- }
704
- case 'openrouter': {
705
- await handleOpenRouterSetting();
706
- break;
707
- }
708
- case 'trello': {
709
- await handleTrelloSetting();
710
- break;
711
- }
712
- case 'github': {
713
- const { setupGithubConfigInteractive } = await import('./core/github-setup.js');
714
- setupGithubConfigInteractive();
715
- break;
502
+ // 4. Registry commands — first match wins
503
+ for (const cmd of COMMAND_REGISTRY) {
504
+ if (args.activeFlags.has(cmd.flag)) {
505
+ try {
506
+ const loader = MODULE_LOADERS[cmd.module];
507
+ if (!loader)
508
+ throw new Error(`No module loader for ${cmd.module}`);
509
+ const mod = (await loader());
510
+ const handlerFn = mod[cmd.handler];
511
+ if (handlerFn) {
512
+ await handlerFn();
716
513
  }
514
+ process.exit(0);
515
+ }
516
+ catch (error) {
517
+ console.error(`${cmd.errorLabel} error:`, error);
518
+ process.exit(1);
717
519
  }
718
- process.exit(0);
719
- }
720
- catch (error) {
721
- console.error('Settings error:', error);
722
- process.exit(1);
723
520
  }
724
521
  }
725
- // Pass stageAll flag into main so workflows can auto-stage all changes
726
- // Start the application with optional start step
727
- main({ startAt, fresh, resume, stageAll }).catch((error) => {
522
+ // 6. Default: run main workflow
523
+ const { main } = await import('./workflows/main.js');
524
+ main({
525
+ startAt: args.startAt,
526
+ fresh: args.fresh,
527
+ resume: args.resume,
528
+ stageAll: args.stageAll,
529
+ }).catch((error) => {
728
530
  console.error('Fatal error:', error);
729
531
  process.exit(1);
730
532
  });
731
- })();
533
+ }
534
+ // ─── Entry Point ─────────────────────────────────────────────────────
535
+ const argv = process.argv.slice(2);
536
+ // Validate unknown flags
537
+ for (const arg of argv) {
538
+ if (arg.startsWith('-') && !validFlags.has(arg)) {
539
+ console.error(`Unknown flag: ${arg}`);
540
+ console.error('Use --help to see available options');
541
+ process.exit(1);
542
+ }
543
+ }
544
+ const args = parseArgs(argv);
545
+ void executeCommand(args);
732
546
  //# sourceMappingURL=index.js.map