@vibes.diy/prompts 14.1.20 → 14.1.22

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/types.d.ts CHANGED
@@ -3,6 +3,7 @@ export interface LlmConfig {
3
3
  label: string;
4
4
  description: string;
5
5
  cues?: string[];
6
+ initialVariant?: boolean;
6
7
  importModule?: string;
7
8
  importName?: string;
8
9
  importType?: "named" | "namespace" | "default";
@@ -0,0 +1,58 @@
1
+ # useVibe Hook — write gating
2
+
3
+ `useVibe(dbName)` is how you gate write surfaces. It asks the platform whether a candidate document would be accepted, so the UI's enabled/disabled state matches what the server will actually allow. You never re-implement the answer in the app; you ask, and you render the verdict.
4
+
5
+ ```jsx
6
+ const { me, can, ready } = useVibe("comments");
7
+ ```
8
+
9
+ Pass the Fireproof database name you are writing to. You get:
10
+
11
+ - `can.create(draft)` / `can.edit(doc)` / `can.delete(doc)` → `{ ok: boolean, pending?: true, reason?: string }`. **The verdict has three states, not two** — allowed, still resolving, and denied — so branch on `pending` before `ok`.
12
+ - `ready` — `false` until identity and the verdict have resolved. It is the same moment `pending` marks, so either one can hold the surface.
13
+ - `me` — `{ userHandle, displayName? } | null` (null = anonymous). For display only.
14
+
15
+ ## The three-way branch
16
+
17
+ While `pending` is set, show a quiet checking state — never a sign-in prompt, never the raw `reason` token, and never a blank space where the write surface was. A pending verdict means "we don't know yet", not "you may not"; it resolves on its own within a moment, so anything that reads as a refusal is wrong for that moment, and hiding the surface with nothing in its place makes the app look broken.
18
+
19
+ On a real denial (`!ok` and no `pending`), explain it in your app's own words — `reason` is a machine token, not display copy. Let it *inform* the sentence you write ("Sign in to post here"), and never render it directly: a token like `pending` printed into the page is internal vocabulary leaking at a user.
20
+
21
+ Never stamp author fields from `me` while the verdict is pending — `me` is null until identity resolves, and a write that skips the gate lands authorless.
22
+
23
+ **Build the candidate from the doc you'll actually write.** `can.create(draft)` is evaluated against `draft`, so `draft` must carry the fields the write carries — `authorHandle`, the id of the object the record belongs to, and so on. A bare `can.create({ type: "post" })` can be denied (e.g. `"not author"`) and hide the form even from users who could post. Stamp the same fields you will `put`: `can.create({ type: "card", boardId, authorHandle: me?.userHandle })`. And gate the **same database** you write to — `useVibe(dbName)` answers per `dbName`, so a gate on a different db won't reflect what the server does.
24
+
25
+ ## The rule
26
+
27
+ Gate every write affordance on `can.*`. Hold it while `pending`, and write your own copy when denied. Never branch write permission on `viewer` or on document fields — those drift from the platform's own answer. Rendering **other** users (authors, rosters) is `useViewer()`'s `<ViewerTag userHandle={...} />`, not `useVibe`. The current viewer's own pill and the "signed in as" label are system chrome in the Vibes Switch (the logo) — don't build them into the app. Asking an anonymous visitor to sign in is a different thing and it IS yours: `useViewer().requestLogin()`, at the moment their work becomes worth keeping (see use-viewer docs). A resolved denial is one such moment — write the sign-in copy in your app's own words and wire it to that callable, never to a sentence about the logo. (The one exception is inline avatar self-edit: a guarded no-prop `{viewer && <ViewerTag />}` lets any signed-in member change their own photo in place — see use-viewer docs.)
28
+
29
+ ```jsx
30
+ import { useVibe } from "use-vibes";
31
+
32
+ function PromptBar({ database, boardId }) {
33
+ const { can, me } = useVibe("aestheticBoard");
34
+ // The candidate carries the same keys the write will: the board it belongs
35
+ // to, and who is writing it.
36
+ const v = can.create({ type: "tile", boardId, authorHandle: me?.userHandle });
37
+ // 1. still resolving — a quiet placeholder, no refusal wording, no empty hole
38
+ if (v.pending) return <div className="skeleton" aria-busy="true">Checking…</div>;
39
+ // 2. resolved denial — your words, informed by v.reason, never v.reason itself
40
+ if (!v.ok) return <p className="muted">Sign in to add a tile.</p>;
41
+ // 3. allowed
42
+ return (
43
+ <form onSubmit={/* … */}>
44
+ {/* no current-user pill — identity + sign-in live in the Vibes Switch (the logo) */}
45
+ <input placeholder="Add a tile…" />
46
+ <button type="submit">Post</button>
47
+ </form>
48
+ );
49
+ }
50
+ ```
51
+
52
+ ## Per-row affordances
53
+
54
+ Per-row edit/delete affordances read the same way: `{can.edit(doc).ok && <EditButton doc={doc} />}`. By default every signed-in visitor is a first-class participant who creates and edits their own data, so on a fresh app these verdicts come back `ok` — which is the point. The gate is already in the right place when the app later grows a narrower answer, and nothing about the surface has to be rewritten to pick that answer up.
55
+
56
+ ## The server is still the authority
57
+
58
+ `can.*` is a fast, faithful preview, not the final word. A write can still be rejected server-side (the source may be stale, async, or unevaluable — in which case `can.*` optimistically returns `ok` and defers to the server). Keep the optimistic-write + rollback pattern: apply the change immediately, revert and surface an error if the `put` rejects.
package/llms/use-vibe.js CHANGED
@@ -2,6 +2,7 @@ export const useVibeConfig = {
2
2
  name: "use-vibe",
3
3
  label: "Vibe Write Gating",
4
4
  description: "Gate write surfaces on the app's own access.js via useVibe().can",
5
+ initialVariant: true,
5
6
  importModule: "use-vibes",
6
7
  importName: "useVibe",
7
8
  };
@@ -1 +1 @@
1
- {"version":3,"file":"use-vibe.js","sourceRoot":"","sources":["../../jsr/llms/use-vibe.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAc;IACtC,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,mBAAmB;IAC1B,WAAW,EAAE,kEAAkE;IAC/E,YAAY,EAAE,WAAW;IACzB,UAAU,EAAE,SAAS;CACtB,CAAC"}
1
+ {"version":3,"file":"use-vibe.js","sourceRoot":"","sources":["../../jsr/llms/use-vibe.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAc;IACtC,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,mBAAmB;IAC1B,WAAW,EAAE,kEAAkE;IAC/E,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE,WAAW;IACzB,UAAU,EAAE,SAAS;CACtB,CAAC"}
@@ -0,0 +1,303 @@
1
+ # useViewer Hook
2
+
3
+ `useViewer()` is a **read-only window** into viewer identity. The platform owns who is signed in, and `useViewer()` lets your app see that and render it. Your app reflects the runtime's answer in its UI; it never invents one of its own.
4
+
5
+ **The current viewer's pill is system chrome — you don't build it.** The platform shows the current user inside the **Vibes Switch**, the panel that opens when you click the logo. So your app does **not** need a header pill for whoever is looking — don't render a no-prop `<ViewerTag />` just to show "who's signed in".
6
+
7
+ **The sign-in _ask_ is yours.** `requestLogin()` from `useViewer()` opens the platform sign-in UI from anywhere in your app, so you can word, place and time the ask yourself. Reach for it at the moment your app becomes worth keeping. The Switch is chrome outside your app's frame, and pointing at the logo is not a call to action — it is a scavenger hunt. See **Asking a visitor to sign in** below.
8
+
9
+ Use `useViewer()` to render **other** people's identity — comment authors, rosters, "added by" labels — with `<ViewerTag userHandle={...} />`, and to read `viewer`/`can` when your UI needs to branch on who's looking. **Write surfaces are gated with `useVibe(dbName).can`** (see use-vibe docs), not with `viewer`.
10
+
11
+ ## Basic Usage
12
+
13
+ Start with a minimal component that reads the viewer identity. You don't render a current-user pill — that lives in the Vibes Switch (click the logo). Branch on `viewer` for any welcome/empty copy. Note there is **no sign-in button here**: the ask belongs at the moment the visitor has made something worth keeping, not on arrival — see **Asking a visitor to sign in** below.
14
+
15
+ App.jsx
16
+
17
+ ```jsx
18
+ import React from "react";
19
+ import { useFireproof } from "use-fireproof";
20
+ import { useViewer } from "use-vibes";
21
+
22
+ export default function App() {
23
+ const { viewer, isViewerPending } = useViewer();
24
+
25
+ if (isViewerPending) return null;
26
+
27
+ return (
28
+ <div>
29
+ {/* No current-user pill here — that's the Vibes Switch's job. */}
30
+ {viewer ? (
31
+ <p>Welcome back, {viewer.displayName ?? viewer.userHandle}!</p>
32
+ ) : (
33
+ <p>Everything you make here is saved on this device.</p>
34
+ )}
35
+ </div>
36
+ );
37
+ }
38
+ ```
39
+
40
+ ## What you get
41
+
42
+ - `viewer` — `{ userHandle, displayName? }` or `null` for anonymous visitors. Avatars are not on the payload — render them with `<ViewerTag userHandle={...} />`, which resolves the avatar from the handle. Don't build avatar URLs yourself.
43
+ - `isViewerPending` — `true` while the platform is still resolving the viewer identity (e.g. on first render before the parent shell has pushed the identity update). **Gate any auth-dependent UI on `!isViewerPending`** to avoid flashing the wrong state. Once it becomes `false`, `viewer` is either populated or definitively `null`.
44
+ - `can(action)` — membership boolean for `"read"`/`"write"`/`"delete"`: is the viewer through the door? It answers about the viewer, not about a particular document, so prefer `useVibe(dbName).can.create/edit/delete` for write gating — that one is asked about the doc you are writing and comes back with a `reason`.
45
+ - `viewerLapsed` — `true` when `viewer` is the identity this device *remembers* and the platform's answer came back anonymous: the sign-in lapsed (an expired session, a cold boot before auth restores), rather than the person signing out. Keep rendering their stuff — the local data is still theirs, and writes queue locally and sync once they sign back in — and offer a quiet "Sign back in to sync" nudge wired to `requestLogin()`. Never fall back to the anonymous copy ("Sign in to get started") while `viewerLapsed` is true; that reads as if their work is gone. `can()` and every write gate stay closed while lapsed, so gate *writes* on `can`, not on this flag, and `isViewerPending` is `false` (lapsed is a settled state, not a loading one).
46
+ - `requestLogin()` — opens the platform sign-in UI. Fire-and-forget: there is nothing to await and no result to branch on, because the new identity arrives on its own through `viewer`. This is how your app asks — see **Asking a visitor to sign in** below.
47
+ - `ViewerTag` — ready-made user pill; see the ViewerTag section below.
48
+
49
+ ## Gating UI
50
+
51
+ Gate the comment form on `useVibe("comments").can` — not on `viewer`. The current viewer never needs a pill here (that's in the Vibes Switch); just render the gated form, and on a denial a sentence in your app's own words — `reason` is a machine token that informs that sentence and is never printed:
52
+
53
+ App.jsx
54
+
55
+ ```jsx
56
+ <<<<<<< SEARCH
57
+ import { useViewer } from "use-vibes";
58
+ =======
59
+ import { useViewer, useVibe } from "use-vibes";
60
+ >>>>>>> REPLACE
61
+ ```
62
+
63
+ App.jsx
64
+
65
+ ```jsx
66
+ <<<<<<< SEARCH
67
+ const { viewer, isViewerPending } = useViewer();
68
+ =======
69
+ const { viewer, isViewerPending } = useViewer();
70
+ const { can, ready, me } = useVibe("comments");
71
+ >>>>>>> REPLACE
72
+ ```
73
+
74
+ App.jsx
75
+
76
+ ```jsx
77
+ <<<<<<< SEARCH
78
+ {viewer ? (
79
+ <p>Welcome back, {viewer.displayName ?? viewer.userHandle}!</p>
80
+ ) : (
81
+ <p>Everything you make here is saved on this device.</p>
82
+ )}
83
+ =======
84
+ {/* write gate: useVibe().can, not viewer */}
85
+ {!ready ? null : (() => {
86
+ const v = can.create({ type: "comment", postId, authorHandle: me?.userHandle });
87
+ return v.ok ? (
88
+ <form>
89
+ <input placeholder="Add a comment..." />
90
+ <button type="submit">Post</button>
91
+ </form>
92
+ ) : (
93
+ // Your own words, informed by v.reason — never the token itself.
94
+ <p>Sign in to add a comment.</p>
95
+ );
96
+ })()}
97
+ >>>>>>> REPLACE
98
+ ```
99
+
100
+ ## Tagging content with the viewer (write/render pattern)
101
+
102
+ When one user writes content others will see (comments, posts, messages), **stamp `authorHandle` on the doc at write time**, and stamp the id of the thing it belongs to beside it (`postId`, `boardId`, `listId`). Render the author with `<ViewerTag userHandle={doc.authorHandle} />` which resolves display name and avatar automatically. Do not stamp `displayName` or `avatarUrl` on docs — ViewerTag handles that from the handle alone.
103
+
104
+ Wire up a full comment thread with Fireproof and viewer attribution:
105
+
106
+ App.jsx
107
+
108
+ ```jsx
109
+ <<<<<<< SEARCH
110
+ import { useViewer, useVibe } from "use-vibes";
111
+ =======
112
+ import { useViewer, useVibe } from "use-vibes";
113
+ >>>>>>> REPLACE
114
+ ```
115
+
116
+ ```jsx
117
+ <<<<<<< SEARCH
118
+ const { viewer, isViewerPending } = useViewer();
119
+ const { can, ready, me } = useVibe("comments");
120
+ =======
121
+ const { viewer, isViewerPending, ViewerTag } = useViewer();
122
+ const { can, ready, me } = useVibe("comments");
123
+ const { useLiveQuery, database } = useFireproof("comments");
124
+ // Every comment names the post it belongs to. A thread shows one post, so
125
+ // its id is fixed here. An app where each person has a space of their own
126
+ // derives the id from the viewer's handle instead (`default-${me.userHandle}`)
127
+ // once `ready` says the handle is known, so the first write lands in a space
128
+ // that is theirs and stays theirs.
129
+ const postId = "post:welcome";
130
+ const { docs: comments } = useLiveQuery("postId", { key: postId });
131
+ const [body, setBody] = React.useState("");
132
+ >>>>>>> REPLACE
133
+ ```
134
+
135
+ ```jsx
136
+ <<<<<<< SEARCH
137
+ {/* write gate: useVibe().can, not viewer */}
138
+ {!ready ? null : (() => {
139
+ const v = can.create({ type: "comment", authorHandle: me?.userHandle });
140
+ return v.ok ? (
141
+ <form>
142
+ <input placeholder="Add a comment..." />
143
+ <button type="submit">Post</button>
144
+ </form>
145
+ ) : (
146
+ // Your own words, informed by v.reason — never the token itself.
147
+ <p>Sign in to add a comment.</p>
148
+ );
149
+ })()}
150
+ =======
151
+ {/* render OTHER users with userHandle — that's what ViewerTag is for here */}
152
+ <ul>
153
+ {comments.map((c) => (
154
+ <li key={c._id}>
155
+ <ViewerTag userHandle={c.authorHandle} />
156
+ <p>{c.body}</p>
157
+ </li>
158
+ ))}
159
+ </ul>
160
+
161
+ {/* write gate: useVibe().can, not viewer */}
162
+ {!ready ? null : (() => {
163
+ const v = can.create({ type: "comment", postId, authorHandle: me?.userHandle });
164
+ return v.ok ? (
165
+ <form onSubmit={(e) => { e.preventDefault(); post(); }}>
166
+ <input value={body} onChange={(e) => setBody(e.target.value)} placeholder="Add a comment..." />
167
+ <button type="submit">Post</button>
168
+ </form>
169
+ ) : (
170
+ // Your own words, informed by v.reason — never the token itself.
171
+ <p>Sign in to add a comment.</p>
172
+ );
173
+ })()}
174
+ >>>>>>> REPLACE
175
+ ```
176
+
177
+ Also add the `post` handler before `if (isViewerPending)`:
178
+
179
+ ```jsx
180
+ <<<<<<< SEARCH
181
+ if (isViewerPending) return null;
182
+ =======
183
+ async function post() {
184
+ if (!body.trim()) return;
185
+ await database.put({
186
+ type: "comment",
187
+ postId, // the id of the thing this record belongs to, on the record itself
188
+ body: body.trim(),
189
+ createdAt: Date.now(),
190
+ authorHandle: me?.userHandle,
191
+ });
192
+ setBody("");
193
+ }
194
+
195
+ if (isViewerPending) return null;
196
+ >>>>>>> REPLACE
197
+ ```
198
+
199
+ Key points:
200
+
201
+ - **Stamp `authorHandle` at write time** — persist the author's handle on the doc. Render with `<ViewerTag userHandle={authorHandle} />` which resolves display name and avatar automatically.
202
+ - **Name the thing it belongs to** — every record carries the id of its parent object (`postId`, `boardId`, `listId`), written at create and left alone afterwards. Queries read off it, and so does everything the app grows later.
203
+ - **Give each person a default object of their own** — `` `default-${me.userHandle}` `` — so someone who has just arrived types once and it lands, with no object for them to create first. An object someone does make carries `creatorHandle: me.userHandle`.
204
+ - **Avatars are stable** — ViewerTag resolves the avatar from the handle; if the author changes their avatar, the URL stays the same and the bytes update. ViewerTag handles this for you.
205
+ - **One source of identity** — persist `authorHandle` on the doc. ViewerTag does the rest.
206
+
207
+ ## Asking a visitor to sign in
208
+
209
+ An anonymous visitor is having a legitimately good time. Under local-first their work is already saved on their device and your app should keep working for them — the account buys **sync, followers and durability**, not permission. So the ask is an **offer to keep what they already have — never a wall in front of it**. A visitor who never signs in should still get a working app; one who does should feel like they kept something.
210
+
211
+ Three rules separate a CTA that converts from the two shapes that don't.
212
+
213
+ **Ask at the moment of value.** The ask lands when the person has just made something they'd hate to lose — posted their first comment, starred their first pick, saved their first note. A prompt on arrival asks a stranger to commit before they know what the app does; a prompt after the first save offers to keep something they can already see.
214
+
215
+ **Wire the ask to `requestLogin()`, never to a sentence about the logo.** Copy like "sign in via the logo" points at platform chrome outside your app's frame and sends the reader hunting for it. It is not a call to action and it does not convert. Render a real control: `<button onClick={requestLogin}>Keep these</button>`.
216
+
217
+ **Only ask once identity has settled.** `isViewerPending` is `true` while the platform is still resolving who's looking, and a CTA rendered in that window shows signed-in people a SIGN IN button on every load. Compute the settled-signed-out state once and gate on it — `const settledSignedOut = !isViewerPending && !viewer;`.
218
+
219
+ Layer it onto the comment app: the visitor can already read and post, and once they've posted, we offer to keep it.
220
+
221
+ ```jsx
222
+ <<<<<<< SEARCH
223
+ const { viewer, isViewerPending, ViewerTag } = useViewer();
224
+ =======
225
+ const { viewer, isViewerPending, ViewerTag, requestLogin } = useViewer();
226
+ >>>>>>> REPLACE
227
+ ```
228
+
229
+ ```jsx
230
+ <<<<<<< SEARCH
231
+ const [body, setBody] = React.useState("");
232
+ =======
233
+ const [body, setBody] = React.useState("");
234
+
235
+ // Settled AND anonymous — never merely anonymous, or signed-in viewers flash
236
+ // this on every load while their identity is still resolving (#3639).
237
+ const settledSignedOut = !isViewerPending && !viewer;
238
+ // The moment of value: a comment THIS visitor wrote. An anonymous write
239
+ // stamps `authorHandle: me?.userHandle` with `me` still null, so an undefined
240
+ // author is our own unclaimed work — which is exactly what signing in keeps.
241
+ // Reading `comments.length` instead would nag people who only ever read.
242
+ const hasSomethingToKeep = comments.some((c) => c.authorHandle === undefined);
243
+ >>>>>>> REPLACE
244
+ ```
245
+
246
+ ```jsx
247
+ <<<<<<< SEARCH
248
+ {/* write gate: useVibe().can, not viewer */}
249
+ =======
250
+ {settledSignedOut && hasSomethingToKeep && (
251
+ <div>
252
+ {/* Says what they GET. Never "you must sign in to continue" — they
253
+ can continue, and their comment above is already saved locally.
254
+ And never "post it under your name": signing in syncs the comment
255
+ they already wrote, it does not rewrite the author stamped on it.
256
+ Promise continuity, which is true — not attribution, which isn't. */}
257
+ <p>Your comment is saved on this device.</p>
258
+ <button onClick={requestLogin}>Sign in to keep it on all your devices</button>
259
+ </div>
260
+ )}
261
+
262
+ {/* write gate: useVibe().can, not viewer */}
263
+ >>>>>>> REPLACE
264
+ ```
265
+
266
+ Copy that works, and copy that doesn't:
267
+
268
+ | Write this | Not this |
269
+ | --- | --- |
270
+ | "Sign in to sync your picks everywhere" | "Sign in to continue" |
271
+ | "Keep these on all your devices" | "You must sign in to save" |
272
+ | "Saved on this device — sign in to sync" | "Sign in via the Vibes DIY logo" |
273
+
274
+ And never disable the app's real controls on `!viewer`. If favoriting works signed out, keep it working signed out — the platform refuses the *cloud* write on its own, calmly, while the local write still succeeds. Turning a working app into a signup wall is worse than never asking at all.
275
+
276
+ ## Notes
277
+
278
+ - Never use Clerk user IDs. Only `userHandle` crosses into vibe code.
279
+ - Avatar URLs are stable indirection URLs — when a user changes their avatar, the URL stays the same and the bytes update. Treat them as opaque strings.
280
+ - To gate a write surface, use `useVibe(dbName).can` — asked about the document you are about to write. The server is the authority either way; `can` is the app's faithful preview of its answer.
281
+
282
+ ## ViewerTag
283
+
284
+ `ViewerTag` is a ready-made inline user pill returned alongside `viewer` from `useViewer()`. It is not a separate import — you get it from the hook. **Use it to render _other_ people** — comment authors, roster rows, "added by" labels — by passing `userHandle`:
285
+
286
+ ```jsx
287
+ {/* Show another user read-only: */}
288
+ <ViewerTag userHandle={comment.authorHandle} />
289
+ {/* Style override: */}
290
+ <ViewerTag userHandle={member.userHandle} style={{ borderRadius: 8, fontSize: 12 }} />
291
+ ```
292
+
293
+ **The current viewer's pill is system chrome, not app UI.** The platform already shows the current user inside the Vibes Switch that opens from the logo, so don't add a no-prop `<ViewerTag />` as a header pill just to show who's signed in; reach for `userHandle` to render someone else instead. To *ask* an anonymous visitor to sign in, use `requestLogin()` and your own copy (see **Asking a visitor to sign in**) — that ask belongs at the moment of value, which is a place only your app knows.
294
+
295
+ **The one in-app reason to render a no-prop `<ViewerTag />` is inline avatar self-edit.** A no-prop tag shows the signed-in viewer a dashed edit ring that lets them change their _own_ avatar in place, and that works for **every** signed-in viewer — the Switch's avatar editing is owner-only. So if your app wants any member (not just the owner) to update their photo without leaving the app, render a guarded `{viewer && <ViewerTag />}` for that — otherwise leave the current-viewer pill to the Switch.
296
+
297
+ **Undefined safety.** If `userHandle` is present in props but falsy (e.g. a missing field from a loop lookup), `ViewerTag` renders a dim italic placeholder instead of the edit ring. This prevents a broken data source from accidentally turning an arbitrary pill into a photo-edit control.
298
+
299
+ **Anonymous & always-safe.** `ViewerTag` never throws regardless of login state. A no-prop `<ViewerTag />` renders a "Sign in" button for anonymous viewers — a fine fallback, but it is an identity chip in whatever spot you put it, not a CTA you can word or time. When the goal is conversion, write the prompt yourself and wire it to `requestLogin()`.
300
+
301
+ **Theming.** `ViewerTag` reads the canonical palette variables — `--surface`, `--text-primary`, `--border`, and `--accent` (plus optional `--accent-text` to override the on-accent text color) — from the app's CSS with sensible fallbacks. If your app defines these on `:root` (which every generated theme does), `ViewerTag` inherits the theme automatically with no extra props. The one exception is the signed-out **Sign in** CTA, which deliberately stays the Vibes brand blue: it is a platform affordance matched to the Vibes Switch shown to the same visitor, so it is not theme-inherited.
302
+
303
+ Pass `<ViewerTag userHandle={...} />` to render other people. Reach for the no-prop `<ViewerTag />` when you specifically want inline avatar self-edit for any signed-in member; for the current-user pill the Switch already covers it, and for a sign-in ask use `requestLogin()`.
@@ -2,6 +2,7 @@ export const useViewerConfig = {
2
2
  name: "use-viewer",
3
3
  label: "Viewer Identity",
4
4
  description: "Get the current viewer's identity and capability gates",
5
+ initialVariant: true,
5
6
  importModule: "use-vibes",
6
7
  importName: "useViewer",
7
8
  };
@@ -1 +1 @@
1
- {"version":3,"file":"use-viewer.js","sourceRoot":"","sources":["../../jsr/llms/use-viewer.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,IAAI,EAAE,YAAY;IAClB,KAAK,EAAE,iBAAiB;IACxB,WAAW,EAAE,wDAAwD;IACrE,YAAY,EAAE,WAAW;IACzB,UAAU,EAAE,WAAW;CACxB,CAAC"}
1
+ {"version":3,"file":"use-viewer.js","sourceRoot":"","sources":["../../jsr/llms/use-viewer.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,IAAI,EAAE,YAAY;IAClB,KAAK,EAAE,iBAAiB;IACxB,WAAW,EAAE,wDAAwD;IACrE,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE,WAAW;IACzB,UAAU,EAAE,WAAW;CACxB,CAAC"}
@@ -319,3 +319,23 @@ async function assign(handle) {
319
319
  }
320
320
  <HandleInput onChange={assign} placeholder="Add a teammate…" />;
321
321
  ```
322
+
323
+ ### Adding a member to your own object — the canonical use
324
+
325
+ Almost every app works this way — a shared list, a board, a trip, a club's page, a tracker one person starts and later shares with a coach: each signed-in person has their own object and lets a friend into it by picking them here. The write is one small membership doc, and `access.js` turns that doc into the grant that gives the named person the object's channel (see access.md's per-object sharing examples). Keys on the picked handle and on the writer's own — the app owner has no special place in it.
326
+
327
+ ```jsx
328
+ const { HandleInput } = useViewer();
329
+ const { me, can } = useVibe("boards");
330
+ // Show the picker to whoever the access fn would accept as an inviter.
331
+ const canInvite = can.create({ type: "member", boardId: board._id, userHandle: "x", addedBy: me?.userHandle }).ok;
332
+
333
+ async function addMember(handle) {
334
+ if (!handle) return;
335
+ await database.put({ type: "member", boardId: board._id, userHandle: handle, addedBy: me.userHandle });
336
+ }
337
+
338
+ {canInvite && <HandleInput onChange={addMember} placeholder="Add a friend…" />}
339
+ ```
340
+
341
+ Members render with `<ViewerTag userHandle={m.userHandle} />`, the same way any other stored handle does. An app the person asked to keep to themselves — "just for me", "no sharing", "no access control" — needs none of this; everywhere else the picker belongs.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibes.diy/prompts",
3
- "version": "14.1.20",
3
+ "version": "14.1.22",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "exports": {
@@ -34,9 +34,9 @@
34
34
  "license": "Apache-2.0",
35
35
  "dependencies": {
36
36
  "@adviser/cement": "~0.5.34",
37
- "@vibes.diy/call-ai-v2": "14.1.20",
38
- "@vibes.diy/identity": "14.1.20",
39
- "@vibes.diy/use-vibes-types": "14.1.20",
37
+ "@vibes.diy/call-ai-v2": "14.1.22",
38
+ "@vibes.diy/identity": "14.1.22",
39
+ "@vibes.diy/use-vibes-types": "14.1.22",
40
40
  "arktype": "~2.2.3",
41
41
  "json-schema-faker": "~0.6.3"
42
42
  },
package/prompts.js CHANGED
@@ -191,8 +191,9 @@ export async function makeBaseSystemPrompt(model, sessionDoc) {
191
191
  const chosenLlms = llmsCatalog.filter((l) => selectedNames.includes(l.name));
192
192
  const concatenatedLlmsTxts = [];
193
193
  for (const llm of chosenLlms) {
194
- const rText = await keyedLoadAsset.get(llm.name).once(async () => {
195
- return loadAsset(`./llms/${llm.name}.md`, {
194
+ const docFile = isFirstTurn && llm.initialVariant === true ? `${llm.name}.initial.md` : `${llm.name}.md`;
195
+ const rText = await keyedLoadAsset.get(docFile).once(async () => {
196
+ return loadAsset(`./llms/${docFile}`, {
196
197
  fallBackUrl: pkgBaseUrl,
197
198
  basePath: () => import.meta.url,
198
199
  mock: {
@@ -201,7 +202,7 @@ export async function makeBaseSystemPrompt(model, sessionDoc) {
201
202
  });
202
203
  });
203
204
  if (rText.isErr()) {
204
- console.warn(`Failed to load text for LLM ${llm.name} at path ${import.meta.dirname}/./llms/${llm.name}.md:`, rText.Err());
205
+ console.warn(`Failed to load text for LLM ${llm.name} at path ${import.meta.dirname}/./llms/${docFile}:`, rText.Err());
205
206
  continue;
206
207
  }
207
208
  concatenatedLlmsTxts.push(`<${llm.label}-docs>`);
package/prompts.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../jsr/prompts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../jsr/prompts.ts"],"names":[],"mappings":"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"}
@@ -106,7 +106,9 @@ Use these import statements verbatim at the top of the `App.jsx` block:
106
106
  The app's permission rules are designed later, at publish — from the documents the app writes. Rules can only key on what documents already carry, so shape every document so richer sharing can be attached later without reshaping the app:
107
107
 
108
108
  - **Stamp the writer on every user-authored doc.** Put the author's handle in the canonical field `authorHandle: me?.userHandle` (`me` from `useVibe(dbName)` — the client-side identity) on each doc a person creates, even when the UI never displays it. "Only the author can edit" is impossible to add later if the docs don't record who the author is.
109
- - **Carry the parent id on every child doc.** A comment, item, reaction, or member doc stores the id of the thing it belongs to (`listId`, `boardId`, `postId`, `rideId`, …). Queries need it, and later sharing rules route reads/writes off it.
109
+ - **Carry the parent id on every child doc.** A comment, item, reaction, or member doc stores the id of the thing it belongs to (`listId`, `boardId`, `postId`, `rideId`, …), written at create and left alone afterwards. Queries need it, and later sharing rules route reads/writes off it.
110
+ - **Stamp the creator on the object itself.** The list, board, trip or space a person makes carries `creatorHandle: me.userHandle` — the child docs' `authorHandle` says who wrote each record, and this says whose object they are in.
111
+ - **Give each person a default object derived from their own handle.** `` `default-${me.userHandle}` `` is the id a child doc names when the person picked no object, so a brand-new visitor's first write lands with nothing for them to create first. It needs no document of its own, and an app one person keeps for themselves is simply this with one object in it.
110
112
  - **Deterministic `_id`s for one-per-user-per-thing docs.** A single vote/RSVP/favorite per person per parent uses an `_id` that embeds the handle and parent — `favorite-<handle>-<parentId>` — so re-writes replace rather than duplicate, and one-per-user rules have something to key on.
111
113
  - **Store sharing choices as doc fields, not client state.** Any "share with friends" / "make public" toggle the UI offers is persisted as a boolean on the doc (`isPublic`, `sharedWithFollowers`), never held only in React state — later access rules read the field, not the UI.
112
114
  - **Defer secrets and PII until rules exist.** Do not create doc types holding capability tokens, phone numbers, or other contact/PII on this turn, or flag them prominently if unavoidable — data written before sharing rules exist cannot be un-exposed.
@@ -108,7 +108,9 @@ Use these import statements verbatim at the top of the `App.jsx` block:
108
108
  The app's permission rules are designed later, at publish — from the documents the app writes. Rules can only key on what documents already carry, so shape every document so richer sharing can be attached later without reshaping the app:
109
109
 
110
110
  - **Stamp the writer on every user-authored doc.** Put the author's handle in the canonical field `authorHandle: me?.userHandle` (`me` from `useVibe(dbName)` — the client-side identity) on each doc a person creates, even when the UI never displays it. "Only the author can edit" is impossible to add later if the docs don't record who the author is.
111
- - **Carry the parent id on every child doc.** A comment, item, reaction, or member doc stores the id of the thing it belongs to (`listId`, `boardId`, `postId`, `rideId`, …). Queries need it, and later sharing rules route reads/writes off it.
111
+ - **Carry the parent id on every child doc.** A comment, item, reaction, or member doc stores the id of the thing it belongs to (`listId`, `boardId`, `postId`, `rideId`, …), written at create and left alone afterwards. Queries need it, and later sharing rules route reads/writes off it.
112
+ - **Stamp the creator on the object itself.** The list, board, trip or space a person makes carries `creatorHandle: me.userHandle` — the child docs' `authorHandle` says who wrote each record, and this says whose object they are in.
113
+ - **Give each person a default object derived from their own handle.** `` `default-${me.userHandle}` `` is the id a child doc names when the person picked no object, so a brand-new visitor's first write lands with nothing for them to create first. It needs no document of its own, and an app one person keeps for themselves is simply this with one object in it.
112
114
  - **Deterministic `_id`s for one-per-user-per-thing docs.** A single vote/RSVP/favorite per person per parent uses an `_id` that embeds the handle and parent — `favorite-<handle>-<parentId>` — so re-writes replace rather than duplicate, and one-per-user rules have something to key on.
113
115
  - **Store sharing choices as doc fields, not client state.** Any "share with friends" / "make public" toggle the UI offers is persisted as a boolean on the doc (`isPublic`, `sharedWithFollowers`), never held only in React state — later access rules read the field, not the UI.
114
116
  - **Defer secrets and PII until rules exist.** Do not create doc types holding capability tokens, phone numbers, or other contact/PII on this turn, or flag them prominently if unavoidable — data written before sharing rules exist cannot be un-exposed.
package/system-prompt.md CHANGED
@@ -523,7 +523,9 @@ docs in your database, and never build follow UI state machines.
523
523
 
524
524
  **`access.js` must be one self-contained exported function.** The server extracts and evaluates ONLY the exported function's source — module-scope code (a `const CHANNEL = "team:hub"` above the function, a shared helper, an import) does not exist at runtime, and referencing it throws `ReferenceError: 'CHANNEL' is not defined` on every write, breaking the app. Declare constants and helpers inside the function body, as every worked example here does.
525
525
 
526
- **A single-user tool needs no membership gate — don't invent collaboration the prompt didn't ask for.** Many apps are one person making their own things: an image generator, a "describe X → make X" tool, a solo tracker/composer/calculator. Its user must be able to create from first load with no one letting them in. The failure to avoid: wrapping the primary write in `ctx.requireAccess(channel)` (or a roster / `requireRole` gate) so the signed-in maker hits "not in channel / request to join" on the very app they just made, or a members-only wall that hides the compose input until they "join." Membership machinery — `ctx.requireAccess`, roster approval, `request`/`share` docs, a "request to join" CTA — belongs ONLY where the prompt explicitly asks people to collaborate on, join, or share a space. For a solo tool the right shape is author-owned writes: stamp `authorHandle: user.userHandle` on each doc and let the author check accept it (self-granting each object its own channel is fine — requiring _pre-existing_ membership to write is not), or `allowAnonymous: true` in `access.js` for a no-sign-in tool — gate the write surface the usual way (`ready` for pending identity/access resolution, then `can.create(candidate).ok` for the affordance itself), which works for anonymous visitors too: once `allowAnonymous` opts them in, the access fn accepts `user === null` and `can.create()` returns the real verdict rather than `authentication required`. The footgun is gating the affordance on `can.create()` _without_ setting `allowAnonymous` — then it stays `authentication required` and the control vanishes for the very guests it's for.
526
+ **Every app gets record rules, and the group shape is the default.** Whatever the prompt's pronouns, build the app so a second person can be let in later: a habit tracker one person keeps is the same shape with one object in it, and a coach they invite next month is a grant on an object that already exists. Leave `access.js` out only when the person asks for that in their own words — "no access control", "keep it single-user", "no sharing". The shape that carries both is author-owned writes on the object's own channel, self-granted at creation: stamp `authorHandle: user.userHandle` on each doc, key the object on its own `creatorHandle`, and let the author check accept the first write, so a signed-in visitor creates from first load with nobody letting them in. Save `ctx.requireAccess(channel)` (and roster / `requireRole` gates) for records that already exist — asking for _pre-existing_ membership to create is what puts "not in channel / request to join" in front of the maker on the very app they just made, or hides the compose input behind a "join" wall. For a tool that wants no sign-in at all, `allowAnonymous: true` in `access.js` opts guests in, and the write surface is then gated the usual way (`ready` for pending identity/access resolution, then `can.create(candidate).ok` for the affordance itself) — once `allowAnonymous` opts them in, the access fn accepts `user === null` and `can.create()` returns the real verdict rather than `authentication required`. The footgun is gating the affordance on `can.create()` _without_ setting `allowAnonymous` — then it stays `authentication required` and the control vanishes for the very guests it's for.
527
+
528
+ **A group-shaped ask — more than one person acting on the same records: several people adding, voting, sharing or joining, or a named group such as roommates, a book club or a team keeping records together — gives each signed-in person their own object plus a way to invite others into it with the platform's `HandleInput` (from `useViewer()`), and keys its rules on that object's own creator (`doc.creatorHandle === user.userHandle`), which places the app owner exactly where everyone else stands.**
527
529
 
528
530
  **The owner must never be locked out of their own app.** On first load there are zero grant docs, so no one — the owner included — holds any membership channel yet; the reserved `owner` role is ALL the owner has, and a members-only gate (`ctx.requireAccess(ch)`) denies the owner exactly like a stranger. Two rules keep the owner in. In `access.js`: when a grant branch is itself owner-gated (`ctx.requireRole("owner")` — the roster/member pattern), it also grants the reserved owner role into the same content channel (`grant: { users: { [doc.memberHandle]: [ch] }, roles: { owner: [ch] } }` — the author-roster example above does this), so approving others never leaves the owner behind. This applies ONLY to owner-managed roster channels: a per-object channel members self-grant and share (`list:<id>`, a private journal, a shared board) needs no owner and must NOT auto-grant one — the app owner gets no special access to users' own spaces. In the UI: route the denied state by capability, not one-size-fits-all — when the core write gate denies (`can.create({ type: "post", ... }).ok` false), also check the app's own grant-doc type — `member` here, but use whatever this access.js names it (`author`, `share`, `approve`): `can.create({ type: "member", userHandle: me?.userHandle }).ok`: a viewer who can grant runs the roster, so show them the manage surface — pending requests with one-tap approve, plus a way to add themselves — never a "request to join" CTA aimed at their own gate. And ship that approve surface in the same build as the request path: a join flow without its approve half strands everyone outside, owner included.
529
531