@vibes.diy/prompts 2.6.0 → 2.6.1

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/d3.md CHANGED
@@ -179,7 +179,6 @@ svg.append("g")
179
179
  svg.append("g")
180
180
  .attr("transform", `translate(${margin.left},0)`)
181
181
  .call(d3.axisLeft(y));
182
- </script>
183
182
  ```
184
183
 
185
184
  ### 2. Interactive Scatter Plot
package/llms/fireproof.md CHANGED
@@ -394,7 +394,7 @@ The access function is the single source of truth for permissions. Gate write su
394
394
 
395
395
  This example shows the full round-trip — access.js declares channels and grants; App.jsx reads them back via `access`. Key details:
396
396
 
397
- - **Owner bootstrap:** the vibe owner is auto-seeded into the reserved `owner` role, so gate management operations (channel setup, role grants, moderation) on `ctx.requireRole("owner")` — **never `user.isOwner`** (`isOwner` is being retired from the access-fn `user`). No bootstrap problem — the seed means the owner can manage without a prior grant. Default content, though, should be author-owned (anyone signed-in creates and edits their own); reserve owner-gating for shared admin surfaces.
397
+ - **Owner bootstrap:** the vibe owner is auto-seeded into the reserved `owner` role, so gate management operations (channel setup, role grants, moderation) on `ctx.requireRole("owner")` — **never on a display flag** (the UI gates on `can.*`). No bootstrap problem — the seed means the owner can manage without a prior grant. Default content, though, should be author-owned (anyone signed-in creates and edits their own); reserve owner-gating for shared admin surfaces.
398
398
  - **Channel identity:** Channel docs use `_id: "ch:" + name` so names are unique. The `_id` is the channel identifier everywhere — in `channels`, `grant`, and `ctx.requireAccess()`.
399
399
  - **Channel grant:** A channel document grants the creator (`grant.users`), adds `grant.public` so all members can read, and `grant.roles` so posters can write.
400
400
  - **Write surfaces** are gated with `useVibe(dbName).can.create/edit/delete` — it runs this same access function, so the UI verdict matches the server. Render `.reason` when denied. (See use-vibe docs.)
@@ -444,7 +444,7 @@ export function announcements(doc, oldDoc, user, ctx) {
444
444
  }
445
445
  ```
446
446
 
447
- App.jsx — `useVibe().can` gates every write surface (posts AND owner-only management); `access.hasChannel()` reflects display-only membership; `isOwner` is a display hint only:
447
+ App.jsx — `useVibe().can` gates every write surface (posts AND owner-only management); `access.hasChannel()` reflects display-only membership:
448
448
 
449
449
  ```jsx
450
450
  import React from "react";
@@ -500,7 +500,7 @@ export default function App() {
500
500
  viewer && <p style={{ color: "var(--muted, #888)" }}>{canPost.reason}</p>
501
501
  )}
502
502
 
503
- {/* owner-only management — gated on can.*, not isOwner */}
503
+ {/* owner-only management — gated on can.* */}
504
504
  {canGrant.ok && (
505
505
  <button onClick={() => database.put({ type: "roleGrant", role: "poster", userHandle: "newUser" })}>
506
506
  Grant poster role
@@ -519,21 +519,12 @@ export default function App() {
519
519
  }
520
520
  ```
521
521
 
522
- The pattern: `useVibe().can` gates every write surface — including owner-only management, which the access function enforces via `ctx.requireRole("owner")` so `can.create({ type: "roleGrant", … })` is false for non-owners. `access.hasChannel()` reflects display-only membership, and `isOwner` is a display hint only, never the write gate. The access function is the server-side authority — `useVibe().can` is how the UI reflects its decisions for writes.
522
+ The pattern: `useVibe().can` gates every write surface — including owner-only management, which the access function enforces via `ctx.requireRole("owner")` so `can.create({ type: "roleGrant", … })` is false for non-owners. `access.hasChannel()` reflects display-only membership; the write gate is always `can.*`. The access function is the server-side authority — `useVibe().can` is how the UI reflects its decisions for writes.
523
523
 
524
- **Owner-management panels (appoint/revoke moderators, grant/revoke roles) gate on `can.*`, not `isOwner`.** It's tempting to wrap an admin panel in `{isOwner && <ModeratorPanel />}` and have its buttons call `database.put`/`database.del` directly. Don't let `isOwner` be what decides a write it's the same display hint as everywhere else. Gate each mutating control on the verdict from the doc you'll actually write appoint on `can.create({ type: "modGrant", role: "moderator", userHandle }).ok`, revoke on `can.delete(grantDoc).ok` — and render `.reason` when denied. `can.*` runs the app's own `access.js` to produce the verdict, so the control's enabled state and message track what the access function decides and stay correct as it grows beyond owner-only (a delegated admin role, say). Gate the panel's *visibility* on those same verdicts too, not `isOwner` alone — otherwise a delegated admin the access function now allows never reaches the controls or their reason.
524
+ **Owner-management panels (appoint/revoke moderators, grant/revoke roles) gate on `can.*`.** Gate each mutating control and the panel's visibilityon the `can.*` verdict from the doc you'll actually write: appoint on `can.create({ type: "modGrant", role: "moderator", userHandle }).ok`, revoke on `can.delete(grantDoc).ok` — and render `.reason` when denied. `can.*` runs the app's own `access.js` to produce the verdict, so the control's enabled state and message track what the access function decides and stay correct as the rule grows beyond owner-only (a delegated admin role, say).
525
525
 
526
526
  ```jsx
527
- // Don't: isOwner decides visibility AND the writes are ungated a non-owner the
528
- // access function would allow never reaches the controls, and isOwner drifts from access.js
529
- {isOwner && (
530
- <ModeratorPanel>
531
- <button onClick={() => database.put({ type: "modGrant", role: "moderator", userHandle })}>Appoint</button>
532
- <button onClick={() => database.del(grantDoc._id)}>Revoke</button>
533
- </ModeratorPanel>
534
- )}
535
-
536
- // Do: can.* decides visibility AND gates each write, and supplies the denial reason
527
+ // Gate visibility AND each write on the can.* verdict, and supply the denial reason
537
528
  const canAppoint = can.create({ type: "modGrant", role: "moderator", userHandle });
538
529
  const canRevoke = can.delete(grantDoc);
539
530
  {(canAppoint.ok || canRevoke.ok) && (
@@ -601,7 +592,7 @@ App.jsx — `access.hasChannel()` filters which channels are visible (display);
601
592
  {viewer && access.hasChannel(channel) && (
602
593
  =======
603
594
  {/* filter to channels the viewer can see — use _id as channel identifier (display only) */}
604
- {channels.filter((ch) => isOwner || access.hasChannel(ch._id)).map((ch) => (
595
+ {channels.filter((ch) => access.hasChannel(ch._id)).map((ch) => (
605
596
  <button key={ch._id} onClick={() => setChannel(ch._id)}>{ch.name}</button>
606
597
  ))}
607
598
 
package/llms/use-vibe.md CHANGED
@@ -10,22 +10,22 @@ Pass the Fireproof database name you are writing to. You get:
10
10
 
11
11
  - `can.create(draft)` / `can.edit(doc)` / `can.delete(doc)` → `{ ok: boolean, reason?: string }`. Gate the write surface on `.ok`; when `!ok`, render `.reason` as the fallback copy (e.g. "authentication required", "not in channel: team").
12
12
  - `ready` — `false` until identity and the access function have resolved. While `false`, show a neutral skeleton or disabled control; gating on it avoids a flash of the wrong state.
13
- - `me` — `{ userHandle, displayName?, isOwner } | null` (null = anonymous). For display only.
13
+ - `me` — `{ userHandle, displayName? } | null` (null = anonymous). For display only.
14
14
 
15
15
  **Build the candidate from the doc you'll actually write.** `can.create(draft)` runs the access function against `draft`, so `draft` must carry the fields the function checks — `authorHandle`, `channelId`, etc. A bare `can.create({ type: "post" })` gets denied (e.g. `"not author"`) and hides the form even from users who could post. Stamp the same fields you'll `put`: `can.create({ type: "post", channelId, authorHandle: me?.userHandle })`. And gate the **same database** you write to — `useVibe(dbName)` selects the access function and grants by `dbName`, so a gate on a different db won't reflect server enforcement.
16
16
 
17
17
  ## The rule
18
18
 
19
- Gate every write affordance on `can.*`. Render `reason` when denied. Never branch write permission on `viewer`, `isOwner`, `access.hasRole()`/`access.hasChannel()`, or document fields — those drift from what `access.js` actually does. Identity display (avatars, "signed in as") comes from `useViewer()`'s `ViewerTag`, not from `useVibe`.
19
+ Gate every write affordance on `can.*`. Render `reason` when denied. Never branch write permission on `viewer`, `access.hasRole()`/`access.hasChannel()`, or document fields — those drift from what `access.js` actually does. Identity display (avatars, "signed in as") comes from `useViewer()`'s `ViewerTag`, not from `useVibe`.
20
20
 
21
21
  ```jsx
