@vibes.diy/prompts 14.3.166 → 14.3.167

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/llms/backend.md CHANGED
@@ -183,7 +183,10 @@ const routes = await ctx.github.routes(); // [{ repo, accountLogin, binderHandle
183
183
  a path outside `/repos/…` + `/installation/repositories`, or one naming a repo
184
184
  this vibe is not bound to,
185
185
  `unsupported_method`, `streaming_unsupported`, `body_too_large`,
186
- `permission_not_granted` — the installation lacks that permission, or
186
+ `permission_not_declared` — `config.github.permissions` leaves out the
187
+ permission this call needs, `permission_not_consented` — declared, but the
188
+ person who connected the repo agreed before it was (they press Connect
189
+ again), `permission_not_granted` — the installation lacks that permission, or
187
190
  `upstream_error`); branch on `err.reason`, and tell the user which one it was.
188
191
 
189
192
  - **Connecting a repository is a link, not a call.** The page links to the
package/llms/github.md CHANGED
@@ -31,13 +31,15 @@ the GitHub App carries the repos. An app can use both side by side.
31
31
  ### 1. Declare it — `backend.js`
32
32
 
33
33
  **`backend.js` declares `config.github` with `bind` and a `why` sentence** the
34
- visitor reads on the platform's consent page before GitHub opens:
34
+ visitor reads on the platform's consent page before GitHub opens, and the
35
+ `permissions` the app uses in each connected repo:
35
36
 
36
37
  ```js
37
38
  export const config = {
38
39
  github: {
39
40
  bind: "anyone",
40
41
  why: "Leaves a short note on each new pull request in the repos you pick.",
42
+ permissions: ["pull_requests:write"],
41
43
  },
42
44
  };
43
45
  ```
