claude-artifact-framework 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,17 @@
1
- var ArtifactKit=(()=>{var K=Object.defineProperty;var Ve=Object.getOwnPropertyDescriptor;var Fe=Object.getOwnPropertyNames;var Pe=Object.prototype.hasOwnProperty;var He=(e,a)=>{for(var t in a)K(e,t,{get:a[t],enumerable:!0})},Ke=(e,a,t,r)=>{if(a&&typeof a=="object"||typeof a=="function")for(let o of Fe(a))!Pe.call(e,o)&&o!==t&&K(e,o,{get:()=>a[o],enumerable:!(r=Ve(a,o))||r.enumerable});return e};var Ye=e=>Ke(K({},"__esModule",{value:!0}),e);var Rt={};He(Rt,{contrast:()=>W,createApp:()=>Ie,createPersistedStore:()=>fe,createSharedStore:()=>de,createStore:()=>le,hasReact:()=>_,palette:()=>X,storage:()=>w,themeCss:()=>D,useReact:()=>ue});function L(){return typeof window<"u"&&typeof window.storage=="object"&&window.storage!==null}function ie(e){return{async get(a,t=void 0){if(!L())return t;try{let r=await window.storage.get(a,e);if(r?.value===void 0||r?.value===null)return t;try{return JSON.parse(r.value)}catch{return r.value}}catch{return t}},async set(a,t,{raw:r=!1}={}){if(!L())throw new Error("window.storage is not available (is this a Code Artifact rather than a published Chat Artifact?)");let o=r?t:JSON.stringify(t);if(typeof o!="string")throw new Error("window.storage only accepts strings \u2014 the value must be JSON-serializable");return window.storage.set(a,o,e)},async delete(a){if(L())try{await window.storage.delete(a,e)}catch{}},async list(a){if(!L())return[];try{return(await window.storage.list(a,e))?.keys||[]}catch{return[]}}}}var w={...ie(!1),shared:ie(!0),available:L};function Y(e){let a=e,t=new Set;function r(){return a}function o(i){a=typeof i=="function"?i(a):i,t.forEach(c=>c(a))}function s(i){return t.add(i),()=>t.delete(i)}return{get:r,set:o,subscribe:s}}function ce(e,a){let t;return(...r)=>{clearTimeout(t),t=setTimeout(()=>e(...r),a)}}function le(e){return Y(e)}function fe(e,a,{debounceMs:t=300}={}){let r=Y(a),o=ce(i=>w.set(e,i),t),s=w.get(e,a).then(i=>r.set(i));return r.subscribe(o),{...r,ready:s}}function de(e,a,{pollMs:t=2e3,debounceMs:r=300}={}){let o=Y(a),s=ce(d=>w.shared.set(e,d),r),i=!1;o.subscribe(d=>{i||s(d)});async function c(){let d=await w.shared.get(e,a);JSON.stringify(d)!==JSON.stringify(o.get())&&(i=!0,o.set(d),i=!1)}let f=c(),l=setInterval(c,t);return{...o,ready:f,stop:()=>clearInterval(l)}}var j=typeof globalThis<"u"?globalThis.React:void 0;function ue(e){return j=e,e}function _(){return!!j}function me(){return O()}function O(){if(!j)throw new Error(`claude-artifact-framework: React not found. Hand it over once, before createApp:
1
+ var ArtifactKit=(()=>{var U=Object.defineProperty;var He=Object.getOwnPropertyDescriptor;var Je=Object.getOwnPropertyNames;var Ue=Object.prototype.hasOwnProperty;var qe=(e,t)=>{for(var a in t)U(e,a,{get:t[a],enumerable:!0})},We=(e,t,a,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Je(t))!Ue.call(e,o)&&o!==a&&U(e,o,{get:()=>t[o],enumerable:!(r=He(t,o))||r.enumerable});return e};var Xe=e=>We(U({},"__esModule",{value:!0}),e);var It={};qe(It,{contrast:()=>G,createApp:()=>Pe,createPersistedStore:()=>ue,createSharedStore:()=>me,createStore:()=>de,hasReact:()=>z,palette:()=>Z,storage:()=>k,themeCss:()=>V,useReact:()=>pe});function M(){return typeof window<"u"&&typeof window.storage=="object"&&window.storage!==null}function le(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={...le(!1),shared:le(!0),available:M};function q(e){let t=e,a=new Set;function r(){return t}function o(i){t=typeof i=="function"?i(t):i,a.forEach(c=>c(t))}function s(i){return a.add(i),()=>a.delete(i)}return{get:r,set:o,subscribe:s}}function fe(e,t){let a;return(...r)=>{clearTimeout(a),a=setTimeout(()=>e(...r),t)}}function de(e){return q(e)}function ue(e,t,{debounceMs:a=300}={}){let r=q(t),o=fe(i=>k.set(e,i),a),s=k.get(e,t).then(i=>r.set(i));return r.subscribe(o),{...r,ready:s}}function me(e,t,{pollMs:a=2e3,debounceMs:r=300}={}){let o=q(t),s=fe(d=>k.shared.set(e,d),r),i=!1;o.subscribe(d=>{i||s(d)});async function c(){let d=await k.shared.get(e,t);JSON.stringify(d)!==JSON.stringify(o.get())&&(i=!0,o.set(d),i=!1)}let f=c(),l=setInterval(c,a);return{...o,ready:f,stop:()=>clearInterval(l)}}var j=typeof globalThis<"u"?globalThis.React:void 0;function pe(e){return j=e,e}function z(){return!!j}function be(){return O()}function O(){if(!j)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 j}var n=(...e)=>O().createElement(...e),k=(...e)=>O().useState(...e),S=(...e)=>O().useEffect(...e);var pe=(...e)=>O().useRef(...e),Bt=j&&j.Component||class{render(){return O()}};var J="caf:data",be="caf:viewer",he="caf:view",ge={screen:null,arg:null,stack:[],step:0,selected:null,tabs:{},collapsed:{}};function z(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function q(e,a){if(!z(e)||!z(a))return a===void 0?e:a;let t={...e};for(let r of Object.keys(a))t[r]=z(e[r])?q(e[r],a[r]):a[r];return t}function ye(e,a){let t;return(...r)=>{clearTimeout(t),t=setTimeout(()=>e(...r),a)}}function we(e,{debounceMs:a=400,shared:t=!1,pollMs:r=2500}={}){let o=t?w.shared:w,s=U(e),i={...ge},c=!1,f=null,l=0,d=0,m=new Set,h=!1;function u(){h||(h=!0,Promise.resolve().then(()=>{h=!1;for(let p of m)p()}))}let b=ye(()=>{let p=l;Promise.resolve(o.set(J,s)).then(()=>{d=Math.max(d,p)}).catch(()=>{})},a),v=ye(()=>w.set(he,i),a);t&&setInterval(async()=>{if(!(!c||l>d))try{let p=await o.get(J,void 0);p!==void 0&&JSON.stringify(p)!==JSON.stringify(s)&&(s=q(e,p),u())}catch{}},r);let A=(async()=>{let[p,y,$]=await Promise.all([o.get(J,void 0),w.get(he,void 0),w.get(be,void 0)]);typeof $=="string"&&$?f=$:(f="v"+Math.random().toString(36).slice(2,10)+Math.random().toString(36).slice(2,6),w.set(be,f).catch?.(()=>{})),p!==void 0&&(s=q(e,p)),y!==void 0&&(i={...ge,...y}),c=!0,u()})();function x(p){let y=p(s);y!==void 0&&(s=y),s={...s},l++,b(),u()}function T(p){i={...i,...p},v(),u()}return{ready:A,isHydrated:()=>c,getViewerId:()=>f,getData:()=>s,getView:()=>i,update:x,setView:T,go(p,y){T({stack:[...i.stack,{screen:i.screen,arg:i.arg}],screen:p,arg:y})},back(){let p=i.stack.slice(),y=p.pop()||{screen:null,arg:null};T({stack:p,screen:y.screen,arg:y.arg})},subscribe(p){return m.add(p),()=>m.delete(p)}}}function U(e){if(Array.isArray(e))return e.map(U);if(z(e)){let a={};for(let t of Object.keys(e))a[t]=U(e[t]);return a}return e}function C(e,a,t){return Math.min(t,Math.max(a,e))}function I(e){let a=String(e).replace("#","").trim();a.length===3&&(a=a.split("").map(r=>r+r).join(""));let t=parseInt(a,16);return Number.isFinite(t)?[t>>16&255,t>>8&255,t&255]:[59,110,246]}function Je(e){return"#"+e.map(a=>C(Math.round(a),0,255).toString(16).padStart(2,"0")).join("")}function ve([e,a,t]){e/=255,a/=255,t/=255;let r=Math.max(e,a,t),o=Math.min(e,a,t),s=(r+o)/2,i=r-o,c=0,f=0;return i&&(f=s>.5?i/(2-r-o):i/(r+o),r===e?c=(a-t)/i+(a<t?6:0):r===a?c=(t-e)/i+2:c=(e-a)/i+4,c/=6),[c*360,f*100,s*100]}function qe(e,a,t){if(e=(e%360+360)%360/360,a=C(a,0,100)/100,t=C(t,0,100)/100,!a)return[t*255,t*255,t*255];let r=t<.5?t*(1+a):t+a-t*a,o=2*t-r,s=i=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?o+(r-o)*6*i:i<1/2?r:i<2/3?o+(r-o)*(2/3-i)*6:o);return[s(e+1/3)*255,s(e)*255,s(e-1/3)*255]}function g(e,a,t){return Je(qe(e,a,t))}function ke(e){let a=e.map(t=>(t/=255,t<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4)));return .2126*a[0]+.7152*a[1]+.0722*a[2]}function W(e,a){let t=ke(I(e)),r=ke(I(a));return(Math.max(t,r)+.05)/(Math.min(t,r)+.05)}function E(e,a,t,r,o,s){for(let i=o;i>=4&&i<=96;i+=s){let c=g(e,a,i);if(W(c,t)>=r)return c}return g(e,a,s<0?24:82)}function X(e="#3b6ef6"){let[a,t]=ve(I(e)),r=C(t,30,88),o=C(r*.1,3,9),s=g(a,o*.4,100),i=g(a,o*1.4,13);return{light:{bg:g(a,o,96.5),surface:s,sunken:g(a,o,93),border:g(a,o,86),text:g(a,o*1.6,11),muted:g(a,o*1.2,41),accent:E(a,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(a,o*1.5,9),surface:i,sunken:g(a,o*1.5,7),border:g(a,o*1.3,24),text:g(a,o*.6,95),muted:g(a,o*.8,66),accent:E(a,C(r,40,80),i,4.5,62,2),accentText:g(a,o*2,8),danger:E(2,70,i,4.5,62,2),ok:E(148,55,i,4.5,62,2),warn:E(38,80,i,4.5,62,2)}}}function B(e){return Object.entries(e).map(([a,t])=>`--caf-${a}: ${t};`).join("")}function D(e){let a=X(e);return`
6
- :root { ${B(a.light)} }
7
- @media (prefers-color-scheme: dark) { :root { ${B(a.dark)} } }
8
- :root[data-theme="dark"] { ${B(a.dark)} }
9
- :root[data-theme="light"] { ${B(a.light)} }
10
- `}function xe(e,a){let[t,r]=ve(I(e||"#3b6ef6")),o=C(r,45,70);return Array.from({length:a},(s,i)=>g((t+i*137.5)%360,o,52))}var G=["system","greeting","placeholder","tools","model","maxTokens"],Ue="claude-sonnet-4-6",We=8;async function Xe({model:e,maxTokens:a,system:t,messages:r,onText:o}){let s=await fetch("https://api.anthropic.com/v1/messages",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:e,max_tokens:a,system:t,messages:r,stream:!0})});if(!s.ok||!s.body){let d="";try{let m=await s.json();d=m&&m.error&&m.error.message||JSON.stringify(m)}catch{d=await s.text().catch(()=>"")}throw new Error(`HTTP ${s.status}${d?": "+d:""}`)}let i=s.body.getReader(),c=new TextDecoder,f="",l="";for(;;){let{done:d,value:m}=await i.read();if(d)break;l+=c.decode(m,{stream:!0});let h=l.split(`
11
- `);l=h.pop();for(let u of h)if(u.startsWith("data: "))try{let b=JSON.parse(u.slice(6));b.type==="content_block_delta"&&b.delta&&b.delta.text&&(f+=b.delta.text,o&&o(f))}catch{}}return f}function Qe(e){let a=e.match(/```tool_call\s*\n?([\s\S]*?)```/);if(!a)return null;try{let t=JSON.parse(a[1]);return Array.isArray(t)&&t.length?t:null}catch{return null}}function Ne(e){return e.replace(/```tool_call\s*\n?[\s\S]*?```/,"").trim()}function Ge(e){return`
5
+ `);return j}var n=(...e)=>O().createElement(...e),v=(...e)=>O().useState(...e),E=(...e)=>O().useEffect(...e);var he=(...e)=>O().useRef(...e),Yt=j&&j.Component||class{render(){return O()}};var W="caf:data",ge="caf:viewer",ye="caf:view",we={screen:null,arg:null,stack:[],step:0,selected:null,tabs:{},collapsed:{}};function D(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function X(e,t){if(!D(e)||!D(t))return t===void 0?e:t;let a={...e};for(let r of Object.keys(t))a[r]=D(e[r])?X(e[r],t[r]):t[r];return a}function ke(e,t){let a;return(...r)=>{clearTimeout(a),a=setTimeout(()=>e(...r),t)}}function ve(e,{debounceMs:t=400,shared:a=!1,pollMs:r=2500}={}){let o=a?k.shared:k,s=Q(e),i={...we},c=!1,f=null,l=0,d=0,p=new Set,u=!1;function b(){u||(u=!0,Promise.resolve().then(()=>{u=!1;for(let h of p)h()}))}let m=ke(()=>{let h=l;Promise.resolve(o.set(W,s)).then(()=>{d=Math.max(d,h)}).catch(()=>{})},t),w=ke(()=>k.set(ye,i),t);a&&setInterval(async()=>{if(!(!c||l>d))try{let h=await o.get(W,void 0);h!==void 0&&JSON.stringify(h)!==JSON.stringify(s)&&(s=X(e,h),b())}catch{}},r);let x=(async()=>{let[h,y,C]=await Promise.all([o.get(W,void 0),k.get(ye,void 0),k.get(ge,void 0)]);typeof C=="string"&&C?f=C:(f="v"+Math.random().toString(36).slice(2,10)+Math.random().toString(36).slice(2,6),k.set(ge,f).catch?.(()=>{})),h!==void 0&&(s=X(e,h)),y!==void 0&&(i={...we,...y}),c=!0,b()})();function T(h){let y=h(s);y!==void 0&&(s=y),s={...s},l++,m(),b()}function N(h){i={...i,...h},w(),b()}return{ready:x,isHydrated:()=>c,getViewerId:()=>f,getData:()=>s,getView:()=>i,update:T,setView:N,go(h,y){N({stack:[...i.stack,{screen:i.screen,arg:i.arg}],screen:h,arg:y})},back(){let h=i.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 Q(e){if(Array.isArray(e))return e.map(Q);if(D(e)){let t={};for(let a of Object.keys(e))t[a]=Q(e[a]);return t}return e}function A(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 Qe(e){return"#"+e.map(t=>A(Math.round(t),0,255).toString(16).padStart(2,"0")).join("")}function Ne([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,i=r-o,c=0,f=0;return i&&(f=s>.5?i/(2-r-o):i/(r+o),r===e?c=(t-a)/i+(t<a?6:0):r===t?c=(a-e)/i+2:c=(e-t)/i+4,c/=6),[c*360,f*100,s*100]}function Ge(e,t,a){if(e=(e%360+360)%360/360,t=A(t,0,100)/100,a=A(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=i=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?o+(r-o)*6*i:i<1/2?r:i<2/3?o+(r-o)*(2/3-i)*6:o);return[s(e+1/3)*255,s(e)*255,s(e-1/3)*255]}function g(e,t,a){return Qe(Ge(e,t,a))}function xe(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 G(e,t){let a=xe(I(e)),r=xe(I(t));return(Math.max(a,r)+.05)/(Math.min(a,r)+.05)}function $(e,t,a,r,o,s){for(let i=o;i>=4&&i<=96;i+=s){let c=g(e,t,i);if(G(c,a)>=r)return c}return g(e,t,s<0?24:82)}function Z(e="#3b6ef6"){let[t,a]=Ne(I(e)),r=A(a,30,88),o=A(r*.1,3,9),s=g(t,o*.4,100),i=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:$(t,r,"#ffffff",4.5,54,-2),accentText:"#ffffff",danger:$(2,68,"#ffffff",4.5,54,-2),ok:$(148,62,"#ffffff",4.5,44,-2),warn:$(38,88,"#ffffff",4.5,44,-2)},dark:{bg:g(t,o*1.5,9),surface:i,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:$(t,A(r,40,80),i,4.5,62,2),accentText:g(t,o*2,8),danger:$(2,70,i,4.5,62,2),ok:$(148,55,i,4.5,62,2),warn:$(38,80,i,4.5,62,2)}}}function B(e){return Object.entries(e).map(([t,a])=>`--caf-${t}: ${a};`).join("")}function V(e){let t=Z(e);return`
6
+ :root { ${B(t.light)} }
7
+ @media (prefers-color-scheme: dark) { :root { ${B(t.dark)} } }
8
+ :root[data-theme="dark"] { ${B(t.dark)} }
9
+ :root[data-theme="light"] { ${B(t.light)} }
10
+ `}function Se(e,t){let[a,r]=Ne(I(e||"#3b6ef6")),o=A(r,45,70);return Array.from({length:t},(s,i)=>g((a+i*137.5)%360,o,52))}var te=["system","greeting","placeholder","tools","model","maxTokens"],Ze="claude-sonnet-4-6",et=8;async function tt({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 d="";try{let p=await s.json();d=p&&p.error&&p.error.message||JSON.stringify(p)}catch{d=await s.text().catch(()=>"")}throw new Error(`HTTP ${s.status}${d?": "+d:""}`)}let i=s.body.getReader(),c=new TextDecoder,f="",l="";for(;;){let{done:d,value:p}=await i.read();if(d)break;l+=c.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&&(f+=m.delta.text,o&&o(f))}catch{}}return f}function at(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 Ee(e){return e.replace(/```tool_call\s*\n?[\s\S]*?```/,"").trim()}function rt(e){return`
12
12
 
13
13
  You have tools available:
14
- ${Object.entries(e).map(([t,r])=>`- ${t}: ${r.description}
14
+ ${Object.entries(e).map(([a,r])=>`- ${a}: ${r.description}
15
15
  Input: ${JSON.stringify(r.input||{})}`).join(`
16
16
  `)}
17
17
 
@@ -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 Ze(e,a,t){return e.map(r=>{let o=a[r.name];if(!o)return{name:r.name,error:`unknown tool "${r.name}". Valid tools: ${Object.keys(a).join(", ")}`};try{let s=o.run(r.input||{},t);return{name:r.name,result:s===void 0?{ok:!0}:s}}catch(s){return{name:r.name,error:String(s&&s.message||s)}}})}var Se=e=>String(e).replace(/[&<>"]/g,a=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"})[a]);function Q(e){let a=[],t=String(e).replace(/```[a-z]*\n?([\s\S]*?)```/g,(r,o)=>(a.push(o.replace(/\n$/,"")),"\0"+(a.length-1)+"\0"));return t=Se(t),t=t.replace(/`([^`]+)`/g,"<code>$1</code>"),t=t.replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>"),t=t.replace(/(^|[^*])\*([^*\n]+)\*/g,"$1<em>$2</em>"),t=t.replace(/^#{1,3} (.+)$/gm,'<strong class="caf-md-h">$1</strong>'),t=t.replace(/^[-•*] (.+)$/gm,'<span class="caf-md-li">$1</span>'),t=t.replace(/^\d+\. (.+)$/gm,'<span class="caf-md-li caf-md-num">$1</span>'),t=t.replace(/\n/g,"<br>"),t=t.replace(/\u0000(\d+)\u0000/g,(r,o)=>'<pre class="caf-code">'+Se(a[Number(o)])+"</pre>"),t}function et({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:Q(e.content)}})}function Z({cfg:e,ctx:a}){let t=e,[r,o]=k(""),[s,i]=k(!1),[c,f]=k(null),l=pe(null),d=a.data.chat||{api:[],log:[]},m=d.log||[];S(()=>{l.current&&l.current.scrollIntoView({block:"end"})},[m.length,c]);async function h(){let u=r.trim();if(!u||s)return;o(""),i(!0);let b=[...d.api||[],{role:"user",content:u}],v=[...m,{role:"user",content:u}],A=()=>a.update(x=>{x.chat={api:b,log:v}});A();try{let x=(typeof t.system=="function"?t.system(a.data):t.system||"")+(t.tools?Ge(t.tools):"");for(let T=0;T<We;T++){let p=await Xe({model:t.model||Ue,maxTokens:t.maxTokens||2e3,system:x,messages:b,onText:H=>f(Ne(H))});b=[...b,{role:"assistant",content:p}];let y=Ne(p),$=t.tools?Qe(p):null;if(!$){v=[...v,{role:"assistant",content:y||p}],A();break}let De=Ze($,t.tools,a);y&&(v=[...v,{role:"assistant",content:y}]),v=[...v,{role:"tools",tools:$.map(H=>H.name)}],b=[...b,{role:"user",content:`[TOOL_RESULT]
25
- ${JSON.stringify(De)}
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 nt(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 $e=e=>String(e).replace(/[&<>"]/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"})[t]);function ee(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=$e(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">'+$e(t[Number(o)])+"</pre>"),a}function ot({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:ee(e.content)}})}function ae({cfg:e,ctx:t,title:a}){let r=e,[o,s]=v(""),[i,c]=v(!1),[f,l]=v(null),d=he(null),p=t.data.chat||{api:[],log:[]},u=p.log||[];E(()=>{d.current&&d.current.scrollIntoView({block:"end"})},[u.length,f]);async function b(){let m=o.trim();if(!m||i)return;s(""),c(!0);let w=[...p.api||[],{role:"user",content:m}],x=[...u,{role:"user",content:m}],T=()=>t.update(N=>{N.chat={api:w,log:x}});T();try{let N=(typeof r.system=="function"?r.system(t.data):r.system||"")+(r.tools?rt(r.tools):"");for(let h=0;h<et;h++){let y=await tt({model:r.model||Ze,maxTokens:r.maxTokens||2e3,system:N,messages:w,onText:J=>l(Ee(J))});w=[...w,{role:"assistant",content:y}];let C=Ee(y),H=r.tools?at(y):null;if(!H){x=[...x,{role:"assistant",content:C||y}],T();break}let Ye=nt(H,r.tools,t);C&&(x=[...x,{role:"assistant",content:C}]),x=[...x,{role:"tools",tools:H.map(J=>J.name)}],w=[...w,{role:"user",content:`[TOOL_RESULT]
25
+ ${JSON.stringify(Ye)}
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.`}],A(),f(null)}}catch(x){v=[...v,{role:"error",content:String(x&&x.message||x)}],A()}finally{f(null),i(!1)}}return n("div",{className:"caf-chat-panel"},n("div",{className:"caf-block caf-chat-log"},t.greeting?n("div",{className:"caf-msg caf-msg-assistant",dangerouslySetInnerHTML:{__html:Q(t.greeting)}}):null,m.map((u,b)=>n(et,{key:b,m:u})),c!==null?n("div",{className:"caf-msg caf-msg-assistant caf-msg-live",dangerouslySetInnerHTML:{__html:Q(c||"\u2026")}}):null,s&&c===null?n("div",{className:"caf-msg-tools"},"thinking\u2026"):null,n("div",{ref:l})),n("div",{className:"caf-chat-input"},n("input",{value:r,placeholder:t.placeholder||"Message\u2026",disabled:s,enterKeyHint:"send",onChange:u=>o(u.target.value),onKeyDown:u=>{u.key==="Enter"&&(u.preventDefault(),h())},"aria-label":"Message"}),n("button",{type:"button",className:"caf-btn caf-btn-primary",disabled:s||!r.trim(),onClick:h},"Send")))}function Ee({spec:e,ctx:a}){return n("div",{className:"caf-panel caf-panel-single"},n(Z,{cfg:e.chat,ctx:a}))}var ee=["text","textarea","number","money","percent","check","date","select","file"];function N(e,a){if(e==null||e==="")return"\u2014";let t=Number(e);switch(a){case"money":return Number.isFinite(t)?t.toLocaleString(void 0,{style:"currency",currency:"USD",maximumFractionDigits:2}):String(e);case"percent":return Number.isFinite(t)?`${t.toLocaleString(void 0,{maximumFractionDigits:2})}%`:String(e);case"number":return Number.isFinite(t)?t.toLocaleString(void 0,{maximumFractionDigits:2}):String(e);case"date":return e instanceof Date?e.toLocaleDateString():String(e);default:return String(e)}}function te(e,a){if(e.required&&(a===""||a===null||a===void 0))return"Required";if(a===""||a===null||a===void 0)return null;if(e.type==="number"||e.type==="money"||e.type==="percent"){let t=Number(a);if(!Number.isFinite(t))return"Must be a number";if(e.min!==void 0&&t<e.min)return`Must be at least ${e.min}`;if(e.max!==void 0&&t>e.max)return`Must be at most ${e.max}`}return null}function R({field:e,value:a,onChange:t,data:r}){let o=te(e,a),s=`caf-f-${e.key}`,i=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=>t(l.target.files&&l.target.files[0]?l.target.files[0]:null)}),a&&a.name?n("small",{className:"caf-hint"},`${a.name} (${Math.round((a.size||0)/1024)} KB)${a.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:!!a,onChange:l=>t(l.target.checked)}),n("span",null,e.label||e.key));let c={id:s,value:a??"","aria-invalid":o?"true":void 0,onChange:l=>t(i?tt(l.target.value):l.target.value)},f;if(e.type==="textarea")f=n("textarea",{...c,rows:e.rows||3});else if(e.type==="select"){let l=typeof e.options=="function"?e.options(r)||[]:e.options||[];f=n("select",c,n("option",{value:""},e.placeholder||"Select\u2026"),l.map(d=>{let m=typeof d=="string"?d:d.value,h=typeof d=="string"?d:d.label;return n("option",{key:m,value:m},h)}))}else f=n("input",{...c,type:e.type==="date"?"date":i?"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),f,e.hint&&!o?n("small",{className:"caf-hint"},e.hint):null,o?n("small",{className:"caf-error"},o):null)}function tt(e){if(e==="")return"";let a=Number(e);return Number.isFinite(a)?a:e}function ae(e,a,t,r,o){if(t.type==="file"){e.files[a]=r||null;let s=r?{name:r.name,size:r.size,type:r.type}:null;e.update(i=>o(i,s));return}e.update(s=>o(s,r))}function at({spec:e,ctx:a}){let t=e.fields||[];return n("div",{className:"caf-block caf-fields"},e.title?n("h2",{className:"caf-block-title"},e.title):null,t.map(r=>n(R,{key:r.key,field:r,data:a.data,value:a.data[r.key],onChange:o=>ae(a,r.key,r,o,(s,i)=>{s[r.key]=i})})))}function rt({spec:e,ctx:a}){let t=typeof e.output=="function"?e.output(a.data):e.output||[];return t.length?n("div",{className:"caf-block caf-output"},e.title?n("h2",{className:"caf-block-title"},e.title):null,n("div",{className:"caf-output-grid"},t.map((r,o)=>n("div",{key:r.label||o,className:r.big?"caf-stat caf-stat-big":"caf-stat"},n("span",{className:"caf-stat-label"},r.label),n("span",{className:"caf-stat-value"},N(r.value,r.format)),r.hint?n("small",{className:"caf-hint"},r.hint):null)))):n("div",{className:"caf-block caf-empty"},e.empty||"Nothing to show yet.")}function nt({spec:e,ctx:a}){let t=typeof e.text=="function"?e.text(a.data):e.text;return n("div",{className:"caf-block caf-text"},e.title?n("h2",{className:"caf-block-title"},e.title):null,n("p",null,t))}function ot({spec:e,ctx:a}){let t=(typeof e.list=="function"?e.list(a.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 t.length?n("div",{className:"caf-block caf-list"},r?n("h2",{className:"caf-block-title"},r):null,t.map((s,i)=>n("button",{key:s.id??i,className:"caf-row",type:"button",onClick:e.onSelect?()=>e.onSelect(s,a):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 $e=["bar","line","donut"];function st({spec:e,ctx:a}){let t=typeof e.chart=="function"?e.chart(a.data):e.chart,r=t&&t.items||[];if(!r.length)return n("div",{className:"caf-block caf-empty"},e.empty||"No data to chart yet.");let o=t.type||"bar";if(!$e.includes(o))throw new Error(`unknown chart type "${o}". Valid types: ${$e.join(", ")}.`);let s=a.colors(r.length),i=o==="bar"?it(r,t,s):o==="line"?ct(r,t):lt(r,t,s);return n("div",{className:"caf-block caf-chart"},e.title?n("h2",{className:"caf-block-title"},e.title):null,i)}function it(e,a,t){let r=Math.max(...e.map(o=>Number(o.value)||0),0)||1;return n("div",{className:"caf-bars"},e.map((o,s)=>n("div",{key:o.label??s,className:"caf-bar-row"},n("span",{className:"caf-bar-label"},o.label),n("div",{className:"caf-bar-track"},n("div",{className:"caf-bar-fill",style:{width:`${Math.max(2,(Number(o.value)||0)/r*100)}%`,background:t[s]}})),n("span",{className:"caf-bar-value"},N(o.value,a.format)))))}function ct(e,a){let t=e.map(d=>Number(d.value)||0),r=Math.min(...t),s=Math.max(...t)-r||1,i=100,c=36,f=t.map((d,m)=>[t.length===1?i/2:m/(t.length-1)*i,c-3-(d-r)/s*(c-6)]),l=f[f.length-1];return n("div",{className:"caf-line"},n("svg",{viewBox:`0 0 ${i} ${c}`,className:"caf-line-svg",preserveAspectRatio:"none","aria-hidden":"true"},[.25,.5,.75].map(d=>n("line",{key:d,x1:0,x2:i,y1:c*d,y2:c*d,className:"caf-line-grid"})),n("polyline",{points:f.map(d=>d.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"},N(t[t.length-1],a.format)),n("span",{className:"caf-hint"},String(e[e.length-1].label??""))))}function lt(e,a,t){let r=e.reduce((c,f)=>c+(Number(f.value)||0),0)||1,o=15.9155,s=25,i=e.map((c,f)=>{let l=(Number(c.value)||0)/r*100,d=n("circle",{key:c.label??f,cx:21,cy:21,r:o,className:"caf-donut-seg",stroke:t[f],strokeDasharray:`${l} ${100-l}`,strokeDashoffset:s});return s-=l,d});return n("div",{className:"caf-donut"},n("svg",{viewBox:"0 0 42 42",className:"caf-donut-svg","aria-hidden":"true"},i),n("div",{className:"caf-donut-legend"},e.map((c,f)=>n("div",{key:c.label??f,className:"caf-legend-row"},n("span",{className:"caf-legend-swatch",style:{background:t[f]}}),n("span",{className:"caf-legend-label"},c.label),n("span",{className:"caf-legend-value"},N(c.value,a.format))))))}function ft({spec:e,ctx:a}){let t=e.timer||{},r=Math.max(1,Math.round((t.minutes||0)*60+(t.seconds||0))||300),[o,s]=k(r),[i,c]=k(!1);S(()=>{if(!i)return;let m=setInterval(()=>s(h=>Math.max(0,h-1)),1e3);return()=>clearInterval(m)},[i]),S(()=>{o===0&&i&&(c(!1),typeof t.onDone=="function"&&a.update(m=>t.onDone(m)))},[o,i]);let f=String(Math.floor(o/60)).padStart(2,"0"),l=String(o%60).padStart(2,"0"),d=o===0;return n("div",{className:"caf-block caf-timer"},e.title?n("h2",{className:"caf-block-title"},e.title):null,t.label?n("span",{className:"caf-hint"},t.label):null,n("div",{className:d?"caf-timer-time caf-timer-done":"caf-timer-time"},d?t.doneText||"Done!":`${f}:${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:d,onClick:()=>c(m=>!m)},i?"Pause":"Start"),n("button",{type:"button",className:"caf-btn",onClick:()=>{c(!1),s(r)}},"Reset")))}function dt({spec:e,ctx:a}){let r=(e.actions||[]).filter(o=>!o.when||o.when(a.data,a.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:()=>a.update(s=>o.run(s,a.viewerId))},o.label))))}function ut({spec:e,ctx:a}){let t=e.custom(a),r=e.fill?"caf-block caf-block-fill":"caf-block";return typeof t=="string"?n("div",{className:r,dangerouslySetInnerHTML:{__html:t}}):n("div",{className:r},t)}var re={fields:at,output:rt,text:nt,list:ot,chart:st,timer:ft,actions:dt,chat:({spec:e,ctx:a})=>n(Z,{cfg:e.chat,ctx:a}),custom:ut},V=Object.keys(re);function Ce(e){return Object.entries(e.compute||{}).map(([a,t])=>[a,typeof t=="function"?{value:t}:t])}function ne(e,a){if(!e.compute)return a;let t={...a};for(let[r,o]of Ce(e))try{t[r]=o.value(a)}catch{t[r]=void 0}return t}function Ae(e){let a={};for(let t of e)a[t.key]=t.value!==void 0?t.value:t.type==="check"?!1:"";return a}function Te(){return"r"+Date.now().toString(36)+Math.random().toString(36).slice(2,8)}function mt(e,a){if(e.title)return e.title(a);let t=e.fields.find(o=>!o.type||o.type==="text"||o.type==="textarea"||o.type==="select"),r=t&&a[t.key];return r===""||r===void 0||r===null?"(untitled)":String(r)}function pt({spec:e,records:a}){if(!e.summary)return null;let t=e.summary(a)||[];return t.length?n("div",{className:"caf-block caf-output"},n("div",{className:"caf-output-grid"},t.map((r,o)=>n("div",{key:r.label||o,className:r.big?"caf-stat caf-stat-big":"caf-stat"},n("span",{className:"caf-stat-label"},r.label),n("span",{className:"caf-stat-value"},N(r.value,r.format)))))):null}function bt({spec:e,ctx:a}){let t=e.label||"item",[r,o]=k(""),s=a.data.records.map(l=>ne(e,l));e.sort&&(s=s.slice().sort(e.sort));let i=s.length,c=r.trim().toLowerCase();e.search&&c&&(s=s.filter(l=>e.fields.some(d=>String(l[d.key]??"").toLowerCase().includes(c))));function f(){let l={id:Te(),...Ae(e.fields)};e.items&&(l.items=[]),a.update(d=>{d.records=[...d.records,l]}),a.go("record",l.id)}return n("div",{className:"caf-block caf-list"},n("div",{className:"caf-toolbar"},n("span",{className:"caf-count"},e.search&&c?`${s.length} of ${i}`:`${i} ${t}${i===1?"":"s"}`),n("button",{type:"button",className:"caf-btn caf-btn-primary",onClick:f},`Add ${t}`)),e.search?n("input",{className:"caf-search",value:r,placeholder:`Search ${t}s\u2026`,"aria-label":"Search",onChange:l=>o(l.target.value)}):null,e.search&&c&&s.length===0&&i>0?n("div",{className:"caf-empty"},`Nothing matches "${r}".`):null,s.length===0?n("div",{className:"caf-empty"},e.empty||`No ${t}s yet. Add the first one.`):s.map(l=>n("div",{key:l.id,className:"caf-row-wrap"},n("button",{type:"button",className:"caf-row",onClick:()=>a.go("record",l.id)},n("span",{className:"caf-row-title"},mt(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(d=>!d.when||d.when(l,a.viewerId)).map(d=>n("button",{key:d.label,type:"button",className:d.kind==="danger"?"caf-btn caf-btn-danger caf-btn-sm":"caf-btn caf-btn-sm",onClick:()=>a.update(m=>{let h=m.records.find(u=>u.id===l.id);h&&d.run(h,m,a.viewerId)})},d.label))):null)))}function ht({spec:e,ctx:a,record:t}){let r=e.label||"item";function o(){a.update(s=>{s.records=s.records.filter(i=>i.id!==t.id)}),a.back()}return n("div",{className:"caf-block caf-fields"},n("div",{className:"caf-toolbar"},n("button",{type:"button",className:"caf-btn",onClick:a.back},"\u2039 Back"),n("button",{type:"button",className:"caf-btn caf-btn-danger",onClick:o},`Delete ${r}`)),e.fields.map(s=>n(R,{key:s.key,field:s,data:a.data,value:t[s.key],onChange:i=>a.update(c=>{let f=c.records.find(l=>l.id===t.id);f&&(f[s.key]=i)})})),e.items?n(gt,{spec:e,ctx:a,record:t}):null,e.compute?n("div",{className:"caf-output-grid caf-computed"},Ce(e).map(([s,i])=>{let c=ne(e,t);return n("div",{key:s,className:"caf-stat"},n("span",{className:"caf-stat-label"},i.label||s),n("span",{className:"caf-stat-value"},N(c[s],i.format)))})):null)}function gt({spec:e,ctx:a,record:t}){let r=e.items,o=r.label||"item";function s(c){a.update(f=>{let l=f.records.find(d=>d.id===t.id);l&&(Array.isArray(l.items)||(l.items=[]),c(l))})}let i=Array.isArray(t.items)?t.items:[];return n("div",{className:"caf-items"},n("div",{className:"caf-toolbar"},n("span",{className:"caf-count"},`${i.length} ${o}${i.length===1?"":"s"}`),n("button",{type:"button",className:"caf-btn caf-btn-sm",onClick:()=>s(c=>c.items.push({id:Te(),...Ae(r.fields)}))},`Add ${o}`)),i.length===0?n("div",{className:"caf-empty caf-empty-sm"},r.empty||`No ${o}s yet.`):i.map(c=>n("div",{key:c.id,className:"caf-item-row"},r.fields.map(f=>n(R,{key:f.key,field:f,data:a.data,value:c[f.key],onChange:l=>s(d=>{let m=d.items.find(h=>h.id===c.id);m&&(m[f.key]=l)})})),n("button",{type:"button",className:"caf-btn caf-btn-danger caf-btn-sm caf-item-remove","aria-label":`Remove ${o}`,onClick:()=>s(f=>{f.items=f.items.filter(l=>l.id!==c.id)})},"\u2715"))))}function je({spec:e,ctx:a}){let t=e.records;if(a.view.screen==="record"){let r=a.data.records.find(o=>o.id===a.view.arg);if(r)return n("div",{className:"caf-panel caf-panel-single"},n(ht,{spec:t,ctx:a,record:r}))}return n("div",{className:"caf-panel caf-panel-single"},n(pt,{spec:t,records:a.data.records.map(r=>ne(t,r))}),n(bt,{spec:t,ctx:a}))}function yt(e,a){return(e.fields||[]).some(t=>te(t,a[t.key])!==null)}function wt({step:e,ctx:a}){let t=e.result(a.data)||[];return n("div",{className:"caf-block caf-output"},e.title?n("h2",{className:"caf-block-title"},e.title):null,n("div",{className:"caf-output-grid"},t.map((r,o)=>n("div",{key:r.label??o,className:r.big?"caf-stat caf-stat-big":"caf-stat"},n("span",{className:"caf-stat-label"},r.label),n("span",{className:"caf-stat-value"},N(r.value,r.format)),r.hint?n("small",{className:"caf-hint"},r.hint):null))),n("div",{className:"caf-step-nav"},n("button",{type:"button",className:"caf-btn",onClick:()=>a.setStep(0)},"Start over")))}function Oe({spec:e,ctx:a}){let t=e.steps,r=Math.min(Math.max(a.view.step||0,0),t.length-1),o=t[r],s=typeof o.result=="function",i=r===t.length-1;return n("div",{className:"caf-panel caf-panel-single"},n("div",{className:"caf-steps-progress"},n("span",{className:"caf-hint"},s?"Result":`Step ${r+1} of ${t.length}`),n("div",{className:"caf-bar-track"},n("div",{className:"caf-bar-fill caf-steps-fill",style:{width:`${(r+1)/t.length*100}%`}}))),s?n(wt,{step:o,ctx:a}):n("div",{className:"caf-block caf-fields"},o.title?n("h2",{className:"caf-block-title"},o.title):null,o.text?n("p",{className:"caf-step-text"},typeof o.text=="function"?o.text(a.data):o.text):null,(o.fields||[]).map(c=>n(R,{key:c.key,field:c,data:a.data,value:a.data[c.key],onChange:f=>ae(a,c.key,c,f,(l,d)=>{l[c.key]=d})})),n("div",{className:"caf-step-nav"},r>0?n("button",{type:"button",className:"caf-btn",onClick:()=>a.setStep(r-1)},"\u2039 Back"):n("span"),i?null:n("button",{type:"button",className:"caf-btn caf-btn-primary",disabled:yt(o,a.data),onClick:()=>a.setStep(r+1)},"Next \u203A"))))}var Re=["panel","records","steps","chat","workspace"],kt=["title","empty","wide","onSelect","subtitle","when","collapsible","fill"],Le=["title","subtitle","theme","layout","blocks","records","steps","chat","data","shared","main","sidebar","libs"];function F(e,a){for(let t of e||[]){if(!t||!t.key)throw new Error(`claude-artifact-framework: every field in ${a} needs a \`key\`.`);if(t.type!==void 0&&!ee.includes(t.type))throw new Error(`claude-artifact-framework: field "${t.key}" in ${a} has unknown type "${t.type}". Valid types: ${ee.join(", ")}.`);if(t.type==="select"&&t.options!==void 0&&!Array.isArray(t.options)&&typeof t.options!="function")throw new Error(`claude-artifact-framework: field "${t.key}" in ${a}: \`options\` must be an array or a function of data returning one.`)}}function _e(e,a){if(!e||typeof e.system!="string"&&typeof e.system!="function")throw new Error(`claude-artifact-framework: ${a} needs \`{ system: "..." }\` (a string or a function of data).`);let t=Object.keys(e).filter(r=>!G.includes(r));if(t.length)throw new Error(`claude-artifact-framework: ${a} has unknown keys (${t.join(", ")}). Valid keys: ${G.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 Me=["label","run","when","kind"];function ze(e,a){if(!Array.isArray(e))throw new Error(`claude-artifact-framework: ${a} must be an array of { label, run }.`);e.forEach((t,r)=>{if(!t||typeof t.label!="string"||typeof t.run!="function")throw new Error(`claude-artifact-framework: ${a}[${r}] needs a \`label\` string and a \`run\` function.`);let o=Object.keys(t).filter(s=>!Me.includes(s));if(o.length)throw new Error(`claude-artifact-framework: ${a}[${r}] has unknown keys (${o.join(", ")}). Valid keys: ${Me.join(", ")}.`)})}function M(e){if(!Array.isArray(e))throw new Error("claude-artifact-framework: `blocks` must be an array.");e.forEach((a,t)=>{if(!a||typeof a!="object")throw new Error(`claude-artifact-framework: blocks[${t}] must be an object like { fields: [...] }.`);let r=Object.keys(a).filter(s=>!kt.includes(s)),o=r.filter(s=>V.includes(s)||s==="tabs");if(o.length===0)throw new Error(`claude-artifact-framework: blocks[${t}] has no recognised block type (found: ${r.join(", ")||"nothing"}). Valid block types: ${V.join(", ")}.`);if(o.length>1)throw new Error(`claude-artifact-framework: blocks[${t}] declares more than one block type (${o.join(", ")}). Split them into separate entries of \`blocks\`.`);if(F(a.fields,`blocks[${t}]`),o[0]==="actions"&&ze(a.actions,`blocks[${t}].actions`),o[0]==="chat"&&_e(a.chat,`blocks[${t}].chat`),o[0]==="tabs"){let s=a.tabs;if(!Array.isArray(s)||s.length===0)throw new Error(`claude-artifact-framework: blocks[${t}].tabs needs an array of { label, blocks: [...] }.`);s.forEach((i,c)=>{if(!i||typeof i.label!="string"||!Array.isArray(i.blocks)||i.blocks.length===0)throw new Error(`claude-artifact-framework: tabs[${c}] needs a \`label\` string and a non-empty \`blocks\` array.`);if(i.blocks.some(f=>f&&f.tabs))throw new Error("claude-artifact-framework: tabs cannot nest inside tabs.");M(i.blocks)})}if(a.when!==void 0&&typeof a.when!="function")throw new Error(`claude-artifact-framework: blocks[${t}].when must be a function of data returning true/false.`);if(a.fill!==void 0&&o[0]!=="custom")throw new Error(`claude-artifact-framework: \`fill\` is only valid on custom blocks \u2014 blocks[${t}] is "${o[0]}".`)})}function vt(e){let a=Object.keys(e).filter(r=>!Le.includes(r));if(a.length)throw new Error(`claude-artifact-framework: unknown top-level keys (${a.join(", ")}). Valid keys: ${Le.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 t=e.layout||"panel";if(!Re.includes(t))throw new Error(`claude-artifact-framework: unknown layout "${t}". Valid layouts: ${Re.join(", ")}.`);if(t==="steps"){let r=e.steps;if(!Array.isArray(r)||r.length===0)throw new Error('claude-artifact-framework: layout "steps" needs `steps: [...]` with at least one step.');let o=["title","text","fields","result"],s=new Set;return r.forEach((i,c)=>{if(!i||typeof i!="object")throw new Error(`claude-artifact-framework: steps[${c}] must be an object.`);let f=Object.keys(i).filter(l=>!o.includes(l));if(f.length)throw new Error(`claude-artifact-framework: steps[${c}] has unknown keys (${f.join(", ")}). Valid keys: ${o.join(", ")}.`);if(!i.fields&&!i.text&&!i.result)throw new Error(`claude-artifact-framework: steps[${c}] needs \`fields\`, \`text\`, or \`result\`.`);F(i.fields,`steps[${c}]`);for(let l of i.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)}}),t}if(t==="chat")return _e(e.chat,"chat"),t;if(t==="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(M(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.");M(e.sidebar)}if(se([...e.main,...e.sidebar||[]]).filter(o=>o&&o.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 t}if(t==="records"){let r=e.records;if(!r||!Array.isArray(r.fields)||r.fields.length===0)throw new Error('claude-artifact-framework: layout "records" needs `records: { fields: [...] }` \u2014 the same field declarations the fields block uses.');let o=["label","fields","title","subtitle","sort","summary","empty","search","compute","items","actions"],s=Object.keys(r).filter(c=>!o.includes(c));if(s.length)throw new Error(`claude-artifact-framework: records has unknown keys (${s.join(", ")}). Valid keys: ${o.join(", ")}.`);if(F(r.fields,"records"),r.fields.some(c=>c.type==="file")||r.items&&r.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 i=new Set;for(let c of r.fields){if(c.key==="id")throw new Error('claude-artifact-framework: "id" is reserved on records \u2014 the framework assigns it.');if(i.has(c.key))throw new Error(`claude-artifact-framework: duplicate records field key "${c.key}".`);i.add(c.key)}if(e.blocks&&M(e.blocks),r.actions&&ze(r.actions,"records.actions"),r.items){let c=["label","fields","empty"],f=Object.keys(r.items).filter(l=>!c.includes(l));if(f.length)throw new Error(`claude-artifact-framework: records.items has unknown keys (${f.join(", ")}). Valid keys: ${c.join(", ")}.`);if(!Array.isArray(r.items.fields)||r.items.fields.length===0)throw new Error("claude-artifact-framework: records.items needs `fields: [...]` \u2014 the same field declarations as everywhere else.");F(r.items.fields,"records.items");for(let l of r.items.fields)if(l.key==="id")throw new Error('claude-artifact-framework: "id" is reserved on items \u2014 the framework assigns it.');if(i.has("items")||r.fields.some(l=>l.key==="items"))throw new Error('claude-artifact-framework: a records field cannot be named "items" when `items` is declared \u2014 that key holds the child collection.')}for(let[c,f]of Object.entries(r.compute||{})){if(i.has(c)||c==="id"||r.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 f!="function"&&typeof(f&&f.value)!="function")throw new Error(`claude-artifact-framework: compute "${c}" must be a function of the record, or { label, format, value: (r) => ... }.`)}return t}return M(e.blocks||[]),t}function se(e){let a=[];for(let t of e||[])if(a.push(t),t&&Array.isArray(t.tabs))for(let r of t.tabs)a.push(...se(r.blocks));return a}function xt(e){let a={...e.data||{}};(e.layout||"panel")==="records"&&!Array.isArray(a.records)&&(a.records=[]);let t=se([...e.blocks||[],...e.main||[],...e.sidebar||[]]);((e.layout||"panel")==="chat"||t.some(o=>o&&o.chat))&&!a.chat&&(a.chat={api:[],log:[]});for(let o of[...t,...e.steps||[]])for(let s of o.fields||[])s&&s.key!==void 0&&!(s.key in a)&&(a[s.key]=s.value!==void 0?s.value:s.type==="check"?!1:"");return a}var oe=null;function Nt(e){return oe||(oe=class extends e.Component{constructor(a){super(a),this.state={error:null}}static getDerivedStateFromError(a){return{error:a}}render(){return this.state.error?n("div",{className:"caf-block caf-block-error"},n("strong",null,"This section failed to render"),n("code",null,String(this.state.error.message||this.state.error))):this.props.children}}),oe}function St({spec:e,ctx:a}){let t=e.tabs,r=t.map(i=>i.label).join("|"),o=a.view.tabs?a.view.tabs[r]:void 0,s=Math.min(o===void 0?0:o,t.length-1);return n("div",{className:"caf-tabs"},n("div",{className:"caf-tabbar",role:"tablist"},t.map((i,c)=>n("button",{key:i.label,type:"button",role:"tab","aria-selected":c===s,className:c===s?"caf-tab caf-tab-active":"caf-tab",onClick:()=>a.setTab(r,c)},i.label))),n("div",{className:"caf-tabs-body"},t[s].blocks.map((i,c)=>n(P,{key:s+":"+c,block:i,ctx:a}))))}var Et={...re,tabs:St},$t=[...V,"tabs"];function P({block:e,ctx:a}){if(typeof e.when=="function"&&!e.when(a.data))return null;let t=Object.keys(e).find(c=>$t.includes(c)),r=Et[t],o=n(Nt(a.React),null,n(r,{spec:e.collapsible?{...e,title:void 0}:e,ctx:a}));if(!e.collapsible)return o;let s=typeof e.title=="string"&&e.title?e.title:t,i=a.view.collapsed&&s in a.view.collapsed?a.view.collapsed[s]:e.collapsible==="collapsed";return n("div",{className:"caf-collapse"},n("button",{type:"button",className:"caf-collapse-head","aria-expanded":!i,onClick:()=>a.toggleCollapsed(s,!i)},n("span",null,e.title||t),n("span",{className:i?"caf-chevron caf-chevron-closed":"caf-chevron"},"\u25BE")),i?null:n("div",{className:"caf-collapse-body"},o))}function Ct({spec:e,ctx:a}){return n("div",{className:"caf-panel"},(e.blocks||[]).map((t,r)=>n("section",{key:r,className:t.wide||t.collapsible?"caf-slot caf-slot-wide":"caf-slot"},n(P,{block:t,ctx:a}))))}function At({spec:e,ctx:a}){let t=a.view.screen==="record"&&(a.data.records||[]).some(r=>r.id===a.view.arg);return n("div",null,n(je,{spec:e,ctx:a}),!t&&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(P,{block:r,ctx:a})))):null)}function Tt({spec:e,ctx:a}){let t=r=>(r||[]).map((o,s)=>n("section",{key:s,className:"caf-ws-slot"},n(P,{block:o,ctx:a})));return n("div",{className:"caf-workspace"},n("div",{className:"caf-ws-main"},t(e.main)),e.sidebar&&e.sidebar.length?n("div",{className:"caf-ws-side"},t(e.sidebar)):null)}var jt={panel:Ct,records:At,steps:Oe,chat:Ee,workspace:Tt};function Be(e){return new Promise((a,t)=>{let r=document.querySelector(`script[src="${e}"]`);if(r){if(r.dataset.cafReady==="1")return a();r.addEventListener("load",a),r.addEventListener("error",()=>t(new Error(`failed to load ${e}`)));return}let o=document.createElement("script");o.src=e,o.onload=()=>{o.dataset.cafReady="1",a()},o.onerror=()=>{let s=e.match(/^(https:\/\/cdn\.jsdelivr\.net\/npm\/(?:@[^/]+\/)?[^/]+)\/.+/);s&&s[1]!==e?Be(s[1]).then(a,()=>t(new Error(`failed to load ${e} (also tried package default ${s[1]})`))):t(new Error(`failed to load ${e}`))},document.head.appendChild(o)})}function Ie(e={}){let a=vt(e),t=we(xt(e),{shared:!!e.shared}),r=D(e.theme&&e.theme.seed)+Ot,o={};return function(){if(!_())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.`}],T(),l(null)}}catch(N){x=[...x,{role:"error",content:String(N&&N.message||N)}],T()}finally{l(null),c(!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:ee(r.greeting)}}):null,u.map((m,w)=>n(ot,{key:w,m})),f!==null?n("div",{className:"caf-msg caf-msg-assistant caf-msg-live",dangerouslySetInnerHTML:{__html:ee(f||"\u2026")}}):null,i&&f===null?n("div",{className:"caf-msg-tools"},"thinking\u2026"):null,n("div",{ref:d})),n("div",{className:"caf-chat-input"},n("input",{value:o,placeholder:r.placeholder||"Message\u2026",disabled:i,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:i||!o.trim(),onClick:b},"Send")))}function Ce({spec:e,ctx:t}){return n("div",{className:"caf-panel caf-panel-single"},n(ae,{cfg:e.chat,ctx:t}))}var re=["text","textarea","number","money","percent","check","date","select","file"];function S(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 ne(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 R({field:e,value:t,onChange:a,data:r}){let o=ne(e,t),s=`caf-f-${e.key}`,i=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 c={id:s,value:t??"","aria-invalid":o?"true":void 0,onChange:l=>a(i?st(l.target.value):l.target.value)},f;if(e.type==="textarea")f=n("textarea",{...c,rows:e.rows||3});else if(e.type==="select"){let l=typeof e.options=="function"?e.options(r)||[]:e.options||[];f=n("select",c,n("option",{value:""},e.placeholder||"Select\u2026"),l.map(d=>{let p=typeof d=="string"?d:d.value,u=typeof d=="string"?d:d.label;return n("option",{key:p,value:p},u)}))}else f=n("input",{...c,type:e.type==="date"?"date":i?"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),f,e.hint&&!o?n("small",{className:"caf-hint"},e.hint):null,o?n("small",{className:"caf-error"},o):null)}function st(e){if(e==="")return"";let t=Number(e);return Number.isFinite(t)?t:e}function oe(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(i=>o(i,s));return}e.update(s=>o(s,r))}function it({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(R,{key:r.key,field:r,data:t.data,value:t.data[r.key],onChange:o=>oe(t,r.key,r,o,(s,i)=>{s[r.key]=i})})))}function ct({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"},S(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 lt({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 ft({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,i)=>n("button",{key:s.id??i,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 Ae=["bar","line","donut"];function dt({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(!Ae.includes(o))throw new Error(`unknown chart type "${o}". Valid types: ${Ae.join(", ")}.`);let s=t.colors(r.length),i=o==="bar"?ut(r,a,s):o==="line"?mt(r,a):pt(r,a,s);return n("div",{className:"caf-block caf-chart"},e.title?n("h2",{className:"caf-block-title"},e.title):null,i)}function ut(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"},S(o.value,t.format)))))}function mt(e,t){let a=e.map(d=>Number(d.value)||0),r=Math.min(...a),s=Math.max(...a)-r||1,i=100,c=36,f=a.map((d,p)=>[a.length===1?i/2:p/(a.length-1)*i,c-3-(d-r)/s*(c-6)]),l=f[f.length-1];return n("div",{className:"caf-line"},n("svg",{viewBox:`0 0 ${i} ${c}`,className:"caf-line-svg",preserveAspectRatio:"none","aria-hidden":"true"},[.25,.5,.75].map(d=>n("line",{key:d,x1:0,x2:i,y1:c*d,y2:c*d,className:"caf-line-grid"})),n("polyline",{points:f.map(d=>d.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"},S(a[a.length-1],t.format)),n("span",{className:"caf-hint"},String(e[e.length-1].label??""))))}function pt(e,t,a){let r=e.reduce((c,f)=>c+(Number(f.value)||0),0)||1,o=15.9155,s=25,i=e.map((c,f)=>{let l=(Number(c.value)||0)/r*100,d=n("circle",{key:c.label??f,cx:21,cy:21,r:o,className:"caf-donut-seg",stroke:a[f],strokeDasharray:`${l} ${100-l}`,strokeDashoffset:s});return s-=l,d});return n("div",{className:"caf-donut"},n("svg",{viewBox:"0 0 42 42",className:"caf-donut-svg","aria-hidden":"true"},i),n("div",{className:"caf-donut-legend"},e.map((c,f)=>n("div",{key:c.label??f,className:"caf-legend-row"},n("span",{className:"caf-legend-swatch",style:{background:a[f]}}),n("span",{className:"caf-legend-label"},c.label),n("span",{className:"caf-legend-value"},S(c.value,t.format))))))}function bt({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),[i,c]=v(!1);E(()=>{if(!i)return;let p=setInterval(()=>s(u=>Math.max(0,u-1)),1e3);return()=>clearInterval(p)},[i]),E(()=>{o===0&&i&&(c(!1),typeof a.onDone=="function"&&t.update(p=>a.onDone(p)))},[o,i]);let f=String(Math.floor(o/60)).padStart(2,"0"),l=String(o%60).padStart(2,"0"),d=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:d?"caf-timer-time caf-timer-done":"caf-timer-time"},d?a.doneText||"Done!":`${f}:${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:d,onClick:()=>c(p=>!p)},i?"Pause":"Start"),n("button",{type:"button",className:"caf-btn",onClick:()=>{c(!1),s(r)}},"Reset")))}function ht({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 gt({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 se={fields:it,output:ct,text:lt,list:ft,chart:dt,timer:bt,actions:ht,chat:({spec:e,ctx:t})=>n(ae,{cfg:e.chat,ctx:t,title:e.title}),custom:gt},F=Object.keys(se);function Te(e){return Object.entries(e.compute||{}).map(([t,a])=>[t,typeof a=="function"?{value:a}:a])}function ie(e,t){if(!e.compute)return t;let a={...t};for(let[r,o]of Te(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 Oe(){return"r"+Date.now().toString(36)+Math.random().toString(36).slice(2,8)}function yt(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 wt({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"},S(r.value,r.format)))))):null}function kt({spec:e,ctx:t}){let a=e.label||"item",[r,o]=v(""),s=t.data.records.map(l=>ie(e,l));e.sort&&(s=s.slice().sort(e.sort));let i=s.length,c=r.trim().toLowerCase();e.search&&c&&(s=s.filter(l=>e.fields.some(d=>String(l[d.key]??"").toLowerCase().includes(c))));function f(){let l={id:Oe(),...je(e.fields)};e.items&&(l.items=[]),t.update(d=>{d.records=[...d.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&&c?`${s.length} of ${i}`:`${i} ${a}${i===1?"":"s"}`),n("button",{type:"button",className:"caf-btn caf-btn-primary",onClick:f},`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&&c&&s.length===0&&i>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"},yt(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(d=>!d.when||d.when(l,t.viewerId)).map(d=>n("button",{key:d.label,type:"button",className:d.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&&d.run(u,p,t.viewerId)})},d.label))):null)))}function vt({spec:e,ctx:t,record:a}){let r=e.label||"item";function o(){t.update(s=>{s.records=s.records.filter(i=>i.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(R,{key:s.key,field:s,data:t.data,value:a[s.key],onChange:i=>t.update(c=>{let f=c.records.find(l=>l.id===a.id);f&&(f[s.key]=i)})})),e.items?n(xt,{spec:e,ctx:t,record:a}):null,e.compute?n("div",{className:"caf-output-grid caf-computed"},Te(e).map(([s,i])=>{let c=ie(e,a);return n("div",{key:s,className:"caf-stat"},n("span",{className:"caf-stat-label"},i.label||s),n("span",{className:"caf-stat-value"},S(c[s],i.format)))})):null)}function xt({spec:e,ctx:t,record:a}){let r=e.items,o=r.label||"item";function s(c){t.update(f=>{let l=f.records.find(d=>d.id===a.id);l&&(Array.isArray(l.items)||(l.items=[]),c(l))})}let i=Array.isArray(a.items)?a.items:[];return n("div",{className:"caf-items"},n("div",{className:"caf-toolbar"},n("span",{className:"caf-count"},`${i.length} ${o}${i.length===1?"":"s"}`),n("button",{type:"button",className:"caf-btn caf-btn-sm",onClick:()=>s(c=>c.items.push({id:Oe(),...je(r.fields)}))},`Add ${o}`)),i.length===0?n("div",{className:"caf-empty caf-empty-sm"},r.empty||`No ${o}s yet.`):i.map(c=>n("div",{key:c.id,className:"caf-item-row"},r.fields.map(f=>n(R,{key:f.key,field:f,data:t.data,value:c[f.key],onChange:l=>s(d=>{let p=d.items.find(u=>u.id===c.id);p&&(p[f.key]=l)})})),n("button",{type:"button",className:"caf-btn caf-btn-danger caf-btn-sm caf-item-remove","aria-label":`Remove ${o}`,onClick:()=>s(f=>{f.items=f.items.filter(l=>l.id!==c.id)})},"\u2715"))))}function Re({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(vt,{spec:a,ctx:t,record:r}))}return n("div",{className:"caf-panel caf-panel-single"},n(wt,{spec:a,records:t.data.records.map(r=>ie(a,r))}),n(kt,{spec:a,ctx:t}))}function Nt(e,t){return(e.fields||[]).some(a=>ne(a,t[a.key])!==null)}function St({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"},S(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 Le({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",i=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(St,{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(c=>n(R,{key:c.key,field:c,data:t.data,value:t.data[c.key],onChange:f=>oe(t,c.key,c,f,(l,d)=>{l[c.key]=d})})),n("div",{className:"caf-step-nav"},r>0?n("button",{type:"button",className:"caf-btn",onClick:()=>t.setStep(r-1)},"\u2039 Back"):n("span"),i?null:n("button",{type:"button",className:"caf-btn caf-btn-primary",disabled:Nt(o,t.data),onClick:()=>t.setStep(r+1)},"Next \u203A"))))}var _e=["panel","records","steps","chat","workspace","documents"],Et=["title","empty","wide","onSelect","subtitle","when","collapsible","fill"],Me=["title","subtitle","theme","layout","blocks","records","steps","chat","data","shared","main","sidebar","libs","documents"],ze=["label","title","blocks","empty"];function P(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&&!re.includes(a.type))throw new Error(`claude-artifact-framework: field "${a.key}" in ${t} has unknown type "${a.type}". Valid types: ${re.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 Ie(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=>!te.includes(r));if(a.length)throw new Error(`claude-artifact-framework: ${t} has unknown keys (${a.join(", ")}). Valid keys: ${te.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 De=["label","run","when","kind"];function Ve(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=>!De.includes(s));if(o.length)throw new Error(`claude-artifact-framework: ${t}[${r}] has unknown keys (${o.join(", ")}). Valid keys: ${De.join(", ")}.`)})}function L(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=>!Et.includes(s)),o=r.filter(s=>F.includes(s)||s==="tabs");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.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(P(t.fields,`blocks[${a}]`),o[0]==="actions"&&Ve(t.actions,`blocks[${a}].actions`),o[0]==="chat"&&Ie(t.chat,`blocks[${a}].chat`),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((i,c)=>{if(!i||typeof i.label!="string"||!Array.isArray(i.blocks)||i.blocks.length===0)throw new Error(`claude-artifact-framework: tabs[${c}] needs a \`label\` string and a non-empty \`blocks\` array.`);if(i.blocks.some(f=>f&&f.tabs))throw new Error("claude-artifact-framework: tabs cannot nest inside tabs.");L(i.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 $t(e){let t=Object.keys(e).filter(r=>!Me.includes(r));if(t.length)throw new Error(`claude-artifact-framework: unknown top-level keys (${t.join(", ")}). Valid keys: ${Me.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(!_e.includes(a))throw new Error(`claude-artifact-framework: unknown layout "${a}". Valid layouts: ${_e.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((i,c)=>{if(!i||typeof i!="object")throw new Error(`claude-artifact-framework: steps[${c}] must be an object.`);let f=Object.keys(i).filter(l=>!o.includes(l));if(f.length)throw new Error(`claude-artifact-framework: steps[${c}] has unknown keys (${f.join(", ")}). Valid keys: ${o.join(", ")}.`);if(!i.fields&&!i.text&&!i.result)throw new Error(`claude-artifact-framework: steps[${c}] needs \`fields\`, \`text\`, or \`result\`.`);P(i.fields,`steps[${c}]`);for(let l of i.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 Ie(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(L(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.");L(e.sidebar)}if(_([...e.main,...e.sidebar||[]]).filter(o=>o&&o.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 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=>!ze.includes(i));if(o.length)throw new Error(`claude-artifact-framework: documents has unknown keys (${o.join(", ")}). Valid keys: ${ze.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.");L(r.blocks);let s=_(r.blocks);if(s.some(i=>i&&i.chat))throw new Error('claude-artifact-framework: a chat block inside "documents" is not supported \u2014 the conversation store is app-wide, not per document.');if(s.some(i=>(i.fields||[]).some(c=>c.type==="file")))throw new Error("claude-artifact-framework: `file` fields live in the flat data pool \u2014 they are not supported inside documents (the live File cannot be scoped per document).");return a}if(a==="records"){let r=e.records;if(!r||!Array.isArray(r.fields)||r.fields.length===0)throw new Error('claude-artifact-framework: layout "records" needs `records: { fields: [...] }` \u2014 the same field declarations the fields block uses.');let o=["label","fields","title","subtitle","sort","summary","empty","search","compute","items","actions"],s=Object.keys(r).filter(c=>!o.includes(c));if(s.length)throw new Error(`claude-artifact-framework: records has unknown keys (${s.join(", ")}). Valid keys: ${o.join(", ")}.`);if(P(r.fields,"records"),r.fields.some(c=>c.type==="file")||r.items&&r.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 i=new Set;for(let c of r.fields){if(c.key==="id")throw new Error('claude-artifact-framework: "id" is reserved on records \u2014 the framework assigns it.');if(i.has(c.key))throw new Error(`claude-artifact-framework: duplicate records field key "${c.key}".`);i.add(c.key)}if(e.blocks&&L(e.blocks),r.actions&&Ve(r.actions,"records.actions"),r.items){let c=["label","fields","empty"],f=Object.keys(r.items).filter(l=>!c.includes(l));if(f.length)throw new Error(`claude-artifact-framework: records.items has unknown keys (${f.join(", ")}). Valid keys: ${c.join(", ")}.`);if(!Array.isArray(r.items.fields)||r.items.fields.length===0)throw new Error("claude-artifact-framework: records.items needs `fields: [...]` \u2014 the same field declarations as everywhere else.");P(r.items.fields,"records.items");for(let l of r.items.fields)if(l.key==="id")throw new Error('claude-artifact-framework: "id" is reserved on items \u2014 the framework assigns it.');if(i.has("items")||r.fields.some(l=>l.key==="items"))throw new Error('claude-artifact-framework: a records field cannot be named "items" when `items` is declared \u2014 that key holds the child collection.')}for(let[c,f]of Object.entries(r.compute||{})){if(i.has(c)||c==="id"||r.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 f!="function"&&typeof(f&&f.value)!="function")throw new Error(`claude-artifact-framework: compute "${c}" must be a function of the record, or { label, format, value: (r) => ... }.`)}return a}return L(e.blocks||[]),a}function _(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.blocks));return t}function Ct(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=_([...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:"");return t}var ce=null;function At(e){return ce||(ce=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}}),ce}function Tt({spec:e,ctx:t}){let a=e.tabs,r=a.map(i=>i.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((i,c)=>n("button",{key:i.label,type:"button",role:"tab","aria-selected":c===s,className:c===s?"caf-tab caf-tab-active":"caf-tab",onClick:()=>t.setTab(r,c)},i.label))),n("div",{className:"caf-tabs-body"},a[s].blocks.map((i,c)=>n(Y,{key:s+":"+c,block:i,ctx:t}))))}var jt={...se,tabs:Tt},Ot=[...F,"tabs"];function Y({block:e,ctx:t}){if(typeof e.when=="function"&&!e.when(t.data))return null;let a=Object.keys(e).find(c=>Ot.includes(c)),r=jt[a],o=n(At(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,i=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":!i,onClick:()=>t.toggleCollapsed(s,!i)},n("span",null,e.title||a),n("span",{className:i?"caf-chevron caf-chevron-closed":"caf-chevron"},"\u25BE")),i?null:n("div",{className:"caf-collapse-body"},o))}function Fe({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(Y,{block:a,ctx:t}))))}function Rt({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(Re,{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(Y,{block:r,ctx:t})))):null)}function Lt({spec:e,ctx:t}){let a=r=>(r||[]).map((o,s)=>n("section",{key:s,className:"caf-ws-slot"},n(Y,{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 Be(e){let t={};for(let a of _(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:"");return t}function _t(){return"d"+Date.now().toString(36)+Math.random().toString(36).slice(2,8)}var K="caf:doc";function Mt(e,t){if(e.title)try{let a=e.title(t);if(a!=null&&a!=="")return String(a)}catch{}for(let a of _(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 zt({spec:e,ctx:t}){let a=e.documents,r=a.label||"document",o=Array.isArray(t.data.docs)?t.data.docs:[],s=Be(a),i=t.view.tabs?t.view.tabs[K]:void 0,c=o.find(u=>u.id===i)||o[0];function f(){let u={id:_t(),data:Be(a)};t.update(b=>{b.docs=[...b.docs||[],u]}),t.setTab(K,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)}),c&&c.id===u){let m=o[b+1]||o[b-1];m&&t.setTab(K,m.id)}}if(!c)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:f},`New ${r}`)));let d={...s,...c.data},p={...t,data:d,update:u=>t.update(b=>{let m=(b.docs||[]).find(w=>w.id===c.id);m&&u(m.data)})};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===c.id,className:u.id===c.id?"caf-tab caf-tab-active":"caf-tab",onClick:()=>t.setTab(K,u.id)},Mt(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:f},"+")),n(Fe,{spec:{blocks:a.blocks},ctx:p}))}var Dt={panel:Fe,records:Rt,steps:Le,chat:Ce,workspace:Lt,documents:zt};function Ke(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?Ke(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 Pe(e={}){let t=$t(e),a=ve(Ct(e),{shared:!!e.shared}),r=V(e.theme&&e.theme.seed)+Bt,o={};return function(){if(!z())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[,i]=k(0),[c,f]=k(e.libs&&e.libs.length?"loading":"ready"),[l,d]=k(null);S(()=>{!e.libs||!e.libs.length||Promise.all(e.libs.map(Be)).then(()=>f("ready"),u=>{d(String(u&&u.message||u)),f("error")})},[]),S(()=>{let u=t.subscribe(()=>i(b=>b+1));return t.isHydrated()&&i(b=>b+1),u},[]);let m={React:me(),data:t.getData(),view:t.getView(),update:t.update,go:t.go,back:t.back,setStep:u=>t.setView({step:u}),files:o,viewerId:t.getViewerId(),setTab:(u,b)=>t.setView({tabs:{...t.getView().tabs,[u]:b}}),toggleCollapsed:(u,b)=>t.setView({collapsed:{...t.getView().collapsed,[u]:b}}),colors:u=>xe(e.theme&&e.theme.seed,u)},h=jt[a];return n("div",{className:`caf-root caf-layout-${a}`},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),c==="error"?n("div",{className:"caf-block caf-block-error"},n("strong",null,"A library failed to load"),n("code",null,l)):!t.isHydrated()||c==="loading"?n("div",{className:"caf-block caf-loading"},c==="loading"?"Loading libraries\u2026":"Loading\u2026"):n(h,{spec:e,ctx:m}))}}var Ot=`
32
+ `);let[,i]=v(0),[c,f]=v(e.libs&&e.libs.length?"loading":"ready"),[l,d]=v(null);E(()=>{!e.libs||!e.libs.length||Promise.all(e.libs.map(Ke)).then(()=>f("ready"),b=>{d(String(b&&b.message||b)),f("error")})},[]),E(()=>{let b=a.subscribe(()=>i(m=>m+1));return a.isHydrated()&&i(m=>m+1),b},[]);let p={React:be(),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=>Se(e.theme&&e.theme.seed,b)},u=Dt[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),c==="error"?n("div",{className:"caf-block caf-block-error"},n("strong",null,"A library failed to load"),n("code",null,l)):!a.isHydrated()||c==="loading"?n("div",{className:"caf-block caf-loading"},c==="loading"?"Loading libraries\u2026":"Loading\u2026"):n(u,{spec:e,ctx:p}))}}var Bt=`
33
33
  .caf-root {
34
34
  --caf-radius: 10px;
35
35
  --caf-control-radius: 7px; /* one radius for every control: buttons, inputs, rows */
@@ -66,7 +66,9 @@ Continue with this information. If you have everything you need, answer in natur
66
66
  }
67
67
  .caf-block-title { margin: 0; font-size: 0.78rem; font-weight: 650; text-transform: uppercase; letter-spacing: 0.06em; color: var(--caf-muted); }
68
68
  .caf-field { display: flex; flex-direction: column; gap: 0.3rem; }
69
- .caf-field label { font-size: 0.72rem; font-weight: 500; color: var(--caf-muted); letter-spacing: 0.02em; }
69
+ /* A full size+weight step below .caf-block-title \u2014 the uppercase alone was
70
+ not enough to tell "card title" from "field label" at a glance. */
71
+ .caf-field label { font-size: 0.68rem; font-weight: 500; color: var(--caf-muted); }
70
72
  .caf-field input, .caf-field select, .caf-field textarea {
71
73
  font: inherit; font-size: 0.95rem; padding: 0.5rem 0.6rem;
72
74
  border-radius: var(--caf-control-radius); border: 1px solid var(--caf-border);
@@ -100,7 +102,9 @@ Continue with this information. If you have everything you need, answer in natur
100
102
  .caf-row-sub { font-size: 0.78rem; color: var(--caf-muted); }
101
103
  .caf-panel-single { grid-template-columns: 1fr; }
102
104
  .caf-panel-single .caf-slot, .caf-panel-single > * { grid-column: span 1; }
103
- .caf-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding: 0.3rem 0.3rem 0.5rem; }
105
+ /* Bottom padding matches the inter-row rhythm so the toolbar doesn't sit
106
+ closer to the first row than rows sit to each other. */
107
+ .caf-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding: 0.3rem 0.3rem 0.75rem; }
104
108
  .caf-count { font-size: 0.8rem; color: var(--caf-muted); font-variant-numeric: tabular-nums; }
105
109
  .caf-btn {
106
110
  font: inherit; font-size: 0.85rem; font-weight: 600; cursor: pointer;
@@ -125,7 +129,8 @@ Continue with this information. If you have everything you need, answer in natur
125
129
  .caf-line-meta { display: flex; justify-content: space-between; align-items: baseline; gap: 0.6rem; }
126
130
  .caf-line-last { font-weight: 650; font-variant-numeric: tabular-nums; color: var(--caf-accent); }
127
131
  .caf-donut { display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap; }
128
- .caf-donut-svg { width: 110px; height: 110px; flex: none; transform: rotate(0.001deg); }
132
+ /* -3px optical correction: a circle beside flush-left text reads indented. */
133
+ .caf-donut-svg { width: 110px; height: 110px; flex: none; transform: rotate(0.001deg); margin-left: -3px; }
129
134
  .caf-donut-seg { fill: none; stroke-width: 6; }
130
135
  /* Capped width keeps each value NEXT TO its label in wide cards \u2014 the pair
131
136
  must read as a pair regardless of container width. */
@@ -218,12 +223,24 @@ Continue with this information. If you have everything you need, answer in natur
218
223
  .caf-collapse-head { box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08); }
219
224
  .caf-collapse-head:hover { filter: brightness(0.97); }
220
225
  .caf-collapse-head:focus-visible { outline: 2px solid var(--caf-accent); outline-offset: 1px; }
221
- .caf-chevron { transition: transform 0.15s ease; color: var(--caf-muted); }
226
+ /* Accent chevron: the one interaction cue that distinguishes a collapsible
227
+ header from a static card title without breaking their shared typography. */
228
+ .caf-chevron { transition: transform 0.15s ease; color: var(--caf-accent); }
229
+ .caf-documents { max-width: 760px; margin: 0 auto; display: flex; flex-direction: column; gap: 1rem; }
230
+ .caf-doc-tab { display: inline-flex; align-items: center; }
231
+ .caf-doc-tab .caf-tab { padding-right: 0.35rem; max-width: 180px; overflow: hidden; text-overflow: ellipsis; }
232
+ .caf-doc-close {
233
+ font: inherit; font-size: 0.7rem; cursor: pointer; border: none; background: none;
234
+ color: var(--caf-muted); padding: 0.2rem 0.45rem 0.2rem 0.1rem; line-height: 1;
235
+ }
236
+ .caf-doc-close:hover { color: var(--caf-danger); }
237
+ .caf-doc-add { font-size: 1rem; font-weight: 650; }
238
+ .caf-empty .caf-btn { margin-top: 0.6rem; }
222
239
  .caf-chevron-closed { transform: rotate(-90deg); }
223
240
  .caf-block-fill { border: none; background: transparent; padding: 0; overflow: auto; min-height: 320px; }
224
241
  .caf-empty, .caf-loading { color: var(--caf-muted); font-size: 0.9rem; text-align: center; padding: 1.6rem 1rem; }
225
242
  .caf-block-error { border-color: var(--caf-danger); gap: 0.4rem; }
226
243
  .caf-block-error strong { font-size: 0.9rem; color: var(--caf-danger); }
227
244
  .caf-block-error code { font-size: 0.78rem; color: var(--caf-muted); word-break: break-word; }
228
- `;return Ye(Rt);})();
245
+ `;return Xe(It);})();
229
246
  //# sourceMappingURL=index.global.js.map