@andre-barbosa/opencode-commit 0.1.0 → 0.1.3
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/LICENSE +21 -21
- package/README.md +112 -122
- package/commands/commit.md +5 -5
- package/opencode.example.json +12 -17
- package/package.json +50 -48
- package/src/generate.ts +89 -112
- package/src/git.ts +116 -64
- package/src/index.ts +149 -136
- package/src/prompt.ts +72 -51
- package/src/types.ts +53 -40
- package/agents/commit-writer.md +0 -27
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026
|
|
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.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 André Barbosa
|
|
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
CHANGED
|
@@ -1,122 +1,112 @@
|
|
|
1
|
-
# opencode-commit
|
|
2
|
-
|
|
3
|
-
OpenCode plugin that generates **Conventional Commits** messages from
|
|
4
|
-
|
|
5
|
-
Run `/commit` in the OpenCode TUI to get a suggested message like `feat(auth): add oauth login flow` — copy it and commit manually.
|
|
6
|
-
|
|
7
|
-
## Features
|
|
8
|
-
|
|
9
|
-
- `/commit` slash command (display only, no auto-commit)
|
|
10
|
-
- Dedicated
|
|
11
|
-
- Conventional Commits format enforced (`feat(scope): ...`, `fix(scope): ...`, etc.)
|
|
12
|
-
- Optional hint: `/commit emphasize breaking API change`
|
|
13
|
-
- Uses staged
|
|
14
|
-
|
|
15
|
-
## Requirements
|
|
16
|
-
|
|
17
|
-
- [OpenCode](https://opencode.ai/) with plugin support
|
|
18
|
-
- A git repository with
|
|
19
|
-
|
|
20
|
-
## Installation
|
|
21
|
-
|
|
22
|
-
###
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
"commit
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
##
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
##
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
opencode-commit/
|
|
114
|
-
├── src/ # plugin source
|
|
115
|
-
├── agents/ # commit-writer sub-agent template
|
|
116
|
-
├── commands/ # /commit command stub
|
|
117
|
-
└── opencode.example.json
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## License
|
|
121
|
-
|
|
122
|
-
MIT
|
|
1
|
+
# @andre-barbosa/opencode-commit
|
|
2
|
+
|
|
3
|
+
OpenCode plugin that generates **Conventional Commits** messages from uncommitted git changes using a model you choose.
|
|
4
|
+
|
|
5
|
+
Run `/commit` in the OpenCode TUI to get a suggested message like `feat(auth): add oauth login flow` — copy it and commit manually.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- `/commit` slash command (display only, no auto-commit)
|
|
10
|
+
- Dedicated model for commit message generation
|
|
11
|
+
- Conventional Commits format enforced (`feat(scope): ...`, `fix(scope): ...`, etc.)
|
|
12
|
+
- Optional hint: `/commit emphasize breaking API change`
|
|
13
|
+
- Uses staged diffs, unstaged diffs, non-ignored untracked filenames, branch name, and recent commit subjects for context
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
- [OpenCode](https://opencode.ai/) with plugin support
|
|
18
|
+
- A git repository with uncommitted changes
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
### Configure the plugin
|
|
23
|
+
|
|
24
|
+
**Local development** (this repo):
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"$schema": "https://opencode.ai/config.json",
|
|
29
|
+
"plugin": [
|
|
30
|
+
[
|
|
31
|
+
"file:///C:/absolute/path/to/opencode-commit/src/index.ts",
|
|
32
|
+
{
|
|
33
|
+
"model": "opencode-go/deepseek-v4-flash",
|
|
34
|
+
"maxDiffChars": 12000
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**From npm:**
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"$schema": "https://opencode.ai/config.json",
|
|
46
|
+
"plugin": [
|
|
47
|
+
["@andre-barbosa/opencode-commit", { "model": "opencode-go/deepseek-v4-flash" }]
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
See [opencode.example.json](opencode.example.json) for a full example.
|
|
53
|
+
|
|
54
|
+
Run `opencode models` to list available models.
|
|
55
|
+
Restart OpenCode after editing config.
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
1. Make changes in a git repository. Staging is optional.
|
|
60
|
+
2. Open OpenCode in the project.
|
|
61
|
+
3. Run `/commit`.
|
|
62
|
+
4. Copy the suggested message and commit: `git commit -m "feat(scope): ..."`.
|
|
63
|
+
|
|
64
|
+
Optional extra instruction:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
/commit focus on test coverage improvements
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Plugin options
|
|
71
|
+
|
|
72
|
+
When loading the plugin as a tuple `[name, options]`:
|
|
73
|
+
|
|
74
|
+
| Option | Default | Description |
|
|
75
|
+
| --- | --- | --- |
|
|
76
|
+
| `model` | required | Model to use in `provider/model-id` format |
|
|
77
|
+
| `maxDiffChars` | `12000` | Max tracked diff characters sent across staged and unstaged diffs |
|
|
78
|
+
|
|
79
|
+
## Change scope
|
|
80
|
+
|
|
81
|
+
`/commit` analyzes:
|
|
82
|
+
|
|
83
|
+
- Staged tracked changes from `git diff --staged`
|
|
84
|
+
- Unstaged tracked changes from `git diff`
|
|
85
|
+
- Non-ignored untracked filenames from `git ls-files --others --exclude-standard`
|
|
86
|
+
|
|
87
|
+
It does not read untracked file contents and does not ask Git for ignored files.
|
|
88
|
+
|
|
89
|
+
## Commit message format
|
|
90
|
+
|
|
91
|
+
Generated messages follow [Conventional Commits](https://www.conventionalcommits.org/):
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
type(scope): short imperative description
|
|
95
|
+
|
|
96
|
+
- optional bullet body
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`.
|
|
100
|
+
|
|
101
|
+
## Project layout
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
opencode-commit/
|
|
105
|
+
├── src/ # plugin source
|
|
106
|
+
├── commands/ # optional /commit command stub
|
|
107
|
+
└── opencode.example.json
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## License
|
|
111
|
+
|
|
112
|
+
MIT
|
package/commands/commit.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Generate a commit message from
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Handled by the opencode-commit plugin.
|
|
1
|
+
---
|
|
2
|
+
description: Generate a commit message from uncommitted changes
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Handled by the opencode-commit plugin.
|
package/opencode.example.json
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://opencode.ai/config.json",
|
|
3
|
-
"plugin": [
|
|
4
|
-
[
|
|
5
|
-
"opencode-commit",
|
|
6
|
-
{
|
|
7
|
-
"
|
|
8
|
-
"maxDiffChars": 12000
|
|
9
|
-
}
|
|
10
|
-
]
|
|
11
|
-
]
|
|
12
|
-
|
|
13
|
-
"commit-writer": {
|
|
14
|
-
"model": "your-provider/your-model"
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://opencode.ai/config.json",
|
|
3
|
+
"plugin": [
|
|
4
|
+
[
|
|
5
|
+
"@andre-barbosa/opencode-commit",
|
|
6
|
+
{
|
|
7
|
+
"model": "your-provider/your-model",
|
|
8
|
+
"maxDiffChars": 12000
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
]
|
|
12
|
+
}
|
package/package.json
CHANGED
|
@@ -1,48 +1,50 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@andre-barbosa/opencode-commit",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "OpenCode plugin that generates Conventional Commit messages via a
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "src/index.ts",
|
|
7
|
-
"exports": {
|
|
8
|
-
".": "./src/index.ts"
|
|
9
|
-
},
|
|
10
|
-
"files": [
|
|
11
|
-
"src",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"opencode",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@andre-barbosa/opencode-commit",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "OpenCode plugin that generates Conventional Commit messages via /commit using a configured model",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./src/index.ts"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src",
|
|
12
|
+
"commands",
|
|
13
|
+
"opencode.example.json",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
19
|
+
"prepublishOnly": "npm run typecheck"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"opencode",
|
|
23
|
+
"opencode-plugin",
|
|
24
|
+
"git",
|
|
25
|
+
"commit",
|
|
26
|
+
"conventional-commits"
|
|
27
|
+
],
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/AndreB10/opencode-commit.git"
|
|
32
|
+
},
|
|
33
|
+
"bugs": {
|
|
34
|
+
"url": "https://github.com/AndreB10/opencode-commit/issues"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/AndreB10/opencode-commit#readme",
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@opencode-ai/plugin": "^1.3.3"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@opencode-ai/sdk": "^1.3.3",
|
|
45
|
+
"typescript": "^5.8.3"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18"
|
|
49
|
+
}
|
|
50
|
+
}
|
package/src/generate.ts
CHANGED
|
@@ -1,112 +1,89 @@
|
|
|
1
|
-
import type { createOpencodeClient } from "@opencode-ai/sdk";
|
|
2
|
-
import type {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
if (error) {
|
|
93
|
-
throw new Error(`Sub-agent prompt failed: ${String(error)}`);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const parts =
|
|
97
|
-
(result as { parts?: Array<{ type?: string; text?: string }> } | undefined)
|
|
98
|
-
?.parts ?? [];
|
|
99
|
-
const rawText = extractText(parts);
|
|
100
|
-
|
|
101
|
-
if (!rawText) {
|
|
102
|
-
throw new Error(
|
|
103
|
-
`Sub-agent returned no text. Child session: ${childSessionID}`,
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return {
|
|
108
|
-
message: stripCodeFences(rawText),
|
|
109
|
-
childSessionID,
|
|
110
|
-
modelLabel: formatModelRef(input.agent.model),
|
|
111
|
-
};
|
|
112
|
-
}
|
|
1
|
+
import type { createOpencodeClient } from "@opencode-ai/sdk";
|
|
2
|
+
import type { ModelRef } from "./types.js";
|
|
3
|
+
import {
|
|
4
|
+
buildCommitPrompt,
|
|
5
|
+
COMMIT_SYSTEM_PROMPT,
|
|
6
|
+
stripCodeFences,
|
|
7
|
+
} from "./prompt.js";
|
|
8
|
+
import type { GitContext } from "./types.js";
|
|
9
|
+
|
|
10
|
+
type Client = ReturnType<typeof createOpencodeClient>;
|
|
11
|
+
const COMMIT_AGENT = "plan";
|
|
12
|
+
|
|
13
|
+
function extractText(parts: Array<{ type?: string; text?: string }>): string {
|
|
14
|
+
return parts
|
|
15
|
+
.filter((part) => part.type === "text" && typeof part.text === "string")
|
|
16
|
+
.map((part) => part.text as string)
|
|
17
|
+
.join("")
|
|
18
|
+
.trim();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function formatModelRef(model?: ModelRef): string {
|
|
22
|
+
if (!model) return "default";
|
|
23
|
+
return `${model.providerID}/${model.modelID}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function createChildSession(
|
|
27
|
+
client: Client,
|
|
28
|
+
parentSessionID: string,
|
|
29
|
+
): Promise<string> {
|
|
30
|
+
const { data: session, error } = await client.session.create({
|
|
31
|
+
body: {
|
|
32
|
+
title: "Commit message",
|
|
33
|
+
parentID: parentSessionID,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (error || !session?.id) {
|
|
38
|
+
throw new Error(`Failed to create child session: ${String(error)}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return session.id;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function generateCommitMessage(input: {
|
|
45
|
+
client: Client;
|
|
46
|
+
parentSessionID: string;
|
|
47
|
+
model: ModelRef;
|
|
48
|
+
context: GitContext;
|
|
49
|
+
userHint?: string;
|
|
50
|
+
}): Promise<{ message: string; childSessionID: string; modelLabel: string }> {
|
|
51
|
+
const childSessionID = await createChildSession(
|
|
52
|
+
input.client,
|
|
53
|
+
input.parentSessionID,
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const prompt = buildCommitPrompt(input.context, input.userHint);
|
|
57
|
+
const body = {
|
|
58
|
+
agent: COMMIT_AGENT,
|
|
59
|
+
model: input.model,
|
|
60
|
+
system: COMMIT_SYSTEM_PROMPT,
|
|
61
|
+
parts: [{ type: "text" as const, text: prompt }],
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const { data: result, error } = await input.client.session.prompt({
|
|
65
|
+
path: { id: childSessionID },
|
|
66
|
+
body,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
if (error) {
|
|
70
|
+
throw new Error(`Commit prompt failed: ${String(error)}`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const parts =
|
|
74
|
+
(result as { parts?: Array<{ type?: string; text?: string }> } | undefined)
|
|
75
|
+
?.parts ?? [];
|
|
76
|
+
const rawText = extractText(parts);
|
|
77
|
+
|
|
78
|
+
if (!rawText) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`Commit model returned no text. Child session: ${childSessionID}`,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
message: stripCodeFences(rawText),
|
|
86
|
+
childSessionID,
|
|
87
|
+
modelLabel: formatModelRef(input.model),
|
|
88
|
+
};
|
|
89
|
+
}
|