@vibes.diy/prompts 14.1.50 → 14.1.52

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/three-js.md CHANGED
@@ -1208,6 +1208,7 @@ Structure your component in this order:
1208
1208
  import React, { useState, useEffect, useRef, useCallback } from "react";
1209
1209
  import { useFireproof } from "use-fireproof";
1210
1210
  import * as THREE from "three";
1211
+ import { Card, CardContent, CardHeader, CardTitle } from "@vibes.diy/look";
1211
1212
 
1212
1213
  export default function SkyGlider() {
1213
1214
  const { database, useLiveQuery } = useFireproof("skyGliderScores");
@@ -1605,25 +1606,33 @@ export default function SkyGlider() {
1605
1606
  }, [initThreeJS, handleKeyDown, handleKeyUp, handleResize]);
1606
1607
 
1607
1608
  return (
1608
- <div className="relative h-screen w-full bg-sky-200">
1609
+ <div className="relative h-screen w-full bg-background text-foreground font-sans">
1609
1610
  <canvas ref={canvasRef} className="absolute inset-0" />
1610
- <div className="absolute top-4 left-4 rounded-lg bg-card text-card-foreground p-4 shadow-md">
1611
- <h2 className="text-lg font-bold">Sky Glider</h2>
1612
- <p>Score: {currentScore}</p>
1613
- <p className="mt-2 text-sm">WASD/Arrows: Fly, Space: Thrust</p>
1614
- </div>
1611
+ <Card className="absolute top-4 left-4">
1612
+ <CardHeader>
1613
+ <CardTitle>Sky Glider</CardTitle>
1614
+ </CardHeader>
1615
+ <CardContent>
1616
+ <p>Score: {currentScore}</p>
1617
+ <p className="mt-2 text-muted-foreground">WASD/Arrows: Fly, Space: Thrust</p>
1618
+ </CardContent>
1619
+ </Card>
1615
1620
  {scoreData.length > 0 && (
1616
- <div className="absolute top-4 right-4 rounded-lg bg-card text-card-foreground p-4 shadow-md">
1617
- <h3 className="font-bold">High Scores</h3>
1618
- {scoreData
1619
- .sort((a, b) => b.value - a.value)
1620
- .slice(0, 3)
1621
- .map((score, i) => (
1622
- <div key={score._id} className="text-sm">
1623
- #{i + 1}: {score.value}
1624
- </div>
1625
- ))}
1626
- </div>
1621
+ <Card className="absolute top-4 right-4">
1622
+ <CardHeader>
1623
+ <CardTitle>High Scores</CardTitle>
1624
+ </CardHeader>
1625
+ <CardContent>
1626
+ {scoreData
1627
+ .sort((a, b) => b.value - a.value)
1628
+ .slice(0, 3)
1629
+ .map((score, i) => (
1630
+ <div key={score._id}>
1631
+ #{i + 1}: {score.value}
1632
+ </div>
1633
+ ))}
1634
+ </CardContent>
1635
+ </Card>
1627
1636
  )}
1628
1637
  </div>
1629
1638
  );
@@ -1640,6 +1649,8 @@ import { OrbitControls } from "three/addons/controls/OrbitControls.js";
1640
1649
  import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";
1641
1650
  import { RenderPass } from "three/addons/postprocessing/RenderPass.js";
1642
1651
  import { HalftonePass } from "three/addons/postprocessing/HalftonePass.js";
1652
+ import { Button, Card, CardContent, CardHeader, CardTitle, Input, Label, Separator } from "@vibes.diy/look";
1653
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@vibes.diy/look/overlay";
1643
1654
 
