claude-artifact-framework 0.12.0 → 0.13.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,14 +1,14 @@
1
- var ArtifactKit=(()=>{var q=Object.defineProperty;var Ze=Object.getOwnPropertyDescriptor;var et=Object.getOwnPropertyNames;var tt=Object.prototype.hasOwnProperty;var at=(e,t)=>{for(var a in t)q(e,a,{get:t[a],enumerable:!0})},rt=(e,t,a,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of et(t))!tt.call(e,o)&&o!==a&&q(e,o,{get:()=>t[o],enumerable:!(r=Ze(t,o))||r.enumerable});return e};var nt=e=>rt(q({},"__esModule",{value:!0}),e);var Ht={};at(Ht,{contrast:()=>Z,createApp:()=>Qe,createPersistedStore:()=>pe,createSharedStore:()=>be,createStore:()=>me,hasReact:()=>z,palette:()=>ee,storage:()=>k,themeCss:()=>V,useReact:()=>he});function M(){return typeof window<"u"&&typeof window.storage=="object"&&window.storage!==null}function de(e){return{async get(t,a=void 0){if(!M())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(!M())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(M())try{await window.storage.delete(t,e)}catch{}},async list(t){if(!M())return[];try{return(await window.storage.list(t,e))?.keys||[]}catch{return[]}}}}var k={...de(!1),shared:de(!0),available:M};function W(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 ue(e,t){let a;return(...r)=>{clearTimeout(a),a=setTimeout(()=>e(...r),t)}}function me(e){return W(e)}function pe(e,t,{debounceMs:a=300}={}){let r=W(t),o=ue(c=>k.set(e,c),a),s=k.get(e,t).then(c=>r.set(c));return r.subscribe(o),{...r,ready:s}}function be(e,t,{pollMs:a=2e3,debounceMs:r=300}={}){let o=W(t),s=ue(f=>k.shared.set(e,f),r),c=!1;o.subscribe(f=>{c||s(f)});async function i(){let f=await k.shared.get(e,t);JSON.stringify(f)!==JSON.stringify(o.get())&&(c=!0,o.set(f),c=!1)}let d=i(),l=setInterval(i,a);return{...o,ready:d,stop:()=>clearInterval(l)}}var O=typeof globalThis<"u"?globalThis.React:void 0;function he(e){return O=e,e}function z(){return!!O}function ge(){return j()}function j(){if(!O)throw new Error(`claude-artifact-framework: React not found. Hand it over once, before createApp:
1
+ var ArtifactKit=(()=>{var W=Object.defineProperty;var et=Object.getOwnPropertyDescriptor;var tt=Object.getOwnPropertyNames;var at=Object.prototype.hasOwnProperty;var rt=(e,t)=>{for(var a in t)W(e,a,{get:t[a],enumerable:!0})},nt=(e,t,a,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of tt(t))!at.call(e,o)&&o!==a&&W(e,o,{get:()=>t[o],enumerable:!(r=et(t,o))||r.enumerable});return e};var ot=e=>nt(W({},"__esModule",{value:!0}),e);var Jt={};rt(Jt,{contrast:()=>ee,createApp:()=>Ze,createPersistedStore:()=>he,createSharedStore:()=>ge,createStore:()=>be,hasReact:()=>I,palette:()=>te,storage:()=>x,themeCss:()=>K,useReact:()=>ye});function D(){return typeof window<"u"&&typeof window.storage=="object"&&window.storage!==null}function me(e){return{async get(t,a=void 0){if(!D())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(!D())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(D())try{await window.storage.delete(t,e)}catch{}},async list(t){if(!D())return[];try{return(await window.storage.list(t,e))?.keys||[]}catch{return[]}}}}var x={...me(!1),shared:me(!0),available:D};function X(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 pe(e,t){let a;return(...r)=>{clearTimeout(a),a=setTimeout(()=>e(...r),t)}}function be(e){return X(e)}function he(e,t,{debounceMs:a=300}={}){let r=X(t),o=pe(c=>x.set(e,c),a),s=x.get(e,t).then(c=>r.set(c));return r.subscribe(o),{...r,ready:s}}function ge(e,t,{pollMs:a=2e3,debounceMs:r=300}={}){let o=X(t),s=pe(f=>x.shared.set(e,f),r),c=!1;o.subscribe(f=>{c||s(f)});async function i(){let f=await x.shared.get(e,t);JSON.stringify(f)!==JSON.stringify(o.get())&&(c=!0,o.set(f),c=!1)}let d=i(),l=setInterval(i,a);return{...o,ready:d,stop:()=>clearInterval(l)}}var _=typeof globalThis<"u"?globalThis.React:void 0;function ye(e){return _=e,e}function I(){return!!_}function we(){return M()}function M(){if(!_)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 O}var n=(...e)=>j().createElement(...e),v=(...e)=>j().useState(...e),S=(...e)=>j().useEffect(...e);var ye=(...e)=>j().useRef(...e),Xt=O&&O.Component||class{render(){return j()}};var X="caf:data",we="caf:viewer",ke="caf:view",ve={screen:null,arg:null,stack:[],step:0,selected:null,tabs:{},collapsed:{}};function B(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Q(e,t){if(!B(e)||!B(t))return t===void 0?e:t;let a={...e};for(let r of Object.keys(t))a[r]=B(e[r])?Q(e[r],t[r]):t[r];return a}function xe(e,t){let a;return(...r)=>{clearTimeout(a),a=setTimeout(()=>e(...r),t)}}function Ne(e,{debounceMs:t=400,shared:a=!1,pollMs:r=2500}={}){let o=a?k.shared:k,s=G(e),c={...ve},i=!1,d=null,l=0,f=0,p=new Set,u=!1;function b(){u||(u=!0,Promise.resolve().then(()=>{u=!1;for(let h of p)h()}))}let m=xe(()=>{let h=l;Promise.resolve(o.set(X,s)).then(()=>{f=Math.max(f,h)}).catch(()=>{})},t),w=xe(()=>k.set(ke,c),t);a&&setInterval(async()=>{if(!(!i||l>f))try{let h=await o.get(X,void 0);h!==void 0&&JSON.stringify(h)!==JSON.stringify(s)&&(s=Q(e,h),b())}catch{}},r);let x=(async()=>{let[h,y,C]=await Promise.all([o.get(X,void 0),k.get(ke,void 0),k.get(we,void 0)]);typeof C=="string"&&C?d=C:(d="v"+Math.random().toString(36).slice(2,10)+Math.random().toString(36).slice(2,6),k.set(we,d).catch?.(()=>{})),h!==void 0&&(s=Q(e,h)),y!==void 0&&(c={...ve,...y}),i=!0,b()})();function R(h){let y=h(s);y!==void 0&&(s=y),s={...s},l++,m(),b()}function N(h){c={...c,...h},w(),b()}return{ready:x,isHydrated:()=>i,getViewerId:()=>d,getData:()=>s,getView:()=>c,update:R,setView:N,go(h,y){N({stack:[...c.stack,{screen:c.screen,arg:c.arg}],screen:h,arg:y})},back(){let h=c.stack.slice(),y=h.pop()||{screen:null,arg:null};N({stack:h,screen:y.screen,arg:y.arg})},subscribe(h){return p.add(h),()=>p.delete(h)}}}function G(e){if(Array.isArray(e))return e.map(G);if(B(e)){let t={};for(let a of Object.keys(e))t[a]=G(e[a]);return t}return e}function T(e,t,a){return Math.min(a,Math.max(t,e))}function I(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 ot(e){return"#"+e.map(t=>T(Math.round(t),0,255).toString(16).padStart(2,"0")).join("")}function $e([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,d=0;return c&&(d=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,d*100,s*100]}function st(e,t,a){if(e=(e%360+360)%360/360,t=T(t,0,100)/100,a=T(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 g(e,t,a){return ot(st(e,t,a))}function Se(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 Z(e,t){let a=Se(I(e)),r=Se(I(t));return(Math.max(a,r)+.05)/(Math.min(a,r)+.05)}function E(e,t,a,r,o,s){for(let c=o;c>=4&&c<=96;c+=s){let i=g(e,t,c);if(Z(i,a)>=r)return i}return g(e,t,s<0?24:82)}function ee(e="#3b6ef6"){let[t,a]=$e(I(e)),r=T(a,30,88),o=T(r*.1,3,9),s=g(t,o*.4,100),c=g(t,o*1.4,13);return{light:{bg:g(t,o,96.5),surface:s,sunken:g(t,o,93),border:g(t,o,86),text:g(t,o*1.6,11),muted:g(t,o*1.2,41),accent:E(t,r,"#ffffff",4.5,54,-2),accentText:"#ffffff",danger:E(2,68,"#ffffff",4.5,54,-2),ok:E(148,62,"#ffffff",4.5,44,-2),warn:E(38,88,"#ffffff",4.5,44,-2)},dark:{bg:g(t,o*1.5,9),surface:c,sunken:g(t,o*1.5,7),border:g(t,o*1.3,24),text:g(t,o*.6,95),muted:g(t,o*.8,66),accent:E(t,T(r,40,80),c,4.5,62,2),accentText:g(t,o*2,8),danger:E(2,70,c,4.5,62,2),ok:E(148,55,c,4.5,62,2),warn:E(38,80,c,4.5,62,2)}}}function D(e){return Object.entries(e).map(([t,a])=>`--caf-${t}: ${a};`).join("")}function V(e){let t=ee(e);return`
6
- :root { ${D(t.light)} }
7
- @media (prefers-color-scheme: dark) { :root { ${D(t.dark)} } }
8
- :root[data-theme="dark"] { ${D(t.dark)} }
9
- :root[data-theme="light"] { ${D(t.light)} }
10
- `}function Ee(e,t){let[a,r]=$e(I(e||"#3b6ef6")),o=T(r,45,70);return Array.from({length:t},(s,c)=>g((a+c*137.5)%360,o,52))}var ae=["system","greeting","placeholder","tools","model","maxTokens"],ct="claude-sonnet-4-6",it=8;async function lt({model:e,maxTokens:t,system:a,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:t,system:a,messages:r,stream:!0})});if(!s.ok||!s.body){let f="";try{let p=await s.json();f=p&&p.error&&p.error.message||JSON.stringify(p)}catch{f=await s.text().catch(()=>"")}throw new Error(`HTTP ${s.status}${f?": "+f:""}`)}let c=s.body.getReader(),i=new TextDecoder,d="",l="";for(;;){let{done:f,value:p}=await c.read();if(f)break;l+=i.decode(p,{stream:!0});let u=l.split(`
11
- `);l=u.pop();for(let b of u)if(b.startsWith("data: "))try{let m=JSON.parse(b.slice(6));m.type==="content_block_delta"&&m.delta&&m.delta.text&&(d+=m.delta.text,o&&o(d))}catch{}}return d}function ft(e){let t=e.match(/```tool_call\s*\n?([\s\S]*?)```/);if(!t)return null;try{let a=JSON.parse(t[1]);return Array.isArray(a)&&a.length?a:null}catch{return null}}function Ae(e){return e.replace(/```tool_call\s*\n?[\s\S]*?```/,"").trim()}function dt(e){return`
5
+ `);return _}var n=(...e)=>M().createElement(...e),N=(...e)=>M().useState(...e),T=(...e)=>M().useEffect(...e);var ke=(...e)=>M().useRef(...e),Qt=_&&_.Component||class{render(){return M()}};var Q="caf:data",ve="caf:viewer",xe="caf:view",Ne={screen:null,arg:null,stack:[],step:0,selected:null,tabs:{},collapsed:{}};function V(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function G(e,t){if(!V(e)||!V(t))return t===void 0?e:t;let a={...e};for(let r of Object.keys(t))a[r]=V(e[r])?G(e[r],t[r]):t[r];return a}function $e(e,t){let a;return(...r)=>{clearTimeout(a),a=setTimeout(()=>e(...r),t)}}function Se(e,{debounceMs:t=400,shared:a=!1,pollMs:r=2500}={}){let o=a?x.shared:x,s=Z(e),c={...Ne},i=!1,d=null,l=0,f=0,u=new Set,m=!1;function b(){m||(m=!0,Promise.resolve().then(()=>{m=!1;for(let g of u)g()}))}let h=$e(()=>{let g=l;Promise.resolve(o.set(Q,s)).then(()=>{f=Math.max(f,g)}).catch(()=>{})},t),$=$e(()=>x.set(xe,c),t);a&&setInterval(async()=>{if(!(!i||l>f))try{let g=await o.get(Q,void 0);g!==void 0&&JSON.stringify(g)!==JSON.stringify(s)&&(s=G(e,g),b())}catch{}},r);let v=(async()=>{let[g,y,p]=await Promise.all([o.get(Q,void 0),x.get(xe,void 0),x.get(ve,void 0)]);typeof p=="string"&&p?d=p:(d="v"+Math.random().toString(36).slice(2,10)+Math.random().toString(36).slice(2,6),x.set(ve,d).catch?.(()=>{})),g!==void 0&&(s=G(e,g)),y!==void 0&&(c={...Ne,...y}),i=!0,b()})();function E(g){let y=g(s);y!==void 0&&(s=y),s={...s},l++,h(),b()}function S(g){c={...c,...g},$(),b()}return{ready:v,isHydrated:()=>i,getViewerId:()=>d,getData:()=>s,getView:()=>c,update:E,setView:S,go(g,y){S({stack:[...c.stack,{screen:c.screen,arg:c.arg}],screen:g,arg:y})},back(){let g=c.stack.slice(),y=g.pop()||{screen:null,arg:null};S({stack:g,screen:y.screen,arg:y.arg})},subscribe(g){return u.add(g),()=>u.delete(g)}}}function Z(e){if(Array.isArray(e))return e.map(Z);if(V(e)){let t={};for(let a of Object.keys(e))t[a]=Z(e[a]);return t}return e}function L(e,t,a){return Math.min(a,Math.max(t,e))}function P(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 st(e){return"#"+e.map(t=>L(Math.round(t),0,255).toString(16).padStart(2,"0")).join("")}function Ae([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,d=0;return c&&(d=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,d*100,s*100]}function ct(e,t,a){if(e=(e%360+360)%360/360,t=L(t,0,100)/100,a=L(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 w(e,t,a){return st(ct(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 ee(e,t){let a=Ee(P(e)),r=Ee(P(t));return(Math.max(a,r)+.05)/(Math.min(a,r)+.05)}function O(e,t,a,r,o,s){for(let c=o;c>=4&&c<=96;c+=s){let i=w(e,t,c);if(ee(i,a)>=r)return i}return w(e,t,s<0?24:82)}function te(e="#3b6ef6"){let[t,a]=Ae(P(e)),r=L(a,30,88),o=L(r*.1,3,9),s=w(t,o*.4,100),c=w(t,o*1.4,13);return{light:{bg:w(t,o,96.5),surface:s,sunken:w(t,o,93),border:w(t,o,86),text:w(t,o*1.6,11),muted:w(t,o*1.2,41),accent:O(t,r,"#ffffff",4.5,54,-2),accentText:"#ffffff",danger:O(2,68,"#ffffff",4.5,54,-2),ok:O(148,62,"#ffffff",4.5,44,-2),warn:O(38,88,"#ffffff",4.5,44,-2)},dark:{bg:w(t,o*1.5,9),surface:c,sunken:w(t,o*1.5,7),border:w(t,o*1.3,24),text:w(t,o*.6,95),muted:w(t,o*.8,66),accent:O(t,L(r,40,80),c,4.5,62,2),accentText:w(t,o*2,8),danger:O(2,70,c,4.5,62,2),ok:O(148,55,c,4.5,62,2),warn:O(38,80,c,4.5,62,2)}}}function F(e){return Object.entries(e).map(([t,a])=>`--caf-${t}: ${a};`).join("")}function K(e){let t=te(e);return`
6
+ :root { ${F(t.light)} }
7
+ @media (prefers-color-scheme: dark) { :root { ${F(t.dark)} } }
8
+ :root[data-theme="dark"] { ${F(t.dark)} }
9
+ :root[data-theme="light"] { ${F(t.light)} }
10
+ `}function Ce(e,t){let[a,r]=Ae(P(e||"#3b6ef6")),o=L(r,45,70);return Array.from({length:t},(s,c)=>w((a+c*137.5)%360,o,52))}var re=["system","greeting","placeholder","tools","model","maxTokens"],it="claude-sonnet-4-6",lt=8;async function ft({model:e,maxTokens:t,system:a,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:t,system:a,messages:r,stream:!0})});if(!s.ok||!s.body){let f="";try{let u=await s.json();f=u&&u.error&&u.error.message||JSON.stringify(u)}catch{f=await s.text().catch(()=>"")}throw new Error(`HTTP ${s.status}${f?": "+f:""}`)}let c=s.body.getReader(),i=new TextDecoder,d="",l="";for(;;){let{done:f,value:u}=await c.read();if(f)break;l+=i.decode(u,{stream:!0});let m=l.split(`
11
+ `);l=m.pop();for(let b of m)if(b.startsWith("data: "))try{let h=JSON.parse(b.slice(6));h.type==="content_block_delta"&&h.delta&&h.delta.text&&(d+=h.delta.text,o&&o(d))}catch{}}return d}function dt(e){let t=e.match(/```tool_call\s*\n?([\s\S]*?)```/);if(!t)return null;try{let a=JSON.parse(t[1]);return Array.isArray(a)&&a.length?a:null}catch{return null}}function Te(e){return e.replace(/```tool_call\s*\n?[\s\S]*?```/,"").trim()}function ut(e){return`
12
12
 
13
13
  You have tools available:
14
14
  ${Object.entries(e).map(([a,r])=>`- ${a}: ${r.description}
@@ -21,15 +21,15 @@ This environment does not support native function calling. To use a tool, reply
21
21
  [{ "name": "tool_name", "input": { "param": "value" } }]
22
22
  \`\`\`
23
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 ut(e,t,a){return e.map(r=>{let o=t[r.name];if(!o)return{name:r.name,error:`unknown tool "${r.name}". Valid tools: ${Object.keys(t).join(", ")}`};try{let s=o.run(r.input||{},a);return{name:r.name,result:s===void 0?{ok:!0}:s}}catch(s){return{name:r.name,error:String(s&&s.message||s)}}})}var Ce=e=>String(e).replace(/[&<>"]/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"})[t]);function te(e){let t=[],a=String(e).replace(/```[a-z]*\n?([\s\S]*?)```/g,(r,o)=>(t.push(o.replace(/\n$/,"")),"\0"+(t.length-1)+"\0"));return a=Ce(a),a=a.replace(/`([^`]+)`/g,"<code>$1</code>"),a=a.replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>"),a=a.replace(/(^|[^*])\*([^*\n]+)\*/g,"$1<em>$2</em>"),a=a.replace(/^#{1,3} (.+)$/gm,'<strong class="caf-md-h">$1</strong>'),a=a.replace(/^[-•*] (.+)$/gm,'<span class="caf-md-li">$1</span>'),a=a.replace(/^\d+\. (.+)$/gm,'<span class="caf-md-li caf-md-num">$1</span>'),a=a.replace(/\n/g,"<br>"),a=a.replace(/\u0000(\d+)\u0000/g,(r,o)=>'<pre class="caf-code">'+Ce(t[Number(o)])+"</pre>"),a}function mt({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.")):e.role==="user"?n("div",{className:"caf-msg caf-msg-user"},e.content):n("div",{className:"caf-msg caf-msg-assistant",dangerouslySetInnerHTML:{__html:te(e.content)}})}function re({cfg:e,ctx:t,title:a}){let r=e,[o,s]=v(""),[c,i]=v(!1),[d,l]=v(null),f=ye(null),p=t.data.chat||{api:[],log:[]},u=p.log||[];S(()=>{f.current&&f.current.scrollIntoView({block:"end"})},[u.length,d]);async function b(){let m=o.trim();if(!m||c)return;s(""),i(!0);let w=[...p.api||[],{role:"user",content:m}],x=[...u,{role:"user",content:m}],R=()=>t.update(N=>{N.chat={api:w,log:x}});R();try{let N=(typeof r.system=="function"?r.system(t.data):r.system||"")+(r.tools?dt(r.tools):"");for(let h=0;h<it;h++){let y=await lt({model:r.model||ct,maxTokens:r.maxTokens||2e3,system:N,messages:w,onText:U=>l(Ae(U))});w=[...w,{role:"assistant",content:y}];let C=Ae(y),J=r.tools?ft(y):null;if(!J){x=[...x,{role:"assistant",content:C||y}],R();break}let Ge=ut(J,r.tools,t);C&&(x=[...x,{role:"assistant",content:C}]),x=[...x,{role:"tools",tools:J.map(U=>U.name)}],w=[...w,{role:"user",content:`[TOOL_RESULT]
25
- ${JSON.stringify(Ge)}
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 mt(e,t,a){return e.map(r=>{let o=t[r.name];if(!o)return{name:r.name,error:`unknown tool "${r.name}". Valid tools: ${Object.keys(t).join(", ")}`};try{let s=o.run(r.input||{},a);return{name:r.name,result:s===void 0?{ok:!0}:s}}catch(s){return{name:r.name,error:String(s&&s.message||s)}}})}var je=e=>String(e).replace(/[&<>"]/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"})[t]);function ae(e){let t=[],a=String(e).replace(/```[a-z]*\n?([\s\S]*?)```/g,(r,o)=>(t.push(o.replace(/\n$/,"")),"\0"+(t.length-1)+"\0"));return a=je(a),a=a.replace(/`([^`]+)`/g,"<code>$1</code>"),a=a.replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>"),a=a.replace(/(^|[^*])\*([^*\n]+)\*/g,"$1<em>$2</em>"),a=a.replace(/^#{1,3} (.+)$/gm,'<strong class="caf-md-h">$1</strong>'),a=a.replace(/^[-•*] (.+)$/gm,'<span class="caf-md-li">$1</span>'),a=a.replace(/^\d+\. (.+)$/gm,'<span class="caf-md-li caf-md-num">$1</span>'),a=a.replace(/\n/g,"<br>"),a=a.replace(/\u0000(\d+)\u0000/g,(r,o)=>'<pre class="caf-code">'+je(t[Number(o)])+"</pre>"),a}function pt({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.")):e.role==="user"?n("div",{className:"caf-msg caf-msg-user"},e.content):n("div",{className:"caf-msg caf-msg-assistant",dangerouslySetInnerHTML:{__html:ae(e.content)}})}function ne({cfg:e,ctx:t,title:a}){let r=e,[o,s]=N(""),[c,i]=N(!1),[d,l]=N(null),f=ke(null),u=t.data.chat||{api:[],log:[]},m=u.log||[];T(()=>{f.current&&f.current.scrollIntoView({block:"end"})},[m.length,d]);async function b(){let h=o.trim();if(!h||c)return;s(""),i(!0);let $=[...u.api||[],{role:"user",content:h}],v=[...m,{role:"user",content:h}],E=()=>t.update(S=>{S.chat={api:$,log:v}});E();try{let S=(typeof r.system=="function"?r.system(t.data):r.system||"")+(r.tools?ut(r.tools):"");for(let g=0;g<lt;g++){let y=await ft({model:r.model||it,maxTokens:r.maxTokens||2e3,system:S,messages:$,onText:C=>l(Te(C))});$=[...$,{role:"assistant",content:y}];let p=Te(y),A=r.tools?dt(y):null;if(!A){v=[...v,{role:"assistant",content:p||y}],E();break}let k=mt(A,r.tools,t);p&&(v=[...v,{role:"assistant",content:p}]),v=[...v,{role:"tools",tools:A.map(C=>C.name)}],$=[...$,{role:"user",content:`[TOOL_RESULT]
25
+ ${JSON.stringify(k)}
26
26
  [/TOOL_RESULT]
27
27
 
28
- Continue with this information. If you have everything you need, answer in natural language without further tool_call.`}],R(),l(null)}}catch(N){x=[...x,{role:"error",content:String(N&&N.message||N)}],R()}finally{l(null),i(!1)}}return n("div",{className:"caf-chat-panel"},n("div",{className:"caf-block caf-chat-log"},a?n("h2",{className:"caf-block-title"},a):null,r.greeting?n("div",{className:"caf-msg caf-msg-assistant",dangerouslySetInnerHTML:{__html:te(r.greeting)}}):null,u.map((m,w)=>n(mt,{key:w,m})),d!==null?n("div",{className:"caf-msg caf-msg-assistant caf-msg-live",dangerouslySetInnerHTML:{__html:te(d||"\u2026")}}):null,c&&d===null?n("div",{className:"caf-msg-tools"},"thinking\u2026"):null,n("div",{ref:f})),n("div",{className:"caf-chat-input"},n("input",{value:o,placeholder:r.placeholder||"Message\u2026",disabled:c,enterKeyHint:"send",onChange:m=>s(m.target.value),onKeyDown:m=>{m.key==="Enter"&&(m.preventDefault(),b())},"aria-label":"Message"}),n("button",{type:"button",className:"caf-btn caf-btn-primary",disabled:c||!o.trim(),onClick:b},"Send")))}function Te({spec:e,ctx:t}){return n("div",{className:"caf-panel caf-panel-single"},n(re,{cfg:e.chat,ctx:t}))}var ne=["text","textarea","number","money","percent","check","date","select","file"];function $(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 oe(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 L({field:e,value:t,onChange:a,data:r}){let o=oe(e,t),s=`caf-f-${e.key}`,c=e.type==="number"||e.type==="money"||e.type==="percent";if(e.type==="file")return n("div",{className:"caf-field"},n("label",{htmlFor:s},e.label||e.key),n("input",{id:s,type:"file",accept:e.accept,onChange:l=>a(l.target.files&&l.target.files[0]?l.target.files[0]:null)}),t&&t.name?n("small",{className:"caf-hint"},`${t.name} (${Math.round((t.size||0)/1024)} KB)${t.stale?" \u2014 re-pick after reload":""}`):e.hint?n("small",{className:"caf-hint"},e.hint):null);if(e.type==="check")return n("label",{className:"caf-check"},n("input",{id:s,type:"checkbox",checked:!!t,onChange:l=>a(l.target.checked)}),n("span",null,e.label||e.key));let i={id:s,value:t??"","aria-invalid":o?"true":void 0,onChange:l=>a(c?pt(l.target.value):l.target.value)},d;if(e.type==="textarea")d=n("textarea",{...i,rows:e.rows||3});else if(e.type==="select"){let l=typeof e.options=="function"?e.options(r)||[]:e.options||[];d=n("select",i,n("option",{value:""},e.placeholder||"Select\u2026"),l.map(f=>{let p=typeof f=="string"?f:f.value,u=typeof f=="string"?f:f.label;return n("option",{key:p,value:p},u)}))}else d=n("input",{...i,type:e.type==="date"?"date":c?"number":"text",min:e.min,max:e.max,step:e.step||(e.type==="money"||e.type==="percent"?"any":void 0),placeholder:e.placeholder});return n("div",{className:"caf-field"},n("label",{htmlFor:s},e.label||e.key),d,e.hint&&!o?n("small",{className:"caf-hint"},e.hint):null,o?n("small",{className:"caf-error"},o):null)}function pt(e){if(e==="")return"";let t=Number(e);return Number.isFinite(t)?t:e}function se(e,t,a,r,o){if(a.type==="file"){e.files[t]=r||null;let s=r?{name:r.name,size:r.size,type:r.type}:null;e.update(c=>o(c,s));return}e.update(s=>o(s,r))}function bt({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(L,{key:r.key,field:r,data:t.data,value:t.data[r.key],onChange:o=>se(t,r.key,r,o,(s,c)=>{s[r.key]=c})})))}function ht({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"},$(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 gt({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 yt({spec:e,ctx:t}){let a=(typeof e.list=="function"?e.list(t.data):e.list)||[],r=typeof e.title=="string"?e.title:null,o=typeof e.title=="function"?e.title:s=>s.title??s.name??s.label??s.text??String(s);return a.length?n("div",{className:"caf-block caf-list"},r?n("h2",{className:"caf-block-title"},r):null,a.map((s,c)=>n("button",{key:s.id??c,className:"caf-row",type:"button",onClick:e.onSelect?()=>e.onSelect(s,t):void 0},n("span",{className:"caf-row-title"},o(s)),e.subtitle?n("span",{className:"caf-row-sub"},e.subtitle(s)):null))):n("div",{className:"caf-block caf-empty"},e.empty||"Nothing here yet.")}var Re=["bar","line","donut"];function wt({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"?kt(r,a,s):o==="line"?vt(r,a):xt(r,a,s);return n("div",{className:"caf-block caf-chart"},e.title?n("h2",{className:"caf-block-title"},e.title):null,c)}function kt(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"},$(o.value,t.format)))))}function vt(e,t){let a=e.map(f=>Number(f.value)||0),r=Math.min(...a),s=Math.max(...a)-r||1,c=100,i=36,d=a.map((f,p)=>[a.length===1?c/2:p/(a.length-1)*c,i-3-(f-r)/s*(i-6)]),l=d[d.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(f=>n("line",{key:f,x1:0,x2:c,y1:i*f,y2:i*f,className:"caf-line-grid"})),n("polyline",{points:d.map(f=>f.join(",")).join(" "),className:"caf-line-path"}),n("circle",{cx:l[0],cy:l[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"},$(a[a.length-1],t.format)),n("span",{className:"caf-hint"},String(e[e.length-1].label??""))))}function xt(e,t,a){let r=e.reduce((i,d)=>i+(Number(d.value)||0),0)||1,o=15.9155,s=25,c=e.map((i,d)=>{let l=(Number(i.value)||0)/r*100,f=n("circle",{key:i.label??d,cx:21,cy:21,r:o,className:"caf-donut-seg",stroke:a[d],strokeDasharray:`${l} ${100-l}`,strokeDashoffset:s});return s-=l,f});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,d)=>n("div",{key:i.label??d,className:"caf-legend-row"},n("span",{className:"caf-legend-swatch",style:{background:a[d]}}),n("span",{className:"caf-legend-label"},i.label),n("span",{className:"caf-legend-value"},$(i.value,t.format))))))}function Nt({spec:e,ctx:t}){let a=e.timer||{},r=Math.max(1,Math.round((a.minutes||0)*60+(a.seconds||0))||300),[o,s]=v(r),[c,i]=v(!1);S(()=>{if(!c)return;let p=setInterval(()=>s(u=>Math.max(0,u-1)),1e3);return()=>clearInterval(p)},[c]),S(()=>{o===0&&c&&(i(!1),typeof a.onDone=="function"&&t.update(p=>a.onDone(p)))},[o,c]);let d=String(Math.floor(o/60)).padStart(2,"0"),l=String(o%60).padStart(2,"0"),f=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:f?"caf-timer-time caf-timer-done":"caf-timer-time"},f?a.doneText||"Done!":`${d}:${l}`),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:f,onClick:()=>i(p=>!p)},c?"Pause":"Start"),n("button",{type:"button",className:"caf-btn",onClick:()=>{i(!1),s(r)}},"Reset")))}function St({spec:e,ctx:t}){let r=(e.actions||[]).filter(o=>!o.when||o.when(t.data,t.viewerId));return n("div",{className:"caf-block caf-actions"},e.title?n("h2",{className:"caf-block-title"},e.title):null,n("div",{className:"caf-actions-row"},r.map(o=>n("button",{key:o.label,type:"button",className:o.kind==="danger"?"caf-btn caf-btn-danger":o.kind==="primary"?"caf-btn caf-btn-primary":"caf-btn",onClick:()=>t.update(s=>o.run(s,t.viewerId))},o.label))))}function $t({spec:e,ctx:t}){let a=e.custom(t),r=e.fill?"caf-block caf-block-fill":"caf-block";return typeof a=="string"?n("div",{className:r,dangerouslySetInnerHTML:{__html:a}}):n("div",{className:r},a)}var ce={fields:bt,output:ht,text:gt,list:yt,chart:wt,timer:Nt,actions:St,chat:({spec:e,ctx:t})=>n(re,{cfg:e.chat,ctx:t,title:e.title}),custom:$t},F=Object.keys(ce);function Oe(e){return Object.entries(e.compute||{}).map(([t,a])=>[t,typeof a=="function"?{value:a}:a])}function K(e,t){if(!e.compute)return t;let a={...t};for(let[r,o]of Oe(e))try{a[r]=o.value(t)}catch{a[r]=void 0}return a}function je(e){let t={};for(let a of e)t[a.key]=a.value!==void 0?a.value:a.type==="check"?!1:"";return t}function ie(){return"r"+Date.now().toString(36)+Math.random().toString(36).slice(2,8)}function Et(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 Le({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"},$(r.value,r.format)))))):null}function _e({spec:e,ctx:t}){let a=e.label||"item",[r,o]=v("");S(()=>{(t.data.records||[]).some(l=>l&&!l.id)&&t.update(l=>{for(let f of l.records||[])f&&!f.id&&(f.id=ie())})});let s=t.data.records.map(l=>K(e,l));e.sort&&(s=s.slice().sort(e.sort));let c=s.length,i=r.trim().toLowerCase();e.search&&i&&(s=s.filter(l=>e.fields.some(f=>String(l[f.key]??"").toLowerCase().includes(i))));function d(){let l={id:ie(),...je(e.fields)};e.items&&(l.items=[]),t.update(f=>{f.records=[...f.records,l]}),t.go("record",l.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} ${a}${c===1?"":"s"}`),n("button",{type:"button",className:"caf-btn caf-btn-primary",onClick:d},`Add ${a}`)),e.search?n("input",{className:"caf-search",value:r,placeholder:`Search ${a}s\u2026`,"aria-label":"Search",onChange:l=>o(l.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 ${a}s yet. Add the first one.`):s.map(l=>n("div",{key:l.id,className:"caf-row-wrap"},n("button",{type:"button",className:"caf-row",onClick:()=>t.go("record",l.id)},n("span",{className:"caf-row-title"},Et(e,l)),e.subtitle?n("span",{className:"caf-row-sub"},e.subtitle(l)):null),e.actions?n("div",{className:"caf-row-actions"},e.actions.filter(f=>!f.when||f.when(l,t.viewerId)).map(f=>n("button",{key:f.label,type:"button",className:f.kind==="danger"?"caf-btn caf-btn-danger caf-btn-sm":"caf-btn caf-btn-sm",onClick:()=>t.update(p=>{let u=p.records.find(b=>b.id===l.id);u&&f.run(u,p,t.viewerId)})},f.label))):null)))}function Me({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(L,{key:s.key,field:s,data:t.data,value:a[s.key],onChange:c=>t.update(i=>{let d=i.records.find(l=>l.id===a.id);d&&(d[s.key]=c)})})),e.items?n(At,{spec:e,ctx:t,record:a}):null,e.compute?n("div",{className:"caf-output-grid caf-computed"},Oe(e).map(([s,c])=>{let i=K(e,a);return n("div",{key:s,className:"caf-stat"},n("span",{className:"caf-stat-label"},c.label||s),n("span",{className:"caf-stat-value"},$(i[s],c.format)))})):null)}function At({spec:e,ctx:t,record:a}){let r=e.items,o=r.label||"item";function s(i){t.update(d=>{let l=d.records.find(f=>f.id===a.id);l&&(Array.isArray(l.items)||(l.items=[]),i(l))})}let c=Array.isArray(a.items)?a.items:[];return n("div",{className:"caf-items"},n("div",{className:"caf-toolbar"},n("span",{className:"caf-count"},`${c.length} ${o}${c.length===1?"":"s"}`),n("button",{type:"button",className:"caf-btn caf-btn-sm",onClick:()=>s(i=>i.items.push({id:ie(),...je(r.fields)}))},`Add ${o}`)),c.length===0?n("div",{className:"caf-empty caf-empty-sm"},r.empty||`No ${o}s yet.`):c.map(i=>n("div",{key:i.id,className:"caf-item-row"},r.fields.map(d=>n(L,{key:d.key,field:d,data:t.data,value:i[d.key],onChange:l=>s(f=>{let p=f.items.find(u=>u.id===i.id);p&&(p[d.key]=l)})})),n("button",{type:"button",className:"caf-btn caf-btn-danger caf-btn-sm caf-item-remove","aria-label":`Remove ${o}`,onClick:()=>s(d=>{d.items=d.items.filter(l=>l.id!==i.id)})},"\u2715"))))}function Ct(e,t){return t==="records"?e:new Proxy(e,{get:(a,r,o)=>r==="records"?a[t]:Reflect.get(a,r,o),set:(a,r,o)=>Reflect.set(a,r==="records"?t:r,o),has:(a,r)=>r==="records"?t in a:r in a})}function ze({spec:e,ctx:t}){let a=e.records,r=a.key||"records",o=Array.isArray(t.data[r])?t.data[r]:[],s="caf:rec:"+r,c=t.view.tabs?t.view.tabs[s]:void 0,i={...t,data:{...t.data,records:o},update:l=>t.update(f=>l(Ct(f,r))),go:(l,f)=>t.setTab(s,f),back:()=>t.setTab(s,void 0)},d=c?o.find(l=>l.id===c):null;return n("div",{className:"caf-records-block"},e.title?n("h2",{className:"caf-block-title"},e.title):null,d?n(Me,{key:"d",spec:a,ctx:i,record:d}):[n(Le,{key:"s",spec:a,records:o.map(l=>K(a,l))}),n(_e,{key:"l",spec:a,ctx:i})])}function Be({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(Me,{spec:a,ctx:t,record:r}))}return n("div",{className:"caf-panel caf-panel-single"},n(Le,{spec:a,records:t.data.records.map(r=>K(a,r))}),n(_e,{spec:a,ctx:t}))}function Tt(e,t){return(e.fields||[]).some(a=>oe(a,t[a.key])!==null)}function Rt({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"},$(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 De({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(Rt,{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(L,{key:i.key,field:i,data:t.data,value:t.data[i.key],onChange:d=>se(t,i.key,i,d,(l,f)=>{l[i.key]=f})})),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:Tt(o,t.data),onClick:()=>t.setStep(r+1)},"Next \u203A"))))}var Ie=["panel","records","steps","chat","workspace","documents"],Ot=["title","empty","wide","onSelect","subtitle","when","collapsible","fill"],Ve=["title","subtitle","theme","layout","blocks","records","steps","chat","data","shared","main","sidebar","libs","documents"],Fe=["label","title","blocks","empty"],Ke=["label","fields","title","subtitle","sort","summary","empty","search","compute","items","actions"],Pe=["label","fields","empty"];function Y(e,t){for(let a of e||[]){if(!a||!a.key)throw new Error(`claude-artifact-framework: every field in ${t} needs a \`key\`.`);if(a.type!==void 0&&!ne.includes(a.type))throw new Error(`claude-artifact-framework: field "${a.key}" in ${t} has unknown type "${a.type}". Valid types: ${ne.join(", ")}.`);if(a.type==="select"&&a.options!==void 0&&!Array.isArray(a.options)&&typeof a.options!="function")throw new Error(`claude-artifact-framework: field "${a.key}" in ${t}: \`options\` must be an array or a function of data returning one.`)}}function Je(e,t){if(!e||typeof e.system!="string"&&typeof e.system!="function")throw new Error(`claude-artifact-framework: ${t} needs \`{ system: "..." }\` (a string or a function of data).`);let a=Object.keys(e).filter(r=>!ae.includes(r));if(a.length)throw new Error(`claude-artifact-framework: ${t} has unknown keys (${a.join(", ")}). Valid keys: ${ae.join(", ")}.`);for(let[r,o]of Object.entries(e.tools||{}))if(!o||typeof o.description!="string"||typeof o.run!="function")throw new Error(`claude-artifact-framework: chat tool "${r}" needs a \`description\` string and a \`run(input, ctx)\` function.`)}var Ye=["label","run","when","kind"];function Ue(e,t){if(!Array.isArray(e))throw new Error(`claude-artifact-framework: ${t} must be an array of { label, run }.`);e.forEach((a,r)=>{if(!a||typeof a.label!="string"||typeof a.run!="function")throw new Error(`claude-artifact-framework: ${t}[${r}] needs a \`label\` string and a \`run\` function.`);let o=Object.keys(a).filter(s=>!Ye.includes(s));if(o.length)throw new Error(`claude-artifact-framework: ${t}[${r}] has unknown keys (${o.join(", ")}). Valid keys: ${Ye.join(", ")}.`)})}function _(e){if(!Array.isArray(e))throw new Error("claude-artifact-framework: `blocks` must be an array.");e.forEach((t,a)=>{if(!t||typeof t!="object")throw new Error(`claude-artifact-framework: blocks[${a}] must be an object like { fields: [...] }.`);let r=Object.keys(t).filter(s=>!Ot.includes(s)),o=r.filter(s=>F.includes(s)||s==="tabs"||s==="records");if(o.length===0)throw new Error(`claude-artifact-framework: blocks[${a}] has no recognised block type (found: ${r.join(", ")||"nothing"}). Valid block types: ${[...F,"tabs","records"].join(", ")}.`);if(o.length>1)throw new Error(`claude-artifact-framework: blocks[${a}] declares more than one block type (${o.join(", ")}). Split them into separate entries of \`blocks\`.`);if(Y(t.fields,`blocks[${a}]`),o[0]==="actions"&&Ue(t.actions,`blocks[${a}].actions`),o[0]==="chat"&&Je(t.chat,`blocks[${a}].chat`),o[0]==="records"&&qe(t.records,`blocks[${a}].records`,!0),o[0]==="tabs"){let s=t.tabs;if(!Array.isArray(s)||s.length===0)throw new Error(`claude-artifact-framework: blocks[${a}].tabs needs an array of { label, blocks: [...] }.`);s.forEach((c,i)=>{if(!c||typeof c.label!="string"||!Array.isArray(c.blocks)||c.blocks.length===0)throw new Error(`claude-artifact-framework: tabs[${i}] needs a \`label\` string and a non-empty \`blocks\` array.`);if(c.blocks.some(d=>d&&d.tabs))throw new Error("claude-artifact-framework: tabs cannot nest inside tabs.");_(c.blocks)})}if(t.when!==void 0&&typeof t.when!="function")throw new Error(`claude-artifact-framework: blocks[${a}].when must be a function of data returning true/false.`);if(t.fill!==void 0&&o[0]!=="custom")throw new Error(`claude-artifact-framework: \`fill\` is only valid on custom blocks \u2014 blocks[${a}] is "${o[0]}".`)})}function jt(e){let t=Object.keys(e).filter(r=>!Ve.includes(r));if(t.length)throw new Error(`claude-artifact-framework: unknown top-level keys (${t.join(", ")}). Valid keys: ${Ve.join(", ")}.`);if(e.libs!==void 0&&(!Array.isArray(e.libs)||e.libs.some(r=>typeof r!="string"||!/^https?:\/\//.test(r))))throw new Error("claude-artifact-framework: `libs` must be an array of https:// script URLs.");let a=e.layout||"panel";if(!Ie.includes(a))throw new Error(`claude-artifact-framework: unknown layout "${a}". Valid layouts: ${Ie.join(", ")}.`);if(a==="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 d=Object.keys(c).filter(l=>!o.includes(l));if(d.length)throw new Error(`claude-artifact-framework: steps[${i}] has unknown keys (${d.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\`.`);Y(c.fields,`steps[${i}]`);for(let l of c.fields||[]){if(s.has(l.key))throw new Error(`claude-artifact-framework: field key "${l.key}" appears in more than one step \u2014 keys share one data pool and must be unique.`);s.add(l.key)}}),a}if(a==="chat")return Je(e.chat,"chat"),a;if(a==="workspace"){if(!Array.isArray(e.main)||e.main.length===0)throw new Error('claude-artifact-framework: layout "workspace" needs `main: [...]` (an array of blocks). `sidebar: [...]` is optional.');if(_(e.main),e.sidebar!==void 0){if(!Array.isArray(e.sidebar))throw new Error("claude-artifact-framework: workspace `sidebar` must be an array of blocks.");_(e.sidebar)}let r=A([...e.main,...e.sidebar||[]]);if(r.filter(s=>s&&s.chat).length>1)throw new Error("claude-artifact-framework: only one chat block per app \u2014 the conversation persists under data.chat and there is exactly one.");return le(r),a}if(a==="documents"){let r=e.documents;if(!r||!Array.isArray(r.blocks)||r.blocks.length===0)throw new Error('claude-artifact-framework: layout "documents" needs `documents: { blocks: [...] }` \u2014 the blocks every document repeats, each with its own data.');let o=Object.keys(r).filter(i=>!Fe.includes(i));if(o.length)throw new Error(`claude-artifact-framework: documents has unknown keys (${o.join(", ")}). Valid keys: ${Fe.join(", ")}.`);if(r.title!==void 0&&typeof r.title!="function")throw new Error("claude-artifact-framework: documents.title must be a function of the document's data returning the tab label.");_(r.blocks);let s=A(r.blocks);if(s.filter(i=>i&&i.chat).length>1)throw new Error("claude-artifact-framework: only one chat block per document \u2014 each document's conversation persists under its own data.chat and there is exactly one.");return le(s),a}if(a==="records"){if(qe(e.records,"records",!1),e.blocks&&(_(e.blocks),A(e.blocks).some(r=>r&&r.records)))throw new Error("claude-artifact-framework: a records BLOCK below a records LAYOUT is ambiguous \u2014 the layout already owns the collection. Use panel/workspace/documents to embed records blocks.");return a}return _(e.blocks||[]),le(A(e.blocks||[])),a}function qe(e,t,a){if(!e||!Array.isArray(e.fields)||e.fields.length===0)throw new Error(`claude-artifact-framework: ${t} needs \`records: { fields: [...] }\` \u2014 the same field declarations the fields block uses.`);let r=a?[...Ke,"key"]:Ke,o=Object.keys(e).filter(c=>!r.includes(c));if(o.length)throw new Error(`claude-artifact-framework: ${t} has unknown keys (${o.join(", ")}). Valid keys: ${r.join(", ")}.`);if(a&&e.key!==void 0&&(typeof e.key!="string"||!e.key))throw new Error(`claude-artifact-framework: ${t}.key must be a non-empty string naming the collection in data.`);if(Y(e.fields,t),e.fields.some(c=>c.type==="file")||e.items&&e.items.fields.some(c=>c.type==="file"))throw new Error("claude-artifact-framework: `file` fields live in the flat data pool (panel blocks or steps) \u2014 they are not supported inside records or items.");let s=new Set;for(let c of e.fields){if(c.key==="id")throw new Error('claude-artifact-framework: "id" is reserved on records \u2014 the framework assigns it.');if(s.has(c.key))throw new Error(`claude-artifact-framework: duplicate ${t} field key "${c.key}".`);s.add(c.key)}if(e.actions&&Ue(e.actions,`${t}.actions`),e.items){let c=Object.keys(e.items).filter(i=>!Pe.includes(i));if(c.length)throw new Error(`claude-artifact-framework: ${t}.items has unknown keys (${c.join(", ")}). Valid keys: ${Pe.join(", ")}.`);if(!Array.isArray(e.items.fields)||e.items.fields.length===0)throw new Error(`claude-artifact-framework: ${t}.items needs \`fields: [...]\` \u2014 the same field declarations as everywhere else.`);Y(e.items.fields,`${t}.items`);for(let i of e.items.fields)if(i.key==="id")throw new Error('claude-artifact-framework: "id" is reserved on items \u2014 the framework assigns it.');if(s.has("items")||e.fields.some(i=>i.key==="items"))throw new Error(`claude-artifact-framework: a ${t} field cannot be named "items" when \`items\` is declared \u2014 that key holds the child collection.`)}for(let[c,i]of Object.entries(e.compute||{})){if(s.has(c)||c==="id"||e.items&&c==="items")throw new Error(`claude-artifact-framework: compute key "${c}" collides with a field key \u2014 computed values are derived, never stored.`);if(typeof i!="function"&&typeof(i&&i.value)!="function")throw new Error(`claude-artifact-framework: compute "${c}" must be a function of the record, or { label, format, value: (r) => ... }.`)}}function le(e){let t=new Set;for(let a of e){if(!a||!a.records)continue;let r=a.records.key||"records";if(t.has(r))throw new Error(`claude-artifact-framework: two records blocks share the collection key "${r}" \u2014 give each a distinct \`key\`.`);t.add(r)}}function A(e){let t=[];for(let a of e||[])if(t.push(a),a&&Array.isArray(a.tabs))for(let r of a.tabs)t.push(...A(r.blocks));return t}function Lt(e){let t={...e.data||{}};(e.layout||"panel")==="records"&&!Array.isArray(t.records)&&(t.records=[]),(e.layout||"panel")==="documents"&&!Array.isArray(t.docs)&&(t.docs=[]);let a=A([...e.blocks||[],...e.main||[],...e.sidebar||[]]);((e.layout||"panel")==="chat"||a.some(o=>o&&o.chat))&&!t.chat&&(t.chat={api:[],log:[]});for(let o of[...a,...e.steps||[]])for(let s of o.fields||[])s&&s.key!==void 0&&!(s.key in t)&&(t[s.key]=s.value!==void 0?s.value:s.type==="check"?!1:"");for(let o of a)if(o&&o.records){let s=o.records.key||"records";Array.isArray(t[s])||(t[s]=[])}return t}var fe=null;function _t(e){return fe||(fe=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}}),fe}function Mt({spec:e,ctx:t}){let a=e.tabs,r=a.map(c=>c.label).join("|"),o=t.view.tabs?t.view.tabs[r]:void 0,s=Math.min(o===void 0?0:o,a.length-1);return n("div",{className:"caf-tabs"},n("div",{className:"caf-tabbar",role:"tablist"},a.map((c,i)=>n("button",{key:c.label,type:"button",role:"tab","aria-selected":i===s,className:i===s?"caf-tab caf-tab-active":"caf-tab",onClick:()=>t.setTab(r,i)},c.label))),n("div",{className:"caf-tabs-body"},a[s].blocks.map((c,i)=>n(H,{key:s+":"+i,block:c,ctx:t}))))}var zt={...ce,tabs:Mt,records:ze},Bt=[...F,"tabs","records"];function H({block:e,ctx:t}){if(typeof e.when=="function"&&!e.when(t.data))return null;let a=Object.keys(e).find(i=>Bt.includes(i)),r=zt[a],o=n(_t(t.React),null,n(r,{spec:e.collapsible?{...e,title:void 0}:e,ctx:t}));if(!e.collapsible)return o;let s=typeof e.title=="string"&&e.title?e.title:a,c=t.view.collapsed&&s in t.view.collapsed?t.view.collapsed[s]:e.collapsible==="collapsed";return n("div",{className:"caf-collapse"},n("button",{type:"button",className:"caf-collapse-head","aria-expanded":!c,onClick:()=>t.toggleCollapsed(s,!c)},n("span",null,e.title||a),n("span",{className:c?"caf-chevron caf-chevron-closed":"caf-chevron"},"\u25BE")),c?null:n("div",{className:"caf-collapse-body"},o))}function We({spec:e,ctx:t}){return n("div",{className:"caf-panel"},(e.blocks||[]).map((a,r)=>n("section",{key:r,className:a.wide||a.collapsible?"caf-slot caf-slot-wide":"caf-slot"},n(H,{block:a,ctx:t}))))}function Dt({spec:e,ctx:t}){let a=t.view.screen==="record"&&(t.data.records||[]).some(r=>r.id===t.view.arg);return n("div",null,n(Be,{spec:e,ctx:t}),!a&&Array.isArray(e.blocks)&&e.blocks.length?n("div",{className:"caf-panel caf-records-blocks"},e.blocks.map((r,o)=>n("section",{key:o,className:r.wide||r.collapsible?"caf-slot caf-slot-wide":"caf-slot"},n(H,{block:r,ctx:t})))):null)}function It({spec:e,ctx:t}){let a=r=>(r||[]).map((o,s)=>n("section",{key:s,className:"caf-ws-slot"},n(H,{block:o,ctx:t})));return n("div",{className:"caf-workspace"},n("div",{className:"caf-ws-main"},a(e.main)),e.sidebar&&e.sidebar.length?n("div",{className:"caf-ws-side"},a(e.sidebar)):null)}function He(e){let t={};for(let a of A(e.blocks)){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:"");if(a.records){let r=a.records.key||"records";Array.isArray(t[r])||(t[r]=[])}}return t}function Vt(){return"d"+Date.now().toString(36)+Math.random().toString(36).slice(2,8)}var P="caf:doc";function Ft(e,t){if(e.title)try{let a=e.title(t);if(a!=null&&a!=="")return String(a)}catch{}for(let a of A(e.blocks))for(let r of a.fields||[])if(!r.type||r.type==="text"||r.type==="textarea"||r.type==="select"){let o=t[r.key];return o!==""&&o!==void 0&&o!==null?String(o):"(untitled)"}return"(untitled)"}function Kt({spec:e,ctx:t}){let a=e.documents,r=a.label||"document",o=Array.isArray(t.data.docs)?t.data.docs:[],s=He(a),c=t.view.tabs?t.view.tabs[P]:void 0,i=o.find(u=>u.id===c)||o[0];function d(){let u={id:Vt(),data:He(a)};t.update(b=>{b.docs=[...b.docs||[],u]}),t.setTab(P,u.id)}function l(u){let b=o.findIndex(m=>m.id===u);if(t.update(m=>{m.docs=m.docs.filter(w=>w.id!==u)}),delete t.files["doc:"+u],i&&i.id===u){let m=o[b+1]||o[b-1];m&&t.setTab(P,m.id)}}if(!i)return n("div",{className:"caf-panel caf-panel-single"},n("div",{className:"caf-block caf-empty"},n("p",null,a.empty||`No ${r}s yet. Create the first one.`),n("button",{type:"button",className:"caf-btn caf-btn-primary",onClick:d},`New ${r}`)));let f={...s,...i.data},p={...t,data:f,update:u=>t.update(b=>{let m=(b.docs||[]).find(w=>w.id===i.id);m&&u(m.data)}),files:t.files["doc:"+i.id]=t.files["doc:"+i.id]||{}};return n("div",{className:"caf-documents"},n("div",{className:"caf-tabbar",role:"tablist"},o.map(u=>n("span",{key:u.id,className:"caf-doc-tab"},n("button",{type:"button",role:"tab","aria-selected":u.id===i.id,className:u.id===i.id?"caf-tab caf-tab-active":"caf-tab",onClick:()=>t.setTab(P,u.id)},Ft(a,{...s,...u.data})),n("button",{type:"button",className:"caf-doc-close","aria-label":`Close ${r}`,onClick:()=>l(u.id)},"\u2715"))),n("button",{type:"button",className:"caf-tab caf-doc-add","aria-label":`New ${r}`,onClick:d},"+")),n(We,{spec:{blocks:a.blocks},ctx:p}))}var Pt={panel:We,records:Dt,steps:De,chat:Te,workspace:It,documents:Kt};function Xe(e){return new Promise((t,a)=>{let r=document.querySelector(`script[src="${e}"]`);if(r){if(r.dataset.cafReady==="1")return t();r.addEventListener("load",t),r.addEventListener("error",()=>a(new Error(`failed to load ${e}`)));return}let o=document.createElement("script");o.src=e,o.onload=()=>{o.dataset.cafReady="1",t()},o.onerror=()=>{let s=e.match(/^(https:\/\/cdn\.jsdelivr\.net\/npm\/(?:@[^/]+\/)?[^/]+)\/.+/);s&&s[1]!==e?Xe(s[1]).then(t,()=>a(new Error(`failed to load ${e} (also tried package default ${s[1]})`))):a(new Error(`failed to load ${e}`))},document.head.appendChild(o)})}function Qe(e={}){let t=jt(e),a=Ne(Lt(e),{shared:!!e.shared}),r=V(e.theme&&e.theme.seed)+Yt,o={};return function(){if(!z())throw new Error(`claude-artifact-framework: React not found. Hand it over once, before rendering:
28
+ Continue with this information. If you have everything you need, answer in natural language without further tool_call.`}],E(),l(null)}}catch(S){v=[...v,{role:"error",content:String(S&&S.message||S)}],E()}finally{l(null),i(!1)}}return n("div",{className:"caf-chat-panel"},n("div",{className:"caf-block caf-chat-log"},a?n("h2",{className:"caf-block-title"},a):null,r.greeting?n("div",{className:"caf-msg caf-msg-assistant",dangerouslySetInnerHTML:{__html:ae(r.greeting)}}):null,m.map((h,$)=>n(pt,{key:$,m:h})),d!==null?n("div",{className:"caf-msg caf-msg-assistant caf-msg-live",dangerouslySetInnerHTML:{__html:ae(d||"\u2026")}}):null,c&&d===null?n("div",{className:"caf-msg-tools"},"thinking\u2026"):null,n("div",{ref:f})),n("div",{className:"caf-chat-input"},n("input",{value:o,placeholder:r.placeholder||"Message\u2026",disabled:c,enterKeyHint:"send",onChange:h=>s(h.target.value),onKeyDown:h=>{h.key==="Enter"&&(h.preventDefault(),b())},"aria-label":"Message"}),n("button",{type:"button",className:"caf-btn caf-btn-primary",disabled:c||!o.trim(),onClick:b},"Send")))}function Oe({spec:e,ctx:t}){return n("div",{className:"caf-panel caf-panel-single"},n(ne,{cfg:e.chat,ctx:t}))}var oe=["text","textarea","number","money","percent","check","date","select","file"];function j(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 se(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 z({field:e,value:t,onChange:a,data:r}){let o=se(e,t),s=`caf-f-${e.key}`,c=e.type==="number"||e.type==="money"||e.type==="percent";if(e.type==="file")return n("div",{className:"caf-field"},n("label",{htmlFor:s},e.label||e.key),n("input",{id:s,type:"file",accept:e.accept,onChange:l=>a(l.target.files&&l.target.files[0]?l.target.files[0]:null)}),t&&t.name?n("small",{className:"caf-hint"},`${t.name} (${Math.round((t.size||0)/1024)} KB)${t.stale?" \u2014 re-pick after reload":""}`):e.hint?n("small",{className:"caf-hint"},e.hint):null);if(e.type==="check")return n("label",{className:"caf-check"},n("input",{id:s,type:"checkbox",checked:!!t,onChange:l=>a(l.target.checked)}),n("span",null,e.label||e.key));let i={id:s,value:t??"","aria-invalid":o?"true":void 0,onChange:l=>a(c?bt(l.target.value):l.target.value)},d;if(e.type==="textarea")d=n("textarea",{...i,rows:e.rows||3});else if(e.type==="select"){let l=typeof e.options=="function"?e.options(r)||[]:e.options||[];d=n("select",i,n("option",{value:""},e.placeholder||"Select\u2026"),l.map(f=>{let u=typeof f=="string"?f:f.value,m=typeof f=="string"?f:f.label;return n("option",{key:u,value:u},m)}))}else d=n("input",{...i,type:e.type==="date"?"date":c?"number":"text",min:e.min,max:e.max,step:e.step||(e.type==="money"||e.type==="percent"?"any":void 0),placeholder:e.placeholder});return n("div",{className:"caf-field"},n("label",{htmlFor:s},e.label||e.key),d,e.hint&&!o?n("small",{className:"caf-hint"},e.hint):null,o?n("small",{className:"caf-error"},o):null)}function bt(e){if(e==="")return"";let t=Number(e);return Number.isFinite(t)?t:e}function ce(e,t,a,r,o){if(a.type==="file"){e.files[t]=r||null;let s=r?{name:r.name,size:r.size,type:r.type}:null;e.update(c=>o(c,s));return}e.update(s=>o(s,r))}function ht({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(z,{key:r.key,field:r,data:t.data,value:t.data[r.key],onChange:o=>ce(t,r.key,r,o,(s,c)=>{s[r.key]=c})})))}function gt({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"},j(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 yt({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 wt({spec:e,ctx:t}){let a=(typeof e.list=="function"?e.list(t.data):e.list)||[],r=typeof e.title=="string"?e.title:null,o=typeof e.title=="function"?e.title:s=>s.title??s.name??s.label??s.text??String(s);return a.length?n("div",{className:"caf-block caf-list"},r?n("h2",{className:"caf-block-title"},r):null,a.map((s,c)=>n("button",{key:s.id??c,className:"caf-row",type:"button",onClick:e.onSelect?()=>e.onSelect(s,t):void 0},n("span",{className:"caf-row-title"},o(s)),e.subtitle?n("span",{className:"caf-row-sub"},e.subtitle(s)):null))):n("div",{className:"caf-block caf-empty"},e.empty||"Nothing here yet.")}var Re=["bar","line","donut"];function kt({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"?vt(r,a,s):o==="line"?xt(r,a):Nt(r,a,s);return n("div",{className:"caf-block caf-chart"},e.title?n("h2",{className:"caf-block-title"},e.title):null,c)}function vt(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"},j(o.value,t.format)))))}function xt(e,t){let a=e.map(f=>Number(f.value)||0),r=Math.min(...a),s=Math.max(...a)-r||1,c=100,i=36,d=a.map((f,u)=>[a.length===1?c/2:u/(a.length-1)*c,i-3-(f-r)/s*(i-6)]),l=d[d.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(f=>n("line",{key:f,x1:0,x2:c,y1:i*f,y2:i*f,className:"caf-line-grid"})),n("polyline",{points:d.map(f=>f.join(",")).join(" "),className:"caf-line-path"}),n("circle",{cx:l[0],cy:l[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"},j(a[a.length-1],t.format)),n("span",{className:"caf-hint"},String(e[e.length-1].label??""))))}function Nt(e,t,a){let r=e.reduce((i,d)=>i+(Number(d.value)||0),0)||1,o=15.9155,s=25,c=e.map((i,d)=>{let l=(Number(i.value)||0)/r*100,f=n("circle",{key:i.label??d,cx:21,cy:21,r:o,className:"caf-donut-seg",stroke:a[d],strokeDasharray:`${l} ${100-l}`,strokeDashoffset:s});return s-=l,f});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,d)=>n("div",{key:i.label??d,className:"caf-legend-row"},n("span",{className:"caf-legend-swatch",style:{background:a[d]}}),n("span",{className:"caf-legend-label"},i.label),n("span",{className:"caf-legend-value"},j(i.value,t.format))))))}function $t({spec:e,ctx:t}){let a=e.timer||{},r=Math.max(1,Math.round((a.minutes||0)*60+(a.seconds||0))||300),[o,s]=N(r),[c,i]=N(!1);T(()=>{if(!c)return;let u=setInterval(()=>s(m=>Math.max(0,m-1)),1e3);return()=>clearInterval(u)},[c]),T(()=>{o===0&&c&&(i(!1),typeof a.onDone=="function"&&t.update(u=>a.onDone(u)))},[o,c]);let d=String(Math.floor(o/60)).padStart(2,"0"),l=String(o%60).padStart(2,"0"),f=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:f?"caf-timer-time caf-timer-done":"caf-timer-time"},f?a.doneText||"Done!":`${d}:${l}`),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:f,onClick:()=>i(u=>!u)},c?"Pause":"Start"),n("button",{type:"button",className:"caf-btn",onClick:()=>{i(!1),s(r)}},"Reset")))}function St({spec:e,ctx:t}){let r=(e.actions||[]).filter(o=>!o.when||o.when(t.data,t.viewerId));return n("div",{className:"caf-block caf-actions"},e.title?n("h2",{className:"caf-block-title"},e.title):null,n("div",{className:"caf-actions-row"},r.map(o=>n("button",{key:o.label,type:"button",className:o.kind==="danger"?"caf-btn caf-btn-danger":o.kind==="primary"?"caf-btn caf-btn-primary":"caf-btn",onClick:()=>t.update(s=>o.run(s,t.viewerId))},o.label))))}function Et({spec:e,ctx:t}){let a=e.custom(t),r=e.fill?"caf-block caf-block-fill":"caf-block";return typeof a=="string"?n("div",{className:r,dangerouslySetInnerHTML:{__html:a}}):n("div",{className:r},a)}var ie={fields:ht,output:gt,text:yt,list:wt,chart:kt,timer:$t,actions:St,chat:({spec:e,ctx:t})=>n(ne,{cfg:e.chat,ctx:t,title:e.title}),custom:Et},Y=Object.keys(ie);function Le(e){return Object.entries(e.compute||{}).map(([t,a])=>[t,typeof a=="function"?{value:a}:a])}function H(e,t){if(!e.compute)return t;let a={...t};for(let[r,o]of Le(e))try{a[r]=o.value(t)}catch{a[r]=void 0}return a}function _e(e){let t={};for(let a of e)t[a.key]=a.value!==void 0?a.value:a.type==="check"?!1:"";return t}function le(){return"r"+Date.now().toString(36)+Math.random().toString(36).slice(2,8)}function At(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"},j(r.value,r.format)))))):null}function ze({spec:e,ctx:t}){let a=e.label||"item",[r,o]=N("");T(()=>{(t.data.records||[]).some(l=>l&&!l.id)&&t.update(l=>{for(let f of l.records||[])f&&!f.id&&(f.id=le())})});let s=t.data.records.map(l=>H(e,l));e.sort&&(s=s.slice().sort(e.sort));let c=s.length,i=r.trim().toLowerCase();e.search&&i&&(s=s.filter(l=>e.fields.some(f=>String(l[f.key]??"").toLowerCase().includes(i))));function d(){let l={id:le(),..._e(e.fields)};e.items&&(l.items=[]),t.update(f=>{f.records=[...f.records,l]}),t.go("record",l.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} ${a}${c===1?"":"s"}`),n("button",{type:"button",className:"caf-btn caf-btn-primary",onClick:d},`Add ${a}`)),e.search?n("input",{className:"caf-search",value:r,placeholder:`Search ${a}s\u2026`,"aria-label":"Search",onChange:l=>o(l.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 ${a}s yet. Add the first one.`):s.map(l=>n("div",{key:l.id,className:"caf-row-wrap"},n("button",{type:"button",className:"caf-row",onClick:()=>t.go("record",l.id)},n("span",{className:"caf-row-title"},At(e,l)),e.subtitle?n("span",{className:"caf-row-sub"},e.subtitle(l)):null),e.actions?n("div",{className:"caf-row-actions"},e.actions.filter(f=>!f.when||f.when(l,t.viewerId)).map(f=>n("button",{key:f.label,type:"button",className:f.kind==="danger"?"caf-btn caf-btn-danger caf-btn-sm":"caf-btn caf-btn-sm",onClick:()=>t.update(u=>{let m=u.records.find(b=>b.id===l.id);m&&f.run(m,u,t.viewerId)})},f.label))):null)))}function Be({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(z,{key:s.key,field:s,data:t.data,value:a[s.key],onChange:c=>t.update(i=>{let d=i.records.find(l=>l.id===a.id);d&&(d[s.key]=c)})})),e.items?n(Ct,{spec:e,ctx:t,record:a}):null,e.compute?n("div",{className:"caf-output-grid caf-computed"},Le(e).map(([s,c])=>{let i=H(e,a);return n("div",{key:s,className:"caf-stat"},n("span",{className:"caf-stat-label"},c.label||s),n("span",{className:"caf-stat-value"},j(i[s],c.format)))})):null)}function Ct({spec:e,ctx:t,record:a}){let r=e.items,o=r.label||"item";function s(i){t.update(d=>{let l=d.records.find(f=>f.id===a.id);l&&(Array.isArray(l.items)||(l.items=[]),i(l))})}let c=Array.isArray(a.items)?a.items:[];return n("div",{className:"caf-items"},n("div",{className:"caf-toolbar"},n("span",{className:"caf-count"},`${c.length} ${o}${c.length===1?"":"s"}`),n("button",{type:"button",className:"caf-btn caf-btn-sm",onClick:()=>s(i=>i.items.push({id:le(),..._e(r.fields)}))},`Add ${o}`)),c.length===0?n("div",{className:"caf-empty caf-empty-sm"},r.empty||`No ${o}s yet.`):c.map(i=>n("div",{key:i.id,className:"caf-item-row"},r.fields.map(d=>n(z,{key:d.key,field:d,data:t.data,value:i[d.key],onChange:l=>s(f=>{let u=f.items.find(m=>m.id===i.id);u&&(u[d.key]=l)})})),n("button",{type:"button",className:"caf-btn caf-btn-danger caf-btn-sm caf-item-remove","aria-label":`Remove ${o}`,onClick:()=>s(d=>{d.items=d.items.filter(l=>l.id!==i.id)})},"\u2715"))))}function Tt(e,t){return t==="records"?e:new Proxy(e,{get:(a,r,o)=>r==="records"?a[t]:Reflect.get(a,r,o),set:(a,r,o)=>Reflect.set(a,r==="records"?t:r,o),has:(a,r)=>r==="records"?t in a:r in a})}function De({spec:e,ctx:t}){let a=e.records,r=a.key||"records",o=Array.isArray(t.data[r])?t.data[r]:[],s="caf:rec:"+r,c=t.view.tabs?t.view.tabs[s]:void 0,i={...t,data:{...t.data,records:o},update:l=>t.update(f=>l(Tt(f,r))),go:(l,f)=>t.setTab(s,f),back:()=>t.setTab(s,void 0)},d=c?o.find(l=>l.id===c):null;return n("div",{className:"caf-records-block"},e.title?n("h2",{className:"caf-block-title"},e.title):null,d?n(Be,{key:"d",spec:a,ctx:i,record:d}):[n(Me,{key:"s",spec:a,records:o.map(l=>H(a,l))}),n(ze,{key:"l",spec:a,ctx:i})])}function Ie({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(Be,{spec:a,ctx:t,record:r}))}return n("div",{className:"caf-panel caf-panel-single"},n(Me,{spec:a,records:t.data.records.map(r=>H(a,r))}),n(ze,{spec:a,ctx:t}))}function jt(e,t){return(e.fields||[]).some(a=>se(a,t[a.key])!==null)}function Ot({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"},j(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 Ve({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(Ot,{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(z,{key:i.key,field:i,data:t.data,value:t.data[i.key],onChange:d=>ce(t,i.key,i,d,(l,f)=>{l[i.key]=f})})),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:jt(o,t.data),onClick:()=>t.setStep(r+1)},"Next \u203A"))))}var Fe=["panel","records","steps","chat","workspace","documents"],Rt=["title","empty","wide","onSelect","subtitle","when","collapsible","fill"],Pe=["title","subtitle","theme","layout","blocks","records","steps","chat","data","shared","main","sidebar","libs","documents"],Ke=["label","title","blocks","empty","types"],Ye=["label","fields","title","subtitle","sort","summary","empty","search","compute","items","actions"],He=["label","fields","empty"];function U(e,t){for(let a of e||[]){if(!a||!a.key)throw new Error(`claude-artifact-framework: every field in ${t} needs a \`key\`.`);if(a.type!==void 0&&!oe.includes(a.type))throw new Error(`claude-artifact-framework: field "${a.key}" in ${t} has unknown type "${a.type}". Valid types: ${oe.join(", ")}.`);if(a.type==="select"&&a.options!==void 0&&!Array.isArray(a.options)&&typeof a.options!="function")throw new Error(`claude-artifact-framework: field "${a.key}" in ${t}: \`options\` must be an array or a function of data returning one.`)}}function qe(e,t){if(!e||typeof e.system!="string"&&typeof e.system!="function")throw new Error(`claude-artifact-framework: ${t} needs \`{ system: "..." }\` (a string or a function of data).`);let a=Object.keys(e).filter(r=>!re.includes(r));if(a.length)throw new Error(`claude-artifact-framework: ${t} has unknown keys (${a.join(", ")}). Valid keys: ${re.join(", ")}.`);for(let[r,o]of Object.entries(e.tools||{}))if(!o||typeof o.description!="string"||typeof o.run!="function")throw new Error(`claude-artifact-framework: chat tool "${r}" needs a \`description\` string and a \`run(input, ctx)\` function.`)}var Je=["label","run","when","kind"];function We(e,t){if(!Array.isArray(e))throw new Error(`claude-artifact-framework: ${t} must be an array of { label, run }.`);e.forEach((a,r)=>{if(!a||typeof a.label!="string"||typeof a.run!="function")throw new Error(`claude-artifact-framework: ${t}[${r}] needs a \`label\` string and a \`run\` function.`);let o=Object.keys(a).filter(s=>!Je.includes(s));if(o.length)throw new Error(`claude-artifact-framework: ${t}[${r}] has unknown keys (${o.join(", ")}). Valid keys: ${Je.join(", ")}.`)})}function B(e){if(!Array.isArray(e))throw new Error("claude-artifact-framework: `blocks` must be an array.");e.forEach((t,a)=>{if(!t||typeof t!="object")throw new Error(`claude-artifact-framework: blocks[${a}] must be an object like { fields: [...] }.`);let r=Object.keys(t).filter(s=>!Rt.includes(s)),o=r.filter(s=>Y.includes(s)||s==="tabs"||s==="records");if(o.length===0)throw new Error(`claude-artifact-framework: blocks[${a}] has no recognised block type (found: ${r.join(", ")||"nothing"}). Valid block types: ${[...Y,"tabs","records"].join(", ")}.`);if(o.length>1)throw new Error(`claude-artifact-framework: blocks[${a}] declares more than one block type (${o.join(", ")}). Split them into separate entries of \`blocks\`.`);if(U(t.fields,`blocks[${a}]`),o[0]==="actions"&&We(t.actions,`blocks[${a}].actions`),o[0]==="chat"&&qe(t.chat,`blocks[${a}].chat`),o[0]==="records"&&Xe(t.records,`blocks[${a}].records`,!0),o[0]==="tabs"){let s=t.tabs;if(!Array.isArray(s)||s.length===0)throw new Error(`claude-artifact-framework: blocks[${a}].tabs needs an array of { label, blocks: [...] }.`);s.forEach((c,i)=>{if(!c||typeof c.label!="string"||!Array.isArray(c.blocks)||c.blocks.length===0)throw new Error(`claude-artifact-framework: tabs[${i}] needs a \`label\` string and a non-empty \`blocks\` array.`);if(c.blocks.some(d=>d&&d.tabs))throw new Error("claude-artifact-framework: tabs cannot nest inside tabs.");B(c.blocks)})}if(t.when!==void 0&&typeof t.when!="function")throw new Error(`claude-artifact-framework: blocks[${a}].when must be a function of data returning true/false.`);if(t.fill!==void 0&&o[0]!=="custom")throw new Error(`claude-artifact-framework: \`fill\` is only valid on custom blocks \u2014 blocks[${a}] is "${o[0]}".`)})}function Lt(e){let t=Object.keys(e).filter(r=>!Pe.includes(r));if(t.length)throw new Error(`claude-artifact-framework: unknown top-level keys (${t.join(", ")}). Valid keys: ${Pe.join(", ")}.`);if(e.libs!==void 0&&(!Array.isArray(e.libs)||e.libs.some(r=>typeof r!="string"||!/^https?:\/\//.test(r))))throw new Error("claude-artifact-framework: `libs` must be an array of https:// script URLs.");let a=e.layout||"panel";if(!Fe.includes(a))throw new Error(`claude-artifact-framework: unknown layout "${a}". Valid layouts: ${Fe.join(", ")}.`);if(a==="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 d=Object.keys(c).filter(l=>!o.includes(l));if(d.length)throw new Error(`claude-artifact-framework: steps[${i}] has unknown keys (${d.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\`.`);U(c.fields,`steps[${i}]`);for(let l of c.fields||[]){if(s.has(l.key))throw new Error(`claude-artifact-framework: field key "${l.key}" appears in more than one step \u2014 keys share one data pool and must be unique.`);s.add(l.key)}}),a}if(a==="chat")return qe(e.chat,"chat"),a;if(a==="workspace"){if(!Array.isArray(e.main)||e.main.length===0)throw new Error('claude-artifact-framework: layout "workspace" needs `main: [...]` (an array of blocks). `sidebar: [...]` is optional.');if(B(e.main),e.sidebar!==void 0){if(!Array.isArray(e.sidebar))throw new Error("claude-artifact-framework: workspace `sidebar` must be an array of blocks.");B(e.sidebar)}let r=R([...e.main,...e.sidebar||[]]);if(r.filter(s=>s&&s.chat).length>1)throw new Error("claude-artifact-framework: only one chat block per app \u2014 the conversation persists under data.chat and there is exactly one.");return fe(r),a}if(a==="documents"){let r=e.documents;if(!r||typeof r!="object"||!r.blocks&&!r.types)throw new Error('claude-artifact-framework: layout "documents" needs `documents: { blocks: [...] }` (every document repeats the same blocks) or `documents: { types: {...} }` (each document is one of several kinds).');if(r.blocks&&r.types)throw new Error("claude-artifact-framework: documents takes `blocks` (uniform documents) OR `types` (typed documents) \u2014 not both.");let o=Object.keys(r).filter(c=>!Ke.includes(c));if(o.length)throw new Error(`claude-artifact-framework: documents has unknown keys (${o.join(", ")}). Valid keys: ${Ke.join(", ")}.`);if(r.title!==void 0&&typeof r.title!="function")throw new Error("claude-artifact-framework: documents.title must be a function of the document's data returning the tab label.");let s=(c,i)=>{B(c);let d=R(c);if(d.filter(l=>l&&l.chat).length>1)throw new Error(`claude-artifact-framework: only one chat block per document (${i}) \u2014 each document's conversation persists under its own data.chat and there is exactly one.`);fe(d)};if(r.blocks){if(!Array.isArray(r.blocks)||r.blocks.length===0)throw new Error("claude-artifact-framework: documents.blocks must be a non-empty array of blocks.");s(r.blocks,"documents.blocks")}else{let c=Object.keys(r.types||{});if(!c.length)throw new Error("claude-artifact-framework: documents.types needs at least one type, e.g. `types: { nota: { blocks: [...] } }`.");for(let i of c){let d=r.types[i],l=["label","title","blocks","empty"],f=Object.keys(d||{}).filter(u=>!l.includes(u));if(f.length)throw new Error(`claude-artifact-framework: documents.types.${i} has unknown keys (${f.join(", ")}). Valid keys: ${l.join(", ")}.`);if(!d||!Array.isArray(d.blocks)||d.blocks.length===0)throw new Error(`claude-artifact-framework: documents.types.${i} needs a non-empty \`blocks\` array.`);if(d.title!==void 0&&typeof d.title!="function")throw new Error(`claude-artifact-framework: documents.types.${i}.title must be a function of the document's data.`);s(d.blocks,`documents.types.${i}`)}}return a}if(a==="records"){if(Xe(e.records,"records",!1),e.blocks&&(B(e.blocks),R(e.blocks).some(r=>r&&r.records)))throw new Error("claude-artifact-framework: a records BLOCK below a records LAYOUT is ambiguous \u2014 the layout already owns the collection. Use panel/workspace/documents to embed records blocks.");return a}return B(e.blocks||[]),fe(R(e.blocks||[])),a}function Xe(e,t,a){if(!e||!Array.isArray(e.fields)||e.fields.length===0)throw new Error(`claude-artifact-framework: ${t} needs \`records: { fields: [...] }\` \u2014 the same field declarations the fields block uses.`);let r=a?[...Ye,"key"]:Ye,o=Object.keys(e).filter(c=>!r.includes(c));if(o.length)throw new Error(`claude-artifact-framework: ${t} has unknown keys (${o.join(", ")}). Valid keys: ${r.join(", ")}.`);if(a&&e.key!==void 0&&(typeof e.key!="string"||!e.key))throw new Error(`claude-artifact-framework: ${t}.key must be a non-empty string naming the collection in data.`);if(U(e.fields,t),e.fields.some(c=>c.type==="file")||e.items&&e.items.fields.some(c=>c.type==="file"))throw new Error("claude-artifact-framework: `file` fields live in the flat data pool (panel blocks or steps) \u2014 they are not supported inside records or items.");let s=new Set;for(let c of e.fields){if(c.key==="id")throw new Error('claude-artifact-framework: "id" is reserved on records \u2014 the framework assigns it.');if(s.has(c.key))throw new Error(`claude-artifact-framework: duplicate ${t} field key "${c.key}".`);s.add(c.key)}if(e.actions&&We(e.actions,`${t}.actions`),e.items){let c=Object.keys(e.items).filter(i=>!He.includes(i));if(c.length)throw new Error(`claude-artifact-framework: ${t}.items has unknown keys (${c.join(", ")}). Valid keys: ${He.join(", ")}.`);if(!Array.isArray(e.items.fields)||e.items.fields.length===0)throw new Error(`claude-artifact-framework: ${t}.items needs \`fields: [...]\` \u2014 the same field declarations as everywhere else.`);U(e.items.fields,`${t}.items`);for(let i of e.items.fields)if(i.key==="id")throw new Error('claude-artifact-framework: "id" is reserved on items \u2014 the framework assigns it.');if(s.has("items")||e.fields.some(i=>i.key==="items"))throw new Error(`claude-artifact-framework: a ${t} field cannot be named "items" when \`items\` is declared \u2014 that key holds the child collection.`)}for(let[c,i]of Object.entries(e.compute||{})){if(s.has(c)||c==="id"||e.items&&c==="items")throw new Error(`claude-artifact-framework: compute key "${c}" collides with a field key \u2014 computed values are derived, never stored.`);if(typeof i!="function"&&typeof(i&&i.value)!="function")throw new Error(`claude-artifact-framework: compute "${c}" must be a function of the record, or { label, format, value: (r) => ... }.`)}}function fe(e){let t=new Set;for(let a of e){if(!a||!a.records)continue;let r=a.records.key||"records";if(t.has(r))throw new Error(`claude-artifact-framework: two records blocks share the collection key "${r}" \u2014 give each a distinct \`key\`.`);t.add(r)}}function R(e){let t=[];for(let a of e||[])if(t.push(a),a&&Array.isArray(a.tabs))for(let r of a.tabs)t.push(...R(r.blocks));return t}function _t(e){let t={...e.data||{}};(e.layout||"panel")==="records"&&!Array.isArray(t.records)&&(t.records=[]),(e.layout||"panel")==="documents"&&!Array.isArray(t.docs)&&(t.docs=[]);let a=R([...e.blocks||[],...e.main||[],...e.sidebar||[]]);((e.layout||"panel")==="chat"||a.some(o=>o&&o.chat))&&!t.chat&&(t.chat={api:[],log:[]});for(let o of[...a,...e.steps||[]])for(let s of o.fields||[])s&&s.key!==void 0&&!(s.key in t)&&(t[s.key]=s.value!==void 0?s.value:s.type==="check"?!1:"");for(let o of a)if(o&&o.records){let s=o.records.key||"records";Array.isArray(t[s])||(t[s]=[])}return t}var de=null;function Mt(e){return de||(de=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}}),de}function zt({spec:e,ctx:t}){let a=e.tabs,r=a.map(c=>c.label).join("|"),o=t.view.tabs?t.view.tabs[r]:void 0,s=Math.min(o===void 0?0:o,a.length-1);return n("div",{className:"caf-tabs"},n("div",{className:"caf-tabbar",role:"tablist"},a.map((c,i)=>n("button",{key:c.label,type:"button",role:"tab","aria-selected":i===s,className:i===s?"caf-tab caf-tab-active":"caf-tab",onClick:()=>t.setTab(r,i)},c.label))),n("div",{className:"caf-tabs-body"},a[s].blocks.map((c,i)=>n(q,{key:s+":"+i,block:c,ctx:t}))))}var Bt={...ie,tabs:zt,records:De},Dt=[...Y,"tabs","records"];function q({block:e,ctx:t}){if(typeof e.when=="function"&&!e.when(t.data))return null;let a=Object.keys(e).find(i=>Dt.includes(i)),r=Bt[a],o=n(Mt(t.React),null,n(r,{spec:e.collapsible?{...e,title:void 0}:e,ctx:t}));if(!e.collapsible)return o;let s=typeof e.title=="string"&&e.title?e.title:a,c=t.view.collapsed&&s in t.view.collapsed?t.view.collapsed[s]:e.collapsible==="collapsed";return n("div",{className:"caf-collapse"},n("button",{type:"button",className:"caf-collapse-head","aria-expanded":!c,onClick:()=>t.toggleCollapsed(s,!c)},n("span",null,e.title||a),n("span",{className:c?"caf-chevron caf-chevron-closed":"caf-chevron"},"\u25BE")),c?null:n("div",{className:"caf-collapse-body"},o))}function Qe({spec:e,ctx:t}){return n("div",{className:"caf-panel"},(e.blocks||[]).map((a,r)=>n("section",{key:r,className:a.wide||a.collapsible?"caf-slot caf-slot-wide":"caf-slot"},n(q,{block:a,ctx:t}))))}function It({spec:e,ctx:t}){let a=t.view.screen==="record"&&(t.data.records||[]).some(r=>r.id===t.view.arg);return n("div",null,n(Ie,{spec:e,ctx:t}),!a&&Array.isArray(e.blocks)&&e.blocks.length?n("div",{className:"caf-panel caf-records-blocks"},e.blocks.map((r,o)=>n("section",{key:o,className:r.wide||r.collapsible?"caf-slot caf-slot-wide":"caf-slot"},n(q,{block:r,ctx:t})))):null)}function Vt({spec:e,ctx:t}){let a=r=>(r||[]).map((o,s)=>n("section",{key:s,className:"caf-ws-slot"},n(q,{block:o,ctx:t})));return n("div",{className:"caf-workspace"},n("div",{className:"caf-ws-main"},a(e.main)),e.sidebar&&e.sidebar.length?n("div",{className:"caf-ws-side"},a(e.sidebar)):null)}function ue(e){let t={};for(let a of R(e.blocks)){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:"");if(a.records){let r=a.records.key||"records";Array.isArray(t[r])||(t[r]=[])}}return t}function Ft(){return"d"+Date.now().toString(36)+Math.random().toString(36).slice(2,8)}var J="caf:doc";function Pt(e,t,a){if(e.title)try{let r=e.title(t);if(r!=null&&r!=="")return String(r)}catch{}for(let r of R(e.blocks))for(let o of r.fields||[])if(!o.type||o.type==="text"||o.type==="textarea"||o.type==="select"){let s=t[o.key];return s!==""&&s!==void 0&&s!==null?String(s):a||"(untitled)"}return a||"(untitled)"}function Kt({spec:e,ctx:t}){let a=e.documents,r=a.label||"document",o=Array.isArray(t.data.docs)?t.data.docs:[],s=a.types||null,c=s?Object.keys(s):[],i=p=>s?s[p.type]:a,d=p=>s[p]&&s[p].label||p,[l,f]=N(!1),u=t.view.tabs?t.view.tabs[J]:void 0,m=o.find(p=>p.id===u)||o[0];function b(p){let A=s?s[p]:a,k={id:Ft(),...s?{type:p}:{},data:ue(A)};t.update(C=>{C.docs=[...C.docs||[],k]}),t.setTab(J,k.id),f(!1)}function h(){if(!s)return b();if(c.length===1)return b(c[0]);f(p=>!p)}function $(p){let A=o.findIndex(k=>k.id===p);if(t.update(k=>{k.docs=k.docs.filter(C=>C.id!==p)}),delete t.files["doc:"+p],m&&m.id===p){let k=o[A+1]||o[A-1];k&&t.setTab(J,k.id)}}let v=s&&l?n("div",{className:"caf-doc-typemenu"},c.map(p=>n("button",{key:p,type:"button",className:"caf-btn caf-btn-sm",onClick:()=>b(p)},d(p)))):null;if(!m)return n("div",{className:"caf-panel caf-panel-single"},n("div",{className:"caf-block caf-empty"},n("p",null,a.empty||`No ${r}s yet. Create the first one.`),s?n("div",{className:"caf-doc-typemenu"},c.map(p=>n("button",{key:p,type:"button",className:"caf-btn caf-btn-primary",onClick:()=>b(p)},`New ${d(p)}`))):n("button",{type:"button",className:"caf-btn caf-btn-primary",onClick:()=>b()},`New ${r}`)));let E=i(m);if(!E)return n("div",{className:"caf-documents"},n(Ue,{docs:o,active:m,dspec:a,types:s,close:$,onAdd:h,label:r,ctx:t}),v,n("div",{className:"caf-block caf-block-error"},n("strong",null,`This ${r}'s type "${m.type}" no longer exists`),n("code",null,`valid types: ${c.join(", ")}`)));let g={...ue(E),...m.data},y={...t,data:g,update:p=>t.update(A=>{let k=(A.docs||[]).find(C=>C.id===m.id);k&&p(k.data)}),files:t.files["doc:"+m.id]=t.files["doc:"+m.id]||{}};return n("div",{className:"caf-documents"},n(Ue,{docs:o,active:m,dspec:a,types:s,close:$,onAdd:h,label:r,ctx:t}),v,n(Qe,{spec:{blocks:E.blocks},ctx:y}))}function Ue({docs:e,active:t,dspec:a,types:r,close:o,onAdd:s,label:c,ctx:i}){let d=l=>{let f=r?r[l.type]:a;if(!f)return l.type;let u={...ue(f),...l.data},m=r?f.label||l.type:void 0;return Pt(f,u,m)};return n("div",{className:"caf-tabbar",role:"tablist"},e.map(l=>n("span",{key:l.id,className:"caf-doc-tab"},n("button",{type:"button",role:"tab","aria-selected":l.id===t.id,className:l.id===t.id?"caf-tab caf-tab-active":"caf-tab",onClick:()=>i.setTab(J,l.id)},d(l)),n("button",{type:"button",className:"caf-doc-close","aria-label":`Close ${c}`,onClick:()=>o(l.id)},"\u2715"))),n("button",{type:"button",className:"caf-tab caf-doc-add","aria-label":`New ${c}`,onClick:s},"+"))}var Yt={panel:Qe,records:It,steps:Ve,chat:Oe,workspace:Vt,documents:Kt};function Ge(e){return new Promise((t,a)=>{let r=document.querySelector(`script[src="${e}"]`);if(r){if(r.dataset.cafReady==="1")return t();r.addEventListener("load",t),r.addEventListener("error",()=>a(new Error(`failed to load ${e}`)));return}let o=document.createElement("script");o.src=e,o.onload=()=>{o.dataset.cafReady="1",t()},o.onerror=()=>{let s=e.match(/^(https:\/\/cdn\.jsdelivr\.net\/npm\/(?:@[^/]+\/)?[^/]+)\/.+/);s&&s[1]!==e?Ge(s[1]).then(t,()=>a(new Error(`failed to load ${e} (also tried package default ${s[1]})`))):a(new Error(`failed to load ${e}`))},document.head.appendChild(o)})}function Ze(e={}){let t=Lt(e),a=Se(_t(e),{shared:!!e.shared}),r=K(e.theme&&e.theme.seed)+Ht,o={};return function(){if(!I())throw new Error(`claude-artifact-framework: React not found. Hand it over once, before rendering:
29
29
 
30
30
  import React from "react";
31
31
  ArtifactKit.useReact(React);
32
- `);let[,c]=v(0),[i,d]=v(e.libs&&e.libs.length?"loading":"ready"),[l,f]=v(null);S(()=>{!e.libs||!e.libs.length||Promise.all(e.libs.map(Xe)).then(()=>d("ready"),b=>{f(String(b&&b.message||b)),d("error")})},[]),S(()=>{let b=a.subscribe(()=>c(m=>m+1));return a.isHydrated()&&c(m=>m+1),b},[]);let p={React:ge(),data:a.getData(),view:a.getView(),update:a.update,go:a.go,back:a.back,setStep:b=>a.setView({step:b}),files:o,viewerId:a.getViewerId(),setTab:(b,m)=>a.setView({tabs:{...a.getView().tabs,[b]:m}}),toggleCollapsed:(b,m)=>a.setView({collapsed:{...a.getView().collapsed,[b]:m}}),colors:b=>Ee(e.theme&&e.theme.seed,b)},u=Pt[t];return n("div",{className:`caf-root caf-layout-${t}`},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),i==="error"?n("div",{className:"caf-block caf-block-error"},n("strong",null,"A library failed to load"),n("code",null,l)):!a.isHydrated()||i==="loading"?n("div",{className:"caf-block caf-loading"},i==="loading"?"Loading libraries\u2026":"Loading\u2026"):n(u,{spec:e,ctx:p}))}}var Yt=`
32
+ `);let[,c]=N(0),[i,d]=N(e.libs&&e.libs.length?"loading":"ready"),[l,f]=N(null);T(()=>{!e.libs||!e.libs.length||Promise.all(e.libs.map(Ge)).then(()=>d("ready"),b=>{f(String(b&&b.message||b)),d("error")})},[]),T(()=>{let b=a.subscribe(()=>c(h=>h+1));return a.isHydrated()&&c(h=>h+1),b},[]);let u={React:we(),data:a.getData(),view:a.getView(),update:a.update,go:a.go,back:a.back,setStep:b=>a.setView({step:b}),files:o,viewerId:a.getViewerId(),setTab:(b,h)=>a.setView({tabs:{...a.getView().tabs,[b]:h}}),toggleCollapsed:(b,h)=>a.setView({collapsed:{...a.getView().collapsed,[b]:h}}),colors:b=>Ce(e.theme&&e.theme.seed,b)},m=Yt[t];return n("div",{className:`caf-root caf-layout-${t}`},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),i==="error"?n("div",{className:"caf-block caf-block-error"},n("strong",null,"A library failed to load"),n("code",null,l)):!a.isHydrated()||i==="loading"?n("div",{className:"caf-block caf-loading"},i==="loading"?"Loading libraries\u2026":"Loading\u2026"):n(m,{spec:e,ctx:u}))}}var Ht=`
33
33
  .caf-root {
34
34
  --caf-radius: 10px;
35
35
  --caf-control-radius: 7px; /* one radius for every control: buttons, inputs, rows */
@@ -237,11 +237,12 @@ Continue with this information. If you have everything you need, answer in natur
237
237
  .caf-doc-add { font-size: 1rem; font-weight: 650; }
238
238
  .caf-empty .caf-btn { margin-top: 0.6rem; }
239
239
  .caf-records-block { display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
240
+ .caf-doc-typemenu { display: flex; gap: 0.5rem; flex-wrap: wrap; }
240
241
  .caf-chevron-closed { transform: rotate(-90deg); }
241
242
  .caf-block-fill { border: none; background: transparent; padding: 0; overflow: auto; min-height: 320px; }
242
243
  .caf-empty, .caf-loading { color: var(--caf-muted); font-size: 0.9rem; text-align: center; padding: 1.6rem 1rem; }
243
244
  .caf-block-error { border-color: var(--caf-danger); gap: 0.4rem; }
244
245
  .caf-block-error strong { font-size: 0.9rem; color: var(--caf-danger); }
245
246
  .caf-block-error code { font-size: 0.78rem; color: var(--caf-muted); word-break: break-word; }
246
- `;return nt(Ht);})();
247
+ `;return ot(Jt);})();
247
248
  //# sourceMappingURL=index.global.js.map