@vibes.diy/prompts 2.2.11 → 2.2.13-dev.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/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/prompts.d.ts +1 -1
- package/prompts.js +2 -2
- package/prompts.js.map +1 -1
- package/system-prompt-initial.md +1 -0
- package/system-prompt.md +85 -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.1",
|
|
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.1",
|
|
34
|
+
"@vibes.diy/use-vibes-types": "^2.2.13-dev.1",
|
|
35
35
|
"arktype": "~2.2.0",
|
|
36
36
|
"json-schema-faker": "~0.6.1"
|
|
37
37
|
},
|
package/prompts.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export declare const preAllocSchema: {
|
|
|
41
41
|
};
|
|
42
42
|
readonly theme: {
|
|
43
43
|
readonly type: "string";
|
|
44
|
-
readonly description: "
|
|
44
|
+
readonly description: "Theme slug from the theme catalog above. Pick the one whose mood best fits the app \u2014 playful apps lean playful themes, focus/utility apps lean clean themes, retro apps lean retro themes, etc. Always pick something rather than leaving empty; the catalog is broad enough to cover most app moods. Only omit if the request is so abstract that every theme would feel arbitrary.";
|
|
45
45
|
};
|
|
46
46
|
};
|
|
47
47
|
};
|
package/prompts.js
CHANGED
|
@@ -38,7 +38,7 @@ export async function makePreAllocUserMessage(userPrompt) {
|
|
|
38
38
|
.map((t) => `- ${t.slug}: ${t.name}${t.bodyFont ? ` (${t.bodyFont.replace(/['"]/g, "").split(",")[0].trim()})` : ""}`)
|
|
39
39
|
.join("\n");
|
|
40
40
|
return [
|
|
41
|
-
"Pick skills from this catalog that fit the user's app request, propose 3 title/slug pairs for naming, propose a one-line icon subject, and
|
|
41
|
+
"Pick skills from this catalog that fit the user's app request, propose 3 title/slug pairs for naming, propose a one-line icon subject, and pick a theme that matches the app's mood.",
|
|
42
42
|
"",
|
|
43
43
|
"Skill catalog:",
|
|
44
44
|
catalogText,
|
|
@@ -75,7 +75,7 @@ export const preAllocSchema = {
|
|
|
75
75
|
},
|
|
76
76
|
theme: {
|
|
77
77
|
type: "string",
|
|
78
|
-
description: "
|
|
78
|
+
description: "Theme slug from the theme catalog above. Pick the one whose mood best fits the app — playful apps lean playful themes, focus/utility apps lean clean themes, retro apps lean retro themes, etc. Always pick something rather than leaving empty; the catalog is broad enough to cover most app moods. Only omit if the request is so abstract that every theme would feel arbitrary.",
|
|
79
79
|
},
|
|
80
80
|
},
|
|
81
81
|
};
|
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,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAmB,MAAM,gBAAgB,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,MAAM,CAAC,MAAM,oBAAoB,GAAG,2BAAoC,CAAC;AAEzE,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,UAAU,gBAAgB,CAAC,EAAW;IAC1C,OAAO,wBAAwB,CAAC,EAAE,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,EAAW;IAC5C,OAAO,OAAO,wBAAwB,CAAC,EAAE,CAAC,KAAK,QAAQ,CAAC;AAC1D,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,CAAC,CAAC;AAC3D,CAAC;AASD,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,
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../jsr/prompts.ts"],"names":[],"mappings":"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"}
|
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
|
|
@@ -60,6 +61,90 @@ Each `<<<<<<< SEARCH` snippet must match exactly one place in the current file (
|
|
|
60
61
|
|
|
61
62
|
If a single SEARCH/REPLACE grows beyond ~25 lines, split it.
|
|
62
63
|
|
|
64
|
+
**Two `...` shortcuts on the SEARCH side keep edits compact:**
|
|
65
|
+
|
|
66
|
+
- A line ending in `...` is a single-line **prefix match** — the source line must begin with what's before the `...`; the rest is ignored. Use this to skip long Tailwind class strings or other noisy line tails.
|
|
67
|
+
- A line starting with `...` is a **multi-line skip** — it matches zero or more source lines of any content. Any text after the leading `...` is just a comment for clarity (e.g. `...rest of body`). The skipped lines are part of the replaced range.
|
|
68
|
+
- A `...` in the middle of a line is literal text and participates in exact match. The REPLACE side never has special meaning for `...` — write the new content verbatim.
|
|
69
|
+
|
|
70
|
+
Example — replacing a function with a fat Tailwind line without retyping the classes:
|
|
71
|
+
|
|
72
|
+
```jsx
|
|
73
|
+
<<<<<<< SEARCH
|
|
74
|
+
function CardHeader() {
|
|
75
|
+
return <h2 className="text-2xl font-bold...
|
|
76
|
+
}
|
|
77
|
+
=======
|
|
78
|
+
function CardHeader() {
|
|
79
|
+
return <h2 className="text-3xl font-extrabold tracking-tight">{title}</h2>;
|
|
80
|
+
}
|
|
81
|
+
>>>>>>> REPLACE
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The matcher still requires exactly one match in the file; if the `...` shortcuts make the SEARCH ambiguous, add a surrounding anchor line to disambiguate.
|
|
85
|
+
|
|
86
|
+
**The most common use of `...` is editing one key in a multi-line styles object.** Tailwind class strings, theme `:root { ... }` blocks, oklch/rgba color tokens — these lines are long and easy to misremember. Always edit ONE key per SEARCH/REPLACE, anchor on the key name, and let `...` consume the value:
|
|
87
|
+
|
|
88
|
+
**Keep the prefix as short as possible — just enough to be unique in the file.** For an object key, the key name alone is usually unique. You do NOT need to copy the existing value to anchor on it; the `...` does that.
|
|
89
|
+
|
|
90
|
+
Tailwind classNames object — change the page background color only:
|
|
91
|
+
|
|
92
|
+
```jsx
|
|
93
|
+
<<<<<<< SEARCH
|
|
94
|
+
page: "...
|
|
95
|
+
=======
|
|
96
|
+
page: "min-h-screen flex flex-col max-w-lg mx-auto bg-[#1a0015]",
|
|
97
|
+
>>>>>>> REPLACE
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
` page: "` is unique inside the `c = { ... }` object, so that's the whole anchor needed. The `...` consumes whatever value is there now; the REPLACE writes the new one.
|
|
101
|
+
|
|
102
|
+
CSS variable inside `THEME_CSS` — change one variable, leave the rest:
|
|
103
|
+
|
|
104
|
+
```jsx
|
|
105
|
+
<<<<<<< SEARCH
|
|
106
|
+
--bg:...
|
|
107
|
+
=======
|
|
108
|
+
--bg: #1a0510;
|
|
109
|
+
>>>>>>> REPLACE
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Inline JSX attribute on a long element — change just one prop:
|
|
113
|
+
|
|
114
|
+
```jsx
|
|
115
|
+
<<<<<<< SEARCH
|
|
116
|
+
<button className="...
|
|
117
|
+
=======
|
|
118
|
+
<button className="px-6 py-3 rounded-2xl bg-emerald-600 hover:bg-emerald-700">
|
|
119
|
+
>>>>>>> REPLACE
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
If a short prefix would match in two places, then add just enough surrounding context to disambiguate — but don't pre-emptively copy the whole long line.
|
|
123
|
+
|
|
124
|
+
❌ Do NOT replace the entire `c = { ... }` styles object, the entire `:root { ... }` block, or a long JSX line in one giant SEARCH/REPLACE. Reproducing those bytes from memory drifts (variable names invented, rgba values guessed, key order shuffled, trailing commas changed) and the matcher rejects with `no-match` over and over. **One key, one variable, one attribute per edit, with `...` doing the heavy lifting.**
|
|
125
|
+
|
|
126
|
+
❌ Even worse: writing a single-line SEARCH that retypes the FULL existing Tailwind value to anchor on it, like:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
<<<<<<< SEARCH
|
|
130
|
+
page: "w-full h-screen flex flex-col overflow-hidden relative",
|
|
131
|
+
=======
|
|
132
|
+
page: "w-full h-screen flex flex-col overflow-hidden relative bg-[#2a1810]",
|
|
133
|
+
>>>>>>> REPLACE
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
That looks safe but isn't — your memory of the value drifts a single space or class away from the bytes on disk and the matcher fails. **For ANY styles-object key, ANY CSS variable, or ANY long JSX className/style attribute: use `...`. The whole value is don't-care — let the matcher swallow it.** The correct shape is:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
<<<<<<< SEARCH
|
|
140
|
+
page: "...
|
|
141
|
+
=======
|
|
142
|
+
page: "w-full h-screen flex flex-col overflow-hidden relative bg-[#2a1810]",
|
|
143
|
+
>>>>>>> REPLACE
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Same edit, fewer bytes, and the SEARCH matches whatever the file actually contains regardless of whether you remembered it correctly. **Never retype a value just to anchor on it — anchor on the key + `...` instead.**
|
|
147
|
+
|
|
63
148
|
**Always go feature-by-feature with SEARCH/REPLACE.** Do NOT emit the whole file as a single edit just because the build feels substantial — the user wants to see each feature land incrementally. If you find yourself thinking "this is a substantial build, I'll do it in one pass", do not — go feature-by-feature instead.
|
|
64
149
|
|
|
65
150
|
**Heavy rewrites use a full-file block, never a giant SEARCH/REPLACE.** When the user explicitly asks for a complete overhaul or redesign (e.g. "redo the whole thing", "switch to a totally different layout"), or when more than ~60% of the file would change, emit a fresh **full-file block** — exactly the same shape as the scaffold above: a filename line, a fenced ```jsx block, the entire new file contents, the closing fence. **No `<<<<<<< SEARCH` markers.\*\* This replaces the file in one shot.
|