1644
1655
  export default function HalftoneArtStudio() {
1645
1656
  const { database, useLiveQuery } = useFireproof("halftoneStudio");
@@ -1994,292 +2005,145 @@ export default function HalftoneArtStudio() {
1994
2005
  <div className="relative h-screen w-full overflow-hidden bg-background text-foreground font-sans">
1995
2006
  <canvas ref={canvasRef} className="absolute inset-0" />
1996
2007
 
1997
- {/* Main Control Panel */}
1998
- <div
1999
- className={`absolute top-4 left-4 max-h-[calc(100vh-2rem)] overflow-y-auto rounded-lg bg-card text-card-foreground p-4 shadow-lg transition-all duration-300 ${showParameters ? "w-80" : "w-64"}`}
2000
- >
2001
- <h2 className="mb-4 text-lg font-bold text-card-foreground">RGB Halftone Studio</h2>
2002
-
2003
- {/* Always visible controls */}
2004
- <div className="mb-4 space-y-3">
2005
- <button
2006
- onClick={generateRandomScene}
2007
- disabled={isGenerating}
2008
- className="w-full rounded-md bg-primary px-4 py-3 font-bold text-primary-foreground shadow-sm active:translate-y-px active:shadow-sm disabled:opacity-50"
2009
- >
2010
- {isGenerating ? "Generating..." : "🎲 Random Art"}
2011
- </button>
2012
-
2013
- <button
2014
- onClick={() => setShowParameters(!showParameters)}
2015
- className="w-full rounded-md bg-secondary px-4 py-2 font-bold text-secondary-foreground shadow-sm active:translate-y-px active:shadow-sm"
2016
- >
2008
+ {/* One control panel. The look's `Card` IS the panel — its `className`
2009
+ carries placement only; the cushion, corner and ink are its own. */}
2010
+ <Card className="absolute inset-y-4 left-4 w-80 overflow-y-auto">
2011
+ <CardHeader>
2012
+ <CardTitle>RGB Halftone Studio</CardTitle>
2013
+ </CardHeader>
2014
+ <CardContent className="space-y-4">
2015
+ <Button className="w-full" onClick={generateRandomScene} disabled={isGenerating}>
2016
+ {isGenerating ? "Generating…" : "🎲 Random Art"}
2017
+ </Button>
2018
+ <Button variant="secondary" className="w-full" onClick={() => setShowParameters(!showParameters)}>
2017
2019
  {showParameters ? "🔼 Hide Controls" : "🔽 Show Controls"}
2018
- </button>
2019
- </div>
2020
-
2021
- {/* Expandable parameter controls */}
2022
- {showParameters && (
2023
- <div className="space-y-4">
2024
- {/* Shape Controls */}
2025
- <div>
2026
- <label className="mb-2 block text-sm font-bold text-card-foreground">Shape: {shapeName}</label>
2027
- <select
2028
- value={parameters.shape}
2029
- onChange={(e) =>
2030
- setParameters((prev) => ({
2031
- ...prev,
2032
- shape: parseInt(e.target.value),
2033
- }))
2034
- }
2035
- className="w-full rounded-md border border-input p-2 text-card-foreground focus:ring-2 focus:ring-ring"
2036
- >
2037
- <option value={1}>Dot</option>
2038
- <option value={2}>Ellipse</option>
2039
- <option value={3}>Line</option>
2040
- <option value={4}>Square</option>
2041
- </select>
2042
- </div>
2043
-
2044
- {/* Size Controls */}
2045
- <div>
2046
- <label className="mb-2 block text-sm font-bold text-card-foreground">Size: {parameters.radius.toFixed(1)}</label>
2047
- <input
2048
- type="range"
2049
- min="1"
2050
- max="25"
2051
- step="0.5"
2052
- value={parameters.radius}
2053
- onChange={(e) =>
2054
- setParameters((prev) => ({
2055
- ...prev,
2056
- radius: parseFloat(e.target.value),
2057
- }))
2058
- }
2059
- className="w-full"
2060
- />
2061
- </div>
2062
-
2063
- {/* Color Rotation */}
2064
- <div className="grid grid-cols-3 gap-2">
2065
- <div>
2066
- <label className="mb-1 block text-xs font-bold text-muted-foreground">Red: {parameters.rotateR.toFixed(0)}°</label>
2067
- <input
2068
- type="range"
2069
- min="0"
2070
- max="90"
2071
- value={parameters.rotateR}
2072
- onChange={(e) =>
2073
- setParameters((prev) => ({
2074
- ...prev,
2075
- rotateR: parseFloat(e.target.value),
2076
- }))
2077
- }
2078
- className="w-full"
2079
- />
2020
+ </Button>
2021
+
2022
+ {showParameters && (
2023
+ <div className="space-y-4">
2024
+ <Separator />
2025
+
2026
+ {/* A chooser is `Select`, and its props do the styling. */}
2027
+ <div className="space-y-2">
2028
+ <Label htmlFor="shape">Shape: {shapeName}</Label>
2029
+ <Select value={String(parameters.shape)} onValueChange={(value) => setParameters((prev) => ({ ...prev, shape: parseInt(value) }))}>
2030
+ <SelectTrigger id="shape" className="w-full">
2031
+ <SelectValue />
2032
+ </SelectTrigger>
2033
+ <SelectContent>
2034
+ <SelectItem value="1">Dot</SelectItem>
2035
+ <SelectItem value="2">Ellipse</SelectItem>
2036
+ <SelectItem value="3">Line</SelectItem>
2037
+ <SelectItem value="4">Square</SelectItem>
2038
+ </SelectContent>
2039
+ </Select>
2080
2040
  </div>
2081
- <div>
2082
- <label className="mb-1 block text-xs font-bold text-muted-foreground">Green: {parameters.rotateG.toFixed(0)}°</label>
2041
+
2042
+ {/* A range slider and a checkbox are NOT in the package, so they
2043
+ stay plain elements you style by hand. Blend amount and the
2044
+ per-channel R/G/B rotations are this same Label + range pair,
2045
+ one per uniform. */}
2046
+ <div className="space-y-2">
2047
+ <Label htmlFor="size">Size: {parameters.radius.toFixed(1)}</Label>
2083
2048
  <input
2049
+ id="size"
2084
2050
  type="range"
2085
- min="0"
2086
- max="90"
2087
- value={parameters.rotateG}
2088
- onChange={(e) =>
2089
- setParameters((prev) => ({
2090
- ...prev,
2091
- rotateG: parseFloat(e.target.value),
2092
- }))
2093
- }
2051
+ min="1"
2052
+ max="25"
2053
+ step="0.5"
2054
+ value={parameters.radius}
2055
+ onChange={(e) => setParameters((prev) => ({ ...prev, radius: parseFloat(e.target.value) }))}
2094
2056
  className="w-full"
2095
2057
  />
2096
2058
  </div>
2097
- <div>
2098
- <label className="mb-1 block text-xs font-bold text-muted-foreground">Blue: {parameters.rotateB.toFixed(0)}°</label>
2059
+
2060
+ <div className="space-y-2">
2061
+ <Label htmlFor="scatter">Scatter: {(parameters.scatter * 100).toFixed(0)}%</Label>
2099
2062
  <input
2063
+ id="scatter"
2100
2064
  type="range"
2101
2065
  min="0"
2102
- max="90"
2103
- value={parameters.rotateB}
2104
- onChange={(e) =>
2105
- setParameters((prev) => ({
2106
- ...prev,
2107
- rotateB: parseFloat(e.target.value),
2108
- }))
2109
- }
2066
+ max="1"
2067
+ step="0.01"
2068
+ value={parameters.scatter}
2069
+ onChange={(e) => setParameters((prev) => ({ ...prev, scatter: parseFloat(e.target.value) }))}
2110
2070
  className="w-full"
2111
2071
  />
2112
2072
  </div>
2113
- </div>
2114
-
2115
- {/* Effects */}
2116
- <div>
2117
- <label className="mb-2 block text-sm font-bold text-card-foreground">
2118
- Scatter: {(parameters.scatter * 100).toFixed(0)}%
2119
- </label>
2120
- <input
2121
- type="range"
2122
- min="0"
2123
- max="1"
2124
- step="0.01"
2125
- value={parameters.scatter}
2126
- onChange={(e) =>
2127
- setParameters((prev) => ({
2128
- ...prev,
2129
- scatter: parseFloat(e.target.value),
2130
- }))
2131
- }
2132
- className="w-full"
2133
- />
2134
- </div>
2135
2073
 
2136
- <div>
2137
- <label className="mb-2 block text-sm font-bold text-card-foreground">
2138
- Blend: {(parameters.blending * 100).toFixed(0)}%
2139
- </label>
2140
- <input
2141
- type="range"
2142
- min="0"
2143
- max="1"
2144
- step="0.01"
2145
- value={parameters.blending}
2146
- onChange={(e) =>
2147
- setParameters((prev) => ({
2148
- ...prev,
2149
- blending: parseFloat(e.target.value),
2150
- }))
2151
- }
2152
- className="w-full"
2153
- />
2154
- </div>
2155
-
2156
- <div>
2157
- <label className="mb-2 block text-sm font-bold text-card-foreground">Blend Mode: {blendModeName}</label>
2158
- <select
2159
- value={parameters.blendingMode}
2160
- onChange={(e) =>
2161
- setParameters((prev) => ({
2162
- ...prev,
2163
- blendingMode: parseInt(e.target.value),
2164
- }))
2165
- }
2166
- className="w-full rounded-md border border-input p-2 text-card-foreground focus:ring-2 focus:ring-ring"
2167
- >
2168
- <option value={1}>Linear</option>
2169
- <option value={2}>Multiply</option>
2170
- <option value={3}>Add</option>
2171
- <option value={4}>Lighter</option>
2172
- <option value={5}>Darker</option>
2173
- </select>
2174
- </div>
2175
-
2176
- {/* Toggles */}
2177
- <div className="space-y-2">
2178
- <label className="flex items-center">
2179
- <input
2180
- type="checkbox"
2181
- checked={parameters.greyscale}
2182
- onChange={(e) =>
2183
- setParameters((prev) => ({
2184
- ...prev,
2185
- greyscale: e.target.checked,
2186
- }))
2187
- }
2188
- className="mr-2"
2189
- />
2190
- <span className="text-sm font-bold text-card-foreground">Greyscale</span>
2191
- </label>
2192
-
2193
- <label className="flex items-center">
2194
- <input
2195
- type="checkbox"
2196
- checked={parameters.disable}
2197
- onChange={(e) =>
2198
- setParameters((prev) => ({
2199
- ...prev,
2200
- disable: e.target.checked,
2201
- }))
2202
- }
2203
- className="mr-2"
2204
- />
2205
- <span className="text-sm font-bold text-card-foreground">Disable Effect</span>
2206
- </label>
2207
- </div>
2074
+ <div className="space-y-2">
2075
+ <Label htmlFor="blend-mode">Blend Mode: {blendModeName}</Label>
2076
+ <Select
2077
+ value={String(parameters.blendingMode)}
2078
+ onValueChange={(value) => setParameters((prev) => ({ ...prev, blendingMode: parseInt(value) }))}
2079
+ >
2080
+ <SelectTrigger id="blend-mode" className="w-full">
2081
+ <SelectValue />
2082
+ </SelectTrigger>
2083
+ <SelectContent>
2084
+ <SelectItem value="1">Linear</SelectItem>
2085
+ <SelectItem value="2">Multiply</SelectItem>
2086
+ <SelectItem value="3">Add</SelectItem>
2087
+ <SelectItem value="4">Lighter</SelectItem>
2088
+ <SelectItem value="5">Darker</SelectItem>
2089
+ </SelectContent>
2090
+ </Select>
2091
+ </div>
2208
2092
 
2209
- {/* Save Preset */}
2210
- <div>
2211
- <input
2212
- type="text"
2213
- placeholder="Preset name..."
2214
- value={presetName}
2215
- onChange={(e) => setPresetName(e.target.value)}
2216
- className="mb-2 w-full rounded-md border border-input p-2 text-card-foreground focus:ring-2 focus:ring-ring"
2217
- />
2218
- <button
2219
- onClick={savePreset}
2220
- disabled={!presetName.trim()}
2221
- className="w-full rounded-md bg-accent px-4 py-2 font-bold text-accent-foreground shadow-sm active:translate-y-px active:shadow-sm disabled:opacity-50"
2222
- >
2223
- 💾 Save Preset
2224
- </button>
2225
- </div>
2093
+ <Label className="flex items-center gap-2">
2094
+ <input type="checkbox" checked={parameters.greyscale} onChange={(e) => setParameters((prev) => ({ ...prev, greyscale: e.target.checked }))} />
2095
+ Greyscale
2096
+ </Label>
2097
+ <Label className="flex items-center gap-2">
2098
+ <input type="checkbox" checked={parameters.disable} onChange={(e) => setParameters((prev) => ({ ...prev, disable: e.target.checked }))} />
2099
+ Disable Effect
2100
+ </Label>
2101
+
2102
+ <div className="space-y-2">
2103
+ <Label htmlFor="preset-name">Preset name</Label>
2104
+ <Input id="preset-name" placeholder="Preset name…" value={presetName} onChange={(e) => setPresetName(e.target.value)} className="w-full" />
2105
+ <Button variant="secondary" className="w-full" onClick={savePreset} disabled={!presetName.trim()}>
2106
+ 💾 Save Preset
2107
+ </Button>
2108
+ </div>
2226
2109
 
2227
- {/* Saved Presets */}
2228
- {presets.length > 0 && (
2229
- <div>
2230
- <h4 className="mb-2 text-sm font-bold text-card-foreground">💾 Saved Presets</h4>
2231
- <div className="max-h-32 space-y-2 overflow-y-auto">
2110
+ {/* A row that selects something is a `Button`, and which one is
2111
+ chosen is a `variant` — never a colour `className`. */}
2112
+ {presets.length > 0 && (
2113
+ <div className="space-y-2">
2114
+ <h4 className="font-bold">💾 Saved Presets</h4>
2232
2115
  {presets
2233
2116
  .sort((a, b) => b.timestamp - a.timestamp)
2234
2117
  .map((preset) => (
2235
- <div
2118
+ <Button
2236
2119
  key={preset._id}
2237
- className={`cursor-pointer rounded-md p-3 transition-colors ${
2238
- currentPreset?._id === preset._id
2239
- ? "bg-primary text-primary-foreground shadow-sm"
2240
- : "bg-card text-card-foreground shadow-sm"
2241
- }`}
2120
+ variant={currentPreset?._id === preset._id ? "default" : "secondary"}
2121
+ className="w-full justify-start"
2242
2122
  onClick={() => loadPreset(preset)}
2243
2123
  >
2244
- <div className="text-xs font-bold text-card-foreground">{preset.name}</div>
2245
- <div className="text-xs text-card-foreground opacity-75">
2246
- {["", "Dot", "Ellipse", "Line", "Square"][preset.parameters.shape]} •{" "}
2247
- {preset.parameters.greyscale ? "B&W" : "Color"}
2248
- </div>
2249
- </div>
2124
+ {preset.name} · {["", "Dot", "Ellipse", "Line", "Square"][preset.parameters.shape]}
2125
+ </Button>
2250
2126
  ))}
2251
2127
  </div>
2252
- </div>
2253
- )}
2128
+ )}
2254
2129
 
2255
- {/* Parameter History */}
2256
- {parameterHistory.length > 0 && (
2257
- <div>
2258
- <h4 className="mb-2 text-sm font-bold text-card-foreground">📜 Parameter History</h4>
2259
- <div className="max-h-40 space-y-2 overflow-y-auto">
2130
+ {parameterHistory.length > 0 && (
2131
+ <div className="space-y-2">
2132
+ <h4 className="font-bold">📜 Parameter History</h4>
2260
2133
  {parameterHistory
2261
2134
  .sort((a, b) => b.timestamp - a.timestamp)
2262
2135
  .slice(0, 10)
2263
2136
  .map((state) => (
2264
- <div
2265
- key={state._id}
2266
- className="cursor-pointer rounded-md bg-card text-card-foreground p-3 shadow-sm transition-shadow hover:shadow-md"
2267
- onClick={() => loadParameterState(state)}
2268
- >
2269
- <div className="text-xs font-bold text-card-foreground">{actionNames[state.action] || "⚙️ Unknown"}</div>
2270
- <div className="text-xs text-card-foreground opacity-75">
2271
- {["", "Dot", "Ellipse", "Line", "Square"][state.parameters.shape]} • Size:{" "}
2272
- {state.parameters.radius.toFixed(1)} • {state.parameters.greyscale ? "B&W" : "Color"}
2273
- </div>
2274
- <div className="text-xs text-card-foreground opacity-50">{new Date(state.timestamp).toLocaleTimeString()}</div>
2275
- </div>
2137
+ <Button key={state._id} variant="outline" className="w-full justify-start" onClick={() => loadParameterState(state)}>
2138
+ {actionNames[state.action] || "⚙️ Unknown"} · {new Date(state.timestamp).toLocaleTimeString()}
2139
+ </Button>
2276
2140
  ))}
2277
2141
  </div>
2278
- </div>
2279
- )}
2280
- </div>
2281
- )}
2282
- </div>
2142
+ )}
2143
+ </div>
2144
+ )}
2145
+ </CardContent>
2146
+ </Card>
2283
2147
  </div>
2284
2148
  );
2285
2149
  }
