opencode-gitbutler 0.1.0
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 -0
- package/README.md +147 -0
- package/command/b-branch-commit.md +105 -0
- package/command/b-branch-gc.md +58 -0
- package/command/b-branch-pr.md +221 -0
- package/command/b-branch.md +88 -0
- package/dist/auto-update.d.ts +39 -0
- package/dist/auto-update.d.ts.map +1 -0
- package/dist/cli.d.ts +85 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/config.d.ts +36 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1731 -0
- package/dist/logger.d.ts +21 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/notify.d.ts +11 -0
- package/dist/notify.d.ts.map +1 -0
- package/dist/plugin.d.ts +21 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/reword.d.ts +104 -0
- package/dist/reword.d.ts.map +1 -0
- package/dist/state.d.ts +38 -0
- package/dist/state.d.ts.map +1 -0
- package/package.json +56 -0
- package/postinstall.mjs +10 -0
- package/skill/gitbutler/SKILL.md +275 -0
- package/skill/gitbutler/references/cheatsheet.md +271 -0
- package/skill/gitbutler/references/concepts.md +333 -0
- package/skill/gitbutler/references/examples.md +512 -0
- package/skill/gitbutler/references/reference.md +504 -0
- package/skill/gitbutler/references/tutorial.md +486 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 gaboe
|
|
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,147 @@
|
|
|
1
|
+
# opencode-gitbutler
|
|
2
|
+
|
|
3
|
+
OpenCode plugin for seamless GitButler integration. Automatically manages branches, generates commit messages via LLM, and provides real-time workspace state notifications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add opencode-gitbutler
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
- **GitButler CLI** (`but`) — [Install via Homebrew](https://docs.gitbutler.com/installation)
|
|
14
|
+
- **OpenCode** — v1.1.0 or later
|
|
15
|
+
- **Bun** — v1.0.0 or later (plugin runtime)
|
|
16
|
+
|
|
17
|
+
The postinstall script checks for the GitButler CLI and warns if missing (install never fails).
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
Add to your OpenCode config (`.opencode/config.json`):
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"plugins": ["opencode-gitbutler"]
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The plugin automatically:
|
|
30
|
+
- Creates and renames branches based on your prompts
|
|
31
|
+
- Generates commit messages using Claude Haiku
|
|
32
|
+
- Injects workspace state into agent context via `SKILL.md`
|
|
33
|
+
- Checks for updates on session creation
|
|
34
|
+
|
|
35
|
+
## Configuration
|
|
36
|
+
|
|
37
|
+
Create `.opencode/gitbutler.json` in your workspace root to override defaults:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
// Enable debug logging to .opencode/plugin/debug.log
|
|
42
|
+
"log_enabled": true,
|
|
43
|
+
|
|
44
|
+
// LLM provider and model for commit message generation
|
|
45
|
+
"commit_message_provider": "anthropic",
|
|
46
|
+
"commit_message_model": "claude-haiku-4-5",
|
|
47
|
+
|
|
48
|
+
// Timeout for LLM requests (milliseconds)
|
|
49
|
+
"llm_timeout_ms": 15000,
|
|
50
|
+
|
|
51
|
+
// Maximum diff size to send to LLM (characters)
|
|
52
|
+
"max_diff_chars": 4000,
|
|
53
|
+
|
|
54
|
+
// Maximum length of auto-generated branch slugs
|
|
55
|
+
"branch_slug_max_length": 50,
|
|
56
|
+
|
|
57
|
+
// Enable automatic version update checks
|
|
58
|
+
"auto_update": true,
|
|
59
|
+
|
|
60
|
+
// Regex pattern for default branch detection
|
|
61
|
+
"default_branch_pattern": "^ge-branch-\\d+$"
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Configuration Reference
|
|
66
|
+
|
|
67
|
+
| Key | Type | Default | Description |
|
|
68
|
+
|-----|------|---------|-------------|
|
|
69
|
+
| `log_enabled` | boolean | `true` | Write debug logs to `.opencode/plugin/debug.log` |
|
|
70
|
+
| `commit_message_provider` | string | `"anthropic"` | LLM provider ID |
|
|
71
|
+
| `commit_message_model` | string | `"claude-haiku-4-5"` | Model ID for commit generation |
|
|
72
|
+
| `llm_timeout_ms` | number | `15000` | Request timeout in milliseconds |
|
|
73
|
+
| `max_diff_chars` | number | `4000` | Max diff size sent to LLM |
|
|
74
|
+
| `branch_slug_max_length` | number | `50` | Max auto-generated branch name length |
|
|
75
|
+
| `auto_update` | boolean | `true` | Check npm for newer versions |
|
|
76
|
+
| `default_branch_pattern` | string | `"^ge-branch-\\d+$"` | Regex for default branch detection |
|
|
77
|
+
|
|
78
|
+
All fields are optional. Missing fields use defaults.
|
|
79
|
+
|
|
80
|
+
## Feature Parity vs Native Integrations
|
|
81
|
+
|
|
82
|
+
How this plugin compares to GitButler's built-in Cursor and Claude Code integrations:
|
|
83
|
+
|
|
84
|
+
| Feature | Cursor | Claude Code | This Plugin | Status |
|
|
85
|
+
|---------|--------|-------------|-------------|--------|
|
|
86
|
+
| Post-edit hook | `after-edit` | PostToolUse | `tool.execute.after` | Equal |
|
|
87
|
+
| Stop/idle hook | `stop` | Stop | `session.idle` | Equal |
|
|
88
|
+
| Branch creation | `get_or_create_session` | `get_or_create_session` | via `conversation_id` | Equal |
|
|
89
|
+
| Auto-assign to existing branch | — | — | `but rub` via `findFileBranch()` | **Better** |
|
|
90
|
+
| Branch auto-rename (LLM) | From Cursor DB | From transcript | `but reword` + user prompt | Equal |
|
|
91
|
+
| Auto-commit on stop | `handle_changes()` | `handle_changes()` | via `but cursor stop` | Equal |
|
|
92
|
+
| Commit message (LLM) | OpenAI gpt-4-mini | OpenAI gpt-4-mini | Claude Haiku via OpenCode SDK | Equal |
|
|
93
|
+
| Multi-agent session mapping | — | — | `resolveSessionRoot()` | **Unique** |
|
|
94
|
+
| File locking (concurrent) | — | 60s wait + retry | 60s poll + stale cleanup | Equal |
|
|
95
|
+
| Agent state notifications | — | — | `chat.messages.transform` | **Unique** |
|
|
96
|
+
| Hunk-level rub guard | — | — | Skip multi-stack files | **Better** |
|
|
97
|
+
|
|
98
|
+
**Score**: 7 Equal, 4 Better/Unique
|
|
99
|
+
|
|
100
|
+
For the full architecture breakdown, gap analysis, and known issues, see [`docs/gitbutler-integration.md`](docs/gitbutler-integration.md).
|
|
101
|
+
|
|
102
|
+
## Troubleshooting
|
|
103
|
+
|
|
104
|
+
### GitButler CLI not found
|
|
105
|
+
|
|
106
|
+
**Error:** `⚠ GitButler CLI not found. Install with: brew install gitbutler`
|
|
107
|
+
|
|
108
|
+
**Solution:** Install GitButler via Homebrew:
|
|
109
|
+
```bash
|
|
110
|
+
brew install gitbutler
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The plugin will work without it, but workspace commands will fail at runtime.
|
|
114
|
+
|
|
115
|
+
### Config file not found
|
|
116
|
+
|
|
117
|
+
If `.opencode/gitbutler.json` is missing, the plugin uses all defaults. No error is raised.
|
|
118
|
+
|
|
119
|
+
### Debug logging
|
|
120
|
+
|
|
121
|
+
Enable `log_enabled: true` in config to write detailed logs to `.opencode/plugin/debug.log`. Useful for diagnosing branch creation, commit message generation, and state injection issues.
|
|
122
|
+
|
|
123
|
+
### LLM timeout
|
|
124
|
+
|
|
125
|
+
If commit message generation times out, increase `llm_timeout_ms` in config:
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"llm_timeout_ms": 30000
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Large diffs
|
|
133
|
+
|
|
134
|
+
If diffs are truncated, increase `max_diff_chars`:
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"max_diff_chars": 8000
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Workspace Guide
|
|
142
|
+
|
|
143
|
+
See `SKILL.md` bundled with this package for detailed GitButler workspace commands, multi-agent safety rules, and known issues.
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
MIT
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create GitButler branch from changes and commit
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Create GitButler Branch and Commit
|
|
6
|
+
|
|
7
|
+
Analyze modified files, create/reuse a `but` branch with a meaningful name, format code, and commit changes.
|
|
8
|
+
|
|
9
|
+
## Delegation
|
|
10
|
+
|
|
11
|
+
Delegate change analysis and commit-message drafting; keep formatting and `but commit --changes` execution in the main agent.
|
|
12
|
+
Flow: Subagent (analyze/summarize) -> Main agent (decide/execute).
|
|
13
|
+
|
|
14
|
+
## Additional Instructions
|
|
15
|
+
|
|
16
|
+
$ARGUMENTS
|
|
17
|
+
|
|
18
|
+
## Instructions
|
|
19
|
+
|
|
20
|
+
### Step 1: Sync and check state
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
but pull
|
|
24
|
+
but status --json -f
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Review the output:
|
|
28
|
+
- Identify **unassigned changes** (in `zz` or uncommitted)
|
|
29
|
+
- Identify which files YOU modified (if unsure, list them and ask)
|
|
30
|
+
- Check if an existing branch already matches this work
|
|
31
|
+
|
|
32
|
+
### Step 2: Decide branch strategy
|
|
33
|
+
|
|
34
|
+
**If changes are already on a named branch** (not `zz`):
|
|
35
|
+
- Reuse that branch, skip to Step 4
|
|
36
|
+
|
|
37
|
+
**If changes are unassigned** (in `zz`):
|
|
38
|
+
- Analyze the modified files to understand the scope
|
|
39
|
+
- Classify: `feat/`, `fix/`, `chore/`, `refactor/`, `docs/`
|
|
40
|
+
- Generate descriptive branch name (e.g., `feat/add-user-settings`)
|
|
41
|
+
|
|
42
|
+
**If an existing branch matches the work:**
|
|
43
|
+
- ASK user whether to reuse it or create new
|
|
44
|
+
|
|
45
|
+
### Step 3: Create branch and assign changes (if needed)
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
but branch new <branch-name>
|
|
49
|
+
but status --json -f
|
|
50
|
+
but stage <file-id> <branch-name>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Repeat staging for each unassigned file that belongs to this work.
|
|
54
|
+
|
|
55
|
+
### Step 4: Format code
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
bun run format
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Step 5: Get change IDs and commit
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
but status --json -f
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Collect the file/hunk IDs that belong to this branch, then commit:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
but commit <branch> -m "<type>(<scope>): <description>" --changes <id>,<id>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Commit message rules:**
|
|
74
|
+
- Use conventional commits: `feat:`, `fix:`, `chore:`, `refactor:`, `docs:`, `test:`
|
|
75
|
+
- Include scope when clear (e.g., `feat(auth):`, `fix(ui):`)
|
|
76
|
+
- Short description (max 72 chars)
|
|
77
|
+
- Describe WHAT and WHY, not HOW
|
|
78
|
+
|
|
79
|
+
If the pre-commit hook fails on YOUR changes, fix the code and retry.
|
|
80
|
+
If the hook fails on pre-existing errors, run `bun run format` and use `--no-hooks`.
|
|
81
|
+
|
|
82
|
+
### Step 6: Verify
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
but status --json -f
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Confirm:
|
|
89
|
+
- Branch exists with correct name
|
|
90
|
+
- Changes are committed
|
|
91
|
+
- No unrelated files were committed
|
|
92
|
+
|
|
93
|
+
Report: "Branch `<branch-name>` created. Committed: `<commit-message>`"
|
|
94
|
+
|
|
95
|
+
## Constraints
|
|
96
|
+
|
|
97
|
+
- **NEVER commit without `--changes`** — this prevents committing other agents' work
|
|
98
|
+
- **NEVER discard changes** in `zz` that you didn't create
|
|
99
|
+
- **NEVER move files** that don't belong to current work
|
|
100
|
+
- **ALWAYS run `bun run format`** before committing
|
|
101
|
+
- If unsure which files belong, **ASK the user**
|
|
102
|
+
|
|
103
|
+
## State
|
|
104
|
+
|
|
105
|
+
!`but status --json -f 2>/dev/null || echo "GitButler not active"`
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Clean up empty or orphaned GitButler branches
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# GitButler Branch Garbage Collection
|
|
6
|
+
|
|
7
|
+
Identify and remove empty or orphaned `ge-branch-*` branches that have accumulated from past sessions.
|
|
8
|
+
|
|
9
|
+
## Additional Instructions
|
|
10
|
+
|
|
11
|
+
$ARGUMENTS
|
|
12
|
+
|
|
13
|
+
## Instructions
|
|
14
|
+
|
|
15
|
+
### Step 1: Survey current branches
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
but status --json -f
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Review the output and categorize branches:
|
|
22
|
+
|
|
23
|
+
- **Empty branches**: `ge-branch-*` with 0 commits and 0 assigned changes — safe to remove
|
|
24
|
+
- **Orphaned branches**: `ge-branch-*` with commits but no recent activity — list for user review
|
|
25
|
+
- **Active branches**: branches with assigned changes or recent commits — DO NOT touch
|
|
26
|
+
- **User-named branches**: branches NOT matching `ge-branch-*` — DO NOT touch
|
|
27
|
+
|
|
28
|
+
### Step 2: Report findings
|
|
29
|
+
|
|
30
|
+
Present a summary table:
|
|
31
|
+
|
|
32
|
+
| Branch | Commits | Changes | Status | Action |
|
|
33
|
+
|--------|---------|---------|--------|--------|
|
|
34
|
+
|
|
35
|
+
### Step 3: Clean up empty branches
|
|
36
|
+
|
|
37
|
+
For each empty `ge-branch-*` branch (0 commits, 0 changes):
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
but unapply <branch-cli-id>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Report each cleanup result.
|
|
44
|
+
|
|
45
|
+
### Step 4: Handle orphaned branches
|
|
46
|
+
|
|
47
|
+
For orphaned `ge-branch-*` branches (has commits but appears stale):
|
|
48
|
+
|
|
49
|
+
- List them with their last commit message
|
|
50
|
+
- Ask the user which ones to remove
|
|
51
|
+
- Only remove explicitly approved branches
|
|
52
|
+
|
|
53
|
+
### Safety Rules
|
|
54
|
+
|
|
55
|
+
- NEVER remove branches that are NOT `ge-branch-*` pattern
|
|
56
|
+
- NEVER remove branches with assigned changes
|
|
57
|
+
- NEVER remove branches without user confirmation (except empty ones)
|
|
58
|
+
- If `but unapply` fails, log the error and continue with the next branch
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create GitButler branch, commit, push, open PR, and monitor CI with auto-fix
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Create GitButler Branch, PR, and Monitor CI
|
|
6
|
+
|
|
7
|
+
Full workflow: analyze changes → create/reuse branch → commit → push → create PR → monitor CI → auto-fix failures and review comments.
|
|
8
|
+
|
|
9
|
+
## Delegation
|
|
10
|
+
|
|
11
|
+
Delegate PR-state and CI-failure analysis; keep branch writes, pushes, and PR updates in the main agent.
|
|
12
|
+
Flow: Subagent (analyze/summarize) -> Main agent (decide/execute).
|
|
13
|
+
|
|
14
|
+
## Additional Instructions
|
|
15
|
+
|
|
16
|
+
$ARGUMENTS
|
|
17
|
+
|
|
18
|
+
## Instructions
|
|
19
|
+
|
|
20
|
+
### Step 1: Sync and check state
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
but pull
|
|
24
|
+
but status --json -f
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Review the output:
|
|
28
|
+
- Identify **unassigned changes** (in `zz` or uncommitted)
|
|
29
|
+
- Identify which files YOU modified (if unsure, list them and ask)
|
|
30
|
+
- Check if an existing branch already matches this work
|
|
31
|
+
|
|
32
|
+
### Step 2: Decide branch strategy
|
|
33
|
+
|
|
34
|
+
**If changes are already on a named branch** (not `zz`):
|
|
35
|
+
- Reuse that branch, skip to Step 4
|
|
36
|
+
- Check if branch already has a PR (Step 6 will handle this)
|
|
37
|
+
|
|
38
|
+
**If changes are unassigned** (in `zz`):
|
|
39
|
+
- Analyze the modified files to understand the scope
|
|
40
|
+
- Classify: `feat/`, `fix/`, `chore/`, `refactor/`, `docs/`
|
|
41
|
+
- Generate descriptive branch name (e.g., `feat/add-user-settings`)
|
|
42
|
+
|
|
43
|
+
**If an existing branch matches the work:**
|
|
44
|
+
- ASK user whether to reuse it or create new
|
|
45
|
+
|
|
46
|
+
### Step 3: Create branch and assign changes (if needed)
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
but branch new <branch-name>
|
|
50
|
+
but status --json -f
|
|
51
|
+
but stage <file-id> <branch-name>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Repeat staging for each unassigned file that belongs to this work.
|
|
55
|
+
|
|
56
|
+
### Step 4: Format and validate
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
bun run format
|
|
60
|
+
bun run check
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Fix any issues found by `bun run check` before proceeding. Re-run until clean.
|
|
64
|
+
|
|
65
|
+
### Step 5: Commit
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
but status --json -f
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Collect the file/hunk IDs that belong to this branch, then commit:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
but commit <branch> -m "<type>(<scope>): <description>" --changes <id>,<id>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Commit message rules:**
|
|
78
|
+
- Conventional commits: `feat:`, `fix:`, `chore:`, `refactor:`, `docs:`, `test:`
|
|
79
|
+
- Include scope when clear (e.g., `feat(auth):`, `fix(ui):`)
|
|
80
|
+
- Short description (max 72 chars)
|
|
81
|
+
|
|
82
|
+
If format changes were generated, absorb them:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
but status --json -f
|
|
86
|
+
but absorb <format-file-id>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Step 6: Push and create/update PR
|
|
90
|
+
|
|
91
|
+
Push the branch:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
but push <branch>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Check if a PR already exists for this branch (must specify `--head` in GitButler workspace):
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
bun run gh-tool pr view --head <branch> 2>/dev/null
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**If no PR exists**, create one:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
but pr new <branch> -t
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Or with a custom message for more control:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
but pr new <branch> -m "<PR title>
|
|
113
|
+
|
|
114
|
+
## Summary
|
|
115
|
+
<1-2 sentences>
|
|
116
|
+
|
|
117
|
+
## Changes
|
|
118
|
+
- <bullet list>"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**If PR already exists**, update it:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
bun run gh-tool pr edit <pr_number> --title "<title>" --body "<body>"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Get the PR number for monitoring:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
bun run gh-tool pr view --head <branch> --json number -q .number
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Step 7: Monitor CI checks
|
|
134
|
+
|
|
135
|
+
Inform the user: "PR created/updated. Monitoring CI checks... (say 'stop' to exit)"
|
|
136
|
+
|
|
137
|
+
#### 7.1 Wait for checks
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
bun run gh-tool pr checks --pr <pr_number> --watch --fail-fast > /dev/null 2>&1; echo $?
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Exit codes:**
|
|
144
|
+
- `0` - All checks passed
|
|
145
|
+
- `1` - One or more checks failed
|
|
146
|
+
|
|
147
|
+
#### 7.2 Handle check results
|
|
148
|
+
|
|
149
|
+
**If checks failed (exit code 1):**
|
|
150
|
+
|
|
151
|
+
1. Get failed check details:
|
|
152
|
+
```bash
|
|
153
|
+
bun run gh-tool pr checks-failed --pr <pr_number>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
2. Analyze the failure, fix locally
|
|
157
|
+
3. Run `bun run check` to validate
|
|
158
|
+
4. Format, commit, and push the fix:
|
|
159
|
+
```bash
|
|
160
|
+
bun run format
|
|
161
|
+
but status --json -f
|
|
162
|
+
but commit <branch> -m "fix: resolve CI check failures" --changes <id>,<id>
|
|
163
|
+
but push <branch>
|
|
164
|
+
```
|
|
165
|
+
5. **Go back to Step 7.1**
|
|
166
|
+
|
|
167
|
+
**If checks passed (exit code 0):**
|
|
168
|
+
|
|
169
|
+
1. Check for review comments:
|
|
170
|
+
```bash
|
|
171
|
+
bun run gh-tool pr threads --pr <pr_number> --unresolved-only
|
|
172
|
+
bun run gh-tool pr issue-comments-latest --pr <pr_number> --author claude --body-contains "Claude Code Review"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
2. **If unresolved review comments exist:**
|
|
176
|
+
- Inform user: "CI passed but review comments found. Processing..."
|
|
177
|
+
- **Execute the pr-fix-comments workflow** (Steps 3-7 from pr-fix-comments command):
|
|
178
|
+
- Analyze each comment
|
|
179
|
+
- Apply valid fixes
|
|
180
|
+
- Reply to each comment and resolve threads
|
|
181
|
+
- Run `bun run check`
|
|
182
|
+
- Commit and push fixes using `but commit <branch> --changes`
|
|
183
|
+
- **Go back to Step 7.1** to re-monitor
|
|
184
|
+
|
|
185
|
+
3. **If no comments:**
|
|
186
|
+
- Inform user: "All checks passed and no review comments. PR is ready for review!"
|
|
187
|
+
- Exit
|
|
188
|
+
|
|
189
|
+
#### 7.3 Loop exit conditions
|
|
190
|
+
|
|
191
|
+
Exit when:
|
|
192
|
+
- All checks pass AND no unresolved review comments
|
|
193
|
+
- User says "stop"
|
|
194
|
+
- Maximum 5 iterations reached (ask user to continue)
|
|
195
|
+
|
|
196
|
+
## PR Body Format
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
## Summary
|
|
200
|
+
<1-2 sentences>
|
|
201
|
+
|
|
202
|
+
## Changes
|
|
203
|
+
- <bullet list>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Constraints
|
|
207
|
+
|
|
208
|
+
- **NEVER commit without `--changes`** — prevents committing other agents' work
|
|
209
|
+
- **NEVER discard changes** in `zz` that you didn't create
|
|
210
|
+
- **NEVER move files** that don't belong to current work
|
|
211
|
+
- **ALWAYS run `bun run format`** before committing
|
|
212
|
+
- **ALWAYS run `bun run check`** before first push
|
|
213
|
+
- If unsure which files belong, **ASK the user**
|
|
214
|
+
|
|
215
|
+
## State
|
|
216
|
+
|
|
217
|
+
!`but status --json -f 2>/dev/null || echo "GitButler not active"`
|
|
218
|
+
|
|
219
|
+
### Existing PR
|
|
220
|
+
!`bun run gh-tool pr view 2>/dev/null || echo "No PR found for current branch"`
|
|
221
|
+
|||||||
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create a GitButler branch from current changes with a descriptive name
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Create GitButler Branch
|
|
6
|
+
|
|
7
|
+
Analyze all modified/unassigned files, create a new `but` branch with a meaningful name, and assign changes to it.
|
|
8
|
+
|
|
9
|
+
## Delegation
|
|
10
|
+
|
|
11
|
+
Delegate change-scope analysis and branch-name proposal; keep branch creation and staging actions in the main agent.
|
|
12
|
+
Flow: Subagent (analyze/summarize) -> Main agent (decide/execute).
|
|
13
|
+
|
|
14
|
+
## Additional Instructions
|
|
15
|
+
|
|
16
|
+
$ARGUMENTS
|
|
17
|
+
|
|
18
|
+
## Instructions
|
|
19
|
+
|
|
20
|
+
### Step 1: Sync and check state
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
but pull
|
|
24
|
+
but status --json -f
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Review the output:
|
|
28
|
+
- Identify **unassigned changes** (in `zz` or uncommitted)
|
|
29
|
+
- Identify which files YOU modified (if unsure, list them and ask)
|
|
30
|
+
- Check if an existing branch already matches this work
|
|
31
|
+
|
|
32
|
+
### Step 2: Analyze changes and generate branch name
|
|
33
|
+
|
|
34
|
+
Look at the modified files and understand the scope of changes:
|
|
35
|
+
|
|
36
|
+
1. Read the changed files to understand what was done
|
|
37
|
+
2. Classify the change type: `feat/`, `fix/`, `chore/`, `refactor/`, `docs/`
|
|
38
|
+
3. Generate a descriptive branch name (e.g., `feat/add-user-settings`, `fix/auth-token-refresh`)
|
|
39
|
+
|
|
40
|
+
**Branch name rules:**
|
|
41
|
+
- Use conventional prefix: `feat/`, `fix/`, `chore/`, `refactor/`, `docs/`
|
|
42
|
+
- Use kebab-case after prefix
|
|
43
|
+
- Keep it short but descriptive (max 50 chars total)
|
|
44
|
+
- Must describe WHAT the changes do, not WHERE they are
|
|
45
|
+
|
|
46
|
+
### Step 3: Create branch and assign changes
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
but branch new <branch-name>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Then check status to get file IDs:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
but status --json -f
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
If files are unassigned (in `zz`), stage them to the new branch:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
but stage <file-id> <branch-name>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Repeat for each unassigned file that belongs to this work.
|
|
65
|
+
|
|
66
|
+
### Step 4: Verify
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
but status --json -f
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Confirm:
|
|
73
|
+
- Branch exists with correct name
|
|
74
|
+
- All relevant files are assigned to the branch
|
|
75
|
+
- No unrelated files were moved
|
|
76
|
+
|
|
77
|
+
Report: "Branch `<branch-name>` created with N files assigned."
|
|
78
|
+
|
|
79
|
+
## Constraints
|
|
80
|
+
|
|
81
|
+
- **NEVER discard changes** in `zz` that you didn't create
|
|
82
|
+
- **NEVER move files** that don't belong to current work
|
|
83
|
+
- If unsure which files belong to the branch, **ASK the user**
|
|
84
|
+
- If a matching branch already exists, **ASK** whether to reuse it or create a new one
|
|
85
|
+
|
|
86
|
+
## State
|
|
87
|
+
|
|
88
|
+
!`but status --json -f 2>/dev/null || echo "GitButler not active"`
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-update check for opencode-gitbutler.
|
|
3
|
+
*
|
|
4
|
+
* Queries the npm registry for the latest published version and
|
|
5
|
+
* returns an update notification if a newer version is available.
|
|
6
|
+
*
|
|
7
|
+
* Design constraints:
|
|
8
|
+
* - Never throws — all fetch/parse failures return null.
|
|
9
|
+
* - No external semver dependency — uses simple numeric comparison.
|
|
10
|
+
* - Non-blocking — callers should fire-and-forget.
|
|
11
|
+
* - Respects config.auto_update === false to disable checks.
|
|
12
|
+
*/
|
|
13
|
+
export type UpdateInfo = {
|
|
14
|
+
current: string;
|
|
15
|
+
latest: string;
|
|
16
|
+
updateAvailable: boolean;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Check the npm registry for a newer version of opencode-gitbutler.
|
|
20
|
+
*
|
|
21
|
+
* @returns UpdateInfo if the check succeeds, null on any failure.
|
|
22
|
+
*/
|
|
23
|
+
export declare function checkForUpdate(currentVersion: string): Promise<UpdateInfo | null>;
|
|
24
|
+
export type AutoUpdateConfig = {
|
|
25
|
+
currentVersion: string;
|
|
26
|
+
auto_update?: boolean;
|
|
27
|
+
};
|
|
28
|
+
export type AutoUpdateHook = {
|
|
29
|
+
onSessionCreated: () => Promise<string | null>;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Create an auto-update hook that checks once per plugin lifecycle.
|
|
33
|
+
*
|
|
34
|
+
* The returned `onSessionCreated` should be called from the event handler
|
|
35
|
+
* when a new root session is created. It fires the update check on the
|
|
36
|
+
* first invocation and caches the result; subsequent calls return null.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createAutoUpdateHook(config: AutoUpdateConfig): AutoUpdateHook;
|
|
39
|
+
//# sourceMappingURL=auto-update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-update.d.ts","sourceRoot":"","sources":["../src/auto-update.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAgDF;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA6B5B;AASD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,gBAAgB,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAChD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,gBAAgB,GACvB,cAAc,CAqChB"}
|