gitpt 1.6.1 → 1.7.2

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 (127) hide show
  1. package/README.md +34 -167
  2. package/dist/commands/commit/commitFlags.js +7 -0
  3. package/dist/commands/commit/context/buildPrompt.js +13 -10
  4. package/dist/commands/commit/context/summaryPrompt.js +5 -2
  5. package/dist/commands/commit/context/systemPrompt.js +4 -1
  6. package/dist/commands/commit/context/userPrompt.js +4 -1
  7. package/dist/commands/commit/generateCommitMessage.js +14 -17
  8. package/dist/commands/commit/index.js +186 -179
  9. package/dist/commands/commit/summarizeDiff.js +183 -162
  10. package/dist/commands/config.js +24 -9
  11. package/dist/commands/hook/index.js +68 -0
  12. package/dist/commands/middleware/capabilitiesMiddleware/ghCapability.js +20 -20
  13. package/dist/commands/middleware/capabilitiesMiddleware/gitCapability.js +13 -10
  14. package/dist/commands/middleware/capabilitiesMiddleware/index.js +12 -11
  15. package/dist/commands/middleware/hasStagedChangesMiddleware.js +9 -6
  16. package/dist/commands/middleware/setupMiddleware/defaultModels.js +14 -10
  17. package/dist/commands/middleware/setupMiddleware/index.js +65 -71
  18. package/dist/commands/model.js +7 -4
  19. package/dist/commands/passthroughArgs.js +11 -0
  20. package/dist/commands/pr/context/systemPrompt.js +4 -1
  21. package/dist/commands/pr/context/userPrompt.js +4 -1
  22. package/dist/commands/pr/generatePRDetails.js +24 -23
  23. package/dist/commands/pr/getPRContext.js +37 -62
  24. package/dist/commands/pr/index.js +57 -62
  25. package/dist/commands/reset.js +23 -23
  26. package/dist/commands/review/index.js +31 -0
  27. package/dist/commands/setup.js +38 -13
  28. package/dist/config.js +63 -60
  29. package/dist/index.js +30 -67
  30. package/dist/llm/budget.js +10 -0
  31. package/dist/llm/index.js +12 -7
  32. package/dist/llm/providers/anthropic/index.js +30 -30
  33. package/dist/llm/providers/apiKey.js +36 -35
  34. package/dist/llm/providers/apple/client.js +73 -83
  35. package/dist/llm/providers/apple/index.js +64 -72
  36. package/dist/llm/providers/apple/models.js +27 -19
  37. package/dist/llm/providers/base.js +36 -36
  38. package/dist/llm/providers/local/index.js +79 -91
  39. package/dist/llm/providers/openai/index.js +19 -16
  40. package/dist/llm/providers/openaiCompatible.js +59 -62
  41. package/dist/llm/providers/openrouter/index.js +18 -15
  42. package/dist/llm/registry.js +30 -34
  43. package/dist/llm/setup/getAvailableModels.js +15 -9
  44. package/dist/llm/setup/selectModel.js +36 -44
  45. package/dist/llm/tokenCount.js +4 -3
  46. package/dist/package.js +67 -0
  47. package/dist/services/gh/createPullRequest.js +38 -58
  48. package/dist/services/gh/index.js +6 -3
  49. package/dist/services/gh/isAvailable.js +10 -8
  50. package/dist/services/git/executeGitAdd.js +11 -12
  51. package/dist/services/git/executeGitCommit.js +10 -11
  52. package/dist/services/git/getAmendChanges.js +23 -0
  53. package/dist/services/git/getChangedFiles.js +28 -61
  54. package/dist/services/git/getCommitsSinceBaseBranch.js +28 -56
  55. package/dist/services/git/getCurrentBranch.js +10 -8
  56. package/dist/services/git/getDefaultBranch.js +35 -60
  57. package/dist/services/git/getStagedChanges.js +10 -8
  58. package/dist/services/git/getStagedFiles.js +10 -9
  59. package/dist/services/git/hasStagedChanges.js +9 -8
  60. package/dist/services/git/index.js +17 -12
  61. package/dist/services/git/isAvailable.js +10 -8
  62. package/dist/services/git/isGitRepository.js +10 -8
  63. package/dist/utils/commitlint.js +97 -135
  64. package/dist/utils/formatBaseURL.js +7 -6
  65. package/dist/utils/maskApiKey.js +6 -7
  66. package/package.json +14 -4
  67. package/dist/commands/commit/context/buildPrompt.d.ts +0 -4
  68. package/dist/commands/commit/context/summaryPrompt.d.ts +0 -2
  69. package/dist/commands/commit/context/systemPrompt.d.ts +0 -1
  70. package/dist/commands/commit/context/userPrompt.d.ts +0 -1
  71. package/dist/commands/commit/generateCommitMessage.d.ts +0 -1
  72. package/dist/commands/commit/index.d.ts +0 -7
  73. package/dist/commands/commit/summarizeDiff.d.ts +0 -1
  74. package/dist/commands/config.d.ts +0 -1
  75. package/dist/commands/middleware/capabilitiesMiddleware/ghCapability.d.ts +0 -1
  76. package/dist/commands/middleware/capabilitiesMiddleware/gitCapability.d.ts +0 -1
  77. package/dist/commands/middleware/capabilitiesMiddleware/index.d.ts +0 -3
  78. package/dist/commands/middleware/hasStagedChangesMiddleware.d.ts +0 -1
  79. package/dist/commands/middleware/setupMiddleware/defaultModels.d.ts +0 -8
  80. package/dist/commands/middleware/setupMiddleware/index.d.ts +0 -4
  81. package/dist/commands/model.d.ts +0 -1
  82. package/dist/commands/pr/context/systemPrompt.d.ts +0 -1
  83. package/dist/commands/pr/context/userPrompt.d.ts +0 -1
  84. package/dist/commands/pr/generatePRDetails.d.ts +0 -4
  85. package/dist/commands/pr/getPRContext.d.ts +0 -1
  86. package/dist/commands/pr/index.d.ts +0 -10
  87. package/dist/commands/reset.d.ts +0 -3
  88. package/dist/commands/setup.d.ts +0 -3
  89. package/dist/config.d.ts +0 -14
  90. package/dist/index.d.ts +0 -2
  91. package/dist/llm/client.d.ts +0 -24
  92. package/dist/llm/client.js +0 -1
  93. package/dist/llm/index.d.ts +0 -6
  94. package/dist/llm/providers/anthropic/index.d.ts +0 -9
  95. package/dist/llm/providers/apiKey.d.ts +0 -3
  96. package/dist/llm/providers/apple/client.d.ts +0 -3
  97. package/dist/llm/providers/apple/index.d.ts +0 -13
  98. package/dist/llm/providers/apple/models.d.ts +0 -14
  99. package/dist/llm/providers/base.d.ts +0 -30
  100. package/dist/llm/providers/local/index.d.ts +0 -11
  101. package/dist/llm/providers/openai/index.d.ts +0 -10
  102. package/dist/llm/providers/openaiCompatible.d.ts +0 -15
  103. package/dist/llm/providers/openrouter/index.d.ts +0 -9
  104. package/dist/llm/registry.d.ts +0 -8
  105. package/dist/llm/setup/getAvailableModels.d.ts +0 -5
  106. package/dist/llm/setup/selectModel.d.ts +0 -5
  107. package/dist/llm/setup/types.d.ts +0 -13
  108. package/dist/llm/setup/types.js +0 -1
  109. package/dist/llm/tokenCount.d.ts +0 -3
  110. package/dist/services/gh/createPullRequest.d.ts +0 -1
  111. package/dist/services/gh/index.d.ts +0 -4
  112. package/dist/services/gh/isAvailable.d.ts +0 -1
  113. package/dist/services/git/executeGitAdd.d.ts +0 -1
  114. package/dist/services/git/executeGitCommit.d.ts +0 -1
  115. package/dist/services/git/getChangedFiles.d.ts +0 -1
  116. package/dist/services/git/getCommitsSinceBaseBranch.d.ts +0 -1
  117. package/dist/services/git/getCurrentBranch.d.ts +0 -1
  118. package/dist/services/git/getDefaultBranch.d.ts +0 -1
  119. package/dist/services/git/getStagedChanges.d.ts +0 -1
  120. package/dist/services/git/getStagedFiles.d.ts +0 -1
  121. package/dist/services/git/hasStagedChanges.d.ts +0 -1
  122. package/dist/services/git/index.d.ts +0 -13
  123. package/dist/services/git/isAvailable.d.ts +0 -1
  124. package/dist/services/git/isGitRepository.d.ts +0 -1
  125. package/dist/utils/commitlint.d.ts +0 -25
  126. package/dist/utils/formatBaseURL.d.ts +0 -1
  127. package/dist/utils/maskApiKey.d.ts +0 -1
