Buckets:

HuggingFaceDocBuilder's picture
download
raw
85.5 kB
import{s as _l,o as Hl,n as Cl}from"../chunks/scheduler.4048030c.js";import{S as Ll,i as Dl,e as u,s as p,c as h,h as Pl,a as J,d as l,b as e,f as Fl,j as w,g as T,k as dl,l as Kl,m as a,n as r,t as d,o as I,p as C}from"../chunks/index.5d0b9360.js";import{C as Ol,H as E,E as sa}from"../chunks/MermaidChart.svelte_svelte_type_style_lang.9a03e56b.js";import{C as Z}from"../chunks/CodeBlock.249eb434.js";import{H as la,a as Il}from"../chunks/HfOption.0fd5270b.js";function aa(R){let c,N="<code>.claude/settings.json</code>:",A,U,b,i,Q="Claude Code’s payload already includes <code>hook_event_name</code>, <code>tool_name</code>, and <code>tool_input</code>, so the normalizer picks them up without extra work. The <code>X-Platform</code> header tags them as <code>claude-code</code>.",f,n,B="Start a new Claude Code session in this project directory and ask it to do something concrete:",o,m,g;return U=new Z({props:{code:"JTdCJTBBJTIwJTIwJTIyaG9va3MlMjIlM0ElMjAlN0IlMEElMjAlMjAlMjAlMjAlMjJQcmVUb29sVXNlJTIyJTNBJTIwJTIwJTVCJTdCJTIwJTIybWF0Y2hlciUyMiUzQSUyMCUyMiolMjIlMkMlMjAlMjJob29rcyUyMiUzQSUyMCU1QiU3QiUyMCUyMnR5cGUlMjIlM0ElMjAlMjJodHRwJTIyJTJDJTIwJTIydXJsJTIyJTNBJTIwJTIyaHR0cCUzQSUyRiUyRmxvY2FsaG9zdCUzQTgwMDAlMkZldmVudCUyMiUyQyUyMCUyMmhlYWRlcnMlMjIlM0ElMjAlN0IlMjAlMjJYLVBsYXRmb3JtJTIyJTNBJTIwJTIyY2xhdWRlLWNvZGUlMjIlMjAlN0QlMjAlN0QlNUQlMjAlN0QlNUQlMkMlMEElMjAlMjAlMjAlMjAlMjJQb3N0VG9vbFVzZSUyMiUzQSUyMCU1QiU3QiUyMCUyMm1hdGNoZXIlMjIlM0ElMjAlMjIqJTIyJTJDJTIwJTIyaG9va3MlMjIlM0ElMjAlNUIlN0IlMjAlMjJ0eXBlJTIyJTNBJTIwJTIyaHR0cCUyMiUyQyUyMCUyMnVybCUyMiUzQSUyMCUyMmh0dHAlM0ElMkYlMkZsb2NhbGhvc3QlM0E4MDAwJTJGZXZlbnQlMjIlMkMlMjAlMjJoZWFkZXJzJTIyJTNBJTIwJTdCJTIwJTIyWC1QbGF0Zm9ybSUyMiUzQSUyMCUyMmNsYXVkZS1jb2RlJTIyJTIwJTdEJTIwJTdEJTVEJTIwJTdEJTVEJTJDJTBBJTIwJTIwJTIwJTIwJTIyVXNlclByb21wdFN1Ym1pdCUyMiUzQSUyMCU1QiU3QiUyMCUyMmhvb2tzJTIyJTNBJTIwJTVCJTdCJTIwJTIydHlwZSUyMiUzQSUyMCUyMmh0dHAlMjIlMkMlMjAlMjJ1cmwlMjIlM0ElMjAlMjJodHRwJTNBJTJGJTJGbG9jYWxob3N0JTNBODAwMCUyRmV2ZW50JTIyJTJDJTIwJTIyaGVhZGVycyUyMiUzQSUyMCU3QiUyMCUyMlgtUGxhdGZvcm0lMjIlM0ElMjAlMjJjbGF1ZGUtY29kZSUyMiUyMCU3RCUyMCU3RCU1RCUyMCU3RCU1RCUyQyUwQSUyMCUyMCUyMCUyMCUyMlN0b3AlMjIlM0ElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNUIlN0IlMjAlMjJob29rcyUyMiUzQSUyMCU1QiU3QiUyMCUyMnR5cGUlMjIlM0ElMjAlMjJodHRwJTIyJTJDJTIwJTIydXJsJTIyJTNBJTIwJTIyaHR0cCUzQSUyRiUyRmxvY2FsaG9zdCUzQTgwMDAlMkZldmVudCUyMiUyQyUyMCUyMmhlYWRlcnMlMjIlM0ElMjAlN0IlMjAlMjJYLVBsYXRmb3JtJTIyJTNBJTIwJTIyY2xhdWRlLWNvZGUlMjIlMjAlN0QlMjAlN0QlNUQlMjAlN0QlNUQlMkMlMEElMjAlMjAlMjAlMjAlMjJTZXNzaW9uU3RhcnQlMjIlM0ElMjAlMjAlMjAlMjAlNUIlN0IlMjAlMjJob29rcyUyMiUzQSUyMCU1QiU3QiUyMCUyMnR5cGUlMjIlM0ElMjAlMjJodHRwJTIyJTJDJTIwJTIydXJsJTIyJTNBJTIwJTIyaHR0cCUzQSUyRiUyRmxvY2FsaG9zdCUzQTgwMDAlMkZldmVudCUyMiUyQyUyMCUyMmhlYWRlcnMlMjIlM0ElMjAlN0IlMjAlMjJYLVBsYXRmb3JtJTIyJTNBJTIwJTIyY2xhdWRlLWNvZGUlMjIlMjAlN0QlMjAlN0QlNUQlMjAlN0QlNUQlMEElMjAlMjAlN0QlMEElN0Q=",highlighted:`<span class="hljs-punctuation">{</span>
<span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">&quot;PreToolUse&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;matcher&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;*&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;type&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;http&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;http://localhost:8000/event&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;headers&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;X-Platform&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;claude-code&quot;</span> <span class="hljs-punctuation">}</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">&quot;PostToolUse&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;matcher&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;*&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;type&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;http&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;http://localhost:8000/event&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;headers&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;X-Platform&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;claude-code&quot;</span> <span class="hljs-punctuation">}</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">&quot;UserPromptSubmit&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;type&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;http&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;http://localhost:8000/event&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;headers&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;X-Platform&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;claude-code&quot;</span> <span class="hljs-punctuation">}</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">&quot;Stop&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;type&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;http&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;http://localhost:8000/event&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;headers&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;X-Platform&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;claude-code&quot;</span> <span class="hljs-punctuation">}</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">&quot;SessionStart&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;type&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;http&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;http://localhost:8000/event&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;headers&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;X-Platform&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;claude-code&quot;</span> <span class="hljs-punctuation">}</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>`,lang:"json",wrap:!1}}),m=new Z({props:{code:"TGlzdCUyMHRoZSUyMGZpbGVzJTIwaW4lMjB0aGlzJTIwZGlyZWN0b3J5JTJDJTIwdGhlbiUyMHJlYWQlMjBSRUFETUUubWQlMjBhbmQlMjBzdW1tYXJpemUlMjBpdC4=",highlighted:'List <span class="hljs-keyword">the</span> <span class="hljs-built_in">files</span> <span class="hljs-keyword">in</span> this <span class="hljs-built_in">directory</span>, <span class="hljs-keyword">then</span> <span class="hljs-built_in">read</span> README.md <span class="hljs-keyword">and</span> summarize <span class="hljs-keyword">it</span>.',lang:"",wrap:!1}}),{c(){c=u("p"),c.innerHTML=N,A=p(),h(U.$$.fragment),b=p(),i=u("p"),i.innerHTML=Q,f=p(),n=u("p"),n.textContent=B,o=p(),h(m.$$.fragment)},l(M){c=J(M,"P",{"data-svelte-h":!0}),T(c)!=="svelte-1mw41u7"&&(c.innerHTML=N),A=e(M),w(U.$$.fragment,M),b=e(M),i=J(M,"P",{"data-svelte-h":!0}),T(i)!=="svelte-4v31qy"&&(i.innerHTML=Q),f=e(M),n=J(M,"P",{"data-svelte-h":!0}),T(n)!=="svelte-ce1hmd"&&(n.textContent=B),o=e(M),w(m.$$.fragment,M)},m(M,v){a(M,c,v),a(M,A,v),r(U,M,v),a(M,b,v),a(M,i,v),a(M,f,v),a(M,n,v),a(M,o,v),r(m,M,v),g=!0},p:Cl,i(M){g||(d(U.$$.fragment,M),d(m.$$.fragment,M),g=!0)},o(M){I(U.$$.fragment,M),I(m.$$.fragment,M),g=!1},d(M){M&&(l(c),l(A),l(b),l(i),l(f),l(n),l(o)),C(U,M),C(m,M)}}}function ta(R){let c,N="Make sure <code>~/.codex/config.toml</code> has:",A,U,b,i,Q="These examples assume <code>jq</code> and <code>curl</code> are installed and available on your <code>PATH</code>.",f,n,B="<code>.codex/hooks.json</code>:",o,m,g,M,v="Each hook reshapes Codex’s payload into the normalized <code>{platform, event, tool, args}</code> shape, then POSTs it. The <code>--max-time 2</code> on <code>curl</code> protects the agent from hanging if the dashboard is slow, and <code>|| true</code> keeps logging best-effort if the dashboard is offline.",j,q,Qs="Restart Codex to pick up the hooks, then try:",S,G,x;return U=new Z({props:{code:"JTVCZmVhdHVyZXMlNUQlMEFjb2RleF9ob29rcyUyMCUzRCUyMHRydWU=",highlighted:`<span class="hljs-section">[features]</span>
<span class="hljs-attr">codex_hooks</span> = <span class="hljs-literal">true</span>`,lang:"toml",wrap:!1}}),m=new Z({props:{code:"JTdCJTBBJTIwJTIwJTIyaG9va3MlMjIlM0ElMjAlN0IlMEElMjAlMjAlMjAlMjAlMjJQcmVUb29sVXNlJTIyJTNBJTIwJTIwJTVCJTdCJTIwJTIybWF0Y2hlciUyMiUzQSUyMCUyMkJhc2glMjIlMkMlMjAlMjJob29rcyUyMiUzQSUyMCU1QiU3QiUyMCUyMnR5cGUlMjIlM0ElMjAlMjJjb21tYW5kJTIyJTJDJTIwJTIyY29tbWFuZCUyMiUzQSUyMCUyMmpxJTIwLWMlMjAnJTdCcGxhdGZvcm0lM0ElNUMlMjJjb2RleCU1QyUyMiUyQyUyMGV2ZW50JTNBJTVDJTIyUHJlVG9vbFVzZSU1QyUyMiUyQyUyMHRvb2wlM0EudG9vbF9uYW1lJTJDJTIwYXJncyUzQS50b29sX2lucHV0JTdEJyUyMCU3QyUyMGN1cmwlMjAtcyUyMC0tbWF4LXRpbWUlMjAyJTIwLVglMjBQT1NUJTIwLUglMjAnQ29udGVudC1UeXBlJTNBJTIwYXBwbGljYXRpb24lMkZqc29uJyUyMC0tZGF0YS1iaW5hcnklMjAlNDAtJTIwaHR0cCUzQSUyRiUyRmxvY2FsaG9zdCUzQTgwMDAlMkZldmVudCUyMCU3QyU3QyUyMHRydWUlMjIlMjAlN0QlNUQlMjAlN0QlNUQlMkMlMEElMjAlMjAlMjAlMjAlMjJQb3N0VG9vbFVzZSUyMiUzQSUyMCU1QiU3QiUyMCUyMm1hdGNoZXIlMjIlM0ElMjAlMjJCYXNoJTIyJTJDJTIwJTIyaG9va3MlMjIlM0ElMjAlNUIlN0IlMjAlMjJ0eXBlJTIyJTNBJTIwJTIyY29tbWFuZCUyMiUyQyUyMCUyMmNvbW1hbmQlMjIlM0ElMjAlMjJqcSUyMC1jJTIwJyU3QnBsYXRmb3JtJTNBJTVDJTIyY29kZXglNUMlMjIlMkMlMjBldmVudCUzQSU1QyUyMlBvc3RUb29sVXNlJTVDJTIyJTJDJTIwdG9vbCUzQS50b29sX25hbWUlMkMlMjBhcmdzJTNBLnRvb2xfcmVzcG9uc2UlN0QnJTIwJTdDJTIwY3VybCUyMC1zJTIwLS1tYXgtdGltZSUyMDIlMjAtWCUyMFBPU1QlMjAtSCUyMCdDb250ZW50LVR5cGUlM0ElMjBhcHBsaWNhdGlvbiUyRmpzb24nJTIwLS1kYXRhLWJpbmFyeSUyMCU0MC0lMjBodHRwJTNBJTJGJTJGbG9jYWxob3N0JTNBODAwMCUyRmV2ZW50JTIwJTdDJTdDJTIwdHJ1ZSUyMiUyMCU3RCU1RCUyMCU3RCU1RCUyQyUwQSUyMCUyMCUyMCUyMCUyMlVzZXJQcm9tcHRTdWJtaXQlMjIlM0ElMjAlNUIlN0IlMjAlMjJob29rcyUyMiUzQSUyMCU1QiU3QiUyMCUyMnR5cGUlMjIlM0ElMjAlMjJjb21tYW5kJTIyJTJDJTIwJTIyY29tbWFuZCUyMiUzQSUyMCUyMmpxJTIwLWMlMjAnJTdCcGxhdGZvcm0lM0ElNUMlMjJjb2RleCU1QyUyMiUyQyUyMGV2ZW50JTNBJTVDJTIyVXNlclByb21wdFN1Ym1pdCU1QyUyMiUyQyUyMGFyZ3MlM0EucHJvbXB0JTdEJyUyMCU3QyUyMGN1cmwlMjAtcyUyMC0tbWF4LXRpbWUlMjAyJTIwLVglMjBQT1NUJTIwLUglMjAnQ29udGVudC1UeXBlJTNBJTIwYXBwbGljYXRpb24lMkZqc29uJyUyMC0tZGF0YS1iaW5hcnklMjAlNDAtJTIwaHR0cCUzQSUyRiUyRmxvY2FsaG9zdCUzQTgwMDAlMkZldmVudCUyMCU3QyU3QyUyMHRydWUlMjIlMjAlN0QlNUQlMjAlN0QlNUQlMkMlMEElMjAlMjAlMjAlMjAlMjJTdG9wJTIyJTNBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTVCJTdCJTIwJTIyaG9va3MlMjIlM0ElMjAlNUIlN0IlMjAlMjJ0eXBlJTIyJTNBJTIwJTIyY29tbWFuZCUyMiUyQyUyMCUyMmNvbW1hbmQlMjIlM0ElMjAlMjJqcSUyMC1jJTIwJyU3QnBsYXRmb3JtJTNBJTVDJTIyY29kZXglNUMlMjIlMkMlMjBldmVudCUzQSU1QyUyMlN0b3AlNUMlMjIlMkMlMjBhcmdzJTNBLmxhc3RfYXNzaXN0YW50X21lc3NhZ2UlN0QnJTIwJTdDJTIwY3VybCUyMC1zJTIwLS1tYXgtdGltZSUyMDIlMjAtWCUyMFBPU1QlMjAtSCUyMCdDb250ZW50LVR5cGUlM0ElMjBhcHBsaWNhdGlvbiUyRmpzb24nJTIwLS1kYXRhLWJpbmFyeSUyMCU0MC0lMjBodHRwJTNBJTJGJTJGbG9jYWxob3N0JTNBODAwMCUyRmV2ZW50JTIwJTdDJTdDJTIwdHJ1ZSUyMiUyMCU3RCU1RCUyMCU3RCU1RCUyQyUwQSUyMCUyMCUyMCUyMCUyMlNlc3Npb25TdGFydCUyMiUzQSUyMCUyMCUyMCUyMCU1QiU3QiUyMCUyMmhvb2tzJTIyJTNBJTIwJTVCJTdCJTIwJTIydHlwZSUyMiUzQSUyMCUyMmNvbW1hbmQlMjIlMkMlMjAlMjJjb21tYW5kJTIyJTNBJTIwJTIyanElMjAtYyUyMCclN0JwbGF0Zm9ybSUzQSU1QyUyMmNvZGV4JTVDJTIyJTJDJTIwZXZlbnQlM0ElNUMlMjJTZXNzaW9uU3RhcnQlNUMlMjIlN0QnJTIwJTdDJTIwY3VybCUyMC1zJTIwLS1tYXgtdGltZSUyMDIlMjAtWCUyMFBPU1QlMjAtSCUyMCdDb250ZW50LVR5cGUlM0ElMjBhcHBsaWNhdGlvbiUyRmpzb24nJTIwLS1kYXRhLWJpbmFyeSUyMCU0MC0lMjBodHRwJTNBJTJGJTJGbG9jYWxob3N0JTNBODAwMCUyRmV2ZW50JTIwJTdDJTdDJTIwdHJ1ZSUyMiUyMCU3RCU1RCUyMCU3RCU1RCUwQSUyMCUyMCU3RCUwQSU3RA==",highlighted:`<span class="hljs-punctuation">{</span>
<span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">&quot;PreToolUse&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;matcher&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;Bash&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;type&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;command&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;command&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;jq -c &#x27;{platform:\\&quot;codex\\&quot;, event:\\&quot;PreToolUse\\&quot;, tool:.tool_name, args:.tool_input}&#x27; | curl -s --max-time 2 -X POST -H &#x27;Content-Type: application/json&#x27; --data-binary @- http://localhost:8000/event || true&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">&quot;PostToolUse&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;matcher&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;Bash&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;type&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;command&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;command&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;jq -c &#x27;{platform:\\&quot;codex\\&quot;, event:\\&quot;PostToolUse\\&quot;, tool:.tool_name, args:.tool_response}&#x27; | curl -s --max-time 2 -X POST -H &#x27;Content-Type: application/json&#x27; --data-binary @- http://localhost:8000/event || true&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">&quot;UserPromptSubmit&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;type&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;command&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;command&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;jq -c &#x27;{platform:\\&quot;codex\\&quot;, event:\\&quot;UserPromptSubmit\\&quot;, args:.prompt}&#x27; | curl -s --max-time 2 -X POST -H &#x27;Content-Type: application/json&#x27; --data-binary @- http://localhost:8000/event || true&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">&quot;Stop&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;type&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;command&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;command&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;jq -c &#x27;{platform:\\&quot;codex\\&quot;, event:\\&quot;Stop\\&quot;, args:.last_assistant_message}&#x27; | curl -s --max-time 2 -X POST -H &#x27;Content-Type: application/json&#x27; --data-binary @- http://localhost:8000/event || true&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">&quot;SessionStart&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;type&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;command&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;command&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;jq -c &#x27;{platform:\\&quot;codex\\&quot;, event:\\&quot;SessionStart\\&quot;}&#x27; | curl -s --max-time 2 -X POST -H &#x27;Content-Type: application/json&#x27; --data-binary @- http://localhost:8000/event || true&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>`,lang:"json",wrap:!1}}),G=new Z({props:{code:"UnVuJTIwJTYwbHMlNjAlMjBpbiUyMHRoaXMlMjBkaXJlY3RvcnklMjBhbmQlMjB0aGVuJTIwc2hvdyUyMG1lJTIwdGhlJTIwZmlyc3QlMjAyMCUyMGxpbmVzJTIwb2YlMjBhcHAucHku",highlighted:'Run `ls` <span class="hljs-keyword">in</span> this <span class="hljs-built_in">directory</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">then</span> show me <span class="hljs-keyword">the</span> <span class="hljs-keyword">first</span> <span class="hljs-number">20</span> <span class="hljs-keyword">lines</span> <span class="hljs-keyword">of</span> app.py.',lang:"",wrap:!1}}),{c(){c=u("p"),c.innerHTML=N,A=p(),h(U.$$.fragment),b=p(),i=u("p"),i.innerHTML=Q,f=p(),n=u("p"),n.innerHTML=B,o=p(),h(m.$$.fragment),g=p(),M=u("p"),M.innerHTML=v,j=p(),q=u("p"),q.textContent=Qs,S=p(),h(G.$$.fragment)},l(y){c=J(y,"P",{"data-svelte-h":!0}),T(c)!=="svelte-qkre0j"&&(c.innerHTML=N),A=e(y),w(U.$$.fragment,y),b=e(y),i=J(y,"P",{"data-svelte-h":!0}),T(i)!=="svelte-1lytxog"&&(i.innerHTML=Q),f=e(y),n=J(y,"P",{"data-svelte-h":!0}),T(n)!=="svelte-83hg9d"&&(n.innerHTML=B),o=e(y),w(m.$$.fragment,y),g=e(y),M=J(y,"P",{"data-svelte-h":!0}),T(M)!=="svelte-19fe8rh"&&(M.innerHTML=v),j=e(y),q=J(y,"P",{"data-svelte-h":!0}),T(q)!=="svelte-jpifa0"&&(q.textContent=Qs),S=e(y),w(G.$$.fragment,y)},m(y,k){a(y,c,k),a(y,A,k),r(U,y,k),a(y,b,k),a(y,i,k),a(y,f,k),a(y,n,k),a(y,o,k),r(m,y,k),a(y,g,k),a(y,M,k),a(y,j,k),a(y,q,k),a(y,S,k),r(G,y,k),x=!0},p:Cl,i(y){x||(d(U.$$.fragment,y),d(m.$$.fragment,y),d(G.$$.fragment,y),x=!0)},o(y){I(U.$$.fragment,y),I(m.$$.fragment,y),I(G.$$.fragment,y),x=!1},d(y){y&&(l(c),l(A),l(b),l(i),l(f),l(n),l(o),l(g),l(M),l(j),l(q),l(S)),C(U,y),C(m,y),C(G,y)}}}function na(R){let c,N="<code>.opencode/plugins/dashboard.ts</code>:",A,U,b,i,Q="If this is the first OpenCode plugin in the project, initialize a local package.json too:",f,n,B,o,m="Restart OpenCode so the plugin loads at startup, then run:",g,M,v;return U=new Z({props:{code:"aW1wb3J0JTIwdHlwZSUyMCU3QiUyMFBsdWdpbiUyMCU3RCUyMGZyb20lMjAlMjIlNDBvcGVuY29kZS1haSUyRnBsdWdpbiUyMiUwQSUwQWNvbnN0JTIwVVJMJTIwJTNEJTIwcHJvY2Vzcy5lbnYuREFTSEJPQVJEX1VSTCUyMCUzRiUzRiUyMCUyMmh0dHAlM0ElMkYlMkZsb2NhbGhvc3QlM0E4MDAwJTJGZXZlbnQlMjIlMEElMEFhc3luYyUyMGZ1bmN0aW9uJTIwc2VuZChldmVudCUzQSUyMHN0cmluZyUyQyUyMHBheWxvYWQlM0ElMjBSZWNvcmQlM0NzdHJpbmclMkMlMjB1bmtub3duJTNFKSUyMCU3QiUwQSUyMCUyMHRyeSUyMCU3QiUwQSUyMCUyMCUyMCUyMGF3YWl0JTIwZmV0Y2goVVJMJTJDJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwbWV0aG9kJTNBJTIwJTIyUE9TVCUyMiUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMGhlYWRlcnMlM0ElMjAlN0IlMjAlMjJDb250ZW50LVR5cGUlMjIlM0ElMjAlMjJhcHBsaWNhdGlvbiUyRmpzb24lMjIlMjAlN0QlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjBib2R5JTNBJTIwSlNPTi5zdHJpbmdpZnkoJTdCJTIwcGxhdGZvcm0lM0ElMjAlMjJvcGVuY29kZSUyMiUyQyUyMGV2ZW50JTJDJTIwLi4ucGF5bG9hZCUyMCU3RCklMkMlMEElMjAlMjAlMjAlMjAlMjAlMjBzaWduYWwlM0ElMjBBYm9ydFNpZ25hbC50aW1lb3V0KDIwMDApJTJDJTBBJTIwJTIwJTIwJTIwJTdEKSUwQSUyMCUyMCU3RCUyMGNhdGNoJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTJGJTJGJTIwZGFzaGJvYXJkJTIwbWF5JTIwYmUlMjBvZmZsaW5lJTNCJTIwbmV2ZXIlMjBibG9jayUyMGElMjB0b29sJTBBJTIwJTIwJTdEJTBBJTdEJTBBJTBBZXhwb3J0JTIwY29uc3QlMjBEYXNoYm9hcmRQbHVnaW4lM0ElMjBQbHVnaW4lMjAlM0QlMjBhc3luYyUyMCgpJTIwJTNEJTNFJTIwKCU3QiUwQSUyMCUyMCUyMnRvb2wuZXhlY3V0ZS5iZWZvcmUlMjIlM0ElMjBhc3luYyUyMChpbnB1dCUyQyUyMG91dHB1dCklMjAlM0QlM0UlMEElMjAlMjAlMjAlMjBzZW5kKCUyMlByZVRvb2xVc2UlMjIlMkMlMjAlN0IlMjB0b29sJTNBJTIwaW5wdXQudG9vbCUyQyUyMGFyZ3MlM0ElMjBvdXRwdXQuYXJncyUyMCU3RCklMkMlMEElMEElMjAlMjAlMjJ0b29sLmV4ZWN1dGUuYWZ0ZXIlMjIlM0ElMjBhc3luYyUyMChpbnB1dCUyQyUyMG91dHB1dCklMjAlM0QlM0UlMEElMjAlMjAlMjAlMjBzZW5kKCUyMlBvc3RUb29sVXNlJTIyJTJDJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwdG9vbCUzQSUyMGlucHV0LnRvb2wlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjBhcmdzJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdHlwZW9mJTIwKG91dHB1dCUyMGFzJTIwJTdCJTIwb3V0cHV0JTNGJTNBJTIwdW5rbm93biUyMCU3RCkub3V0cHV0JTIwJTNEJTNEJTNEJTIwJTIyc3RyaW5nJTIyJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNGJTIwKChvdXRwdXQlMjBhcyUyMCU3QiUyMG91dHB1dCUzQSUyMHN0cmluZyUyMCU3RCkub3V0cHV0LnNsaWNlKDAlMkMlMjAyMDApKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUzQSUyMCUyMiUyMiUyQyUwQSUyMCUyMCUyMCUyMCU3RCklMkMlMEElMEElMjAlMjBldmVudCUzQSUyMGFzeW5jJTIwKCU3QiUyMGV2ZW50JTIwJTdEKSUyMCUzRCUzRSUyMCU3QiUwQSUyMCUyMCUyMCUyMGlmJTIwKGV2ZW50LnR5cGUlMjAlM0QlM0QlM0QlMjAlMjJzZXNzaW9uLmNyZWF0ZWQlMjIpJTIwYXdhaXQlMjBzZW5kKCUyMlNlc3Npb25TdGFydCUyMiUyQyUyMCU3QiU3RCklMEElMjAlMjAlMjAlMjBpZiUyMChldmVudC50eXBlJTIwJTNEJTNEJTNEJTIwJTIyc2Vzc2lvbi5pZGxlJTIyKSUyMGF3YWl0JTIwc2VuZCglMjJTdG9wJTIyJTJDJTIwJTdCJTdEKSUwQSUyMCUyMCU3RCUyQyUwQSU3RCk=",highlighted:`<span class="hljs-keyword">import</span> <span class="hljs-keyword">type</span> { <span class="hljs-title class_">Plugin</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;@opencode-ai/plugin&quot;</span>
<span class="hljs-keyword">const</span> <span class="hljs-variable constant_">URL</span> = process.<span class="hljs-property">env</span>.<span class="hljs-property">DASHBOARD_URL</span> ?? <span class="hljs-string">&quot;http://localhost:8000/event&quot;</span>
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">send</span>(<span class="hljs-params">event: <span class="hljs-built_in">string</span>, payload: Record&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">unknown</span>&gt;</span>) {
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">await</span> <span class="hljs-title function_">fetch</span>(<span class="hljs-variable constant_">URL</span>, {
<span class="hljs-attr">method</span>: <span class="hljs-string">&quot;POST&quot;</span>,
<span class="hljs-attr">headers</span>: { <span class="hljs-string">&quot;Content-Type&quot;</span>: <span class="hljs-string">&quot;application/json&quot;</span> },
<span class="hljs-attr">body</span>: <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>({ <span class="hljs-attr">platform</span>: <span class="hljs-string">&quot;opencode&quot;</span>, event, ...payload }),
<span class="hljs-attr">signal</span>: <span class="hljs-title class_">AbortSignal</span>.<span class="hljs-title function_">timeout</span>(<span class="hljs-number">2000</span>),
})
} <span class="hljs-keyword">catch</span> {
<span class="hljs-comment">// dashboard may be offline; never block a tool</span>
}
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> <span class="hljs-title class_">DashboardPlugin</span>: <span class="hljs-title class_">Plugin</span> = <span class="hljs-keyword">async</span> () =&gt; ({
<span class="hljs-string">&quot;tool.execute.before&quot;</span>: <span class="hljs-keyword">async</span> (input, output) =&gt;
<span class="hljs-title function_">send</span>(<span class="hljs-string">&quot;PreToolUse&quot;</span>, { <span class="hljs-attr">tool</span>: input.<span class="hljs-property">tool</span>, <span class="hljs-attr">args</span>: output.<span class="hljs-property">args</span> }),
<span class="hljs-string">&quot;tool.execute.after&quot;</span>: <span class="hljs-keyword">async</span> (input, output) =&gt;
<span class="hljs-title function_">send</span>(<span class="hljs-string">&quot;PostToolUse&quot;</span>, {
<span class="hljs-attr">tool</span>: input.<span class="hljs-property">tool</span>,
<span class="hljs-attr">args</span>:
<span class="hljs-keyword">typeof</span> (output <span class="hljs-keyword">as</span> { output?: <span class="hljs-built_in">unknown</span> }).<span class="hljs-property">output</span> === <span class="hljs-string">&quot;string&quot;</span>
? ((output <span class="hljs-keyword">as</span> { <span class="hljs-attr">output</span>: <span class="hljs-built_in">string</span> }).<span class="hljs-property">output</span>.<span class="hljs-title function_">slice</span>(<span class="hljs-number">0</span>, <span class="hljs-number">200</span>))
: <span class="hljs-string">&quot;&quot;</span>,
}),
<span class="hljs-attr">event</span>: <span class="hljs-keyword">async</span> ({ event }) =&gt; {
<span class="hljs-keyword">if</span> (event.<span class="hljs-property">type</span> === <span class="hljs-string">&quot;session.created&quot;</span>) <span class="hljs-keyword">await</span> <span class="hljs-title function_">send</span>(<span class="hljs-string">&quot;SessionStart&quot;</span>, {})
<span class="hljs-keyword">if</span> (event.<span class="hljs-property">type</span> === <span class="hljs-string">&quot;session.idle&quot;</span>) <span class="hljs-keyword">await</span> <span class="hljs-title function_">send</span>(<span class="hljs-string">&quot;Stop&quot;</span>, {})
},
})`,lang:"ts",wrap:!1}}),n=new Z({props:{code:"Y2QlMjAub3BlbmNvZGUlMEFidW4lMjBpbml0JTIwLXklMEFidW4lMjBhZGQlMjAtZCUyMCU0MG9wZW5jb2RlLWFpJTJGcGx1Z2lu",highlighted:`<span class="hljs-built_in">cd</span> .opencode
bun init -y
bun add -d @opencode-ai/plugin`,lang:"bash",wrap:!1}}),M=new Z({props:{code:"UmVhZCUyMFJFQURNRS5tZCUyMGFuZCUyMGxpc3QlMjBpdHMlMjBzZWN0aW9ucy4=",highlighted:'<span class="hljs-symbol">Read</span> README.md <span class="hljs-keyword">and</span> list <span class="hljs-keyword">its</span> sections.',lang:"",wrap:!1}}),{c(){c=u("p"),c.innerHTML=N,A=p(),h(U.$$.fragment),b=p(),i=u("p"),i.textContent=Q,f=p(),h(n.$$.fragment),B=p(),o=u("p"),o.textContent=m,g=p(),h(M.$$.fragment)},l(j){c=J(j,"P",{"data-svelte-h":!0}),T(c)!=="svelte-j05721"&&(c.innerHTML=N),A=e(j),w(U.$$.fragment,j),b=e(j),i=J(j,"P",{"data-svelte-h":!0}),T(i)!=="svelte-yxw79l"&&(i.textContent=Q),f=e(j),w(n.$$.fragment,j),B=e(j),o=J(j,"P",{"data-svelte-h":!0}),T(o)!=="svelte-wgqtvr"&&(o.textContent=m),g=e(j),w(M.$$.fragment,j)},m(j,q){a(j,c,q),a(j,A,q),r(U,j,q),a(j,b,q),a(j,i,q),a(j,f,q),r(n,j,q),a(j,B,q),a(j,o,q),a(j,g,q),r(M,j,q),v=!0},p:Cl,i(j){v||(d(U.$$.fragment,j),d(n.$$.fragment,j),d(M.$$.fragment,j),v=!0)},o(j){I(U.$$.fragment,j),I(n.$$.fragment,j),I(M.$$.fragment,j),v=!1},d(j){j&&(l(c),l(A),l(b),l(i),l(f),l(B),l(o),l(g)),C(U,j),C(n,j),C(M,j)}}}function pa(R){let c,N="<code>.pi/extensions/dashboard.ts</code>:",A,U,b,i,Q="Create <code>.pi/extensions/</code> if needed, then start Pi (or run <code>/reload</code> if Pi is already open) and try:",f,n,B;return U=new Z({props:{code:"aW1wb3J0JTIwdHlwZSUyMCU3QiUyMEV4dGVuc2lvbkFQSSUyMCU3RCUyMGZyb20lMjAlMjIlNDBtYXJpb3plY2huZXIlMkZwaS1jb2RpbmctYWdlbnQlMjIlM0IlMEElMEFjb25zdCUyMFVSTCUyMCUzRCUyMHByb2Nlc3MuZW52LkRBU0hCT0FSRF9VUkwlMjAlM0YlM0YlMjAlMjJodHRwJTNBJTJGJTJGbG9jYWxob3N0JTNBODAwMCUyRmV2ZW50JTIyJTNCJTBBJTBBYXN5bmMlMjBmdW5jdGlvbiUyMHNlbmQoZXZlbnQlM0ElMjBzdHJpbmclMkMlMjBwYXlsb2FkJTNBJTIwUmVjb3JkJTNDc3RyaW5nJTJDJTIwdW5rbm93biUzRSklMjAlN0IlMEElMjAlMjB0cnklMjAlN0IlMEElMjAlMjAlMjAlMjBhd2FpdCUyMGZldGNoKFVSTCUyQyUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMG1ldGhvZCUzQSUyMCUyMlBPU1QlMjIlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjBoZWFkZXJzJTNBJTIwJTdCJTIwJTIyQ29udGVudC1UeXBlJTIyJTNBJTIwJTIyYXBwbGljYXRpb24lMkZqc29uJTIyJTIwJTdEJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwYm9keSUzQSUyMEpTT04uc3RyaW5naWZ5KCU3QiUyMHBsYXRmb3JtJTNBJTIwJTIycGklMjIlMkMlMjBldmVudCUyQyUyMC4uLnBheWxvYWQlMjAlN0QpJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwc2lnbmFsJTNBJTIwQWJvcnRTaWduYWwudGltZW91dCgyMDAwKSUyQyUwQSUyMCUyMCUyMCUyMCU3RCklM0IlMEElMjAlMjAlN0QlMjBjYXRjaCUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyRiUyRiUyMGRhc2hib2FyZCUyMG1heSUyMGJlJTIwb2ZmbGluZSUzQiUyMG5ldmVyJTIwYmxvY2slMjB0aGUlMjBhZ2VudCUwQSUyMCUyMCU3RCUwQSU3RCUwQSUwQWV4cG9ydCUyMGRlZmF1bHQlMjBmdW5jdGlvbiUyMChwaSUzQSUyMEV4dGVuc2lvbkFQSSklMjAlN0IlMEElMjAlMjBwaS5vbiglMjJzZXNzaW9uX3N0YXJ0JTIyJTJDJTIwYXN5bmMlMjAoKSUyMCUzRCUzRSUyMCU3QiUwQSUyMCUyMCUyMCUyMGF3YWl0JTIwc2VuZCglMjJTZXNzaW9uU3RhcnQlMjIlMkMlMjAlN0IlN0QpJTNCJTBBJTIwJTIwJTdEKSUzQiUwQSUwQSUyMCUyMHBpLm9uKCUyMmJlZm9yZV9hZ2VudF9zdGFydCUyMiUyQyUyMGFzeW5jJTIwKGV2ZW50KSUyMCUzRCUzRSUyMCU3QiUwQSUyMCUyMCUyMCUyMGF3YWl0JTIwc2VuZCglMjJVc2VyUHJvbXB0U3VibWl0JTIyJTJDJTIwJTdCJTIwYXJncyUzQSUyMGV2ZW50LnByb21wdCUyMCU3RCklM0IlMEElMjAlMjAlN0QpJTNCJTBBJTBBJTIwJTIwcGkub24oJTIydG9vbF9jYWxsJTIyJTJDJTIwYXN5bmMlMjAoZXZlbnQpJTIwJTNEJTNFJTIwJTdCJTBBJTIwJTIwJTIwJTIwYXdhaXQlMjBzZW5kKCUyMlByZVRvb2xVc2UlMjIlMkMlMjAlN0IlMjB0b29sJTNBJTIwZXZlbnQudG9vbE5hbWUlMkMlMjBhcmdzJTNBJTIwZXZlbnQuaW5wdXQlMjAlN0QpJTNCJTBBJTIwJTIwJTdEKSUzQiUwQSUwQSUyMCUyMHBpLm9uKCUyMnRvb2xfcmVzdWx0JTIyJTJDJTIwYXN5bmMlMjAoZXZlbnQpJTIwJTNEJTNFJTIwJTdCJTBBJTIwJTIwJTIwJTIwYXdhaXQlMjBzZW5kKCUyMlBvc3RUb29sVXNlJTIyJTJDJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwdG9vbCUzQSUyMGV2ZW50LnRvb2xOYW1lJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwYXJncyUzQSUyMGV2ZW50LmRldGFpbHMlMjAlM0YlM0YlMjBldmVudC5jb250ZW50JTJDJTBBJTIwJTIwJTIwJTIwJTdEKSUzQiUwQSUyMCUyMCU3RCklM0IlMEElMEElMjAlMjBwaS5vbiglMjJhZ2VudF9lbmQlMjIlMkMlMjBhc3luYyUyMCgpJTIwJTNEJTNFJTIwJTdCJTBBJTIwJTIwJTIwJTIwYXdhaXQlMjBzZW5kKCUyMlN0b3AlMjIlMkMlMjAlN0IlN0QpJTNCJTBBJTIwJTIwJTdEKSUzQiUwQSU3RA==",highlighted:`<span class="hljs-keyword">import</span> <span class="hljs-keyword">type</span> { <span class="hljs-title class_">ExtensionAPI</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;@mariozechner/pi-coding-agent&quot;</span>;
<span class="hljs-keyword">const</span> <span class="hljs-variable constant_">URL</span> = process.<span class="hljs-property">env</span>.<span class="hljs-property">DASHBOARD_URL</span> ?? <span class="hljs-string">&quot;http://localhost:8000/event&quot;</span>;
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">send</span>(<span class="hljs-params">event: <span class="hljs-built_in">string</span>, payload: Record&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">unknown</span>&gt;</span>) {
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">await</span> <span class="hljs-title function_">fetch</span>(<span class="hljs-variable constant_">URL</span>, {
<span class="hljs-attr">method</span>: <span class="hljs-string">&quot;POST&quot;</span>,
<span class="hljs-attr">headers</span>: { <span class="hljs-string">&quot;Content-Type&quot;</span>: <span class="hljs-string">&quot;application/json&quot;</span> },
<span class="hljs-attr">body</span>: <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>({ <span class="hljs-attr">platform</span>: <span class="hljs-string">&quot;pi&quot;</span>, event, ...payload }),
<span class="hljs-attr">signal</span>: <span class="hljs-title class_">AbortSignal</span>.<span class="hljs-title function_">timeout</span>(<span class="hljs-number">2000</span>),
});
} <span class="hljs-keyword">catch</span> {
<span class="hljs-comment">// dashboard may be offline; never block the agent</span>
}
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> (<span class="hljs-params">pi: ExtensionAPI</span>) {
pi.<span class="hljs-title function_">on</span>(<span class="hljs-string">&quot;session_start&quot;</span>, <span class="hljs-keyword">async</span> () =&gt; {
<span class="hljs-keyword">await</span> <span class="hljs-title function_">send</span>(<span class="hljs-string">&quot;SessionStart&quot;</span>, {});
});
pi.<span class="hljs-title function_">on</span>(<span class="hljs-string">&quot;before_agent_start&quot;</span>, <span class="hljs-keyword">async</span> (event) =&gt; {
<span class="hljs-keyword">await</span> <span class="hljs-title function_">send</span>(<span class="hljs-string">&quot;UserPromptSubmit&quot;</span>, { <span class="hljs-attr">args</span>: event.<span class="hljs-property">prompt</span> });
});
pi.<span class="hljs-title function_">on</span>(<span class="hljs-string">&quot;tool_call&quot;</span>, <span class="hljs-keyword">async</span> (event) =&gt; {
<span class="hljs-keyword">await</span> <span class="hljs-title function_">send</span>(<span class="hljs-string">&quot;PreToolUse&quot;</span>, { <span class="hljs-attr">tool</span>: event.<span class="hljs-property">toolName</span>, <span class="hljs-attr">args</span>: event.<span class="hljs-property">input</span> });
});
pi.<span class="hljs-title function_">on</span>(<span class="hljs-string">&quot;tool_result&quot;</span>, <span class="hljs-keyword">async</span> (event) =&gt; {
<span class="hljs-keyword">await</span> <span class="hljs-title function_">send</span>(<span class="hljs-string">&quot;PostToolUse&quot;</span>, {
<span class="hljs-attr">tool</span>: event.<span class="hljs-property">toolName</span>,
<span class="hljs-attr">args</span>: event.<span class="hljs-property">details</span> ?? event.<span class="hljs-property">content</span>,
});
});
pi.<span class="hljs-title function_">on</span>(<span class="hljs-string">&quot;agent_end&quot;</span>, <span class="hljs-keyword">async</span> () =&gt; {
<span class="hljs-keyword">await</span> <span class="hljs-title function_">send</span>(<span class="hljs-string">&quot;Stop&quot;</span>, {});
});
}`,lang:"ts",wrap:!1}}),n=new Z({props:{code:"UmVhZCUyMFJFQURNRS5tZCUyMGFuZCUyMGxpc3QlMjBpdHMlMjBzZWN0aW9ucy4=",highlighted:'<span class="hljs-symbol">Read</span> README.md <span class="hljs-keyword">and</span> list <span class="hljs-keyword">its</span> sections.',lang:"",wrap:!1}}),{c(){c=u("p"),c.innerHTML=N,A=p(),h(U.$$.fragment),b=p(),i=u("p"),i.innerHTML=Q,f=p(),h(n.$$.fragment)},l(o){c=J(o,"P",{"data-svelte-h":!0}),T(c)!=="svelte-1mai2d9"&&(c.innerHTML=N),A=e(o),w(U.$$.fragment,o),b=e(o),i=J(o,"P",{"data-svelte-h":!0}),T(i)!=="svelte-1miu66k"&&(i.innerHTML=Q),f=e(o),w(n.$$.fragment,o)},m(o,m){a(o,c,m),a(o,A,m),r(U,o,m),a(o,b,m),a(o,i,m),a(o,f,m),r(n,o,m),B=!0},p:Cl,i(o){B||(d(U.$$.fragment,o),d(n.$$.fragment,o),B=!0)},o(o){I(U.$$.fragment,o),I(n.$$.fragment,o),B=!1},d(o){o&&(l(c),l(A),l(b),l(i),l(f)),C(U,o),C(n,o)}}}function ea(R){let c,N,A,U,b,i,Q,f;return c=new Il({props:{id:"tool",option:"Claude Code",$$slots:{default:[aa]},$$scope:{ctx:R}}}),A=new Il({props:{id:"tool",option:"Codex",$$slots:{default:[ta]},$$scope:{ctx:R}}}),b=new Il({props:{id:"tool",option:"OpenCode",$$slots:{default:[na]},$$scope:{ctx:R}}}),Q=new Il({props:{id:"tool",option:"Pi",$$slots:{default:[pa]},$$scope:{ctx:R}}}),{c(){h(c.$$.fragment),N=p(),h(A.$$.fragment),U=p(),h(b.$$.fragment),i=p(),h(Q.$$.fragment)},l(n){w(c.$$.fragment,n),N=e(n),w(A.$$.fragment,n),U=e(n),w(b.$$.fragment,n),i=e(n),w(Q.$$.fragment,n)},m(n,B){r(c,n,B),a(n,N,B),r(A,n,B),a(n,U,B),r(b,n,B),a(n,i,B),r(Q,n,B),f=!0},p(n,B){const o={};B&2&&(o.$$scope={dirty:B,ctx:n}),c.$set(o);const m={};B&2&&(m.$$scope={dirty:B,ctx:n}),A.$set(m);const g={};B&2&&(g.$$scope={dirty:B,ctx:n}),b.$set(g);const M={};B&2&&(M.$$scope={dirty:B,ctx:n}),Q.$set(M)},i(n){f||(d(c.$$.fragment,n),d(A.$$.fragment,n),d(b.$$.fragment,n),d(Q.$$.fragment,n),f=!0)},o(n){I(c.$$.fragment,n),I(A.$$.fragment,n),I(b.$$.fragment,n),I(Q.$$.fragment,n),f=!1},d(n){n&&(l(N),l(U),l(i)),C(c,n),C(A,n),C(b,n),C(Q,n)}}}function Ma(R){let c,N,A,U,b,i,Q,f,n,B="This project wires the hooks you configured in the previous lesson into a live dashboard. The dashboard is a Gradio app that accepts hook events over HTTP, shows the most recent calls in a table, and plots tool usage over time. It works against Claude Code, Codex, OpenCode, and Pi — with the same agent doing the work, you see what actually happens under the hood.",o,m,g,M,v="One Python process that does two things at once:",j,q,Qs="<li>A <strong>FastAPI</strong> endpoint at <code>POST /event</code> that any hook can post to.</li> <li>A <strong>Gradio</strong> app mounted on the same server that renders the events live.</li>",S,G,x="The Gradio app polls the in-memory event buffer and re-renders every second, so you can watch the agent work in real time.",y,k,ks,Y,ml="Create a fresh project directory:",gs,X,Ns,z,bl="Install dependencies:",vs,F,Zs,_,Bl="Create <code>requirements.txt</code> for later deployment:",Gs,H,Rs,L,Es,D,Al="Create <code>app.py</code>:",Ss,P,$s,K,fl="Run it:",Ws,O,Vs,ss,Ql="Open <code>http://localhost:8000</code> in a browser. The dashboard is empty — that’s expected until a hook sends an event.",xs,$,ql="<p>The FastAPI route for <code>/event</code> is defined before Gradio is mounted at <code>/</code>, so POSTs hit the receiver and everything else lands on the Gradio UI.</p>",Ys,ls,Xs,as,kl="Use the hook config from the previous lesson. A quick reminder of the shape for each platform, adjusted so the normalizer in <code>app.py</code> can make sense of the payload.",zs,W,Fs,ts,_s,ns,gl="Leave <code>python app.py</code> running in one terminal and your agent running in another. As the agent works, events stream into the dashboard:",Hs,ps,Ls,es,Nl="The bar chart updates live as tools accumulate, which makes it obvious when the agent is stuck in a loop on the same tool.",Ds,Ms,Ps,os,vl="A log-only dashboard is already useful, but the real power of hooks is that they can intervene. Extend the Claude Code hook to block dangerous commands.",Ks,cs,Zl="Add a second hook handler for <code>PreToolUse</code> that runs before the dashboard logger:",Os,ys,sl,js,Gl="Now the same <code>PreToolUse</code> event does two things: denies obviously destructive shell patterns (exit code <code>2</code> with a stderr message) and logs everything else to the dashboard. Create a disposable test folder:",ll,us,al,Js,Rl="Then ask the agent to run:",tl,Us,nl,is,El="You’ll see it refuse before the command executes, and you’ll see the guardrail event in the dashboard.",pl,V,Sl="<p>The equivalent OpenCode guard is a <code>throw new Error(&quot;blocked: dangerous shell pattern&quot;)</code> inside <code>&quot;tool.execute.before&quot;</code>. For Codex, the hook can either exit <code>2</code> with a stderr reason or print <code>jq -c &#39;{hookSpecificOutput:{hookEventName:&quot;PreToolUse&quot;, permissionDecision:&quot;deny&quot;, permissionDecisionReason:&quot;…&quot;}}&#39;</code> on stdout.</p>",el,Ts,Ml,hs,$l='For a team-facing dashboard, host the Gradio app on <a href="https://huggingface.co/spaces" rel="nofollow">Hugging Face Spaces</a>. Push <code>app.py</code> and <code>requirements.txt</code>, and update the hook URLs from <code>http://localhost:8000/event</code> to <code>https://YOUR-USERNAME-agent-dashboard.hf.space/event</code>.',ol,ws,Wl="A few cautions for a shared dashboard:",cl,rs,Vl="<li>Payloads can contain secrets (prompts, file contents, command lines). Redact sensitive fields in <code>_normalize</code> before appending to the buffer.</li> <li>A public Space is, well, public. Put authentication in front of <code>/event</code>, or keep the Space private and use a personal access token in the hook <code>headers</code>.</li> <li>The in-memory buffer resets on restart. For durable history, swap <code>deque</code> for a SQLite file or a Spaces persistent volume.</li>",yl,ds,jl,Is,ul,Cs,Jl,ms,xl="This project shows how to pick the right event for observability (<code>PreToolUse</code> and <code>PostToolUse</code>), how to collapse four different payload shapes into one normalized record, and how to use exit codes / <code>hookSpecificOutput</code> / thrown errors / returned values to enforce policy. The Gradio + FastAPI pattern — one process, two surfaces — keeps the whole thing short and makes it easy to host on Spaces.",Ul,bs,il,Bs,Yl="A hook is only useful if its output goes somewhere. A Gradio dashboard is a fast way to turn raw hook events into something you can actually learn from: you can watch an agent work, see where it’s stuck, and prove that guardrails fire. The same dashboard works across Claude Code, Codex, OpenCode, and Pi because the event shape is narrow and the normalizer is small.",Tl,As,Xl="Next, one more quiz to wrap up the unit.",hl,fs,wl,qs,rl;return b=new Ol({props:{containerStyle:"float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"}}),Q=new E({props:{title:"Hands-On: Build an Agent Activity Dashboard with Gradio",local:"hands-on-build-an-agent-activity-dashboard-with-gradio",headingTag:"h1"}}),m=new E({props:{title:"What You’ll Build",local:"what-youll-build",headingTag:"h2"}}),k=new E({props:{title:"Project Setup",local:"project-setup",headingTag:"h2"}}),X=new Z({props:{code:"bWtkaXIlMjBhZ2VudC1hY3Rpdml0eS1kYXNoYm9hcmQlMEFjZCUyMGFnZW50LWFjdGl2aXR5LWRhc2hib2FyZA==",highlighted:`<span class="hljs-built_in">mkdir</span> agent-activity-dashboard
<span class="hljs-built_in">cd</span> agent-activity-dashboard`,lang:"bash",wrap:!1}}),F=new Z({props:{code:"cGlwJTIwaW5zdGFsbCUyMCUyMmdyYWRpbyUzRSUzRDQuNDElMjIlMjAlMjJmYXN0YXBpJTIyJTIwJTIydXZpY29ybiU1QnN0YW5kYXJkJTVEJTIyJTIwJTIycGFuZGFzJTIy",highlighted:'pip install <span class="hljs-string">&quot;gradio&gt;=4.41&quot;</span> <span class="hljs-string">&quot;fastapi&quot;</span> <span class="hljs-string">&quot;uvicorn[standard]&quot;</span> <span class="hljs-string">&quot;pandas&quot;</span>',lang:"bash",wrap:!1}}),H=new Z({props:{code:"Z3JhZGlvJTNFJTNENC40MSUwQWZhc3RhcGklMEF1dmljb3JuJTVCc3RhbmRhcmQlNUQlMEFwYW5kYXM=",highlighted:`gradio&gt;=4.41
fastapi
uvicorn[standard]
pandas`,lang:"text",wrap:!1}}),L=new E({props:{title:"Step 1: Build the Receiver and Dashboard",local:"step-1-build-the-receiver-and-dashboard",headingTag:"h2"}}),P=new Z({props:{code:"aW1wb3J0JTIwZGF0ZXRpbWUlMjBhcyUyMGR0JTBBZnJvbSUyMGNvbGxlY3Rpb25zJTIwaW1wb3J0JTIwQ291bnRlciUyQyUyMGRlcXVlJTBBZnJvbSUyMHR5cGluZyUyMGltcG9ydCUyMEFueSUwQSUwQWltcG9ydCUyMGdyYWRpbyUyMGFzJTIwZ3IlMEFpbXBvcnQlMjBwYW5kYXMlMjBhcyUyMHBkJTBBZnJvbSUyMGZhc3RhcGklMjBpbXBvcnQlMjBGYXN0QVBJJTJDJTIwUmVxdWVzdCUwQWZyb20lMjBmYXN0YXBpLnJlc3BvbnNlcyUyMGltcG9ydCUyMEpTT05SZXNwb25zZSUwQSUwQSUyMyUyMC0tLS0tLS0tLS0lMjBTaGFyZWQlMjBzdGF0ZSUyMC0tLS0tLS0tLS0lMEFNQVhfRVZFTlRTJTIwJTNEJTIwNTAwJTBBZXZlbnRzJTNBJTIwZGVxdWUlNUJkaWN0JTVCc3RyJTJDJTIwQW55JTVEJTVEJTIwJTNEJTIwZGVxdWUobWF4bGVuJTNETUFYX0VWRU5UUyklMEElMEElMEFkZWYlMjBfdHJ1bmNhdGUodmFsdWUlM0ElMjBBbnklMkMlMjBuJTNBJTIwaW50KSUyMC0lM0UlMjBzdHIlM0ElMEElMjAlMjAlMjAlMjB0ZXh0JTIwJTNEJTIwJTIyJTIyJTIwaWYlMjB2YWx1ZSUyMGlzJTIwTm9uZSUyMGVsc2UlMjBzdHIodmFsdWUpJTBBJTIwJTIwJTIwJTIwcmV0dXJuJTIwdGV4dCUyMGlmJTIwbGVuKHRleHQpJTIwJTNDJTNEJTIwbiUyMGVsc2UlMjB0ZXh0JTVCJTNBJTIwbiUyMC0lMjAxJTVEJTIwJTJCJTIwJTIyJUUyJTgwJUE2JTIyJTBBJTBBJTBBZGVmJTIwX25vcm1hbGl6ZShib2R5JTNBJTIwZGljdCU1QnN0ciUyQyUyMEFueSU1RCUyQyUyMGhlYWRlcnMlM0ElMjBkaWN0JTVCc3RyJTJDJTIwc3RyJTVEKSUyMC0lM0UlMjBkaWN0JTVCc3RyJTJDJTIwQW55JTVEJTNBJTBBJTIwJTIwJTIwJTIwJTIyJTIyJTIyTWFwJTIwQ2xhdWRlJTIwQ29kZSUyMCUyRiUyMENvZGV4JTIwJTJGJTIwT3BlbkNvZGUlMjAlMkYlMjBQaSUyMHBheWxvYWRzJTIwdG8lMjBvbmUlMjBzaGFwZS4lMjIlMjIlMjIlMEElMjAlMjAlMjAlMjBwbGF0Zm9ybSUyMCUzRCUyMCglMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBib2R5LmdldCglMjJwbGF0Zm9ybSUyMiklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBvciUyMGhlYWRlcnMuZ2V0KCUyMngtcGxhdGZvcm0lMjIpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwb3IlMjAlMjJ1bmtub3duJTIyJTBBJTIwJTIwJTIwJTIwKSUwQSUyMCUyMCUyMCUyMGV2ZW50X25hbWUlMjAlM0QlMjBib2R5LmdldCglMjJldmVudCUyMiklMjBvciUyMGJvZHkuZ2V0KCUyMmhvb2tfZXZlbnRfbmFtZSUyMiklMjBvciUyMCUyMlVua25vd24lMjIlMEElMjAlMjAlMjAlMjB0b29sJTIwJTNEJTIwYm9keS5nZXQoJTIydG9vbCUyMiklMjBvciUyMGJvZHkuZ2V0KCUyMnRvb2xfbmFtZSUyMiklMjBvciUyMCUyMiUyMiUwQSUyMCUyMCUyMCUyMGFyZ3MlMjAlM0QlMjBib2R5LmdldCglMjJhcmdzJTIyKSUyMG9yJTIwYm9keS5nZXQoJTIydG9vbF9pbnB1dCUyMiklMjBvciUyMGJvZHkuZ2V0KCUyMnByb21wdCUyMiklMjBvciUyMCUyMiUyMiUwQSUyMCUyMCUyMCUyMHJldHVybiUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMnRpbWVzdGFtcCUyMiUzQSUyMGR0LmRhdGV0aW1lLnV0Y25vdygpLmlzb2Zvcm1hdCh0aW1lc3BlYyUzRCUyMnNlY29uZHMlMjIpJTIwJTJCJTIwJTIyWiUyMiUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMnBsYXRmb3JtJTIyJTNBJTIwc3RyKHBsYXRmb3JtKSUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMmV2ZW50JTIyJTNBJTIwc3RyKGV2ZW50X25hbWUpJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIydG9vbCUyMiUzQSUyMHN0cih0b29sKSUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMmFyZ3MlMjIlM0ElMjBfdHJ1bmNhdGUoYXJncyUyQyUyMDIwMCklMkMlMEElMjAlMjAlMjAlMjAlN0QlMEElMEElMEElMjMlMjAtLS0tLS0tLS0tJTIwRmFzdEFQSSUyMHJlY2VpdmVyJTIwLS0tLS0tLS0tLSUwQWFwaSUyMCUzRCUyMEZhc3RBUEkodGl0bGUlM0QlMjJBZ2VudCUyMEFjdGl2aXR5JTIwRGFzaGJvYXJkJTIyKSUwQSUwQSUwQSU0MGFwaS5wb3N0KCUyMiUyRmV2ZW50JTIyKSUwQWFzeW5jJTIwZGVmJTIwZXZlbnQocmVxJTNBJTIwUmVxdWVzdCklM0ElMEElMjAlMjAlMjAlMjB0cnklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBib2R5JTIwJTNEJTIwYXdhaXQlMjByZXEuanNvbigpJTBBJTIwJTIwJTIwJTIwZXhjZXB0JTIwRXhjZXB0aW9uJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwYm9keSUyMCUzRCUyMCU3QiU3RCUwQSUyMCUyMCUyMCUyMHJlY29yZCUyMCUzRCUyMF9ub3JtYWxpemUoYm9keSUyQyUyMCU3QmsubG93ZXIoKSUzQSUyMHYlMjBmb3IlMjBrJTJDJTIwdiUyMGluJTIwcmVxLmhlYWRlcnMuaXRlbXMoKSU3RCklMEElMjAlMjAlMjAlMjBldmVudHMuYXBwZW5kbGVmdChyZWNvcmQpJTBBJTIwJTIwJTIwJTIwJTIzJTIwUmV0dXJuJTIwYW4lMjBlbXB0eSUyMGJvZHklMjBzbyUyMGhvb2slMjBjYWxsZXJzJTIwbmV2ZXIlMjBibG9jayUyMG9uJTIwdGhlJTIwZGFzaGJvYXJkJTIwcmVjZWl2ZXIuJTBBJTIwJTIwJTIwJTIwcmV0dXJuJTIwSlNPTlJlc3BvbnNlKCU3QiU3RCklMEElMEElMEElNDBhcGkuZ2V0KCUyMiUyRmhlYWx0aCUyMiklMEFkZWYlMjBoZWFsdGgoKSUzQSUwQSUyMCUyMCUyMCUyMHJldHVybiUyMCU3QiUyMm9rJTIyJTNBJTIwVHJ1ZSUyQyUyMCUyMmV2ZW50cyUyMiUzQSUyMGxlbihldmVudHMpJTdEJTBBJTBBJTBBJTIzJTIwLS0tLS0tLS0tLSUyMEdyYWRpbyUyMHZpZXdzJTIwLS0tLS0tLS0tLSUwQUNPTFVNTlMlMjAlM0QlMjAlNUIlMjJ0aW1lc3RhbXAlMjIlMkMlMjAlMjJwbGF0Zm9ybSUyMiUyQyUyMCUyMmV2ZW50JTIyJTJDJTIwJTIydG9vbCUyMiUyQyUyMCUyMmFyZ3MlMjIlNUQlMEElMEElMEFkZWYlMjBldmVudHNfZGYoKSUyMC0lM0UlMjBwZC5EYXRhRnJhbWUlM0ElMEElMjAlMjAlMjAlMjBpZiUyMG5vdCUyMGV2ZW50cyUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMHBkLkRhdGFGcmFtZShjb2x1bW5zJTNEQ09MVU1OUyklMEElMjAlMjAlMjAlMjByZXR1cm4lMjBwZC5EYXRhRnJhbWUobGlzdChldmVudHMpJTJDJTIwY29sdW1ucyUzRENPTFVNTlMpJTBBJTBBJTBBZGVmJTIwdG9vbF9jb3VudHNfZGYoKSUyMC0lM0UlMjBwZC5EYXRhRnJhbWUlM0ElMEElMjAlMjAlMjAlMjBjb3VudGVyJTIwJTNEJTIwQ291bnRlcihlJTVCJTIydG9vbCUyMiU1RCUyMGZvciUyMGUlMjBpbiUyMGV2ZW50cyUyMGlmJTIwZSU1QiUyMnRvb2wlMjIlNUQpJTBBJTIwJTIwJTIwJTIwcm93cyUyMCUzRCUyMCU1QiU3QiUyMnRvb2wlMjIlM0ElMjB0b29sJTJDJTIwJTIyY291bnQlMjIlM0ElMjBuJTdEJTIwZm9yJTIwdG9vbCUyQyUyMG4lMjBpbiUyMGNvdW50ZXIubW9zdF9jb21tb24oMTUpJTVEJTBBJTIwJTIwJTIwJTIwcmV0dXJuJTIwcGQuRGF0YUZyYW1lKHJvd3MlMkMlMjBjb2x1bW5zJTNEJTVCJTIydG9vbCUyMiUyQyUyMCUyMmNvdW50JTIyJTVEKSUwQSUwQSUwQWRlZiUyMHN1bW1hcnlfbWQoKSUyMC0lM0UlMjBzdHIlM0ElMEElMjAlMjAlMjAlMjB0b3RhbCUyMCUzRCUyMGxlbihldmVudHMpJTBBJTIwJTIwJTIwJTIwcGxhdGZvcm1zJTIwJTNEJTIwc29ydGVkKCU3QmUlNUIlMjJwbGF0Zm9ybSUyMiU1RCUyMGZvciUyMGUlMjBpbiUyMGV2ZW50cyU3RCklMjBvciUyMCU1QiUyMihub25lKSUyMiU1RCUwQSUyMCUyMCUyMCUyMHRvb2xzJTIwJTNEJTIwc29ydGVkKCU3QmUlNUIlMjJ0b29sJTIyJTVEJTIwZm9yJTIwZSUyMGluJTIwZXZlbnRzJTIwaWYlMjBlJTVCJTIydG9vbCUyMiU1RCU3RCklMEElMjAlMjAlMjAlMjB0b29sc19kaXNwbGF5JTIwJTNEJTIwJTIyJTJDJTIwJTIyLmpvaW4odG9vbHMpJTIwaWYlMjB0b29scyUyMGVsc2UlMjAlMjIobm9uZSklMjIlMEElMjAlMjAlMjAlMjByZXR1cm4lMjAoJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZiUyMioqRXZlbnRzJTNBKiolMjAlN0J0b3RhbCU3RCUyMChidWZmZXIlMjBob2xkcyUyMHVwJTIwdG8lMjAlN0JNQVhfRVZFTlRTJTdEKSUyMCUyMCU1Q24lMjIlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBmJTIyKipQbGF0Zm9ybXMlMjBzZWVuJTNBKiolMjAlN0InJTJDJTIwJy5qb2luKHBsYXRmb3JtcyklN0QlMjAlMjAlNUNuJTIyJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZiUyMioqVG9vbHMlMjBzZWVuJTNBKiolMjAlN0J0b29sc19kaXNwbGF5JTdEJTIyJTBBJTIwJTIwJTIwJTIwKSUwQSUwQSUwQWRlZiUyMHJlZnJlc2goKSUzQSUwQSUyMCUyMCUyMCUyMHJldHVybiUyMGV2ZW50c19kZigpJTJDJTIwdG9vbF9jb3VudHNfZGYoKSUyQyUyMHN1bW1hcnlfbWQoKSUwQSUwQSUwQWRlZiUyMGNsZWFyX2V2ZW50cygpJTNBJTBBJTIwJTIwJTIwJTIwZXZlbnRzLmNsZWFyKCklMEElMjAlMjAlMjAlMjByZXR1cm4lMjByZWZyZXNoKCklMEElMEElMEF3aXRoJTIwZ3IuQmxvY2tzKHRpdGxlJTNEJTIyQWdlbnQlMjBBY3Rpdml0eSUyMERhc2hib2FyZCUyMiklMjBhcyUyMHVpJTNBJTBBJTIwJTIwJTIwJTIwZ3IuTWFya2Rvd24oJTIyJTIzJTIwQWdlbnQlMjBBY3Rpdml0eSUyMERhc2hib2FyZCUyMiklMEElMjAlMjAlMjAlMjBnci5NYXJrZG93biglMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJQb2ludCUyMHlvdXIlMjBDbGF1ZGUlMjBDb2RlJTJDJTIwQ29kZXglMkMlMjBPcGVuQ29kZSUyQyUyMG9yJTIwUGklMjBob29rcyUyRmV4dGVuc2lvbnMlMjBhdCUyMCUyMiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMiU2MFBPU1QlMjBodHRwJTNBJTJGJTJGbG9jYWxob3N0JTNBODAwMCUyRmV2ZW50JTYwJTIwdG8lMjBzZWUlMjBsaXZlJTIwYWN0aXZpdHklMjBoZXJlLiUyMiUwQSUyMCUyMCUyMCUyMCklMEElMEElMjAlMjAlMjAlMjBoZWFkZXIlMjAlM0QlMjBnci5NYXJrZG93bih2YWx1ZSUzRHN1bW1hcnlfbWQoKSklMEElMEElMjAlMjAlMjAlMjB3aXRoJTIwZ3IuUm93KCklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBjbGVhcl9idG4lMjAlM0QlMjBnci5CdXR0b24oJTIyQ2xlYXIlMjBldmVudHMlMjIlMkMlMjB2YXJpYW50JTNEJTIyc2Vjb25kYXJ5JTIyKSUwQSUwQSUyMCUyMCUyMCUyMGNoYXJ0JTIwJTNEJTIwZ3IuQmFyUGxvdCglMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB2YWx1ZSUzRHRvb2xfY291bnRzX2RmKCklMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB4JTNEJTIydG9vbCUyMiUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHklM0QlMjJjb3VudCUyMiUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHRpdGxlJTNEJTIyVG9vbCUyMHVzYWdlJTIyJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdG9vbHRpcCUzRCU1QiUyMnRvb2wlMjIlMkMlMjAlMjJjb3VudCUyMiU1RCUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGhlaWdodCUzRDI4MCUyQyUwQSUyMCUyMCUyMCUyMCklMEElMEElMjAlMjAlMjAlMjB0YWJsZSUyMCUzRCUyMGdyLkRhdGFmcmFtZSglMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB2YWx1ZSUzRGV2ZW50c19kZigpJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwaGVhZGVycyUzRENPTFVNTlMlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBsYWJlbCUzRCUyMlJlY2VudCUyMGV2ZW50cyUyMChuZXdlc3QlMjBmaXJzdCklMjIlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB3cmFwJTNEVHJ1ZSUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGludGVyYWN0aXZlJTNERmFsc2UlMkMlMEElMjAlMjAlMjAlMjApJTBBJTBBJTIwJTIwJTIwJTIwJTIzJTIwUG9sbCUyMHRoZSUyMHNoYXJlZCUyMGJ1ZmZlciUyMG9uY2UlMjBhJTIwc2Vjb25kLiUwQSUyMCUyMCUyMCUyMGdyLlRpbWVyKDEuMCkudGljayhyZWZyZXNoJTJDJTIwb3V0cHV0cyUzRCU1QnRhYmxlJTJDJTIwY2hhcnQlMkMlMjBoZWFkZXIlNUQpJTBBJTIwJTIwJTIwJTIwY2xlYXJfYnRuLmNsaWNrKGNsZWFyX2V2ZW50cyUyQyUyMG91dHB1dHMlM0QlNUJ0YWJsZSUyQyUyMGNoYXJ0JTJDJTIwaGVhZGVyJTVEKSUwQSUwQSUwQSUyMyUyME1vdW50JTIwR3JhZGlvJTIwb24lMjB0aGUlMjBGYXN0QVBJJTIwYXBwJTIwc28lMjAlNjAlMkZldmVudCU2MCUyMGFuZCUyMHRoZSUyMFVJJTIwc2hhcmUlMjBvbmUlMjBwcm9jZXNzLiUwQWFwcCUyMCUzRCUyMGdyLm1vdW50X2dyYWRpb19hcHAoYXBpJTJDJTIwdWklMkMlMjBwYXRoJTNEJTIyJTJGJTIyKSUwQSUwQSUwQWlmJTIwX19uYW1lX18lMjAlM0QlM0QlMjAlMjJfX21haW5fXyUyMiUzQSUwQSUyMCUyMCUyMCUyMGltcG9ydCUyMHV2aWNvcm4lMEElMEElMjAlMjAlMjAlMjB1dmljb3JuLnJ1bihhcHAlMkMlMjBob3N0JTNEJTIyMC4wLjAuMCUyMiUyQyUyMHBvcnQlM0Q4MDAwKQ==",highlighted:`<span class="hljs-keyword">import</span> datetime <span class="hljs-keyword">as</span> dt
<span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> Counter, deque
<span class="hljs-keyword">from</span> typing <span class="hljs-keyword">import</span> <span class="hljs-type">Any</span>
<span class="hljs-keyword">import</span> gradio <span class="hljs-keyword">as</span> gr
<span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd
<span class="hljs-keyword">from</span> fastapi <span class="hljs-keyword">import</span> FastAPI, Request
<span class="hljs-keyword">from</span> fastapi.responses <span class="hljs-keyword">import</span> JSONResponse
<span class="hljs-comment"># ---------- Shared state ----------</span>
MAX_EVENTS = <span class="hljs-number">500</span>
events: deque[<span class="hljs-built_in">dict</span>[<span class="hljs-built_in">str</span>, <span class="hljs-type">Any</span>]] = deque(maxlen=MAX_EVENTS)
<span class="hljs-keyword">def</span> <span class="hljs-title function_">_truncate</span>(<span class="hljs-params">value: <span class="hljs-type">Any</span>, n: <span class="hljs-built_in">int</span></span>) -&gt; <span class="hljs-built_in">str</span>:
text = <span class="hljs-string">&quot;&quot;</span> <span class="hljs-keyword">if</span> value <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span> <span class="hljs-keyword">else</span> <span class="hljs-built_in">str</span>(value)
<span class="hljs-keyword">return</span> text <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(text) &lt;= n <span class="hljs-keyword">else</span> text[: n - <span class="hljs-number">1</span>] + <span class="hljs-string">&quot;…&quot;</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">_normalize</span>(<span class="hljs-params">body: <span class="hljs-built_in">dict</span>[<span class="hljs-built_in">str</span>, <span class="hljs-type">Any</span>], headers: <span class="hljs-built_in">dict</span>[<span class="hljs-built_in">str</span>, <span class="hljs-built_in">str</span>]</span>) -&gt; <span class="hljs-built_in">dict</span>[<span class="hljs-built_in">str</span>, <span class="hljs-type">Any</span>]:
<span class="hljs-string">&quot;&quot;&quot;Map Claude Code / Codex / OpenCode / Pi payloads to one shape.&quot;&quot;&quot;</span>
platform = (
body.get(<span class="hljs-string">&quot;platform&quot;</span>)
<span class="hljs-keyword">or</span> headers.get(<span class="hljs-string">&quot;x-platform&quot;</span>)
<span class="hljs-keyword">or</span> <span class="hljs-string">&quot;unknown&quot;</span>
)
event_name = body.get(<span class="hljs-string">&quot;event&quot;</span>) <span class="hljs-keyword">or</span> body.get(<span class="hljs-string">&quot;hook_event_name&quot;</span>) <span class="hljs-keyword">or</span> <span class="hljs-string">&quot;Unknown&quot;</span>
tool = body.get(<span class="hljs-string">&quot;tool&quot;</span>) <span class="hljs-keyword">or</span> body.get(<span class="hljs-string">&quot;tool_name&quot;</span>) <span class="hljs-keyword">or</span> <span class="hljs-string">&quot;&quot;</span>
args = body.get(<span class="hljs-string">&quot;args&quot;</span>) <span class="hljs-keyword">or</span> body.get(<span class="hljs-string">&quot;tool_input&quot;</span>) <span class="hljs-keyword">or</span> body.get(<span class="hljs-string">&quot;prompt&quot;</span>) <span class="hljs-keyword">or</span> <span class="hljs-string">&quot;&quot;</span>
<span class="hljs-keyword">return</span> {
<span class="hljs-string">&quot;timestamp&quot;</span>: dt.datetime.utcnow().isoformat(timespec=<span class="hljs-string">&quot;seconds&quot;</span>) + <span class="hljs-string">&quot;Z&quot;</span>,
<span class="hljs-string">&quot;platform&quot;</span>: <span class="hljs-built_in">str</span>(platform),
<span class="hljs-string">&quot;event&quot;</span>: <span class="hljs-built_in">str</span>(event_name),
<span class="hljs-string">&quot;tool&quot;</span>: <span class="hljs-built_in">str</span>(tool),
<span class="hljs-string">&quot;args&quot;</span>: _truncate(args, <span class="hljs-number">200</span>),
}
<span class="hljs-comment"># ---------- FastAPI receiver ----------</span>
api = FastAPI(title=<span class="hljs-string">&quot;Agent Activity Dashboard&quot;</span>)
<span class="hljs-meta">@api.post(<span class="hljs-params"><span class="hljs-string">&quot;/event&quot;</span></span>)</span>
<span class="hljs-keyword">async</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">event</span>(<span class="hljs-params">req: Request</span>):
<span class="hljs-keyword">try</span>:
body = <span class="hljs-keyword">await</span> req.json()
<span class="hljs-keyword">except</span> Exception:
body = {}
record = _normalize(body, {k.lower(): v <span class="hljs-keyword">for</span> k, v <span class="hljs-keyword">in</span> req.headers.items()})
events.appendleft(record)
<span class="hljs-comment"># Return an empty body so hook callers never block on the dashboard receiver.</span>
<span class="hljs-keyword">return</span> JSONResponse({})
<span class="hljs-meta">@api.get(<span class="hljs-params"><span class="hljs-string">&quot;/health&quot;</span></span>)</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">health</span>():
<span class="hljs-keyword">return</span> {<span class="hljs-string">&quot;ok&quot;</span>: <span class="hljs-literal">True</span>, <span class="hljs-string">&quot;events&quot;</span>: <span class="hljs-built_in">len</span>(events)}
<span class="hljs-comment"># ---------- Gradio views ----------</span>
COLUMNS = [<span class="hljs-string">&quot;timestamp&quot;</span>, <span class="hljs-string">&quot;platform&quot;</span>, <span class="hljs-string">&quot;event&quot;</span>, <span class="hljs-string">&quot;tool&quot;</span>, <span class="hljs-string">&quot;args&quot;</span>]
<span class="hljs-keyword">def</span> <span class="hljs-title function_">events_df</span>() -&gt; pd.DataFrame:
<span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> events:
<span class="hljs-keyword">return</span> pd.DataFrame(columns=COLUMNS)
<span class="hljs-keyword">return</span> pd.DataFrame(<span class="hljs-built_in">list</span>(events), columns=COLUMNS)
<span class="hljs-keyword">def</span> <span class="hljs-title function_">tool_counts_df</span>() -&gt; pd.DataFrame:
counter = Counter(e[<span class="hljs-string">&quot;tool&quot;</span>] <span class="hljs-keyword">for</span> e <span class="hljs-keyword">in</span> events <span class="hljs-keyword">if</span> e[<span class="hljs-string">&quot;tool&quot;</span>])
rows = [{<span class="hljs-string">&quot;tool&quot;</span>: tool, <span class="hljs-string">&quot;count&quot;</span>: n} <span class="hljs-keyword">for</span> tool, n <span class="hljs-keyword">in</span> counter.most_common(<span class="hljs-number">15</span>)]
<span class="hljs-keyword">return</span> pd.DataFrame(rows, columns=[<span class="hljs-string">&quot;tool&quot;</span>, <span class="hljs-string">&quot;count&quot;</span>])
<span class="hljs-keyword">def</span> <span class="hljs-title function_">summary_md</span>() -&gt; <span class="hljs-built_in">str</span>:
total = <span class="hljs-built_in">len</span>(events)
platforms = <span class="hljs-built_in">sorted</span>({e[<span class="hljs-string">&quot;platform&quot;</span>] <span class="hljs-keyword">for</span> e <span class="hljs-keyword">in</span> events}) <span class="hljs-keyword">or</span> [<span class="hljs-string">&quot;(none)&quot;</span>]
tools = <span class="hljs-built_in">sorted</span>({e[<span class="hljs-string">&quot;tool&quot;</span>] <span class="hljs-keyword">for</span> e <span class="hljs-keyword">in</span> events <span class="hljs-keyword">if</span> e[<span class="hljs-string">&quot;tool&quot;</span>]})
tools_display = <span class="hljs-string">&quot;, &quot;</span>.join(tools) <span class="hljs-keyword">if</span> tools <span class="hljs-keyword">else</span> <span class="hljs-string">&quot;(none)&quot;</span>
<span class="hljs-keyword">return</span> (
<span class="hljs-string">f&quot;**Events:** <span class="hljs-subst">{total}</span> (buffer holds up to <span class="hljs-subst">{MAX_EVENTS}</span>) \\n&quot;</span>
<span class="hljs-string">f&quot;**Platforms seen:** <span class="hljs-subst">{<span class="hljs-string">&#x27;, &#x27;</span>.join(platforms)}</span> \\n&quot;</span>
<span class="hljs-string">f&quot;**Tools seen:** <span class="hljs-subst">{tools_display}</span>&quot;</span>
)
<span class="hljs-keyword">def</span> <span class="hljs-title function_">refresh</span>():
<span class="hljs-keyword">return</span> events_df(), tool_counts_df(), summary_md()
<span class="hljs-keyword">def</span> <span class="hljs-title function_">clear_events</span>():
events.clear()
<span class="hljs-keyword">return</span> refresh()
<span class="hljs-keyword">with</span> gr.Blocks(title=<span class="hljs-string">&quot;Agent Activity Dashboard&quot;</span>) <span class="hljs-keyword">as</span> ui:
gr.Markdown(<span class="hljs-string">&quot;# Agent Activity Dashboard&quot;</span>)
gr.Markdown(
<span class="hljs-string">&quot;Point your Claude Code, Codex, OpenCode, or Pi hooks/extensions at &quot;</span>
<span class="hljs-string">&quot;\`POST http://localhost:8000/event\` to see live activity here.&quot;</span>
)
header = gr.Markdown(value=summary_md())
<span class="hljs-keyword">with</span> gr.Row():
clear_btn = gr.Button(<span class="hljs-string">&quot;Clear events&quot;</span>, variant=<span class="hljs-string">&quot;secondary&quot;</span>)
chart = gr.BarPlot(
value=tool_counts_df(),
x=<span class="hljs-string">&quot;tool&quot;</span>,
y=<span class="hljs-string">&quot;count&quot;</span>,
title=<span class="hljs-string">&quot;Tool usage&quot;</span>,
tooltip=[<span class="hljs-string">&quot;tool&quot;</span>, <span class="hljs-string">&quot;count&quot;</span>],
height=<span class="hljs-number">280</span>,
)
table = gr.Dataframe(
value=events_df(),
headers=COLUMNS,
label=<span class="hljs-string">&quot;Recent events (newest first)&quot;</span>,
wrap=<span class="hljs-literal">True</span>,
interactive=<span class="hljs-literal">False</span>,
)
<span class="hljs-comment"># Poll the shared buffer once a second.</span>
gr.Timer(<span class="hljs-number">1.0</span>).tick(refresh, outputs=[table, chart, header])
clear_btn.click(clear_events, outputs=[table, chart, header])
<span class="hljs-comment"># Mount Gradio on the FastAPI app so \`/event\` and the UI share one process.</span>
app = gr.mount_gradio_app(api, ui, path=<span class="hljs-string">&quot;/&quot;</span>)
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&quot;__main__&quot;</span>:
<span class="hljs-keyword">import</span> uvicorn
uvicorn.run(app, host=<span class="hljs-string">&quot;0.0.0.0&quot;</span>, port=<span class="hljs-number">8000</span>)`,lang:"python",wrap:!1}}),O=new Z({props:{code:"cHl0aG9uJTIwYXBwLnB5",highlighted:"python app.py",lang:"bash",wrap:!1}}),ls=new E({props:{title:"Step 2: Connect Your Agent",local:"step-2-connect-your-agent",headingTag:"h2"}}),W=new la({props:{id:"tool",options:["Claude Code","Codex","OpenCode","Pi"],$$slots:{default:[ea]},$$scope:{ctx:R}}}),ts=new E({props:{title:"Step 3: Watch It Live",local:"step-3-watch-it-live",headingTag:"h2"}}),ps=new Z({props:{code:"dGltZXN0YW1wJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcGxhdGZvcm0lMjAlMjAlMjAlMjAlMjBldmVudCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHRvb2wlMjAlMjAlMjAlMjBhcmdzJTBBMjAyNi0wNC0yMFQxMCUzQTE1JTNBMDJaJTIwJTIwJTIwY2xhdWRlLWNvZGUlMjAlMjBVc2VyUHJvbXB0U3VibWl0JTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwTGlzdCUyMHRoZSUyMGZpbGVzJUUyJTgwJUE2JTBBMjAyNi0wNC0yMFQxMCUzQTE1JTNBMDNaJTIwJTIwJTIwY2xhdWRlLWNvZGUlMjAlMjBQcmVUb29sVXNlJTIwJTIwJTIwJTIwJTIwJTIwJTIwQmFzaCUyMCUyMCUyMCUyMCU3QiUyMmNvbW1hbmQlMjIlM0ElMjJscyUyMiU3RCUwQTIwMjYtMDQtMjBUMTAlM0ExNSUzQTAzWiUyMCUyMCUyMGNsYXVkZS1jb2RlJTIwJTIwUG9zdFRvb2xVc2UlMjAlMjAlMjAlMjAlMjAlMjBCYXNoJTIwJTIwJTIwJTIwJTdCJTIyZXhpdF9jb2RlJTIyJTNBMCUyQyVFMiU4MCVBNiU3RCUwQTIwMjYtMDQtMjBUMTAlM0ExNSUzQTA0WiUyMCUyMCUyMGNsYXVkZS1jb2RlJTIwJTIwUHJlVG9vbFVzZSUyMCUyMCUyMCUyMCUyMCUyMCUyMFJlYWQlMjAlMjAlMjAlMjAlN0IlMjJwYXRoJTIyJTNBJTIyUkVBRE1FJUUyJTgwJUE2JTBBMjAyNi0wNC0yMFQxMCUzQTE1JTNBMDRaJTIwJTIwJTIwY2xhdWRlLWNvZGUlMjAlMjBQb3N0VG9vbFVzZSUyMCUyMCUyMCUyMCUyMCUyMFJlYWQlMjAlMjAlMjAlMjAlN0IlMjJjb250ZW50JTIyJTNBJTIyJTIzJTIwJUUyJTgwJUE2JTBBMjAyNi0wNC0yMFQxMCUzQTE1JTNBMDZaJTIwJTIwJTIwY2xhdWRlLWNvZGUlMjAlMjBTdG9wJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJUUyJTgwJUE2",highlighted:`timestamp platform event tool args
2026<span class="hljs-string">-04</span><span class="hljs-string">-20</span>T10:15:02Z claude-code UserPromptSubmit List the files…
2026<span class="hljs-string">-04</span><span class="hljs-string">-20</span>T10:15:03Z claude-code PreToolUse Bash {&quot;command&quot;:&quot;ls&quot;}
2026<span class="hljs-string">-04</span><span class="hljs-string">-20</span>T10:15:03Z claude-code PostToolUse Bash {&quot;exit_code&quot;:0,…}
2026<span class="hljs-string">-04</span><span class="hljs-string">-20</span>T10:15:04Z claude-code PreToolUse Read {&quot;path&quot;:&quot;README…
2026<span class="hljs-string">-04</span><span class="hljs-string">-20</span>T10:15:04Z claude-code PostToolUse Read {&quot;content&quot;:&quot;# …
2026<span class="hljs-string">-04</span><span class="hljs-string">-20</span>T10:15:06Z claude-code Stop …`,lang:"",wrap:!1}}),Ms=new E({props:{title:"Step 4: Add a Guardrail",local:"step-4-add-a-guardrail",headingTag:"h2"}}),ys=new Z({props:{code:"JTdCJTBBJTIwJTIwJTIyaG9va3MlMjIlM0ElMjAlN0IlMEElMjAlMjAlMjAlMjAlMjJQcmVUb29sVXNlJTIyJTNBJTIwJTVCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIybWF0Y2hlciUyMiUzQSUyMCUyMkJhc2glMjIlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJob29rcyUyMiUzQSUyMCU1QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMnR5cGUlMjIlM0ElMjAlMjJjb21tYW5kJTIyJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIyY29tbWFuZCUyMiUzQSUyMCUyMmpxJTIwLXIlMjAnLnRvb2xfaW5wdXQuY29tbWFuZCUyMCUyRiUyRiUyMCU1QyUyMiU1QyUyMiclMjAlN0MlMjBncmVwJTIwLUVxJTIwJ3JtJTIwLXJmJTdDJTNBJTVDJTVDKCU1QyU1QyklNUMlNUMlN0IuKiU1QyU1QyU3Qy4qJTI2LiolNUMlNUMlN0QlM0EnJTIwJTI2JTI2JTIwJTdCJTIwZWNobyUyMCdibG9ja2VkJTNBJTIwZGFuZ2Vyb3VzJTIwc2hlbGwlMjBwYXR0ZXJuJyUyMCUzRSUyNjIlM0IlMjBleGl0JTIwMiUzQiUyMCU3RCUyMCU3QyU3QyUyMGV4aXQlMjAwJTIyJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdEJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTVEJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTdEJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIybWF0Y2hlciUyMiUzQSUyMCUyMiolMjIlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJob29rcyUyMiUzQSUyMCU1QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3QiUyMCUyMnR5cGUlMjIlM0ElMjAlMjJodHRwJTIyJTJDJTIwJTIydXJsJTIyJTNBJTIwJTIyaHR0cCUzQSUyRiUyRmxvY2FsaG9zdCUzQTgwMDAlMkZldmVudCUyMiUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMmhlYWRlcnMlMjIlM0ElMjAlN0IlMjAlMjJYLVBsYXRmb3JtJTIyJTNBJTIwJTIyY2xhdWRlLWNvZGUlMjIlMjAlN0QlMjAlN0QlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNUQlMEElMjAlMjAlMjAlMjAlMjAlMjAlN0QlMEElMjAlMjAlMjAlMjAlNUQlMEElMjAlMjAlN0QlMEElN0Q=",highlighted:`<span class="hljs-punctuation">{</span>
<span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">&quot;PreToolUse&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-punctuation">{</span>
<span class="hljs-attr">&quot;matcher&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;Bash&quot;</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-punctuation">{</span>
<span class="hljs-attr">&quot;type&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;command&quot;</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">&quot;command&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;jq -r &#x27;.tool_input.command // \\&quot;\\&quot;&#x27; | grep -Eq &#x27;rm -rf|:\\\\(\\\\)\\\\{.*\\\\|.*&amp;.*\\\\}:&#x27; &amp;&amp; { echo &#x27;blocked: dangerous shell pattern&#x27; &gt;&amp;2; exit 2; } || exit 0&quot;</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-punctuation">{</span>
<span class="hljs-attr">&quot;matcher&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;*&quot;</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">&quot;hooks&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;type&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;http&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;http://localhost:8000/event&quot;</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">&quot;headers&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;X-Platform&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;claude-code&quot;</span> <span class="hljs-punctuation">}</span> <span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>`,lang:"json",wrap:!1}}),us=new Z({props:{code:"bWtkaXIlMjAtcCUyMCUyRnRtcCUyRmhvb2stZ3VhcmRyYWlsLWRlbW8tZGVsZXRlLW1l",highlighted:'<span class="hljs-built_in">mkdir</span> -p /tmp/hook-guardrail-demo-delete-me',lang:"bash",wrap:!1}}),Us=new Z({props:{code:"cm0lMjAtcmYlMjAlMkZ0bXAlMkZob29rLWd1YXJkcmFpbC1kZW1vLWRlbGV0ZS1tZQ==",highlighted:"rm -rf /tmp/hook-guardrail-demo-delete-me",lang:"text",wrap:!1}}),Ts=new E({props:{title:"Step 5: Deploy (Optional)",local:"step-5-deploy-optional",headingTag:"h2"}}),ds=new E({props:{title:"Full Directory Layout",local:"full-directory-layout",headingTag:"h2"}}),Is=new Z({props:{code:"YWdlbnQtYWN0aXZpdHktZGFzaGJvYXJkJTJGJTBBJUUyJTk0JTlDJUUyJTk0JTgwJUUyJTk0JTgwJTIwYXBwLnB5JTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIzJTIwR3JhZGlvJTIwJTJCJTIwRmFzdEFQSSUyMHNlcnZlciUwQSVFMiU5NCU5QyVFMiU5NCU4MCVFMiU5NCU4MCUyMHJlcXVpcmVtZW50cy50eHQlMEElRTIlOTQlOUMlRTIlOTQlODAlRTIlOTQlODAlMjAuY2xhdWRlJTJGJTBBJUUyJTk0JTgyJTIwJTIwJTIwJUUyJTk0JTk0JUUyJTk0JTgwJUUyJTk0JTgwJTIwc2V0dGluZ3MuanNvbiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMyUyMENsYXVkZSUyMENvZGUlMjBob29rcyUwQSVFMiU5NCU5QyVFMiU5NCU4MCVFMiU5NCU4MCUyMC5jb2RleCUyRiUwQSVFMiU5NCU4MiUyMCUyMCUyMCVFMiU5NCU5NCVFMiU5NCU4MCVFMiU5NCU4MCUyMGhvb2tzLmpzb24lMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjMlMjBDb2RleCUyMGhvb2tzJTBBJUUyJTk0JTlDJUUyJTk0JTgwJUUyJTk0JTgwJTIwLm9wZW5jb2RlJTJGJTBBJUUyJTk0JTgyJTIwJTIwJTIwJUUyJTk0JTk0JUUyJTk0JTgwJUUyJTk0JTgwJTIwcGx1Z2lucyUyRiUwQSVFMiU5NCU4MiUyMCUyMCUyMCUyMCUyMCUyMCUyMCVFMiU5NCU5NCVFMiU5NCU4MCVFMiU5NCU4MCUyMGRhc2hib2FyZC50cyUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMyUyME9wZW5Db2RlJTIwcGx1Z2luJTBBJUUyJTk0JTk0JUUyJTk0JTgwJUUyJTk0JTgwJTIwLnBpJTJGJTBBJTIwJTIwJTIwJTIwJUUyJTk0JTk0JUUyJTk0JTgwJUUyJTk0JTgwJTIwZXh0ZW5zaW9ucyUyRiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCVFMiU5NCU5NCVFMiU5NCU4MCVFMiU5NCU4MCUyMGRhc2hib2FyZC50cyUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMyUyMFBpJTIwZXh0ZW5zaW9u",highlighted:`agent-activity-dashboard/
├── app.py <span class="hljs-comment"># Gradio + FastAPI server</span>
├── requirements.txt
├── <span class="hljs-string">.claude/</span>
│ └── settings.json <span class="hljs-comment"># Claude Code hooks</span>
├── <span class="hljs-string">.codex/</span>
│ └── hooks.json <span class="hljs-comment"># Codex hooks</span>
├── <span class="hljs-string">.opencode/</span>
│ └── plugins/
│ └── dashboard.ts <span class="hljs-comment"># OpenCode plugin</span>
└── <span class="hljs-string">.pi/</span>
└── extensions/
└── dashboard.ts <span class="hljs-comment"># Pi extension</span>`,lang:"",wrap:!1}}),Cs=new E({props:{title:"Best Practices Demonstrated",local:"best-practices-demonstrated",headingTag:"h2"}}),bs=new E({props:{title:"Key Takeaways",local:"key-takeaways",headingTag:"h2"}}),fs=new sa({props:{source:"https://github.com/huggingface/context-course/blob/main/units/en/unit5/hands-on.mdx"}}),{c(){c=u("meta"),N=p(),A=u("p"),U=p(),h(b.$$.fragment),i=p(),h(Q.$$.fragment),f=p(),n=u("p"),n.textContent=B,o=p(),h(m.$$.fragment),g=p(),M=u("p"),M.textContent=v,j=p(),q=u("ol"),q.innerHTML=Qs,S=p(),G=u("p"),G.textContent=x,y=p(),h(k.$$.fragment),ks=p(),Y=u("p"),Y.textContent=ml,gs=p(),h(X.$$.fragment),Ns=p(),z=u("p"),z.textContent=bl,vs=p(),h(F.$$.fragment),Zs=p(),_=u("p"),_.innerHTML=Bl,Gs=p(),h(H.$$.fragment),Rs=p(),h(L.$$.fragment),Es=p(),D=u("p"),D.innerHTML=Al,Ss=p(),h(P.$$.fragment),$s=p(),K=u("p"),K.textContent=fl,Ws=p(),h(O.$$.fragment),Vs=p(),ss=u("p"),ss.innerHTML=Ql,xs=p(),$=u("blockquote"),$.innerHTML=ql,Ys=p(),h(ls.$$.fragment),Xs=p(),as=u("p"),as.innerHTML=kl,zs=p(),h(W.$$.fragment),Fs=p(),h(ts.$$.fragment),_s=p(),ns=u("p"),ns.innerHTML=gl,Hs=p(),h(ps.$$.fragment),Ls=p(),es=u("p"),es.textContent=Nl,Ds=p(),h(Ms.$$.fragment),Ps=p(),os=u("p"),os.textContent=vl,Ks=p(),cs=u("p"),cs.innerHTML=Zl,Os=p(),h(ys.$$.fragment),sl=p(),js=u("p"),js.innerHTML=Gl,ll=p(),h(us.$$.fragment),al=p(),Js=u("p"),Js.textContent=Rl,tl=p(),h(Us.$$.fragment),nl=p(),is=u("p"),is.textContent=El,pl=p(),V=u("blockquote"),V.innerHTML=Sl,el=p(),h(Ts.$$.fragment),Ml=p(),hs=u("p"),hs.innerHTML=$l,ol=p(),ws=u("p"),ws.textContent=Wl,cl=p(),rs=u("ul"),rs.innerHTML=Vl,yl=p(),h(ds.$$.fragment),jl=p(),h(Is.$$.fragment),ul=p(),h(Cs.$$.fragment),Jl=p(),ms=u("p"),ms.innerHTML=xl,Ul=p(),h(bs.$$.fragment),il=p(),Bs=u("p"),Bs.textContent=Yl,Tl=p(),As=u("p"),As.textContent=Xl,hl=p(),h(fs.$$.fragment),wl=p(),qs=u("p"),this.h()},l(s){const t=Pl("svelte-u9bgzb",document.head);c=J(t,"META",{name:!0,content:!0}),t.forEach(l),N=e(s),A=J(s,"P",{}),Fl(A).forEach(l),U=e(s),w(b.$$.fragment,s),i=e(s),w(Q.$$.fragment,s),f=e(s),n=J(s,"P",{"data-svelte-h":!0}),T(n)!=="svelte-1v0okw4"&&(n.textContent=B),o=e(s),w(m.$$.fragment,s),g=e(s),M=J(s,"P",{"data-svelte-h":!0}),T(M)!=="svelte-bv11ys"&&(M.textContent=v),j=e(s),q=J(s,"OL",{"data-svelte-h":!0}),T(q)!=="svelte-6jlqsf"&&(q.innerHTML=Qs),S=e(s),G=J(s,"P",{"data-svelte-h":!0}),T(G)!=="svelte-18lrl7m"&&(G.textContent=x),y=e(s),w(k.$$.fragment,s),ks=e(s),Y=J(s,"P",{"data-svelte-h":!0}),T(Y)!=="svelte-k8ffup"&&(Y.textContent=ml),gs=e(s),w(X.$$.fragment,s),Ns=e(s),z=J(s,"P",{"data-svelte-h":!0}),T(z)!=="svelte-axv5aq"&&(z.textContent=bl),vs=e(s),w(F.$$.fragment,s),Zs=e(s),_=J(s,"P",{"data-svelte-h":!0}),T(_)!=="svelte-1wif1w7"&&(_.innerHTML=Bl),Gs=e(s),w(H.$$.fragment,s),Rs=e(s),w(L.$$.fragment,s),Es=e(s),D=J(s,"P",{"data-svelte-h":!0}),T(D)!=="svelte-v6usc5"&&(D.innerHTML=Al),Ss=e(s),w(P.$$.fragment,s),$s=e(s),K=J(s,"P",{"data-svelte-h":!0}),T(K)!=="svelte-vg7em0"&&(K.textContent=fl),Ws=e(s),w(O.$$.fragment,s),Vs=e(s),ss=J(s,"P",{"data-svelte-h":!0}),T(ss)!=="svelte-dbrytl"&&(ss.innerHTML=Ql),xs=e(s),$=J(s,"BLOCKQUOTE",{class:!0,"data-svelte-h":!0}),T($)!=="svelte-1a6web2"&&($.innerHTML=ql),Ys=e(s),w(ls.$$.fragment,s),Xs=e(s),as=J(s,"P",{"data-svelte-h":!0}),T(as)!=="svelte-cthaxr"&&(as.innerHTML=kl),zs=e(s),w(W.$$.fragment,s),Fs=e(s),w(ts.$$.fragment,s),_s=e(s),ns=J(s,"P",{"data-svelte-h":!0}),T(ns)!=="svelte-hgprkk"&&(ns.innerHTML=gl),Hs=e(s),w(ps.$$.fragment,s),Ls=e(s),es=J(s,"P",{"data-svelte-h":!0}),T(es)!=="svelte-b7u1qp"&&(es.textContent=Nl),Ds=e(s),w(Ms.$$.fragment,s),Ps=e(s),os=J(s,"P",{"data-svelte-h":!0}),T(os)!=="svelte-1n20nlg"&&(os.textContent=vl),Ks=e(s),cs=J(s,"P",{"data-svelte-h":!0}),T(cs)!=="svelte-1uhmwr4"&&(cs.innerHTML=Zl),Os=e(s),w(ys.$$.fragment,s),sl=e(s),js=J(s,"P",{"data-svelte-h":!0}),T(js)!=="svelte-rtlx51"&&(js.innerHTML=Gl),ll=e(s),w(us.$$.fragment,s),al=e(s),Js=J(s,"P",{"data-svelte-h":!0}),T(Js)!=="svelte-1yjdm92"&&(Js.textContent=Rl),tl=e(s),w(Us.$$.fragment,s),nl=e(s),is=J(s,"P",{"data-svelte-h":!0}),T(is)!=="svelte-gd2dw1"&&(is.textContent=El),pl=e(s),V=J(s,"BLOCKQUOTE",{class:!0,"data-svelte-h":!0}),T(V)!=="svelte-jlb7hj"&&(V.innerHTML=Sl),el=e(s),w(Ts.$$.fragment,s),Ml=e(s),hs=J(s,"P",{"data-svelte-h":!0}),T(hs)!=="svelte-3d0kdp"&&(hs.innerHTML=$l),ol=e(s),ws=J(s,"P",{"data-svelte-h":!0}),T(ws)!=="svelte-1d43rs8"&&(ws.textContent=Wl),cl=e(s),rs=J(s,"UL",{"data-svelte-h":!0}),T(rs)!=="svelte-rg4p77"&&(rs.innerHTML=Vl),yl=e(s),w(ds.$$.fragment,s),jl=e(s),w(Is.$$.fragment,s),ul=e(s),w(Cs.$$.fragment,s),Jl=e(s),ms=J(s,"P",{"data-svelte-h":!0}),T(ms)!=="svelte-1sruzmf"&&(ms.innerHTML=xl),Ul=e(s),w(bs.$$.fragment,s),il=e(s),Bs=J(s,"P",{"data-svelte-h":!0}),T(Bs)!=="svelte-1yg7kbu"&&(Bs.textContent=Yl),Tl=e(s),As=J(s,"P",{"data-svelte-h":!0}),T(As)!=="svelte-1ie4ifs"&&(As.textContent=Xl),hl=e(s),w(fs.$$.fragment,s),wl=e(s),qs=J(s,"P",{}),Fl(qs).forEach(l),this.h()},h(){dl(c,"name","hf:doc:metadata"),dl(c,"content",oa),dl($,"class","tip"),dl(V,"class","tip")},m(s,t){Kl(document.head,c),a(s,N,t),a(s,A,t),a(s,U,t),r(b,s,t),a(s,i,t),r(Q,s,t),a(s,f,t),a(s,n,t),a(s,o,t),r(m,s,t),a(s,g,t),a(s,M,t),a(s,j,t),a(s,q,t),a(s,S,t),a(s,G,t),a(s,y,t),r(k,s,t),a(s,ks,t),a(s,Y,t),a(s,gs,t),r(X,s,t),a(s,Ns,t),a(s,z,t),a(s,vs,t),r(F,s,t),a(s,Zs,t),a(s,_,t),a(s,Gs,t),r(H,s,t),a(s,Rs,t),r(L,s,t),a(s,Es,t),a(s,D,t),a(s,Ss,t),r(P,s,t),a(s,$s,t),a(s,K,t),a(s,Ws,t),r(O,s,t),a(s,Vs,t),a(s,ss,t),a(s,xs,t),a(s,$,t),a(s,Ys,t),r(ls,s,t),a(s,Xs,t),a(s,as,t),a(s,zs,t),r(W,s,t),a(s,Fs,t),r(ts,s,t),a(s,_s,t),a(s,ns,t),a(s,Hs,t),r(ps,s,t),a(s,Ls,t),a(s,es,t),a(s,Ds,t),r(Ms,s,t),a(s,Ps,t),a(s,os,t),a(s,Ks,t),a(s,cs,t),a(s,Os,t),r(ys,s,t),a(s,sl,t),a(s,js,t),a(s,ll,t),r(us,s,t),a(s,al,t),a(s,Js,t),a(s,tl,t),r(Us,s,t),a(s,nl,t),a(s,is,t),a(s,pl,t),a(s,V,t),a(s,el,t),r(Ts,s,t),a(s,Ml,t),a(s,hs,t),a(s,ol,t),a(s,ws,t),a(s,cl,t),a(s,rs,t),a(s,yl,t),r(ds,s,t),a(s,jl,t),r(Is,s,t),a(s,ul,t),r(Cs,s,t),a(s,Jl,t),a(s,ms,t),a(s,Ul,t),r(bs,s,t),a(s,il,t),a(s,Bs,t),a(s,Tl,t),a(s,As,t),a(s,hl,t),r(fs,s,t),a(s,wl,t),a(s,qs,t),rl=!0},p(s,[t]){const zl={};t&2&&(zl.$$scope={dirty:t,ctx:s}),W.$set(zl)},i(s){rl||(d(b.$$.fragment,s),d(Q.$$.fragment,s),d(m.$$.fragment,s),d(k.$$.fragment,s),d(X.$$.fragment,s),d(F.$$.fragment,s),d(H.$$.fragment,s),d(L.$$.fragment,s),d(P.$$.fragment,s),d(O.$$.fragment,s),d(ls.$$.fragment,s),d(W.$$.fragment,s),d(ts.$$.fragment,s),d(ps.$$.fragment,s),d(Ms.$$.fragment,s),d(ys.$$.fragment,s),d(us.$$.fragment,s),d(Us.$$.fragment,s),d(Ts.$$.fragment,s),d(ds.$$.fragment,s),d(Is.$$.fragment,s),d(Cs.$$.fragment,s),d(bs.$$.fragment,s),d(fs.$$.fragment,s),rl=!0)},o(s){I(b.$$.fragment,s),I(Q.$$.fragment,s),I(m.$$.fragment,s),I(k.$$.fragment,s),I(X.$$.fragment,s),I(F.$$.fragment,s),I(H.$$.fragment,s),I(L.$$.fragment,s),I(P.$$.fragment,s),I(O.$$.fragment,s),I(ls.$$.fragment,s),I(W.$$.fragment,s),I(ts.$$.fragment,s),I(ps.$$.fragment,s),I(Ms.$$.fragment,s),I(ys.$$.fragment,s),I(us.$$.fragment,s),I(Us.$$.fragment,s),I(Ts.$$.fragment,s),I(ds.$$.fragment,s),I(Is.$$.fragment,s),I(Cs.$$.fragment,s),I(bs.$$.fragment,s),I(fs.$$.fragment,s),rl=!1},d(s){s&&(l(N),l(A),l(U),l(i),l(f),l(n),l(o),l(g),l(M),l(j),l(q),l(S),l(G),l(y),l(ks),l(Y),l(gs),l(Ns),l(z),l(vs),l(Zs),l(_),l(Gs),l(Rs),l(Es),l(D),l(Ss),l($s),l(K),l(Ws),l(Vs),l(ss),l(xs),l($),l(Ys),l(Xs),l(as),l(zs),l(Fs),l(_s),l(ns),l(Hs),l(Ls),l(es),l(Ds),l(Ps),l(os),l(Ks),l(cs),l(Os),l(sl),l(js),l(ll),l(al),l(Js),l(tl),l(nl),l(is),l(pl),l(V),l(el),l(Ml),l(hs),l(ol),l(ws),l(cl),l(rs),l(yl),l(jl),l(ul),l(Jl),l(ms),l(Ul),l(il),l(Bs),l(Tl),l(As),l(hl),l(wl),l(qs)),l(c),C(b,s),C(Q,s),C(m,s),C(k,s),C(X,s),C(F,s),C(H,s),C(L,s),C(P,s),C(O,s),C(ls,s),C(W,s),C(ts,s),C(ps,s),C(Ms,s),C(ys,s),C(us,s),C(Us,s),C(Ts,s),C(ds,s),C(Is,s),C(Cs,s),C(bs,s),C(fs,s)}}}const oa='{"title":"Hands-On: Build an Agent Activity Dashboard with Gradio","local":"hands-on-build-an-agent-activity-dashboard-with-gradio","sections":[{"title":"What You’ll Build","local":"what-youll-build","sections":[],"depth":2},{"title":"Project Setup","local":"project-setup","sections":[],"depth":2},{"title":"Step 1: Build the Receiver and Dashboard","local":"step-1-build-the-receiver-and-dashboard","sections":[],"depth":2},{"title":"Step 2: Connect Your Agent","local":"step-2-connect-your-agent","sections":[],"depth":2},{"title":"Step 3: Watch It Live","local":"step-3-watch-it-live","sections":[],"depth":2},{"title":"Step 4: Add a Guardrail","local":"step-4-add-a-guardrail","sections":[],"depth":2},{"title":"Step 5: Deploy (Optional)","local":"step-5-deploy-optional","sections":[],"depth":2},{"title":"Full Directory Layout","local":"full-directory-layout","sections":[],"depth":2},{"title":"Best Practices Demonstrated","local":"best-practices-demonstrated","sections":[],"depth":2},{"title":"Key Takeaways","local":"key-takeaways","sections":[],"depth":2}],"depth":1}';function ca(R){return Hl(()=>{new URLSearchParams(window.location.search).get("fw")}),[]}class ia extends Ll{constructor(c){super(),Dl(this,c,ca,Ma,_l,{})}}export{ia as component};

Xet Storage Details

Size:
85.5 kB
·
Xet hash:
64052fea33b8308e552e85b771c01dd378313e263512da346e08ef702ad64377

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.