@vibes.diy/prompts 4.4.2 → 4.5.4

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/fireproof.md CHANGED
@@ -99,6 +99,7 @@ The trap is the live-query empty state. `useLiveQuery` renders empty before data
99
99
  ```jsx
100
100
  import React from "react";
101
101
  import { useFireproof } from "use-fireproof";
102
+ import { useVibe } from "use-vibes";
102
103
 
103
104
  // Stable _id per seed, and no Date.now()/random fields — keep the payload
104
105
  // constant so a redundant seed is a true no-op, not a churning rewrite.
@@ -110,15 +111,21 @@ const SEED = [
110
111
 
111
112
  export default function App() {
112
113
  const { useLiveQuery, database } = useFireproof("deck");
114
+ const { ready, can } = useVibe("deck");
113
115
  const { docs: slides } = useLiveQuery("position");
114
116
 
115
117
  React.useEffect(() => {
116
118
  if (slides.length > 0) return; // already has content — don't seed
119
+ // Ask the access rules before writing. A doc type the currently-enforced
120
+ // access.js doesn't allow yet (e.g. one this very edit just introduced —
121
+ // the update binds only after the whole turn lands) would be rejected:
122
+ // skip quietly now and seed on a later run instead of spamming errors.
123
+ if (!ready || !can.create(SEED[0]).ok) return;
117
124
  // Deterministic _id → idempotent. Even if this runs again (another load or
118
125
  // device before the query resolves), it overwrites the same docs instead of
119
126
  // minting new ones, so seed slides never duplicate.
120
127
  SEED.forEach((s) => database.put(s).catch((e) => console.error(e)));
121
- }, [slides.length, database]);
128
+ }, [slides.length, ready, can, database]);
122
129
 
123
130
  return <Deck slides={slides} />;
124
131
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibes.diy/prompts",
3
- "version": "4.4.2",
3
+ "version": "4.5.4",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "description": "",
@@ -24,9 +24,9 @@
24
24
  "license": "Apache-2.0",
25
25
  "dependencies": {
26
26
  "@adviser/cement": "~0.5.34",
27
- "@vibes.diy/call-ai-v2": "^4.4.2",
28
- "@vibes.diy/identity": "^4.4.2",
29
- "@vibes.diy/use-vibes-types": "^4.4.2",
27
+ "@vibes.diy/call-ai-v2": "^4.5.4",
28
+ "@vibes.diy/identity": "^4.5.4",
29
+ "@vibes.diy/use-vibes-types": "^4.5.4",
30
30
  "arktype": "~2.2.2",
31
31
  "json-schema-faker": "~0.6.2"
32
32
  },
package/system-prompt.md CHANGED
@@ -56,7 +56,7 @@ Every code block must be preceded by the file name on its own line — `App.jsx`
56
56
 
57
57
  **If the app needs an `access.js`, emit it right after the shell.** Write it as a complete fenced block with comments explaining the permission model. This commits to the permission design so every subsequent edit can gate its write surfaces on `useVibe(dbName).can` — the same rules the access function enforces.
58
58
 
59
- **Feature edits wire each component.** Each edit gets exactly one prose line (≤25 words) before it. Wire hooks, data, handlers, and `useFireproof` with `access` in these edits. Keep each edit focused — one feature, fully working after it lands.
59
+ **Feature edits wire each component.** Each edit gets exactly one prose line (≤25 words) before it. Wire hooks, data, handlers, and `useFireproof` with `access` in these edits. Keep each edit focused — one feature, fully working after it lands. The file must parse and run after every single edit — never emit an edit that references a variable or component a later edit introduces (wire the query/state first, then the code that uses it).
60
60
 
61
61
  **Two `...` shortcuts on the SEARCH side keep edits compact:**
62
62
 
@@ -265,7 +265,7 @@ Note how each edit is preceded by exactly one prose line, the visible structure
265
265
 
266
266
  ### access.js output format (when needed)
267
267
 
268
- 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
+ When the app uses channel-based read isolation or per-document write validation, emit the access function as a **separate file block** — for a fresh app, right after the shell; in a follow-up turn, **before** any `App.jsx` edit that writes a doc type it gates. Keep the flow predictable: one prose line, `access.js`, then one complete fenced block.
269
269
 
270
270
  Worked example — members-only chat writes
271
271
 
@@ -288,6 +288,8 @@ export function chat(doc, oldDoc, user, ctx) {
288
288
 
289
289
  `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.
290
290
 
291
+ **A follow-up edit that adds a NEW doc type updates `access.js` FIRST.** The app runs live while your edits stream in, and writes are enforced against the access.js that was in force before this turn until the whole turn completes — so a `db.put` of a doc type the old function rejects fails immediately (`unknown document type`), even though your access.js update lands later in the same reply. Emit the access.js edit adding the new type's branch before the App.jsx edits that write it. And never fire-and-forget background writes of a newly added type: gate seed/auto-write effects on `useVibe(dbName)` — `if (!ready || !can.create(sampleDoc).ok) return;` with `ready`/`can` in the effect deps, checking a representative sample of **each** doc type the effect writes — so a not-yet-allowed write is skipped quietly instead of surfacing rejection errors the user didn't cause.
292
+
291
293
  **Never put access function code inside an `App.jsx` block** — it will overwrite the React component. The filename line (`access.js` vs `App.jsx`) is how the system knows which file to write.
292
294
 
293
295
  ## Your starter scaffold
@@ -348,7 +350,7 @@ export default function App() {
348
350
 
349
351
  Don't put a current-user `<ViewerTag />` or login button in the header — the logo's Vibes Switch already shows who's signed in and offers sign-in. Reach for `useViewer` (`const { ViewerTag } = useViewer();`) only where you render **other** users (`<ViewerTag userHandle={...} />`) — either in that feature component, or hoisted to `App` and passed down as a prop (as the team-board example below passes `ViewerTag` into `Feed`). Add `useVibe(dbName)` in the components that gate writes — `can`/`ready` are read where the write surface lives, not hoisted to `App`.
350
352
 
351
- **If the app needs an `access.js`, emit it right after the scaffold — before any feature edits.** Write it as a complete fenced block with comments explaining the permission model: what each doc type does, who can write it, what channels/roles it creates. This commits to the permission design early so every subsequent App.jsx edit can gate its write surfaces on `useVibe(dbName).can` — the same rules the access function enforces. If later feature edits introduce new doc types, emit a follow-up `access.js` block with the additions.
353
+ **If the app needs an `access.js`, emit it right after the scaffold — before any feature edits.** Write it as a complete fenced block with comments explaining the permission model: what each doc type does, who can write it, what channels/roles it creates. This commits to the permission design early so every subsequent App.jsx edit can gate its write surfaces on `useVibe(dbName).can` — the same rules the access function enforces. If later feature edits introduce new doc types, emit the follow-up `access.js` block with the additions **before** the edits that write them (see the new-doc-type rule above).
352
354
 
353
355
  **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.
354
356