@@ -28,6 +28,7 @@ Gate every write affordance on `can.*`. Hold it while `pending`, and write your
28
28
 
29
29
  ```jsx
30
30
  import { useVibe } from "use-vibes";
31
+ import { Button, Input, Skeleton } from "@vibes.diy/look";
31
32
 
32
33
  function PromptBar({ database, boardId }) {
33
34
  const { can, me } = useVibe("aestheticBoard");
@@ -35,15 +36,15 @@ function PromptBar({ database, boardId }) {
35
36
  // to, and who is writing it.
36
37
  const v = can.create({ type: "tile", boardId, authorHandle: me?.userHandle });
37
38
  // 1. still resolving — a quiet placeholder, no refusal wording, no empty hole
38
- if (v.pending) return <div className="skeleton" aria-busy="true">Checking…</div>;
39
+ if (v.pending) return <Skeleton className="h-10 w-full" aria-busy="true" />;
39
40
  // 2. resolved denial — your words, informed by v.reason, never v.reason itself
40
- if (!v.ok) return <p className="muted">Sign in to add a tile.</p>;
41
+ if (!v.ok) return <p className="text-muted-foreground">Sign in to add a tile.</p>;
41
42
  // 3. allowed
42
43
  return (
43
44
  <form onSubmit={/* … */}>
44
45
  {/* no current-user pill — identity + sign-in live in the Vibes Switch (the logo) */}
45
- <input placeholder="Add a tile…" />
46
- <button type="submit">Post</button>
46
+ <Input placeholder="Add a tile…" />
47
+ <Button type="submit">Post</Button>
47
48
  </form>
48
49
  );
49
50
  }
package/llms/use-vibe.md CHANGED
@@ -28,14 +28,15 @@ Gate every write affordance on `can.*`. Hold it while `pending`, and write your
28
28
 
29
29
  ```jsx file=App.jsx
