gitcoach-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 (185) hide show
  1. package/bin/run.js +80 -0
  2. package/dist/analytics/index.d.ts +3 -0
  3. package/dist/analytics/index.d.ts.map +1 -0
  4. package/dist/analytics/index.js +3 -0
  5. package/dist/analytics/index.js.map +1 -0
  6. package/dist/analytics/stats-calculator.d.ts +24 -0
  7. package/dist/analytics/stats-calculator.d.ts.map +1 -0
  8. package/dist/analytics/stats-calculator.js +135 -0
  9. package/dist/analytics/stats-calculator.js.map +1 -0
  10. package/dist/analytics/tracker.d.ts +36 -0
  11. package/dist/analytics/tracker.d.ts.map +1 -0
  12. package/dist/analytics/tracker.js +103 -0
  13. package/dist/analytics/tracker.js.map +1 -0
  14. package/dist/commands/config.d.ts +7 -0
  15. package/dist/commands/config.d.ts.map +1 -0
  16. package/dist/commands/config.js +12 -0
  17. package/dist/commands/config.js.map +1 -0
  18. package/dist/commands/index.d.ts +9 -0
  19. package/dist/commands/index.d.ts.map +1 -0
  20. package/dist/commands/index.js +154 -0
  21. package/dist/commands/index.js.map +1 -0
  22. package/dist/commands/init.d.ts +7 -0
  23. package/dist/commands/init.d.ts.map +1 -0
  24. package/dist/commands/init.js +45 -0
  25. package/dist/commands/init.js.map +1 -0
  26. package/dist/commands/quick.d.ts +12 -0
  27. package/dist/commands/quick.d.ts.map +1 -0
  28. package/dist/commands/quick.js +112 -0
  29. package/dist/commands/quick.js.map +1 -0
  30. package/dist/commands/stats.d.ts +7 -0
  31. package/dist/commands/stats.d.ts.map +1 -0
  32. package/dist/commands/stats.js +42 -0
  33. package/dist/commands/stats.js.map +1 -0
  34. package/dist/config/defaults.d.ts +37 -0
  35. package/dist/config/defaults.d.ts.map +1 -0
  36. package/dist/config/defaults.js +33 -0
  37. package/dist/config/defaults.js.map +1 -0
  38. package/dist/config/index.d.ts +3 -0
  39. package/dist/config/index.d.ts.map +1 -0
  40. package/dist/config/index.js +3 -0
  41. package/dist/config/index.js.map +1 -0
  42. package/dist/config/user-config.d.ts +33 -0
  43. package/dist/config/user-config.d.ts.map +1 -0
  44. package/dist/config/user-config.js +106 -0
  45. package/dist/config/user-config.js.map +1 -0
  46. package/dist/i18n/index.d.ts +8 -0
  47. package/dist/i18n/index.d.ts.map +1 -0
  48. package/dist/i18n/index.js +45 -0
  49. package/dist/i18n/index.js.map +1 -0
  50. package/dist/i18n/locales/en.json +353 -0
  51. package/dist/i18n/locales/es.json +353 -0
  52. package/dist/i18n/locales/fr.json +353 -0
  53. package/dist/index.d.ts +9 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +11 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/services/analysis-service.d.ts +24 -0
  58. package/dist/services/analysis-service.d.ts.map +1 -0
  59. package/dist/services/analysis-service.js +158 -0
  60. package/dist/services/analysis-service.js.map +1 -0
  61. package/dist/services/copilot-service.d.ts +30 -0
  62. package/dist/services/copilot-service.d.ts.map +1 -0
  63. package/dist/services/copilot-service.js +385 -0
  64. package/dist/services/copilot-service.js.map +1 -0
  65. package/dist/services/git-service.d.ts +75 -0
  66. package/dist/services/git-service.d.ts.map +1 -0
  67. package/dist/services/git-service.js +230 -0
  68. package/dist/services/git-service.js.map +1 -0
  69. package/dist/services/index.d.ts +5 -0
  70. package/dist/services/index.d.ts.map +1 -0
  71. package/dist/services/index.js +5 -0
  72. package/dist/services/index.js.map +1 -0
  73. package/dist/services/prevention-service.d.ts +29 -0
  74. package/dist/services/prevention-service.d.ts.map +1 -0
  75. package/dist/services/prevention-service.js +213 -0
  76. package/dist/services/prevention-service.js.map +1 -0
  77. package/dist/ui/components/box.d.ts +16 -0
  78. package/dist/ui/components/box.d.ts.map +1 -0
  79. package/dist/ui/components/box.js +100 -0
  80. package/dist/ui/components/box.js.map +1 -0
  81. package/dist/ui/components/index.d.ts +5 -0
  82. package/dist/ui/components/index.d.ts.map +1 -0
  83. package/dist/ui/components/index.js +5 -0
  84. package/dist/ui/components/index.js.map +1 -0
  85. package/dist/ui/components/prompt.d.ts +19 -0
  86. package/dist/ui/components/prompt.d.ts.map +1 -0
  87. package/dist/ui/components/prompt.js +62 -0
  88. package/dist/ui/components/prompt.js.map +1 -0
  89. package/dist/ui/components/spinner.d.ts +8 -0
  90. package/dist/ui/components/spinner.d.ts.map +1 -0
  91. package/dist/ui/components/spinner.js +24 -0
  92. package/dist/ui/components/spinner.js.map +1 -0
  93. package/dist/ui/components/table.d.ts +25 -0
  94. package/dist/ui/components/table.d.ts.map +1 -0
  95. package/dist/ui/components/table.js +72 -0
  96. package/dist/ui/components/table.js.map +1 -0
  97. package/dist/ui/index.d.ts +3 -0
  98. package/dist/ui/index.d.ts.map +1 -0
  99. package/dist/ui/index.js +3 -0
  100. package/dist/ui/index.js.map +1 -0
  101. package/dist/ui/menus/add-menu.d.ts +6 -0
  102. package/dist/ui/menus/add-menu.d.ts.map +1 -0
  103. package/dist/ui/menus/add-menu.js +60 -0
  104. package/dist/ui/menus/add-menu.js.map +1 -0
  105. package/dist/ui/menus/branch-menu.d.ts +8 -0
  106. package/dist/ui/menus/branch-menu.d.ts.map +1 -0
  107. package/dist/ui/menus/branch-menu.js +141 -0
  108. package/dist/ui/menus/branch-menu.js.map +1 -0
  109. package/dist/ui/menus/commit-menu.d.ts +7 -0
  110. package/dist/ui/menus/commit-menu.d.ts.map +1 -0
  111. package/dist/ui/menus/commit-menu.js +129 -0
  112. package/dist/ui/menus/commit-menu.js.map +1 -0
  113. package/dist/ui/menus/config-menu.d.ts +3 -0
  114. package/dist/ui/menus/config-menu.d.ts.map +1 -0
  115. package/dist/ui/menus/config-menu.js +97 -0
  116. package/dist/ui/menus/config-menu.js.map +1 -0
  117. package/dist/ui/menus/help-menu.d.ts +3 -0
  118. package/dist/ui/menus/help-menu.d.ts.map +1 -0
  119. package/dist/ui/menus/help-menu.js +133 -0
  120. package/dist/ui/menus/help-menu.js.map +1 -0
  121. package/dist/ui/menus/history-menu.d.ts +3 -0
  122. package/dist/ui/menus/history-menu.d.ts.map +1 -0
  123. package/dist/ui/menus/history-menu.js +129 -0
  124. package/dist/ui/menus/history-menu.js.map +1 -0
  125. package/dist/ui/menus/index.d.ts +8 -0
  126. package/dist/ui/menus/index.d.ts.map +1 -0
  127. package/dist/ui/menus/index.js +8 -0
  128. package/dist/ui/menus/index.js.map +1 -0
  129. package/dist/ui/menus/main-menu.d.ts +4 -0
  130. package/dist/ui/menus/main-menu.d.ts.map +1 -0
  131. package/dist/ui/menus/main-menu.js +134 -0
  132. package/dist/ui/menus/main-menu.js.map +1 -0
  133. package/dist/ui/menus/pull-menu.d.ts +7 -0
  134. package/dist/ui/menus/pull-menu.d.ts.map +1 -0
  135. package/dist/ui/menus/pull-menu.js +69 -0
  136. package/dist/ui/menus/pull-menu.js.map +1 -0
  137. package/dist/ui/menus/push-menu.d.ts +8 -0
  138. package/dist/ui/menus/push-menu.d.ts.map +1 -0
  139. package/dist/ui/menus/push-menu.js +160 -0
  140. package/dist/ui/menus/push-menu.js.map +1 -0
  141. package/dist/ui/menus/setup-menu.d.ts +5 -0
  142. package/dist/ui/menus/setup-menu.d.ts.map +1 -0
  143. package/dist/ui/menus/setup-menu.js +234 -0
  144. package/dist/ui/menus/setup-menu.js.map +1 -0
  145. package/dist/ui/menus/stash-menu.d.ts +3 -0
  146. package/dist/ui/menus/stash-menu.d.ts.map +1 -0
  147. package/dist/ui/menus/stash-menu.js +205 -0
  148. package/dist/ui/menus/stash-menu.js.map +1 -0
  149. package/dist/ui/menus/undo-menu.d.ts +3 -0
  150. package/dist/ui/menus/undo-menu.d.ts.map +1 -0
  151. package/dist/ui/menus/undo-menu.js +197 -0
  152. package/dist/ui/menus/undo-menu.js.map +1 -0
  153. package/dist/ui/themes/colored.d.ts +35 -0
  154. package/dist/ui/themes/colored.d.ts.map +1 -0
  155. package/dist/ui/themes/colored.js +85 -0
  156. package/dist/ui/themes/colored.js.map +1 -0
  157. package/dist/ui/themes/index.d.ts +39 -0
  158. package/dist/ui/themes/index.d.ts.map +1 -0
  159. package/dist/ui/themes/index.js +9 -0
  160. package/dist/ui/themes/index.js.map +1 -0
  161. package/dist/ui/themes/monochrome.d.ts +35 -0
  162. package/dist/ui/themes/monochrome.d.ts.map +1 -0
  163. package/dist/ui/themes/monochrome.js +80 -0
  164. package/dist/ui/themes/monochrome.js.map +1 -0
  165. package/dist/utils/error-helper.d.ts +10 -0
  166. package/dist/utils/error-helper.d.ts.map +1 -0
  167. package/dist/utils/error-helper.js +55 -0
  168. package/dist/utils/error-helper.js.map +1 -0
  169. package/dist/utils/helpers.d.ts +16 -0
  170. package/dist/utils/helpers.d.ts.map +1 -0
  171. package/dist/utils/helpers.js +95 -0
  172. package/dist/utils/helpers.js.map +1 -0
  173. package/dist/utils/index.d.ts +4 -0
  174. package/dist/utils/index.d.ts.map +1 -0
  175. package/dist/utils/index.js +4 -0
  176. package/dist/utils/index.js.map +1 -0
  177. package/dist/utils/logger.d.ts +24 -0
  178. package/dist/utils/logger.d.ts.map +1 -0
  179. package/dist/utils/logger.js +71 -0
  180. package/dist/utils/logger.js.map +1 -0
  181. package/dist/utils/validators.d.ts +10 -0
  182. package/dist/utils/validators.d.ts.map +1 -0
  183. package/dist/utils/validators.js +78 -0
  184. package/dist/utils/validators.js.map +1 -0
  185. package/package.json +71 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/themes/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAsClD,MAAM,UAAU,QAAQ;IACtB,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC;IACxC,OAAO,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC;AAClE,CAAC;AAED,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,35 @@