@@ -1,185 +1,192 @@
1
- import chalk from "chalk";
2
- import inquirer from "inquirer";
1
+ import { git } from "../../services/git/index.js";
3
2
  import { capabilitiesMiddleware } from "../middleware/capabilitiesMiddleware/index.js";
3
+ import { isDebug } from "../../config.js";
4
4
  import { setupMiddleware } from "../middleware/setupMiddleware/index.js";
5
- import { git } from "../../services/git/index.js";
6
- import { hasCommitlintConfig, validateCommitMessage, } from "../../utils/commitlint.js";
5
+ import { hasCommitlintConfig, validateCommitMessage } from "../../utils/commitlint.js";
7
6
  import { hasStagedChangesMiddleware } from "../middleware/hasStagedChangesMiddleware.js";
8
7
  import { generateCommitMessage } from "./generateCommitMessage.js";
9
8
  import { prepareCommitContext } from "./summarizeDiff.js";
10
- export const commitCommand = async (options) => {
11
- capabilitiesMiddleware(["git"]);
12
- await setupMiddleware();
13
- hasStagedChangesMiddleware();
14
- let commitMessage;
15
- // If message is provided, use that
16
- if (options.message) {
17
- commitMessage = options.message;
18
- }
19
- else {
20
- try {
21
- // Get staged changes
22
- const diff = git.getStagedChanges();
23
- const context = await prepareCommitContext(diff);
24
- console.log(chalk.blue("Generating commit message..."));
25
- // Check if commitlint is configured
26
- let hasCommitlint = false;
27
- try {
28
- hasCommitlint = hasCommitlintConfig();
29
- if (hasCommitlint) {
30
- console.log(chalk.blue("Commitlint configuration detected. Generating message according to rules..."));
31
- }
32
- }
33
- catch (error) {
34
- console.warn(chalk.yellow("Warning: Error detecting commitlint config, proceeding without commitlint validation."));
35
- }
36
- // Generate first commit message
37
- commitMessage = await generateCommitMessage(context);
38
- // If commitlint is configured, try to validate and regenerate up to 3 times
39
- if (hasCommitlint) {
40
- try {
41
- console.log(chalk.blue("Validating commit message against commitlint rules..."));
42
- // Try up to 3 times to get a valid message
43
- let validMessage = false;
44
- let attempts = 0;
45
- const MAX_ATTEMPTS = 3;
46
- let validationErrors;
47
- while (!validMessage && attempts < MAX_ATTEMPTS) {
48
- const validation = await validateCommitMessage(commitMessage);
49
- if (validation.valid) {
50
- console.log(chalk.green("✓ Commit message passed validation"));
51
- validMessage = true;
52
- break;
53
- }
54
- else {
55
- attempts++;
56
- console.log(chalk.yellow(`Commit message failed validation. ${attempts < MAX_ATTEMPTS
57
- ? "Regenerating..."
58
- : "Max attempts reached."}`));
59
- if (validation.errors) {
60
- console.log(chalk.gray(validation.errors));
61
- validationErrors = validation.errors;
62
- }
63
- if (attempts < MAX_ATTEMPTS) {
64
- // Try regenerating with validation errors
65
- try {
66
- commitMessage = await generateCommitMessage(context, validationErrors);
67
- }
68
- catch (error) {
69
- console.warn(chalk.yellow("Error regenerating message, breaking validation loop."));
70
- break;
71
- }
72
- }
73
- else {
74
- // Ask user what to do after max attempts
75
- const { action } = await inquirer.prompt([
76
- {
77
- type: "list",
78
- name: "action",
79
- message: "Failed to generate a valid commit message after 3 attempts. What would you like to do?",
80
- choices: [
81
- {
82
- name: "Proceed with invalid message",
83
- value: "proceed",
84
- },
85
- { name: "Edit message manually", value: "edit" },
86
- { name: "Abort commit", value: "abort" },
87
- ],
88
- },
89
- ]);
90
- if (action === "abort") {
91
- console.log(chalk.red("Commit aborted due to validation failures."));
92
- process.exit(1);
93
- }
94
- else if (action === "edit") {
95
- options.edit = true; // Force editor to open
96
- }
97
- else {
98
- console.log(chalk.yellow("Proceeding with invalid message..."));
99
- }
100
- break;
101
- }
102
- }
103
- }
104
- }
105
- catch (error) {
106
- // If there's an error with commitlint validation, continue without it
107
- console.warn(chalk.yellow("Warning: Error during commitlint validation, proceeding without validation."));
108
- console.warn(chalk.gray("This may be due to an ESM module cycle conflict or missing commitlint dependencies."));
109
- }
110
- }
111
- console.log(chalk.green("✓ Commit message generated"));
112
- console.log("");
113
- console.log(chalk.cyan("Generated message:"));
114
- console.log(commitMessage);
115
- console.log("");
116
- }
117
- catch (error) {
118
- console.error(chalk.red("Error:"), error instanceof Error ? error.message : String(error));
119
- process.exit(1);
120
- }
121
- }
122
- // If edit is true or not specified, prompt user to edit the message
123
- if (options.edit !== false) {
124
- const answer = await inquirer.prompt([
125
- {
126
- type: "editor",
127
- name: "message",
128
- message: "Edit commit message:",
129
- default: commitMessage,
130
- },
131
- ]);
132
- commitMessage = answer.message;
133
- // Validate the edited message once
134
- try {
135
- const hasCommitlint = hasCommitlintConfig();
136
- if (hasCommitlint) {
137
- console.log(chalk.blue("Validating edited commit message..."));
138
- const validation = await validateCommitMessage(commitMessage);
139
- if (!validation.valid) {
140
- console.log(chalk.yellow("Warning: Edited message still has validation issues."));
141
- if (validation.errors) {
142
- console.log(chalk.gray(validation.errors));
143
- }
144
- // Ask if user wants to proceed anyway
145
- const { proceed } = await inquirer.prompt([
146
- {
147
- type: "confirm",
148
- name: "proceed",
149
- message: "Proceed with invalid commit message?",
150
- default: false,
151
- },
152
- ]);
153
- if (!proceed) {
154
- console.log(chalk.red("Commit aborted by user."));
155
- process.exit(1);
156
- }
157
- }
158
- else {
159
- console.log(chalk.green("✓ Edited message passed validation"));
160
- }
161
- }
162
- }
163
- catch (error) {
164
- // If validation fails, just warn and continue
165
- console.warn(chalk.yellow("Could not validate edited message, proceeding anyway."));
166
- }
167
- }
168
- // Extract other git options to pass through
169
- const gitOptions = Object.keys(options)
170
- .filter((key) => !["message", "edit"].includes(key))
171
- .map((key) => {
172
- if (typeof options[key] === "boolean") {
173
- return options[key] ? `--${key}` : `--no-${key}`;
174
- }
175
- return `--${key}=${options[key]}`;
176
- });
177
- try {
178
- git.commit(commitMessage, gitOptions);
179
- console.log(chalk.green("✓ Changes committed successfully"));
180
- }
181
- catch (error) {
182
- console.error(chalk.red("Error:"), error instanceof Error ? error.message : String(error));
183
- process.exit(1);
184
- }
9
+ import { isAmend, skipsStagedGuard } from "./commitFlags.js";
10
+ import { passthroughArgs } from "../passthroughArgs.js";
11
+ import chalk from "chalk";
12
+ import inquirer from "inquirer";
13
+ //#region src/commands/commit/index.ts
14
+ var commitCommand = async (options, command) => {
15
+ if (options.debug) ({}).GITPT_DEBUG = "1";
16
+ capabilitiesMiddleware(["git"]);
17
+ await setupMiddleware();
18
+ const passthrough = passthroughArgs(command);
19
+ const amend = isAmend(passthrough);
20
+ const noEdit = options.edit === false;
21
+ if (!skipsStagedGuard(passthrough)) hasStagedChangesMiddleware();
22
+ if (amend && noEdit && !options.message) {
23
+ if (options.dryRun) {
24
+ console.log(chalk.yellow("[dry-run] Would amend the last commit (keeping its message). Nothing changed."));
25
+ return;
26
+ }
27
+ try {
28
+ git.commit(null, [...passthrough, "--no-edit"]);
29
+ console.log(chalk.green(" Amended (kept the original message)."));
30
+ } catch (error) {
31
+ console.error(chalk.red("Error:"), error instanceof Error ? error.message : String(error));
32
+ process.exit(1);
33
+ }
34
+ return;
35
+ }
36
+ let commitMessage;
37
+ let context;
38
+ if (options.message) commitMessage = options.message;
39
+ else try {
40
+ const diff = amend ? git.getAmendChanges() : git.getStagedChanges();
41
+ if (!diff.trim()) {
42
+ console.error(chalk.red("Error: nothing to summarise. Provide a message with -m \"...\"."));
43
+ process.exit(1);
44
+ }
45
+ context = await prepareCommitContext(diff);
46
+ console.log(chalk.blue("Generating commit message..."));
47
+ let hasCommitlint = false;
48
+ try {
49
+ hasCommitlint = hasCommitlintConfig();
50
+ if (hasCommitlint) console.log(chalk.blue("Commitlint configuration detected. Generating message according to rules..."));
51
+ } catch (error) {
52
+ console.warn(chalk.yellow("Warning: Error detecting commitlint config, proceeding without commitlint validation."));
53
+ }
54
+ const startedAt = Date.now();
55
+ commitMessage = await generateCommitMessage(context);
56
+ if (isDebug()) console.log(chalk.gray(`⚙ debug · ~${Math.ceil(context.length / 3)} context tokens · generated in ${Date.now() - startedAt}ms`));
57
+ if (hasCommitlint) try {
58
+ console.log(chalk.blue("Validating commit message against commitlint rules..."));
59
+ let validMessage = false;
60
+ let attempts = 0;
61
+ const MAX_ATTEMPTS = 3;
62
+ let validationErrors;
63
+ while (!validMessage && attempts < MAX_ATTEMPTS) {
64
+ const validation = await validateCommitMessage(commitMessage);
65
+ if (validation.valid) {
66
+ console.log(chalk.green("✓ Commit message passed validation"));
67
+ validMessage = true;
68
+ break;
69
+ } else {
70
+ attempts++;
71
+ console.log(chalk.yellow(`Commit message failed validation. ${attempts < MAX_ATTEMPTS ? "Regenerating..." : "Max attempts reached."}`));
72
+ if (validation.errors) {
73
+ console.log(chalk.gray(validation.errors));
74
+ validationErrors = validation.errors;
75
+ }
76
+ if (attempts < MAX_ATTEMPTS) try {
77
+ commitMessage = await generateCommitMessage(context, validationErrors);
78
+ } catch (error) {
79
+ console.warn(chalk.yellow("Error regenerating message, breaking validation loop."));
80
+ break;
81
+ }
82
+ else {
83
+ const { action } = await inquirer.prompt([{
84
+ type: "list",
85
+ name: "action",
86
+ message: "Failed to generate a valid commit message after 3 attempts. What would you like to do?",
87
+ choices: [
88
+ {
89
+ name: "Proceed with invalid message",
90
+ value: "proceed"
91
+ },
92
+ {
93
+ name: "Edit message manually",
94
+ value: "edit"
95
+ },
96
+ {
97
+ name: "Abort commit",
98
+ value: "abort"
99
+ }
100
+ ]
101
+ }]);
102
+ if (action === "abort") {
103
+ console.log(chalk.red("Commit aborted due to validation failures."));
104
+ process.exit(1);
105
+ } else if (action === "edit") options.edit = true;
106
+ else console.log(chalk.yellow("Proceeding with invalid message..."));
107
+ break;
108
+ }
109
+ }
110
+ }
111
+ } catch (error) {
112
+ console.warn(chalk.yellow("Warning: Error during commitlint validation, proceeding without validation."));
113
+ console.warn(chalk.gray("This may be due to an ESM module cycle conflict or missing commitlint dependencies."));
114
+ }
115
+ console.log(chalk.green("✓ Commit message generated"));
116
+ console.log("");
117
+ console.log(chalk.cyan("Generated message:"));
118
+ console.log(commitMessage);
119
+ console.log("");
120
+ } catch (error) {
121
+ console.error(chalk.red("Error:"), error instanceof Error ? error.message : String(error));
122
+ process.exit(1);
123
+ }
124
+ if (options.dryRun) return;
125
+ if (options.edit !== false && !options.message && context !== void 0) {
126
+ let confirmed = false;
127
+ while (!confirmed) {
128
+ const { action } = await inquirer.prompt([{
129
+ type: "list",
130
+ name: "action",
131
+ message: "Use this commit message?",
132
+ choices: [
133
+ {
134
+ name: "Confirm and commit",
135
+ value: "confirm"
136
+ },
137
+ {
138
+ name: "Generate another (different wording)",
139
+ value: "another"
140
+ },
141
+ {
142
+ name: "Edit manually",
143
+ value: "edit"
144
+ },
145
+ {
146
+ name: "Cancel",
147
+ value: "cancel"
148
+ }
149
+ ]
150
+ }]);
151
+ if (action === "confirm") confirmed = true;
152
+ else if (action === "another") {
153
+ commitMessage = (await generateCommitMessage(`${context}\n\nWrite a noticeably different commit message — a fresh wording or angle, not the same as before.`)).trim();
154
+ console.log("");
155
+ console.log(chalk.cyan("Generated message:"));
156
+ console.log(commitMessage);
157
+ console.log("");
158
+ } else if (action === "edit") {
159
+ commitMessage = (await inquirer.prompt([{
160
+ type: "editor",
161
+ name: "message",
162
+ message: "Edit commit message:",
163
+ default: commitMessage
164
+ }])).message;
165
+ confirmed = true;
166
+ } else {
167
+ console.log(chalk.gray("Commit cancelled."));
168
+ process.exit(0);
169
+ }
170
+ }
171
+ try {
172
+ if (hasCommitlintConfig()) {
173
+ const validation = await validateCommitMessage(commitMessage);
174
+ if (!validation.valid) {
175
+ console.log(chalk.yellow("Warning: Edited message still has validation issues."));
176
+ if (validation.errors) console.log(chalk.gray(validation.errors));
177
+ }
178
+ }
179
+ } catch (error) {
180
+ console.warn(chalk.yellow("Could not validate edited message, proceeding anyway."));
181
+ }
182
+ }
183
+ try {
184
+ git.commit(commitMessage, passthrough);
185
+ console.log(chalk.green("✓ Changes committed successfully"));
186
+ } catch (error) {
187
+ console.error(chalk.red("Error:"), error instanceof Error ? error.message : String(error));
188
+ process.exit(1);
189
+ }
185
190
  };
191
+ //#endregion
192
+ export { commitCommand };