30
30
  import { useVibe } from "use-vibes";
31
+ import { Button, Input, Skeleton } from "@vibes.diy/look";
31
32
 
32
33
  function PromptBar({ database }) {
33
34
  const { can, me } = useVibe("aestheticBoard");
34
35
  const v = can.create({ type: "tile", authorHandle: me?.userHandle });
35
36
  // 1. still resolving — a quiet placeholder, no refusal wording, no empty hole
36
- if (v.pending) return <div className="skeleton" aria-busy="true">Checking…</div>;
37
+ if (v.pending) return <Skeleton className="h-10 w-full" aria-busy="true" />;
37
38
  // 2. resolved denial — your words, informed by v.reason, never v.reason itself
38
- if (!v.ok) return <p className="muted">Join the board to add a tile.</p>;
39
+ if (!v.ok) return <p className="text-muted-foreground">Join the board to add a tile.</p>;
39
40
  // 3. allowed
40
41
  return (
41
42
  <form
@@ -45,8 +46,8 @@ function PromptBar({ database }) {
45
46
  }}
46
47
  >
47
48
  {/* no current-user pill — identity + sign-in live in the Vibes Switch (the logo) */}
48
- <input name="tile" placeholder="Add a tile…" />
49
- <button type="submit">Post</button>
49
+ <Input name="tile" placeholder="Add a tile…" />
50
+ <Button type="submit">Post</Button>
50
51
  </form>
51
52
  );