1
+ export declare const monochromeTheme: {
2
+ primary: (text: string) => string;
3
+ secondary: (text: string) => string;
4
+ accent: (text: string) => string;
5
+ success: (text: string) => string;
6
+ warning: (text: string) => string;
7
+ error: (text: string) => string;
8
+ info: (text: string) => string;
9
+ text: (text: string) => string;
10
+ textMuted: (text: string) => string;
11
+ textBold: (text: string) => string;
12
+ staged: (text: string) => string;
13
+ modified: (text: string) => string;
14
+ deleted: (text: string) => string;
15
+ untracked: (text: string) => string;
16
+ branch: (text: string) => string;
17
+ border: (text: string) => string;
18
+ highlight: (text: string) => string;
19
+ selected: (text: string) => string;
20
+ bold: (text: string) => string;
21
+ dim: (text: string) => string;
22
+ italic: (text: string) => string;
23
+ underline: (text: string) => string;
24
+ title(text: string): string;
25
+ subtitle(text: string): string;
26
+ menuItem(key: string, label: string): string;
27
+ statusBadge(type: "success" | "warning" | "error" | "info", text: string): string;
28
+ file(name: string, status: "staged" | "modified" | "deleted" | "untracked"): string;
29
+ commitHash(hash: string): string;
30
+ branchName(name: string, current?: boolean): string;
31
+ keyHint(key: string): string;
32
+ progressBar(percent: number, width?: number): string;
33
+ };
34
+ export default monochromeTheme;
35
+ //# sourceMappingURL=monochrome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monochrome.d.ts","sourceRoot":"","sources":["../../../src/ui/themes/monochrome.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe;oBAFR,MAAM;sBAAN,MAAM;mBAAN,MAAM;oBAAN,MAAM;oBAAN,MAAM;kBAAN,MAAM;iBAAN,MAAM;iBAAN,MAAM;sBAAN,MAAM;qBAAN,MAAM;mBAAN,MAAM;qBAAN,MAAM;oBAAN,MAAM;sBAAN,MAAM;mBAAN,MAAM;mBAAN,MAAM;sBAAN,MAAM;qBAAN,MAAM;iBAAN,MAAM;gBAAN,MAAM;mBAAN,MAAM;sBAAN,MAAM;gBAsCZ,MAAM,GAAG,MAAM;mBAIZ,MAAM,GAAG,MAAM;kBAIhB,MAAM,SAAS,MAAM,GAAG,MAAM;sBAI1B,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,QAAQ,MAAM,GAAG,MAAM;eAUtE,MAAM,UAAU,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM;qBAUlE,MAAM,GAAG,MAAM;qBAIf,MAAM,YAAW,OAAO,GAAW,MAAM;iBAO7C,MAAM,GAAG,MAAM;yBAIP,MAAM,UAAS,MAAM,GAAQ,MAAM;CAMzD,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -0,0 +1,80 @@
1
+ // Monochrome theme - no colors, plain text output
2
+ const noOp = (text) => text;
3
+ export const monochromeTheme = {
4
+ // Brand colors (no-op)
5
+ primary: noOp,
6
+ secondary: noOp,
7
+ accent: noOp,
8
+ // Status colors (no-op)
9
+ success: noOp,
10
+ warning: noOp,
11
+ error: noOp,
12
+ info: noOp,
13
+ // Text colors (no-op)
14
+ text: noOp,
15
+ textMuted: noOp,
16
+ textBold: noOp,
17
+ // Git status colors (no-op)
18
+ staged: noOp,
19
+ modified: noOp,
20
+ deleted: noOp,
21
+ untracked: noOp,
22
+ branch: noOp,
23
+ // UI elements (no-op)
24
+ border: noOp,
25
+ highlight: noOp,
26
+ selected: noOp,
27
+ // Formatting helpers (no-op)
28
+ bold: noOp,
29
+ dim: noOp,
30
+ italic: noOp,
31
+ underline: noOp,
32
+ // Semantic styling
33
+ title(text) {
34
+ return `=== ${text.toUpperCase()} ===`;
35
+ },
36
+ subtitle(text) {
37
+ return `--- ${text} ---`;
38
+ },
39
+ menuItem(key, label) {
40
+ return `[${key}] ${label}`;
41
+ },
42
+ statusBadge(type, text) {
43
+ const labels = {
44
+ success: '[OK]',
45
+ warning: '[WARN]',
46
+ error: '[ERROR]',
47
+ info: '[INFO]'
48
+ };
49
+ return `${labels[type]} ${text}`;
50
+ },
51
+ file(name, status) {
52
+ const prefixes = {
53
+ staged: '[+]',
54
+ modified: '[~]',
55
+ deleted: '[-]',
56
+ untracked: '[?]'
57
+ };
58
+ return `${prefixes[status]} ${name}`;
59
+ },
60
+ commitHash(hash) {
61
+ return hash.substring(0, 7);
62
+ },
63
+ branchName(name, current = false) {
64
+ if (current) {
65
+ return `* ${name}`;
66
+ }
67
+ return ` ${name}`;
68
+ },
69
+ keyHint(key) {
70
+ return `[${key}]`;
71
+ },
72
+ progressBar(percent, width = 20) {
73
+ const filled = Math.round((percent / 100) * width);
74
+ const empty = width - filled;
75
+ const bar = '#'.repeat(filled) + '-'.repeat(empty);
76
+ return `[${bar}] ${percent}%`;
77
+ }
78
+ };
79
+ export default monochromeTheme;
80
+ //# sourceMappingURL=monochrome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monochrome.js","sourceRoot":"","sources":["../../../src/ui/themes/monochrome.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC;AAEpC,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,uBAAuB;IACvB,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,IAAI;IACf,MAAM,EAAE,IAAI;IAEZ,wBAAwB;IACxB,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,IAAI;IACb,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IAEV,sBAAsB;IACtB,IAAI,EAAE,IAAI;IACV,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,IAAI;IAEd,4BAA4B;IAC5B,MAAM,EAAE,IAAI;IACZ,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,IAAI;IACf,MAAM,EAAE,IAAI;IAEZ,sBAAsB;IACtB,MAAM,EAAE,IAAI;IACZ,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,IAAI;IAEd,6BAA6B;IAC7B,IAAI,EAAE,IAAI;IACV,GAAG,EAAE,IAAI;IACT,MAAM,EAAE,IAAI;IACZ,SAAS,EAAE,IAAI;IAEf,mBAAmB;IACnB,KAAK,CAAC,IAAY;QAChB,OAAO,OAAO,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC;IACzC,CAAC;IAED,QAAQ,CAAC,IAAY;QACnB,OAAO,OAAO,IAAI,MAAM,CAAC;IAC3B,CAAC;IAED,QAAQ,CAAC,GAAW,EAAE,KAAa;QACjC,OAAO,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,WAAW,CAAC,IAA8C,EAAE,IAAY;QACtE,MAAM,MAAM,GAAG;YACb,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,QAAQ;YACjB,KAAK,EAAE,SAAS;YAChB,IAAI,EAAE,QAAQ;SACf,CAAC;QACF,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IACnC,CAAC;IAED,IAAI,CAAC,IAAY,EAAE,MAAuD;QACxE,MAAM,QAAQ,GAAG;YACf,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,KAAK;SACjB,CAAC;QACF,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;IACvC,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED,UAAU,CAAC,IAAY,EAAE,UAAmB,KAAK;QAC/C,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,CAAC;QACD,OAAO,KAAK,IAAI,EAAE,CAAC;IACrB,CAAC;IAED,OAAO,CAAC,GAAW;QACjB,OAAO,IAAI,GAAG,GAAG,CAAC;IACpB,CAAC;IAED,WAAW,CAAC,OAAe,EAAE,QAAgB,EAAE;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;QAC7B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnD,OAAO,IAAI,GAAG,KAAK,OAAO,GAAG,CAAC;IAChC,CAAC;CACF,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Handle a Git error with optional AI explanation
3
+ * Shows the error and offers to explain it using Copilot CLI
4
+ */
5
+ export declare function handleGitError(error: Error | string, command?: string, autoExplain?: boolean): Promise<void>;
6
+ /**
7
+ * Format a Git error message for display
8
+ */
9
+ export declare function formatGitError(error: Error | string): string;
10
+ //# sourceMappingURL=error-helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-helper.d.ts","sourceRoot":"","sources":["../../src/utils/error-helper.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,KAAK,GAAG,MAAM,EACrB,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,GAAE,OAAe,GAC3B,OAAO,CAAC,IAAI,CAAC,CA2Cf;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAS5D"}
@@ -0,0 +1,55 @@
1
+ import { t } from '../i18n/index.js';
2
+ import { warningBox, infoBox } from '../ui/components/box.js';
3
+ import { promptConfirm } from '../ui/components/prompt.js';
4
+ import { createSpinner } from '../ui/components/spinner.js';
5
+ import { copilotService } from '../services/copilot-service.js';
6
+ import { logger } from './logger.js';
7
+ /**
8
+ * Handle a Git error with optional AI explanation
9
+ * Shows the error and offers to explain it using Copilot CLI
10
+ */
11
+ export async function handleGitError(error, command, autoExplain = false) {
12
+ const errorMessage = error instanceof Error ? error.message : error;
13
+ // Display the error
14
+ logger.raw(warningBox(errorMessage, t('errors.title') || 'Error'));
15
+ // Check if Copilot is available
16
+ const copilotAvailable = await copilotService.isAvailable();
17
+ if (!copilotAvailable) {
18
+ return;
19
+ }
20
+ // Either auto-explain or ask the user
21
+ let shouldExplain = autoExplain;
22
+ if (!autoExplain) {
23
+ shouldExplain = await promptConfirm(t('errors.explainWithAI') || 'Would you like an AI explanation of this error?', true);
24
+ }
25
+ if (shouldExplain) {
26
+ const spinner = createSpinner({ text: t('errors.analyzing') || 'Analyzing error...' });
27
+ spinner.start();
28
+ try {
29
+ const explanation = await copilotService.explainGitError(errorMessage, command);
30
+ if (explanation.success && explanation.message) {
31
+ spinner.succeed();
32
+ logger.raw('\n' + infoBox(explanation.message, t('errors.explanation') || 'Explanation'));
33
+ }
34
+ else {
35
+ spinner.warn(t('errors.noExplanation') || 'Could not explain the error');
36
+ }
37
+ }
38
+ catch {
39
+ spinner.warn(t('errors.explainFailed') || 'Failed to get explanation');
40
+ }
41
+ }
42
+ }
43
+ /**
44
+ * Format a Git error message for display
45
+ */
46
+ export function formatGitError(error) {
47
+ const message = error instanceof Error ? error.message : error;
48
+ // Clean up common Git error prefixes
49
+ return message
50
+ .replace(/^error:\s*/i, '')
51
+ .replace(/^fatal:\s*/i, '')
52
+ .replace(/^warning:\s*/i, '')
53
+ .trim();
54
+ }
55
+ //# sourceMappingURL=error-helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-helper.js","sourceRoot":"","sources":["../../src/utils/error-helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,kBAAkB,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,KAAqB,EACrB,OAAgB,EAChB,cAAuB,KAAK;IAE5B,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAEpE,oBAAoB;IACpB,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC,cAAc,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC;IAEnE,gCAAgC;IAChC,MAAM,gBAAgB,GAAG,MAAM,cAAc,CAAC,WAAW,EAAE,CAAC;IAE5D,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO;IACT,CAAC;IAED,sCAAsC;IACtC,IAAI,aAAa,GAAG,WAAW,CAAC;IAEhC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,aAAa,GAAG,MAAM,aAAa,CACjC,CAAC,CAAC,sBAAsB,CAAC,IAAI,iDAAiD,EAC9E,IAAI,CACL,CAAC;IACJ,CAAC;IAED,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,kBAAkB,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;QACvF,OAAO,CAAC,KAAK,EAAE,CAAC;QAEhB,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,eAAe,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAEhF,IAAI,WAAW,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;gBAC/C,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,OAAO,CACvB,WAAW,CAAC,OAAO,EACnB,CAAC,CAAC,oBAAoB,CAAC,IAAI,aAAa,CACzC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC,IAAI,6BAA6B,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC,IAAI,2BAA2B,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAqB;IAClD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAE/D,qCAAqC;IACrC,OAAO,OAAO;SACX,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;SAC1B,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;SAC1B,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;SAC5B,IAAI,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,16 @@
1
+ export declare function executeCommand(command: string, timeout?: number): Promise<{
2
+ stdout: string;
3
+ stderr: string;
4
+ }>;
5
+ export declare function truncateString(str: string, maxLength: number): string;
6
+ export declare function formatFileSize(bytes: number): string;
7
+ export declare function formatDuration(ms: number): string;
8
+ export declare function pluralize(count: number, singular: string, plural?: string): string;
9
+ export declare function groupBy<T>(array: T[], keyFn: (item: T) => string): Record<string, T[]>;
10
+ export declare function sleep(ms: number): Promise<void>;
11
+ export declare function debounce<T extends (...args: unknown[]) => unknown>(fn: T, delay: number): (...args: Parameters<T>) => void;
12
+ export declare function getRelativePath(absolutePath: string, basePath: string): string;
13
+ export declare function isWindows(): boolean;
14
+ export declare function normalizeLineEndings(text: string): string;
15
+ export declare function extractFirstLine(text: string): string;
16
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"AAKA,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAc,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAc1H;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWpD;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAUjD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAKlF;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAStF;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,EAChE,EAAE,EAAE,CAAC,EACL,KAAK,EAAE,MAAM,GACZ,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAOlC;AAED,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ9E;AAED,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMrD"}
@@ -0,0 +1,95 @@
1
+ import { exec } from 'child_process';
2
+ import { promisify } from 'util';
3
+ const execAsync = promisify(exec);
4
+ export async function executeCommand(command, timeout = 30000) {
5
+ try {
6
+ const result = await execAsync(command, {
7
+ maxBuffer: 1024 * 1024 * 10, // 10MB buffer
8
+ timeout // Custom timeout (default 30s)
9
+ });
10
+ return result;
11
+ }
12
+ catch (error) {
13
+ if (error instanceof Error && 'stdout' in error && 'stderr' in error) {
14
+ const execError = error;
15
+ return { stdout: execError.stdout || '', stderr: execError.stderr || error.message };
16
+ }
17
+ throw error;
18
+ }
19
+ }
20
+ export function truncateString(str, maxLength) {
21
+ if (str.length <= maxLength) {
22
+ return str;
23
+ }
24
+ return str.substring(0, maxLength - 3) + '...';
25
+ }
26
+ export function formatFileSize(bytes) {
27
+ const units = ['B', 'KB', 'MB', 'GB'];
28
+ let unitIndex = 0;
29
+ let size = bytes;
30
+ while (size >= 1024 && unitIndex < units.length - 1) {
31
+ size /= 1024;
32
+ unitIndex++;
33
+ }
34
+ return `${size.toFixed(1)} ${units[unitIndex]}`;
35
+ }
36
+ export function formatDuration(ms) {
37
+ if (ms < 1000) {
38
+ return `${ms}ms`;
39
+ }
40
+ if (ms < 60000) {
41
+ return `${(ms / 1000).toFixed(1)}s`;
42
+ }
43
+ const minutes = Math.floor(ms / 60000);
44
+ const seconds = Math.floor((ms % 60000) / 1000);
45
+ return `${minutes}m ${seconds}s`;
46
+ }
47
+ export function pluralize(count, singular, plural) {
48
+ if (count === 1) {
49
+ return `${count} ${singular}`;
50
+ }
51
+ return `${count} ${plural || singular + 's'}`;
52
+ }
53
+ export function groupBy(array, keyFn) {
54
+ return array.reduce((result, item) => {
55
+ const key = keyFn(item);
56
+ if (!result[key]) {
57
+ result[key] = [];
58
+ }
59
+ result[key].push(item);
60
+ return result;
61
+ }, {});
62
+ }
63
+ export function sleep(ms) {
64
+ return new Promise(resolve => setTimeout(resolve, ms));
65
+ }
66
+ export function debounce(fn, delay) {
67
+ let timeoutId;
68
+ return (...args) => {
69
+ clearTimeout(timeoutId);
70
+ timeoutId = setTimeout(() => fn(...args), delay);
71
+ };
72
+ }
73
+ export function getRelativePath(absolutePath, basePath) {
74
+ if (absolutePath.startsWith(basePath)) {
75
+ const relative = absolutePath.substring(basePath.length);
76
+ return relative.startsWith('/') || relative.startsWith('\\')
77
+ ? relative.substring(1)
78
+ : relative;
79
+ }
80
+ return absolutePath;
81
+ }
82
+ export function isWindows() {
83
+ return process.platform === 'win32';
84
+ }
85
+ export function normalizeLineEndings(text) {
86
+ return text.replace(/\r\n/g, '\n');
87
+ }
88
+ export function extractFirstLine(text) {
89
+ const newlineIndex = text.indexOf('\n');
90
+ if (newlineIndex === -1) {
91
+ return text;
92
+ }
93
+ return text.substring(0, newlineIndex);
94
+ }
95
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './logger.js';
2
+ export * from './validators.js';
3
+ export * from './helpers.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './logger.js';
2
+ export * from './validators.js';
3
+ export * from './helpers.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC"}
@@ -0,0 +1,24 @@
1
+ export declare enum LogLevel {
2
+ DEBUG = 0,
3
+ INFO = 1,
4
+ WARN = 2,
5
+ ERROR = 3,
6
+ SILENT = 4
7
+ }
8
+ export declare function setLogLevel(level: LogLevel): void;
9
+ export declare function getLogLevel(): LogLevel;
10
+ export declare const logger: {
11
+ debug(message: string, ...args: unknown[]): void;
12
+ info(message: string, ...args: unknown[]): void;
13
+ success(message: string, ...args: unknown[]): void;
14
+ warn(message: string, ...args: unknown[]): void;
15
+ error(message: string, ...args: unknown[]): void;
16
+ raw(message: string): void;
17
+ /**
18
+ * Display a Git command for educational purposes
19
+ * Shows the command in dim gray with a > prefix
20
+ */
21
+ command(cmd: string): void;
22
+ };
23
+ export default logger;
24
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;IACT,MAAM,IAAI;CACX;AAID,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAEjD;AAED,wBAAgB,WAAW,IAAI,QAAQ,CAEtC;AAOD,eAAO,MAAM,MAAM;mBACF,MAAM,WAAW,OAAO,EAAE,GAAG,IAAI;kBAQlC,MAAM,WAAW,OAAO,EAAE,GAAG,IAAI;qBAQ9B,MAAM,WAAW,OAAO,EAAE,GAAG,IAAI;kBAQpC,MAAM,WAAW,OAAO,EAAE,GAAG,IAAI;mBAQhC,MAAM,WAAW,OAAO,EAAE,GAAG,IAAI;iBAQnC,MAAM,GAAG,IAAI;IAK1B;;;OAGG;iBACU,MAAM,GAAG,IAAI;CAI3B,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -0,0 +1,71 @@
1
+ import chalk from 'chalk';
2
+ export var LogLevel;
3
+ (function (LogLevel) {
4
+ LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
5
+ LogLevel[LogLevel["INFO"] = 1] = "INFO";
6
+ LogLevel[LogLevel["WARN"] = 2] = "WARN";
7
+ LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
8
+ LogLevel[LogLevel["SILENT"] = 4] = "SILENT";
9
+ })(LogLevel || (LogLevel = {}));
10
+ let currentLogLevel = LogLevel.INFO;
11
+ export function setLogLevel(level) {
12
+ currentLogLevel = level;
13
+ }
14
+ export function getLogLevel() {
15
+ return currentLogLevel;
16
+ }
17
+ function formatMessage(level, message) {
18
+ const timestamp = new Date().toISOString().substring(11, 19);
19
+ return `[${timestamp}] ${level} ${message}`;
20
+ }
21
+ export const logger = {
22
+ debug(message, ...args) {
23
+ if (currentLogLevel <= LogLevel.DEBUG) {
24
+ const formatted = formatMessage(chalk.gray('DEBUG'), message);
25
+ // eslint-disable-next-line no-console
26
+ console.log(formatted, ...args);
27
+ }
28
+ },
29
+ info(message, ...args) {
30
+ if (currentLogLevel <= LogLevel.INFO) {
31
+ const formatted = formatMessage(chalk.blue('INFO'), message);
32
+ // eslint-disable-next-line no-console
33
+ console.log(formatted, ...args);
34
+ }
35
+ },
36
+ success(message, ...args) {
37
+ if (currentLogLevel <= LogLevel.INFO) {
38
+ const formatted = formatMessage(chalk.green('SUCCESS'), message);
39
+ // eslint-disable-next-line no-console
40
+ console.log(formatted, ...args);
41
+ }
42
+ },
43
+ warn(message, ...args) {
44
+ if (currentLogLevel <= LogLevel.WARN) {
45
+ const formatted = formatMessage(chalk.yellow('WARN'), message);
46
+ // eslint-disable-next-line no-console
47
+ console.warn(formatted, ...args);
48
+ }
49
+ },
50
+ error(message, ...args) {
51
+ if (currentLogLevel <= LogLevel.ERROR) {
52
+ const formatted = formatMessage(chalk.red('ERROR'), message);
53
+ // eslint-disable-next-line no-console
54
+ console.error(formatted, ...args);
55
+ }
56
+ },
57
+ raw(message) {
58
+ // eslint-disable-next-line no-console
59
+ console.log(message);
60
+ },
61
+ /**
62
+ * Display a Git command for educational purposes
63
+ * Shows the command in dim gray with a > prefix
64
+ */
65
+ command(cmd) {
66
+ // eslint-disable-next-line no-console
67
+ console.log(chalk.dim(` > ${cmd}`));
68
+ }
69
+ };
70
+ export default logger;
71
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare function isValidBranchName(name: string): boolean;
2
+ export declare function isValidCommitMessage(message: string): boolean;
3
+ export declare function isConventionalCommit(message: string): boolean;
4
+ export declare function validateFilePath(filePath: string): {
5
+ valid: boolean;
6
+ error?: string;
7
+ };
8
+ export declare function isValidRemoteUrl(url: string): boolean;
9
+ export declare function sanitizeInput(input: string): string;
10
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"AAAA,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAgCvD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAiB7D;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAI7D;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAYrF;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAerD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGnD"}
@@ -0,0 +1,78 @@
1
+ export function isValidBranchName(name) {
2
+ if (!name || name.trim().length === 0) {
3
+ return false;
4
+ }
5
+ // Git branch naming rules
6
+ const invalidPatterns = [
7
+ /^\./, // Cannot start with a dot
8
+ /\.\.$/, // Cannot end with ..
9
+ /\.lock$/, // Cannot end with .lock
10
+ /^-/, // Cannot start with a dash
11
+ /\s/, // Cannot contain whitespace
12
+ /~/, // Cannot contain tilde
13
+ /\^/, // Cannot contain caret
14
+ /:/, // Cannot contain colon
15
+ /\?/, // Cannot contain question mark
16
+ /\*/, // Cannot contain asterisk
17
+ /\[/, // Cannot contain open bracket
18
+ /\\/, // Cannot contain backslash
19
+ /\/\//, // Cannot contain double slash
20
+ /\/$/, // Cannot end with slash
21
+ /^\//, // Cannot start with slash
22
+ /@\{/, // Cannot contain @{
23
+ ];
24
+ for (const pattern of invalidPatterns) {
25
+ if (pattern.test(name)) {
26
+ return false;
27
+ }
28
+ }
29
+ return true;
30
+ }
31
+ export function isValidCommitMessage(message) {
32
+ if (!message || message.trim().length === 0) {
33
+ return false;
34
+ }
35
+ // Minimum length check
36
+ if (message.trim().length < 3) {
37
+ return false;
38
+ }
39
+ // Maximum length for first line (conventional commits)
40
+ const firstLine = message.split('\n')[0];
41
+ if (firstLine.length > 100) {
42
+ return false;
43
+ }
44
+ return true;
45
+ }
46
+ export function isConventionalCommit(message) {
47
+ // Conventional commit format: type(scope)?: description
48
+ const conventionalPattern = /^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9-]+\))?!?:\s.+/i;
49
+ return conventionalPattern.test(message.split('\n')[0]);
50
+ }
51
+ export function validateFilePath(filePath) {
52
+ if (!filePath || filePath.trim().length === 0) {
53
+ return { valid: false, error: 'File path cannot be empty' };
54
+ }
55
+ // Check for invalid characters on Windows
56
+ const invalidChars = /[<>"|?*]/;
57
+ if (invalidChars.test(filePath)) {
58
+ return { valid: false, error: 'File path contains invalid characters' };
59
+ }
60
+ return { valid: true };
61
+ }
62
+ export function isValidRemoteUrl(url) {
63
+ if (!url || url.trim().length === 0) {
64
+ return false;
65
+ }
66
+ // HTTPS URL pattern
67
+ const httpsPattern = /^https:\/\/.+\/.+\.git$/;
68
+ // SSH URL pattern
69
+ const sshPattern = /^git@.+:.+\/.+\.git$/;
70
+ // Alternative SSH pattern
71
+ const sshAltPattern = /^ssh:\/\/.+\/.+\.git$/;
72
+ return httpsPattern.test(url) || sshPattern.test(url) || sshAltPattern.test(url);
73
+ }
74
+ export function sanitizeInput(input) {
75
+ // Remove potential shell injection characters
76
+ return input.replace(/[;&|`$(){}[\]<>\\]/g, '');
77
+ }
78
+ //# sourceMappingURL=validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "gitcoach-cli",
3
+ "version": "1.0.0",
4
+ "description": "AI-powered Git coach CLI that prevents mistakes before they happen",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "gitsense": "./bin/run.js"
9
+ },
10
+ "scripts": {
11
+ "dev": "tsc -w",
12
+ "build": "tsc && npm run copy-locales",
13
+ "copy-locales": "node -e \"const fs=require('fs');const path=require('path');const src='src/i18n/locales';const dest='dist/i18n/locales';fs.mkdirSync(dest,{recursive:true});fs.readdirSync(src).forEach(f=>fs.copyFileSync(path.join(src,f),path.join(dest,f)));\"",
14
+ "start": "node ./bin/run.js",
15
+ "test": "jest",
16
+ "test:coverage": "jest --coverage",
17
+ "lint": "eslint src --ext .ts",
18
+ "lint:fix": "eslint src --ext .ts --fix",
19
+ "format": "prettier --write \"src/**/*.ts\"",
20
+ "clean": "rimraf dist",
21
+ "prepublishOnly": "npm run build"
22
+ },
23
+ "keywords": [
24
+ "git",
25
+ "cli",
26
+ "copilot",
27
+ "ai",
28
+ "coach",
29
+ "helper",
30
+ "beginner",
31
+ "multilingual"
32
+ ],
33
+ "author": "",
34
+ "license": "MIT",
35
+ "oclif": {
36
+ "bin": "gitsense",
37
+ "dirname": "gitsense",
38
+ "commands": "./dist/commands",
39
+ "topicSeparator": " "
40
+ },
41
+ "files": [
42
+ "/bin",
43
+ "/dist"
44
+ ],
45
+ "dependencies": {
46
+ "@inquirer/prompts": "^7.2.1",
47
+ "@oclif/core": "^4.2.1",
48
+ "boxen": "^8.0.1",
49
+ "chalk": "^5.4.1",
50
+ "cli-table3": "^0.6.5",
51
+ "conf": "^13.1.0",
52
+ "i18next": "^24.2.2",
53
+ "ora": "^8.1.1",
54
+ "simple-git": "^3.27.0"
55
+ },
56
+ "devDependencies": {
57
+ "@types/jest": "^29.5.14",
58
+ "@types/node": "^22.10.7",
59
+ "@typescript-eslint/eslint-plugin": "^8.21.0",
60
+ "@typescript-eslint/parser": "^8.21.0",
61
+ "eslint": "^9.18.0",
62
+ "jest": "^29.7.0",
63
+ "prettier": "^3.4.2",
64
+ "rimraf": "^6.0.1",
65
+ "ts-jest": "^29.2.5",
66
+ "typescript": "^5.7.3"
67
+ },
68
+ "engines": {
69
+ "node": ">=18.0.0"
70
+ }
71
+ }