@vibes.diy/prompts 14.3.20 → 14.3.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/access.md +40 -49
- package/llms/backend.md +41 -27
- package/llms/bluesky.md +4 -2
- package/llms/calendar.md +4 -2
- package/llms/callai.initial.md +2 -1
- package/llms/callai.md +4 -2
- package/llms/connections.md +8 -4
- package/llms/create-vibe.md +4 -2
- package/llms/d3.md +2 -1
- package/llms/fireproof.draft.md +47 -0
- package/llms/fireproof.initial.md +33 -29
- package/llms/fireproof.js +1 -0
- package/llms/fireproof.js.map +1 -1
- package/llms/fireproof.md +38 -32
- package/llms/image-gen.initial.md +2 -4
- package/llms/image-gen.md +3 -5
- package/llms/p5.md +2 -3
- package/llms/spotify.md +4 -2
- package/llms/three-js.md +2 -3
- package/llms/types.d.ts +1 -0
- package/llms/use-vibe.md +2 -1
- package/llms/use-viewer.initial.md +5 -10
- package/llms/use-viewer.md +6 -11
- package/llms/webxr.md +2 -1
- package/llms/youtube.md +4 -2
- package/package.json +4 -4
- package/prompts.d.ts +1 -1
- package/prompts.js +54 -11
- package/prompts.js.map +1 -1
- package/recovery-stitch-addendum.md +3 -2
- package/system-prompt-initial-draft.md +128 -0
- package/system-prompt-initial-oneshot.md +14 -6
- package/system-prompt-initial.md +13 -5
- package/system-prompt.md +32 -24
|
@@ -47,7 +47,8 @@ Wire these visible actions in the first working app, using its own record names.
|
|
|
47
47
|
|
|
48
48
|
With the callai skill available, submitting words extracts and normalizes every task they name, then immediately saves one document per task. The saved task is the confirmation and remains editable, with Undo beside the intake after each save. The parent keeps the ids from the last creation or the previous version from an edit, so intake and saved-detail editors share one Undo action. `useLiveQuery` keeps saved tasks visible; `useDocument` supplies the detail editor only after a record exists. For a plain message whose text is already the whole record, save that text directly.
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
### `App.jsx`
|
|
51
|
+
```jsx
|
|
51
52
|
import React, { useState } from "react";
|
|
52
53
|
import { callAI } from "call-ai";
|
|
53
54
|
import { useFireproof } from "use-fireproof";
|
|
@@ -350,8 +351,7 @@ Don't stamp `Date.now()` or other changing values into seed documents — that m
|
|
|
350
351
|
|
|
351
352
|
To update an existing document from a click handler or callback, use `database.put()` directly. Never call `useDocument` inside an event handler — that violates React's Rules of Hooks. Adding a toggle to list items:
|
|
352
353
|
|
|
353
|
-
App.jsx
|
|
354
|
-
|
|
354
|
+
### `App.jsx`
|
|
355
355
|
```jsx
|
|
356
356
|
<<<<<<< SEARCH
|
|
357
357
|
const { useDocument, useLiveQuery } = useFireproof("myLedger");
|
|
@@ -360,8 +360,7 @@ App.jsx
|
|
|
360
360
|
>>>>>>> REPLACE
|
|
361
361
|
```
|
|
362
362
|
|
|
363
|
-
App.jsx
|
|
364
|
-
|
|
363
|
+
### `App.jsx`
|
|
365
364
|
```jsx
|
|
366
365
|
<<<<<<< SEARCH
|
|
367
366
|
<li key={doc._id}>{doc.text}</li>
|
|
@@ -381,8 +380,7 @@ Never call hooks inside handlers — `const { doc, save } = useDocument({ _id: i
|
|
|
381
380
|
|
|
382
381
|
A continuous control (slider, drag, color picker, live-typed text bound to one doc) fires many events in quick succession. **Never call `database.put()` or `save()` on every `onChange`** — that floods the server with rapid concurrent writes to the same `_id`, which collide on the per-document sequence and get rejected (`Failed to put document …`). Instead, `merge()` locally on each event to keep the UI live, and `save()` once when the interaction commits (`onPointerUp`, `onBlur`, `onChange` for a range input's final value, or a debounced trailing call). Editing a single doc with a slider:
|
|
383
382
|
|
|
384
|
-
App.jsx
|
|
385
|
-
|
|
383
|
+
### `App.jsx`
|
|
386
384
|
```jsx
|
|
387
385
|
<<<<<<< SEARCH
|
|
388
386
|
const { useDocument, useLiveQuery, database } = useFireproof("myLedger");
|
|
@@ -394,8 +392,7 @@ App.jsx
|
|
|
394
392
|
>>>>>>> REPLACE
|
|
395
393
|
```
|
|
396
394
|
|
|
397
|
-
App.jsx
|
|
398
|
-
|
|
395
|
+
### `App.jsx`
|
|
399
396
|
```jsx
|
|
400
397
|
<<<<<<< SEARCH
|
|
401
398
|
<h3>Recent Documents</h3>
|
|
@@ -423,8 +420,7 @@ Data is queried by sorted indexes defined by the application. Sort by strings, n
|
|
|
423
420
|
|
|
424
421
|
Passing a string to `useLiveQuery` will index by that field. Use the key argument to filter by a specific value, or range for bounded queries. Switching from temporal to filtered query:
|
|
425
422
|
|
|
426
|
-
App.jsx
|
|
427
|
-
|
|
423
|
+
### `App.jsx`
|
|
428
424
|
```jsx
|
|
429
425
|
<<<<<<< SEARCH
|
|
430
426
|
const { docs } = useLiveQuery("_id", { descending: true, limit: 100 });
|
|
@@ -436,8 +432,7 @@ App.jsx
|
|
|
436
432
|
|
|
437
433
|
Or query a numeric range:
|
|
438
434
|
|
|
439
|
-
App.jsx
|
|
440
|
-
|
|
435
|
+
### `App.jsx`
|
|
441
436
|
```jsx
|
|
442
437
|
<<<<<<< SEARCH
|
|
443
438
|
const { docs } = useLiveQuery("agentName", { key: "agent-1" });
|
|
@@ -451,8 +446,7 @@ App.jsx
|
|
|
451
446
|
|
|
452
447
|
Documents can be updated by multiple clients, and synced later. To create an event counter, don't increment a number on a single doc, instead write a small document per counted event, and query them with an index:
|
|
453
448
|
|
|
454
|
-
App.jsx
|
|
455
|
-
|
|
449
|
+
### `App.jsx`
|
|
456
450
|
```jsx
|
|
457
451
|
<<<<<<< SEARCH
|
|
458
452
|
const { docs } = useLiveQuery("agentRating", { range: [3, 5] });
|
|
@@ -477,8 +471,7 @@ This pattern ensures the count is accurate even during sync — each event is it
|
|
|
477
471
|
|
|
478
472
|
Use a custom index function to normalize and transform document data, for instance if you have both new and old document versions in your app:
|
|
479
473
|
|
|
480
|
-
App.jsx
|
|
481
|
-
|
|
474
|
+
### `App.jsx`
|
|
482
475
|
```jsx
|
|
483
476
|
<<<<<<< SEARCH
|
|
484
477
|
// The counter's scope: the board being viewed and who is counting (useVibe from "use-vibes", as above).
|
|
@@ -507,8 +500,7 @@ App.jsx
|
|
|
507
500
|
|
|
508
501
|
When you want to group rows easily, you can use an array index key. This is great for grouping records by year/month/day or other paths. The prefix query is a shorthand for a key range:
|
|
509
502
|
|
|
510
|
-
App.jsx
|
|
511
|
-
|
|
503
|
+
### `App.jsx`
|
|
512
504
|
```jsx
|
|
513
505
|
<<<<<<< SEARCH
|
|
514
506
|
const { docs } = useLiveQuery(
|
|
@@ -534,8 +526,7 @@ App.jsx
|
|
|
534
526
|
|
|
535
527
|
Sortable lists are a common pattern. Use evenly spaced positions and insert between items using midpoint calculation:
|
|
536
528
|
|
|
537
|
-
App.jsx
|
|
538
|
-
|
|
529
|
+
### `App.jsx`
|
|
539
530
|
```jsx
|
|
540
531
|
<<<<<<< SEARCH
|
|
541
532
|
const { docs } = useLiveQuery(
|
|
@@ -565,6 +556,23 @@ App.jsx
|
|
|
565
556
|
>>>>>>> REPLACE
|
|
566
557
|
```
|
|
567
558
|
|
|
559
|
+
#### Emit a Row Value
|
|
560
|
+
|
|
561
|
+
An index function can call `emit(key, value)` with a second argument to store a value beside the key. `rows[].value` is the value you emitted when you pass one, and the whole document when you call `emit(key)` alone. Emit a small summary when a long list renders only a field or two, and read `docs` when you want the documents themselves — `docs` holds the indexed documents whatever the rows carry.
|
|
562
|
+
|
|
563
|
+
### `App.jsx`
|
|
564
|
+
```jsx
|
|
565
|
+
<<<<<<< SEARCH
|
|
566
|
+
const { docs } = useLiveQuery((doc) => [doc.listId, doc.position], { prefix: ["xyz"] });
|
|
567
|
+
=======
|
|
568
|
+
// Rows carry just what this list renders; docs still holds the whole documents
|
|
569
|
+
const { rows } = useLiveQuery((doc, emit) => emit([doc.listId, doc.position], { label: doc.label }), {
|
|
570
|
+
prefix: ["xyz"],
|
|
571
|
+
});
|
|
572
|
+
const labels = rows.map((row) => row.value.label);
|
|
573
|
+
>>>>>>> REPLACE
|
|
574
|
+
```
|
|
575
|
+
|
|
568
576
|
## Offline writes are on by default (`offlineQueue`)
|
|
569
577
|
|
|
570
578
|
For signed-in users, writes are **local-first by default**: a `put`/`del` that fails on the network is durably queued on the device (it resolves, stays visible, and syncs to the cloud when you're back online) instead of rolling back. You don't opt in — every signed-in vibe gets this. A refusal or validation rejection is **not** queued: it converges **server-wins** (the local optimistic revision is overwritten by the server's version); the platform surfaces the reason only when it has one, and a reason-less rejection converges silently — so keep the UI reactive to the store rather than depending on a toast. Only transport failures queue and retry.
|
|
@@ -595,8 +603,7 @@ Data lives in a local replica (IndexedDB) that the app reads and writes instantl
|
|
|
595
603
|
|
|
596
604
|
You can use the core API outside a React component — in a plain script or a helper module. Instead of hooks, import the core API directly:
|
|
597
605
|
|
|
598
|
-
App.jsx
|
|
599
|
-
|
|
606
|
+
### `App.jsx`
|
|
600
607
|
```jsx
|
|
601
608
|
<<<<<<< SEARCH
|
|
602
609
|
import React from "react";
|
|
@@ -634,8 +641,7 @@ A save that carries `_files` uploads the bytes before the doc lands, so unlike a
|
|
|
634
641
|
|
|
635
642
|
Building an image uploader with `_files`:
|
|
636
643
|
|
|
637
|
-
App.jsx
|
|
638
|
-
|
|
644
|
+
### `App.jsx`
|
|
639
645
|
```jsx
|
|
640
646
|
import React from "react";
|
|
641
647
|
import { useFireproof } from "use-fireproof";
|
|
@@ -716,8 +722,7 @@ For multi-file uploads (e.g. `<input multiple>`), build the `_files` map keyed b
|
|
|
716
722
|
|
|
717
723
|
Adding multi-file support:
|
|
718
724
|
|
|
719
|
-
App.jsx
|
|
720
|
-
|
|
725
|
+
### `App.jsx`
|
|
721
726
|
```jsx
|
|
722
727
|
<<<<<<< SEARCH
|
|
723
728
|
const onPickFile = (e) => {
|
|
@@ -745,8 +750,7 @@ App.jsx
|
|
|
745
750
|
|
|
746
751
|
You can use React's `useState` to manage validation states and error messages. Validate inputs at the UI level before allowing submission. Adding validation to the uploader:
|
|
747
752
|
|
|
748
|
-
App.jsx
|
|
749
|
-
|
|
753
|
+
### `App.jsx`
|
|
750
754
|
```jsx
|
|
751
755
|
<<<<<<< SEARCH
|
|
752
756
|
const onSubmit = async (e) => {
|
package/llms/fireproof.js
CHANGED
package/llms/fireproof.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fireproof.js","sourceRoot":"","sources":["../../jsr/llms/fireproof.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,cAAc;IACrB,WAAW,EAAE,+CAA+C;IAC5D,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE,eAAe;IAC7B,UAAU,EAAE,cAAc;CAC3B,CAAC"}
|
|
1
|
+
{"version":3,"file":"fireproof.js","sourceRoot":"","sources":["../../jsr/llms/fireproof.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,cAAc;IACrB,WAAW,EAAE,+CAA+C;IAC5D,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE,IAAI;IAClB,YAAY,EAAE,eAAe;IAC7B,UAAU,EAAE,cAAc;CAC3B,CAAC"}
|
package/llms/fireproof.md
CHANGED
|
@@ -47,7 +47,8 @@ Wire these visible actions in the first working app, using its own record names.
|
|
|
47
47
|
|
|
48
48
|
With the callai skill available, submitting words extracts and normalizes every task they name, then immediately saves one document per task. The saved task is the confirmation and remains editable, with Undo beside the intake after each save. The parent keeps the ids from the last creation or the previous version from an edit, so intake and saved-detail editors share one Undo action. `useLiveQuery` keeps saved tasks visible; `useDocument` supplies the detail editor only after a record exists. For a plain message whose text is already the whole record, save that text directly.
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
### `App.jsx`
|
|
51
|
+
```jsx
|
|
51
52
|
import React, { useState } from "react";
|
|
52
53
|
import { callAI } from "call-ai";
|
|
53
54
|
import { useFireproof } from "use-fireproof";
|
|
@@ -278,7 +279,8 @@ When an app ships with default content — starter slides, template rows, exampl
|
|
|
278
279
|
|
|
279
280
|
The trap is the live-query empty state. `useLiveQuery` renders empty before data arrives, so `docs.length === 0` is briefly true on **every** fresh load — and a `useRef`/`useState` "already seeded" flag only guards the current session, never the next reload, a second device, or another collaborator. With **auto-generated** `_id`s, each of those re-seeds the full set and duplicate copies pile up without bound. Deterministic `_id`s collapse every re-seed back onto the same N documents.
|
|
280
281
|
|
|
281
|
-
|
|
282
|
+
### `App.jsx`
|
|
283
|
+
```jsx
|
|
282
284
|
import React from "react";
|
|
283
285
|
import { useFireproof } from "use-fireproof";
|
|
284
286
|
import { useVibe } from "use-vibes";
|
|
@@ -319,8 +321,7 @@ Don't stamp `Date.now()` or other changing values into seed documents — that m
|
|
|
319
321
|
|
|
320
322
|
To update an existing document from a click handler or callback, use `database.put()` directly. Never call `useDocument` inside an event handler — that violates React's Rules of Hooks. Adding a toggle to list items:
|
|
321
323
|
|
|
322
|
-
App.jsx
|
|
323
|
-
|
|
324
|
+
### `App.jsx`
|
|
324
325
|
```jsx
|
|
325
326
|
<<<<<<< SEARCH
|
|
326
327
|
const { useDocument, useLiveQuery } = useFireproof("myLedger");
|
|
@@ -329,8 +330,7 @@ App.jsx
|
|
|
329
330
|
>>>>>>> REPLACE
|
|
330
331
|
```
|
|
331
332
|
|
|
332
|
-
App.jsx
|
|
333
|
-
|
|
333
|
+
### `App.jsx`
|
|
334
334
|
```jsx
|
|
335
335
|
<<<<<<< SEARCH
|
|
336
336
|
<li key={doc._id}>{doc.text}</li>
|
|
@@ -350,8 +350,7 @@ Never call hooks inside handlers — `const { doc, save } = useDocument({ _id: i
|
|
|
350
350
|
|
|
351
351
|
A continuous control (slider, drag, color picker, live-typed text bound to one doc) fires many events in quick succession. **Never call `database.put()` or `save()` on every `onChange`** — that floods the server with rapid concurrent writes to the same `_id`, which collide on the per-document sequence and get rejected (`Failed to put document …`). Instead, `merge()` locally on each event to keep the UI live, and `save()` once when the interaction commits (`onPointerUp`, `onBlur`, `onChange` for a range input's final value, or a debounced trailing call). Editing a single doc with a slider:
|
|
352
352
|
|
|
353
|
-
App.jsx
|
|
354
|
-
|
|
353
|
+
### `App.jsx`
|
|
355
354
|
```jsx
|
|
356
355
|
<<<<<<< SEARCH
|
|
357
356
|
const { useDocument, useLiveQuery, database } = useFireproof("myLedger");
|
|
@@ -363,8 +362,7 @@ App.jsx
|
|
|
363
362
|
>>>>>>> REPLACE
|
|
364
363
|
```
|
|
365
364
|
|
|
366
|
-
App.jsx
|
|
367
|
-
|
|
365
|
+
### `App.jsx`
|
|
368
366
|
```jsx
|
|
369
367
|
<<<<<<< SEARCH
|
|
370
368
|
<h3>Recent Documents</h3>
|
|
@@ -392,8 +390,7 @@ Data is queried by sorted indexes defined by the application. Sort by strings, n
|
|
|
392
390
|
|
|
393
391
|
Passing a string to `useLiveQuery` will index by that field. Use the key argument to filter by a specific value, or range for bounded queries. Switching from temporal to filtered query:
|
|
394
392
|
|
|
395
|
-
App.jsx
|
|
396
|
-
|
|
393
|
+
### `App.jsx`
|
|
397
394
|
```jsx
|
|
398
395
|
<<<<<<< SEARCH
|
|
399
396
|
const { docs } = useLiveQuery("_id", { descending: true, limit: 100 });
|
|
@@ -405,8 +402,7 @@ App.jsx
|
|
|
405
402
|
|
|
406
403
|
Or query a numeric range:
|
|
407
404
|
|
|
408
|
-
App.jsx
|
|
409
|
-
|
|
405
|
+
### `App.jsx`
|
|
410
406
|
```jsx
|
|
411
407
|
<<<<<<< SEARCH
|
|
412
408
|
const { docs } = useLiveQuery("agentName", { key: "agent-1" });
|
|
@@ -420,8 +416,7 @@ App.jsx
|
|
|
420
416
|
|
|
421
417
|
Documents can be updated by multiple clients, and synced later. To create an event counter, don't increment a number on a single doc, instead write a small document per counted event, and query them with an index:
|
|
422
418
|
|
|
423
|
-
App.jsx
|
|
424
|
-
|
|
419
|
+
### `App.jsx`
|
|
425
420
|
```jsx
|
|
426
421
|
<<<<<<< SEARCH
|
|
427
422
|
const { docs } = useLiveQuery("agentRating", { range: [3, 5] });
|
|
@@ -441,8 +436,7 @@ This pattern ensures the count is accurate even during sync — each event is it
|
|
|
441
436
|
|
|
442
437
|
Use a custom index function to normalize and transform document data, for instance if you have both new and old document versions in your app:
|
|
443
438
|
|
|
444
|
-
App.jsx
|
|
445
|
-
|
|
439
|
+
### `App.jsx`
|
|
446
440
|
```jsx
|
|
447
441
|
<<<<<<< SEARCH
|
|
448
442
|
const { docs } = useLiveQuery("counter", { key: "my-event-name" });
|
|
@@ -466,8 +460,7 @@ App.jsx
|
|
|
466
460
|
|
|
467
461
|
When you want to group rows easily, you can use an array index key. This is great for grouping records by year/month/day or other paths. The prefix query is a shorthand for a key range:
|
|
468
462
|
|
|
469
|
-
App.jsx
|
|
470
|
-
|
|
463
|
+
### `App.jsx`
|
|
471
464
|
```jsx
|
|
472
465
|
<<<<<<< SEARCH
|
|
473
466
|
const { docs } = useLiveQuery(
|
|
@@ -493,8 +486,7 @@ App.jsx
|
|
|
493
486
|
|
|
494
487
|
Sortable lists are a common pattern. Use evenly spaced positions and insert between items using midpoint calculation:
|
|
495
488
|
|
|
496
|
-
App.jsx
|
|
497
|
-
|
|
489
|
+
### `App.jsx`
|
|
498
490
|
```jsx
|
|
499
491
|
<<<<<<< SEARCH
|
|
500
492
|
const { docs } = useLiveQuery(
|
|
@@ -523,6 +515,23 @@ App.jsx
|
|
|
523
515
|
>>>>>>> REPLACE
|
|
524
516
|
```
|
|
525
517
|
|
|
518
|
+
#### Emit a Row Value
|
|
519
|
+
|
|
520
|
+
An index function can call `emit(key, value)` with a second argument to store a value beside the key. `rows[].value` is the value you emitted when you pass one, and the whole document when you call `emit(key)` alone. Emit a small summary when a long list renders only a field or two, and read `docs` when you want the documents themselves — `docs` holds the indexed documents whatever the rows carry.
|
|
521
|
+
|
|
522
|
+
### `App.jsx`
|
|
523
|
+
```jsx
|
|
524
|
+
<<<<<<< SEARCH
|
|
525
|
+
const { docs } = useLiveQuery((doc) => [doc.list, doc.position], { prefix: ["xyz"] });
|
|
526
|
+
=======
|
|
527
|
+
// Rows carry just what this list renders; docs still holds the whole documents
|
|
528
|
+
const { rows } = useLiveQuery((doc, emit) => emit([doc.list, doc.position], { label: doc.label }), {
|
|
529
|
+
prefix: ["xyz"],
|
|
530
|
+
});
|
|
531
|
+
const labels = rows.map((row) => row.value.label);
|
|
532
|
+
>>>>>>> REPLACE
|
|
533
|
+
```
|
|
534
|
+
|
|
526
535
|
## Offline writes are on by default (`offlineQueue`)
|
|
527
536
|
|
|
528
537
|
For signed-in users, writes are **local-first by default**: a `put`/`del` that fails on the network is durably queued on the device (it resolves, stays visible, and syncs to the cloud when you're back online) instead of rolling back. You don't opt in — every signed-in vibe gets this. An access-denied/validation rejection is **not** queued: it converges **server-wins** (the local optimistic revision is overwritten by the server's version); the platform surfaces the reason whenever there is one, and a reason-less rejection converges silently — so keep the UI reactive to the store rather than depending on a toast. Only transport failures queue and retry.
|
|
@@ -557,8 +566,7 @@ Data lives in a local replica (IndexedDB) that the app reads and writes instantl
|
|
|
557
566
|
|
|
558
567
|
You can use the core API in HTML or on the backend. Instead of hooks, import the core API directly:
|
|
559
568
|
|
|
560
|
-
App.jsx
|
|
561
|
-
|
|
569
|
+
### `App.jsx`
|
|
562
570
|
```jsx
|
|
563
571
|
<<<<<<< SEARCH
|
|
564
572
|
import React from "react";
|
|
@@ -608,9 +616,8 @@ A save that carries `_files` uploads the bytes before the doc lands, so unlike a
|
|
|
608
616
|
|
|
609
617
|
Building an image uploader with `_files`:
|
|
610
618
|
|
|
611
|
-
App.jsx
|
|
612
|
-
|
|
613
|
-
```jsx file=App.jsx
|
|
619
|
+
### `App.jsx`
|
|
620
|
+
```jsx
|
|
614
621
|
import React from "react";
|
|
615
622
|
import { useFireproof } from "use-fireproof";
|
|
616
623
|
import { Button, Card, CardContent, Input, Label } from "@vibes.diy/look";
|
|
@@ -690,8 +697,7 @@ For multi-file uploads (e.g. `<input multiple>`), build the `_files` map keyed b
|
|
|
690
697
|
|
|
691
698
|
Adding multi-file support:
|
|
692
699
|
|
|
693
|
-
App.jsx
|
|
694
|
-
|
|
700
|
+
### `App.jsx`
|
|
695
701
|
```jsx
|
|
696
702
|
<<<<<<< SEARCH
|
|
697
703
|
const onPickFile = (e) => {
|
|
@@ -719,8 +725,7 @@ App.jsx
|
|
|
719
725
|
|
|
720
726
|
You can use React's `useState` to manage validation states and error messages. Validate inputs at the UI level before allowing submission. Adding validation to the uploader:
|
|
721
727
|
|
|
722
|
-
App.jsx
|
|
723
|
-
|
|
728
|
+
### `App.jsx`
|
|
724
729
|
```jsx
|
|
725
730
|
<<<<<<< SEARCH
|
|
726
731
|
const onSubmit = async (e) => {
|
|
@@ -747,7 +752,8 @@ App.jsx
|
|
|
747
752
|
|
|
748
753
|
Code listing for todo tracker App.jsx. Note the code ordering: hooks, then handlers, then classNames right before JSX.
|
|
749
754
|
|
|
750
|
-
|
|
755
|
+
### `App.jsx`
|
|
756
|
+
```js
|
|
751
757
|
import React from "react";
|
|
752
758
|
import { useFireproof } from "use-fireproof";
|
|
753
759
|
import { Button, Card, CardContent, Input, Label } from "@vibes.diy/look";
|
|
@@ -8,8 +8,7 @@ Generate and edit images from a text prompt. Each generated image lands as a fil
|
|
|
8
8
|
|
|
9
9
|
Start with a minimal image generation component:
|
|
10
10
|
|
|
11
|
-
App.jsx
|
|
12
|
-
|
|
11
|
+
### `App.jsx`
|
|
13
12
|
```jsx
|
|
14
13
|
import React from "react";
|
|
15
14
|
import { useFireproof } from "use-fireproof";
|
|
@@ -61,8 +60,7 @@ This is the same `_files`-shape contract documented in `fireproof.md`'s "Working
|
|
|
61
60
|
|
|
62
61
|
Pass a `File` object via `images` to run img2img. Adding a file picker that feeds into ImgGen:
|
|
63
62
|
|
|
64
|
-
App.jsx
|
|
65
|
-
|
|
63
|
+
### `App.jsx`
|
|
66
64
|
```jsx
|
|
67
65
|
<<<<<<< SEARCH
|
|
68
66
|
export default function App() {
|
package/llms/image-gen.md
CHANGED
|
@@ -8,9 +8,8 @@ Generate and edit images from a text prompt. Each generated image lands as a fil
|
|
|
8
8
|
|
|
9
9
|
Start with a minimal image generation component:
|
|
10
10
|
|
|
11
|
-
App.jsx
|
|
12
|
-
|
|
13
|
-
```jsx file=App.jsx
|
|
11
|
+
### `App.jsx`
|
|
12
|
+
```jsx
|
|
14
13
|
import React from "react";
|
|
15
14
|
import { useFireproof } from "use-fireproof";
|
|
16
15
|
import { ImgGen } from "use-vibes";
|
|
@@ -61,8 +60,7 @@ This is the same `_files`-shape contract documented in `fireproof.md`'s "Working
|
|
|
61
60
|
|
|
62
61
|
Pass a `File` object via `images` to run img2img. Adding a file picker that feeds into ImgGen:
|
|
63
62
|
|
|
64
|
-
App.jsx
|
|
65
|
-
|
|
63
|
+
### `App.jsx`
|
|
66
64
|
```jsx
|
|
67
65
|
<<<<<<< SEARCH
|
|
68
66
|
export default function App() {
|
package/llms/p5.md
CHANGED
|
@@ -20,9 +20,8 @@ factory function that receives the host element, the instance is built once in
|
|
|
20
20
|
one `useEffect([])`, the canvas is sized from the host, and the cleanup removes
|
|
21
21
|
the instance so remounts do not leak a second draw loop.
|
|
22
22
|
|
|
23
|
-
App.jsx
|
|
24
|
-
|
|
25
|
-
```jsx file=App.jsx
|
|
23
|
+
### `App.jsx`
|
|
24
|
+
```jsx
|
|
26
25
|
import React from "react";
|
|
27
26
|
import p5 from "https://esm.sh/p5@1.11.13";
|
|
28
27
|
import { Button } from "@vibes.diy/look";
|
package/llms/spotify.md
CHANGED
|
@@ -159,7 +159,8 @@ when the route names it.
|
|
|
159
159
|
|
|
160
160
|
## Complete backend.js
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
### `backend.js`
|
|
163
|
+
```js app=spotify-browser
|
|
163
164
|
const TOKEN_URL = "https://accounts.spotify.com/api/token";
|
|
164
165
|
const API = "https://api.spotify.com/v1";
|
|
165
166
|
|
|
@@ -302,7 +303,8 @@ function artistRow(a) {
|
|
|
302
303
|
|
|
303
304
|
## App.jsx sketch
|
|
304
305
|
|
|
305
|
-
|
|
306
|
+
### `App.jsx`
|
|
307
|
+
```jsx app=spotify-browser
|
|
306
308
|
import React, { useState } from "react";
|
|
307
309
|
|
|
308
310
|
const SETUP_STEPS = [
|
package/llms/three-js.md
CHANGED
|
@@ -15,9 +15,8 @@ one `useEffect([])`, the animation loop is a `requestAnimationFrame`, resize
|
|
|
15
15
|
keeps the camera aspect correct, and the cleanup disposes geometry, material,
|
|
16
16
|
and renderer so remounts don't leak GPU memory.
|
|
17
17
|
|
|
18
|
-
App.jsx
|
|
19
|
-
|
|
20
|
-
```jsx file=App.jsx
|
|
18
|
+
### `App.jsx`
|
|
19
|
+
```jsx
|
|
21
20
|
import React from "react";
|
|
22
21
|
import * as THREE from "three";
|
|
23
22
|
|
package/llms/types.d.ts
CHANGED
package/llms/use-vibe.md
CHANGED
|
@@ -26,7 +26,8 @@ Never stamp author fields from `me` while the verdict is pending — `me` is nul
|
|
|
26
26
|
|
|
27
27
|
Gate every write affordance on `can.*`. Hold it while `pending`, and write your own copy when denied. Never branch write permission on `viewer`, `access.hasRole()`/`access.hasChannel()`, or document fields — those drift from what `access.js` actually does. 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
28
|
|
|
29
|
-
|
|
29
|
+
### `App.jsx`
|
|
30
|
+
```jsx
|
|
30
31
|
import { useVibe } from "use-vibes";
|
|
31
32
|
import { Button, Input, Skeleton } from "@vibes.diy/look";
|
|
32
33
|
|
|
@@ -12,8 +12,7 @@ Use `useViewer()` to render **other** people's identity — comment authors, ros
|
|
|
12
12
|
|
|
13
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
14
|
|
|
15
|
-
App.jsx
|
|
16
|
-
|
|
15
|
+
### `App.jsx`
|
|
17
16
|
```jsx
|
|
18
17
|
import React from "react";
|
|
19
18
|
import { useFireproof } from "use-fireproof";
|
|
@@ -50,8 +49,7 @@ export default function App() {
|
|
|
50
49
|
|
|
51
50
|
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
51
|
|
|
53
|
-
App.jsx
|
|
54
|
-
|
|
52
|
+
### `App.jsx`
|
|
55
53
|
```jsx
|
|
56
54
|
<<<<<<< SEARCH
|
|
57
55
|
import { useViewer } from "use-vibes";
|
|
@@ -60,8 +58,7 @@ import { useViewer, useVibe } from "use-vibes";
|
|
|
60
58
|
>>>>>>> REPLACE
|
|
61
59
|
```
|
|
62
60
|
|
|
63
|
-
App.jsx
|
|
64
|
-
|
|
61
|
+
### `App.jsx`
|
|
65
62
|
```jsx
|
|
66
63
|
<<<<<<< SEARCH
|
|
67
64
|
const { viewer, isViewerPending } = useViewer();
|
|
@@ -71,8 +68,7 @@ App.jsx
|
|
|
71
68
|
>>>>>>> REPLACE
|
|
72
69
|
```
|
|
73
70
|
|
|
74
|
-
App.jsx
|
|
75
|
-
|
|
71
|
+
### `App.jsx`
|
|
76
72
|
```jsx
|
|
77
73
|
<<<<<<< SEARCH
|
|
78
74
|
{viewer ? (
|
|
@@ -105,8 +101,7 @@ When one user writes content others will see (comments, posts, messages), **stam
|
|
|
105
101
|
|
|
106
102
|
Wire up a full comment thread with Fireproof and viewer attribution:
|
|
107
103
|
|
|
108
|
-
App.jsx
|
|
109
|
-
|
|
104
|
+
### `App.jsx`
|
|
110
105
|
```jsx
|
|
111
106
|
<<<<<<< SEARCH
|
|
112
107
|
import { useViewer, useVibe } from "use-vibes";
|
package/llms/use-viewer.md
CHANGED
|
@@ -12,9 +12,8 @@ Use `useViewer()` to render **other** people's identity — comment authors, ros
|
|
|
12
12
|
|
|
13
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
14
|
|
|
15
|
-
App.jsx
|
|
16
|
-
|
|
17
|
-
```jsx file=App.jsx
|
|
15
|
+
### `App.jsx`
|
|
16
|
+
```jsx
|
|
18
17
|
import React from "react";
|
|
19
18
|
import { useFireproof } from "use-fireproof";
|
|
20
19
|
import { useViewer } from "use-vibes";
|
|
@@ -51,8 +50,7 @@ export default function App() {
|
|
|
51
50
|
|
|
52
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:
|
|
53
52
|
|
|
54
|
-
App.jsx
|
|
55
|
-
|
|
53
|
+
### `App.jsx`
|
|
56
54
|
```jsx
|
|
57
55
|
<<<<<<< SEARCH
|
|
58
56
|
import { useViewer } from "use-vibes";
|
|
@@ -61,8 +59,7 @@ import { useViewer, useVibe } from "use-vibes";
|
|
|
61
59
|
>>>>>>> REPLACE
|
|
62
60
|
```
|
|
63
61
|
|
|
64
|
-
App.jsx
|
|
65
|
-
|
|
62
|
+
### `App.jsx`
|
|
66
63
|
```jsx
|
|
67
64
|
<<<<<<< SEARCH
|
|
68
65
|
const { viewer, isViewerPending } = useViewer();
|
|
@@ -72,8 +69,7 @@ App.jsx
|
|
|
72
69
|
>>>>>>> REPLACE
|
|
73
70
|
```
|
|
74
71
|
|
|
75
|
-
App.jsx
|
|
76
|
-
|
|
72
|
+
### `App.jsx`
|
|
77
73
|
```jsx
|
|
78
74
|
<<<<<<< SEARCH
|
|
79
75
|
{viewer ? (
|
|
@@ -106,8 +102,7 @@ When one user writes content others will see (comments, posts, messages), **stam
|
|
|
106
102
|
|
|
107
103
|
Wire up a full comment thread with Fireproof and viewer attribution:
|
|
108
104
|
|
|
109
|
-
App.jsx
|
|
110
|
-
|
|
105
|
+
### `App.jsx`
|
|
111
106
|
```jsx
|
|
112
107
|
<<<<<<< SEARCH
|
|
113
108
|
import { useViewer, useVibe } from "use-vibes";
|
package/llms/webxr.md
CHANGED
|
@@ -417,7 +417,8 @@ for (let i = 0; i < 200; i++) {
|
|
|
417
417
|
|
|
418
418
|
A floating galaxy of 2000 particles with a custom-shader core sphere, navigable in VR. Session data stored in Fireproof.
|
|
419
419
|
|
|
420
|
-
|
|
420
|
+
### `App.jsx`
|
|
421
|
+
```javascript
|
|
421
422
|
import * as BABYLON from "@babylonjs/core";
|
|
422
423
|
import React, { useEffect, useRef } from "react";
|
|
423
424
|
import { useFireproof } from "use-fireproof";
|
package/llms/youtube.md
CHANGED
|
@@ -250,7 +250,8 @@ nothing they can act on, and the four cases above each have a different fix.
|
|
|
250
250
|
|
|
251
251
|
## Complete backend.js
|
|
252
252
|
|
|
253
|
-
|
|
253
|
+
### `backend.js`
|
|
254
|
+
```js app=youtube-dashboard
|
|
254
255
|
export const config = {
|
|
255
256
|
scheduled: { interval: "1h" },
|
|
256
257
|
// The visitor path below reads the snapshot docs on the fetch lane, which
|
|
@@ -507,7 +508,8 @@ export async function scheduled(event, ctx) {
|
|
|
507
508
|
|
|
508
509
|
## App.jsx sketch
|
|
509
510
|
|
|
510
|
-
|
|
511
|
+
### `App.jsx`
|
|
512
|
+
```jsx app=youtube-dashboard
|
|
511
513
|
import React, { useState } from "react";
|
|
512
514
|
import { useFireproof } from "use-fireproof";
|
|
513
515
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibes.diy/prompts",
|
|
3
|
-
"version": "14.3.
|
|
3
|
+
"version": "14.3.22",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"exports": {
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
"license": "Apache-2.0",
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@adviser/cement": "~0.5.34",
|
|
40
|
-
"@vibes.diy/call-ai-v2": "14.3.
|
|
41
|
-
"@vibes.diy/identity": "14.3.
|
|
42
|
-
"@vibes.diy/use-vibes-types": "14.3.
|
|
40
|
+
"@vibes.diy/call-ai-v2": "14.3.22",
|
|
41
|
+
"@vibes.diy/identity": "14.3.22",
|
|
42
|
+
"@vibes.diy/use-vibes-types": "14.3.22",
|
|
43
43
|
"arktype": "~2.2.3",
|
|
44
44
|
"json-schema-faker": "~0.6.3"
|
|
45
45
|
},
|
package/prompts.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export declare function generateImportStatements(llms: LlmCatalogEntry[]): strin
|
|
|
20
20
|
export interface MakeBaseSystemPromptOptions {
|
|
21
21
|
fetch?: typeof fetch;
|
|
22
22
|
pkgBaseUrl?: string;
|
|
23
|
-
variant?: "initial" | "initial-oneshot" | "continuation";
|
|
23
|
+
variant?: "initial" | "initial-oneshot" | "initial-draft" | "continuation";
|
|
24
24
|
suppressDefaultStylePrompt?: boolean;
|
|
25
25
|
look?: boolean;
|
|
26
26
|
}
|