@vibes.diy/prompts 14.3.166 → 14.3.168

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/cli-footer.md CHANGED
@@ -4,16 +4,17 @@
4
4
 
5
5
  1. Run `npx vibes-diy system` to get the coding rules
6
6
  2. Write `App.jsx` following the rules above
7
- 3. Run `npx vibes-diy push` to deploy — prints a live HTTPS URL
7
+ 3. Run `npx vibes-diy push --vibe <handle>/<app-slug>` to deploy — prints the handle/app-slug it used and a live HTTPS URL
8
8
  4. Edit and push again to iterate
9
9
 
10
10
  ### Other Commands
11
11
 
12
- - `npx vibes-diy push --access gated` — deploy so anyone can view but only members write (`open` is the default, `private` is members-only)
13
- - `npx vibes-diy push --access private` — deploy for you and the members you invite, and nobody else
14
- - `npx vibes-diy push --app-slug other-name` — deploy to a different app slug instead of the directory name
15
- - `npx vibes-diy unpublish <vibe>` — take a deployed vibe down (reversible; code and data are kept)
16
- - `npx vibes-diy publish <vibe>` — make it live again, or promote a `--mode dev` draft to production
12
+ - Name the app as `handle/app-slug` on every command (a bare slug falls back to your default handle — fine at a terminal, never in a script or agent)
13
+ - `npx vibes-diy push --vibe <handle>/<app-slug> --access gated` — deploy so anyone can view but only members write (`open` is the default, `private` is members-only)
14
+ - `npx vibes-diy push --vibe <handle>/<app-slug> --access private` — deploy for you and the members you invite, and nobody else
15
+ - `npx vibes-diy push --handle <handle> --app-slug other-name` — deploy to a different app slug instead of the directory name
16
+ - `npx vibes-diy unpublish <handle>/<app-slug>` — take a deployed vibe down (reversible; code and data are kept)
17
+ - `npx vibes-diy publish <handle>/<app-slug>` — make it live again, or promote a `--mode dev` draft to production
17
18
  - `npx vibes-diy login` — authenticate this device (run once before first push)
18
19
  - `npx vibes-diy mcp --help` — start an MCP server for AI agent data access (Claude Desktop / Cowork)
19
20
  - `npx vibes-diy help` — show all available commands
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); updating a pull request's branch also needs `contents:write` |
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,13 @@ 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 on that
148
+ account, which the account owner accepts on GitHub),
109
149
  `unsupported_method`, `body_too_large`, `upstream_error`. Branch on
110
150
  `err.reason` and tell the person which one it was.
111
151
 
@@ -190,6 +230,8 @@ export const config = {
190
230
  github: {
191
231
  bind: "anyone",
192
232
  why: "Leaves a short note on each new pull request in the repos you pick, saying how big the change is.",
233
+ // Reads each pull request and its files, and posts one review.
234
+ permissions: ["pull_requests:write"],
193
235
  },
194
236
  };
195
237
 
@@ -199,6 +241,12 @@ const PR_ACTIONS = ["opened", "reopened", "synchronize"];
199
241
  // The author_association values GitHub gives the people on a repo's team.
200
242
  const TEAM = ["OWNER", "MEMBER", "COLLABORATOR"];
201
243
  const DEFAULT_WHO = "team";
244
+ // What each ctx.github refusal means to the person, in a line they can act on.
245
+ const REASONS = {
246
+ permission_not_consented: "press Connect again to let this app review pull requests here",
247
+ permission_not_declared: "this app's backend needs to declare that GitHub permission",
248
+ permission_not_granted: "the vibes.diy GitHub App needs permission to review pull requests",
249
+ };
202
250
 
203
251
  function json(data, status) {
204
252
  return new Response(JSON.stringify(data), { status: status ?? 200, headers: { "content-type": "application/json" } });
@@ -252,7 +300,7 @@ function takesOn(settings, pr) {
252
300
  async function finishNote(ctx, id, repo, pr, bigAt) {
253
301
  const outcome = await writeNote(ctx, repo, pr, bigAt).catch((err) => ({
254
302
  status: "failed",
255
- reason: err.reason === "permission_not_granted" ? "the GitHub App needs permission to review pull requests" : String(err.reason ?? err.message),
303
+ reason: REASONS[err.reason] ?? String(err.reason ?? err.message),
256
304
  }));
257
305
  const claimed = await ctx.db.get(id, { db: DB });
258
306
  await ctx.db.put({ ...claimed, ...outcome }, { db: DB, id, ifRev: claimed._rev });
@@ -552,11 +600,14 @@ channel.
552
600
  the app is publishing plus `access.js`. Who sets off AI calls and GitHub
553
601
  posts is the repo's `who` setting on deliveries and a `binderHandle` check on
554
602
  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.
603
+ - **Declare what the app uses, and show each refusal.** A call outside the
604
+ declaration answers `permission_not_declared`; one the person has not agreed
605
+ to yet answers `permission_not_consented`, and pressing Connect again shows
606
+ them the new list. `permission_not_granted` means GitHub itself refused,
607
+ because the vibes.diy GitHub App does not hold that permission on that
608
+ account yet. Record the
609
+ reason on the person's record and show it, so they see exactly what happened
610
+ and what one tap fixes it.
560
611
  - **Each app gets the repos chosen for it.** The person ticks repos per app, and
561
612
  each app's connection stands on its own. One repo can feed up to ten apps,
562
613
  each hearing its deliveries with its own connector. While that switches on, a
package/mcp-footer.md CHANGED
@@ -5,7 +5,8 @@ Tools: vibes_list_apps, vibes_list_databases, vibes_get, vibes_put, vibes_delete
5
5
  `vibes_generate` builds a brand-new vibe from a text prompt and deploys it live —
6
6
  it takes minutes and spends your AI credits. The new app is separate from the
7
7
  `--app-slug` this server was started with; the data tools keep pointing at that
8
- one.
8
+ one. Always pass `--handle` with `--app-slug`: without it the server binds to
9
+ whatever the account's default handle is when it starts.
9
10
 
10
11
  `vibes_add_seed_data` adds the live version's sample data (its `seed.json`) to the
11
12
  app's databases, keeping your edits; `vibes_remove_seed_data` takes it out again.
@@ -36,7 +37,7 @@ Add to .mcp.json in your project root:
36
37
  "mcpServers": {
37
38
  "my-vibe": {
38
39
  "command": "npx",
39
- "args": ["vibes-diy", "mcp"]
40
+ "args": ["vibes-diy", "mcp", "--app-slug", "APP", "--handle", "USER"]
40
41
  }
41
42
  }
42
43
  }
@@ -44,4 +45,4 @@ Add to .mcp.json in your project root:
44
45
 
45
46
  ### Test interactively
46
47
 
47
- npx @modelcontextprotocol/inspector npx vibes-diy mcp --app-slug APP
48
+ npx @modelcontextprotocol/inspector npx vibes-diy mcp --app-slug APP --handle USER
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.168",
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.168",
43
+ "@vibes.diy/call-ai-v2": "14.3.168",
44
+ "@vibes.diy/identity": "14.3.168",
45
+ "@vibes.diy/use-vibes-types": "14.3.168",
46
46
  "arktype": "~2.2.6",
47
47
  "json-schema-faker": "~0.6.3"
48
48
  },