@@ -52,6 +54,38 @@ export const config = {
52
54
  remix that opens up to visitors already says what it does.
53
55
  - A malformed `config.github` refuses the push, with a message naming the field.
54
56
 
57
+ **`config.github.permissions` lists every GitHub permission the app's `ctx.github.fetch` calls use**
58
+ — and only those. The platform lets each call through when its permission is
59
+ declared, and the consent page lists the declaration in plain words, so the
60
+ person sees exactly what the app does in their repos. The names are GitHub's
61
+ own, and `:write` includes `:read`:
62
+
63
+ | Permission | The consent page says the app can | Calls it covers |
64
+ | --- | --- | --- |
65
+ | `contents:read` | read its code | `/contents`, `/readme`, `/git`, `/commits`, `/compare`, `/branches`, `/tags`, `/releases` (GET) |
66
+ | `contents:write` | read and change its code | the same paths, writing; merging a pull request |
67
+ | `pull_requests:read` | read its pull requests | `/pulls`, `/pulls/{n}`, `/pulls/{n}/files`, `/reviews`, `/comments` (GET) |
68
+ | `pull_requests:write` | review, comment on, edit and close pull requests | reviews, review comments, requested reviewers, comments and labels on a pull request's conversation, and editing a pull request (title, body, base, open or closed) |
69
+ | `issues:read` | read its issues | `/issues`, `/issues/{n}`, `/labels` (GET) |
70
+ | `issues:write` | label and comment on issues | opening, editing, labelling, assigning and commenting on issues |
71
+ | `statuses:read` | read whether commits are passing | `/commits/{ref}/status`, `/commits/{ref}/statuses` |
72
+ | `statuses:write` | mark commits as passing or failing | `POST /statuses/{sha}` |
73
+ | `checks:read` | read check results on commits | `/check-runs`, `/check-suites`, `/commits/{ref}/check-runs` (GET) |
74
+ | `checks:write` | post check results on commits | creating and updating check runs |
75
+ | `actions:read` | read its Actions runs | `/actions/runs`, `/actions/workflows`, `/actions/jobs`, `/actions/artifacts` (GET) |
76
+
77
+ - A repo's own record (`GET /repos/{owner}/{repo}`) and
78
+ `/installation/repositories` need no permission; every app has them.
79
+ - A pull request's conversation comments and labels live at
80
+ `/repos/{owner}/{repo}/issues/{number}/comments` and `…/labels` on GitHub, and
81
+ `pull_requests:write` covers them when `{number}` is a pull request. An app
82
+ that comments on issues too declares `issues:write`.
83
+ - Leaving `permissions` out gives `["contents:read", "pull_requests:write"]`.
84
+ Write the list anyway, so the consent page names what this app does.
85
+ - When a new version of the app declares more, each person who connected a repo
86
+ keeps the list they agreed to until they press Connect again; the app's owner
87
+ gets the new list right away.
88
+
55
89
  ### 2. Connect it — `App.jsx`
56
90
 
57
91
  **The Connect button is a link to `buildGithubInstallUrl()` from `use-vibes`, opened in a new tab**
@@ -97,7 +131,7 @@ await ctx.github.fetch(`/repos/${repo}/pulls/${number}/reviews`, {
97
131
  ```
98
132
 
99
133
  `ctx.github.fetch` attaches the App's credential itself, so a repo call carries only its path, method and body.
100
- `path` starts at `/`: any `/repos/{owner}/{repo}/…` path for a repo connected to
134
+ `path` starts at `/`: a `/repos/{owner}/{repo}/…` path from the permissions table above, for a repo connected to
101
135
  this app, plus `/installation/repositories`, which lists exactly the repos
102
136
  connected to this app. **An app sees only the repos connected to it**, so build
103
137
  every repo list from `routes()` or that listing. Methods are GET, POST, PUT, PATCH
@@ -105,7 +139,12 @@ and DELETE; an object `body` is sent as JSON. It resolves a normal `Response`
105
139
  (GitHub's own 404 or 422 included — read `res.ok` and `res.status`), and it
106
140
  rejects with an `Error` whose `err.reason` names what happened:
107
141
  `not_connected` (no repo connected yet), `unmodeled_endpoint` (a path outside
108
- those, or a repo this app has not connected), `permission_not_granted`,
142
+ those, or a repo this app has not connected), `permission_not_declared` (the
143
+ call needs a permission `config.github.permissions` leaves out — add it),
144
+ `permission_not_consented` (declared, and the person connected the repo before
145
+ the app asked for it — show them **Connect again** with the
146
+ `buildGithubInstallUrl()` link), `permission_not_granted` (GitHub itself
147
+ refused: the vibes.diy GitHub App does not hold that permission yet),
109
148
  `unsupported_method`, `body_too_large`, `upstream_error`. Branch on
110
149
  `err.reason` and tell the person which one it was.
111
150
 
@@ -190,6 +229,8 @@ export const config = {
190
229
  github: {
191
230
  bind: "anyone",
192
231
  why: "Leaves a short note on each new pull request in the repos you pick, saying how big the change is.",
232
+ // Reads each pull request and its files, and posts one review.
233
+ permissions: ["pull_requests:write"],
193
234
  },
194
235
  };
195
236
 
@@ -199,6 +240,12 @@ const PR_ACTIONS = ["opened", "reopened", "synchronize"];
199
240
  // The author_association values GitHub gives the people on a repo's team.
200
241
  const TEAM = ["OWNER", "MEMBER", "COLLABORATOR"];
201
242
  const DEFAULT_WHO = "team";
243
+ // What each ctx.github refusal means to the person, in a line they can act on.
244
+ const REASONS = {
245
+ permission_not_consented: "press Connect again to let this app review pull requests here",
246
+ permission_not_declared: "this app's backend needs to declare that GitHub permission",
247
+ permission_not_granted: "the vibes.diy GitHub App needs permission to review pull requests",
248
+ };
202
249
 
203
250
  function json(data, status) {
204
251
  return new Response(JSON.stringify(data), { status: status ?? 200, headers: { "content-type": "application/json" } });
@@ -252,7 +299,7 @@ function takesOn(settings, pr) {
252
299
  async function finishNote(ctx, id, repo, pr, bigAt) {
253
300
  const outcome = await writeNote(ctx, repo, pr, bigAt).catch((err) => ({
254
301
  status: "failed",
255
- reason: err.reason === "permission_not_granted" ? "the GitHub App needs permission to review pull requests" : String(err.reason ?? err.message),
302
+ reason: REASONS[err.reason] ?? String(err.reason ?? err.message),
256
303
  }));
257
304
  const claimed = await ctx.db.get(id, { db: DB });
258
305
  await ctx.db.put({ ...claimed, ...outcome }, { db: DB, id, ifRev: claimed._rev });
@@ -552,11 +599,13 @@ channel.
552
599
  the app is publishing plus `access.js`. Who sets off AI calls and GitHub
553
600
  posts is the repo's `who` setting on deliveries and a `binderHandle` check on
554
601
  every spending route. Keep the app published and gate the spend.
555
- - **What the App may do today:** read repository contents, and write to pull
556
- requests — reviews, review comments, and comments on a pull request's
557
- conversation. Build on those. Other writes (labels, issue comments, check
558
- runs) may answer `permission_not_granted`; record that reason on the
559
- person's record and show it, so they see exactly what happened.
602
+ - **Declare what the app uses, and show each refusal.** A call outside the
603
+ declaration answers `permission_not_declared`; one the person has not agreed
604
+ to yet answers `permission_not_consented`, and pressing Connect again shows
605
+ them the new list. `permission_not_granted` means GitHub itself refused,
606
+ because the vibes.diy GitHub App does not hold that permission. Record the
607
+ reason on the person's record and show it, so they see exactly what happened
608
+ and what one tap fixes it.
560
609
  - **Each app gets the repos chosen for it.** The person ticks repos per app, and
561
610
  each app's connection stands on its own. One repo can feed up to ten apps,
562
611
  each hearing its deliveries with its own connector. While that switches on, a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibes.diy/prompts",
3
- "version": "14.3.166",
3
+ "version": "14.3.167",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "exports": {
@@ -39,10 +39,10 @@
39
39
  "license": "Apache-2.0",
40
40
  "dependencies": {
41
41
  "@adviser/cement": "~0.5.34",
42
- "@vibes.diy/api-types": "14.3.166",
43
- "@vibes.diy/call-ai-v2": "14.3.166",
44
- "@vibes.diy/identity": "14.3.166",
45
- "@vibes.diy/use-vibes-types": "14.3.166",
42
+ "@vibes.diy/api-types": "14.3.167",
43
+ "@vibes.diy/call-ai-v2": "14.3.167",
44
+ "@vibes.diy/identity": "14.3.167",
45
+ "@vibes.diy/use-vibes-types": "14.3.167",
46
46
  "arktype": "~2.2.6",
47
47
  "json-schema-faker": "~0.6.3"
48
48
  },