claude-artifact-framework 0.3.0 → 0.5.0
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/README.md +134 -3
- package/dist/index.esm.js +666 -14
- package/dist/index.esm.js.map +3 -3
- package/dist/index.global.js +77 -9
- package/dist/index.global.js.map +4 -4
- package/package.json +1 -1
- package/src/app.js +143 -5
- package/src/appState.js +34 -3
- package/src/blocks.js +177 -3
- package/src/chat.js +248 -0
- package/src/records.js +64 -5
- package/src/steps.js +106 -0
- package/src/theme.js +9 -0
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ mirrors npm packages automatically.
|
|
|
12
12
|
### As a global script (`<script>` tag)
|
|
13
13
|
|
|
14
14
|
```html
|
|
15
|
-
<script src="https://cdn.jsdelivr.net/npm/claude-artifact-framework@0.
|
|
15
|
+
<script src="https://cdn.jsdelivr.net/npm/claude-artifact-framework@0.5.0/dist/index.global.js"></script>
|
|
16
16
|
<script>
|
|
17
17
|
const { storage, createStore, createPersistedStore, createSharedStore } = ArtifactKit;
|
|
18
18
|
</script>
|
|
@@ -27,11 +27,11 @@ mirrors npm packages automatically.
|
|
|
27
27
|
createStore,
|
|
28
28
|
createPersistedStore,
|
|
29
29
|
createSharedStore,
|
|
30
|
-
} from "https://cdn.jsdelivr.net/npm/claude-artifact-framework@0.
|
|
30
|
+
} from "https://cdn.jsdelivr.net/npm/claude-artifact-framework@0.5.0/dist/index.esm.js";
|
|
31
31
|
</script>
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
Pin a version (`@0.
|
|
34
|
+
Pin a version (`@0.5.0`) for reproducible artifacts, or drop the version
|
|
35
35
|
(`claude-artifact-framework/dist/...`) to always get the latest release.
|
|
36
36
|
|
|
37
37
|
### Inside a React artifact
|
|
@@ -123,6 +123,137 @@ persistence path as everything else. `id` is assigned by the framework and
|
|
|
123
123
|
reserved. Optional: `title(r)` / `subtitle(r)` for rows, `sort(a, b)`,
|
|
124
124
|
`summary(records)` for stats above the list, `empty` for the empty-state text.
|
|
125
125
|
|
|
126
|
+
### The `steps` layout — wizards, quizzes, staged calculators
|
|
127
|
+
|
|
128
|
+
Declare the sequence; next/back/progress/result are framework-owned. Step
|
|
129
|
+
fields write into the same flat `data` pool, so the result step is just a
|
|
130
|
+
function of data. Next is gated on the current step's validation; the current
|
|
131
|
+
step survives a reload.
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
ArtifactKit.createApp({
|
|
135
|
+
title: "Quiz de riesgo",
|
|
136
|
+
layout: "steps",
|
|
137
|
+
steps: [
|
|
138
|
+
{ title: "Tu edad", fields: [{ key: "edad", type: "number", required: true, min: 18 }] },
|
|
139
|
+
{ title: "Tu perfil", fields: [{ key: "perfil", type: "select", required: true, options: ["conservador", "moderado", "agresivo"] }] },
|
|
140
|
+
{ title: "Resultado", result: (d) => [{ label: "Puntaje", value: score(d), big: true }] },
|
|
141
|
+
],
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Field keys must be unique across all steps (they share one data pool); a
|
|
146
|
+
duplicate throws at creation, as does an unknown step key.
|
|
147
|
+
|
|
148
|
+
### The `chart` block — bar, line, donut
|
|
149
|
+
|
|
150
|
+
Same vocabulary as `output` (items of `{ label, value }` plus an optional
|
|
151
|
+
`format`), so declaring one teaches nothing new. Colors derive from the theme
|
|
152
|
+
seed by golden-angle rotation — a chart can't clash with the app it lives in.
|
|
153
|
+
|
|
154
|
+
```js
|
|
155
|
+
blocks: [
|
|
156
|
+
{ chart: (d) => ({ type: "bar", format: "money", items: monthlyTotals(d) }), title: "Ventas", wide: true },
|
|
157
|
+
{ chart: { type: "donut", items: [{ label: "Comida", value: 45 }, { label: "Otros", value: 55 }] } },
|
|
158
|
+
]
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### The `timer` block — countdowns that persist their effects
|
|
162
|
+
|
|
163
|
+
The interval is framework-owned and cleaned up on unmount (a leaked
|
|
164
|
+
`setInterval` is a classic half-built artifact bug). The countdown itself is
|
|
165
|
+
deliberately ephemeral; what you declare is what happens when it finishes —
|
|
166
|
+
`onDone` runs through `update()`, so its effects persist like any other change.
|
|
167
|
+
|
|
168
|
+
```js
|
|
169
|
+
blocks: [
|
|
170
|
+
{ timer: { minutes: 25, label: "Focus", onDone: (d) => { d.completados = (d.completados || 0) + 1; } } },
|
|
171
|
+
{ output: (d) => [{ label: "Pomodoros", value: d.completados || 0, big: true }] },
|
|
172
|
+
]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
`text` blocks also accept a function of data — `{ text: (d) => "Hola " + d.nombre }` —
|
|
176
|
+
with the same contract as `output`.
|
|
177
|
+
|
|
178
|
+
### The `chat` layout — apps that talk to Claude
|
|
179
|
+
|
|
180
|
+
Tutors, advisors, generators, roleplay. Every piece of the network contract is
|
|
181
|
+
copied from code proven inside the real artifact runtime: the artifact fetches
|
|
182
|
+
`https://api.anthropic.com/v1/messages` directly with **no API key** (the
|
|
183
|
+
runtime proxies the call and injects auth), `stream: true` works, and tools
|
|
184
|
+
are prompted (the proxy does not support native function calling).
|
|
185
|
+
|
|
186
|
+
The author declares the system prompt and, optionally, tools that operate on
|
|
187
|
+
the app's data — a chat that can drive the app. The framework owns message
|
|
188
|
+
state, live streaming, the busy state, the tool loop, and errors as visible
|
|
189
|
+
bubbles. The conversation persists and survives reload.
|
|
190
|
+
|
|
191
|
+
```js
|
|
192
|
+
ArtifactKit.createApp({
|
|
193
|
+
title: "Asistente de gastos",
|
|
194
|
+
theme: { seed: "#0f766e" },
|
|
195
|
+
layout: "chat",
|
|
196
|
+
chat: {
|
|
197
|
+
system: (d) => "Eres un asistente de gastos. Total actual: " + (d.total || 0),
|
|
198
|
+
greeting: "¡Hola! Contame tus gastos.",
|
|
199
|
+
tools: {
|
|
200
|
+
agregar_gasto: {
|
|
201
|
+
description: "Agrega un gasto",
|
|
202
|
+
input: { concepto: "string", monto: "number" },
|
|
203
|
+
run: (input, ctx) => {
|
|
204
|
+
ctx.update((d) => { d.total = (d.total || 0) + Number(input.monto); });
|
|
205
|
+
return { ok: true };
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
`system` is a string or a function of data. Tool `run(input, ctx)` returns a
|
|
214
|
+
JSON-serializable result that is fed back to the model; an unknown tool name
|
|
215
|
+
is answered in-band so the model corrects itself. Optional: `greeting`,
|
|
216
|
+
`placeholder`, `model` (default `claude-sonnet-4-6`, proven through the
|
|
217
|
+
proxy), `maxTokens`.
|
|
218
|
+
|
|
219
|
+
### Search, computed fields, and shared data
|
|
220
|
+
|
|
221
|
+
Three record-app multipliers, all declarative:
|
|
222
|
+
|
|
223
|
+
```js
|
|
224
|
+
ArtifactKit.createApp({
|
|
225
|
+
title: "Inventario del club",
|
|
226
|
+
layout: "records",
|
|
227
|
+
shared: true, // one copy of the data for every viewer
|
|
228
|
+
records: {
|
|
229
|
+
search: true, // search box over all field values
|
|
230
|
+
fields: [
|
|
231
|
+
{ key: "nombre", type: "text", required: true },
|
|
232
|
+
{ key: "cantidad", type: "number", value: 1, min: 0 },
|
|
233
|
+
{ key: "precio", type: "money", value: 0, min: 0 },
|
|
234
|
+
],
|
|
235
|
+
compute: { // derived per record, never stored
|
|
236
|
+
subtotal: { label: "Subtotal", format: "money", value: (r) => r.cantidad * r.precio },
|
|
237
|
+
},
|
|
238
|
+
summary: (all) => [
|
|
239
|
+
{ label: "Valor total", value: all.reduce((s, r) => s + r.subtotal, 0), format: "money", big: true },
|
|
240
|
+
],
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
- `search: true` adds a filter box over every field's value; the count shows
|
|
246
|
+
"n of total" while filtering.
|
|
247
|
+
- `compute` entries are functions of the record (or `{ label, format, value }`).
|
|
248
|
+
Computed values appear read-only in the detail screen and are available to
|
|
249
|
+
`title` / `subtitle` / `sort` / `summary` as if they were fields. A compute
|
|
250
|
+
key that collides with a field key throws.
|
|
251
|
+
- `shared: true` (top level) stores the app's data in the shared scope: every
|
|
252
|
+
viewer of the published artifact converges on the same data via polling.
|
|
253
|
+
Conflict handling is last-write-wins; a poll never overwrites local edits
|
|
254
|
+
that haven't been persisted yet. View state (which screen is open) stays
|
|
255
|
+
personal per viewer.
|
|
256
|
+
|
|
126
257
|
## `storage`
|
|
127
258
|
|
|
128
259
|
Thin wrapper over `window.storage`, the persistence API Claude injects into a
|