@joe-broadhead/opencode-github 0.0.0 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,87 @@
2
2
 
3
3
  All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
4
 
5
+ ## [0.0.2] - 2026-11-04
6
+
7
+ ### Fixed
8
+
9
+ - **Security:** `github_api` checked its permission rules against the path as written, but sent the request to the
10
+ path after the URL parser removed percent-encoded dot segments such as `.%2e`, `%2e.` and `%2e`. A write could
11
+ therefore reach another repository or endpoint than the one an allow or deny rule named, and the prompt showed the
12
+ wrong path. It now refuses a `.` or `..` segment however it is encoded (double encoding too) and a percent-encoded
13
+ character a path can hold as itself, such as `%6F` for `o`, with `API_PATH_INVALID`, before any prompt or request.
14
+ The path that rules and the prompt see is exactly the path sent, on GitHub.com and with `host`, for uploads too.
15
+ - **Security:** `github_api` rules could be dodged by case and by redirects. GitHub reads owner and repository names
16
+ (and organisation, user, team, environment, label, secret and variable names) without regard to case, so a deny on
17
+ `/repos/owner/prod/*` did not stop `/repos/Owner/Prod/…`. The permission resource now has those names in lower
18
+ case; write rules that way. The status lists rules with an upper-case owner or repo name, which never match, under
19
+ "Rules that never match". And a redirect could take a call to a path no rule had checked: a change now never
20
+ follows one (`API_REDIRECTED`, naming the new path), a read follows one within the API only after the permission
21
+ check passes for the new path, and a read redirected outside the API fails with `API_REDIRECT_OFF_HOST`. Downloads
22
+ still follow GitHub's storage redirects without the token. The tools RPC's `api` method does the same.
23
+ - Status listed agents whose own rules already ask for or deny GitHub's tools, such as agents that end with
24
+ `* * ask`, as agents without default rules. It now lists an agent only when its rules would let a GitHub tool run
25
+ without asking.
26
+ - Status said "Nothing to do." while it listed agents without default rules. The next step now names them and the
27
+ fix.
28
+ - `github_api` downloads had no size limit. A download now stops at 2 GiB with `API_DOWNLOAD_TOO_LARGE`, checked
29
+ against `Content-Length` and while it streams, and the partial file is removed.
30
+ - A `github_api` download without `overwrite` could replace a file created while it ran. It now keeps that file and
31
+ fails with `API_FILE_EXISTS`.
32
+ - A download to a file that already exists asked for approval first and only then failed. It is now refused before
33
+ the prompt.
34
+ - The scripting docs said `opencode api` runs in the directory you call it from. It runs in the OpenCode service's
35
+ default location, your home directory; the docs now say how to target a project. They also say that `opencode api`
36
+ exits with status 1 on an RPC error, and that a tool with no structured content returns its text as `output`.
37
+ - The README says to run `opencode reload` after install, how to update, and orders Uninstall as sign out, remove,
38
+ data folders (none) and copied rules. Its sign-out step is `opencode auth logout GitHub <login>`: without the
39
+ account's label the command needs an interactive terminal, and a token left behind after removing the plugin no
40
+ longer shows in `opencode auth list`.
41
+ - `/github-status` and the dialog left out the Account and Agents without default rules rows when they were empty,
42
+ and `/github-status` had no title line. Every row is now shown, with `none` where it is empty, under
43
+ "GitHub status".
44
+
45
+ ### Changed
46
+
47
+ - `POST /markdown` and `POST /markdown/raw` through `github_api` are reads: they only render Markdown, so they run
48
+ without a prompt and also while read-only. Every other POST is still a write.
49
+ - Code Mode shows a description for the `github` namespace, and every `github_api` input field has one.
50
+ - `issue_artifact_read` (a read) and `issue_artifact_write` (a write), which github-mcp-server v2.1.0 adds to the
51
+ `issues` toolset behind a feature flag the plugin does not turn on, are known tools.
52
+ - A script's `TOOL_UNAVAILABLE` next step names the toolsets that are off by default, and says to add the method's
53
+ toolset to `toolsets` and run `opencode reload`.
54
+ - The tools RPC's shared module is updated: `describe` given any input but nothing or `{}` answers
55
+ `describe takes no input`, an envelope that is not an object gets a plain message, a permission refusal names the
56
+ action that was refused, and a server that reconnects during a call gives `CONNECTING` instead of
57
+ `CONNECTION_FAILED`.
58
+ - OpenCode 2.2.5 is a tested release. The status calls 2.2.3, 2.2.4 and 2.2.5 tested, and a later 2.2 release
59
+ "untested; supported range >=2.2.3 <2.3.0". `HOST_UNTESTED` and the `allowUntestedHost` warning now say "outside
60
+ the supported range".
61
+ - The status RPC (`github.platform`) has the fields every plugin of this family shares
62
+ ([Scripting](https://github.com/joe-broadhead/opencode-github/blob/HEAD/docs/scripting.md#status)):
63
+ - new `version`, the plugin's version;
64
+ - `host` is `{ version, range, tested }`; `host.warning` is now `hostWarning`;
65
+ - `state` values: `needs_auth` is now `sign_in_required`, `pending` is now `connecting`, and `not_registered` is
66
+ now `not_configured`.
67
+
68
+ ## [0.0.1] - 2026-11-03
69
+
70
+ ### Added
71
+
72
+ - The tools RPC, `github.platform.tools`: a script can call GitHub's known MCP reads, and `api` (`github_api` limited
73
+ to REST GET and HEAD and single GraphQL queries), with no model, through `opencode api`, as a session and its agent.
74
+ It gets exactly the access that agent's model has: a tool its rules hide is refused, OpenCode checks each MCP call
75
+ against the agent's and the session's rules, and an ask is refused at once because no one is there to answer it.
76
+ `describe` lists the methods with each tool's live input schema. GitHub's writes, `ui_get` and any tool GitHub adds
77
+ later are never methods, and `api` refuses changes, downloads and uploads with `SCRIPT_READ_ONLY` before any
78
+ request. With `host` (GitHub Enterprise Server) only `api` runs. `docs/scripting.md` explains it.
79
+
80
+ ### Changed
81
+
82
+ - `check_dependency_vulnerabilities`, which GitHub's hosted server now lists in the `dependabot` toolset, is a known
83
+ read: it looks up a list of packages in the GitHub Advisory Database and changes nothing, so it runs without a
84
+ prompt, and `/github-status` no longer lists it as unknown.
85
+
5
86
  ## [0.0.0] - 2026-11-01
6
87
 
7
88
  ### Added
package/README.md CHANGED
@@ -7,8 +7,9 @@ Unofficial; not affiliated with GitHub. GitHub is a trademark of GitHub, Inc.
7
7
 
8
8
  ## Requirements
9
9
 
10
- - OpenCode `>=2.2.3 <2.3.0`, tested on 2.2.3 and 2.2.4. On any other release the plugin refuses to load (see
11
- [`allowUntestedHost`](https://github.com/joe-broadhead/opencode-github/blob/HEAD/docs/configuration.md#allowuntestedhost)).
10
+ - OpenCode `>=2.2.3 <2.3.0`, tested on 2.2.3, 2.2.4 and 2.2.5. A later 2.2 release loads too, and the status marks it
11
+ untested. Outside `>=2.2.3 <2.3.0` the plugin does not load, unless you set
12
+ [`allowUntestedHost`](https://github.com/joe-broadhead/opencode-github/blob/HEAD/docs/configuration.md#allowuntestedhost).
12
13
  - macOS or Linux.
13
14
  - A GitHub account.
14
15
 
@@ -18,7 +19,14 @@ Unofficial; not affiliated with GitHub. GitHub is a trademark of GitHub, Inc.
18
19
  opencode plugin add @joe-broadhead/opencode-github
19
20
  ```
20
21
 
21
- Restart OpenCode. `opencode mcp list` then shows `github needs authentication` until you sign in.
22
+ Run `opencode reload`, or restart OpenCode. Then run `/github-status`: it shows `Connection: sign-in required` until
23
+ you sign in, and `opencode mcp list` shows `github needs authentication`.
24
+
25
+ ### Update
26
+
27
+ Update with `opencode plugin update @joe-broadhead/opencode-github`, then run `opencode reload`. Your options and
28
+ rules stay as they are. An entry pinned to a version (`@joe-broadhead/opencode-github@0.0.1`) does not update: remove
29
+ the `@<version>` from its `plugins` entry first.
22
30
 
23
31
  ## Sign in
24
32
 
@@ -52,7 +60,8 @@ permissions above.
52
60
  A fine-grained token reaches only the repositories you select, and GitHub enforces that. For writes
53
61
  (`readOnly: false`), give the token write access to what those tools change, for example Issues or Pull requests.
54
62
 
55
- To sign out, run `opencode auth logout GitHub`, or remove the account in `/connect` → **GitHub**.
63
+ To sign out, run `opencode auth logout GitHub <login>`, where `<login>` is the account's label, your GitHub login,
64
+ or remove the account in `/connect` → **GitHub**.
56
65
 
57
66
  ## Use
58
67
 
@@ -69,8 +78,9 @@ branch protection, rulesets, Actions variables, downloading artifacts and logs t
69
78
  GitHub's REST or GraphQL API with your GitHub sign-in, for example
70
79
  `{ "method": "GET", "path": "/repos/OWNER/REPO/branches/main/protection" }` or
71
80
  `{ "graphql": { "query": "query { viewer { login } }" } }`. GET, HEAD and a single GraphQL query read; every other
72
- call changes GitHub, asks first, and is refused while the plugin is read-only. Requests go only to GitHub's API; a
73
- redirect to file storage is followed without your token. `download: { path }` saves a response to a file in the
81
+ call changes GitHub, asks first, and is refused while the plugin is read-only. Requests go only to GitHub's API. A
82
+ change never follows a redirect; a read follows one within the API only after asking for the new path, and only a
83
+ download follows one to GitHub's file storage, without your token. `download: { path }` saves a response to a file in the
74
84
  project, and `upload: { path, contentType }` sends a project file as a release asset; both ask first.
75
85
 
76
86
  Three skills come with it:
@@ -82,6 +92,17 @@ Three skills come with it:
82
92
 
83
93
  Each skill reports findings and changes nothing on GitHub unless you ask.
84
94
 
95
+ **Scripts.** A script or a cron job can call GitHub's read tools and `github_api`'s reads with no model, through
96
+ `opencode api`. It runs as a session and its agent, under that agent's permission rules and the session's own.
97
+ Scripts can never change anything on GitHub:
98
+
99
+ ```sh
100
+ opencode api post /api/rpc/github.platform.tools/pull_request_read \
101
+ -d '{"input":{"sessionID":"ses_…","input":{"method":"get","owner":"OWNER","repo":"REPO","pullNumber":42}}}'
102
+ ```
103
+
104
+ See [Scripting](https://github.com/joe-broadhead/opencode-github/blob/HEAD/docs/scripting.md).
105
+
85
106
  **Status.** `/github` in the TUI, or **GitHub: Status** in the command palette, opens a dialog with the state, the
86
107
  account and access, the tools (with the names of any the plugin does not know yet), the agents that miss the default
87
108
  rules with the rules to paste, the OpenCode check and the next step. `r` refreshes it and `Esc` closes it. It also
@@ -111,13 +132,16 @@ Your own rules and saved approvals still win:
111
132
  ```
112
133
 
113
134
  Every rule needs a `"resource"`. OpenCode skips a rule without it.
114
- - `github_api` rules match `METHOD /path`, and `*` matches any text, slashes included. This lets the agent change one
115
- owner's repositories without a prompt, and never delete anything:
135
+ - `github_api` rules match `METHOD /path`, and `*` matches any text, slashes included. **Write owner and repo names
136
+ in lower case**: GitHub reads them without regard to case, so the plugin checks `/repos/Owner/Prod/…` as
137
+ `/repos/owner/prod/…`, and a rule with an upper-case name never matches (the status warns about it). The same holds
138
+ for organisation, user and team names, and environment, label, secret and variable names. This lets the agent change
139
+ one owner's repositories without a prompt, and never delete anything:
116
140
 
117
141
  ```json
118
142
  {
119
143
  "permissions": [
120
- { "action": "github_api", "resource": "POST /repos/OWNER/*", "effect": "allow" },
144
+ { "action": "github_api", "resource": "POST /repos/my-org/*", "effect": "allow" },
121
145
  { "action": "github_api", "resource": "DELETE *", "effect": "deny" }
122
146
  ]
123
147
  }
@@ -204,7 +228,7 @@ overrides user and project config, so members only sign in:
204
228
  ## Troubleshooting
205
229
 
206
230
  `/github-status` and the `/github` dialog show the rows Connection, Account, Access, Toolsets, Host, Tools, Agents
207
- without default rules, OpenCode and Next step. The Connection row and its next step:
231
+ without default rules, OpenCode and Next step, with `none` where a row is empty. The Connection row and its next step:
208
232
 
209
233
  | Connection | Next step |
210
234
  | --- | --- |
@@ -216,14 +240,22 @@ without default rules, OpenCode and Next step. The Connection row and its next s
216
240
  | `not configured` | Restart OpenCode. If GitHub is still missing, check that no other plugin removes the MCP server named github. |
217
241
  | `conflict` | Your OpenCode config or another plugin defines its own MCP server named github, so this plugin left it unchanged. Rename or remove that server to use this plugin's GitHub sign-in. |
218
242
 
243
+ A **Rules that never match** row lists `github_api` rules with an upper-case owner or repo name (see
244
+ [Permissions](#permissions)), and the next step gives the lower-case form. Otherwise, when the connection needs
245
+ nothing, the next step names the agents without default rules and how to fix them (see
246
+ [Permissions](#permissions)); on an untested OpenCode release it names the tested ones. Otherwise it is "Nothing to do."
247
+
219
248
  Error codes:
220
249
 
221
250
  | Code | What to do |
222
251
  | --- | --- |
223
- | `HOST_UNTESTED` | OpenCode is outside `>=2.2.3 <2.3.0`. Update OpenCode or the plugin, or set the option `allowUntestedHost: true` to load it anyway, with a warning in the status. |
252
+ | `HOST_UNTESTED` | OpenCode is outside the supported range `>=2.2.3 <2.3.0`. Update OpenCode or the plugin, or set the option `allowUntestedHost: true` to load it anyway, with a warning in the status. |
224
253
  | `OPTIONS_INVALID` | An option is unknown or has a wrong value; the message names it. Fix that option for the plugin in `opencode.json`. |
225
254
  | `SIGN_IN_…`, `TOKEN_…`, `DEVICE_…`, `CLIENT_ID_UNKNOWN` | Sign-in failed. The message ends with the next step; [the error codes](https://github.com/joe-broadhead/opencode-github/blob/HEAD/docs/configuration.md#errors) list them all. |
226
255
 
256
+ A script's errors from the tools RPC have their own codes, listed in
257
+ [Scripting](https://github.com/joe-broadhead/opencode-github/blob/HEAD/docs/scripting.md#errors).
258
+
227
259
  Other problems:
228
260
 
229
261
  | You see | What to do |
@@ -236,15 +268,24 @@ Other problems:
236
268
 
237
269
  ## Uninstall
238
270
 
239
- 1. Sign out: `opencode auth logout GitHub`.
240
- 2. Run `opencode plugin remove @joe-broadhead/opencode-github`, and remove any default rules you copied into agents.
241
- 3. On GitHub, delete the token under **Settings → Developer settings → Personal access tokens**, or, after a device
242
- sign-in, revoke the OAuth App under **Settings → Applications → Authorized OAuth Apps**.
271
+ Sign out first: once the plugin is removed, `opencode auth list` no longer shows the GitHub sign-in, but OpenCode
272
+ still stores its token.
273
+
274
+ 1. Sign out: `opencode auth logout GitHub <login>`, where `<login>` is the account's label in `/connect`, your GitHub
275
+ login (with `host`: `opencode auth logout "GitHub Enterprise" <login>`). Without `<login>` it asks you to pick the
276
+ account, which works only in an interactive terminal. Then, on GitHub, delete the token under **Settings →
277
+ Developer settings → Personal access tokens**, or, after a device sign-in, revoke the OAuth App under **Settings →
278
+ Applications → Authorized OAuth Apps**.
279
+ 2. Run `opencode plugin remove @joe-broadhead/opencode-github`, then `opencode reload`.
280
+ 3. Data folders: none. The plugin stores nothing of its own.
281
+ 4. Remove the default rules you copied into agents' own `permissions`.
243
282
 
244
283
  ## Links
245
284
 
246
285
  - [Configuration](https://github.com/joe-broadhead/opencode-github/blob/HEAD/docs/configuration.md): options,
247
286
  toolsets, permission rules and error codes.
287
+ - [Scripting](https://github.com/joe-broadhead/opencode-github/blob/HEAD/docs/scripting.md): calling GitHub's reads
288
+ from scripts, with no model.
248
289
  - [Security](https://github.com/joe-broadhead/opencode-github/blob/HEAD/SECURITY.md): network endpoints,
249
290
  credentials, untrusted content and reporting a vulnerability.
250
291
  - [Contributing](https://github.com/joe-broadhead/opencode-github/blob/HEAD/CONTRIBUTING.md): development, checks