gitpt 1.4.0 → 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 (116) hide show
  1. package/README.md +34 -160
  2. package/dist/commands/commit/commitFlags.js +7 -0
  3. package/dist/commands/commit/context/buildPrompt.js +16 -0
  4. package/dist/commands/commit/context/summaryPrompt.js +20 -0
  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 +16 -37
  8. package/dist/commands/commit/index.js +187 -178
  9. package/dist/commands/commit/summarizeDiff.js +193 -0
  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 +15 -0
  17. package/dist/commands/middleware/setupMiddleware/index.js +66 -38
  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 +25 -31
  23. package/dist/commands/pr/getPRContext.js +37 -62
  24. package/dist/commands/pr/index.js +57 -62
  25. package/dist/commands/reset.js +26 -0
  26. package/dist/commands/review/index.js +31 -0
  27. package/dist/commands/setup.js +38 -13
  28. package/dist/config.js +63 -55
  29. package/dist/index.js +31 -62
  30. package/dist/llm/budget.js +10 -0
  31. package/dist/llm/index.js +12 -12
  32. package/dist/llm/providers/anthropic/index.js +31 -0
  33. package/dist/llm/providers/apiKey.js +41 -0
  34. package/dist/llm/providers/apple/client.js +77 -0
  35. package/dist/llm/providers/apple/index.js +69 -0
  36. package/dist/llm/providers/apple/models.js +29 -0
  37. package/dist/llm/providers/base.js +36 -0
  38. package/dist/llm/providers/local/index.js +84 -0
  39. package/dist/llm/providers/openai/index.js +19 -0
  40. package/dist/llm/providers/openaiCompatible.js +66 -0
  41. package/dist/llm/providers/openrouter/index.js +19 -0
  42. package/dist/llm/registry.js +39 -0
  43. package/dist/llm/setup/getAvailableModels.js +17 -0
  44. package/dist/llm/setup/selectModel.js +40 -0
  45. package/dist/llm/tokenCount.js +5 -0
  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 +19 -5
  67. package/dist/commands/commit/context/systemPrompt.d.ts +0 -1
  68. package/dist/commands/commit/context/userPrompt.d.ts +0 -1
  69. package/dist/commands/commit/generateCommitMessage.d.ts +0 -1
  70. package/dist/commands/commit/index.d.ts +0 -7
  71. package/dist/commands/config.d.ts +0 -1
  72. package/dist/commands/middleware/capabilitiesMiddleware/ghCapability.d.ts +0 -1
  73. package/dist/commands/middleware/capabilitiesMiddleware/gitCapability.d.ts +0 -1
  74. package/dist/commands/middleware/capabilitiesMiddleware/index.d.ts +0 -3
  75. package/dist/commands/middleware/hasStagedChangesMiddleware.d.ts +0 -1
  76. package/dist/commands/middleware/setupMiddleware/getAvailableModels.d.ts +0 -4
  77. package/dist/commands/middleware/setupMiddleware/getAvailableModels.js +0 -11
  78. package/dist/commands/middleware/setupMiddleware/getOrUpdateApiKey.d.ts +0 -1
  79. package/dist/commands/middleware/setupMiddleware/getOrUpdateApiKey.js +0 -39
  80. package/dist/commands/middleware/setupMiddleware/index.d.ts +0 -4
  81. package/dist/commands/middleware/setupMiddleware/selectModel.d.ts +0 -5
  82. package/dist/commands/middleware/setupMiddleware/selectModel.js +0 -38
  83. package/dist/commands/middleware/setupMiddleware/setupLocalLLM.d.ts +0 -5
  84. package/dist/commands/middleware/setupMiddleware/setupLocalLLM.js +0 -60
  85. package/dist/commands/middleware/setupMiddleware/setupOpenRouter.d.ts +0 -2
  86. package/dist/commands/middleware/setupMiddleware/setupOpenRouter.js +0 -66
  87. package/dist/commands/middleware/setupMiddleware/types.d.ts +0 -13
  88. package/dist/commands/middleware/setupMiddleware/types.js +0 -1
  89. package/dist/commands/model.d.ts +0 -1
  90. package/dist/commands/pr/context/systemPrompt.d.ts +0 -1
  91. package/dist/commands/pr/context/userPrompt.d.ts +0 -1
  92. package/dist/commands/pr/generatePRDetails.d.ts +0 -4
  93. package/dist/commands/pr/getPRContext.d.ts +0 -1
  94. package/dist/commands/pr/index.d.ts +0 -10
  95. package/dist/commands/setup.d.ts +0 -3
  96. package/dist/config.d.ts +0 -18
  97. package/dist/index.d.ts +0 -2
  98. package/dist/llm/index.d.ts +0 -5
  99. package/dist/services/gh/createPullRequest.d.ts +0 -1
  100. package/dist/services/gh/index.d.ts +0 -4
  101. package/dist/services/gh/isAvailable.d.ts +0 -1
  102. package/dist/services/git/executeGitAdd.d.ts +0 -1
  103. package/dist/services/git/executeGitCommit.d.ts +0 -1
  104. package/dist/services/git/getChangedFiles.d.ts +0 -1
  105. package/dist/services/git/getCommitsSinceBaseBranch.d.ts +0 -1
  106. package/dist/services/git/getCurrentBranch.d.ts +0 -1
  107. package/dist/services/git/getDefaultBranch.d.ts +0 -1
  108. package/dist/services/git/getStagedChanges.d.ts +0 -1
  109. package/dist/services/git/getStagedFiles.d.ts +0 -1
  110. package/dist/services/git/hasStagedChanges.d.ts +0 -1
  111. package/dist/services/git/index.d.ts +0 -13
  112. package/dist/services/git/isAvailable.d.ts +0 -1
  113. package/dist/services/git/isGitRepository.d.ts +0 -1
  114. package/dist/utils/commitlint.d.ts +0 -25
  115. package/dist/utils/formatBaseURL.d.ts +0 -1
  116. package/dist/utils/maskApiKey.d.ts +0 -1
