@senad-d/branchme 0.1.3 → 0.1.5
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 +6 -4
- package/README.md +56 -25
- package/SECURITY.md +24 -7
- package/docs/SMOKE_TEST.md +8 -6
- package/docs/STRUCTURE.md +27 -17
- package/docs/TUI_CAPTURE.md +10 -7
- package/package.json +3 -3
- package/src/commands/branchme-command.ts +8 -5
- package/src/constants.ts +9 -0
- package/src/extension.ts +2 -0
- package/src/git-context.ts +363 -0
- package/src/git.ts +335 -24
- package/src/github.ts +305 -2
- package/src/tools/branchme-tools.ts +39 -21
- package/src/types.ts +57 -0
- package/src/ui/branchme-panel.ts +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
## 0.1.0 - Unreleased
|
|
4
4
|
|
|
5
5
|
- Implemented the `branchme` informational slash command with help aliases.
|
|
6
|
-
- Added strict BranchMe tools: `branch_status`, `change_branch`, `create_branch`, `push_branch`, and `pull_request`.
|
|
7
|
-
- Added argv-style git helpers for repository status, branch validation/creation/switching, clean-worktree preflight, upstream detection, and current-branch push/publish.
|
|
6
|
+
- Added strict BranchMe tools: `branch_status`, `change_branch`, `pull_branch`, `create_branch`, `push_branch`, and `pull_request`.
|
|
7
|
+
- Added argv-style git helpers for repository status, branch validation/creation/switching, clean-worktree preflight, upstream detection, fast-forward-only current-branch pull, and current-branch push/publish.
|
|
8
8
|
- Added GitHub repository resolution, environment-token and local `.env` token fallback handling, REST pull request creation, response validation, and token redaction.
|
|
9
|
-
- Added
|
|
10
|
-
-
|
|
9
|
+
- Added bounded automatic Git context before each agent run with branch/upstream state, working-tree counts and unstaged paths, authenticated related-open-PR lookup, and recent commits.
|
|
10
|
+
- Expanded `branch_status` into a shared, explicit, read-only context refresh for state that may change during a run.
|
|
11
|
+
- Added unit tests with mocked `pi.exec` and `fetch` for Git context collection and prompt safety, git helpers, GitHub helpers, command behavior, tool schemas, prompt metadata, and extension registration.
|
|
12
|
+
- Updated public documentation for automatic context behavior, authenticated lookup and prompt-insertion security boundaries, package structure, and validation commands.
|
package/README.md
CHANGED
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
13
13
|
Current-repository branch and pull request tools for <a href="https://pi.dev">pi</a>.
|
|
14
|
-
<br />Inspect branch state, switch/create branches, push, and open GitHub PRs from pi prompts.
|
|
14
|
+
<br />Inspect branch state, switch/create/update branches, push, and open GitHub PRs from pi prompts.
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
BranchMe is a Pi extension for safe branch workflow automation. It adds an informational `/branchme` command and
|
|
19
|
+
BranchMe is a Pi extension for safe branch workflow automation. Before each agent run, it appends a bounded, read-only snapshot of the current Git repository to the system prompt. It also adds an informational `/branchme` command and six agent-callable tools that explicitly refresh state, switch to an existing local branch, fast-forward the clean current branch from its upstream, create a branch from the current `HEAD`, push the current branch, and create a GitHub pull request.
|
|
20
20
|
|
|
21
21
|
<table align="center">
|
|
22
22
|
<tr>
|
|
@@ -29,12 +29,13 @@ BranchMe is a Pi extension for safe branch workflow automation. It adds an infor
|
|
|
29
29
|
</tr>
|
|
30
30
|
</table>
|
|
31
31
|
|
|
32
|
-
- **
|
|
33
|
-
- **
|
|
32
|
+
- **Context-aware:** every agent run starts with bounded branch, working-tree, related-PR, and recent-commit metadata; repository metadata is untrusted data, not instructions.
|
|
33
|
+
- **Current-repository only:** Git and GitHub operations are scoped to the checkout where pi is running; `pull_branch` updates only the clean current branch from its configured upstream.
|
|
34
|
+
- **Commit-safe:** context collection is read-only, and BranchMe never stages files, creates commits, generates commit messages, rebases, creates merge commits, resets, or edits files directly.
|
|
34
35
|
- **Strict tools:** tool schemas reject extra properties such as `force`, `stash`, `discard`, `owner`, `repo`, `path`, or `baseRef`.
|
|
35
36
|
- **PR-ready:** create GitHub pull requests from existing local branches after verifying the `headBranch` matches GitHub and the base is visible, with explicit PR fields and `GITHUB_TOKEN` or `GH_TOKEN` from the process environment or a local `.env` fallback.
|
|
36
37
|
|
|
37
|
-
> **Security:** pi packages run with your full system permissions. BranchMe
|
|
38
|
+
> **Security:** pi packages run with your full system permissions. BranchMe runs local `git` commands, may make an automatic authenticated GitHub request to find a related open pull request, can switch/create branches and push the current branch, and can create GitHub pull requests. Read [`SECURITY.md`](SECURITY.md).
|
|
38
39
|
|
|
39
40
|
## Table of Contents
|
|
40
41
|
|
|
@@ -70,21 +71,24 @@ Inside pi:
|
|
|
70
71
|
/branchme help
|
|
71
72
|
```
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
A normal prompt can use the automatic start-of-run snapshot without a tool call. Ask for an explicit refresh when needed, for example:
|
|
74
75
|
|
|
75
76
|
```text
|
|
76
|
-
|
|
77
|
+
Refresh the repository state with branch_status, then create a branch named feature/update-docs with create_branch.
|
|
77
78
|
```
|
|
78
79
|
|
|
79
80
|
A typical BranchMe flow is:
|
|
80
81
|
|
|
81
|
-
1.
|
|
82
|
-
2.
|
|
83
|
-
3.
|
|
84
|
-
4.
|
|
85
|
-
5.
|
|
82
|
+
1. Use the automatic snapshot to understand state at the start of the agent run.
|
|
83
|
+
2. Use `branch_status` when you explicitly need fresh state, especially after a Git mutation in the same run.
|
|
84
|
+
3. Switch to the local base branch with `change_branch`.
|
|
85
|
+
4. Update it from its configured upstream with `pull_branch`, which requires a clean worktree and uses fast-forward-only semantics.
|
|
86
|
+
5. Create from the updated `HEAD` with `create_branch`.
|
|
87
|
+
6. Make edits and commit outside BranchMe.
|
|
88
|
+
7. Push the current branch with `push_branch`.
|
|
89
|
+
8. After `push_branch` completes and GitHub can see the branches, create a pull request with `pull_request`.
|
|
86
90
|
|
|
87
|
-
BranchMe is tool-based. The slash command is informational only and never changes branches, pushes, commits, stages, edits files, or opens pull requests.
|
|
91
|
+
BranchMe is tool-based. The slash command is informational only and never changes or updates branches, pushes, commits, stages, edits files, or opens pull requests.
|
|
88
92
|
|
|
89
93
|
---
|
|
90
94
|
|
|
@@ -98,6 +102,8 @@ BranchMe is tool-based. The slash command is informational only and never change
|
|
|
98
102
|
| Git | `pi install git:github.com/senad-d/branchme@<tag>` | Pin a tag or commit. |
|
|
99
103
|
| Local checkout | `pi --no-extensions -e .` | Develop or test this repository in isolation. |
|
|
100
104
|
|
|
105
|
+
Once loaded, BranchMe collects automatic Git context before each agent run. This happens for ordinary prompts; there is no `/branchme context` command and no additional tool to enable it.
|
|
106
|
+
|
|
101
107
|
Source checkout:
|
|
102
108
|
|
|
103
109
|
```bash
|
|
@@ -135,7 +141,7 @@ git remote set-url origin git@github.com:OWNER/REPO.git
|
|
|
135
141
|
export GITHUB_REPOSITORY=OWNER/REPO
|
|
136
142
|
```
|
|
137
143
|
|
|
138
|
-
For `pull_request`, set a token in the process environment before starting pi:
|
|
144
|
+
For automatic related-PR lookup and `pull_request`, set a token in the process environment before starting pi:
|
|
139
145
|
|
|
140
146
|
```bash
|
|
141
147
|
export GITHUB_TOKEN=github_pat_...
|
|
@@ -152,7 +158,7 @@ $EDITOR .env
|
|
|
152
158
|
pi
|
|
153
159
|
```
|
|
154
160
|
|
|
155
|
-
`push_branch`
|
|
161
|
+
`pull_branch` and `push_branch` use your normal Git remote credentials. BranchMe does not inject `GITHUB_TOKEN` into `git pull` or `git push`.
|
|
156
162
|
When the current branch already has an upstream, BranchMe pushes an explicit `HEAD:<upstream-branch-ref>` refspec to the configured upstream remote instead of relying on a bare `git push`.
|
|
157
163
|
Run `pull_request` only after `push_branch` has completed; `pull_request` preflights the GitHub `headBranch` and `baseBranch` before creating the PR and fails with retry guidance if a branch is not visible yet or the GitHub `headBranch` commit does not match the local branch.
|
|
158
164
|
|
|
@@ -160,15 +166,15 @@ Run `pull_request` only after `push_branch` has completed; `pull_request` prefli
|
|
|
160
166
|
|
|
161
167
|
## Configuration
|
|
162
168
|
|
|
163
|
-
BranchMe has no project config file. It reads process environment variables for GitHub pull request creation and optional repository boundary checks, with a local `.env` token fallback when no process token is set. Token lookup checks `process.env.GITHUB_TOKEN`, then `process.env.GH_TOKEN`; if neither is set, BranchMe reads `.env` from the verified git root and checks `GITHUB_TOKEN`, then `GH_TOKEN`.
|
|
169
|
+
BranchMe has no project config file. It reads process environment variables for automatic related-PR lookup, GitHub pull request creation, and optional repository boundary checks, with a local `.env` token fallback when no process token is set. Token lookup checks `process.env.GITHUB_TOKEN`, then `process.env.GH_TOKEN`; if neither is set, BranchMe reads `.env` from the verified git root and checks `GITHUB_TOKEN`, then `GH_TOKEN`.
|
|
164
170
|
|
|
165
171
|
| Variable | Meaning |
|
|
166
172
|
| --- | --- |
|
|
167
|
-
| `GITHUB_TOKEN` | Preferred token for `pull_request`; process environment first, then local `.env` fallback. |
|
|
168
|
-
| `GH_TOKEN` | Fallback token for `pull_request`; process environment first, then local `.env` fallback. |
|
|
173
|
+
| `GITHUB_TOKEN` | Preferred token for automatic related-PR lookup and `pull_request`; process environment first, then local `.env` fallback. |
|
|
174
|
+
| `GH_TOKEN` | Fallback token for automatic related-PR lookup and `pull_request`; process environment first, then local `.env` fallback. |
|
|
169
175
|
| `GITHUB_REPOSITORY=owner/repo` | Optional CI fallback and boundary check for the current GitHub repository; process environment only. |
|
|
170
176
|
|
|
171
|
-
BranchMe reads only `GITHUB_TOKEN` and `GH_TOKEN` from a small regular `.env` file; it rejects directories, symlinks, special files, and oversized files. BranchMe does not import other `.env` keys, read shell profiles, GitHub CLI credentials, or local credential stores. Token values are redacted from errors, tool content, and tool details.
|
|
177
|
+
BranchMe reads only `GITHUB_TOKEN` and `GH_TOKEN` from a small regular `.env` file; it rejects directories, symlinks, special files, and oversized files. BranchMe does not import other `.env` keys, read shell profiles, GitHub CLI credentials, or local credential stores. Token values are redacted from automatic context, errors, tool content, and tool details.
|
|
172
178
|
|
|
173
179
|
If local `origin` and `GITHUB_REPOSITORY` both resolve but disagree, `pull_request` fails closed.
|
|
174
180
|
|
|
@@ -191,31 +197,53 @@ Commands are informational only. BranchMe actions are performed by agent-callabl
|
|
|
191
197
|
|
|
192
198
|
| Tool | Schema | Behavior |
|
|
193
199
|
| --- | --- | --- |
|
|
194
|
-
| `branch_status` | `{}` |
|
|
200
|
+
| `branch_status` | `{}` | Explicitly refreshes the same bounded context used at agent start: repo root in structured details, branch/detached state, upstream and ahead/behind counts, working-tree counts and unstaged/untracked paths, related open PR, and recent commits. It is read-only. |
|
|
195
201
|
| `change_branch` | `{ "branchName": string }` | Validates `branchName`, requires `refs/heads/<branchName>` to exist locally, rejects dirty worktrees, and runs `git switch <branchName>`. |
|
|
202
|
+
| `pull_branch` | `{}` | Requires a clean current branch with a configured upstream and runs `git pull --ff-only --no-rebase --no-autostash <upstream-remote> <upstream-branch-ref>`; divergence fails without rebasing or creating a merge commit. |
|
|
196
203
|
| `create_branch` | `{ "branchName": string }` | Validates `branchName`, rejects existing local branches, and runs `git switch -c <branchName>` from current `HEAD`. |
|
|
197
204
|
| `push_branch` | `{}` | Pushes the current branch to its configured upstream remote with an explicit `HEAD:<upstream-branch-ref>` refspec, or publishes it with `git push --set-upstream origin <currentBranch>` when no upstream exists. |
|
|
198
205
|
| `pull_request` | `{ "headBranch": string, "baseBranch": string, "title": string, "body": string, "draft": boolean }` | Preflights GitHub branch visibility and verifies the GitHub `headBranch` commit matches the local branch, then creates a pull request in the resolved current repository via `POST /repos/{owner}/{repo}/pulls`; branch refs must exist locally and cannot use `owner:branch`. |
|
|
199
206
|
|
|
200
|
-
All schemas reject additional properties. `change_branch` never accepts `baseRef`, `force`, `stash`, `discard`, `create`, `owner`, `repo`, or path inputs. `pull_request` never accepts `owner`, `repo`, or owner-prefixed branch refs; BranchMe resolves the repository from local `origin` and/or matching `GITHUB_REPOSITORY`.
|
|
207
|
+
All schemas reject additional properties. `change_branch` never accepts `baseRef`, `force`, `stash`, `discard`, `create`, `owner`, `repo`, or path inputs. `pull_branch` has a strict empty schema and never accepts a branch, remote, force, or rebase option. `pull_request` never accepts `owner`, `repo`, or owner-prefixed branch refs; BranchMe resolves the repository from local `origin` and/or matching `GITHUB_REPOSITORY`.
|
|
201
208
|
|
|
202
209
|
---
|
|
203
210
|
|
|
204
211
|
## Workflow and Boundaries
|
|
205
212
|
|
|
213
|
+
### Automatic context and freshness
|
|
214
|
+
|
|
215
|
+
Before each agent run, BranchMe appends an **Automatic Git Context** snapshot to the existing system prompt. The snapshot contains these fields in order:
|
|
216
|
+
|
|
217
|
+
- current branch or detached `HEAD`, plus upstream and ahead/behind counts when available;
|
|
218
|
+
- working-tree state and staged, unstaged, and untracked counts;
|
|
219
|
+
- up to 20 unstaged or untracked change entries with Git status, path, and original path for renames/copies;
|
|
220
|
+
- related open PR status and, when found, its number, title, repository, head/base branches, URL, state, and draft flag;
|
|
221
|
+
- up to 5 recent commits with short hash, date, and subject.
|
|
222
|
+
|
|
223
|
+
Collection defaults are a 5-second timeout per local Git command, a 4-second related-PR lookup timeout, at most 512 characters per metadata value, and at most 4,000 characters for the rendered snapshot. GitHub response bodies are limited to 64 KiB. The formatter can further shorten values or omit entries to stay within the total limit.
|
|
224
|
+
|
|
225
|
+
The snapshot is fresh at agent start but is not live. A branch switch, pull, commit, file change, push, or other mutation later in the same run can make it stale. `branch_status` performs an explicit current-state refresh through the same shared collector and remains read-only; it does not mutate files, Git state, or GitHub state.
|
|
226
|
+
|
|
227
|
+
Related-PR metadata does not come from Git alone. When repository, branch, and credentials resolve, automatic collection and explicit `branch_status` may make an authenticated `GET /repos/{owner}/{repo}/pulls?state=open&head={owner}:{branch}&per_page=1` request. Without a token there is no unauthenticated fallback or GitHub request; the PR field is reported as unavailable while local Git context remains usable.
|
|
228
|
+
|
|
229
|
+
Repository paths, commit subjects, branch names, and PR titles are treated as untrusted metadata. BranchMe redacts token values, escapes control characters, quotes and bounds values before prompt insertion, and never captures diffs or file contents. Staged files contribute only to the staged count; the path list is limited to unstaged and untracked entries.
|
|
230
|
+
|
|
206
231
|
Use BranchMe from pi prompts or automation that drives pi with explicit tool calls:
|
|
207
232
|
|
|
208
233
|
```text
|
|
209
234
|
Use branch_status.
|
|
210
|
-
|
|
235
|
+
Switch to the base branch with change_branch, then use pull_branch after the switch completes.
|
|
236
|
+
Create branch feature/docs-refresh from the updated current HEAD with create_branch.
|
|
211
237
|
Push the current branch with push_branch.
|
|
212
238
|
After push_branch completes, create a draft pull request from feature/docs-refresh to main titled "Refresh docs" with this body: "...".
|
|
213
239
|
```
|
|
214
240
|
|
|
215
241
|
BranchMe operates only on the repository where pi is running:
|
|
216
242
|
|
|
243
|
+
- Automatic collection and `branch_status` run bounded, read-only Git commands from the verified git root.
|
|
217
244
|
- Git commands use `pi.exec("git", args, { cwd, signal, timeout })` with argv arrays; repository mutations run from the verified git root.
|
|
218
245
|
- `change_branch` switches only to existing local branches and has no `force`, `stash`, `discard`, remote, or path input.
|
|
246
|
+
- `pull_branch` requires a clean worktree and configured upstream, updates only the current branch with `git pull --ff-only --no-rebase --no-autostash`, and has no branch, remote, force, or rebase input.
|
|
219
247
|
- `create_branch` creates from the current `HEAD` only and has no `baseRef` input.
|
|
220
248
|
- `push_branch` pushes only the current branch, uses no bare upstream `git push`, and has no `branchName` input.
|
|
221
249
|
- `pull_request` creates PRs only for the resolved current GitHub repository, requires `headBranch` and `baseBranch` to exist locally, requires the GitHub `headBranch` commit to match the local branch, queues behind in-flight same-repository git mutation windows when possible, and rejects `owner:branch` head refs.
|
|
@@ -264,11 +292,14 @@ Ensure the token and Git credentials have permission for the branch and pull req
|
|
|
264
292
|
| Problem | Try |
|
|
265
293
|
| --- | --- |
|
|
266
294
|
| Not a git repository | Start pi from inside a git checkout. |
|
|
267
|
-
| Detached `HEAD` | Use `change_branch` to switch to an existing local branch, or checkout a branch before `create_branch
|
|
295
|
+
| Detached `HEAD` | Use `change_branch` to switch to an existing local branch, or checkout a branch before `pull_branch`, `create_branch`, or `push_branch`. |
|
|
268
296
|
| Branch already exists | Choose a new local branch name for `create_branch`, or use `change_branch` to switch to it. |
|
|
269
297
|
| Branch does not exist locally | Create a local branch first; `change_branch` does not checkout remote branches. |
|
|
270
|
-
| Dirty worktree before branch switch | Commit, stash, or discard changes outside BranchMe before using `change_branch`. |
|
|
298
|
+
| Dirty worktree before branch switch or pull | Commit, stash, or discard changes outside BranchMe before using `change_branch` or `pull_branch`. |
|
|
299
|
+
| Pull has no upstream | Configure the current branch upstream outside BranchMe, then retry `pull_branch`. |
|
|
300
|
+
| Pull is not a fast-forward | Reconcile the divergent branch outside BranchMe; `pull_branch` never rebases, force-updates, or creates a merge commit. |
|
|
271
301
|
| Push fails | Confirm the current branch is correct and your normal Git remote credentials can push. |
|
|
302
|
+
| Related PR is unavailable | Set `GITHUB_TOKEN` or `GH_TOKEN` before starting pi if related-PR context is wanted. Without a token, BranchMe keeps local context and intentionally makes no unauthenticated GitHub request. |
|
|
272
303
|
| PR auth fails | Set `GITHUB_TOKEN` or `GH_TOKEN` before starting pi, or copy `.env.example` to `.env` and fill in one token. |
|
|
273
304
|
| PR branch does not exist locally | Create or fetch/check out the local `headBranch` and `baseBranch` branches first; BranchMe does not use remote-only or cross-repository PR refs. |
|
|
274
305
|
| PR branch is not visible or is stale on GitHub | Run `push_branch`, wait for it to complete, then retry `pull_request`; do not batch `push_branch` and `pull_request` in the same assistant tool call. |
|
|
@@ -288,7 +319,7 @@ npm run check:pack
|
|
|
288
319
|
printf '/branchme help\n/quit\n' | pi --no-extensions -e .
|
|
289
320
|
```
|
|
290
321
|
|
|
291
|
-
Validation covers TypeScript typechecking, formatting checks, unit tests, package checks, checkout Pi runtime smoke, and package-content verification. The checkout smoke loads BranchMe through Pi, then uses a temporary verifier command to confirm all
|
|
322
|
+
Validation covers TypeScript typechecking, formatting checks, automatic context collection and prompt injection, mocked GitHub lookup, unit tests, package checks, checkout Pi runtime smoke, and package-content verification. The checkout smoke loads BranchMe through Pi, then uses a temporary verifier command to confirm all six BranchMe tools are visible through `pi.getAllTools()` with strict schemas and prompt metadata. Smoke-test notes are recorded in [`docs/SMOKE_TEST.md`](docs/SMOKE_TEST.md), and TUI/help captures are stored in [`docs/TUI_CAPTURE.md`](docs/TUI_CAPTURE.md).
|
|
292
323
|
|
|
293
324
|
Refresh TUI captures intentionally with:
|
|
294
325
|
|
package/SECURITY.md
CHANGED
|
@@ -17,21 +17,29 @@ Implemented git mutations are limited to:
|
|
|
17
17
|
|
|
18
18
|
- `change_branch`: `git switch <branchName>` after branch-name validation, local `refs/heads/<branchName>` verification, and clean-worktree preflight.
|
|
19
19
|
- `create_branch`: `git switch -c <branchName>` from current `HEAD` after branch-name validation and existing-branch checks.
|
|
20
|
+
- `pull_branch`: `git pull --ff-only --no-rebase --no-autostash <upstreamRemote> <upstreamBranchRef>` for the clean current branch after validating its configured upstream target.
|
|
20
21
|
- `push_branch`: `git push <upstreamRemote> HEAD:<upstreamBranchRef>` for the current branch when an upstream exists, or `git push --set-upstream origin <currentBranch>` when no upstream exists.
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
Before each agent run, BranchMe also runs bounded, read-only Git commands to collect branch/upstream/ahead-behind state, working-tree counts, up to 20 unstaged or untracked path entries, and up to 5 recent commits. The same collector runs when `branch_status` explicitly refreshes context. Collection does not run `switch`, `push`, `add`, `commit`, or any other mutation, and it never reads diffs or file contents.
|
|
24
|
+
|
|
25
|
+
Branch switching and fast-forward pulls can update working-tree files as normal Git behavior. Mutating branch operations for the same repository are serialized to avoid same-turn branch races. `pull_request` also uses the same repository queue around PR preflight and creation so it can wait behind an already-started same-repository mutation. BranchMe rejects dirty worktrees before `change_branch` and `pull_branch`. It does not force checkout, stash, stage files, create commits, reset, rebase, create merge commits, or edit files directly.
|
|
23
26
|
|
|
24
27
|
## Network behavior
|
|
25
28
|
|
|
26
|
-
|
|
29
|
+
`pull_branch` and `push_branch` contact the configured Git remote through the user's normal Git transport and credentials. They do not use or inject `GITHUB_TOKEN` or `GH_TOKEN`.
|
|
30
|
+
|
|
31
|
+
BranchMe's GitHub helpers use these REST API requests:
|
|
27
32
|
|
|
28
33
|
```text
|
|
34
|
+
GET https://api.github.com/repos/{owner}/{repo}/pulls?state=open&head={owner}:{currentBranch}&per_page=1
|
|
29
35
|
GET https://api.github.com/repos/{owner}/{repo}/branches/{headBranch}
|
|
30
36
|
GET https://api.github.com/repos/{owner}/{repo}/branches/{baseBranch}
|
|
31
37
|
POST https://api.github.com/repos/{owner}/{repo}/pulls
|
|
32
38
|
```
|
|
33
39
|
|
|
34
|
-
The
|
|
40
|
+
The first request is an automatic network boundary: it can run before each agent run and whenever `branch_status` explicitly refreshes context. It is a bounded, read-only lookup for one open pull request whose head is the current local branch (`per_page=1`), with a default 4-second timeout and a 64 KiB response-body limit. It is skipped when repository/branch resolution or authentication is unavailable, so BranchMe never makes an unauthenticated fallback request. Timeout, HTTP, network, malformed, and oversized-response failures become a safe unavailable state without exposing response bodies or raw network errors. Git alone is not used or claimed to provide PR metadata.
|
|
41
|
+
|
|
42
|
+
The branch preflight requests have no body. BranchMe uses the `headBranch` preflight response to compare GitHub's branch commit with the local branch commit before creating the PR. The PR request body contains only the explicit PR fields supplied to the tool: title, head branch, base branch, body, and draft flag. All GitHub response reads are bounded.
|
|
35
43
|
|
|
36
44
|
## Repository boundary
|
|
37
45
|
|
|
@@ -40,22 +48,31 @@ BranchMe operates on the current repository only.
|
|
|
40
48
|
- The GitHub repository is inferred from local `origin` and/or `GITHUB_REPOSITORY`.
|
|
41
49
|
- Tool inputs never accept filesystem paths, `owner`, `repo`, or owner-prefixed `owner:branch` PR refs.
|
|
42
50
|
- `change_branch` accepts only `branchName` and never creates branches, checks out remote branches, forces, stashes, or discards changes.
|
|
43
|
-
-
|
|
51
|
+
- `pull_branch` accepts no parameters, updates only the clean current branch from its configured upstream, and uses fast-forward-only semantics.
|
|
52
|
+
- If local `origin` and `GITHUB_REPOSITORY` both resolve but disagree, PR creation and related-PR lookup fail closed.
|
|
44
53
|
- PR branch inputs are validated as existing local branch-name refs; missing local branches and cross-repository `head` values are rejected before token lookup or any GitHub request.
|
|
45
54
|
- PR branch inputs must also be visible on GitHub before the PR is created, and `headBranch` must match the local branch commit; unpublished or stale `headBranch` values fail with guidance to run `push_branch`, wait for it to complete, and retry `pull_request`.
|
|
46
55
|
|
|
47
56
|
## Credentials
|
|
48
57
|
|
|
49
|
-
|
|
58
|
+
Git pull and push authentication is handled by the user's configured Git credential and transport setup. BranchMe never passes GitHub API tokens to Git commands.
|
|
59
|
+
|
|
60
|
+
`pull_request` and related-PR lookup check `process.env.GITHUB_TOKEN`, then `process.env.GH_TOKEN`. If neither process token is set, BranchMe reads a local `.env` file from the verified git root and checks:
|
|
50
61
|
|
|
51
62
|
- `GITHUB_TOKEN` (preferred)
|
|
52
63
|
- `GH_TOKEN` (fallback)
|
|
53
64
|
|
|
54
|
-
Only these two token keys are read from `.env`; other `.env` keys are ignored. The fallback uses async file I/O, requires `.env` to be a small regular file, and rejects directories, symlinks, special files, and oversized files. BranchMe does not read shell profiles, GitHub CLI credentials, or local credential stores. Token values are redacted from thrown errors, tool content, and tool details.
|
|
65
|
+
Only these two token keys are read from `.env`; other `.env` keys are ignored. The fallback uses async file I/O, requires `.env` to be a small regular file, and rejects directories, symlinks, special files, and oversized files. BranchMe does not read shell profiles, GitHub CLI credentials, or local credential stores. Token values are redacted from thrown errors, automatic context, tool content, and tool details.
|
|
66
|
+
|
|
67
|
+
## System prompt boundary
|
|
68
|
+
|
|
69
|
+
Automatic context is appended to Pi's system prompt before each agent run. Branch names, paths, Git status values, commit subjects, and GitHub PR metadata are repository-controlled, untrusted data and must never be interpreted as instructions. BranchMe redacts recognized token values, escapes control and format characters, quotes metadata, limits individual values to 512 characters by default, and limits the complete rendered snapshot to 4,000 characters. It further shortens values or omits entries when needed to enforce the total bound.
|
|
70
|
+
|
|
71
|
+
The automatic snapshot can become stale after a Git or filesystem mutation during the same run. `branch_status` is the explicit, read-only refresh path. Neither automatic collection nor `branch_status` captures diff hunks or file contents; staged paths are not listed, although the staged file count is included.
|
|
55
72
|
|
|
56
73
|
## Telemetry
|
|
57
74
|
|
|
58
|
-
BranchMe does not collect telemetry
|
|
75
|
+
BranchMe does not collect telemetry. Related-PR lookup sends only the resolved repository owner/name and current branch in the authenticated GitHub API URL. PR creation sends only the explicit GitHub pull request fields described above; BranchMe does not send diff contents, filenames, commit subjects, or local file contents to GitHub during context collection.
|
|
59
76
|
|
|
60
77
|
## Reporting vulnerabilities
|
|
61
78
|
|
package/docs/SMOKE_TEST.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# BranchMe Smoke Test Notes
|
|
2
2
|
|
|
3
|
-
Date: 2026-
|
|
3
|
+
Date: 2026-07-15
|
|
4
4
|
|
|
5
5
|
Validated from the repository checkout with no discovered extensions enabled.
|
|
6
6
|
|
|
@@ -17,21 +17,23 @@ pi --no-extensions -e .
|
|
|
17
17
|
|
|
18
18
|
## Automated smoke behavior
|
|
19
19
|
|
|
20
|
-
- `npm run smoke:pi` runs isolated checkout Pi processes from a temporary working directory: one with `pi --no-extensions -e <package> -e <temporary verifier>` and `/branchmeverify verify`, then one with `pi --no-extensions -e <package>` and `/branchme help`.
|
|
21
|
-
- The temporary
|
|
22
|
-
-
|
|
20
|
+
- `npm run smoke:pi` first runs isolated checkout Pi processes from a temporary non-Git working directory: one with `pi --no-extensions -e <package> -e <temporary verifier>` and `/branchmeverify verify`, then one with `pi --no-extensions -e <package>` and `/branchme help`.
|
|
21
|
+
- The temporary command verifier calls `pi.getAllTools()` after BranchMe loads and confirms `branch_status`, `change_branch`, `pull_branch`, `create_branch`, `push_branch`, and `pull_request` are active runtime tools with strict schemas, prompt guidelines, descriptions, and extension source metadata.
|
|
22
|
+
- A second temporary verifier registers a deterministic local smoke model, blocks `fetch`, and runs normal prompts through real Pi lifecycle handling. It verifies automatic no-tool Git context in a temporary repository, one real `branch_status` tool refresh after a verifier-created local change, safe credential-free related-PR status with no request, and non-Git startup fallback.
|
|
23
|
+
- The checkout command smoke accepts either `/branchme help` text or the read-only BranchMe status fallback as equivalent non-mutating command output.
|
|
23
24
|
- `npm run smoke:pi:packed` creates an npm tarball under a temporary directory, installs that tarball into a separate temporary package with `npm install --omit=dev`, and runs pi against the installed package instead of the source checkout.
|
|
24
25
|
- `npm run smoke:pi:packed` is the release gate for packaged runtime imports and required packaged files; `npm run release:check` and `node scripts/publish-npm.mjs` run it before publish, while everyday `npm run validate` keeps the faster checkout smoke.
|
|
25
26
|
- Both smoke runs disable discovered extensions, skills, prompt templates, themes, context files, persistent sessions, telemetry, startup network checks, and GitHub token environment variables.
|
|
26
27
|
- Both smoke runs are credential-free, allow documented credential variable names in help text, reject credential value patterns, do not call BranchMe mutation tools, and do not contact GitHub.
|
|
27
|
-
- Pi's documented `getAllTools()` metadata currently exposes parameter schemas and prompt guidelines, but not `promptSnippet
|
|
28
|
+
- Pi's documented `getAllTools()` metadata currently exposes parameter schemas and prompt guidelines, but not `promptSnippet`. The deterministic local smoke model exercises `branch_status` through Pi's normal model tool-call loop without provider or GitHub network access.
|
|
28
29
|
- Set `BRANCHME_SKIP_PI_SMOKE=1` to skip intentionally, or `BRANCHME_PI_BIN=/path/to/pi` to test a specific Pi binary for the checkout smoke.
|
|
29
30
|
- If no Pi binary is available, the checkout smoke script prints an explicit skip message; default CI installs the Pi dev dependency, so `npm run validate` exercises the real Pi loading path.
|
|
30
31
|
|
|
31
32
|
## Result
|
|
32
33
|
|
|
33
34
|
- `npm run validate` passed.
|
|
34
|
-
- `npm run smoke:pi` loaded BranchMe through Pi, verified all
|
|
35
|
+
- `npm run smoke:pi` loaded BranchMe through Pi, verified all six BranchMe tools through the real `pi.getAllTools()` runtime surface, and confirmed non-mutating BranchMe command output.
|
|
36
|
+
- The isolated Git-context prompt smoke observed the `before_agent_start` snapshot, answered branch and dirty-tree state without a tool call, refreshed a verifier-created local change through one real `branch_status` call, returned safe unavailable context without credentials or outside Git, and attempted no network request.
|
|
35
37
|
- `npm run smoke:pi:packed` packed BranchMe outside the repository, installed the artifact in a temporary production workspace, loaded the installed package through Pi, and confirmed non-mutating BranchMe command output.
|
|
36
38
|
- `npm run check:pack` confirmed the package contents are limited to public docs, images, source, license, package metadata, `.env.example`, and `tsconfig.json`.
|
|
37
39
|
- The isolated Pi smoke command loaded BranchMe and displayed BranchMe help or status output instead of template behavior.
|
package/docs/STRUCTURE.md
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
# BranchMe Structure Guide
|
|
2
2
|
|
|
3
|
-
BranchMe is a TypeScript Pi extension package for current-repository git branch, push, and GitHub pull request workflows.
|
|
3
|
+
BranchMe is a TypeScript Pi extension package for current-repository git branch update, push, and GitHub pull request workflows.
|
|
4
4
|
|
|
5
5
|
## Source layout
|
|
6
6
|
|
|
7
7
|
```text
|
|
8
8
|
src/
|
|
9
|
-
├── extension.ts # extension entry point; registers command and
|
|
10
|
-
├── constants.ts #
|
|
9
|
+
├── extension.ts # extension entry point; registers command, tools, and context hook
|
|
10
|
+
├── constants.ts # names plus Git, context, timeout, API, and output bounds
|
|
11
11
|
├── types.ts # serializable tool details and helper result types
|
|
12
|
+
├── git-context.ts # shared collector/formatter and before_agent_start prompt hook
|
|
12
13
|
├── commands/
|
|
13
14
|
│ └── branchme-command.ts # /branchme status/help command; informational only
|
|
14
15
|
├── tools/
|
|
15
|
-
│ └── branchme-tools.ts # branch_status/change_branch/create_branch/push_branch/pull_request registration
|
|
16
|
+
│ └── branchme-tools.ts # branch_status/change_branch/pull_branch/create_branch/push_branch/pull_request registration
|
|
16
17
|
├── git.ts # argv-style git helpers and per-repo workflow queue
|
|
17
18
|
├── github.ts # GitHub repo resolution, env/.env tokens, branch preflight, REST calls, redaction
|
|
18
19
|
└── ui/
|
|
@@ -21,33 +22,41 @@ src/
|
|
|
21
22
|
|
|
22
23
|
## Module boundaries
|
|
23
24
|
|
|
24
|
-
1. `src/extension.ts` stays small and
|
|
25
|
-
2. `src/
|
|
26
|
-
3. `src/
|
|
27
|
-
4. `src/
|
|
28
|
-
5. `src/
|
|
29
|
-
6. `src/
|
|
30
|
-
7. `src/
|
|
31
|
-
8. `src/
|
|
25
|
+
1. `src/extension.ts` stays small and registers the command, six tools, and one `before_agent_start` context hook.
|
|
26
|
+
2. `src/git-context.ts` owns the shared read-only collector, escaped/bounded formatter, automatic system-prompt append, and the current-state output used by `branch_status`.
|
|
27
|
+
3. `src/commands/branchme-command.ts` parses `/branchme`, `/branchme help`, `--help`, and `-h`; it never performs git or GitHub mutations and avoids raw stdout in JSON mode.
|
|
28
|
+
4. `src/tools/branchme-tools.ts` owns TypeBox schemas, prompt metadata, tool content, and safe structured details. `branch_status` delegates to the shared context collector for an explicit refresh.
|
|
29
|
+
5. `src/git.ts` owns current-repository git behavior: root detection, branch/upstream/ahead-behind inspection, working-tree parsing, recent-commit collection, branch validation, branch creation, existing-local-branch switching, clean-worktree preflight, fast-forward-only current-branch pull, current-branch push/publish, and the per-repository workflow queue.
|
|
30
|
+
6. `src/github.ts` owns GitHub `owner/repo` parsing, repository boundary checks, `GITHUB_TOKEN`/`GH_TOKEN` process-env and hardened git-root `.env` fallback resolution, authenticated related-open-PR lookup, PR branch-name syntax validation, GitHub branch visibility/commit preflight, PR REST calls, bounded response validation, and redacted errors.
|
|
31
|
+
7. `src/redaction.ts` owns shared credential redaction for Git, GitHub, and prompt-bound metadata.
|
|
32
|
+
8. `src/types.ts` keeps serializable details shared by helpers, context, and tools.
|
|
33
|
+
9. `src/ui/branchme-panel.ts` renders a compact status panel and clips lines to terminal width.
|
|
32
34
|
|
|
33
35
|
## Pi extension conventions
|
|
34
36
|
|
|
35
37
|
- No long-lived processes, watchers, timers, sockets, or background jobs start in the extension factory.
|
|
36
|
-
-
|
|
38
|
+
- A single `before_agent_start` handler synchronously collects a fresh snapshot for each agent run and appends it to the existing system prompt; failures degrade to bounded unavailable context rather than blocking startup.
|
|
39
|
+
- Slash commands are informational; tools perform branch update, push, and PR actions. There is no context command or seventh tool.
|
|
37
40
|
- Every tool uses a strict TypeBox object schema with `additionalProperties: false`.
|
|
38
41
|
- Every tool defines a description, `promptSnippet`, and tool-specific `promptGuidelines` that explicitly name the tool.
|
|
39
42
|
- Git commands use `pi.exec("git", args, { cwd, signal, timeout })` with argv arrays; repository mutations run from the verified git root and same-repository mutation/PR windows are serialized per repository.
|
|
40
43
|
- Tool details avoid token values and unbounded raw command/API output.
|
|
44
|
+
- Automatic and explicit context include branch/upstream/ahead-behind state, working-tree counts, up to 20 unstaged/untracked entries, related open PR state, and up to 5 recent commits. Metadata values default to 512 characters and rendered context to 4,000 characters.
|
|
41
45
|
- Pi core packages, including `@earendil-works/pi-tui` for key/width utilities, remain in `peerDependencies` with `"*"`.
|
|
42
46
|
|
|
43
47
|
## Security-sensitive areas
|
|
44
48
|
|
|
49
|
+
- Automatic context and `branch_status` share bounded, read-only collection. They run no mutations and capture repository metadata only—never diffs or file contents.
|
|
50
|
+
- Repository-controlled paths, branch names, commit subjects, and PR fields are escaped, quoted, redacted, bounded, and labeled untrusted before system-prompt insertion.
|
|
51
|
+
- Related-PR lookup may issue an authenticated `GET /pulls` before every agent run and on explicit refresh. It has a 4-second timeout and 64 KiB response limit, and makes no unauthenticated fallback request.
|
|
52
|
+
- The start-of-run snapshot may be stale after a mutation in that same run; `branch_status` is the explicit read-only refresh.
|
|
45
53
|
- `change_branch` mutates local HEAD and working-tree files only through `git switch <branchName>` for existing local branches after a clean-worktree preflight.
|
|
54
|
+
- `pull_branch` requires a clean worktree and configured upstream, then updates only the current branch with an explicit `git pull --ff-only --no-rebase --no-autostash <remote> <remote-ref>` command; divergence fails without a rebase or merge commit.
|
|
46
55
|
- `create_branch` mutates local branch/HEAD only with `git switch -c`.
|
|
47
56
|
- `push_branch` mutates remote refs only for the current branch and uses an explicit upstream remote/refspec instead of bare `git push` when an upstream exists.
|
|
48
57
|
- `pull_request` requires `headBranch` and `baseBranch` to exist locally, requires `headBranch` to match the GitHub-visible branch commit, queues behind already-started same-repository git mutation windows, makes GitHub REST API calls for the resolved current repository only, and rejects missing, owner-prefixed, or unsafe branch refs before token lookup or the request.
|
|
49
58
|
- `pull_request` reads `GITHUB_TOKEN` or `GH_TOKEN` from process environment first; only when neither process token is set does it read those token keys from a small regular `.env` file in the verified git root as a fallback.
|
|
50
|
-
- BranchMe does not force checkout, stash, stage, commit, directly edit files, read non-token `.env` keys, follow unsafe `.env` file types, depend on GitHub CLI, or collect telemetry.
|
|
59
|
+
- BranchMe does not force checkout, stash, stage, commit, rebase, create merge commits, directly edit files, read non-token `.env` keys, follow unsafe `.env` file types, depend on GitHub CLI, or collect telemetry.
|
|
51
60
|
|
|
52
61
|
## Documentation
|
|
53
62
|
|
|
@@ -61,11 +70,12 @@ src/
|
|
|
61
70
|
```text
|
|
62
71
|
test/
|
|
63
72
|
├── command.test.mjs # /branchme parsing, help, fallback, panel width
|
|
73
|
+
├── git-context.test.mjs # collection, prompt hook, formatting, safety, and output bounds
|
|
64
74
|
├── git.test.mjs # git helper command construction and failures
|
|
65
|
-
├── git-integration.test.mjs # isolated real-git branch helper coverage
|
|
66
|
-
├── github.test.mjs # GitHub parsing, token resolution,
|
|
75
|
+
├── git-integration.test.mjs # isolated real-git context and branch helper coverage
|
|
76
|
+
├── github.test.mjs # GitHub parsing, token resolution, related-PR lookup, redaction
|
|
67
77
|
├── preparation.test.mjs # package/docs/source metadata checks
|
|
68
|
-
├── tools.test.mjs # extension registration, schemas,
|
|
78
|
+
├── tools.test.mjs # extension registration, schemas, shared refresh, tool behavior
|
|
69
79
|
└── tui-capture.test.mjs # generated text capture for TUI/help visual baselines
|
|
70
80
|
```
|
|
71
81
|
|
package/docs/TUI_CAPTURE.md
CHANGED
|
@@ -23,16 +23,19 @@ Commands only show info; BranchMe tools perform actions.
|
|
|
23
23
|
## Workflow
|
|
24
24
|
|
|
25
25
|
1. `branch_status` — inspect repo and branch state.
|
|
26
|
-
2. `change_branch`
|
|
27
|
-
3.
|
|
28
|
-
4. `
|
|
29
|
-
5.
|
|
26
|
+
2. `change_branch` — switch to the clean local base branch.
|
|
27
|
+
3. `pull_branch` — fast-forward the current branch from its configured upstream.
|
|
28
|
+
4. `create_branch` — create a new branch from the updated `HEAD`.
|
|
29
|
+
5. Commit outside BranchMe.
|
|
30
|
+
6. `push_branch` — push the current branch.
|
|
31
|
+
7. `pull_request` — open a PR after `push_branch` completes and GitHub sees the branches.
|
|
30
32
|
|
|
31
33
|
## Requirements
|
|
32
34
|
|
|
33
35
|
- Run inside a Git repo with `git` available.
|
|
34
36
|
- For PRs: GitHub `origin` and `GITHUB_TOKEN` or `GH_TOKEN` (environment or `.env`).
|
|
35
|
-
-
|
|
37
|
+
- `pull_branch` requires a clean working tree and configured upstream.
|
|
38
|
+
- BranchMe never stages, commits, rebases, or creates merge commits.
|
|
36
39
|
```
|
|
37
40
|
|
|
38
41
|
## Panel: Tiny mode: clean branch with token
|
|
@@ -98,12 +101,12 @@ Width: 80
|
|
|
98
101
|
│ Status │ WORKFLOW │
|
|
99
102
|
│▶ Workflow │ branch_status -> inspect │
|
|
100
103
|
│ │ change_branch -> existing local │
|
|
104
|
+
│ │ pull_branch -> fast-forward │
|
|
101
105
|
│ │ create_branch -> from HEAD │
|
|
102
106
|
│ │ push_branch -> current branch │
|
|
103
107
|
│ │ pull_request -> after push │
|
|
104
|
-
│ │ │
|
|
105
108
|
├─────────────────────┴────────────────────────────────────────────────────────┤
|
|
106
|
-
│ 2/2 • workflow • inspect → change
|
|
109
|
+
│ 2/2 • workflow • inspect → change → pull → create → push → PR │
|
|
107
110
|
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
108
111
|
```
|
|
109
112
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@senad-d/branchme",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Minimal Pi extension for current-repository git branch, push, and pull request workflows.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"format:check": "node scripts/check-format.mjs",
|
|
51
51
|
"test": "node --test test/*.test.mjs",
|
|
52
52
|
"test:coverage": "mkdir -p coverage && node --test --experimental-test-coverage --test-reporter=spec --test-reporter=lcov --test-reporter-destination=stdout --test-reporter-destination=coverage/lcov.info test/*.test.mjs",
|
|
53
|
-
"smoke:pi": "node scripts/smoke-pi-runtime.mjs",
|
|
53
|
+
"smoke:pi": "node scripts/smoke-pi-runtime.mjs && node scripts/smoke-pi-git-context.mjs",
|
|
54
54
|
"smoke:pi:packed": "node scripts/smoke-pi-installed-package.mjs",
|
|
55
|
-
"check": "node --check scripts/check-format.mjs && node --check scripts/check-package-contents.mjs && node --check scripts/publish-npm.mjs && node --check scripts/smoke-pi-installed-package.mjs && node --check scripts/smoke-pi-runtime.mjs",
|
|
55
|
+
"check": "node --check scripts/check-format.mjs && node --check scripts/check-package-contents.mjs && node --check scripts/publish-npm.mjs && node --check scripts/smoke-pi-git-context.mjs && node --check scripts/smoke-pi-installed-package.mjs && node --check scripts/smoke-pi-runtime.mjs",
|
|
56
56
|
"pack:dry-run": "npm pack --dry-run --json",
|
|
57
57
|
"check:pack": "node scripts/check-package-contents.mjs",
|
|
58
58
|
"validate": "npm run typecheck && npm run format:check && npm run test && npm run smoke:pi && npm run check && npm run check:pack",
|
|
@@ -32,16 +32,19 @@ export function getBranchMeHelpText(): string {
|
|
|
32
32
|
"## Workflow",
|
|
33
33
|
"",
|
|
34
34
|
"1. `branch_status` — inspect repo and branch state.",
|
|
35
|
-
"2. `change_branch`
|
|
36
|
-
"3.
|
|
37
|
-
"4. `
|
|
38
|
-
"5.
|
|
35
|
+
"2. `change_branch` — switch to the clean local base branch.",
|
|
36
|
+
"3. `pull_branch` — fast-forward the current branch from its configured upstream.",
|
|
37
|
+
"4. `create_branch` — create a new branch from the updated `HEAD`.",
|
|
38
|
+
"5. Commit outside BranchMe.",
|
|
39
|
+
"6. `push_branch` — push the current branch.",
|
|
40
|
+
"7. `pull_request` — open a PR after `push_branch` completes and GitHub sees the branches.",
|
|
39
41
|
"",
|
|
40
42
|
"## Requirements",
|
|
41
43
|
"",
|
|
42
44
|
"- Run inside a Git repo with `git` available.",
|
|
43
45
|
"- For PRs: GitHub `origin` and `GITHUB_TOKEN` or `GH_TOKEN` (environment or `.env`).",
|
|
44
|
-
"-
|
|
46
|
+
"- `pull_branch` requires a clean working tree and configured upstream.",
|
|
47
|
+
"- BranchMe never stages, commits, rebases, or creates merge commits.",
|
|
45
48
|
].join("\n");
|
|
46
49
|
}
|
|
47
50
|
|
package/src/constants.ts
CHANGED
|
@@ -4,6 +4,7 @@ export const BRANCHME_COMMAND_NAME = "branchme";
|
|
|
4
4
|
export const BRANCH_STATUS_TOOL_NAME = "branch_status";
|
|
5
5
|
export const CREATE_BRANCH_TOOL_NAME = "create_branch";
|
|
6
6
|
export const CHANGE_BRANCH_TOOL_NAME = "change_branch";
|
|
7
|
+
export const PULL_BRANCH_TOOL_NAME = "pull_branch";
|
|
7
8
|
export const PUSH_BRANCH_TOOL_NAME = "push_branch";
|
|
8
9
|
export const PULL_REQUEST_TOOL_NAME = "pull_request";
|
|
9
10
|
|
|
@@ -11,13 +12,21 @@ export const BRANCHME_TOOL_NAMES = [
|
|
|
11
12
|
BRANCH_STATUS_TOOL_NAME,
|
|
12
13
|
CREATE_BRANCH_TOOL_NAME,
|
|
13
14
|
CHANGE_BRANCH_TOOL_NAME,
|
|
15
|
+
PULL_BRANCH_TOOL_NAME,
|
|
14
16
|
PUSH_BRANCH_TOOL_NAME,
|
|
15
17
|
PULL_REQUEST_TOOL_NAME,
|
|
16
18
|
] as const;
|
|
17
19
|
|
|
18
20
|
export const GIT_STATUS_TIMEOUT_MS = 5_000;
|
|
19
21
|
export const GIT_MUTATION_TIMEOUT_MS = 30_000;
|
|
22
|
+
export const GIT_PULL_TIMEOUT_MS = 120_000;
|
|
20
23
|
export const GIT_PUSH_TIMEOUT_MS = 120_000;
|
|
24
|
+
export const GITHUB_RELATED_PR_TIMEOUT_MS = 4_000;
|
|
25
|
+
|
|
26
|
+
export const GIT_CONTEXT_RECENT_COMMIT_LIMIT = 5;
|
|
27
|
+
export const GIT_CONTEXT_CHANGE_LIMIT = 20;
|
|
28
|
+
export const GIT_CONTEXT_VALUE_LIMIT_CHARS = 512;
|
|
29
|
+
export const GIT_CONTEXT_SUMMARY_LIMIT_CHARS = 4_000;
|
|
21
30
|
|
|
22
31
|
export const GITHUB_API_BASE_URL = "https://api.github.com";
|
|
23
32
|
export const GITHUB_API_VERSION = "2022-11-28";
|
package/src/extension.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { registerBranchMeCommand } from "./commands/branchme-command.ts";
|
|
3
|
+
import { registerGitContextAwareness } from "./git-context.ts";
|
|
3
4
|
import { registerBranchMeTools } from "./tools/branchme-tools.ts";
|
|
4
5
|
|
|
5
6
|
export function branchMeExtension(pi: ExtensionAPI): void {
|
|
6
7
|
registerBranchMeCommand(pi);
|
|
7
8
|
registerBranchMeTools(pi);
|
|
9
|
+
registerGitContextAwareness(pi);
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
export default branchMeExtension;
|