claude-artifact-framework 0.4.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.
@@ -1,17 +1,35 @@
1
- var ArtifactKit=(()=>{var z=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var le=Object.getOwnPropertyNames;var fe=Object.prototype.hasOwnProperty;var ue=(e,t)=>{for(var a in t)z(e,a,{get:t[a],enumerable:!0})},de=(e,t,a,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of le(t))!fe.call(e,o)&&o!==a&&z(e,o,{get:()=>t[o],enumerable:!(r=ie(t,o))||r.enumerable});return e};var me=e=>de(z({},"__esModule",{value:!0}),e);var Pe={};ue(Pe,{contrast:()=>O,createApp:()=>se,createPersistedStore:()=>K,createSharedStore:()=>Y,createStore:()=>P,hasReact:()=>C,palette:()=>B,storage:()=>p,themeCss:()=>j,useReact:()=>q});function x(){return typeof window<"u"&&typeof window.storage=="object"&&window.storage!==null}function H(e){return{async get(t,a=void 0){if(!x())return a;try{let r=await window.storage.get(t,e);if(r?.value===void 0||r?.value===null)return a;try{return JSON.parse(r.value)}catch{return r.value}}catch{return a}},async set(t,a,{raw:r=!1}={}){if(!x())throw new Error("window.storage is not available (is this a Code Artifact rather than a published Chat Artifact?)");let o=r?a:JSON.stringify(a);if(typeof o!="string")throw new Error("window.storage only accepts strings \u2014 the value must be JSON-serializable");return window.storage.set(t,o,e)},async delete(t){if(x())try{await window.storage.delete(t,e)}catch{}},async list(t){if(!x())return[];try{return(await window.storage.list(t,e))?.keys||[]}catch{return[]}}}}var p={...H(!1),shared:H(!0),available:x};function D(e){let t=e,a=new Set;function r(){return t}function o(c){t=typeof c=="function"?c(t):c,a.forEach(i=>i(t))}function s(c){return a.add(c),()=>a.delete(c)}return{get:r,set:o,subscribe:s}}function I(e,t){let a;return(...r)=>{clearTimeout(a),a=setTimeout(()=>e(...r),t)}}function P(e){return D(e)}function K(e,t,{debounceMs:a=300}={}){let r=D(t),o=I(c=>p.set(e,c),a),s=p.get(e,t).then(c=>r.set(c));return r.subscribe(o),{...r,ready:s}}function Y(e,t,{pollMs:a=2e3,debounceMs:r=300}={}){let o=D(t),s=I(u=>p.shared.set(e,u),r),c=!1;o.subscribe(u=>{c||s(u)});async function i(){let u=await p.shared.get(e,t);JSON.stringify(u)!==JSON.stringify(o.get())&&(c=!0,o.set(u),c=!1)}let l=i(),f=setInterval(i,a);return{...o,ready:l,stop:()=>clearInterval(f)}}var w=typeof globalThis<"u"?globalThis.React:void 0;function q(e){return w=e,e}function C(){return!!w}function J(){return N()}function N(){if(!w)throw new Error(`claude-artifact-framework: React not found. Hand it over once, before createApp:
1
+ var ArtifactKit=(()=>{var P=Object.defineProperty;var Se=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var $e=Object.prototype.hasOwnProperty;var Ce=(e,a)=>{for(var t in a)P(e,t,{get:a[t],enumerable:!0})},Te=(e,a,t,r)=>{if(a&&typeof a=="object"||typeof a=="function")for(let o of Ee(a))!$e.call(e,o)&&o!==t&&P(e,o,{get:()=>a[o],enumerable:!(r=Se(a,o))||r.enumerable});return e};var je=e=>Te(P({},"__esModule",{value:!0}),e);var dt={};Ce(dt,{contrast:()=>K,createApp:()=>xe,createPersistedStore:()=>ae,createSharedStore:()=>re,createStore:()=>te,hasReact:()=>A,palette:()=>U,storage:()=>y,themeCss:()=>z,useReact:()=>ne});function O(){return typeof window<"u"&&typeof window.storage=="object"&&window.storage!==null}function Z(e){return{async get(a,t=void 0){if(!O())return t;try{let r=await window.storage.get(a,e);if(r?.value===void 0||r?.value===null)return t;try{return JSON.parse(r.value)}catch{return r.value}}catch{return t}},async set(a,t,{raw:r=!1}={}){if(!O())throw new Error("window.storage is not available (is this a Code Artifact rather than a published Chat Artifact?)");let o=r?t:JSON.stringify(t);if(typeof o!="string")throw new Error("window.storage only accepts strings \u2014 the value must be JSON-serializable");return window.storage.set(a,o,e)},async delete(a){if(O())try{await window.storage.delete(a,e)}catch{}},async list(a){if(!O())return[];try{return(await window.storage.list(a,e))?.keys||[]}catch{return[]}}}}var y={...Z(!1),shared:Z(!0),available:O};function I(e){let a=e,t=new Set;function r(){return a}function o(c){a=typeof c=="function"?c(a):c,t.forEach(i=>i(a))}function s(c){return t.add(c),()=>t.delete(c)}return{get:r,set:o,subscribe:s}}function ee(e,a){let t;return(...r)=>{clearTimeout(t),t=setTimeout(()=>e(...r),a)}}function te(e){return I(e)}function ae(e,a,{debounceMs:t=300}={}){let r=I(a),o=ee(c=>y.set(e,c),t),s=y.get(e,a).then(c=>r.set(c));return r.subscribe(o),{...r,ready:s}}function re(e,a,{pollMs:t=2e3,debounceMs:r=300}={}){let o=I(a),s=ee(u=>y.shared.set(e,u),r),c=!1;o.subscribe(u=>{c||s(u)});async function i(){let u=await y.shared.get(e,a);JSON.stringify(u)!==JSON.stringify(o.get())&&(c=!0,o.set(u),c=!1)}let l=i(),f=setInterval(i,t);return{...o,ready:l,stop:()=>clearInterval(f)}}var T=typeof globalThis<"u"?globalThis.React:void 0;function ne(e){return T=e,e}function A(){return!!T}function oe(){return j()}function j(){if(!T)throw new Error(`claude-artifact-framework: React not found. Hand it over once, before createApp:
2
2
 
3
3
  import React from "react";
4
4
  ArtifactKit.useReact(React);
5
- `);return w}var n=(...e)=>N().createElement(...e),S=(...e)=>N().useState(...e),E=(...e)=>N().useEffect(...e);var Ue=w&&w.Component||class{render(){return N()}};var U="caf:data",W="caf:view",G={screen:null,arg:null,stack:[],step:0,selected:null};function R(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function X(e,t){if(!R(e)||!R(t))return t===void 0?e:t;let a={...e};for(let r of Object.keys(t))a[r]=R(e[r])?X(e[r],t[r]):t[r];return a}function Q(e,t){let a;return(...r)=>{clearTimeout(a),a=setTimeout(()=>e(...r),t)}}function Z(e,{debounceMs:t=400}={}){let a=L(e),r={...G},o=!1,s=new Set,c=!1;function i(){c||(c=!0,Promise.resolve().then(()=>{c=!1;for(let d of s)d()}))}let l=Q(()=>p.set(U,a),t),f=Q(()=>p.set(W,r),t),u=(async()=>{let[d,b]=await Promise.all([p.get(U,void 0),p.get(W,void 0)]);d!==void 0&&(a=X(e,d)),b!==void 0&&(r={...G,...b}),o=!0,i()})();function g(d){let b=d(a);b!==void 0&&(a=b),a={...a},l(),i()}function v(d){r={...r,...d},f(),i()}return{ready:u,isHydrated:()=>o,getData:()=>a,getView:()=>r,update:g,setView:v,go(d,b){v({stack:[...r.stack,{screen:r.screen,arg:r.arg}],screen:d,arg:b})},back(){let d=r.stack.slice(),b=d.pop()||{screen:null,arg:null};v({stack:d,screen:b.screen,arg:b.arg})},subscribe(d){return s.add(d),()=>s.delete(d)}}}function L(e){if(Array.isArray(e))return e.map(L);if(R(e)){let t={};for(let a of Object.keys(e))t[a]=L(e[a]);return t}return e}function k(e,t,a){return Math.min(a,Math.max(t,e))}function M(e){let t=String(e).replace("#","").trim();t.length===3&&(t=t.split("").map(r=>r+r).join(""));let a=parseInt(t,16);return Number.isFinite(a)?[a>>16&255,a>>8&255,a&255]:[59,110,246]}function pe(e){return"#"+e.map(t=>k(Math.round(t),0,255).toString(16).padStart(2,"0")).join("")}function te([e,t,a]){e/=255,t/=255,a/=255;let r=Math.max(e,t,a),o=Math.min(e,t,a),s=(r+o)/2,c=r-o,i=0,l=0;return c&&(l=s>.5?c/(2-r-o):c/(r+o),r===e?i=(t-a)/c+(t<a?6:0):r===t?i=(a-e)/c+2:i=(e-t)/c+4,i/=6),[i*360,l*100,s*100]}function be(e,t,a){if(e=(e%360+360)%360/360,t=k(t,0,100)/100,a=k(a,0,100)/100,!t)return[a*255,a*255,a*255];let r=a<.5?a*(1+t):a+t-a*t,o=2*a-r,s=c=>(c<0&&(c+=1),c>1&&(c-=1),c<1/6?o+(r-o)*6*c:c<1/2?r:c<2/3?o+(r-o)*(2/3-c)*6:o);return[s(e+1/3)*255,s(e)*255,s(e-1/3)*255]}function m(e,t,a){return pe(be(e,t,a))}function ee(e){let t=e.map(a=>(a/=255,a<=.03928?a/12.92:Math.pow((a+.055)/1.055,2.4)));return .2126*t[0]+.7152*t[1]+.0722*t[2]}function O(e,t){let a=ee(M(e)),r=ee(M(t));return(Math.max(a,r)+.05)/(Math.min(a,r)+.05)}function h(e,t,a,r,o,s){for(let c=o;c>=4&&c<=96;c+=s){let i=m(e,t,c);if(O(i,a)>=r)return i}return m(e,t,s<0?24:82)}function B(e="#3b6ef6"){let[t,a]=te(M(e)),r=k(a,30,88),o=k(r*.1,3,9),s=m(t,o*.4,100),c=m(t,o*1.4,13);return{light:{bg:m(t,o,96.5),surface:s,sunken:m(t,o,93),border:m(t,o,86),text:m(t,o*1.6,11),muted:m(t,o*1.2,41),accent:h(t,r,"#ffffff",4.5,54,-2),accentText:"#ffffff",danger:h(2,68,"#ffffff",4.5,54,-2),ok:h(148,62,"#ffffff",4.5,44,-2),warn:h(38,88,"#ffffff",4.5,44,-2)},dark:{bg:m(t,o*1.5,9),surface:c,sunken:m(t,o*1.5,7),border:m(t,o*1.3,24),text:m(t,o*.6,95),muted:m(t,o*.8,66),accent:h(t,k(r,40,80),c,4.5,62,2),accentText:m(t,o*2,8),danger:h(2,70,c,4.5,62,2),ok:h(148,55,c,4.5,62,2),warn:h(38,80,c,4.5,62,2)}}}function A(e){return Object.entries(e).map(([t,a])=>`--caf-${t}: ${a};`).join("")}function j(e){let t=B(e);return`
6
- :root { ${A(t.light)} }
7
- @media (prefers-color-scheme: dark) { :root { ${A(t.dark)} } }
8
- :root[data-theme="dark"] { ${A(t.dark)} }
9
- :root[data-theme="light"] { ${A(t.light)} }
10
- `}function ae(e,t){let[a,r]=te(M(e||"#3b6ef6")),o=k(r,45,70);return Array.from({length:t},(s,c)=>m((a+c*137.5)%360,o,52))}function y(e,t){if(e==null||e==="")return"\u2014";let a=Number(e);switch(t){case"money":return Number.isFinite(a)?a.toLocaleString(void 0,{style:"currency",currency:"USD",maximumFractionDigits:2}):String(e);case"percent":return Number.isFinite(a)?`${a.toLocaleString(void 0,{maximumFractionDigits:2})}%`:String(e);case"number":return Number.isFinite(a)?a.toLocaleString(void 0,{maximumFractionDigits:2}):String(e);case"date":return e instanceof Date?e.toLocaleDateString():String(e);default:return String(e)}}function F(e,t){if(e.required&&(t===""||t===null||t===void 0))return"Required";if(t===""||t===null||t===void 0)return null;if(e.type==="number"||e.type==="money"||e.type==="percent"){let a=Number(t);if(!Number.isFinite(a))return"Must be a number";if(e.min!==void 0&&a<e.min)return`Must be at least ${e.min}`;if(e.max!==void 0&&a>e.max)return`Must be at most ${e.max}`}return null}function $({field:e,value:t,onChange:a}){let r=F(e,t),o=`caf-f-${e.key}`,s=e.type==="number"||e.type==="money"||e.type==="percent";if(e.type==="check")return n("label",{className:"caf-check"},n("input",{id:o,type:"checkbox",checked:!!t,onChange:l=>a(l.target.checked)}),n("span",null,e.label||e.key));let c={id:o,value:t??"","aria-invalid":r?"true":void 0,onChange:l=>a(s?ge(l.target.value):l.target.value)},i;return e.type==="textarea"?i=n("textarea",{...c,rows:e.rows||3}):e.type==="select"?i=n("select",c,n("option",{value:""},e.placeholder||"Select\u2026"),(e.options||[]).map(l=>{let f=typeof l=="string"?l:l.value,u=typeof l=="string"?l:l.label;return n("option",{key:f,value:f},u)})):i=n("input",{...c,type:e.type==="date"?"date":s?"number":"text",min:e.min,max:e.max,step:e.step||(e.type==="money"||e.type==="percent"?"any":void 0),placeholder:e.placeholder}),n("div",{className:"caf-field"},n("label",{htmlFor:o},e.label||e.key),i,e.hint&&!r?n("small",{className:"caf-hint"},e.hint):null,r?n("small",{className:"caf-error"},r):null)}function ge(e){if(e==="")return"";let t=Number(e);return Number.isFinite(t)?t:e}function he({spec:e,ctx:t}){let a=e.fields||[];return n("div",{className:"caf-block caf-fields"},e.title?n("h2",{className:"caf-block-title"},e.title):null,a.map(r=>n($,{key:r.key,field:r,value:t.data[r.key],onChange:o=>t.update(s=>{s[r.key]=o})})))}function ye({spec:e,ctx:t}){let a=typeof e.output=="function"?e.output(t.data):e.output||[];return a.length?n("div",{className:"caf-block caf-output"},e.title?n("h2",{className:"caf-block-title"},e.title):null,n("div",{className:"caf-output-grid"},a.map((r,o)=>n("div",{key:r.label||o,className:r.big?"caf-stat caf-stat-big":"caf-stat"},n("span",{className:"caf-stat-label"},r.label),n("span",{className:"caf-stat-value"},y(r.value,r.format)),r.hint?n("small",{className:"caf-hint"},r.hint):null)))):n("div",{className:"caf-block caf-empty"},e.empty||"Nothing to show yet.")}function ke({spec:e,ctx:t}){let a=typeof e.text=="function"?e.text(t.data):e.text;return n("div",{className:"caf-block caf-text"},e.title?n("h2",{className:"caf-block-title"},e.title):null,n("p",null,a))}function we({spec:e,ctx:t}){let a=(typeof e.list=="function"?e.list(t.data):e.list)||[];if(!a.length)return n("div",{className:"caf-block caf-empty"},e.empty||"Nothing here yet.");let r=e.title||(o=>o.title??o.name??o.label??String(o));return n("div",{className:"caf-block caf-list"},a.map((o,s)=>n("button",{key:o.id??s,className:"caf-row",type:"button",onClick:e.onSelect?()=>e.onSelect(o,t):void 0},n("span",{className:"caf-row-title"},r(o)),e.subtitle?n("span",{className:"caf-row-sub"},e.subtitle(o)):null)))}var re=["bar","line","donut"];function ve({spec:e,ctx:t}){let a=typeof e.chart=="function"?e.chart(t.data):e.chart,r=a&&a.items||[];if(!r.length)return n("div",{className:"caf-block caf-empty"},e.empty||"No data to chart yet.");let o=a.type||"bar";if(!re.includes(o))throw new Error(`unknown chart type "${o}". Valid types: ${re.join(", ")}.`);let s=t.colors(r.length),c=o==="bar"?xe(r,a,s):o==="line"?Ne(r,a):Se(r,a,s);return n("div",{className:"caf-block caf-chart"},e.title?n("h2",{className:"caf-block-title"},e.title):null,c)}function xe(e,t,a){let r=Math.max(...e.map(o=>Number(o.value)||0),0)||1;return n("div",{className:"caf-bars"},e.map((o,s)=>n("div",{key:o.label??s,className:"caf-bar-row"},n("span",{className:"caf-bar-label"},o.label),n("div",{className:"caf-bar-track"},n("div",{className:"caf-bar-fill",style:{width:`${Math.max(2,(Number(o.value)||0)/r*100)}%`,background:a[s]}})),n("span",{className:"caf-bar-value"},y(o.value,t.format)))))}function Ne(e,t){let a=e.map(u=>Number(u.value)||0),r=Math.min(...a),s=Math.max(...a)-r||1,c=100,i=36,l=a.map((u,g)=>[a.length===1?c/2:g/(a.length-1)*c,i-3-(u-r)/s*(i-6)]),f=l[l.length-1];return n("div",{className:"caf-line"},n("svg",{viewBox:`0 0 ${c} ${i}`,className:"caf-line-svg",preserveAspectRatio:"none","aria-hidden":"true"},[.25,.5,.75].map(u=>n("line",{key:u,x1:0,x2:c,y1:i*u,y2:i*u,className:"caf-line-grid"})),n("polyline",{points:l.map(u=>u.join(",")).join(" "),className:"caf-line-path"}),n("circle",{cx:f[0],cy:f[1],r:1.6,className:"caf-line-dot"})),n("div",{className:"caf-line-meta"},n("span",{className:"caf-hint"},String(e[0].label??"")),n("span",{className:"caf-line-last"},y(a[a.length-1],t.format)),n("span",{className:"caf-hint"},String(e[e.length-1].label??""))))}function Se(e,t,a){let r=e.reduce((i,l)=>i+(Number(l.value)||0),0)||1,o=15.9155,s=25,c=e.map((i,l)=>{let f=(Number(i.value)||0)/r*100,u=n("circle",{key:i.label??l,cx:21,cy:21,r:o,className:"caf-donut-seg",stroke:a[l],strokeDasharray:`${f} ${100-f}`,strokeDashoffset:s});return s-=f,u});return n("div",{className:"caf-donut"},n("svg",{viewBox:"0 0 42 42",className:"caf-donut-svg","aria-hidden":"true"},c),n("div",{className:"caf-donut-legend"},e.map((i,l)=>n("div",{key:i.label??l,className:"caf-legend-row"},n("span",{className:"caf-legend-swatch",style:{background:a[l]}}),n("span",{className:"caf-legend-label"},i.label),n("span",{className:"caf-legend-value"},y(i.value,t.format))))))}function Ee({spec:e,ctx:t}){let a=e.timer||{},r=Math.max(1,Math.round((a.minutes||0)*60+(a.seconds||0))||300),[o,s]=S(r),[c,i]=S(!1);E(()=>{if(!c)return;let g=setInterval(()=>s(v=>Math.max(0,v-1)),1e3);return()=>clearInterval(g)},[c]),E(()=>{o===0&&c&&(i(!1),typeof a.onDone=="function"&&t.update(g=>a.onDone(g)))},[o,c]);let l=String(Math.floor(o/60)).padStart(2,"0"),f=String(o%60).padStart(2,"0"),u=o===0;return n("div",{className:"caf-block caf-timer"},e.title?n("h2",{className:"caf-block-title"},e.title):null,a.label?n("span",{className:"caf-hint"},a.label):null,n("div",{className:u?"caf-timer-time caf-timer-done":"caf-timer-time"},u?a.doneText||"Done!":`${l}:${f}`),n("div",{className:"caf-bar-track"},n("div",{className:"caf-bar-fill caf-timer-fill",style:{width:`${o/r*100}%`}})),n("div",{className:"caf-timer-controls"},n("button",{type:"button",className:"caf-btn caf-btn-primary",disabled:u,onClick:()=>i(g=>!g)},c?"Pause":"Start"),n("button",{type:"button",className:"caf-btn",onClick:()=>{i(!1),s(r)}},"Reset")))}function $e({spec:e,ctx:t}){let a=e.custom(t);return typeof a=="string"?n("div",{className:"caf-block",dangerouslySetInnerHTML:{__html:a}}):n("div",{className:"caf-block"},a)}var V={fields:he,output:ye,text:ke,list:we,chart:ve,timer:Ee,custom:$e},T=Object.keys(V);function Ce(e){let t={};for(let a of e)t[a.key]=a.value!==void 0?a.value:a.type==="check"?!1:"";return t}function Re(){return"r"+Date.now().toString(36)+Math.random().toString(36).slice(2,8)}function Ae(e,t){if(e.title)return e.title(t);let a=e.fields.find(o=>!o.type||o.type==="text"||o.type==="textarea"||o.type==="select"),r=a&&t[a.key];return r===""||r===void 0||r===null?"(untitled)":String(r)}function Me({spec:e,records:t}){if(!e.summary)return null;let a=e.summary(t)||[];return a.length?n("div",{className:"caf-block caf-output"},n("div",{className:"caf-output-grid"},a.map((r,o)=>n("div",{key:r.label||o,className:r.big?"caf-stat caf-stat-big":"caf-stat"},n("span",{className:"caf-stat-label"},r.label),n("span",{className:"caf-stat-value"},y(r.value,r.format)))))):null}function je({spec:e,ctx:t}){let a=e.label||"item",r=t.data.records;e.sort&&(r=r.slice().sort(e.sort));function o(){let s={id:Re(),...Ce(e.fields)};t.update(c=>{c.records=[...c.records,s]}),t.go("record",s.id)}return n("div",{className:"caf-block caf-list"},n("div",{className:"caf-toolbar"},n("span",{className:"caf-count"},`${r.length} ${a}${r.length===1?"":"s"}`),n("button",{type:"button",className:"caf-btn caf-btn-primary",onClick:o},`Add ${a}`)),r.length===0?n("div",{className:"caf-empty"},e.empty||`No ${a}s yet. Add the first one.`):r.map(s=>n("button",{key:s.id,type:"button",className:"caf-row",onClick:()=>t.go("record",s.id)},n("span",{className:"caf-row-title"},Ae(e,s)),e.subtitle?n("span",{className:"caf-row-sub"},e.subtitle(s)):null)))}function Te({spec:e,ctx:t,record:a}){let r=e.label||"item";function o(){t.update(s=>{s.records=s.records.filter(c=>c.id!==a.id)}),t.back()}return n("div",{className:"caf-block caf-fields"},n("div",{className:"caf-toolbar"},n("button",{type:"button",className:"caf-btn",onClick:t.back},"\u2039 Back"),n("button",{type:"button",className:"caf-btn caf-btn-danger",onClick:o},`Delete ${r}`)),e.fields.map(s=>n($,{key:s.key,field:s,value:a[s.key],onChange:c=>t.update(i=>{let l=i.records.find(f=>f.id===a.id);l&&(l[s.key]=c)})})))}function ne({spec:e,ctx:t}){let a=e.records;if(t.view.screen==="record"){let r=t.data.records.find(o=>o.id===t.view.arg);if(r)return n("div",{className:"caf-panel caf-panel-single"},n(Te,{spec:a,ctx:t,record:r}))}return n("div",{className:"caf-panel caf-panel-single"},n(Me,{spec:a,records:t.data.records}),n(je,{spec:a,ctx:t}))}function ze(e,t){return(e.fields||[]).some(a=>F(a,t[a.key])!==null)}function De({step:e,ctx:t}){let a=e.result(t.data)||[];return n("div",{className:"caf-block caf-output"},e.title?n("h2",{className:"caf-block-title"},e.title):null,n("div",{className:"caf-output-grid"},a.map((r,o)=>n("div",{key:r.label??o,className:r.big?"caf-stat caf-stat-big":"caf-stat"},n("span",{className:"caf-stat-label"},r.label),n("span",{className:"caf-stat-value"},y(r.value,r.format)),r.hint?n("small",{className:"caf-hint"},r.hint):null))),n("div",{className:"caf-step-nav"},n("button",{type:"button",className:"caf-btn",onClick:()=>t.setStep(0)},"Start over")))}function oe({spec:e,ctx:t}){let a=e.steps,r=Math.min(Math.max(t.view.step||0,0),a.length-1),o=a[r],s=typeof o.result=="function",c=r===a.length-1;return n("div",{className:"caf-panel caf-panel-single"},n("div",{className:"caf-steps-progress"},n("span",{className:"caf-hint"},s?"Result":`Step ${r+1} of ${a.length}`),n("div",{className:"caf-bar-track"},n("div",{className:"caf-bar-fill caf-steps-fill",style:{width:`${(r+1)/a.length*100}%`}}))),s?n(De,{step:o,ctx:t}):n("div",{className:"caf-block caf-fields"},o.title?n("h2",{className:"caf-block-title"},o.title):null,o.text?n("p",{className:"caf-step-text"},typeof o.text=="function"?o.text(t.data):o.text):null,(o.fields||[]).map(i=>n($,{key:i.key,field:i,value:t.data[i.key],onChange:l=>t.update(f=>{f[i.key]=l})})),n("div",{className:"caf-step-nav"},r>0?n("button",{type:"button",className:"caf-btn",onClick:()=>t.setStep(r-1)},"\u2039 Back"):n("span"),c?null:n("button",{type:"button",className:"caf-btn caf-btn-primary",disabled:ze(o,t.data),onClick:()=>t.setStep(r+1)},"Next \u203A"))))}var ce=["panel","records","steps"],Le=["title","empty","wide","onSelect","subtitle"];function Oe(e){let t=e.layout||"panel";if(!ce.includes(t))throw new Error(`claude-artifact-framework: unknown layout "${t}". Valid layouts: ${ce.join(", ")}.`);if(t==="steps"){let r=e.steps;if(!Array.isArray(r)||r.length===0)throw new Error('claude-artifact-framework: layout "steps" needs `steps: [...]` with at least one step.');let o=["title","text","fields","result"],s=new Set;return r.forEach((c,i)=>{if(!c||typeof c!="object")throw new Error(`claude-artifact-framework: steps[${i}] must be an object.`);let l=Object.keys(c).filter(f=>!o.includes(f));if(l.length)throw new Error(`claude-artifact-framework: steps[${i}] has unknown keys (${l.join(", ")}). Valid keys: ${o.join(", ")}.`);if(!c.fields&&!c.text&&!c.result)throw new Error(`claude-artifact-framework: steps[${i}] needs \`fields\`, \`text\`, or \`result\`.`);for(let f of c.fields||[]){if(!f||!f.key)throw new Error(`claude-artifact-framework: every field in steps[${i}] needs a \`key\`.`);if(s.has(f.key))throw new Error(`claude-artifact-framework: field key "${f.key}" appears in more than one step \u2014 keys share one data pool and must be unique.`);s.add(f.key)}}),t}if(t==="records"){let r=e.records;if(!r||!Array.isArray(r.fields)||r.fields.length===0)throw new Error('claude-artifact-framework: layout "records" needs `records: { fields: [...] }` \u2014 the same field declarations the fields block uses.');let o=new Set;for(let s of r.fields){if(!s||!s.key)throw new Error("claude-artifact-framework: every records field needs a `key`.");if(s.key==="id")throw new Error('claude-artifact-framework: "id" is reserved on records \u2014 the framework assigns it.');if(o.has(s.key))throw new Error(`claude-artifact-framework: duplicate records field key "${s.key}".`);o.add(s.key)}return t}let a=e.blocks||[];if(!Array.isArray(a))throw new Error("claude-artifact-framework: `blocks` must be an array.");return a.forEach((r,o)=>{if(!r||typeof r!="object")throw new Error(`claude-artifact-framework: blocks[${o}] must be an object like { fields: [...] }.`);let s=Object.keys(r).filter(i=>!Le.includes(i)),c=s.filter(i=>T.includes(i));if(c.length===0)throw new Error(`claude-artifact-framework: blocks[${o}] has no recognised block type (found: ${s.join(", ")||"nothing"}). Valid block types: ${T.join(", ")}.`);if(c.length>1)throw new Error(`claude-artifact-framework: blocks[${o}] declares more than one block type (${c.join(", ")}). Split them into separate entries of \`blocks\`.`)}),t}function Be(e){let t={...e.data||{}};(e.layout||"panel")==="records"&&!Array.isArray(t.records)&&(t.records=[]);for(let a of[...e.blocks||[],...e.steps||[]])for(let r of a.fields||[])r&&r.key!==void 0&&!(r.key in t)&&(t[r.key]=r.value!==void 0?r.value:r.type==="check"?!1:"");return t}var _=null;function Fe(e){return _||(_=class extends e.Component{constructor(t){super(t),this.state={error:null}}static getDerivedStateFromError(t){return{error:t}}render(){return this.state.error?n("div",{className:"caf-block caf-block-error"},n("strong",null,"This section failed to render"),n("code",null,String(this.state.error.message||this.state.error))):this.props.children}}),_}function Ve({block:e,ctx:t}){let a=Object.keys(e).find(o=>T.includes(o)),r=V[a];return n(Fe(t.React),null,n(r,{spec:e,ctx:t}))}function _e({spec:e,ctx:t}){return n("div",{className:"caf-panel"},(e.blocks||[]).map((a,r)=>n("section",{key:r,className:a.wide?"caf-slot caf-slot-wide":"caf-slot"},n(Ve,{block:a,ctx:t}))))}var He={panel:_e,records:ne,steps:oe};function se(e={}){let t=Oe(e),a=Z(Be(e)),r=j(e.theme&&e.theme.seed)+Ie;return function(){if(!C())throw new Error(`claude-artifact-framework: React not found. Hand it over once, before rendering:
5
+ `);return T}var n=(...e)=>j().createElement(...e),x=(...e)=>j().useState(...e),E=(...e)=>j().useEffect(...e);var se=(...e)=>j().useRef(...e),bt=T&&T.Component||class{render(){return j()}};var Y="caf:data",ce="caf:view",ie={screen:null,arg:null,stack:[],step:0,selected:null};function L(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function H(e,a){if(!L(e)||!L(a))return a===void 0?e:a;let t={...e};for(let r of Object.keys(a))t[r]=L(e[r])?H(e[r],a[r]):a[r];return t}function le(e,a){let t;return(...r)=>{clearTimeout(t),t=setTimeout(()=>e(...r),a)}}function fe(e,{debounceMs:a=400,shared:t=!1,pollMs:r=2500}={}){let o=t?y.shared:y,s=J(e),c={...ie},i=!1,l=0,f=0,u=new Set,m=!1;function k(){m||(m=!0,Promise.resolve().then(()=>{m=!1;for(let d of u)d()}))}let b=le(()=>{let d=l;Promise.resolve(o.set(Y,s)).then(()=>{f=Math.max(f,d)}).catch(()=>{})},a),g=le(()=>y.set(ce,c),a);t&&setInterval(async()=>{if(!(!i||l>f))try{let d=await o.get(Y,void 0);d!==void 0&&JSON.stringify(d)!==JSON.stringify(s)&&(s=H(e,d),k())}catch{}},r);let w=(async()=>{let[d,h]=await Promise.all([o.get(Y,void 0),y.get(ce,void 0)]);d!==void 0&&(s=H(e,d)),h!==void 0&&(c={...ie,...h}),i=!0,k()})();function C(d){let h=d(s);h!==void 0&&(s=h),s={...s},l++,b(),k()}function v(d){c={...c,...d},g(),k()}return{ready:w,isHydrated:()=>i,getData:()=>s,getView:()=>c,update:C,setView:v,go(d,h){v({stack:[...c.stack,{screen:c.screen,arg:c.arg}],screen:d,arg:h})},back(){let d=c.stack.slice(),h=d.pop()||{screen:null,arg:null};v({stack:d,screen:h.screen,arg:h.arg})},subscribe(d){return u.add(d),()=>u.delete(d)}}}function J(e){if(Array.isArray(e))return e.map(J);if(L(e)){let a={};for(let t of Object.keys(e))a[t]=J(e[t]);return a}return e}function $(e,a,t){return Math.min(t,Math.max(a,e))}function _(e){let a=String(e).replace("#","").trim();a.length===3&&(a=a.split("").map(r=>r+r).join(""));let t=parseInt(a,16);return Number.isFinite(t)?[t>>16&255,t>>8&255,t&255]:[59,110,246]}function Oe(e){return"#"+e.map(a=>$(Math.round(a),0,255).toString(16).padStart(2,"0")).join("")}function de([e,a,t]){e/=255,a/=255,t/=255;let r=Math.max(e,a,t),o=Math.min(e,a,t),s=(r+o)/2,c=r-o,i=0,l=0;return c&&(l=s>.5?c/(2-r-o):c/(r+o),r===e?i=(a-t)/c+(a<t?6:0):r===a?i=(t-e)/c+2:i=(e-a)/c+4,i/=6),[i*360,l*100,s*100]}function Re(e,a,t){if(e=(e%360+360)%360/360,a=$(a,0,100)/100,t=$(t,0,100)/100,!a)return[t*255,t*255,t*255];let r=t<.5?t*(1+a):t+a-t*a,o=2*t-r,s=c=>(c<0&&(c+=1),c>1&&(c-=1),c<1/6?o+(r-o)*6*c:c<1/2?r:c<2/3?o+(r-o)*(2/3-c)*6:o);return[s(e+1/3)*255,s(e)*255,s(e-1/3)*255]}function p(e,a,t){return Oe(Re(e,a,t))}function ue(e){let a=e.map(t=>(t/=255,t<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4)));return .2126*a[0]+.7152*a[1]+.0722*a[2]}function K(e,a){let t=ue(_(e)),r=ue(_(a));return(Math.max(t,r)+.05)/(Math.min(t,r)+.05)}function S(e,a,t,r,o,s){for(let c=o;c>=4&&c<=96;c+=s){let i=p(e,a,c);if(K(i,t)>=r)return i}return p(e,a,s<0?24:82)}function U(e="#3b6ef6"){let[a,t]=de(_(e)),r=$(t,30,88),o=$(r*.1,3,9),s=p(a,o*.4,100),c=p(a,o*1.4,13);return{light:{bg:p(a,o,96.5),surface:s,sunken:p(a,o,93),border:p(a,o,86),text:p(a,o*1.6,11),muted:p(a,o*1.2,41),accent:S(a,r,"#ffffff",4.5,54,-2),accentText:"#ffffff",danger:S(2,68,"#ffffff",4.5,54,-2),ok:S(148,62,"#ffffff",4.5,44,-2),warn:S(38,88,"#ffffff",4.5,44,-2)},dark:{bg:p(a,o*1.5,9),surface:c,sunken:p(a,o*1.5,7),border:p(a,o*1.3,24),text:p(a,o*.6,95),muted:p(a,o*.8,66),accent:S(a,$(r,40,80),c,4.5,62,2),accentText:p(a,o*2,8),danger:S(2,70,c,4.5,62,2),ok:S(148,55,c,4.5,62,2),warn:S(38,80,c,4.5,62,2)}}}function M(e){return Object.entries(e).map(([a,t])=>`--caf-${a}: ${t};`).join("")}function z(e){let a=U(e);return`
6
+ :root { ${M(a.light)} }
7
+ @media (prefers-color-scheme: dark) { :root { ${M(a.dark)} } }
8
+ :root[data-theme="dark"] { ${M(a.dark)} }
9
+ :root[data-theme="light"] { ${M(a.light)} }
10
+ `}function me(e,a){let[t,r]=de(_(e||"#3b6ef6")),o=$(r,45,70);return Array.from({length:a},(s,c)=>p((t+c*137.5)%360,o,52))}function N(e,a){if(e==null||e==="")return"\u2014";let t=Number(e);switch(a){case"money":return Number.isFinite(t)?t.toLocaleString(void 0,{style:"currency",currency:"USD",maximumFractionDigits:2}):String(e);case"percent":return Number.isFinite(t)?`${t.toLocaleString(void 0,{maximumFractionDigits:2})}%`:String(e);case"number":return Number.isFinite(t)?t.toLocaleString(void 0,{maximumFractionDigits:2}):String(e);case"date":return e instanceof Date?e.toLocaleDateString():String(e);default:return String(e)}}function q(e,a){if(e.required&&(a===""||a===null||a===void 0))return"Required";if(a===""||a===null||a===void 0)return null;if(e.type==="number"||e.type==="money"||e.type==="percent"){let t=Number(a);if(!Number.isFinite(t))return"Must be a number";if(e.min!==void 0&&t<e.min)return`Must be at least ${e.min}`;if(e.max!==void 0&&t>e.max)return`Must be at most ${e.max}`}return null}function R({field:e,value:a,onChange:t}){let r=q(e,a),o=`caf-f-${e.key}`,s=e.type==="number"||e.type==="money"||e.type==="percent";if(e.type==="check")return n("label",{className:"caf-check"},n("input",{id:o,type:"checkbox",checked:!!a,onChange:l=>t(l.target.checked)}),n("span",null,e.label||e.key));let c={id:o,value:a??"","aria-invalid":r?"true":void 0,onChange:l=>t(s?Ae(l.target.value):l.target.value)},i;return e.type==="textarea"?i=n("textarea",{...c,rows:e.rows||3}):e.type==="select"?i=n("select",c,n("option",{value:""},e.placeholder||"Select\u2026"),(e.options||[]).map(l=>{let f=typeof l=="string"?l:l.value,u=typeof l=="string"?l:l.label;return n("option",{key:f,value:f},u)})):i=n("input",{...c,type:e.type==="date"?"date":s?"number":"text",min:e.min,max:e.max,step:e.step||(e.type==="money"||e.type==="percent"?"any":void 0),placeholder:e.placeholder}),n("div",{className:"caf-field"},n("label",{htmlFor:o},e.label||e.key),i,e.hint&&!r?n("small",{className:"caf-hint"},e.hint):null,r?n("small",{className:"caf-error"},r):null)}function Ae(e){if(e==="")return"";let a=Number(e);return Number.isFinite(a)?a:e}function Le({spec:e,ctx:a}){let t=e.fields||[];return n("div",{className:"caf-block caf-fields"},e.title?n("h2",{className:"caf-block-title"},e.title):null,t.map(r=>n(R,{key:r.key,field:r,value:a.data[r.key],onChange:o=>a.update(s=>{s[r.key]=o})})))}function Me({spec:e,ctx:a}){let t=typeof e.output=="function"?e.output(a.data):e.output||[];return t.length?n("div",{className:"caf-block caf-output"},e.title?n("h2",{className:"caf-block-title"},e.title):null,n("div",{className:"caf-output-grid"},t.map((r,o)=>n("div",{key:r.label||o,className:r.big?"caf-stat caf-stat-big":"caf-stat"},n("span",{className:"caf-stat-label"},r.label),n("span",{className:"caf-stat-value"},N(r.value,r.format)),r.hint?n("small",{className:"caf-hint"},r.hint):null)))):n("div",{className:"caf-block caf-empty"},e.empty||"Nothing to show yet.")}function _e({spec:e,ctx:a}){let t=typeof e.text=="function"?e.text(a.data):e.text;return n("div",{className:"caf-block caf-text"},e.title?n("h2",{className:"caf-block-title"},e.title):null,n("p",null,t))}function ze({spec:e,ctx:a}){let t=(typeof e.list=="function"?e.list(a.data):e.list)||[];if(!t.length)return n("div",{className:"caf-block caf-empty"},e.empty||"Nothing here yet.");let r=e.title||(o=>o.title??o.name??o.label??String(o));return n("div",{className:"caf-block caf-list"},t.map((o,s)=>n("button",{key:o.id??s,className:"caf-row",type:"button",onClick:e.onSelect?()=>e.onSelect(o,a):void 0},n("span",{className:"caf-row-title"},r(o)),e.subtitle?n("span",{className:"caf-row-sub"},e.subtitle(o)):null)))}var pe=["bar","line","donut"];function De({spec:e,ctx:a}){let t=typeof e.chart=="function"?e.chart(a.data):e.chart,r=t&&t.items||[];if(!r.length)return n("div",{className:"caf-block caf-empty"},e.empty||"No data to chart yet.");let o=t.type||"bar";if(!pe.includes(o))throw new Error(`unknown chart type "${o}". Valid types: ${pe.join(", ")}.`);let s=a.colors(r.length),c=o==="bar"?Be(r,t,s):o==="line"?Ve(r,t):Fe(r,t,s);return n("div",{className:"caf-block caf-chart"},e.title?n("h2",{className:"caf-block-title"},e.title):null,c)}function Be(e,a,t){let r=Math.max(...e.map(o=>Number(o.value)||0),0)||1;return n("div",{className:"caf-bars"},e.map((o,s)=>n("div",{key:o.label??s,className:"caf-bar-row"},n("span",{className:"caf-bar-label"},o.label),n("div",{className:"caf-bar-track"},n("div",{className:"caf-bar-fill",style:{width:`${Math.max(2,(Number(o.value)||0)/r*100)}%`,background:t[s]}})),n("span",{className:"caf-bar-value"},N(o.value,a.format)))))}function Ve(e,a){let t=e.map(u=>Number(u.value)||0),r=Math.min(...t),s=Math.max(...t)-r||1,c=100,i=36,l=t.map((u,m)=>[t.length===1?c/2:m/(t.length-1)*c,i-3-(u-r)/s*(i-6)]),f=l[l.length-1];return n("div",{className:"caf-line"},n("svg",{viewBox:`0 0 ${c} ${i}`,className:"caf-line-svg",preserveAspectRatio:"none","aria-hidden":"true"},[.25,.5,.75].map(u=>n("line",{key:u,x1:0,x2:c,y1:i*u,y2:i*u,className:"caf-line-grid"})),n("polyline",{points:l.map(u=>u.join(",")).join(" "),className:"caf-line-path"}),n("circle",{cx:f[0],cy:f[1],r:1.6,className:"caf-line-dot"})),n("div",{className:"caf-line-meta"},n("span",{className:"caf-hint"},String(e[0].label??"")),n("span",{className:"caf-line-last"},N(t[t.length-1],a.format)),n("span",{className:"caf-hint"},String(e[e.length-1].label??""))))}function Fe(e,a,t){let r=e.reduce((i,l)=>i+(Number(l.value)||0),0)||1,o=15.9155,s=25,c=e.map((i,l)=>{let f=(Number(i.value)||0)/r*100,u=n("circle",{key:i.label??l,cx:21,cy:21,r:o,className:"caf-donut-seg",stroke:t[l],strokeDasharray:`${f} ${100-f}`,strokeDashoffset:s});return s-=f,u});return n("div",{className:"caf-donut"},n("svg",{viewBox:"0 0 42 42",className:"caf-donut-svg","aria-hidden":"true"},c),n("div",{className:"caf-donut-legend"},e.map((i,l)=>n("div",{key:i.label??l,className:"caf-legend-row"},n("span",{className:"caf-legend-swatch",style:{background:t[l]}}),n("span",{className:"caf-legend-label"},i.label),n("span",{className:"caf-legend-value"},N(i.value,a.format))))))}function Pe({spec:e,ctx:a}){let t=e.timer||{},r=Math.max(1,Math.round((t.minutes||0)*60+(t.seconds||0))||300),[o,s]=x(r),[c,i]=x(!1);E(()=>{if(!c)return;let m=setInterval(()=>s(k=>Math.max(0,k-1)),1e3);return()=>clearInterval(m)},[c]),E(()=>{o===0&&c&&(i(!1),typeof t.onDone=="function"&&a.update(m=>t.onDone(m)))},[o,c]);let l=String(Math.floor(o/60)).padStart(2,"0"),f=String(o%60).padStart(2,"0"),u=o===0;return n("div",{className:"caf-block caf-timer"},e.title?n("h2",{className:"caf-block-title"},e.title):null,t.label?n("span",{className:"caf-hint"},t.label):null,n("div",{className:u?"caf-timer-time caf-timer-done":"caf-timer-time"},u?t.doneText||"Done!":`${l}:${f}`),n("div",{className:"caf-bar-track"},n("div",{className:"caf-bar-fill caf-timer-fill",style:{width:`${o/r*100}%`}})),n("div",{className:"caf-timer-controls"},n("button",{type:"button",className:"caf-btn caf-btn-primary",disabled:u,onClick:()=>i(m=>!m)},c?"Pause":"Start"),n("button",{type:"button",className:"caf-btn",onClick:()=>{i(!1),s(r)}},"Reset")))}function Ie({spec:e,ctx:a}){let t=e.custom(a);return typeof t=="string"?n("div",{className:"caf-block",dangerouslySetInnerHTML:{__html:t}}):n("div",{className:"caf-block"},t)}var W={fields:Le,output:Me,text:_e,list:ze,chart:De,timer:Pe,custom:Ie},D=Object.keys(W);function ge(e){return Object.entries(e.compute||{}).map(([a,t])=>[a,typeof t=="function"?{value:t}:t])}function Q(e,a){if(!e.compute)return a;let t={...a};for(let[r,o]of ge(e))try{t[r]=o.value(a)}catch{t[r]=void 0}return t}function Ye(e){let a={};for(let t of e)a[t.key]=t.value!==void 0?t.value:t.type==="check"?!1:"";return a}function He(){return"r"+Date.now().toString(36)+Math.random().toString(36).slice(2,8)}function Je(e,a){if(e.title)return e.title(a);let t=e.fields.find(o=>!o.type||o.type==="text"||o.type==="textarea"||o.type==="select"),r=t&&a[t.key];return r===""||r===void 0||r===null?"(untitled)":String(r)}function Ke({spec:e,records:a}){if(!e.summary)return null;let t=e.summary(a)||[];return t.length?n("div",{className:"caf-block caf-output"},n("div",{className:"caf-output-grid"},t.map((r,o)=>n("div",{key:r.label||o,className:r.big?"caf-stat caf-stat-big":"caf-stat"},n("span",{className:"caf-stat-label"},r.label),n("span",{className:"caf-stat-value"},N(r.value,r.format)))))):null}function Ue({spec:e,ctx:a}){let t=e.label||"item",[r,o]=x(""),s=a.data.records.map(f=>Q(e,f));e.sort&&(s=s.slice().sort(e.sort));let c=s.length,i=r.trim().toLowerCase();e.search&&i&&(s=s.filter(f=>e.fields.some(u=>String(f[u.key]??"").toLowerCase().includes(i))));function l(){let f={id:He(),...Ye(e.fields)};a.update(u=>{u.records=[...u.records,f]}),a.go("record",f.id)}return n("div",{className:"caf-block caf-list"},n("div",{className:"caf-toolbar"},n("span",{className:"caf-count"},e.search&&i?`${s.length} of ${c}`:`${c} ${t}${c===1?"":"s"}`),n("button",{type:"button",className:"caf-btn caf-btn-primary",onClick:l},`Add ${t}`)),e.search?n("input",{className:"caf-search",value:r,placeholder:`Search ${t}s\u2026`,"aria-label":"Search",onChange:f=>o(f.target.value)}):null,e.search&&i&&s.length===0&&c>0?n("div",{className:"caf-empty"},`Nothing matches "${r}".`):null,s.length===0?n("div",{className:"caf-empty"},e.empty||`No ${t}s yet. Add the first one.`):s.map(f=>n("button",{key:f.id,type:"button",className:"caf-row",onClick:()=>a.go("record",f.id)},n("span",{className:"caf-row-title"},Je(e,f)),e.subtitle?n("span",{className:"caf-row-sub"},e.subtitle(f)):null)))}function qe({spec:e,ctx:a,record:t}){let r=e.label||"item";function o(){a.update(s=>{s.records=s.records.filter(c=>c.id!==t.id)}),a.back()}return n("div",{className:"caf-block caf-fields"},n("div",{className:"caf-toolbar"},n("button",{type:"button",className:"caf-btn",onClick:a.back},"\u2039 Back"),n("button",{type:"button",className:"caf-btn caf-btn-danger",onClick:o},`Delete ${r}`)),e.fields.map(s=>n(R,{key:s.key,field:s,value:t[s.key],onChange:c=>a.update(i=>{let l=i.records.find(f=>f.id===t.id);l&&(l[s.key]=c)})})),e.compute?n("div",{className:"caf-output-grid caf-computed"},ge(e).map(([s,c])=>{let i=Q(e,t);return n("div",{key:s,className:"caf-stat"},n("span",{className:"caf-stat-label"},c.label||s),n("span",{className:"caf-stat-value"},N(i[s],c.format)))})):null)}function he({spec:e,ctx:a}){let t=e.records;if(a.view.screen==="record"){let r=a.data.records.find(o=>o.id===a.view.arg);if(r)return n("div",{className:"caf-panel caf-panel-single"},n(qe,{spec:t,ctx:a,record:r}))}return n("div",{className:"caf-panel caf-panel-single"},n(Ke,{spec:t,records:a.data.records.map(r=>Q(t,r))}),n(Ue,{spec:t,ctx:a}))}function We(e,a){return(e.fields||[]).some(t=>q(t,a[t.key])!==null)}function Qe({step:e,ctx:a}){let t=e.result(a.data)||[];return n("div",{className:"caf-block caf-output"},e.title?n("h2",{className:"caf-block-title"},e.title):null,n("div",{className:"caf-output-grid"},t.map((r,o)=>n("div",{key:r.label??o,className:r.big?"caf-stat caf-stat-big":"caf-stat"},n("span",{className:"caf-stat-label"},r.label),n("span",{className:"caf-stat-value"},N(r.value,r.format)),r.hint?n("small",{className:"caf-hint"},r.hint):null))),n("div",{className:"caf-step-nav"},n("button",{type:"button",className:"caf-btn",onClick:()=>a.setStep(0)},"Start over")))}function be({spec:e,ctx:a}){let t=e.steps,r=Math.min(Math.max(a.view.step||0,0),t.length-1),o=t[r],s=typeof o.result=="function",c=r===t.length-1;return n("div",{className:"caf-panel caf-panel-single"},n("div",{className:"caf-steps-progress"},n("span",{className:"caf-hint"},s?"Result":`Step ${r+1} of ${t.length}`),n("div",{className:"caf-bar-track"},n("div",{className:"caf-bar-fill caf-steps-fill",style:{width:`${(r+1)/t.length*100}%`}}))),s?n(Qe,{step:o,ctx:a}):n("div",{className:"caf-block caf-fields"},o.title?n("h2",{className:"caf-block-title"},o.title):null,o.text?n("p",{className:"caf-step-text"},typeof o.text=="function"?o.text(a.data):o.text):null,(o.fields||[]).map(i=>n(R,{key:i.key,field:i,value:a.data[i.key],onChange:l=>a.update(f=>{f[i.key]=l})})),n("div",{className:"caf-step-nav"},r>0?n("button",{type:"button",className:"caf-btn",onClick:()=>a.setStep(r-1)},"\u2039 Back"):n("span"),c?null:n("button",{type:"button",className:"caf-btn caf-btn-primary",disabled:We(o,a.data),onClick:()=>a.setStep(r+1)},"Next \u203A"))))}var X=["system","greeting","placeholder","tools","model","maxTokens"],Xe="claude-sonnet-4-6",Ge=8;async function Ze({model:e,maxTokens:a,system:t,messages:r,onText:o}){let s=await fetch("https://api.anthropic.com/v1/messages",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:e,max_tokens:a,system:t,messages:r,stream:!0})});if(!s.ok||!s.body){let u="";try{let m=await s.json();u=m&&m.error&&m.error.message||JSON.stringify(m)}catch{u=await s.text().catch(()=>"")}throw new Error(`HTTP ${s.status}${u?": "+u:""}`)}let c=s.body.getReader(),i=new TextDecoder,l="",f="";for(;;){let{done:u,value:m}=await c.read();if(u)break;f+=i.decode(m,{stream:!0});let k=f.split(`
11
+ `);f=k.pop();for(let b of k)if(b.startsWith("data: "))try{let g=JSON.parse(b.slice(6));g.type==="content_block_delta"&&g.delta&&g.delta.text&&(l+=g.delta.text,o&&o(l))}catch{}}return l}function et(e){let a=e.match(/```tool_call\s*\n?([\s\S]*?)```/);if(!a)return null;try{let t=JSON.parse(a[1]);return Array.isArray(t)&&t.length?t:null}catch{return null}}function ye(e){return e.replace(/```tool_call\s*\n?[\s\S]*?```/,"").trim()}function tt(e){return`
12
+
13
+ You have tools available:
14
+ ${Object.entries(e).map(([t,r])=>`- ${t}: ${r.description}
15
+ Input: ${JSON.stringify(r.input||{})}`).join(`
16
+ `)}
17
+
18
+ This environment does not support native function calling. To use a tool, reply ONLY with a \`\`\`tool_call code block containing a JSON array, with no other text in that turn. Example:
19
+
20
+ \`\`\`tool_call
21
+ [{ "name": "tool_name", "input": { "param": "value" } }]
22
+ \`\`\`
23
+
24
+ You may include several calls in one array. NEVER invent a tool's result \u2014 emit the pure tool_call block and wait for the real result, which arrives in the next message tagged [TOOL_RESULT]. When you have everything you need, answer in natural language with no tool_call block.`}function at(e,a,t){return e.map(r=>{let o=a[r.name];if(!o)return{name:r.name,error:`unknown tool "${r.name}". Valid tools: ${Object.keys(a).join(", ")}`};try{let s=o.run(r.input||{},t);return{name:r.name,result:s===void 0?{ok:!0}:s}}catch(s){return{name:r.name,error:String(s&&s.message||s)}}})}function rt({m:e}){return e.role==="tools"?n("div",{className:"caf-msg-tools"},`used: ${e.tools.join(", ")}`):e.role==="error"?n("div",{className:"caf-msg caf-msg-error"},n("strong",null,"The call failed"),n("span",null,e.content),n("span",{className:"caf-hint"},"Your message is kept \u2014 send again to retry.")):n("div",{className:e.role==="user"?"caf-msg caf-msg-user":"caf-msg caf-msg-assistant"},e.content)}function ke({spec:e,ctx:a}){let t=e.chat,[r,o]=x(""),[s,c]=x(!1),[i,l]=x(null),f=se(null),u=a.data.chat||{api:[],log:[]},m=u.log||[];E(()=>{f.current&&f.current.scrollIntoView({block:"end"})},[m.length,i]);async function k(){let b=r.trim();if(!b||s)return;o(""),c(!0);let g=[...u.api||[],{role:"user",content:b}],w=[...m,{role:"user",content:b}],C=()=>a.update(v=>{v.chat={api:g,log:w}});C();try{let v=(typeof t.system=="function"?t.system(a.data):t.system||"")+(t.tools?tt(t.tools):"");for(let d=0;d<Ge;d++){let h=await Ze({model:t.model||Xe,maxTokens:t.maxTokens||2e3,system:v,messages:g,onText:F=>l(ye(F))});g=[...g,{role:"assistant",content:h}];let B=ye(h),V=t.tools?et(h):null;if(!V){w=[...w,{role:"assistant",content:B||h}],C();break}let Ne=at(V,t.tools,a);B&&(w=[...w,{role:"assistant",content:B}]),w=[...w,{role:"tools",tools:V.map(F=>F.name)}],g=[...g,{role:"user",content:`[TOOL_RESULT]
25
+ ${JSON.stringify(Ne)}
26
+ [/TOOL_RESULT]
27
+
28
+ Continue with this information. If you have everything you need, answer in natural language without further tool_call.`}],C(),l(null)}}catch(v){w=[...w,{role:"error",content:String(v&&v.message||v)}],C()}finally{l(null),c(!1)}}return n("div",{className:"caf-panel caf-panel-single"},n("div",{className:"caf-block caf-chat-log"},t.greeting?n("div",{className:"caf-msg caf-msg-assistant"},t.greeting):null,m.map((b,g)=>n(rt,{key:g,m:b})),i!==null?n("div",{className:"caf-msg caf-msg-assistant caf-msg-live"},i||"\u2026"):null,s&&i===null?n("div",{className:"caf-msg-tools"},"thinking\u2026"):null,n("div",{ref:f})),n("form",{className:"caf-chat-input",onSubmit:b=>{b.preventDefault(),k()}},n("input",{value:r,placeholder:t.placeholder||"Message\u2026",disabled:s,onChange:b=>o(b.target.value),"aria-label":"Message"}),n("button",{type:"submit",className:"caf-btn caf-btn-primary",disabled:s||!r.trim()},"Send")))}var we=["panel","records","steps","chat"],nt=["title","empty","wide","onSelect","subtitle"],ve=["title","subtitle","theme","layout","blocks","records","steps","chat","data","shared"];function ot(e){let a=Object.keys(e).filter(o=>!ve.includes(o));if(a.length)throw new Error(`claude-artifact-framework: unknown top-level keys (${a.join(", ")}). Valid keys: ${ve.join(", ")}.`);let t=e.layout||"panel";if(!we.includes(t))throw new Error(`claude-artifact-framework: unknown layout "${t}". Valid layouts: ${we.join(", ")}.`);if(t==="steps"){let o=e.steps;if(!Array.isArray(o)||o.length===0)throw new Error('claude-artifact-framework: layout "steps" needs `steps: [...]` with at least one step.');let s=["title","text","fields","result"],c=new Set;return o.forEach((i,l)=>{if(!i||typeof i!="object")throw new Error(`claude-artifact-framework: steps[${l}] must be an object.`);let f=Object.keys(i).filter(u=>!s.includes(u));if(f.length)throw new Error(`claude-artifact-framework: steps[${l}] has unknown keys (${f.join(", ")}). Valid keys: ${s.join(", ")}.`);if(!i.fields&&!i.text&&!i.result)throw new Error(`claude-artifact-framework: steps[${l}] needs \`fields\`, \`text\`, or \`result\`.`);for(let u of i.fields||[]){if(!u||!u.key)throw new Error(`claude-artifact-framework: every field in steps[${l}] needs a \`key\`.`);if(c.has(u.key))throw new Error(`claude-artifact-framework: field key "${u.key}" appears in more than one step \u2014 keys share one data pool and must be unique.`);c.add(u.key)}}),t}if(t==="chat"){let o=e.chat;if(!o||typeof o.system!="string"&&typeof o.system!="function")throw new Error('claude-artifact-framework: layout "chat" needs `chat: { system: "..." }` (a string or a function of data).');let s=Object.keys(o).filter(c=>!X.includes(c));if(s.length)throw new Error(`claude-artifact-framework: chat has unknown keys (${s.join(", ")}). Valid keys: ${X.join(", ")}.`);for(let[c,i]of Object.entries(o.tools||{}))if(!i||typeof i.description!="string"||typeof i.run!="function")throw new Error(`claude-artifact-framework: chat tool "${c}" needs a \`description\` string and a \`run(input, ctx)\` function.`);return t}if(t==="records"){let o=e.records;if(!o||!Array.isArray(o.fields)||o.fields.length===0)throw new Error('claude-artifact-framework: layout "records" needs `records: { fields: [...] }` \u2014 the same field declarations the fields block uses.');let s=["label","fields","title","subtitle","sort","summary","empty","search","compute"],c=Object.keys(o).filter(l=>!s.includes(l));if(c.length)throw new Error(`claude-artifact-framework: records has unknown keys (${c.join(", ")}). Valid keys: ${s.join(", ")}.`);let i=new Set;for(let l of o.fields){if(!l||!l.key)throw new Error("claude-artifact-framework: every records field needs a `key`.");if(l.key==="id")throw new Error('claude-artifact-framework: "id" is reserved on records \u2014 the framework assigns it.');if(i.has(l.key))throw new Error(`claude-artifact-framework: duplicate records field key "${l.key}".`);i.add(l.key)}for(let[l,f]of Object.entries(o.compute||{})){if(i.has(l)||l==="id")throw new Error(`claude-artifact-framework: compute key "${l}" collides with a field key \u2014 computed values are derived, never stored.`);if(typeof f!="function"&&typeof(f&&f.value)!="function")throw new Error(`claude-artifact-framework: compute "${l}" must be a function of the record, or { label, format, value: (r) => ... }.`)}return t}let r=e.blocks||[];if(!Array.isArray(r))throw new Error("claude-artifact-framework: `blocks` must be an array.");return r.forEach((o,s)=>{if(!o||typeof o!="object")throw new Error(`claude-artifact-framework: blocks[${s}] must be an object like { fields: [...] }.`);let c=Object.keys(o).filter(l=>!nt.includes(l)),i=c.filter(l=>D.includes(l));if(i.length===0)throw new Error(`claude-artifact-framework: blocks[${s}] has no recognised block type (found: ${c.join(", ")||"nothing"}). Valid block types: ${D.join(", ")}.`);if(i.length>1)throw new Error(`claude-artifact-framework: blocks[${s}] declares more than one block type (${i.join(", ")}). Split them into separate entries of \`blocks\`.`)}),t}function st(e){let a={...e.data||{}};(e.layout||"panel")==="records"&&!Array.isArray(a.records)&&(a.records=[]),(e.layout||"panel")==="chat"&&!a.chat&&(a.chat={api:[],log:[]});for(let t of[...e.blocks||[],...e.steps||[]])for(let r of t.fields||[])r&&r.key!==void 0&&!(r.key in a)&&(a[r.key]=r.value!==void 0?r.value:r.type==="check"?!1:"");return a}var G=null;function ct(e){return G||(G=class extends e.Component{constructor(a){super(a),this.state={error:null}}static getDerivedStateFromError(a){return{error:a}}render(){return this.state.error?n("div",{className:"caf-block caf-block-error"},n("strong",null,"This section failed to render"),n("code",null,String(this.state.error.message||this.state.error))):this.props.children}}),G}function it({block:e,ctx:a}){let t=Object.keys(e).find(o=>D.includes(o)),r=W[t];return n(ct(a.React),null,n(r,{spec:e,ctx:a}))}function lt({spec:e,ctx:a}){return n("div",{className:"caf-panel"},(e.blocks||[]).map((t,r)=>n("section",{key:r,className:t.wide?"caf-slot caf-slot-wide":"caf-slot"},n(it,{block:t,ctx:a}))))}var ft={panel:lt,records:he,steps:be,chat:ke};function xe(e={}){let a=ot(e),t=fe(st(e),{shared:!!e.shared}),r=z(e.theme&&e.theme.seed)+ut;return function(){if(!A())throw new Error(`claude-artifact-framework: React not found. Hand it over once, before rendering:
11
29
 
12
30
  import React from "react";
13
31
  ArtifactKit.useReact(React);
14
- `);let[,s]=S(0);E(()=>{let l=a.subscribe(()=>s(f=>f+1));return a.isHydrated()&&s(f=>f+1),l},[]);let c={React:J(),data:a.getData(),view:a.getView(),update:a.update,go:a.go,back:a.back,setStep:l=>a.setView({step:l}),colors:l=>ae(e.theme&&e.theme.seed,l)},i=He[t];return n("div",{className:"caf-root"},n("style",{dangerouslySetInnerHTML:{__html:r}}),n("header",{className:"caf-header"},e.title?n("h1",null,e.title):null,e.subtitle?n("p",null,e.subtitle):null),a.isHydrated()?n(i,{spec:e,ctx:c}):n("div",{className:"caf-block caf-loading"},"Loading\u2026"))}}var Ie=`
32
+ `);let[,s]=x(0);E(()=>{let l=t.subscribe(()=>s(f=>f+1));return t.isHydrated()&&s(f=>f+1),l},[]);let c={React:oe(),data:t.getData(),view:t.getView(),update:t.update,go:t.go,back:t.back,setStep:l=>t.setView({step:l}),colors:l=>me(e.theme&&e.theme.seed,l)},i=ft[a];return n("div",{className:"caf-root"},n("style",{dangerouslySetInnerHTML:{__html:r}}),n("header",{className:"caf-header"},e.title?n("h1",null,e.title):null,e.subtitle?n("p",null,e.subtitle):null),t.isHydrated()?n(i,{spec:e,ctx:c}):n("div",{className:"caf-block caf-loading"},"Loading\u2026"))}}var ut=`
15
33
  .caf-root {
16
34
  --caf-radius: 10px;
17
35
  box-sizing: border-box;
@@ -113,9 +131,28 @@ var ArtifactKit=(()=>{var z=Object.defineProperty;var ie=Object.getOwnPropertyDe
113
131
  .caf-steps-fill { transition: width 0.25s ease; }
114
132
  .caf-step-text { margin: 0; color: var(--caf-muted); font-size: 0.92rem; line-height: 1.55; }
115
133
  .caf-step-nav { display: flex; justify-content: space-between; gap: 0.6rem; margin-top: 0.4rem; }
134
+ .caf-chat-log { min-height: 320px; max-height: 62vh; overflow-y: auto; gap: 0.55rem; }
135
+ .caf-msg { max-width: 85%; padding: 0.55rem 0.75rem; border-radius: 12px; font-size: 0.92rem; line-height: 1.5; white-space: pre-wrap; word-break: break-word; }
136
+ .caf-msg-user { align-self: flex-end; background: var(--caf-accent); color: var(--caf-accentText); border-bottom-right-radius: 4px; }
137
+ .caf-msg-assistant { align-self: flex-start; background: var(--caf-sunken); border-bottom-left-radius: 4px; }
138
+ .caf-msg-live::after { content: "\u258D"; opacity: 0.6; }
139
+ .caf-msg-tools { align-self: flex-start; font-size: 0.74rem; color: var(--caf-muted); padding: 0.15rem 0.55rem; border: 1px solid var(--caf-border); border-radius: 999px; }
140
+ .caf-msg-error { align-self: stretch; max-width: none; display: flex; flex-direction: column; gap: 0.2rem; background: transparent; border: 1px solid var(--caf-danger); }
141
+ .caf-msg-error strong { color: var(--caf-danger); font-size: 0.85rem; }
142
+ .caf-chat-input { display: flex; gap: 0.6rem; margin-top: 0.8rem; }
143
+ .caf-chat-input input { flex: 1; font: inherit; font-size: 0.95rem; padding: 0.55rem 0.7rem; border-radius: 8px; border: 1px solid var(--caf-border); background: var(--caf-surface); color: var(--caf-text); }
144
+ .caf-chat-input input:focus-visible { outline: 2px solid var(--caf-accent); outline-offset: 1px; }
145
+ .caf-search {
146
+ font: inherit; font-size: 0.9rem; width: 100%;
147
+ padding: 0.5rem 0.65rem; margin: 0 0 0.3rem;
148
+ border-radius: 7px; border: 1px solid var(--caf-border);
149
+ background: var(--caf-sunken); color: var(--caf-text);
150
+ }
151
+ .caf-search:focus-visible { outline: 2px solid var(--caf-accent); outline-offset: 1px; }
152
+ .caf-computed { border-top: 1px solid var(--caf-border); padding-top: 0.7rem; }
116
153
  .caf-empty, .caf-loading { color: var(--caf-muted); font-size: 0.9rem; text-align: center; padding: 1.6rem 1rem; }
117
154
  .caf-block-error { border-color: var(--caf-danger); gap: 0.4rem; }
118
155
  .caf-block-error strong { font-size: 0.9rem; color: var(--caf-danger); }
119
156
  .caf-block-error code { font-size: 0.78rem; color: var(--caf-muted); word-break: break-word; }
120
- `;return me(Pe);})();
157
+ `;return je(dt);})();
121
158
  //# sourceMappingURL=index.global.js.map