pivotdude-git-ai 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/LICENSE +21 -0
- package/README.md +109 -0
- package/bin/git-ai.js +2 -0
- package/config.schema.json +79 -0
- package/dist/cursor-sdk-runner.mjs +49 -0
- package/dist/index.js +2474 -0
- package/dist/prompts/branch-commit-pr.md +28 -0
- package/dist/prompts/branch-commit-push.md +13 -0
- package/dist/prompts/commit-push.md +10 -0
- package/dist/prompts/create-pr.md +25 -0
- package/dist/prompts/git-conventions.md +102 -0
- package/package.json +67 -0
- package/project-config.example/config.json +14 -0
- package/project-config.example/diff-ignore +10 -0
- package/project-config.example/prompts/commit-push.md +14 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [1.0.1] - 2026-07-01
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Publish as unscoped `pivotdude-git-ai` on npm (scoped `@pivotdude/git-ai` was private and not installable).
|
|
10
|
+
|
|
11
|
+
## [1.0.0] - 2026-07-01
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Initial public release extracted from the OpenTrade monorepo.
|
|
16
|
+
- AI-assisted git workflows: commit-push, branch-commit-pr, create-pr, update-pr.
|
|
17
|
+
- Project config via `.git-ai/` directory.
|
|
18
|
+
- OpenAI-compatible, Cursor SDK, and manual AI providers.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 pivotdude
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# git-ai
|
|
2
|
+
|
|
3
|
+
AI-assisted git workflows: commit messages, branches, pull requests, and optional pre-commit fixes.
|
|
4
|
+
|
|
5
|
+
Requires [Bun](https://bun.sh) >= 1.3 and `git` / `gh` on `PATH` for the full workflow.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i -g pivotdude-git-ai
|
|
11
|
+
# or
|
|
12
|
+
bun add -g pivotdude-git-ai
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Run from any directory inside a git repository:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
git-ai
|
|
19
|
+
git-ai --mode commit-push
|
|
20
|
+
git-ai --provider manual
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Monorepos can wire package scripts, e.g. `"git:ai": "git-ai"`.
|
|
24
|
+
|
|
25
|
+
## Project config (`.git-ai/`)
|
|
26
|
+
|
|
27
|
+
Optional files at the **git repository root**:
|
|
28
|
+
|
|
29
|
+
| Path | Purpose |
|
|
30
|
+
|------|---------|
|
|
31
|
+
| `.git-ai/config.json` | `baseBranch`, `stagedFix`, optional `conventions` / `prTemplate` paths ([JSON Schema](config.schema.json)) |
|
|
32
|
+
| `.git-ai/diff-ignore` | `.gitignore`-style patterns omitted from AI diffs (merged with built-in lockfile defaults) |
|
|
33
|
+
| `.git-ai/prompts/*.md` | Per-mode prompt overrides (`commit-push.md`, `create-pr.md`, …) |
|
|
34
|
+
| `.git-ai/conventions.md` | Commit/branch conventions when `conventions` is not set in `config.json` |
|
|
35
|
+
|
|
36
|
+
See `project-config.example/` for a starter layout.
|
|
37
|
+
|
|
38
|
+
Legacy `.git-ai.json` at the repo root is still read if `config.json` is missing.
|
|
39
|
+
|
|
40
|
+
Point `$schema` in `config.json` at the published schema URL for editor autocomplete:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"$schema": "https://raw.githubusercontent.com/pivotdude/git-ai/main/config.schema.json"
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Dry run
|
|
49
|
+
|
|
50
|
+
Print the assembled AI prompt without calling an API or running git actions:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
git-ai --dry-run --mode commit-push
|
|
54
|
+
git-ai -n --mode create-pr
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Git state is still read (staged diff, branch log, etc.) to build the prompt.
|
|
58
|
+
|
|
59
|
+
## `stagedFix` and shell commands
|
|
60
|
+
|
|
61
|
+
`stagedFix` in `config.json` runs **arbitrary shell commands** from the repository root before commit (for example `bun --filter web fix`).
|
|
62
|
+
|
|
63
|
+
- Only add commands you trust, in repositories you control.
|
|
64
|
+
- Anyone who can change `.git-ai/config.json` can run shell code on your machine when you approve a git-ai commit.
|
|
65
|
+
- Commands are executed with `sh -c`; failures are warned but do not always stop the workflow.
|
|
66
|
+
|
|
67
|
+
Treat `.git-ai/` like other sensitive local tooling config (similar to custom git hooks).
|
|
68
|
+
|
|
69
|
+
## AI providers
|
|
70
|
+
|
|
71
|
+
| Provider | Env vars |
|
|
72
|
+
|----------|----------|
|
|
73
|
+
| OpenAI-compatible | `OPENAI_BASE_URL`, `OPENAI_API_KEY`, optional `OPENAI_MODEL` |
|
|
74
|
+
| Cursor SDK | `CURSOR_API_KEY`, optional `CURSOR_MODEL` |
|
|
75
|
+
| Manual | Copies prompt to clipboard / `$EDITOR`; no API key |
|
|
76
|
+
|
|
77
|
+
Before applying, you can **edit** individual fields (branch, commit message, PR title, description) in `$EDITOR`.
|
|
78
|
+
|
|
79
|
+
Uses `$VISUAL` or `$EDITOR` (default `nano`) for manual provider responses and pre-apply edits.
|
|
80
|
+
|
|
81
|
+
When the API returns token usage (OpenAI-compatible providers), git-ai prints a one-line `[tokens]` summary with in/out/total counts. Cost is shown only when included in the response (e.g. some OpenRouter payloads).
|
|
82
|
+
|
|
83
|
+
## Development
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
bun install
|
|
87
|
+
bun run check # typecheck
|
|
88
|
+
bun run lint:check
|
|
89
|
+
bun test # unit tests
|
|
90
|
+
bun run build
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Suggested validation before opening a PR or publishing:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
bun run validate:local-release
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## npm release flow
|
|
100
|
+
|
|
101
|
+
1. Bump `package.json.version`.
|
|
102
|
+
2. Commit and push to GitHub.
|
|
103
|
+
3. Create and push tag `v<version>` (for example `v1.0.1`).
|
|
104
|
+
4. Publish a GitHub Release from that tag.
|
|
105
|
+
5. GitHub Actions publishes the package to npm with the `latest` tag (`NPM_TOKEN` secret required).
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
MIT
|
package/bin/git-ai.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/pivotdude/git-ai/main/config.schema.json",
|
|
4
|
+
"title": "git-ai project config",
|
|
5
|
+
"description": "Optional settings in .git-ai/config.json at the git repository root.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"$schema": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "JSON Schema URL or path for editor validation."
|
|
12
|
+
},
|
|
13
|
+
"baseBranch": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"minLength": 1,
|
|
16
|
+
"description": "Default base branch for create-pr / update-pr diff and PR target.",
|
|
17
|
+
"default": "main"
|
|
18
|
+
},
|
|
19
|
+
"diffIgnore": {
|
|
20
|
+
"type": "array",
|
|
21
|
+
"description": "Extra .gitignore-style patterns omitted from AI diffs. Merged with .git-ai/diff-ignore and built-in lockfile defaults.",
|
|
22
|
+
"items": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"minLength": 1
|
|
25
|
+
},
|
|
26
|
+
"uniqueItems": true
|
|
27
|
+
},
|
|
28
|
+
"conventions": {
|
|
29
|
+
"type": ["string", "null"],
|
|
30
|
+
"description": "Repo-relative path to commit/branch conventions markdown. Null uses .git-ai/conventions.md or the bundled default."
|
|
31
|
+
},
|
|
32
|
+
"prTemplate": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"minLength": 1,
|
|
35
|
+
"description": "Repo-relative path to the pull request template markdown.",
|
|
36
|
+
"default": ".github/PULL_REQUEST_TEMPLATE.md"
|
|
37
|
+
},
|
|
38
|
+
"stagedFix": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"description": "Optional lint/format commands run before commit. Executes arbitrary shell from the repository root.",
|
|
41
|
+
"additionalProperties": false,
|
|
42
|
+
"properties": {
|
|
43
|
+
"rules": {
|
|
44
|
+
"type": "array",
|
|
45
|
+
"items": { "$ref": "#/$defs/stagedFixRule" },
|
|
46
|
+
"default": []
|
|
47
|
+
},
|
|
48
|
+
"root": {
|
|
49
|
+
"oneOf": [{ "$ref": "#/$defs/stagedFixRule" }, { "type": "null" }],
|
|
50
|
+
"default": null
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"default": { "rules": [], "root": null }
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"$defs": {
|
|
57
|
+
"stagedFixRule": {
|
|
58
|
+
"type": "object",
|
|
59
|
+
"additionalProperties": false,
|
|
60
|
+
"required": ["paths", "command"],
|
|
61
|
+
"properties": {
|
|
62
|
+
"paths": {
|
|
63
|
+
"type": "array",
|
|
64
|
+
"minItems": 1,
|
|
65
|
+
"description": ".gitignore-style path patterns. Command runs when any staged file matches.",
|
|
66
|
+
"items": {
|
|
67
|
+
"type": "string",
|
|
68
|
+
"minLength": 1
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"command": {
|
|
72
|
+
"type": "string",
|
|
73
|
+
"minLength": 1,
|
|
74
|
+
"description": "Shell command executed from the repository root (sh -c)."
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
|
|
5
|
+
import { Agent, CursorAgentError } from '@cursor/sdk';
|
|
6
|
+
|
|
7
|
+
const apiKey = process.env.CURSOR_API_KEY;
|
|
8
|
+
const model = process.env.CURSOR_MODEL ?? 'composer-2.5';
|
|
9
|
+
const promptPath = process.argv[2];
|
|
10
|
+
|
|
11
|
+
if (!apiKey) {
|
|
12
|
+
console.error('CURSOR_API_KEY is required');
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (!promptPath) {
|
|
17
|
+
console.error('Usage: cursor-sdk-runner.mjs <prompt-file>');
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const prompt = await readFile(promptPath, 'utf8');
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const result = await Agent.prompt(prompt, {
|
|
25
|
+
apiKey,
|
|
26
|
+
model: { id: model },
|
|
27
|
+
local: { cwd: process.cwd(), settingSources: [] },
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
if (result.status === 'error') {
|
|
31
|
+
console.error(`Cursor agent run failed: ${result.id}`);
|
|
32
|
+
process.exit(2);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const content = result.result?.trim();
|
|
36
|
+
if (!content) {
|
|
37
|
+
console.error('Empty response from Cursor agent');
|
|
38
|
+
process.exit(2);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
process.stdout.write(content);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
if (error instanceof CursorAgentError) {
|
|
44
|
+
console.error(`Cursor SDK startup failed: ${error.message}`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
throw error;
|
|
49
|
+
}
|