claude-artifact-framework 0.4.0 → 0.5.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/README.md +119 -3
- package/dist/index.esm.js +412 -35
- package/dist/index.esm.js.map +3 -3
- package/dist/index.global.js +47 -9
- package/dist/index.global.js.map +4 -4
- package/package.json +1 -1
- package/src/app.js +150 -31
- package/src/appState.js +34 -3
- package/src/chat.js +248 -0
- package/src/records.js +64 -5
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.1/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.1/dist/index.esm.js";
|
|
31
31
|
</script>
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
Pin a version (`@0.
|
|
34
|
+
Pin a version (`@0.5.1`) 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
|
|
@@ -175,6 +175,122 @@ blocks: [
|
|
|
175
175
|
`text` blocks also accept a function of data — `{ text: (d) => "Hola " + d.nombre }` —
|
|
176
176
|
with the same contract as `output`.
|
|
177
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
|
+
|
|
257
|
+
## API reference
|
|
258
|
+
|
|
259
|
+
Everything an app can declare, in one place.
|
|
260
|
+
|
|
261
|
+
**Top-level keys**: `title`, `subtitle`, `theme: { seed }`, `layout`, `blocks`,
|
|
262
|
+
`records`, `steps`, `chat`, `data`, `shared`. Anything else throws.
|
|
263
|
+
|
|
264
|
+
**Layouts** (`layout:`): `panel` (default — grid of blocks), `records` (CRUD
|
|
265
|
+
list), `steps` (wizard), `chat` (conversation with Claude). Each requires its
|
|
266
|
+
matching key (`blocks` / `records` / `steps` / `chat`).
|
|
267
|
+
|
|
268
|
+
**Block types** (entries of `blocks`): `fields`, `output`, `text`, `list`,
|
|
269
|
+
`chart`, `timer`, `custom`. One type per entry, plus optional `title`, `empty`,
|
|
270
|
+
`wide`. In the `records` layout, `blocks` render below the list (never on the
|
|
271
|
+
detail screen); their functions receive the same `data` object as everywhere
|
|
272
|
+
else — the collection lives at `d.records`.
|
|
273
|
+
|
|
274
|
+
**Field types** (`type:` on any field): `text` (default), `textarea`,
|
|
275
|
+
`number`, `money`, `percent`, `check` (checkbox), `date`, `select` (needs
|
|
276
|
+
`options`). Other field keys: `key` (required), `label`, `value` (initial),
|
|
277
|
+
`required`, `min`, `max`, `step`, `placeholder`, `hint`, `rows`, `options`.
|
|
278
|
+
An unknown `type` throws naming the valid ones.
|
|
279
|
+
|
|
280
|
+
**`records` keys**: `label`, `fields`, `title(r)`, `subtitle(r)`, `sort(a,b)`,
|
|
281
|
+
`summary(all)`, `empty`, `search`, `compute`. `id` is framework-assigned and
|
|
282
|
+
reserved.
|
|
283
|
+
|
|
284
|
+
**`steps` keys** (per step): `title`, `text`, `fields`, `result(d)`. Field
|
|
285
|
+
keys must be unique across steps.
|
|
286
|
+
|
|
287
|
+
**`chat` keys**: `system` (string or `(d) => string`), `greeting`,
|
|
288
|
+
`placeholder`, `tools`, `model`, `maxTokens`. Each tool:
|
|
289
|
+
`{ description, input, run(input, ctx) }`.
|
|
290
|
+
|
|
291
|
+
**Formats** (`format:` on output/chart/compute items): `money`, `percent`,
|
|
292
|
+
`number`, `date`.
|
|
293
|
+
|
|
178
294
|
## `storage`
|
|
179
295
|
|
|
180
296
|
Thin wrapper over `window.storage`, the persistence API Claude injects into a
|