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,43 +1,39 @@
1
1
  import { getConfig } from "../config.js";
2
- import { AnthropicProvider } from "./providers/anthropic/index.js";
3
2
  import { getApiKey } from "./providers/apiKey.js";
3
+ import { AnthropicProvider } from "./providers/anthropic/index.js";
4
4
  import { AppleProvider } from "./providers/apple/index.js";
5
5
  import { LocalProvider } from "./providers/local/index.js";
6
6
  import { OpenAIProvider } from "./providers/openai/index.js";
7
7
  import { OpenRouterProvider } from "./providers/openrouter/index.js";
8
- export const PROVIDERS = [
9
- AppleProvider,
10
- OpenRouterProvider,
11
- OpenAIProvider,
12
- AnthropicProvider,
13
- LocalProvider,
8
+ //#region src/llm/registry.ts
9
+ var PROVIDERS = [
10
+ AppleProvider,
11
+ OpenRouterProvider,
12
+ OpenAIProvider,
13
+ AnthropicProvider,
14
+ LocalProvider
14
15
  ];
15
- export const getProviderClass = (id) => PROVIDERS.find((p) => p.id === id);
16
- export const getProvider = () => {
17
- const { provider, model } = getConfig();
18
- const ProviderImpl = getProviderClass(provider);
19
- if (!ProviderImpl) {
20
- throw new Error(`Unknown provider: ${provider ?? "(none)"}. Run "gitpt setup".`);
21
- }
22
- return new ProviderImpl(model ?? "");
16
+ var getProviderClass = (id) => PROVIDERS.find((p) => p.id === id);
17
+ var getProvider = () => {
18
+ const { provider, model } = getConfig();
19
+ const ProviderImpl = getProviderClass(provider);
20
+ if (!ProviderImpl) throw new Error(`Unknown provider: ${provider ?? "(none)"}. Run "gitpt setup".`);
21
+ return new ProviderImpl(model ?? "");
23
22
  };
24
- export const validateConfig = () => {
25
- const { provider, customLLMEndpoint, model } = getConfig();
26
- const errors = [];
27
- const spec = getProviderClass(provider);
28
- if (!spec) {
29
- errors.push("No provider configured. Run 'gitpt setup'.");
30
- }
31
- else {
32
- if (spec.requiresApiKey && !getApiKey()) {
33
- errors.push(`API key is required for ${spec.label}.`);
34
- }
35
- if (spec.requiresEndpoint && !customLLMEndpoint) {
36
- errors.push(`Custom endpoint is required for ${spec.label}.`);
37
- }
38
- }
39
- if (!model) {
40
- errors.push("Model is required.");
41
- }
42
- return { isValid: errors.length === 0, errors };
23
+ var validateConfig = () => {
24
+ const { provider, customLLMEndpoint, model } = getConfig();
25
+ const errors = [];
26
+ const spec = getProviderClass(provider);
27
+ if (!spec) errors.push("No provider configured. Run 'gitpt setup'.");
28
+ else {
29
+ if (spec.requiresApiKey && !getApiKey()) errors.push(`API key is required for ${spec.label}.`);
30
+ if (spec.requiresEndpoint && !customLLMEndpoint) errors.push(`Custom endpoint is required for ${spec.label}.`);
31
+ }
32
+ if (!model) errors.push("Model is required.");
33
+ return {
34
+ isValid: errors.length === 0,
35
+ errors
36
+ };
43
37
  };
38
+ //#endregion
39
+ export { PROVIDERS, getProvider, getProviderClass, validateConfig };
@@ -1,11 +1,17 @@
1
1
  import { getLLMClient } from "../index.js";
2
- export const getAvailableModels = async (options) => {
3
- const { baseURLOverride, apiKey } = options || {};
4
- let modelsList = await getLLMClient({ baseURLOverride, apiKey }).models.list();
5
- const modelsData = modelsList.data;
6
- while (modelsList.hasNextPage()) {
7
- modelsList = await modelsList.getNextPage();
8
- modelsData.push(...modelsList.data);
9
- }
10
- return modelsData;
2
+ //#region src/llm/setup/getAvailableModels.ts
3
+ var getAvailableModels = async (options) => {
4
+ const { baseURLOverride, apiKey } = options || {};
5
+ let modelsList = await getLLMClient({
6
+ baseURLOverride,
7
+ apiKey
8
+ }).models.list();
9
+ const modelsData = modelsList.data;
10
+ while (modelsList.hasNextPage()) {
11
+ modelsList = await modelsList.getNextPage();
12
+ modelsData.push(...modelsList.data);
13
+ }
14
+ return modelsData;
11
15
  };
16
+ //#endregion
17
+ export { getAvailableModels };
@@ -1,48 +1,40 @@
1
1
  import chalk from "chalk";
2
2
  import inquirer from "inquirer";
3
+ //#region src/llm/setup/selectModel.ts
3
4
  /**
4
- * Show a list of models to select from
5
- */
6
- export const selectModel = async (models, existingModel, notes) => {
7
- const modelChoices = models.map((model) => ({
8
- name: model.name
9
- ? model.context_length
10
- ? `${model.name} (Context: ${model.context_length})`
11
- : model.name
12
- : model.id,
13
- value: model.id,
14
- }));
15
- modelChoices.push({
16
- name: "Other (specify model identifier)",
17
- value: "custom",
18
- });
19
- const choices = [...modelChoices];
20
- if (notes && notes.length > 0) {
21
- choices.push(new inquirer.Separator(" "));
22
- for (const note of notes) {
23
- choices.push(new inquirer.Separator(chalk.gray(note)));
24
- }
25
- }
26
- const answers = await inquirer.prompt([
27
- {
28
- type: "list",
29
- name: "modelChoice",
30
- message: "Select an AI model:",
31
- choices,
32
- default: () => {
33
- const currentIndex = modelChoices.findIndex((choice) => choice.value === existingModel);
34
- return currentIndex >= 0 ? currentIndex : 0;
35
- },
36
- },
37
- {
38
- type: "input",
39
- name: "customModel",
40
- message: "Enter model identifier:",
41
- when: (answers) => answers.modelChoice === "custom",
42
- validate: (input) => input ? true : "Model identifier is required",
43
- },
44
- ]);
45
- return answers.modelChoice === "custom"
46
- ? answers.customModel
47
- : answers.modelChoice;
5
+ * Show a list of models to select from
6
+ */
7
+ var selectModel = async (models, existingModel, notes) => {
8
+ const modelChoices = models.map((model) => ({
9
+ name: model.name ? model.context_length ? `${model.name} (Context: ${model.context_length})` : model.name : model.id,
10
+ value: model.id
11
+ }));
12
+ modelChoices.push({
13
+ name: "Other (specify model identifier)",
14
+ value: "custom"
15
+ });
16
+ const choices = [...modelChoices];
17
+ if (notes && notes.length > 0) {
18
+ choices.push(new inquirer.Separator(" "));
19
+ for (const note of notes) choices.push(new inquirer.Separator(chalk.gray(note)));
20
+ }
21
+ const answers = await inquirer.prompt([{
22
+ type: "list",
23
+ name: "modelChoice",
24
+ message: "Select an AI model:",
25
+ choices,
26
+ default: () => {
27
+ const currentIndex = modelChoices.findIndex((choice) => choice.value === existingModel);
28
+ return currentIndex >= 0 ? currentIndex : 0;
29
+ }
30
+ }, {
31
+ type: "input",
32
+ name: "customModel",
33
+ message: "Enter model identifier:",
34
+ when: (answers) => answers.modelChoice === "custom",
35
+ validate: (input) => input ? true : "Model identifier is required"
36
+ }]);
37
+ return answers.modelChoice === "custom" ? answers.customModel : answers.modelChoice;
48
38
  };
39
+ //#endregion
40
+ export { selectModel };
@@ -1,4 +1,5 @@
1
1
  import { getProvider } from "./registry.js";
2
- export const RESERVED_OUTPUT_TOKENS = 1024;
3
- export const countTokens = (text) => getProvider().countTokens(text);
4
- export const getContextWindow = () => getProvider().getContextWindow();
2
+ //#region src/llm/tokenCount.ts
3
+ var countTokens = (text) => getProvider().countTokens(text);
4
+ //#endregion
5
+ export { countTokens };
@@ -0,0 +1,67 @@
1
+ var package_default = {
2
+ name: "gitpt",
3
+ version: "1.7.2",
4
+ description: "CLI tool that helps you write commit messages & pull request descriptions using AI",
5
+ main: "dist/index.js",
6
+ type: "module",
7
+ bin: { "gitpt": "dist/index.js" },
8
+ files: [
9
+ "dist/**/*",
10
+ "README.md",
11
+ "LICENSE"
12
+ ],
13
+ scripts: {
14
+ "typecheck": "tsc --noEmit",
15
+ "lint": "oxlint",
16
+ "build": "vite build",
17
+ "test": "vitest run",
18
+ "test:watch": "vitest",
19
+ "test:apple": "npm run build && node tests/apple-foundation-models/run.mjs",
20
+ "bench:apple": "npm run build && node tests/apple-foundation-models/benchmark.mjs",
21
+ "bench:local": "npm run build && node tests/local-model/run.mjs",
22
+ "bench:all": "npm run build && node tests/run-all.mjs",
23
+ "check:prompt": "npm run build && node tests/snapshots/check.mjs",
24
+ "build:demo": "node scripts/build-demo.mjs",
25
+ "prepublishOnly": "npm run build"
26
+ },
27
+ repository: {
28
+ "type": "git",
29
+ "url": "git+https://github.com/bartaxyz/GitPT.git"
30
+ },
31
+ keywords: [
32
+ "git",
33
+ "ai",
34
+ "prompt"
35
+ ],
36
+ author: "@bartaxyz",
37
+ license: "MIT",
38
+ bugs: { "url": "https://github.com/bartaxyz/GitPT/issues" },
39
+ homepage: "https://github.com/bartaxyz/GitPT#readme",
40
+ devDependencies: {
41
+ "@types/configstore": "^6.0.2",
42
+ "@types/inquirer": "^9.0.7",
43
+ "@types/node": "^22.14.1",
44
+ "@types/node-fetch": "^2.6.12",
45
+ "ffmpeg-static": "^5.3.0",
46
+ "oxlint": "^1.71.0",
47
+ "pngjs": "^7.0.0",
48
+ "tsc-alias": "^1.8.16",
49
+ "typescript": "^5.8.3",
50
+ "vite": "^8.1.0",
51
+ "vitest": "^4.1.9"
52
+ },
53
+ dependencies: {
54
+ "@commitlint/cli": "^19.8.1",
55
+ "@commitlint/config-conventional": "^19.8.1",
56
+ "@commitlint/load": "^19.8.1",
57
+ "chalk": "^5.4.1",
58
+ "commander": "^13.1.0",
59
+ "configstore": "^7.0.0",
60
+ "inquirer": "^12.5.2",
61
+ "node-fetch": "^3.3.2",
62
+ "openai": "^4.100.0",
63
+ "ora": "^8.2.0"
64
+ }
65
+ };
66
+ //#endregion
67
+ export { package_default as default };
@@ -1,63 +1,43 @@
1
1
  import chalk from "chalk";
2
2
  import { execSync } from "child_process";
3
- export const createPullRequest = (title, body, baseBranch, draft) => {
4
- const draftFlag = draft ? "--draft" : "";
5
- try {
6
- console.log(chalk.blue(`Creating pull request to ${baseBranch}...`));
7
- // Create a temporary file for the PR body to avoid issues with escaping
8
- const tempFilePath = `/tmp/gitpt-pr-body-${Date.now()}.md`;
9
- try {
10
- // Write the body to a temporary file
11
- execSync(`cat > "${tempFilePath}" << 'GITPT_EOF'
3
+ //#region src/services/gh/createPullRequest.ts
4
+ var createPullRequest = (title, body, baseBranch, draft) => {
5
+ const draftFlag = draft ? "--draft" : "";
6
+ try {
7
+ console.log(chalk.blue(`Creating pull request to ${baseBranch}...`));
8
+ const tempFilePath = `/tmp/gitpt-pr-body-${Date.now()}.md`;
9
+ try {
10
+ execSync(`cat > "${tempFilePath}" << 'GITPT_EOF'
12
11
  ${body}
13
12
  GITPT_EOF`);
14
- // Try to get the remote repo URL if available
15
- let repoUrlArg = "";
16
- try {
17
- const repoUrl = execSync("git config --get remote.origin.url")
18
- .toString()
19
- .trim();
20
- if (repoUrl) {
21
- repoUrlArg = `--repo "${repoUrl}"`;
22
- }
23
- }
24
- catch (e) {
25
- // Proceed without repo URL
26
- }
27
- // Use the file for the body
28
- const command = `gh pr create --title "${title.replace(/"/g, '\\"')}" --body-file "${tempFilePath}" --base "${baseBranch}" ${draftFlag} ${repoUrlArg}`;
29
- // Set a timeout to avoid hanging indefinitely
30
- console.log(chalk.gray("Running GitHub PR creation command..."));
31
- console.log(chalk.gray(`Using base branch: ${baseBranch}`));
32
- // Add debugging output
33
- console.log(chalk.gray("Executing command with 60s timeout:"));
34
- // Execute the command with a timeout
35
- const result = execSync(command, {
36
- stdio: "pipe",
37
- timeout: 60000, // 60-second timeout
38
- }).toString();
39
- console.log(result);
40
- console.log(chalk.green(" Pull request created successfully"));
41
- }
42
- finally {
43
- // Clean up temporary file
44
- try {
45
- execSync(`rm -f "${tempFilePath}"`);
46
- }
47
- catch (e) {
48
- // Ignore cleanup errors
49
- }
50
- }
51
- }
52
- catch (error) {
53
- if (error instanceof Error && error.message.includes("timeout")) {
54
- console.error(chalk.red("Error: GitHub CLI command timed out after 60 seconds."));
55
- console.log(chalk.yellow("You may need to create the PR manually using:"));
56
- console.log(chalk.yellow(`gh pr create --title "${title}" --base "${baseBranch}" ${draftFlag}`));
57
- }
58
- else {
59
- console.error(chalk.red("Error creating pull request:"), error);
60
- }
61
- throw new Error("Failed to create pull request");
62
- }
13
+ let repoUrlArg = "";
14
+ try {
15
+ const repoUrl = execSync("git config --get remote.origin.url").toString().trim();
16
+ if (repoUrl) repoUrlArg = `--repo "${repoUrl}"`;
17
+ } catch (e) {}
18
+ const command = `gh pr create --title "${title.replace(/"/g, "\\\"")}" --body-file "${tempFilePath}" --base "${baseBranch}" ${draftFlag} ${repoUrlArg}`;
19
+ console.log(chalk.gray("Running GitHub PR creation command..."));
20
+ console.log(chalk.gray(`Using base branch: ${baseBranch}`));
21
+ console.log(chalk.gray("Executing command with 60s timeout:"));
22
+ const result = execSync(command, {
23
+ stdio: "pipe",
24
+ timeout: 6e4
25
+ }).toString();
26
+ console.log(result);
27
+ console.log(chalk.green(" Pull request created successfully"));
28
+ } finally {
29
+ try {
30
+ execSync(`rm -f "${tempFilePath}"`);
31
+ } catch (e) {}
32
+ }
33
+ } catch (error) {
34
+ if (error instanceof Error && error.message.includes("timeout")) {
35
+ console.error(chalk.red("Error: GitHub CLI command timed out after 60 seconds."));
36
+ console.log(chalk.yellow("You may need to create the PR manually using:"));
37
+ console.log(chalk.yellow(`gh pr create --title "${title}" --base "${baseBranch}" ${draftFlag}`));
38
+ } else console.error(chalk.red("Error creating pull request:"), error);
39
+ throw new Error("Failed to create pull request");
40
+ }
63
41
  };
42
+ //#endregion
43
+ export { createPullRequest };
@@ -1,6 +1,9 @@
1
1
  import { createPullRequest } from "./createPullRequest.js";
2
2
  import { isAvailable } from "./isAvailable.js";
3
- export const gh = {
4
- createPullRequest,
5
- isAvailable,
3
+ //#region src/services/gh/index.ts
4
+ var gh = {
5
+ createPullRequest,
6
+ isAvailable
6
7
  };
8
+ //#endregion
9
+ export { gh };
@@ -1,10 +1,12 @@
1
1
  import { execSync } from "child_process";
2
- export const isAvailable = () => {
3
- try {
4
- execSync("gh --version", { stdio: "ignore" });
5
- return true;
6
- }
7
- catch (error) {
8
- return false;
9
- }
2
+ //#region src/services/gh/isAvailable.ts
3
+ var isAvailable = () => {
4
+ try {
5
+ execSync("gh --version", { stdio: "ignore" });
6
+ return true;
7
+ } catch (error) {
8
+ return false;
9
+ }
10
10
  };
11
+ //#endregion
12
+ export { isAvailable };
@@ -1,15 +1,14 @@
1
1
  import chalk from "chalk";
2
2
  import { execSync } from "child_process";
3
- export const executeGitAdd = (files) => {
4
- try {
5
- if (files.length === 0) {
6
- throw new Error("No files specified");
7
- }
8
- const fileArgs = files.join(" ");
9
- execSync(`git add ${fileArgs}`, { stdio: "inherit" });
10
- }
11
- catch (error) {
12
- console.error(chalk.red("Error adding files:"), error);
13
- throw new Error("Failed to add files to git");
14
- }
3
+ //#region src/services/git/executeGitAdd.ts
4
+ var executeGitAdd = (files) => {
5
+ try {
6
+ if (files.length === 0) throw new Error("No files specified");
7
+ execSync(`git add ${files.join(" ")}`, { stdio: "inherit" });
8
+ } catch (error) {
9
+ console.error(chalk.red("Error adding files:"), error);
10
+ throw new Error("Failed to add files to git");
11
+ }
15
12
  };
13
+ //#endregion
14
+ export { executeGitAdd };
@@ -1,12 +1,11 @@
1
- import chalk from "chalk";
2
- import { execSync } from "child_process";
3
- export const executeGitCommit = (message, additionalArgs = []) => {
4
- try {
5
- const args = additionalArgs.join(" ");
6
- execSync(`git commit -m "${message}" ${args}`, { stdio: "inherit" });
7
- }
8
- catch (error) {
9
- console.error(chalk.red("Error committing changes:"), error);
10
- throw new Error("Failed to commit changes");
11
- }
1
+ import { spawnSync } from "child_process";
2
+ //#region src/services/git/executeGitCommit.ts
3
+ var executeGitCommit = (message, additionalArgs = []) => {
4
+ if (spawnSync("git", [
5
+ "commit",
6
+ ...message === null ? [] : ["-m", message],
7
+ ...additionalArgs
8
+ ], { stdio: "inherit" }).status !== 0) throw new Error("Failed to commit changes");
12
9
  };
10
+ //#endregion
11
+ export { executeGitCommit };
@@ -0,0 +1,23 @@
1
+ import chalk from "chalk";
2
+ import { execSync } from "child_process";
3
+ //#region src/services/git/getAmendChanges.ts
4
+ /**
5
+ * The content of the commit being amended: the staged tree compared to the
6
+ * commit before HEAD — so a plain reword still has a diff (even with nothing
7
+ * staged), and any new staged changes are folded in. Falls back to the staged
8
+ * diff when there is no previous commit (amending the very first commit).
9
+ */
10
+ var getAmendChanges = () => {
11
+ try {
12
+ return execSync("git diff --staged --function-context HEAD~1").toString();
13
+ } catch {
14
+ try {
15
+ return execSync("git diff --staged --function-context").toString();
16
+ } catch (error) {
17
+ console.error(chalk.red("Error getting amend changes:"), error);
18
+ throw new Error("Failed to get amend changes");
19
+ }
20
+ }
21
+ };
22
+ //#endregion
23
+ export { getAmendChanges };
@@ -1,64 +1,31 @@
1
1
  import chalk from "chalk";
2
2
  import { execSync } from "child_process";
3
- export const getChangedFiles = (baseBranch) => {
4
- // Try several methods to get changed files
5
- // Method 1: Compare with origin/baseBranch using three dots
6
- try {
7
- const changedFiles = execSync(`git diff --name-only origin/${baseBranch}...HEAD`)
8
- .toString()
9
- .trim();
10
- if (changedFiles) {
11
- return changedFiles.split("\n").filter(Boolean);
12
- }
13
- }
14
- catch (error) {
15
- // Continue to next method
16
- }
17
- // Method 2: Compare with local baseBranch using three dots
18
- try {
19
- const changedFiles = execSync(`git diff --name-only ${baseBranch}...HEAD`)
20
- .toString()
21
- .trim();
22
- if (changedFiles) {
23
- return changedFiles.split("\n").filter(Boolean);
24
- }
25
- }
26
- catch (error) {
27
- // Continue to next method
28
- }
29
- // Method 3: Direct comparison with two dots
30
- try {
31
- const changedFiles = execSync(`git diff --name-only ${baseBranch}..HEAD`)
32
- .toString()
33
- .trim();
34
- if (changedFiles) {
35
- return changedFiles.split("\n").filter(Boolean);
36
- }
37
- }
38
- catch (error) {
39
- // Continue to next method
40
- }
41
- // Method 4: Get recently modified files
42
- try {
43
- console.log(chalk.yellow(`Could not determine changed files relative to ${baseBranch}, using recently modified files...`));
44
- const changedFiles = execSync("git ls-files --modified --others --exclude-standard")
45
- .toString()
46
- .trim();
47
- if (changedFiles) {
48
- return changedFiles.split("\n").filter(Boolean);
49
- }
50
- }
51
- catch (error) {
52
- // Last resort
53
- }
54
- // Method 5: List all files in the repo as a last resort
55
- try {
56
- console.log(chalk.yellow("Using all tracked files as fallback..."));
57
- const allFiles = execSync("git ls-files").toString().trim();
58
- return allFiles.split("\n").filter(Boolean).slice(0, 50); // Limit to first 50 files
59
- }
60
- catch (error) {
61
- console.error(chalk.red("Could not determine changed files."));
62
- return [];
63
- }
3
+ //#region src/services/git/getChangedFiles.ts
4
+ var getChangedFiles = (baseBranch) => {
5
+ try {
6
+ const changedFiles = execSync(`git diff --name-only origin/${baseBranch}...HEAD`).toString().trim();
7
+ if (changedFiles) return changedFiles.split("\n").filter(Boolean);
8
+ } catch (error) {}
9
+ try {
10
+ const changedFiles = execSync(`git diff --name-only ${baseBranch}...HEAD`).toString().trim();
11
+ if (changedFiles) return changedFiles.split("\n").filter(Boolean);
12
+ } catch (error) {}
13
+ try {
14
+ const changedFiles = execSync(`git diff --name-only ${baseBranch}..HEAD`).toString().trim();
15
+ if (changedFiles) return changedFiles.split("\n").filter(Boolean);
16
+ } catch (error) {}
17
+ try {
18
+ console.log(chalk.yellow(`Could not determine changed files relative to ${baseBranch}, using recently modified files...`));
19
+ const changedFiles = execSync("git ls-files --modified --others --exclude-standard").toString().trim();
20
+ if (changedFiles) return changedFiles.split("\n").filter(Boolean);
21
+ } catch (error) {}
22
+ try {
23
+ console.log(chalk.yellow("Using all tracked files as fallback..."));
24
+ return execSync("git ls-files").toString().trim().split("\n").filter(Boolean).slice(0, 50);
25
+ } catch (error) {
26
+ console.error(chalk.red("Could not determine changed files."));
27
+ return [];
28
+ }
64
29
  };
30
+ //#endregion
31
+ export { getChangedFiles };