52
53
  }
package/llms/voxel.md CHANGED
@@ -269,11 +269,16 @@ and only request lock from that click:
269
269
  {worldReady && !isTouch && !locked && (
270
270
  <button onClick={() => engineRef.current?.requestLock()}
271
271
  className="absolute inset-0 z-20 flex flex-col items-center justify-center bg-black/55 backdrop-blur-sm">
272
- <div className="panel">
273
- <h2>Voxel World</h2><p>Click to play</p>
274
- {/* WASD move · Mouse look · Shift sprint · Space jump · Left-click break · Right-click place · F fly · 1–9 blocks */}
275
- </div>
276
- <p className="text-xs opacity-60">Press Esc to release the mouse</p>
272
+ <Card className="max-w-sm">
273
+ <CardHeader>
274
+ <CardTitle>Voxel World</CardTitle>
275
+ </CardHeader>
276
+ <CardContent>
277
+ <p>Click to play</p>
278
+ {/* WASD move · Mouse look · Shift sprint · Space jump · Left-click break · Right-click place · F fly · 1–9 blocks */}
279
+ </CardContent>
280
+ </Card>
281
+ <p className="mt-4 text-muted-foreground">Press Esc to release the mouse</p>
277
282
  </button>
278
283
  )}
279
284
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibes.diy/prompts",
3
- "version": "14.1.50",
3
+ "version": "14.1.52",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "exports": {
@@ -13,7 +13,8 @@
13
13
  "./themes/looks/index.js": "./themes/looks/index.js",
14
14
  "./themes/ornament-pad.js": "./themes/ornament-pad.js",
15
15
  "./themes/palette-gen.js": "./themes/palette-gen.js",
16
- "./themes/style-presets.js": "./themes/style-presets.js"
16
+ "./themes/style-presets.js": "./themes/style-presets.js",
17
+ "./themes/theme-slugs.js": "./themes/theme-slugs.js"
17
18
  },
