claude-artifact-framework 0.14.0 → 0.14.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.
Files changed (3) hide show
  1. package/README.md +32 -0
  2. package/llms.txt +90 -0
  3. package/package.json +9 -4
package/README.md CHANGED
@@ -890,3 +890,35 @@ board.stop(); // stop polling, e.g. on teardown
890
890
  Conflict handling is last-write-wins: if two viewers change the same key
891
891
  within one poll window, whichever write reaches storage last overwrites the
892
892
  other. There is no merge/CRDT logic.
893
+
894
+ ## Hard rules — the short list
895
+
896
+ The rules that decide whether a generated app works, all in one place
897
+ (each is explained in its section above):
898
+
899
+ 1. **Indented, never minified** — the only measured syntax errors came from
900
+ single-line output.
901
+ 2. **Theme variables, never hardcoded hex** — `var(--caf-text)`,
902
+ `var(--caf-surface)`, `var(--caf-accent)`, `var(--caf-border)`,
903
+ `var(--caf-sunken)`, `var(--caf-muted)`, `var(--caf-danger)`, and
904
+ `ctx.colors(n)` for series. A custom block painted with `#fff` or
905
+ `#ef4444` breaks in dark mode.
906
+ 3. **Never render a `<form>`** — the published sandbox lacks `allow-forms`;
907
+ use inputs plus a button with `onClick`.
908
+ 4. **Never write big strings into `data`** (data URLs, file contents) —
909
+ the whole pool shares one ~5MB key; big things live in `React.useState`
910
+ or `ctx.files`.
911
+ 5. **Phases belong to the `machine`** — never track game/process phases
912
+ with hand-rolled flags and `setTimeout`; `ctx.send` is the only door.
913
+ 6. **Never skip a middle positional argument** — `run: (r, d, viewerId)`,
914
+ never `run: (r, viewerId)`.
915
+ 7. **One `big: true` per screen** — it marks THE result, not every stat.
916
+ 8. **The constructive action takes `kind: "primary"`**; a counter changed
917
+ by pressing is an `action`, not an editable `number` field.
918
+ 9. **Parts of a record are `items`** — never JSON in a `textarea`.
919
+ 10. **Don't hand-build empty/loading/error states** — the framework owns
920
+ them.
921
+ 11. **CDN libs: call the method, not the global** (`marked.parse`, not
922
+ `marked(...)`); pin versions; when unsure of the file path use the bare
923
+ package URL.
924
+ 12. **Framework ids are strings** — never `Number(record.id)`.
package/llms.txt ADDED
@@ -0,0 +1,90 @@
1
+ # claude-artifact-framework
2
+
3
+ > Declarative framework for building apps inside Claude Artifacts. Declare what
4
+ > the app IS (fields, records, steps, chat with tools, workspace, documents);
5
+ > the framework owns persistence, hydration, validation, empty/loading/error
6
+ > states, light+dark theming, navigation, and the Claude tool loop.
7
+ > Full documentation: README.md (this file is the compact digest).
8
+
9
+ Load (classic script, global `ArtifactKit`; call `ArtifactKit.useReact(React)` once):
10
+ https://cdn.jsdelivr.net/npm/claude-artifact-framework/dist/index.global.js
11
+
12
+ ## Registries (any other name throws, naming the valid set)
13
+
14
+ - Top-level keys: title, subtitle, theme:{seed}, layout, blocks, records,
15
+ steps, chat, main, sidebar, documents, data, shared, libs, machine
16
+ - Layouts: panel (default), records, steps, chat, workspace, documents
17
+ - Block types: fields, output, text, list, chart, timer, actions, chat, tabs,
18
+ records, custom — plus per-block title, when:(d)=>bool, state:"fase",
19
+ collapsible, wide, fill (custom only)
20
+ - Field types: text, textarea, number, money, percent, check, date, select,
21
+ file — attrs: key, label, value, required, min, max, step, placeholder,
22
+ hint, rows, options (array or (d)=>array), accept
23
+ - records spec: label, fields, title, subtitle, sort, summary, empty, search,
24
+ compute, items, actions (+ key when used as a block)
25
+ - documents: label, title, blocks OR types, empty; machine: key, initial,
26
+ states, events (event: from, do, then); chat: system, greeting, placeholder,
27
+ tools, model, maxTokens; steps step: title, text, fields, result
28
+ - Formats: money, percent (0-100), number, date. Output/chart/compute items:
29
+ { label, value, format, big }
30
+
31
+ ## Hard rules
32
+
33
+ 1. Write the spec INDENTED, never minified (measured: minified output drops
34
+ closing braces).
35
+ 2. Theme variables, never hardcoded hex: var(--caf-text), var(--caf-surface),
36
+ var(--caf-accent), var(--caf-border), var(--caf-sunken), var(--caf-muted),
37
+ var(--caf-danger); ctx.colors(n) for series. Hardcoded #fff breaks dark mode.
38
+ 3. Never render a <form> (sandbox lacks allow-forms) — inputs + button onClick.
39
+ 4. Never write big strings (data URLs, file contents) into data — one ~5MB
40
+ storage key holds the whole pool; big things live in React.useState or
41
+ ctx.files.
42
+ 5. Phases (games, turns, processes) belong to `machine` — ctx.send(event,
43
+ payload) is the only door; events are no-ops outside their `from` states;
44
+ `after: {seconds, then, do}` timers are framework-owned.
45
+ 6. Row actions receive (record, data, viewerId); block actions (data,
46
+ viewerId). Stop early if you like, but never skip a middle argument.
47
+ 7. One big:true per screen; the constructive action takes kind:"primary"; a
48
+ counter changed by pressing is an action, not an editable number field.
49
+ 8. Parts of a record are `items` — never JSON in a textarea.
50
+ 9. Don't hand-build empty/loading/error states — the framework owns them.
51
+ 10. CDN libs via libs:[urls]: call the method, not the global (marked.parse);
52
+ pin versions; unsure of the file path → bare package URL
53
+ (https://cdn.jsdelivr.net/npm/<pkg>@<version>).
54
+ 11. Framework record ids are strings — never Number(record.id).
55
+ 12. In custom blocks: return strings/React elements (never DOM elements — use
56
+ ref + React.useEffect for libs that write into an element); hooks are
57
+ allowed; persistent state via ctx.update, ephemeral via React.useState,
58
+ never createStore for UI state.
59
+
60
+ ## Canonical example
61
+
62
+ ArtifactKit.createApp({
63
+ title: "Gastos",
64
+ theme: { seed: "#c2410c" },
65
+ layout: "records",
66
+ shared: false,
67
+ records: {
68
+ label: "gasto",
69
+ fields: [
70
+ { key: "concepto", label: "Concepto", type: "text", required: true },
71
+ { key: "monto", label: "Monto", type: "money", value: 0, min: 0 },
72
+ { key: "categoria", label: "Categoría", type: "select", options: ["comida", "transporte", "otros"] },
73
+ ],
74
+ subtitle: (r) => r.categoria,
75
+ summary: (all) => [
76
+ { label: "Total", value: all.reduce((s, r) => s + (Number(r.monto) || 0), 0), format: "money", big: true },
77
+ ],
78
+ actions: [{ label: "Duplicar", run: (r, d) => { d.records = [...d.records, { ...r, id: undefined }]; } }],
79
+ },
80
+ blocks: [
81
+ { chart: (d) => ({ type: "donut", format: "money", items: porCategoria(d.records) }), title: "Por categoría" },
82
+ ],
83
+ })
84
+
85
+ Chat with tools (workspace copilot): sidebar block
86
+ { title: "Asistente", chat: { system: (d) => "...", tools: { nombre: {
87
+ description: "...", input: { campo: "string" }, run: (input, ctx) => {
88
+ ctx.update((d) => { /* mutate */ }); return { ok: true }; } } } } }
89
+ — the artifact runtime proxies api.anthropic.com with no API key; default
90
+ model claude-sonnet-4-6; conversation persists under data.chat.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-artifact-framework",
3
- "version": "0.14.0",
3
+ "version": "0.14.1",
4
4
  "description": "Utilities for building apps inside Claude Artifacts: platform storage, chat tool-calling loops, and other primitives verified against the real runtime.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.esm.js",
@@ -12,16 +12,21 @@
12
12
  },
13
13
  "files": [
14
14
  "dist",
15
- "src"
15
+ "src",
16
+ "llms.txt"
16
17
  ],
17
18
  "scripts": {
18
19
  "build": "node scripts/build.mjs",
19
20
  "build:watch": "node scripts/build.mjs --watch",
21
+ "test": "npm run build && node test/e2e.mjs",
20
22
  "prepublishOnly": "npm run build",
21
- "release": "node scripts/check-docs.mjs && bash scripts/publish.sh"
23
+ "release": "node scripts/check-docs.mjs && npm test && bash scripts/publish.sh"
22
24
  },
23
25
  "devDependencies": {
24
- "esbuild": "^0.25.0"
26
+ "esbuild": "^0.25.0",
27
+ "playwright-core": "^1.45.0",
28
+ "react": "^18.3.0",
29
+ "react-dom": "^18.3.0"
25
30
  },
26
31
  "license": "MIT",
27
32
  "author": "Alejandro Cuartas",