@vibes.diy/prompts 2.2.12 → 2.2.13-dev.2
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/json-docs.d.ts +1 -0
- package/json-docs.js.map +1 -1
- package/llms/index.d.ts +2 -1
- package/llms/index.js +11 -1
- package/llms/index.js.map +1 -1
- package/llms/use-viewer.d.ts +2 -0
- package/llms/use-viewer.js +9 -0
- package/llms/use-viewer.js.map +1 -0
- package/llms/use-viewer.md +107 -0
- package/package.json +3 -3
- package/system-prompt-initial.md +1 -0
- package/system-prompt.md +1 -0
package/json-docs.d.ts
CHANGED
package/json-docs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-docs.js","sourceRoot":"","sources":["../jsr/json-docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"json-docs.js","sourceRoot":"","sources":["../jsr/json-docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAuB7C,MAAM,UAAU,kBAAkB;IAChC,OAAO,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,eAAe,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;QACjC,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,IAAuB,EAAE;IAC5D,MAAM,CAAC,GAAa,EAAc,CAAC;IAGnC,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,GAAG,MAAM,CAAC,IAAI,OAAO,CAAC;QACvC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAChD,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC,CAAC,CAAC"}
|
package/llms/index.d.ts
CHANGED
|
@@ -4,5 +4,6 @@ export { imageGenConfig } from "./image-gen.js";
|
|
|
4
4
|
export { webAudioConfig } from "./web-audio.js";
|
|
5
5
|
export { d3Config } from "./d3.js";
|
|
6
6
|
export { threeJsConfig } from "./three-js.js";
|
|
7
|
+
export { useViewerConfig } from "./use-viewer.js";
|
|
7
8
|
export type { LlmConfig } from "./types.js";
|
|
8
|
-
export declare const allConfigs: readonly [import("./types.js").LlmConfig, import("./types.js").LlmConfig, import("./types.js").LlmConfig, import("./types.js").LlmConfig, import("./types.js").LlmConfig, import("./types.js").LlmConfig];
|
|
9
|
+
export declare const allConfigs: readonly [import("./types.js").LlmConfig, import("./types.js").LlmConfig, import("./types.js").LlmConfig, import("./types.js").LlmConfig, import("./types.js").LlmConfig, import("./types.js").LlmConfig, import("./types.js").LlmConfig];
|
package/llms/index.js
CHANGED
|
@@ -4,11 +4,21 @@ import { imageGenConfig } from "./image-gen.js";
|
|
|
4
4
|
import { webAudioConfig } from "./web-audio.js";
|
|
5
5
|
import { d3Config } from "./d3.js";
|
|
6
6
|
import { threeJsConfig } from "./three-js.js";
|
|
7
|
+
import { useViewerConfig } from "./use-viewer.js";
|
|
7
8
|
export { callaiConfig } from "./callai.js";
|
|
8
9
|
export { fireproofConfig } from "./fireproof.js";
|
|
9
10
|
export { imageGenConfig } from "./image-gen.js";
|
|
10
11
|
export { webAudioConfig } from "./web-audio.js";
|
|
11
12
|
export { d3Config } from "./d3.js";
|
|
12
13
|
export { threeJsConfig } from "./three-js.js";
|
|
13
|
-
export
|
|
14
|
+
export { useViewerConfig } from "./use-viewer.js";
|
|
15
|
+
export const allConfigs = [
|
|
16
|
+
callaiConfig,
|
|
17
|
+
imageGenConfig,
|
|
18
|
+
webAudioConfig,
|
|
19
|
+
d3Config,
|
|
20
|
+
threeJsConfig,
|
|
21
|
+
fireproofConfig,
|
|
22
|
+
useViewerConfig,
|
|
23
|
+
];
|
|
14
24
|
//# sourceMappingURL=index.js.map
|
package/llms/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../jsr/llms/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../jsr/llms/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIlD,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,YAAY;IACZ,cAAc;IACd,cAAc;IACd,QAAQ;IACR,aAAa;IACb,eAAe;IACf,eAAe;CACP,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const useViewerConfig = {
|
|
2
|
+
name: "use-viewer",
|
|
3
|
+
label: "Viewer Identity",
|
|
4
|
+
module: "use-vibes",
|
|
5
|
+
description: "Get the current viewer's identity and capability gates",
|
|
6
|
+
importModule: "use-vibes",
|
|
7
|
+
importName: "useViewer",
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=use-viewer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-viewer.js","sourceRoot":"","sources":["../../jsr/llms/use-viewer.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,IAAI,EAAE,YAAY;IAClB,KAAK,EAAE,iBAAiB;IACxB,MAAM,EAAE,WAAW;IACnB,WAAW,EAAE,wDAAwD;IACrE,YAAY,EAAE,WAAW;IACzB,UAAU,EAAE,WAAW;CACxB,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# useViewer Hook
|
|
2
|
+
|
|
3
|
+
Get the current viewer's identity and capabilities. Use it to render avatars, names, and gate UI on what the viewer can do.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
```jsx
|
|
8
|
+
import { useViewer } from "use-vibes";
|
|
9
|
+
|
|
10
|
+
function App() {
|
|
11
|
+
const { viewer, can } = useViewer();
|
|
12
|
+
if (!viewer) return <p>Sign in to use this app.</p>;
|
|
13
|
+
return (
|
|
14
|
+
<header>
|
|
15
|
+
<img src={viewer.avatarUrl} alt={viewer.userSlug} />
|
|
16
|
+
<span>{viewer.displayName ?? viewer.userSlug}</span>
|
|
17
|
+
</header>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## What you get
|
|
23
|
+
|
|
24
|
+
- `viewer` — `{ userSlug, displayName?, avatarUrl }` or `null` for anonymous visitors. `avatarUrl` is a stable opaque URL — just use it in `<img src>`, don't construct it yourself.
|
|
25
|
+
- `can(action, dbName?)` — `true`/`false` for `"read"`, `"write"`, `"delete"`. Pass a `dbName` for multi-db apps; omit for single-db apps. Use it to hide forms when the viewer can't post.
|
|
26
|
+
|
|
27
|
+
## Gating UI
|
|
28
|
+
|
|
29
|
+
```jsx
|
|
30
|
+
function CommentForm() {
|
|
31
|
+
const { viewer, can } = useViewer();
|
|
32
|
+
if (!viewer) return <p>Sign in to comment.</p>;
|
|
33
|
+
if (!can("write", "comments")) return <p>Contact the owner to request write access so you can post.</p>;
|
|
34
|
+
return <form>...</form>;
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Tagging content with the viewer (write/render pattern)
|
|
39
|
+
|
|
40
|
+
When one user writes content others will see (comments, posts, messages), **stamp the viewer's identity onto the doc at write time**. Then any user can render the author info from the doc itself — no extra lookup. The `avatarUrl` is a stable indirection URL so it keeps working when the author later changes their avatar.
|
|
41
|
+
|
|
42
|
+
```jsx
|
|
43
|
+
import { useFireproof } from "use-fireproof";
|
|
44
|
+
import { useViewer } from "use-vibes";
|
|
45
|
+
|
|
46
|
+
function CommentThread() {
|
|
47
|
+
const { viewer, can } = useViewer();
|
|
48
|
+
const { useLiveQuery, database } = useFireproof("comments");
|
|
49
|
+
const { docs: comments } = useLiveQuery("createdAt");
|
|
50
|
+
const [body, setBody] = useState("");
|
|
51
|
+
|
|
52
|
+
async function post() {
|
|
53
|
+
if (!viewer || !body.trim()) return;
|
|
54
|
+
await database.put({
|
|
55
|
+
body: body.trim(),
|
|
56
|
+
createdAt: Date.now(),
|
|
57
|
+
// Stamp the viewer's identity at write time. Other users will
|
|
58
|
+
// render from these fields — no need to look anything up later.
|
|
59
|
+
authorUserSlug: viewer.userSlug,
|
|
60
|
+
authorDisplayName: viewer.displayName ?? viewer.userSlug,
|
|
61
|
+
authorAvatarUrl: viewer.avatarUrl,
|
|
62
|
+
});
|
|
63
|
+
setBody("");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<div>
|
|
68
|
+
<ul>
|
|
69
|
+
{comments.map((c) => (
|
|
70
|
+
<li key={c._id}>
|
|
71
|
+
<img src={c.authorAvatarUrl} alt={c.authorUserSlug} className="avatar" />
|
|
72
|
+
<strong>{c.authorDisplayName}</strong>
|
|
73
|
+
<p>{c.body}</p>
|
|
74
|
+
</li>
|
|
75
|
+
))}
|
|
76
|
+
</ul>
|
|
77
|
+
|
|
78
|
+
{!viewer ? (
|
|
79
|
+
<p>Sign in to comment.</p>
|
|
80
|
+
) : !can("write", "comments") ? (
|
|
81
|
+
<p>Contact the owner to request write access so you can post.</p>
|
|
82
|
+
) : (
|
|
83
|
+
<form
|
|
84
|
+
onSubmit={(e) => {
|
|
85
|
+
e.preventDefault();
|
|
86
|
+
post();
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
<input value={body} onChange={(e) => setBody(e.target.value)} />
|
|
90
|
+
<button type="submit">Post</button>
|
|
91
|
+
</form>
|
|
92
|
+
)}
|
|
93
|
+
</div>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Key points:
|
|
99
|
+
|
|
100
|
+
- **Write-time stamping** — the doc carries the author info, not a foreign-key lookup. Old comments keep working even if the author later deletes their account.
|
|
101
|
+
- **`avatarUrl` is stable** — if the author changes their avatar tomorrow, every historical comment shows the new image because the URL stays the same, the bytes change.
|
|
102
|
+
- **One source of identity** — never store the viewer's user ID, only `userSlug` + `displayName` + `avatarUrl`. The trio is everything a renderer needs.
|
|
103
|
+
|
|
104
|
+
## Notes
|
|
105
|
+
|
|
106
|
+
- Never use Clerk user IDs. Only `userSlug` crosses into vibe code.
|
|
107
|
+
- Avatar URLs are stable indirection URLs — when a user changes their avatar, the URL stays the same and the bytes update. Treat them as opaque strings.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibes.diy/prompts",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.13-dev.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"description": "",
|
|
@@ -30,8 +30,8 @@
|
|
|
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.2.
|
|
34
|
-
"@vibes.diy/use-vibes-types": "^2.2.
|
|
33
|
+
"@vibes.diy/call-ai-v2": "^2.2.13-dev.2",
|
|
34
|
+
"@vibes.diy/use-vibes-types": "^2.2.13-dev.2",
|
|
35
35
|
"arktype": "~2.2.0",
|
|
36
36
|
"json-schema-faker": "~0.6.1"
|
|
37
37
|
},
|
package/system-prompt-initial.md
CHANGED
|
@@ -14,6 +14,7 @@ You are an AI assistant tasked with creating React components. You should create
|
|
|
14
14
|
- Use `callAI` to fetch AI, use schema like this: `JSON.parse(await callAI(prompt, { schema: { properties: { todos: { type: 'array', items: { type: 'string' } } } } }))` and save final responses as individual Fireproof documents.
|
|
15
15
|
- 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); }`
|
|
16
16
|
- For file uploads use drag and drop and store using the `doc._files` API; for AI image generation use `<ImgGen prompt="..." />`
|
|
17
|
+
- For viewer identity and capability gating use `const { viewer, can } = useViewer();` from `"use-vibes"`. `viewer` is `{ userSlug, displayName?, avatarUrl } | null` (null when anonymous). Render avatars with `<img src={viewer.avatarUrl} />` (opaque URL — use directly). Gate write UI on `can("write")` — e.g. `if (!can("write")) return <p>Contact the owner to request write access so you can post.</p>;` before rendering a form. For multi-db apps pass the dbName: `can("write", "comments")`. See use-viewer docs.
|
|
17
18
|
- 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
|
|
18
19
|
- 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.
|
|
19
20
|
- List data items on the main page of your app so users don't have to hunt for them
|
package/system-prompt.md
CHANGED
|
@@ -14,6 +14,7 @@ You are an AI assistant tasked with creating React components. You should create
|
|
|
14
14
|
- Use `callAI` to fetch AI, use schema like this: `JSON.parse(await callAI(prompt, { schema: { properties: { todos: { type: 'array', items: { type: 'string' } } } } }))` and save final responses as individual Fireproof documents.
|
|
15
15
|
- 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); }`
|
|
16
16
|
- For file uploads use drag and drop and store using the `doc._files` API; for AI image generation use `<ImgGen prompt="..." />`
|
|
17
|
+
- For viewer identity and capability gating use `const { viewer, can } = useViewer();` from `"use-vibes"`. `viewer` is `{ userSlug, displayName?, avatarUrl } | null` (null when anonymous). Render avatars with `<img src={viewer.avatarUrl} />` (opaque URL — use directly). Gate write UI on `can("write")` — e.g. `if (!can("write")) return <p>Contact the owner to request write access so you can post.</p>;` before rendering a form. For multi-db apps pass the dbName: `can("write", "comments")`. See use-viewer docs.
|
|
17
18
|
- 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
|
|
18
19
|
- 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.
|
|
19
20
|
- Consider and potentially reuse/extend code from previous responses if relevant
|