18
19
  "description": "",
19
20
  "scripts": {
@@ -36,9 +37,9 @@
36
37
  "license": "Apache-2.0",
37
38
  "dependencies": {
38
39
  "@adviser/cement": "~0.5.34",
39
- "@vibes.diy/call-ai-v2": "14.1.50",
40
- "@vibes.diy/identity": "14.1.50",
41
- "@vibes.diy/use-vibes-types": "14.1.50",
40
+ "@vibes.diy/call-ai-v2": "14.1.52",
41
+ "@vibes.diy/identity": "14.1.52",
42
+ "@vibes.diy/use-vibes-types": "14.1.52",
42
43
  "arktype": "~2.2.3",
43
44
  "json-schema-faker": "~0.6.3"
44
45
  },
package/prompts.d.ts CHANGED
@@ -129,9 +129,7 @@ export interface MakeBaseSystemPromptOptions {
129
129
  pkgBaseUrl?: string;
130
130
  variant?: "initial" | "initial-oneshot" | "continuation";
131
131
  suppressDefaultStylePrompt?: boolean;
132
- look?: {
133
- components: boolean;
134
- };
132
+ look?: boolean;
135
133
  }
136
134
  export declare function makeBaseSystemPrompt(model: string, sessionDoc: Partial<UserSettings> & MakeBaseSystemPromptOptions): Promise<SystemPromptResult>;
137
135
  export declare function getRecoveryAddendum(pkgBaseUrl?: string, fetchFn?: typeof fetch): Promise<string>;