package/README.md CHANGED
@@ -1,201 +1,75 @@
1
1
  # GitPT
2
2
 
3
- Git Prompt Tool is a CLI tool that helps you write commit messages using AI through [OpenRouter](https://openrouter.ai/) or a local LLM. It acts as a complete git wrapper, enhancing specific commands with AI while passing through all other git commands directly.
3
+ GitPT (Git Prompt Tool) is a git command alias that writes your commit messages with an LLM, built for on-device models. Use it anywhere you use git: every command it doesn't change passes straight through, so you can replace git with it and lose nothing. The one command that changes is `commit`, which writes the message for you.
4
4
 
5
- ## Features
5
+ Big remote models already write commits fine. The harder case is the small local model on your machine (Apple's Foundation Models, Ollama, LM Studio), which holds only a few thousand tokens. A real diff is much larger, so GitPT summarizes it file by file until it fits the model's context window, then writes the message from that summary. Remote APIs (OpenAI, Anthropic, OpenRouter) work too.
6
6
 
7
- - Acts as a complete git replacement - all git commands are supported
8
- - Generate commit messages with AI based on your code changes
7
+ ![GitPT generating a commit message](assets/demo.gif)
9
8
 
10
- `gitpt commit`
11
- - Create pull requests with AI-generated titles and descriptions
9
+ <sub>The diff is summarized to fit the model's context window before the message is written.</sub>
12
10
 
13
- `gitpt pr create`
14
- - Compatible with all regular git options (flags, arguments, etc.)
15
- - Edit suggested messages before committing
16
- - Works with various AI models via OpenRouter
17
- - Support for local LLMs with OpenAI-compatible API
18
- - [Commitlint](https://commitlint.js.org/) support - read directly from your repository
11
+ > **New: Apple Foundation Models.** On macOS 27 and later, GitPT runs on Apple's built-in on-device model. No API key, no signup, nothing leaves your Mac. Run `gitpt setup` and choose Apple Foundation Models.
19
12
 
20
- ## Installation
13
+ ## Install
21
14
 
22
15
  ```bash
23
- # Install globally
24
16
  npm install -g gitpt
25
-
26
- # Or use npx
27
- npx gitpt
28
17
  ```
29
18
 
30
- ## Set up
31
-
32
- To configure GitPT with your OpenRouter API key and select a model:
19
+ ## Setup
33
20
 
34
21
  ```bash
35
- gitpt setup
22
+ gitpt setup # pick a model
36
23
  ```
37
24
 
38
- This will guide you through:
39
- 1. Entering your OpenRouter API key
40
- 2. Selecting an AI model from popular options or specifying a custom one
41
-
42
- _It's recommended using small models, such as `openai/gpt-4.1-mini` as your model choice. Mainly due to its large context window, fast response times & cost-effective pricing._
43
-
44
-
45
- You'll need an [OpenRouter](https://openrouter.ai/) account to get an API key.
46
-
47
- ## Usage
48
-
49
- ### Using GitPT as a Complete Git Replacement
50
-
51
- GitPT can be used as a direct replacement for git - any git command can be run through GitPT:
25
+ Optional: alias git so GitPT runs everywhere you already type git.
52
26
 
53
27
  ```bash
54
- # Standard git commands work exactly the same
55
- gitpt status
56
- gitpt log
57
- gitpt branch
58
- gitpt checkout -b new-feature
59
- gitpt push origin main
60
-
61
- # GitPT passes all arguments and options to git
62
- gitpt log --oneline --graph
63
- gitpt merge --no-ff feature-branch
28
+ alias git=gitpt
64
29
  ```
65
30
 
66
- ### Adding Files
31
+ ## Use
67
32
 
68
- Add files to the staging area just like you would with git:
33
+ With plain git, you write the message yourself:
69
34
 
70
35
  ```bash
71
- # Same as git add . (supports all the regular git add options)
72
- gitpt add .
36
+ git add .
37
+ git commit -m "fix: handle empty staged diff" # you write the message
73
38
  ```
74
39
 
75
- ### Creating Commits
76
-
77
- Generate an AI-powered commit message based on your staged changes:
40
+ With GitPT, you don't:
78
41
 
79
42
  ```bash
80
- gitpt commit
81
-
82
- # Or supply -m argument, if you want to avoid gitpt generating the message
83
- gitpt commit -m "feat: file hash validation"
84
-
85
- # Pass any other git commit options
86
- gitpt commit --amend
87
- ```
88
-
89
- The tool will:
90
- 1. Analyze your staged changes
91
- 2. Generate a commit message using the configured AI model
92
- 3. Validate against commitlint rules (if configured)
93
- 4. Regenerate the message if it fails validation
94
- 5. Show you the suggested message
95
- 6. Let you edit the message before committing
96
- 7. Create the commit with your approved message
97
-
98
- ### Changing Models
99
-
100
- You can change the AI model at any time:
101
-
102
- ```bash
103
- # Select model interactively (either OpenRouter or a local LLM)
104
- gitpt model
105
- ```
106
-
107
- _It's recommended using small models, such as `openai/gpt-4.1-mini` as your model choice. Mainly due to its large context window, fast response times & cost-effective pricing._
108
-
109
- #### Using a Local LLM
110
-
111
- GitPT works with any local LLM that provides an OpenAI-compatible API endpoint, such as:
112
- - [Ollama](https://ollama.ai/)
113
- - [LM Studio](https://lmstudio.ai/)
114
- - [LocalAI](https://localai.io/)
115
- - Custom setups with tools like llama.cpp
116
-
117
- ## GitHub Usage
118
-
119
- If you have GitHub CLI (`gh`) installed, you can use GitPT to interact with GitHub (e.g. generate full pull requests).
120
-
121
- ### Creating Pull Requests
122
-
123
- Generate AI-powered pull request titles and descriptions based on your changes:
124
-
125
- ```bash
126
- gitpt pr create
127
- ```
128
-
129
- The tool will:
130
- 1. Analyze the commits and files changed since branching from the base branch
131
- 2. Generate a suitable PR title and detailed description
132
- 3. Show you the suggested content
133
- 4. Let you edit the title and description before submission
134
- 5. Create the pull request with your approved content
135
-
136
- #### Pull Request Options
137
-
138
- ```bash
139
- # Create a draft PR
140
- gitpt pr create --draft
141
-
142
- # Specify a custom base branch
143
- gitpt pr create --base develop
144
-
145
- # Skip editing the PR details
146
- gitpt pr create --no-edit
147
-
148
- # Provide your own title instead of generating one
149
- gitpt pr create --title "Your PR title here"
43
+ gitpt add .
44
+ gitpt commit # GitPT writes it from the diff
150
45
  ```
151
46
 
152
- ## How It Works
47
+ `gitpt commit` reads your staged diff, writes the message, and opens it in your editor. Save and close to commit.
153
48
 
154
- GitPT leverages AI to enhance your Git workflow while acting as a complete git wrapper:
49
+ ### Through plain `git commit`
155
50
 
156
- - **Command Handling:** GitPT intelligently routes commands - enhanced commands (commit, pr) use AI capabilities while all other git commands are passed directly to git.
157
-
158
- - **For commits:** Sends a diff of your staged changes to the AI, which generates a contextual commit message following best practices.
159
-
160
- - **Commitlint Integration:** Automatically detects commitlint configuration files and validates generated commit messages against your project's commit conventions. If validation fails, it regenerates a compliant message.
161
-
162
- - **For pull requests:** Analyzes the commits and file changes between your branch and the base branch, then generates a suitable title and detailed description for your PR.
163
-
164
- - **For other git commands:** Passes them through directly to git with all arguments and options preserved, ensuring complete compatibility with your existing git workflow.
165
-
166
- - **Local LLM Support:** Can use locally running LLM servers with OpenAI-compatible APIs instead of cloud-based services, providing privacy and offline capabilities.
167
-
168
- ## Development
169
-
170
- ```bash
171
- # Clone the repository
172
- git clone https://github.com/bartaxyz/GitPT.git
173
- cd GitPT
174
-
175
- # Install dependencies
176
- npm install
177
-
178
- # Build the project
179
- npm run build
180
-
181
- # Link for local development
182
- npm link
183
- ```
51
+ Prefer typing `git commit`? Two ways:
184
52
 
185
- ## Commitlint Integration
53
+ - **Shell alias** — add `alias git=gitpt` to your shell rc, then `git commit` runs GitPT.
54
+ - **Git hook** — run `gitpt hook install` once. A normal `git commit` (without `-m`) then opens your editor prefilled with an AI-generated message. It steps aside for `-m`, merges, squashes, and amends, and never blocks a commit if generation fails. Remove it with `gitpt hook uninstall`.
186
55
 
187
- GitPT automatically detects and integrates with [commitlint](https://commitlint.js.org/) if it's configured in your repository:
56
+ ## Commands
188
57
 
189
- - **Automatic Detection:** GitPT checks for common commitlint configuration files (commitlint.config.js, .commitlintrc.*, etc.)
58
+ - `gitpt commit`: write a commit message from staged changes. Respects `-m` and your commitlint rules.
59
+ - `gitpt model`: pick or switch the model. Each provider keeps its own key.
60
+ - `gitpt setup` / `gitpt config` / `gitpt reset`: configure, show, or clear settings.
61
+ - `gitpt pr create`: draft a pull request title and description with the `gh` CLI (experimental).
62
+ - `gitpt hook install` / `gitpt hook uninstall`: use GitPT through a plain `git commit` via a `prepare-commit-msg` hook.
190
63
 
191
- - **Rule-Aware Generation:** When commitlint is detected, GitPT instructs the AI to generate messages that follow your specific commit conventions
64
+ ## Models
192
65
 
193
- - **Validation & Regeneration:** Generated messages are validated against your commitlint rules before committing. If validation fails, GitPT automatically regenerates a compliant message
66
+ - **On-device**: Apple's Foundation Models on macOS 27 or later (no API key), or any OpenAI-compatible local server such as Ollama or LM Studio.
67
+ - **Remote**: OpenAI, Anthropic, OpenRouter. Bring an API key.
194
68
 
195
- - **Error Feedback:** Validation errors are sent to the AI to help it understand how to fix the message
69
+ ## Requests and bugs
196
70
 
197
- This integration ensures that all AI-generated commit messages follow your team's established commit conventions without requiring manual corrections.
71
+ Want a feature or hit a bug? [Open an issue](https://github.com/bartaxyz/GitPT/issues).
198
72
 
199
73
  ## License
200
74
 
201
- MIT
75
+ MIT
@@ -0,0 +1,7 @@
1
+ //#region src/commands/commit/commitFlags.ts
2
+ var hasFlag = (args, flag) => args.some((arg) => arg === flag || arg.startsWith(`${flag}=`));
3
+ var isAmend = (args) => hasFlag(args, "--amend");
4
+ var isAllowEmpty = (args) => hasFlag(args, "--allow-empty");
5
+ var skipsStagedGuard = (args) => isAmend(args) || isAllowEmpty(args);
6
+ //#endregion
7
+ export { isAmend, skipsStagedGuard };
@@ -0,0 +1,16 @@
1
+ import { getCommitlintRules, hasCommitlintConfig } from "../../../utils/commitlint.js";
2
+ import { systemPrompt } from "./systemPrompt.js";
3
+ import { userPrompt } from "./userPrompt.js";
4
+ //#region src/commands/commit/context/buildPrompt.ts
5
+ var buildCommitPrompt = (diff, validationErrors) => {
6
+ return {
7
+ system: [
8
+ systemPrompt,
9
+ hasCommitlintConfig() ? getCommitlintRules() : "",
10
+ validationErrors ? `\n\nYOUR PREVIOUS MESSAGE FAILED VALIDATION WITH THESE ERRORS:\n${validationErrors}\n\nFIX THESE ISSUES IN YOUR NEW MESSAGE.` : ""
11
+ ].join("\n\n"),
12
+ user: userPrompt(diff)
13
+ };
14
+ };
15
+ //#endregion
16
+ export { buildCommitPrompt };
@@ -0,0 +1,20 @@
1
+ //#region src/commands/commit/context/summaryPrompt.ts
2
+ var summarySystemPrompt = `
3
+ You are condensing a fragment of a git diff so a commit message can be written afterwards.
4
+
5
+ Output exactly one line per changed file, in this format:
6
+ <path>: <what changed>
7
+
8
+ Rules:
9
+ - One line per file — no more, no less.
10
+ - Keep each description under ~12 words.
11
+ - Describe the functional change (what was added, removed, refactored, or fixed), not file mechanics.
12
+ - Output ONLY these lines. No preamble, no commentary, no code fences, no headings, no blank lines.
13
+ `;
14
+ var summaryUserPrompt = (diffChunk) => `
15
+ Summarize the changes in this git diff fragment:
16
+
17
+ ${diffChunk}
18
+ `;
19
+ //#endregion
20
+ export { summarySystemPrompt, summaryUserPrompt };
@@ -1,4 +1,5 @@
1
- export const systemPrompt = `
1
+ //#region src/commands/commit/context/systemPrompt.ts
2
+ var systemPrompt = `
2
3
  You are a helpful assistant that generates concise, informative Git commit messages.
3
4
 
4
5
  Follow these strict rules:
@@ -36,3 +37,5 @@ Examples of Bad Commit Messages:
36
37
  This implements the login page... ❌ (contains multiple lines)
37
38
  - "fix: update styling" ❌ (includes quotes)
38
39
  `;
40
+ //#endregion
41
+ export { systemPrompt };
@@ -1,5 +1,8 @@
1
- export const userPrompt = (diff) => `
1
+ //#region src/commands/commit/context/userPrompt.ts
2
+ var userPrompt = (diff) => `
2
3
  Generate a single-line commit message for the following git diff:
3
4
 
4
5
  ${diff}
5
6
  `;
7
+ //#endregion
8
+ export { userPrompt };
@@ -1,39 +1,18 @@
1
1
  import { getConfig } from "../../config.js";
2
- import { getLLMClient } from "../../llm/index.js";
3
- import { getCommitlintRules, hasCommitlintConfig, } from "../../utils/commitlint.js";
4
- import { systemPrompt } from "./context/systemPrompt.js";
5
- import { userPrompt } from "./context/userPrompt.js";
6
- export const generateCommitMessage = async (diff, validationErrors) => {
7
- // Check if commitlint is configured
8
- const hasCommitlint = hasCommitlintConfig();
9
- const config = getConfig();
10
- // Check if we have a configured model
11
- if (!config.model) {
12
- throw new Error('GitPT is not configured properly. Please run "gitpt setup" first.');
13
- }
14
- const { model } = config;
15
- const baseRules = hasCommitlint ? getCommitlintRules() : "";
16
- const errorInfo = validationErrors
17
- ? `\n\nYOUR PREVIOUS MESSAGE FAILED VALIDATION WITH THESE ERRORS:\n${validationErrors}\n\nFIX THESE ISSUES IN YOUR NEW MESSAGE.`
18
- : "";
19
- const llmClient = getLLMClient();
20
- const response = await llmClient.chat.completions.create({
21
- model: model,
22
- messages: [
23
- {
24
- role: "system",
25
- content: [systemPrompt, baseRules, errorInfo].join("\n\n"),
26
- },
27
- {
28
- role: "user",
29
- content: userPrompt(diff),
30
- },
31
- ],
32
- max_tokens: 300,
33
- });
34
- const message = response.choices[0].message.content;
35
- if (!message) {
36
- throw new Error("No message returned from LLM");
37
- }
38
- return message;
2
+ import { getProvider } from "../../llm/registry.js";
3
+ import { buildCommitPrompt } from "./context/buildPrompt.js";
4
+ //#region src/commands/commit/generateCommitMessage.ts
5
+ var generateCommitMessage = async (diff, validationErrors) => {
6
+ if (!getConfig().model) throw new Error("GitPT is not configured properly. Please run \"gitpt setup\" first.");
7
+ const { system, user } = buildCommitPrompt(diff, validationErrors);
8
+ const provider = getProvider();
9
+ const message = await provider.complete({
10
+ system,
11
+ user,
12
+ maxTokens: provider.maxOutputTokens
13
+ });
14
+ if (!message) throw new Error("No message returned from LLM");
15
+ return message;
39
16
  };
17
+ //#endregion
18
+ export { generateCommitMessage };