22
22
  import { useVibe, useViewer } from "use-vibes";
23
23
 
24
24
  function PromptBar({ database }) {
25
- const { can, ready } = useVibe("aestheticBoard");
25
+ const { can, ready, me } = useVibe("aestheticBoard");
26
26
  const { ViewerTag } = useViewer();
27
27
  if (!ready) return <div className="skeleton" />;
28
- const v = can.create({ type: "tile" });
28
+ const v = can.create({ type: "tile", authorHandle: me?.userHandle });
29
29
  if (!v.ok) return <p className="muted">{v.reason}</p>; // e.g. "authentication required"
30
30
  return (
31
31
  <form onSubmit={/* … */}>
@@ -39,7 +39,7 @@ function PromptBar({ database }) {
39
39
 
40
40
  ## Owner-only and role-gated surfaces
41
41
 
42
- Don't gate management UI on `isOwner` directly. Encode the rule in `access.js` (e.g. `ctx.requireRole("owner")` — the owner is auto-seeded into the reserved `owner` role) and gate the UI on `can.*` for that database — the verdict reflects the same rule. Per-row edit/delete affordances: `{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; reserve `requireRole("owner")` for genuinely owner-published apps and per-object channels for peer-to-peer sharing. Public-vs-private and the allowed-user list are the owner's runtime sharing settings, not `access.js`.
42
+ Don't gate management UI on a display flag directly. Encode the rule in `access.js` (e.g. `ctx.requireRole("owner")` — the owner is auto-seeded into the reserved `owner` role) and gate the UI on `can.*` for that database — the verdict reflects the same rule. Per-row edit/delete affordances: `{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; reserve `requireRole("owner")` for genuinely owner-published apps and per-object channels for peer-to-peer sharing. Public-vs-private and the allowed-user list are the owner's runtime sharing settings, not `access.js`.
43
43
 
44
44
  ## The server is still the authority
45
45
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  `useViewer()` is a **read-only window** into viewer identity. The platform owns the rules — who's the owner, who has been granted read or write — and `useViewer()` lets your app see who's signed in and render their identity. You cannot grant or revoke access from code; you can only reflect the runtime's verdict in your UI.
4
4
 
5
- Use `useViewer()` for identity and display only — `ViewerTag`, avatars, and showing who's signed in. **Write surfaces are gated with `useVibe(dbName).can`** (see use-vibe docs), not with `viewer`/`isOwner`/`access.*`.
5
+ Use `useViewer()` for identity and display only — `ViewerTag`, avatars, and showing who's signed in. **Write surfaces are gated with `useVibe(dbName).can`** (see use-vibe docs), not with `viewer`/`access.*`.
6
6
 
7
7
  ## Basic Usage
8
8
 
@@ -36,7 +36,6 @@ export default function App() {
36
36
 
37
37
  - `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.
38
38
  - `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`.
39
- - `isOwner` — `true` when the viewer owns this vibe. A display hint only (e.g. an "admin" badge). Gate owner-only management WRITES (settings, role grants, moderation) on `useVibe(dbName).can` — the access function encodes the owner-only rule — never on `isOwner`.
40
39
  - `can(action, dbName?)` — legacy ACL boolean for `"read"`/`"write"`/`"delete"`. Prefer `useVibe(dbName).can.create/edit/delete` for write gating; it runs the app's access function and returns a `reason`.
41
40
  - `ViewerTag` — ready-made user pill; see the ViewerTag section below.
42
41
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibes.diy/prompts",
3
- "version": "2.6.0",
3
+ "version": "2.6.1",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "description": "",
@@ -30,9 +30,9 @@
30
30
  "@fireproof/core-types-base": "~0.24.19",
31
31
  "@fireproof/core-types-protocols-cloud": "~0.24.19",
32
32
  "@fireproof/use-fireproof": "~0.24.19",
33
- "@vibes.diy/call-ai-v2": "^2.6.0",
34
- "@vibes.diy/identity": "^2.6.0",
35
- "@vibes.diy/use-vibes-types": "^2.6.0",
33
+ "@vibes.diy/call-ai-v2": "^2.6.1",
34
+ "@vibes.diy/identity": "^2.6.1",
35
+ "@vibes.diy/use-vibes-types": "^2.6.1",
36
36
  "arktype": "~2.2.1",
37
37
  "json-schema-faker": "~0.6.2"
38
38
  },
package/prompts.js CHANGED
@@ -26,7 +26,7 @@ export async function resolveEffectiveModel(settingsDoc, vibeDoc) {
26
26
  export async function getDefaultSkills() {
27
27
  return ["fireproof", "callai", "image-gen", "web-audio", "use-vibe"];
28
28
  }
29
- const PRE_ALLOC_PLATFORM_PARAGRAPH = "Platform capabilities: every app is a small web app that anyone can open in a browser. Its data is saved automatically in the cloud and stays in sync for everyone at once, so when one person adds or changes something, everyone else viewing the app sees it update right away. Apps can call on a built-in AI assistant that returns a structured result the app saves and displays — for example suggesting or filling in a value, rewriting or extending something someone wrote, or tagging and scoring content as it's added. Apps know who is signed in, so they can show people's names and avatars next to their contributions. By default only the app's owner can make changes; everyone else sees a read-only view, and any editing controls are hidden automatically for people who aren't allowed to use them. When pictures are a natural part of the experience, an app can show a generated illustration instead of requiring an upload.";
29
+ const PRE_ALLOC_PLATFORM_PARAGRAPH = "Platform capabilities: every app is a small web app that anyone can open in a browser. Its data is saved automatically in the cloud and stays in sync for everyone at once, so when one person adds or changes something, everyone else viewing the app sees it update right away. Apps can call on a built-in AI assistant that returns a structured result the app saves and displays — for example suggesting or filling in a value, rewriting or extending something someone wrote, or tagging and scoring content as it's added. Apps know who is signed in, so they can show people's names and avatars next to their contributions. Most apps treat every signed-in visitor as a first-class participant who adds and edits their own contributions while everyone reads what others made; and many are built around a shared thing a group joins and co-edits — a list, a trip, a team space, a board or canvas people can ask to join — where the people who've joined edit it together and a newcomer can request in. Whichever fits, editing controls are hidden automatically for people who aren't allowed to use them. When pictures are a natural part of the experience, an app can show a generated illustration instead of requiring an upload.";
30
30
  export async function makePreAllocUserMessage(userPrompt) {
31
31
  const catalog = await getLlmCatalog();
32
32
  const catalogText = catalog.map((l) => `- ${l.name}: ${l.description}`).join("\n");
@@ -82,7 +82,7 @@ export const preAllocSchema = {
82
82
  "REQUIRED. A 3-sentence preamble that shapes THIS app around our platform's capabilities, written in plain user-friendly language a non-technical person would understand — dense narrative, no padding, no flourishes.",
83
83
  "Sentence 1: what users see and do in this app, and that what they add or change is saved and shared so everyone viewing the app sees the updates right away.",
84
84
  "Sentence 2: name the AI role that fits this app's central activity. Common roles to pick from: (a) suggest or autofill a field — the user taps a button next to an input and the built-in AI returns an example value drawn from the app's subject, ready to accept or edit; (b) critique or extend what someone wrote — the AI scores, rewrites, summarizes, or proposes the next thing (next line of a poem, follow-up task, related recipe); (c) tag, categorize, or score content as it's added — sentiment, topical tags, priority. Pick ONE role that genuinely fits this app. Name the user action that triggers it and what kind of result comes back.",
85
- "Sentence 3: name the things people can add or change in this app, and that only the owner (and anyone they allow) can make those changes while everyone else sees a read-only view, with the editing controls hidden automatically for people who aren't allowed to use them. If generated pictures are naturally part of the app, add a brief clause naming what a generated illustration would depict.",
85
+ "Sentence 3: name the things people can add or change in this app, and who changes them — pick the one that fits: for a personal tracker, journal, budget, or log, each person keeps their own and can invite a chosen buddy, partner, or coach to follow it; for a public wall, guestbook, or feed each signed-in visitor adds their own contributions while everyone reads the rest; for an app built around a shared thing a group joins and co-edits (a list, a trip, a team space, a board or canvas people can ask to join) the people who've joined edit the whole thing together and a newcomer can request in. Whichever fits, the editing controls are hidden automatically for people who aren't allowed to use them. If generated pictures are naturally part of the app, add a brief clause naming what a generated illustration would depict.",
86
86
  "Do NOT include developer language: no library names, no function or feature names, no field names in backticks, no code or data-shape objects. Write it the way you'd describe the finished product to someone who will use it, not build it.",
87
87
  "Do NOT invent imagery features when the app's subject wouldn't naturally include them.",
88
88
  ].join(" "),
package/prompts.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../jsr/prompts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAmB,MAAM,gBAAgB,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACnI,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAIxD,MAAM,CAAC,MAAM,6BAA6B,GAAG,2BAAoC,CAAC;AAElF,MAAM,CAAC,MAAM,oBAAoB,GAC/B,UAAU,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,6BAA6B,CAAC;AAEjG,KAAK,UAAU,kBAAkB;IAC/B,OAAO,oBAAoB,CAAC;AAC9B,CAAC;AAED,SAAS,wBAAwB,CAAC,EAAW;IAC3C,IAAI,OAAO,EAAE,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC7C,MAAM,OAAO,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;IAC1B,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,WAAgC,EAChC,OAAoC;IAEpC,MAAM,aAAa,GAAG,wBAAwB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACvE,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC;IACxC,MAAM,YAAY,GAAG,wBAAwB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAClE,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IACtC,OAAO,kBAAkB,EAAE,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,OAAO,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;AACvE,CAAC;AAWD,MAAM,4BAA4B,GAChC,65BAA65B,CAAC;AAUh6B,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,UAAkB;IAC9D,MAAM,OAAO,GAAG,MAAM,aAAa,EAAE,CAAC;IACtC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnF,MAAM,SAAS,GAAG,WAAW;SAC1B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;SACrH,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO;QACL,4BAA4B;QAC5B,EAAE;QACF,+UAA+U;QAC/U,EAAE;QACF,gBAAgB;QAChB,WAAW;QACX,EAAE;QACF,gBAAgB;QAChB,SAAS;QACT,EAAE;QACF,eAAe;QACf,UAAU;KACX,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAOD,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,WAAW;IACjB,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,CAAC;IAClE,UAAU,EAAE;QACV,MAAM,EAAE;YACN,IAAI,EAAE,OAAO;YACb,WAAW,EACT,2IAA2I;YAC7I,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SAC1B;QACD,KAAK,EAAE;YACL,IAAI,EAAE,OAAO;YACb,WAAW,EACT,kHAAkH;YACpH,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACzB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;iBACzB;aACF;SACF;QACD,eAAe,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,+TAA+T;SAClU;QACD,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,sXAAsX;SACzX;QACD,cAAc,EAAE;YACd,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE;gBACX,wNAAwN;gBACxN,8JAA8J;gBAC9J,goBAAgoB;gBAChoB,0YAA0Y;gBAC1Y,+OAA+O;gBAC/O,wFAAwF;aACzF,CAAC,IAAI,CAAC,GAAG,CAAC;SACZ;KACF;CACO,CAAC;AAYX,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE;IAC9B,KAAK,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE;IACxD,eAAe,EAAE,QAAQ;IACzB,QAAQ,EAAE,QAAQ;IAClB,aAAa,EAAE,QAAQ;IACvB,iBAAiB,EAAE,QAAQ;CAC5B,CAAC,CAAC;AAYH,MAAM,UAAU,wBAAwB,CAAC,IAAuB;IAC9D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,OAAO,IAAI;SACR,MAAM,CAAC,CAAC,CAAC,EAAuE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC;SAC3H,KAAK,EAAE;SACP,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;SAC5D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACZ,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;QAChD,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,UAAU,GAAG,CAAC,CAAC,UAAU,IAAI,OAAO,CAAC;QAC3C,QAAQ,UAAU,EAAE,CAAC;YACnB,KAAK,WAAW;gBACd,OAAO,iBAAiB,CAAC,CAAC,UAAU,UAAU,CAAC,CAAC,YAAY,GAAG,CAAC;YAClE,KAAK,SAAS;gBACZ,OAAO,YAAY,CAAC,CAAC,UAAU,UAAU,CAAC,CAAC,YAAY,GAAG,CAAC;YAC7D,KAAK,OAAO,CAAC;YACb;gBACE,OAAO,cAAc,CAAC,CAAC,UAAU,YAAY,CAAC,CAAC,YAAY,GAAG,CAAC;QACnE,CAAC;IACH,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,MAAM,cAAc,GAAG,IAAI,eAAe,EAAE,CAAC;AAe7C,MAAM,oBAAoB,GAAG,oCAAoC,CAAC;AAElE,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,KAAa,EACb,UAA+D;IAE/D,MAAM,UAAU,GAAG,UAAU,EAAE,UAAU,IAAI,EAAE,CAAC;IAChD,MAAM,UAAU,GAAG,UAAU,EAAE,UAAU,IAAI,oBAAoB,CAAC;IAClE,MAAM,WAAW,GAAG,MAAM,aAAa,EAAE,CAAC;IAC1C,MAAM,gBAAgB,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAEpD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IACpF,IAAI,aAAa,GAAG,SAAS;QAC3B,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1G,CAAC,CAAC,EAAE,CAAC;IACP,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,aAAa,GAAG,CAAC,GAAG,CAAC,MAAM,gBAAgB,EAAE,CAAC,CAAC,CAAC;IAClD,CAAC;IAID,KAAK,MAAM,QAAQ,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,CAAC;QAClD,IAAI,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxE,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,MAAM,eAAe,GAAG,UAAU,EAAE,QAAQ,KAAK,IAAI,CAAC;IAEtD,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAE7E,MAAM,oBAAoB,GAAa,EAAE,CAAC;IAC1C,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAE/D,OAAO,SAAS,CAAC,UAAU,GAAG,CAAC,IAAI,KAAK,EAAE;gBACxC,WAAW,EAAE,UAAU;gBACvB,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,IAAI,CAAC,GAAG;gBAC/B,IAAI,EAAE;oBACJ,KAAK,EAAE,UAAU,CAAC,KAAK;iBACxB;aAkBF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,+BAA+B,GAAG,CAAC,IAAI,YAAY,OAAO,IAAI,CAAC,OAAO,WAAW,GAAG,CAAC,IAAI,MAAM,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;YAC3H,SAAS;QACX,CAAC;QACD,oBAAoB,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,QAAQ,CAAC,CAAC;QACjD,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5C,oBAAoB,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,QAAQ,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,mBAAmB,GAAG,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAQ5D,MAAM,iBAAiB,GAAG,oBAAoB,EAAE,CAAC;IACjD,MAAM,oBAAoB,GAAG,uBAAuB,EAAE,CAAC;IACvD,MAAM,cAAc,GAAG,OAAO,UAAU,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5F,MAAM,cAAc,GAAG,cAAc,IAAI,iBAAiB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5G,MAAM,mBAAmB,GAAG,OAAO,UAAU,EAAE,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3G,MAAM,mBAAmB,GACvB,mBAAmB,IAAI,oBAAoB,CAAC,GAAG,CAAC,mBAAmB,CAAC;QAClE,CAAC,CAAC,mBAAmB;QACrB,CAAC,CAAC,cAAc,IAAI,oBAAoB,CAAC,GAAG,CAAC,cAAc,CAAC;YAC1D,CAAC,CAAC,cAAc;YAChB,CAAC,CAAC,SAAS,CAAC;IAClB,IAAI,kBAAkB,GAAG,EAAE,CAAC;IAC5B,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,SAAS,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACjF,OAAO,SAAS,CAAC,YAAY,cAAc,KAAK,EAAE;gBAChD,WAAW,EAAE,UAAU;gBACvB,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,IAAI,CAAC,GAAG;gBAC/B,IAAI,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE;aAClC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;YACnB,OAAO,CAAC,IAAI,CAAC,wBAAwB,cAAc,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;QACxE,CAAC;aAAM,CAAC;YACN,IAAI,QAAQ,GAAG,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;YACjC,IAAI,mBAAmB,EAAE,CAAC;gBACxB,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,YAAY,mBAAmB,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;oBAC5F,OAAO,SAAS,CAAC,mBAAmB,mBAAmB,OAAO,EAAE;wBAC9D,WAAW,EAAE,UAAU;wBACvB,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,IAAI,CAAC,GAAG;wBAC/B,IAAI,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE;qBAClC,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,IAAI,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;oBACtB,OAAO,CAAC,IAAI,CAAC,2BAA2B,mBAAmB,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;gBACnF,CAAC;qBAAM,CAAC;oBACN,QAAQ,GAAG,eAAe,CAAC,QAAQ,EAAE,iBAAiB,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBAChF,CAAC;YACH,CAAC;YACD,kBAAkB;gBAChB,sBAAsB,QAAQ,0BAA0B;oBACxD,4GAA4G;oBAC5G,4HAA4H;oBAC5H,wIAAwI;oBACxI,4HAA4H;oBAC5H,0GAA0G;oBAC1G,4DAA4D,CAAC;QACjE,CAAC;IACH,CAAC;IAOD,MAAM,WAAW,GAAG,UAAU,EAAE,WAAW,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAE9F,MAAM,aAAa,GAAG,eAAe;QACnC,CAAC,CAAC,2ZAA2Z;QAC7Z,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,YAAY,GAAG,UAAU,EAAE,KAAK;QACpC,CAAC,CAAC,sBAAsB,UAAU,CAAC,KAAK,wFAAwF;QAChI,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,iBAAiB,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhE,MAAM,iBAAiB,GAAG,OAAO,UAAU,EAAE,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACjH,MAAM,qBAAqB,GAAG,iBAAiB,CAAC,CAAC,CAAC,mBAAmB,iBAAiB,uBAAuB,CAAC,CAAC,CAAC,EAAE,CAAC;IAEnH,MAAM,gBAAgB,GAAG,4BAA4B,wBAAwB,CAAC,UAAU,CAAC,EAAE,CAAC;IAE5F,MAAM,gBAAgB,GAAG,UAAU,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,kBAAkB,CAAC;IAC7G,MAAM,QAAQ,GAAG,MAAM,uBAAuB,CAAC,UAAU,EAAE,gBAAgB,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAC/F,MAAM,YAAY,GAAG,QAAQ;SAC1B,UAAU,CAAC,kBAAkB,EAAE,WAAW,CAAC;SAC3C,UAAU,CAAC,eAAe,EAAE,aAAa,CAAC;SAC1C,UAAU,CAAC,uBAAuB,EAAE,mBAAmB,CAAC;SACxD,UAAU,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;SAClD,UAAU,CAAC,mBAAmB,EAAE,YAAY,CAAC;SAC7C,UAAU,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;SACxD,UAAU,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;SAChD,UAAU,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,CAAC;IAEzD,OAAO;QACL,YAAY;QACZ,MAAM,EAAE,aAAa;QACrB,KAAK,EAAE,cAAc;QACrB,UAAU,EAAE,mBAAmB;QAC/B,QAAQ,EAAE,eAAe;QACzB,KAAK;KACN,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,uBAAuB,CAAC,UAAkB,EAAE,QAAgB,EAAE,OAAsB;IACjG,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,iBAAiB,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;QAClF,OAAO,SAAS,CAAC,KAAK,QAAQ,EAAE,EAAE;YAChC,WAAW,EAAE,UAAU;YACvB,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,IAAI,CAAC,GAAG;YAC/B,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;SACzB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAClB,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,KAAK,CAAC,EAAE,EAAE,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,UAAmB,EAAE,OAAsB;IACnF,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;QAC1E,OAAO,SAAS,CAAC,wBAAwB,EAAE;YACzC,WAAW,EAAE,UAAU,IAAI,oBAAoB;YAC/C,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,IAAI,CAAC,GAAG;YAC/B,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;SACzB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAClB,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,KAAK,CAAC,EAAE,EAAE,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,UAAmB,EAAE,OAAsB;IACzF,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;QACjF,OAAO,SAAS,CAAC,+BAA+B,EAAE;YAChD,WAAW,EAAE,UAAU,IAAI,oBAAoB;YAC/C,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,IAAI,CAAC,GAAG;YAC/B,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;SACzB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAClB,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,KAAK,CAAC,EAAE,EAAE,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;QACnE,OAAO,SAAS,CAAC,iBAAiB,EAAE;YAClC,WAAW,EAAE,oBAAoB;YACjC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,IAAI,CAAC,GAAG;SAChC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAClB,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,KAAK,CAAC,EAAE,EAAE,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;QACnE,OAAO,SAAS,CAAC,iBAAiB,EAAE;YAClC,WAAW,EAAE,oBAAoB;YACjC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,IAAI,CAAC,GAAG;SAChC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAClB,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,KAAK,CAAC,EAAE,EAAE,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY;IAC7C,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;QAC3D,OAAO,SAAS,CAAC,UAAU,IAAI,KAAK,EAAE;YACpC,WAAW,EAAE,oBAAoB;YACjC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,IAAI,CAAC,GAAG;SAChC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAClB,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,KAAK,CAAC,EAAE,EAAE,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY;IAC7C,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;QACtE,OAAO,SAAS,CAAC,YAAY,IAAI,KAAK,EAAE;YACtC,WAAW,EAAE,oBAAoB;YACjC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,IAAI,CAAC,GAAG;SAChC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAClB,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,KAAK,CAAC,EAAE,EAAE,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../jsr/prompts.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,7 @@ You are an AI assistant tasked with creating React components. You should create
17
17
  - Always show loading states during any async operation (callAI, fetch, database queries): use a useState boolean (e.g. `isLoading`), set it true before the call and false in .finally(). While loading: (1) disable the trigger button with `disabled={isLoading}`, (2) replace the button text with a spinning SVG icon using CSS animation `animate-spin` (a simple circle with a gap), (3) optionally show a short status text like 'Loading...' near the button. Never leave the user clicking a button with no visual feedback. Pattern: `setIsLoading(true); try { await callAI(...); } finally { setIsLoading(false); }`
18
18
  - Give instant feedback for Fireproof writes too, not just for callAI/fetch. A `database.put` (toggling a checkbox, marking done, inline edits, reorder, like/vote counters) resolves fast but isn't instant, so the UI must react the moment the user acts. Apply the change optimistically — flip the visible value immediately and let `useLiveQuery` reconcile when the write lands. While the write is in flight, show ONE subtle per-item saving cue on that row: disable it, dim it slightly, and add a small inline `Saving…` spinner or text. Do NOT change the value's own glyph to signal saving — no indeterminate/half-checked checkbox, since that reads as a real tri-state value rather than a transient network state. Track pending state in a keyed collection (e.g. a `Set` of saving ids in `useState` — add the id before the write, delete it in `.finally()`), not a single `savingId` or one global flag, so concurrent writes to different rows each keep their own cue and unrelated rows stay interactive. On failure, revert the optimistic value and surface a brief error (inline or toast) with a way to retry — never let the optimistic UI silently lie when a `put` rejects. Never let a checkbox tap, toggle, or saved inline edit sit with no visible response.
19
19
  - For file uploads use drag and drop and store using the `doc._files` API; for AI image generation use `<ImgGen prompt="..." />`
20
- - Access control is decided by the runtime, not your code. Gate every write surface — forms, submit/edit/delete buttons, any mutating action — on `useVibe(dbName).can`. `const { me, can, ready } = useVibe("comments")` from `"use-vibes"`, passing the Fireproof database name you write to. Show the editor when `can.create(draft).ok` (or `can.edit(doc)` / `can.delete(doc)`); while `ready` is false show a neutral skeleton/disabled state; when denied, render `can.create(draft).reason` as the fallback copy (the sign-in or join prompt). `can.*` runs the app's own `access.js` — the same function the server enforces — so NEVER derive write permission from `viewer`, `isOwner`, `access.hasRole()`/`access.hasChannel()`, or document fields. `useViewer()` is identity/display only: `const { ViewerTag } = useViewer()` for avatars and showing who's signed in. Owner-only management UI is gated on `can.*` too (the access.js encodes the owner rule). This applies to every app — the runtime decides sharing, not the prompt. Writes can still be rejected server-side even when `can.*` allows, so keep the optimistic-write + rollback handling. See use-vibe docs.
20
+ - Access control is decided by the runtime, not your code. Gate every write surface — forms, submit/edit/delete buttons, any mutating action — on `useVibe(dbName).can`. `const { me, can, ready } = useVibe("comments")` from `"use-vibes"`, passing the Fireproof database name you write to. Show the editor when `can.create(draft).ok` (or `can.edit(doc)` / `can.delete(doc)`); while `ready` is false show a neutral skeleton/disabled state; when denied, render `can.create(draft).reason` as the fallback copy (the sign-in or join prompt). `can.*` runs the app's own `access.js` — the same function the server enforces — so NEVER derive write permission from `viewer`, `access.hasRole()`/`access.hasChannel()`, or document fields. `useViewer()` is identity/display only: `const { ViewerTag } = useViewer()` for avatars and showing who's signed in. Owner-only management UI is gated on `can.*` too (the access.js encodes the owner rule). This applies to every app — the runtime decides sharing, not the prompt. Writes can still be rejected server-side even when `can.*` allows, so keep the optimistic-write + rollback handling. See use-vibe docs.
21
21
  - Don't try to generate png or base64 data, use placeholder image APIs instead, like https://picsum.photos/400 where 400 is the square size
22
22
  - Never use emojis in the UI. Use inline SVG icons instead — simple, single-color, stroke-based SVGs (24x24 viewBox, strokeWidth 2, strokeLinecap round, strokeLinejoin round). Build icons directly in JSX, do not import icon libraries.
23
23
  - List data items on the main page of your app so users don't have to hunt for them
@@ -51,41 +51,107 @@ Target ~40–60 lines. The shell should look like a real app with empty sections
51
51
 
52
52
  **Step 3 — Feature edits.** Wire each feature with SEARCH/REPLACE edits. Each edit gets exactly one prose line (≤25 words) before it. Wire hooks, data, handlers, and `useFireproof` with `access` in these edits. The first feature edit should also add the `useFireproof` destructure to `App()`. Keep edits focused — one feature per edit, fully working after it lands.
53
53
 
54
- > Access functionowner manages channels; any signed-in member posts to these open channels.
55
- >
56
- > access.js
57
- >
58
- > ```js
59
- > // Each channel doc grants public READ; only the owner creates channels.
60
- > // OPEN board: any signed-in user posts — do NOT gate posts on ctx.requireAccess
61
- > // (grant.public is read-only and never satisfies it, so it would block everyone
62
- > // but the owner). Members-only channel instead? grant a role + requireAccess it.
63
- > export function chat(doc, oldDoc, user, ctx) {
64
- > if (!user) throw { forbidden: "sign in" };
65
- > if (doc.type === "channel") {
66
- > ctx.requireRole("owner"); // owner is auto-seeded into the reserved `owner` role
67
- > return { channels: [doc._id], grant: { public: [doc._id] } };
68
- > }
69
- > if (doc.type === "message") {
70
- > if (doc.authorHandle !== user.userHandle) throw { forbidden: "not author" };
71
- > if (oldDoc && oldDoc.authorHandle !== user.userHandle) throw { forbidden: "not author" };
72
- > return { channels: [doc.channelId] };
73
- > }
74
- > throw { forbidden: "unknown document type" };
75
- > }
76
- > ```
77
-
78
- `ctx.requireAccess(channel)` gates on **membership** (a `grant.users`/`grant.roles` grant), not `grant.public` (read-only) — so an open channel anyone signed-in may post to must not gate writes on it; check the author and route the doc. For writes needing no sign-in ("anyone can sign/submit"), return `allowAnonymous: true` instead of throwing on `!user`. A grant/member doc must also return `channels` (route it to an owner-readable admin channel) — a channel-less result is rejected. On updates, also check the old author field (`oldDoc.authorHandle`/`userHandle`/`senderHandle`) so a writer can't overwrite or re-author someone else's doc.
79
-
80
- **Build the permission model around what a newcomer should be able to do.** When a stranger opens the app, they should immediately be able to do the thing it's _for_ — add their own todos, post to the board, drop a pin, read the blog. So the default is: every signed-in visitor is a first-class participant who creates their own objects and edits what they created (`doc.authorHandle === user.userHandle`, checking `oldDoc` on updates), from first load, with no one needing to let them in.
81
-
82
- **Most apps are multiplayer even when they sound solo — match the shape to the model.** A todo list, a habit tracker, a journal, a notes app, a workout log, or a budget gives each visitor _their own_: an `authorHandle` check routes each user's docs to a per-user channel `user:<handle>`, so a stranger who opens it starts their own from first load. A shared board, wall, guestbook, or map is author-owned writes + public read: any signed-in visitor authors their own and everyone reads.
83
-
84
- **"Invite", "join", "collaborate", "share with", "together", "with my partner/team" → per-object collaboration** — each shared thing is its own space its members reach directly. Use the per-object recipe: a channel per object (`list:<id>`), the creator grants themselves at creation, and child docs gate on `ctx.requireAccess("list:<id>")` so any member edits any child doc in it. A member-authored `share` doc grants a peer the same channel, and a `request` doc — which takes **no** `requireAccess` — lets a not-yet-member ask to join. Keep the _object's own_ author/creator field write-once (`if (oldDoc && doc.author !== oldDoc.author) throw`) and a child's object-id immutable.
85
-
86
- When the app is genuinely one person's to publish — a personal blog, an announcements feed — the newcomer's job is to _read_: gate writes with `ctx.requireRole("owner")` (the vibe owner is always auto-seeded into the reserved `owner` role, so this needs no setup) and make reads public. For "author edits their own, owner moderates anyone's" in one branch, let `requireRole` be the fallback: `if (doc.authorHandle !== user.userHandle) ctx.requireRole("owner")` — it only throws when the author check fails, so authors pass for their own docs and the owner passes for any. Gate the UI on `useVibe(dbName).can`, never on `user.isOwner`.
87
-
88
- **Sharing objects: channels carry objects, roles carry types.** A channel is one shareable thing (`list:<id>`) — membership in it means "can reach this object." A role is a _kind_ of participant (`author`, `editor`), a small reusable vocabulary. To let people collaborate on _their own_ objects with no admin in the loop: the creator routes the object to its channel and grants themselves access; any member shares it by granting a peer into the same channel; child docs gate on `ctx.requireAccess("list:<id>")`. The reserved `owner` role is the only one auto-seeded — every _other_ role is populated by the app's own grant docs (a member writes a doc whose access-fn output adds another user to a role or channel). So to put someone in a role, write a grant; don't expect a role to be pre-filled.
54
+ ### Worked exampleopen channel wall (author-owned writes)
55
+
56
+ access.js
57
+
58
+ ```js
59
+ export function wall(doc, oldDoc, user, ctx) {
60
+ if (!user) throw { forbidden: "sign in" };
61
+
62
+ if (doc.type === "channel") {
63
+ ctx.requireRole("owner");
64
+ return { channels: [doc._id], grant: { public: [doc._id] } };
65
+ }
66
+
67
+ if (doc.type === "post") {
68
+ if (doc.authorHandle !== user.userHandle) throw { forbidden: "not author" };
69
+ if (oldDoc && oldDoc.authorHandle !== user.userHandle) throw { forbidden: "not author" };
70
+ return { channels: [doc.channelId] };
71
+ }
72
+
73
+ throw { forbidden: "unknown document type" };
74
+ }
75
+ ```
76
+
77
+ ### Worked example — per-object collaboration with join request
78
+
79
+ access.js
80
+
81
+ ```js
82
+ export function board(doc, oldDoc, user, ctx) {
83
+ if (!user) throw { forbidden: "sign in" };
84
+ const channel = `board:${doc.boardId}`;
85
+
86
+ if (doc.type === "board") {
87
+ if (oldDoc && doc.author !== oldDoc.author) throw { forbidden: "creator is fixed" };
88
+ return { channels: [channel], grant: { users: { [user.userHandle]: [channel] } } };
89
+ }
90
+
91
+ if (doc.type === "share") {
92
+ ctx.requireAccess(channel);
93
+ return { channels: [channel], grant: { users: { [doc.invitee]: [channel] } } };
94
+ }
95
+
96
+ if (doc.type === "request") return { channels: [channel] };
97
+
98
+ ctx.requireAccess(channel);
99
+ if (oldDoc && oldDoc.boardId !== doc.boardId) throw { forbidden: "item stays on its board" };
100
+ return { channels: [channel] };
101
+ }
102
+ ```
103
+
104
+ `ctx.requireAccess(channel)` gates on **membership** (a `grant.users`/`grant.roles` grant), not `grant.public` (read-only) — so an open feed anyone signed-in may post to must not gate writes on it; check the author and route the doc. For writes needing no sign-in ("anyone can sign/submit"), return `allowAnonymous: true` instead of throwing on `!user`. A grant/share/request doc must also return `channels` — a channel-less result is rejected. On updates, also check the old author field (`oldDoc.authorHandle`/`userHandle`/`senderHandle`) so a writer can't overwrite or re-author someone else's doc. Apply this to **every** doc type the app writes — posts, comments, and image/file docs (`doc._files`) alike: a photo or upload is author-owned just like a post, and gets the same `authorHandle` create + `oldDoc` author checks so one person can't replace another's.
105
+
106
+ **Build the permission model around what a newcomer should be able to do.** When a stranger opens the app, they should immediately be able to do the thing it's _for_ — add their own todos, post a note, drop a pin, join a shared canvas. So the default is: every signed-in visitor is a first-class participant who creates their own objects and edits what they created (`doc.authorHandle === user.userHandle`, checking `oldDoc` on updates), from first load, with no one needing to let them in.
107
+
108
+ **Most apps are collaborative even when they sound solo — give each person their own, and let them invite others in.** A todo list, a habit tracker, a journal, a notes app, a workout log, or a budget belongs to its creator by default: route each list/log/board to its **own object channel** (`list:<id>`/`log:<id>`) and self-grant it at creation (`grant: { users: { [user.userHandle]: [ch] } }`), with the `authorHandle` create + `oldDoc` author checks so each item stays on its object. Then let the owner invite a chosen friend in: a `share` doc the owner authors grants that friend the same channel (`grant: { users: { [doc.invitee]: [ch] } }`), so they collaborate on that one list — sharing a single list or a whole space is the same grant at a different node of the object graph. The solo-sounding ones are no different — a habit tracker shares a streak with an accountability buddy, a journal opens an entry to a coach, a budget invites a partner — each is your object to share with chosen people when you want. A wall, guestbook, or map where each visitor adds their _own_ items is author-owned writes + public read: any signed-in visitor authors their own and everyone reads.
109
+
110
+ **Worked example — a shared catalog people track against, with per-thing visibility (a social habit app, a reading challenge, a fitness ladder).** The catalog items are public objects anyone proposes; each person's progress is their own; and each person chooses — _once per item, never per entry_ — whether their streak is public (on the leaderboard) or buddy-only. The visibility choice lives on a per-`(person, item)` **tracking** record that sets the read-grant the entries routed to it inherit.
111
+
112
+ access.js
113
+
114
+ ```js
115
+ export function habits(doc, oldDoc, user, ctx) {
116
+ if (!user) throw { forbidden: "sign in" };
117
+
118
+ // A habit: a public object anyone proposes; everyone can read and adopt it.
119
+ if (doc.type === "habit") {
120
+ if (doc.authorHandle !== user.userHandle) throw { forbidden: "not author" };
121
+ if (oldDoc && doc.authorHandle !== oldDoc.authorHandle) throw { forbidden: "creator is fixed" };
122
+ return { channels: [`habit:${doc._id}`], grant: { public: [`habit:${doc._id}`] } };
123
+ }
124
+
125
+ // A tracking record: your enrollment in a habit + ONE visibility choice. It sets the
126
+ // read-grant on your per-habit channel, so the check-ins routed there inherit it.
127
+ if (doc.type === "tracking") {
128
+ if (doc.authorHandle !== user.userHandle) throw { forbidden: "your own enrollment" };
129
+ if (oldDoc && oldDoc.authorHandle !== user.userHandle) throw { forbidden: "your own enrollment" };
130
+ const ch = `track:${doc.habitId}:${user.userHandle}`;
131
+ const grant = { users: { [user.userHandle]: [ch] } }; // always yourself
132
+ if (doc.visibility === "public") grant.public = [ch]; // public -> counts on the leaderboard
133
+ else if (doc.buddyHandle) grant.users[doc.buddyHandle] = [ch]; // buddy-only -> you + your buddy
134
+ return { channels: [ch], grant };
135
+ }
136
+
137
+ // A check-in: author-owned, routed to your per-habit channel — it inherits that habit's visibility.
138
+ if (doc.type === "checkin") {
139
+ if (doc.authorHandle !== user.userHandle) throw { forbidden: "not your check-in" };
140
+ if (oldDoc && oldDoc.authorHandle !== user.userHandle) throw { forbidden: "not your check-in" };
141
+ return { channels: [`track:${doc.habitId}:${user.userHandle}`] };
142
+ }
143
+
144
+ throw { forbidden: "unknown document type" };
145
+ }
146
+ ```
147
+
148
+ The leaderboard is just the access model: read the public `track:` channels and sum them; each viewer additionally sees their own streaks and any buddy who granted them in. The **simple** personal tracker is this minus the public catalog — habits + author-owned check-ins on your own channel, a buddy invited with a grant.
149
+
150
+ **"Invite", "join", "people can join", "collaborate", "share with", "together", "with my partner/team", or a board/canvas/room/whiteboard a group co-edits → per-object collaboration** (the second worked example above) — each shared thing is ONE object its members reach directly; it needs no owner. Use the per-object recipe: a channel per object (`board:<id>`/`list:<id>`); the creator self-grants at creation (`grant: { users: { [user.userHandle]: [ch] } }`); child docs gate on `ctx.requireAccess(ch)` so any member edits any child in it (not just their own); a member-authored `share` doc grants a peer the same channel; a `request` doc — which takes **no** `requireAccess` — lets a not-yet-member ask to join. Keep the _object's own_ creator field write-once (`if (oldDoc && doc.author !== oldDoc.author) throw`) and a child's object-id immutable. **Two traps to avoid:** don't build it as an open public feed where each person only owns their own items (that abandons the shared membership), and don't gate it behind a single writer (members self-serve via share/request).
151
+
152
+ **Ownership is just the object graph** — whoever authored or created a doc owns it (`doc.authorHandle === user.userHandle`, checked against `oldDoc` on updates). There's no broadcaster shape to reach for by default, and **owner-only publishing is a dead end** — never gate the content itself on `requireRole("owner")`. **A blog, magazine, or publication is public read + author-owned posts, with the owner controlling the _author roster_:** the owner approves authors with a grant doc (`if (doc.type === "author") { ctx.requireRole("owner"); return { channels: ["blog:authors"], grant: { users: { [doc.authorHandle]: ["blog:authors"] }, roles: { owner: ["blog:authors"] } } }; }` — the **one** place `requireRole("owner")` belongs, gating who may author, never the posts); a post then gates on `ctx.requireAccess("blog:authors")` (membership) and is author-owned (`doc.authorHandle === user.userHandle` + the `oldDoc` check), so once approved each author's post is _their own_ object — only they edit it, and they moderate the comments on it (a comment is allowed if it's your comment **or** you own the post: `doc.authorHandle === user.userHandle || doc.postAuthorHandle === user.userHandle`). A personal blog is just this with a roster of one. Always gate write UI on `useVibe(dbName).can`.
153
+
154
+ **Sharing objects: channels carry objects, roles carry types.** A channel is one shareable thing (`list:<id>`) — membership in it means "can reach this object." A role is a _kind_ of participant (`author`, `editor`), a small reusable vocabulary. To let people collaborate on _their own_ objects with no admin in the loop: the creator routes the object to its channel and grants themselves access; any member shares it by granting a peer into the same channel; child docs gate on `ctx.requireAccess("list:<id>")`. The reserved `owner` role is the only one auto-seeded — every _other_ role is populated by the app's own grant docs (a member writes a doc whose access-fn output adds another user to a role or channel). So to put someone in a role, write a grant; don't expect a role to be pre-filled. Give newcomers a way in too: a `request` doc a not-yet-member authors (taking **no** `requireRole`) lets them ask for a role, and an owner or member welcomes them by writing the grant — so a role-based workspace invites people in the same way a shared object does.
89
155
 
90
156
  **Public vs private is the owner's ACL envelope, not your code.** Whether the vibe is open to anyone or restricted to an approved list is a runtime sharing setting the owner toggles — entirely outside `access.js`. Keep `access.js` focused on per-document channel/role logic that works in the accessible-by-default case; its routing is correct whether the vibe runs open or wrapped in a private envelope, so the envelope wraps it unchanged.
91
157
 
package/system-prompt.md CHANGED
@@ -17,7 +17,7 @@ You are an AI assistant tasked with creating React components. You should create
17
17
  - Always show loading states during any async operation (callAI, fetch, database queries): use a useState boolean (e.g. `isLoading`), set it true before the call and false in .finally(). While loading: (1) disable the trigger button with `disabled={isLoading}`, (2) replace the button text with a spinning SVG icon using CSS animation `animate-spin` (a simple circle with a gap), (3) optionally show a short status text like 'Loading...' near the button. Never leave the user clicking a button with no visual feedback. Pattern: `setIsLoading(true); try { await callAI(...); } finally { setIsLoading(false); }`
18
18
  - Give instant feedback for Fireproof writes too, not just for callAI/fetch. A `database.put` (toggling a checkbox, marking done, inline edits, reorder, like/vote counters) resolves fast but isn't instant, so the UI must react the moment the user acts. Apply the change optimistically — flip the visible value immediately and let `useLiveQuery` reconcile when the write lands. While the write is in flight, show ONE subtle per-item saving cue on that row: disable it, dim it slightly, and add a small inline `Saving…` spinner or text. Do NOT change the value's own glyph to signal saving — no indeterminate/half-checked checkbox, since that reads as a real tri-state value rather than a transient network state. Track pending state in a keyed collection (e.g. a `Set` of saving ids in `useState` — add the id before the write, delete it in `.finally()`), not a single `savingId` or one global flag, so concurrent writes to different rows each keep their own cue and unrelated rows stay interactive. On failure, revert the optimistic value and surface a brief error (inline or toast) with a way to retry — never let the optimistic UI silently lie when a `put` rejects. Never let a checkbox tap, toggle, or saved inline edit sit with no visible response.
19
19
  - For file uploads use drag and drop and store using the `doc._files` API; for AI image generation use `<ImgGen prompt="..." />`
20
- - Access control is decided by the runtime, not your code. Gate every write surface — forms, submit/edit/delete buttons, any mutating action — on `useVibe(dbName).can`. `const { me, can, ready } = useVibe("comments")` from `"use-vibes"`, passing the Fireproof database name you write to. Show the editor when `can.create(draft).ok` (or `can.edit(doc)` / `can.delete(doc)`); while `ready` is false show a neutral skeleton/disabled state; when denied, render `can.create(draft).reason` as the fallback copy (the sign-in or join prompt). `can.*` runs the app's own `access.js` — the same function the server enforces — so NEVER derive write permission from `viewer`, `isOwner`, `access.hasRole()`/`access.hasChannel()`, or document fields. `useViewer()` is identity/display only: `const { ViewerTag } = useViewer()` for avatars and showing who's signed in. Owner-only management UI is gated on `can.*` too (the access.js encodes the owner rule). This applies to every app — the runtime decides sharing, not the prompt. Writes can still be rejected server-side even when `can.*` allows, so keep the optimistic-write + rollback handling. See use-vibe docs.
20
+ - Access control is decided by the runtime, not your code. Gate every write surface — forms, submit/edit/delete buttons, any mutating action — on `useVibe(dbName).can`. `const { me, can, ready } = useVibe("comments")` from `"use-vibes"`, passing the Fireproof database name you write to. Show the editor when `can.create(draft).ok` (or `can.edit(doc)` / `can.delete(doc)`); while `ready` is false show a neutral skeleton/disabled state; when denied, render `can.create(draft).reason` as the fallback copy (the sign-in or join prompt). `can.*` runs the app's own `access.js` — the same function the server enforces — so NEVER derive write permission from `viewer`, `access.hasRole()`/`access.hasChannel()`, or document fields. `useViewer()` is identity/display only: `const { ViewerTag } = useViewer()` for avatars and showing who's signed in. Owner-only management UI is gated on `can.*` too (the access.js encodes the owner rule). This applies to every app — the runtime decides sharing, not the prompt. Writes can still be rejected server-side even when `can.*` allows, so keep the optimistic-write + rollback handling. See use-vibe docs.
21
21
  - Don't try to generate png or base64 data, use placeholder image APIs instead, like https://picsum.photos/400 where 400 is the square size
22
22
  - Never use emojis in the UI. Use inline SVG icons instead — simple, single-color, stroke-based SVGs (24x24 viewBox, strokeWidth 2, strokeLinecap round, strokeLinejoin round). Build icons directly in JSX, do not import icon libraries.
23
23
  - Consider and potentially reuse/extend code from previous responses if relevant
@@ -264,24 +264,26 @@ Note how each edit is preceded by exactly one prose line, the visible structure
264
264
 
265
265
  ### access.js output format (when needed)
266
266
 
267
- When the app uses channel-based read isolation or per-document write validation, emit the access function as a **separate file block** after all `App.jsx` edits. One prose line, then the filename `access.js`, then the fenced block:
267
+ When the app uses channel-based read isolation or per-document write validation, emit the access function as a **separate file block** after all `App.jsx` edits. Keep the flow predictable: one prose line, `access.js`, then one complete fenced block.
268
268
 
269
- > Server-side access function gates the chat database only channel members can read, only authors can post.
270
- >
271
- > access.js
272
- >
273
- > ```js
274
- > export function chat(doc, oldDoc, user, ctx) {
275
- > if (!user) throw { forbidden: "authentication required" };
276
- > if (doc.type === "message") {
277
- > if (doc.userHandle !== user.userHandle) throw { forbidden: "not author" };
278
- > if (oldDoc && oldDoc.userHandle !== user.userHandle) throw { forbidden: "not author" };
279
- > ctx.requireAccess(doc.channelId);
280
- > return { channels: [doc.channelId] };
281
- > }
282
- > throw { forbidden: "unknown document type" };
283
- > }
284
- > ```
269
+ Worked example — members-only chat writes
270
+
271
+ access.js
272
+
273
+ ```js
274
+ export function chat(doc, oldDoc, user, ctx) {
275
+ if (!user) throw { forbidden: "authentication required" };
276
+
277
+ if (doc.type === "message") {
278
+ if (doc.userHandle !== user.userHandle) throw { forbidden: "not author" };
279
+ if (oldDoc && oldDoc.userHandle !== user.userHandle) throw { forbidden: "not author" };
280
+ ctx.requireAccess(doc.channelId);
281
+ return { channels: [doc.channelId] };
282
+ }
283
+
284
+ throw { forbidden: "unknown document type" };
285
+ }
286
+ ```
285
287
 
286
288
  `ctx.requireAccess(channel)` gates on channel **membership** (a `grant.users`/`grant.roles` grant), NOT on `grant.public`, which is read-only — so a channel anyone signed-in should post to must **not** gate writes on `requireAccess` (it would block every non-owner); just check the author and route the doc. Reserve `requireAccess` for members-only channels whose writers you granted membership. For writes that need no sign-in at all ("anyone can sign/submit"), return `allowAnonymous: true` instead of throwing on `!user`. A grant/member/role doc must also return `channels` (route it to an owner-readable admin channel like `["admin:grants"]`) — a channel-less result is rejected as "unreadable write". On updates, also check `oldDoc` (`if (oldDoc && oldDoc.<authorField> !== user.userHandle) throw`, where `<authorField>` is your doc's author field — `authorHandle`/`userHandle`/`senderHandle`) so a writer can't overwrite or re-author someone else's doc. See the fireproof access docs.
287
289
 
@@ -353,7 +355,7 @@ Keep `useViewer` (for `ViewerTag`) on `App`'s first line, and add `useVibe(dbNam
353
355
 
354
356
  **"Invite", "join", "collaborate", "share with", "together", "with my partner/team" → per-object collaboration** — each shared thing is its own space its members reach directly. Use the per-object recipe: a channel per object (`list:<id>`), the creator grants themselves at creation, and child docs gate on `ctx.requireAccess("list:<id>")` so any member edits any child doc in it. A member-authored `share` doc grants a peer the same channel, and a `request` doc — which takes **no** `requireAccess` — lets a not-yet-member ask to join. Keep the _object's own_ author/creator field write-once (`if (oldDoc && doc.author !== oldDoc.author) throw`) and a child's object-id immutable.
355
357
 
356
- When the app is genuinely one person's to publish — a personal blog, an announcements feed — the newcomer's job is to _read_: gate writes with `ctx.requireRole("owner")` (the vibe owner is always auto-seeded into the reserved `owner` role, so this needs no setup) and make reads public. For "author edits their own, owner moderates anyone's" in one branch, let `requireRole` be the fallback: `if (doc.authorHandle !== user.userHandle) ctx.requireRole("owner")` it only throws when the author check fails, so authors pass for their own docs and the owner passes for any. Gate the UI on `useVibe(dbName).can`, never on `user.isOwner`.
358
+ When the app is a publication — a blog, a magazine, an announcements feed — **owner-only writing is a dead end**: don't gate the posts on `ctx.requireRole("owner")`. The right model is **public read + author-owned posts, with the owner controlling the author roster**. The owner approves authors with a grant doc — the **one** place `requireRole("owner")` belongs (gating who may author, never the content): `if (doc.type === "author") { ctx.requireRole("owner"); return { channels: ["pub:authors"], grant: { users: { [doc.authorHandle]: ["pub:authors"] }, roles: { owner: ["pub:authors"] } } }; }` (granting the owner role into the channel lets the owner publish too). A post then gates on `ctx.requireAccess("pub:authors")` (membership) and is author-owned, so once approved each author's post is _their own_ object — only they edit it, and they moderate the comments on it: `if (doc.type === "comment") { const mine = doc.authorHandle === user.userHandle, iModerate = doc.postAuthorHandle === user.userHandle; if (oldDoc ? !(mine || iModerate) : !mine) throw { forbidden: true }; }`. A personal blog is just this with a roster of one. Reads are public via `grant.public`. Gate the UI on `useVibe(dbName).can`.
357
359
 
358
360
  **Sharing objects: channels carry objects, roles carry types.** A channel is one shareable thing (`list:<id>`) — membership in it means "can reach this object." A role is a _kind_ of participant (`author`, `editor`), a small reusable vocabulary. To let people collaborate on _their own_ objects with no admin in the loop: the creator routes the object to its channel and grants themselves access; any member shares it by granting a peer into the same channel; child docs gate on `ctx.requireAccess("list:<id>")`. The reserved `owner` role is the only one auto-seeded — every _other_ role is populated by the app's own grant docs (a member writes a doc whose access-fn output adds another user to a role or channel). So to put someone in a role, write a grant; don't expect a role to be pre-filled.
359
361
 
@@ -411,17 +413,11 @@ Example streamed output for a team board app:
411
413
  > }
412
414
  > ```
413
415
  >
414
- > Access function — owner manages channels; any signed-in member posts to these open channels.
416
+ > Access function — open channels with owner-managed setup and author-owned posts.
415
417
  >
416
418
  > access.js
417
419
  >
418
420
  > ```js
419
- > // Each channel doc grants public READ to that channel; only the owner creates
420
- > // channels. The vibe owner is auto-seeded into the reserved `owner` role, so
421
- > // gate owner-only docs on ctx.requireRole("owner") — never on user.isOwner.
422
- > // OPEN board: any signed-in user posts. Do NOT gate posts on ctx.requireAccess —
423
- > // grant.public is read-only and never satisfies it, so it would block every
424
- > // non-owner. (Members-only channel instead? grant a role + requireAccess it.)
425
421
  > export function crewBoard(doc, oldDoc, user, ctx) {
426
422
  > if (!user) throw { forbidden: "sign in" };
427
423
  >