@stacknet/rackutils 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,10 @@
1
- 'use strict';var react=require('react'),lucideReact=require('lucide-react'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),jsxRuntime=require('react/jsx-runtime');function k(...r){return tailwindMerge.twMerge(clsx.clsx(r))}async function v(r,e,i,s){let o={"Content-Type":"application/json",...i?.headers};s&&(o.Authorization=`Bearer ${s}`);let c=await fetch(`${r}${e}`,{...i,headers:o});if(!c.ok){let t=`HTTP ${c.status}`;try{let a=await c.json();a.error&&(t=a.error);}catch{}throw new Error(t)}return c.json()}function P(r){let e=r.indexOf(":");return {mode:r.slice(0,e),cid:r.slice(e+1)}}function M(r){let e=r.apiBaseUrl,i=r.authorMid,s=r.ownerMid,o=r.apiKey,c=r.stacknetUrl||r.apiBaseUrl;return react.useMemo(()=>({async listRepos(t){let a=t||s?`?owner=${encodeURIComponent(t||s)}`:"";return (await v(e,`/api/rack/repos${a}`,void 0,o)).repos||[]},async initRepo(t){return v(e,"/api/rack/init",{method:"POST",body:JSON.stringify({...t,owner_mid:s})},o)},async push(t,a){return v(e,`/api/rack/${t}/push`,{method:"POST",body:JSON.stringify({...a,author_mid:i})},o)},async getTree(t,a="main"){let l=await v(e,`/api/rack/${t}/tree/${a}`,void 0,o);return {tree:l.tree,commit_cid:l.commit_cid}},async getBlob(t,a){return (await v(e,`/api/rack/${t}/blob/${a}`,void 0,o)).content},async getLog(t,a,l){let d=new URLSearchParams;a&&d.set("ref",a),l&&d.set("max_count",String(l));let u=d.toString()?`?${d}`:"";return (await v(e,`/api/rack/${t}/log${u}`,void 0,o)).commits||[]},async getBranches(t){return (await v(e,`/api/rack/${t}/branches`,void 0,o)).branches||[]},async createBranch(t,a,l){return v(e,`/api/rack/${t}/branch`,{method:"POST",body:JSON.stringify({branch_name:a,from_ref:l})},o)},async merge(t,a,l){return v(e,`/api/rack/${t}/merge`,{method:"POST",body:JSON.stringify({source_branch:a,target_branch:l})},o)},async getDiff(t,a,l){return (await v(e,`/api/rack/${t}/diff/${a}/${l}`,void 0,o)).diff?.entries||[]},async starRepo(t){return v(e,`/api/rack/${t}/star`,{method:"POST"},o)},async unstarRepo(t){return v(e,`/api/rack/${t}/star`,{method:"DELETE"},o)},async getStarInfo(t){return v(e,`/api/rack/${t}/stars`,void 0,o)},async getSkillStats(t){let a={meta:null,tokenCount:null,usageCount:null};try{let{tree:l}=await this.getTree(t,"main");if(!l?.entries)return a;if(l.entries["META.json"]){let p=P(l.entries["META.json"]).cid,g=await this.getBlob(t,p);a.meta=JSON.parse(g);}let d=0,u=Object.values(l.entries).map(async p=>{try{let g=P(p).cid,f=await this.getBlob(t,g);d+=f.length;}catch{}});await Promise.all(u),d>0&&(a.tokenCount=Math.ceil(d/4)),a.meta?.skill_id&&(a.usageCount=await this.getSkillUsageCount(a.meta.skill_id));}catch{}return a},async getSkillUsageCount(t){try{let a=await fetch(`${c}/v1/skills/${encodeURIComponent(t)}`);if(a.ok){let d=await a.json();return d.usage_count??d.usageCount??null}let l=await fetch(`${c}/v1/skills?scope=public`);if(l.ok){let u=((await l.json()).skills||[]).find(p=>p.name===t||p.id===t);if(u)return u.usage_count??u.usageCount??0}return 0}catch{return null}},async getTensorStats(t){let a={meta:null,sizeMB:null};try{let{tree:l}=await this.getTree(t,"main");if(!l?.entries)return a;if(l.entries["TENSOR_META.json"]){let d=P(l.entries["TENSOR_META.json"]).cid,u=await this.getBlob(t,d);a.meta=JSON.parse(u),a.sizeMB=a.meta?.tensor_size_mb??null;}}catch{}return a},async getNetworkStats(){try{return (await v(e,"/api/rack/stats",void 0,o)).stats||null}catch{return null}},async getTrending(t=5,a=1){try{return (await v(e,`/api/rack/trending?limit=${t}&days=${a}`,void 0,o)).trending||[]}catch{return []}}}),[e,i,s,o,c])}function Z(r){let e=M(r),i=react.useRef(e);i.current=e;let[s,o]=react.useState([]),[c,t]=react.useState(true),[a,l]=react.useState(null),d=react.useRef(true),u=react.useRef(null),p=react.useCallback(async()=>{u.current?.abort();let g=new AbortController;u.current=g;try{d.current&&(t(!0),l(null));let f=await i.current.listRepos();d.current&&!g.signal.aborted&&o(f);}catch(f){d.current&&!g.signal.aborted&&l(f instanceof Error?f.message:"Failed to load repos");}finally{d.current&&!g.signal.aborted&&t(false);}},[]);return react.useEffect(()=>(d.current=true,p(),()=>{d.current=false,u.current?.abort();}),[p]),{repos:s,loading:c,error:a,refresh:p}}function ge(r){return Object.entries(r).map(([e,i])=>{let s=i.indexOf(":"),o=s>0?i.slice(0,s):"100644",c=s>0?i.slice(s+1):i;return {path:e,mode:o,cid:c,isDir:o==="040000"}}).sort((e,i)=>e.isDir!==i.isDir?e.isDir?-1:1:e.path.localeCompare(i.path))}function W(r,e,i="main"){let s=M(r),[o,c]=react.useState([]),[t,a]=react.useState(false),[l,d]=react.useState(null),u=react.useRef(true),p=react.useCallback(async()=>{if(e)try{u.current&&(a(!0),d(null));let{tree:f}=await s.getTree(e,i);u.current&&c(ge(f.entries));}catch(f){u.current&&d(f instanceof Error?f.message:"Failed to load tree");}finally{u.current&&a(false);}},[s,e,i]);react.useEffect(()=>(u.current=true,p(),()=>{u.current=false;}),[p]);let g=react.useCallback(async f=>{if(!e)throw new Error("No repo selected");return s.getBlob(e,f)},[s,e]);return {entries:o,loading:t,error:l,refresh:p,getFileContent:g}}var pe=/^(https?:\/\/|mailto:|\/[^/])/i;function he(r){let e=r.trim();return pe.test(e)?e:null}function z(r){let e=[],i=/(`[^`]+`)|(\*\*(.+?)\*\*)|(\*(.+?)\*)|(_(.+?)_)|(\[([^\]]+)\]\(([^)]+)\))/g,s=0,o,c=0;for(;(o=i.exec(r))!==null;){o.index>s&&e.push(r.slice(s,o.index));let t=`i${c++}`;if(o[1])e.push(jsxRuntime.jsx("code",{className:"rounded bg-muted px-1.5 py-0.5 text-[0.85em] font-mono text-pink-400",children:o[1].slice(1,-1)},t));else if(o[2])e.push(jsxRuntime.jsx("strong",{children:o[3]},t));else if(o[4])e.push(jsxRuntime.jsx("em",{children:o[5]},t));else if(o[6])e.push(jsxRuntime.jsx("em",{children:o[7]},t));else if(o[8]){let a=he(o[10]);a?e.push(jsxRuntime.jsx("a",{href:a,className:"text-blue-400 underline hover:text-blue-300",target:"_blank",rel:"noopener noreferrer",children:o[9]},t)):e.push(o[9]);}s=o.index+o[0].length;}return s<r.length&&e.push(r.slice(s)),e.length>0?e:[r]}function xe(r){let e=r.split(`
1
+ 'use strict';var react=require('react'),lucideReact=require('lucide-react'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),jsxRuntime=require('react/jsx-runtime');function k(...r){return tailwindMerge.twMerge(clsx.clsx(r))}async function v(r,e,i,s){let o={"Content-Type":"application/json",...i?.headers};s&&(o.Authorization=`Bearer ${s}`);let c=await fetch(`${r}${e}`,{...i,headers:o});if(!c.ok){let t=`HTTP ${c.status}`;try{let a=await c.json();a.error&&(t=a.error);}catch{}throw new Error(t)}return c.json()}function $(r){let e=r.indexOf(":");return {mode:r.slice(0,e),cid:r.slice(e+1)}}function P(r){let e=r.apiBaseUrl,i=r.authorMid,s=r.ownerMid,o=r.apiKey,c=r.stacknetUrl||r.apiBaseUrl;return react.useMemo(()=>({async listRepos(t,a){let l=new URLSearchParams;(t||s)&&l.set("owner",t||s),a?.limit&&l.set("limit",String(a.limit)),a?.cursor&&l.set("cursor",a.cursor);let d=l.toString()?`?${l}`:"",u=await v(e,`/api/rack/repos${d}`,void 0,o);return {items:u.repos||[],pagination:u.pagination||{total:(u.repos||[]).length,limit:50,has_more:false,next_cursor:null}}},async initRepo(t){return v(e,"/api/rack/init",{method:"POST",body:JSON.stringify({...t,owner_mid:s})},o)},async push(t,a){return v(e,`/api/rack/${t}/push`,{method:"POST",body:JSON.stringify({...a,author_mid:i})},o)},async getTree(t,a="main"){let l=await v(e,`/api/rack/${t}/tree/${a}`,void 0,o);return {tree:l.tree,commit_cid:l.commit_cid}},async getBlob(t,a){return (await v(e,`/api/rack/${t}/blob/${a}`,void 0,o)).content},async getLog(t,a,l){let d=new URLSearchParams;a&&d.set("ref",a),l&&d.set("max_count",String(l));let u=d.toString()?`?${d}`:"";return (await v(e,`/api/rack/${t}/log${u}`,void 0,o)).commits||[]},async getBranches(t){return (await v(e,`/api/rack/${t}/branches`,void 0,o)).branches||[]},async createBranch(t,a,l){return v(e,`/api/rack/${t}/branch`,{method:"POST",body:JSON.stringify({branch_name:a,from_ref:l})},o)},async merge(t,a,l){return v(e,`/api/rack/${t}/merge`,{method:"POST",body:JSON.stringify({source_branch:a,target_branch:l})},o)},async getDiff(t,a,l){return (await v(e,`/api/rack/${t}/diff/${a}/${l}`,void 0,o)).diff?.entries||[]},async starRepo(t){return v(e,`/api/rack/${t}/star`,{method:"POST"},o)},async unstarRepo(t){return v(e,`/api/rack/${t}/star`,{method:"DELETE"},o)},async getStarInfo(t){return v(e,`/api/rack/${t}/stars`,void 0,o)},async getSkillStats(t){let a={meta:null,tokenCount:null,usageCount:null};try{let{tree:l}=await this.getTree(t,"main");if(!l?.entries)return a;if(l.entries["META.json"]){let p=$(l.entries["META.json"]).cid,g=await this.getBlob(t,p);a.meta=JSON.parse(g);}let d=0,u=Object.values(l.entries).map(async p=>{try{let g=$(p).cid,f=await this.getBlob(t,g);d+=f.length;}catch{}});await Promise.all(u),d>0&&(a.tokenCount=Math.ceil(d/4)),a.meta?.skill_id&&(a.usageCount=await this.getSkillUsageCount(a.meta.skill_id));}catch{}return a},async getSkillUsageCount(t){try{let a=await fetch(`${c}/v1/skills/${encodeURIComponent(t)}`);if(a.ok){let d=await a.json();return d.usage_count??d.usageCount??null}let l=await fetch(`${c}/v1/skills?scope=public`);if(l.ok){let u=((await l.json()).skills||[]).find(p=>p.name===t||p.id===t);if(u)return u.usage_count??u.usageCount??0}return 0}catch{return null}},async getTensorStats(t){let a={meta:null,sizeMB:null};try{let{tree:l}=await this.getTree(t,"main");if(!l?.entries)return a;if(l.entries["TENSOR_META.json"]){let d=$(l.entries["TENSOR_META.json"]).cid,u=await this.getBlob(t,d);a.meta=JSON.parse(u),a.sizeMB=a.meta?.tensor_size_mb??null;}}catch{}return a},async getNetworkStats(){try{return (await v(e,"/api/rack/stats",void 0,o)).stats||null}catch{return null}},async getTrending(t=5,a=1,l){try{let d=new URLSearchParams({limit:String(t),days:String(a)});l&&d.set("cursor",l);let u=await v(e,`/api/rack/trending?${d}`,void 0,o);return {items:u.trending||[],pagination:u.pagination||{total:(u.trending||[]).length,limit:t,has_more:!1,next_cursor:null}}}catch{return {items:[],pagination:{total:0,limit:t,has_more:false,next_cursor:null}}}}}),[e,i,s,o,c])}function Z(r){let e=P(r),i=react.useRef(e);i.current=e;let[s,o]=react.useState([]),[c,t]=react.useState(true),[a,l]=react.useState(null),d=react.useRef(true),u=react.useRef(null),p=react.useCallback(async()=>{u.current?.abort();let g=new AbortController;u.current=g;try{d.current&&(t(!0),l(null));let f=await i.current.listRepos();d.current&&!g.signal.aborted&&o(f.items);}catch(f){d.current&&!g.signal.aborted&&l(f instanceof Error?f.message:"Failed to load repos");}finally{d.current&&!g.signal.aborted&&t(false);}},[]);return react.useEffect(()=>(d.current=true,p(),()=>{d.current=false,u.current?.abort();}),[p]),{repos:s,loading:c,error:a,refresh:p}}function ge(r){return Object.entries(r).map(([e,i])=>{let s=i.indexOf(":"),o=s>0?i.slice(0,s):"100644",c=s>0?i.slice(s+1):i;return {path:e,mode:o,cid:c,isDir:o==="040000"}}).sort((e,i)=>e.isDir!==i.isDir?e.isDir?-1:1:e.path.localeCompare(i.path))}function W(r,e,i="main"){let s=P(r),[o,c]=react.useState([]),[t,a]=react.useState(false),[l,d]=react.useState(null),u=react.useRef(true),p=react.useCallback(async()=>{if(e)try{u.current&&(a(!0),d(null));let{tree:f}=await s.getTree(e,i);u.current&&c(ge(f.entries));}catch(f){u.current&&d(f instanceof Error?f.message:"Failed to load tree");}finally{u.current&&a(false);}},[s,e,i]);react.useEffect(()=>(u.current=true,p(),()=>{u.current=false;}),[p]);let g=react.useCallback(async f=>{if(!e)throw new Error("No repo selected");return s.getBlob(e,f)},[s,e]);return {entries:o,loading:t,error:l,refresh:p,getFileContent:g}}var pe=/^(https?:\/\/|mailto:|\/[^/])/i;function he(r){let e=r.trim();return pe.test(e)?e:null}function M(r){let e=[],i=/(`[^`]+`)|(\*\*(.+?)\*\*)|(\*(.+?)\*)|(_(.+?)_)|(\[([^\]]+)\]\(([^)]+)\))/g,s=0,o,c=0;for(;(o=i.exec(r))!==null;){o.index>s&&e.push(r.slice(s,o.index));let t=`i${c++}`;if(o[1])e.push(jsxRuntime.jsx("code",{className:"rounded bg-muted px-1.5 py-0.5 text-[0.85em] font-mono text-pink-400",children:o[1].slice(1,-1)},t));else if(o[2])e.push(jsxRuntime.jsx("strong",{children:o[3]},t));else if(o[4])e.push(jsxRuntime.jsx("em",{children:o[5]},t));else if(o[6])e.push(jsxRuntime.jsx("em",{children:o[7]},t));else if(o[8]){let a=he(o[10]);a?e.push(jsxRuntime.jsx("a",{href:a,className:"text-blue-400 underline hover:text-blue-300",target:"_blank",rel:"noopener noreferrer",children:o[9]},t)):e.push(o[9]);}s=o.index+o[0].length;}return s<r.length&&e.push(r.slice(s)),e.length>0?e:[r]}function xe(r){let e=r.split(`
2
2
  `),i=[],s=0;for(;s<e.length;){let o=e[s];if(o.trim()===""){s++;continue}if(/^(-{3,}|\*{3,}|_{3,})$/.test(o.trim())){i.push({type:"hr"}),s++;continue}let c=o.match(/^(#{1,6})\s+(.+)/);if(c){i.push({type:"heading",level:c[1].length,content:c[2]}),s++;continue}if(o.trim().startsWith("```")){let a=o.trim().slice(3).trim(),l=[];for(s++;s<e.length&&!e[s].trim().startsWith("```");)l.push(e[s]),s++;i.push({type:"code",content:l.join(`
3
- `),lang:a||void 0}),s++;continue}if(/^\s*[-*+]\s/.test(o)){let a=[];for(;s<e.length&&/^\s*[-*+]\s/.test(e[s]);)a.push(e[s].replace(/^\s*[-*+]\s+/,"")),s++;i.push({type:"ul",items:a});continue}if(/^\s*\d+[.)]\s/.test(o)){let a=[];for(;s<e.length&&/^\s*\d+[.)]\s/.test(e[s]);)a.push(e[s].replace(/^\s*\d+[.)]\s+/,"")),s++;i.push({type:"ol",items:a});continue}let t=[];for(;s<e.length&&e[s].trim()!==""&&!e[s].match(/^#{1,6}\s/)&&!e[s].trim().startsWith("```")&&!/^\s*[-*+]\s/.test(e[s])&&!/^\s*\d+[.)]\s/.test(e[s]);)t.push(e[s]),s++;t.length>0&&i.push({type:"paragraph",content:t.join(" ")});}return i}var ve={1:"text-2xl font-bold mt-6 mb-3",2:"text-xl font-bold mt-5 mb-2",3:"text-lg font-semibold mt-4 mb-2",4:"text-base font-semibold mt-3 mb-1",5:"text-sm font-semibold mt-2 mb-1",6:"text-sm font-medium mt-2 mb-1"};function be(r,e){switch(r.type){case "hr":return jsxRuntime.jsx("hr",{className:"my-4 border-border"},`b${e}`);case "heading":{let i=Math.min(Math.max(r.level||1,1),6),s=`h${i}`;return jsxRuntime.jsx(s,{className:k("text-foreground",ve[i]),children:z(r.content||"")},`b${e}`)}case "paragraph":return jsxRuntime.jsx("p",{className:"mb-3 leading-relaxed text-foreground",children:z(r.content||"")},`b${e}`);case "code":return jsxRuntime.jsx("pre",{className:"mb-3 overflow-x-auto rounded-lg bg-muted p-4 text-sm font-mono leading-relaxed text-foreground",children:jsxRuntime.jsx("code",{children:r.content})},`b${e}`);case "ul":return jsxRuntime.jsx("ul",{className:"mb-3 ml-5 list-disc space-y-1 text-foreground",children:r.items?.map((i,s)=>jsxRuntime.jsx("li",{className:"leading-relaxed",children:z(i)},`li${e}-${s}`))},`b${e}`);case "ol":return jsxRuntime.jsx("ol",{className:"mb-3 ml-5 list-decimal space-y-1 text-foreground",children:r.items?.map((i,s)=>jsxRuntime.jsx("li",{className:"leading-relaxed",children:z(i)},`li${e}-${s}`))},`b${e}`);default:return null}}function B({content:r,className:e}){let i=xe(r);return jsxRuntime.jsx("div",{className:k("text-sm",e),children:i.map((s,o)=>be(s,o))})}function Q({open:r,className:e}){return jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:k("shrink-0 transition-transform duration-150",r?"rotate-0":"-rotate-90",e),children:jsxRuntime.jsx("path",{d:"M16.134 6.16a.5.5 0 1 1 .732.68l-6.5 7-.077.068a.5.5 0 0 1-.655-.068l-6.5-7-.062-.08a.5.5 0 0 1 .718-.667l.076.067L10 12.767z"})})}function q({size:r=20,className:e}){return jsxRuntime.jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsxRuntime.jsx("path",{d:"M8.5 2a6.5 6.5 0 0 1 4.935 10.728l4.419 4.419.064.078a.5.5 0 0 1-.693.693l-.079-.064-4.419-4.42A6.5 6.5 0 1 1 8.5 2m0 1a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11"})})}function L({size:r=20,className:e}){return jsxRuntime.jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsxRuntime.jsx("path",{d:"M15.147 4.146a.5.5 0 0 1 .707.707L10.707 10l5.147 5.147a.5.5 0 0 1-.63.771l-.078-.064L10 10.707l-5.146 5.147a.5.5 0 0 1-.708-.707L9.293 10 4.146 4.853a.5.5 0 0 1 .708-.707L10 9.293z"})})}function Y({size:r=20,className:e}){return jsxRuntime.jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsxRuntime.jsx("path",{d:"M10 3a.5.5 0 0 1 .5.5v6h6l.1.01a.5.5 0 0 1 0 .98l-.1.01h-6v6a.5.5 0 0 1-1 0v-6h-6a.5.5 0 0 1 0-1h6v-6A.5.5 0 0 1 10 3"})})}function ke(){return jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M6.5 3A2.5 2.5 0 0 0 4 5.5v9A2.5 2.5 0 0 0 6.5 17h7a2.5 2.5 0 0 0 2.5-2.5v-7A2.5 2.5 0 0 0 13.5 5H11V3.5a.5.5 0 0 0-1 0V5H6.5ZM5 5.5A1.5 1.5 0 0 1 6.5 4H9v1H6.5A1.5 1.5 0 0 0 5 6.5v8A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-7A1.5 1.5 0 0 0 13.5 6H11V4h2.5A2.5 2.5 0 0 1 16 6.5v8a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-9Z"})})}function Ne(){return jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M5.5 3A2.5 2.5 0 0 0 3 5.5v9A2.5 2.5 0 0 0 5.5 17h9a2.5 2.5 0 0 0 2.5-2.5v-9A2.5 2.5 0 0 0 14.5 3h-9ZM4 5.5A1.5 1.5 0 0 1 5.5 4h9A1.5 1.5 0 0 1 16 5.5v9a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 4 14.5v-9ZM7 7.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5Z"})})}function Re(){return jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M10 2a.5.5 0 0 1 .354.146l3 3a.5.5 0 0 1-.708.708L10.5 3.707V12.5a.5.5 0 0 1-1 0V3.707L7.354 5.854a.5.5 0 1 1-.708-.708l3-3A.5.5 0 0 1 10 2ZM4 13.5a.5.5 0 0 1 1 0v1A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-1a.5.5 0 0 1 1 0v1a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-1Z"})})}function X(){let[r,e]=react.useState(false);return react.useEffect(()=>{if(typeof window>"u")return;let i=()=>e(window.innerWidth<768);return i(),window.addEventListener("resize",i),()=>window.removeEventListener("resize",i)},[]),r}function ee({onClose:r,children:e,title:i}){let s=X(),o=react.useRef(r);return o.current=r,react.useEffect(()=>{let c=t=>{t.key==="Escape"&&o.current();};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[]),s?jsxRuntime.jsxs("div",{className:"fixed inset-0 z-50 flex items-end justify-center",onClick:r,children:[jsxRuntime.jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxRuntime.jsxs("div",{className:"relative z-10 w-full max-h-[90vh] overflow-y-auto rounded-t-2xl bg-[#1a1a1a] p-5 pb-8 animate-in slide-in-from-bottom duration-200",onClick:c=>c.stopPropagation(),children:[jsxRuntime.jsx("div",{className:"mx-auto mb-4 h-1 w-10 rounded-full bg-zinc-600"}),jsxRuntime.jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsxRuntime.jsx("h2",{className:"text-lg font-semibold text-foreground",children:i}),jsxRuntime.jsx("button",{onClick:r,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsxRuntime.jsx(L,{size:20})})]}),e]})]}):jsxRuntime.jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center",onClick:r,children:[jsxRuntime.jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxRuntime.jsxs("div",{className:"relative z-10 w-full max-w-lg overflow-y-auto rounded-2xl bg-[#1a1a1a] p-6 shadow-2xl animate-in fade-in zoom-in-95 duration-150",onClick:c=>c.stopPropagation(),children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsxRuntime.jsx("h2",{className:"text-lg font-semibold text-foreground",children:i}),jsxRuntime.jsx("button",{onClick:r,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsxRuntime.jsx(L,{size:20})})]}),e]})]})}function Ce({onClose:r,onCreated:e,config:i}){let[s,o]=react.useState(""),[c,t]=react.useState(""),[a,l]=react.useState(""),[d,u]=react.useState(false),[p,g]=react.useState(null);return jsxRuntime.jsx(ee,{title:"Write skill instructions",onClose:r,children:jsxRuntime.jsxs("div",{className:"space-y-4",children:[jsxRuntime.jsxs("div",{className:"space-y-1.5",children:[jsxRuntime.jsx("label",{htmlFor:"skill-name",className:"text-sm text-muted-foreground",children:"Skill name"}),jsxRuntime.jsx("input",{id:"skill-name",value:s,onChange:w=>o(w.target.value),placeholder:"weekly-status-report",className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxRuntime.jsxs("div",{className:"space-y-1.5",children:[jsxRuntime.jsx("label",{htmlFor:"skill-desc",className:"text-sm text-muted-foreground",children:"Description"}),jsxRuntime.jsx("textarea",{id:"skill-desc",value:c,onChange:w=>t(w.target.value),placeholder:"Generate weekly status reports from recent work.",rows:3,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxRuntime.jsxs("div",{className:"space-y-1.5",children:[jsxRuntime.jsx("label",{htmlFor:"skill-instructions",className:"text-sm text-muted-foreground",children:"Instructions"}),jsxRuntime.jsx("textarea",{id:"skill-instructions",value:a,onChange:w=>l(w.target.value),placeholder:"Summarize my recent work in three sections: wins, blockers, and next steps.",rows:8,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),p&&jsxRuntime.jsx("p",{className:"text-sm text-red-500",children:p}),jsxRuntime.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[jsxRuntime.jsx("button",{onClick:r,className:"rounded-lg border border-zinc-700 px-4 py-2 text-sm text-foreground hover:bg-zinc-800",children:"Cancel"}),jsxRuntime.jsx("button",{onClick:async()=>{if(s.trim()){u(true),g(null);try{let w=i.apiBaseUrl||"",S=`# ${s.trim()}
3
+ `),lang:a||void 0}),s++;continue}if(/^\s*[-*+]\s/.test(o)){let a=[];for(;s<e.length&&/^\s*[-*+]\s/.test(e[s]);)a.push(e[s].replace(/^\s*[-*+]\s+/,"")),s++;i.push({type:"ul",items:a});continue}if(/^\s*\d+[.)]\s/.test(o)){let a=[];for(;s<e.length&&/^\s*\d+[.)]\s/.test(e[s]);)a.push(e[s].replace(/^\s*\d+[.)]\s+/,"")),s++;i.push({type:"ol",items:a});continue}let t=[];for(;s<e.length&&e[s].trim()!==""&&!e[s].match(/^#{1,6}\s/)&&!e[s].trim().startsWith("```")&&!/^\s*[-*+]\s/.test(e[s])&&!/^\s*\d+[.)]\s/.test(e[s]);)t.push(e[s]),s++;t.length>0&&i.push({type:"paragraph",content:t.join(" ")});}return i}var ve={1:"text-2xl font-bold mt-6 mb-3",2:"text-xl font-bold mt-5 mb-2",3:"text-lg font-semibold mt-4 mb-2",4:"text-base font-semibold mt-3 mb-1",5:"text-sm font-semibold mt-2 mb-1",6:"text-sm font-medium mt-2 mb-1"};function be(r,e){switch(r.type){case "hr":return jsxRuntime.jsx("hr",{className:"my-4 border-border"},`b${e}`);case "heading":{let i=Math.min(Math.max(r.level||1,1),6),s=`h${i}`;return jsxRuntime.jsx(s,{className:k("text-foreground",ve[i]),children:M(r.content||"")},`b${e}`)}case "paragraph":return jsxRuntime.jsx("p",{className:"mb-3 leading-relaxed text-foreground",children:M(r.content||"")},`b${e}`);case "code":return jsxRuntime.jsx("pre",{className:"mb-3 overflow-x-auto rounded-lg bg-muted p-4 text-sm font-mono leading-relaxed text-foreground",children:jsxRuntime.jsx("code",{children:r.content})},`b${e}`);case "ul":return jsxRuntime.jsx("ul",{className:"mb-3 ml-5 list-disc space-y-1 text-foreground",children:r.items?.map((i,s)=>jsxRuntime.jsx("li",{className:"leading-relaxed",children:M(i)},`li${e}-${s}`))},`b${e}`);case "ol":return jsxRuntime.jsx("ol",{className:"mb-3 ml-5 list-decimal space-y-1 text-foreground",children:r.items?.map((i,s)=>jsxRuntime.jsx("li",{className:"leading-relaxed",children:M(i)},`li${e}-${s}`))},`b${e}`);default:return null}}function L({content:r,className:e}){let i=xe(r);return jsxRuntime.jsx("div",{className:k("text-sm",e),children:i.map((s,o)=>be(s,o))})}function Q({open:r,className:e}){return jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:k("shrink-0 transition-transform duration-150",r?"rotate-0":"-rotate-90",e),children:jsxRuntime.jsx("path",{d:"M16.134 6.16a.5.5 0 1 1 .732.68l-6.5 7-.077.068a.5.5 0 0 1-.655-.068l-6.5-7-.062-.08a.5.5 0 0 1 .718-.667l.076.067L10 12.767z"})})}function q({size:r=20,className:e}){return jsxRuntime.jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsxRuntime.jsx("path",{d:"M8.5 2a6.5 6.5 0 0 1 4.935 10.728l4.419 4.419.064.078a.5.5 0 0 1-.693.693l-.079-.064-4.419-4.42A6.5 6.5 0 1 1 8.5 2m0 1a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11"})})}function B({size:r=20,className:e}){return jsxRuntime.jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsxRuntime.jsx("path",{d:"M15.147 4.146a.5.5 0 0 1 .707.707L10.707 10l5.147 5.147a.5.5 0 0 1-.63.771l-.078-.064L10 10.707l-5.146 5.147a.5.5 0 0 1-.708-.707L9.293 10 4.146 4.853a.5.5 0 0 1 .708-.707L10 9.293z"})})}function Y({size:r=20,className:e}){return jsxRuntime.jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsxRuntime.jsx("path",{d:"M10 3a.5.5 0 0 1 .5.5v6h6l.1.01a.5.5 0 0 1 0 .98l-.1.01h-6v6a.5.5 0 0 1-1 0v-6h-6a.5.5 0 0 1 0-1h6v-6A.5.5 0 0 1 10 3"})})}function ke(){return jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M6.5 3A2.5 2.5 0 0 0 4 5.5v9A2.5 2.5 0 0 0 6.5 17h7a2.5 2.5 0 0 0 2.5-2.5v-7A2.5 2.5 0 0 0 13.5 5H11V3.5a.5.5 0 0 0-1 0V5H6.5ZM5 5.5A1.5 1.5 0 0 1 6.5 4H9v1H6.5A1.5 1.5 0 0 0 5 6.5v8A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-7A1.5 1.5 0 0 0 13.5 6H11V4h2.5A2.5 2.5 0 0 1 16 6.5v8a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-9Z"})})}function Ne(){return jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M5.5 3A2.5 2.5 0 0 0 3 5.5v9A2.5 2.5 0 0 0 5.5 17h9a2.5 2.5 0 0 0 2.5-2.5v-9A2.5 2.5 0 0 0 14.5 3h-9ZM4 5.5A1.5 1.5 0 0 1 5.5 4h9A1.5 1.5 0 0 1 16 5.5v9a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 4 14.5v-9ZM7 7.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5Z"})})}function Re(){return jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M10 2a.5.5 0 0 1 .354.146l3 3a.5.5 0 0 1-.708.708L10.5 3.707V12.5a.5.5 0 0 1-1 0V3.707L7.354 5.854a.5.5 0 1 1-.708-.708l3-3A.5.5 0 0 1 10 2ZM4 13.5a.5.5 0 0 1 1 0v1A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-1a.5.5 0 0 1 1 0v1a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-1Z"})})}function X(){let[r,e]=react.useState(false);return react.useEffect(()=>{if(typeof window>"u")return;let i=()=>e(window.innerWidth<768);return i(),window.addEventListener("resize",i),()=>window.removeEventListener("resize",i)},[]),r}function ee({onClose:r,children:e,title:i}){let s=X(),o=react.useRef(r);return o.current=r,react.useEffect(()=>{let c=t=>{t.key==="Escape"&&o.current();};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[]),s?jsxRuntime.jsxs("div",{className:"fixed inset-0 z-50 flex items-end justify-center",onClick:r,children:[jsxRuntime.jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxRuntime.jsxs("div",{className:"relative z-10 w-full max-h-[90vh] overflow-y-auto rounded-t-2xl bg-[#1a1a1a] p-5 pb-8 animate-in slide-in-from-bottom duration-200",onClick:c=>c.stopPropagation(),children:[jsxRuntime.jsx("div",{className:"mx-auto mb-4 h-1 w-10 rounded-full bg-zinc-600"}),jsxRuntime.jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsxRuntime.jsx("h2",{className:"text-lg font-semibold text-foreground",children:i}),jsxRuntime.jsx("button",{onClick:r,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsxRuntime.jsx(B,{size:20})})]}),e]})]}):jsxRuntime.jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center",onClick:r,children:[jsxRuntime.jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxRuntime.jsxs("div",{className:"relative z-10 w-full max-w-lg overflow-y-auto rounded-2xl bg-[#1a1a1a] p-6 shadow-2xl animate-in fade-in zoom-in-95 duration-150",onClick:c=>c.stopPropagation(),children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsxRuntime.jsx("h2",{className:"text-lg font-semibold text-foreground",children:i}),jsxRuntime.jsx("button",{onClick:r,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsxRuntime.jsx(B,{size:20})})]}),e]})]})}function Ce({onClose:r,onCreated:e,config:i}){let[s,o]=react.useState(""),[c,t]=react.useState(""),[a,l]=react.useState(""),[d,u]=react.useState(false),[p,g]=react.useState(null);return jsxRuntime.jsx(ee,{title:"Write skill instructions",onClose:r,children:jsxRuntime.jsxs("div",{className:"space-y-4",children:[jsxRuntime.jsxs("div",{className:"space-y-1.5",children:[jsxRuntime.jsx("label",{htmlFor:"skill-name",className:"text-sm text-muted-foreground",children:"Skill name"}),jsxRuntime.jsx("input",{id:"skill-name",value:s,onChange:w=>o(w.target.value),placeholder:"weekly-status-report",className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxRuntime.jsxs("div",{className:"space-y-1.5",children:[jsxRuntime.jsx("label",{htmlFor:"skill-desc",className:"text-sm text-muted-foreground",children:"Description"}),jsxRuntime.jsx("textarea",{id:"skill-desc",value:c,onChange:w=>t(w.target.value),placeholder:"Generate weekly status reports from recent work.",rows:3,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxRuntime.jsxs("div",{className:"space-y-1.5",children:[jsxRuntime.jsx("label",{htmlFor:"skill-instructions",className:"text-sm text-muted-foreground",children:"Instructions"}),jsxRuntime.jsx("textarea",{id:"skill-instructions",value:a,onChange:w=>l(w.target.value),placeholder:"Summarize my recent work in three sections: wins, blockers, and next steps.",rows:8,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),p&&jsxRuntime.jsx("p",{className:"text-sm text-red-500",children:p}),jsxRuntime.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[jsxRuntime.jsx("button",{onClick:r,className:"rounded-lg border border-zinc-700 px-4 py-2 text-sm text-foreground hover:bg-zinc-800",children:"Cancel"}),jsxRuntime.jsx("button",{onClick:async()=>{if(s.trim()){u(true),g(null);try{let w=i.apiBaseUrl||"",S=`# ${s.trim()}
4
4
 
5
5
  ${c.trim()}
6
6
 
7
7
  ---
8
8
 
9
- ${a.trim()}`,N=await fetch(`${w}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:s.trim(),description:c.trim(),skill_md:S,content_type:"code"})});if(!N.ok){let C=`Failed to register skill (${N.status})`;try{let y=await N.json();y.error&&(C=y.error);}catch{}throw new Error(C)}e?.(),r();}catch(w){g(w instanceof Error?w.message:"Failed to create skill");}finally{u(false);}}},disabled:d||!s.trim(),className:"rounded-lg bg-zinc-600 px-4 py-2 text-sm font-medium text-white hover:bg-zinc-500 disabled:opacity-50",children:d?"Creating...":"Create"})]})]})})}function Se({onClose:r,onCreated:e,config:i}){let s=react.useRef(null),[o,c]=react.useState(false),[t,a]=react.useState(false),[l,d]=react.useState(null),u=async g=>{a(true),d(null);try{let f=await g.text(),w=i.apiBaseUrl||"",S=g.name.replace(/\.[^.]+$/,"").replace(/[^a-zA-Z0-9-_]/g,"-"),N=await fetch(`${w}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:S,skill_md:f,content_type:"code"})});if(!N.ok){let C=`Failed to register skill (${N.status})`;try{let y=await N.json();y.error&&(C=y.error);}catch{}throw new Error(C)}e?.(),r();}catch(f){d(f instanceof Error?f.message:"Upload failed");}finally{a(false);}};return jsxRuntime.jsx(ee,{title:"Upload skill",onClose:r,children:jsxRuntime.jsxs("div",{className:"space-y-4",children:[jsxRuntime.jsxs("div",{onDragOver:g=>{g.preventDefault(),c(true);},onDragLeave:()=>c(false),onDrop:g=>{g.preventDefault(),c(false);let f=g.dataTransfer.files[0];f&&u(f);},onClick:()=>s.current?.click(),className:k("flex cursor-pointer flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed p-10 transition-colors",o?"border-zinc-400 bg-zinc-800/50":"border-zinc-700 hover:border-zinc-500"),children:[jsxRuntime.jsx("div",{className:"rounded-lg border border-zinc-600 p-2",children:jsxRuntime.jsx(Y,{size:20,className:"text-muted-foreground"})}),jsxRuntime.jsx("p",{className:"text-sm text-muted-foreground",children:t?"Uploading...":"Drag and drop or click to upload"})]}),jsxRuntime.jsx("input",{ref:s,type:"file",accept:".md,.zip,.skill,.txt,.yml,.yaml",className:"hidden","aria-label":"Upload skill file",onChange:g=>{let f=g.target.files?.[0];f&&u(f);}}),l&&jsxRuntime.jsx("p",{className:"text-sm text-red-500",children:l}),jsxRuntime.jsxs("div",{className:"space-y-2 text-xs text-muted-foreground",children:[jsxRuntime.jsx("p",{className:"font-medium text-foreground/70",children:"File requirements"}),jsxRuntime.jsxs("ul",{className:"list-disc pl-5 space-y-1",children:[jsxRuntime.jsx("li",{children:".md file must contain skill name and description formatted in YAML"}),jsxRuntime.jsx("li",{children:".zip or .skill file must include a SKILL.md file"})]})]})]})})}function Te({onClose:r,onSelect:e}){let i=X(),s=react.useRef(null),o=react.useRef(r);o.current=r,react.useEffect(()=>{if(i)return;let t=a=>{s.current&&a.target instanceof Node&&!s.current.contains(a.target)&&o.current();};return document.addEventListener("mousedown",t),()=>document.removeEventListener("mousedown",t)},[i]);let c=[{id:"create-with-geoff",icon:jsxRuntime.jsx(ke,{}),label:"Create with Geoff"},{id:"write",icon:jsxRuntime.jsx(Ne,{}),label:"Write skill instructions"},{id:"upload",icon:jsxRuntime.jsx(Re,{}),label:"Upload a skill"}];return i?jsxRuntime.jsxs("div",{className:"fixed inset-0 z-50 flex items-end",onClick:r,children:[jsxRuntime.jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxRuntime.jsxs("div",{className:"relative z-10 w-full rounded-t-2xl bg-[#1a1a1a] p-4 pb-8 animate-in slide-in-from-bottom duration-200",onClick:t=>t.stopPropagation(),children:[jsxRuntime.jsx("div",{className:"mx-auto mb-3 h-1 w-10 rounded-full bg-zinc-600"}),c.map(t=>jsxRuntime.jsxs("button",{onClick:()=>{e(t.id),r();},className:"flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-800",children:[t.icon,t.label]},t.id))]})]}):jsxRuntime.jsx("div",{ref:s,className:"absolute right-2 top-11 z-50 w-56 overflow-hidden rounded-xl border border-zinc-700 bg-[#2a2a2a] shadow-xl animate-in fade-in zoom-in-95 duration-100",children:c.map(t=>jsxRuntime.jsxs("button",{onClick:()=>{e(t.id),r();},className:"flex w-full items-center gap-3 px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-700/50",children:[t.icon,t.label]},t.id))})}function Ee({entry:r,selected:e,onSelect:i,depth:s=0}){return jsxRuntime.jsxs("button",{onClick:()=>i(r),className:k("flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),style:{paddingLeft:`${8+s*16}px`},children:[jsxRuntime.jsx("span",{className:"truncate flex-1",children:r.path.split("/").pop()}),r.isDir&&jsxRuntime.jsx(Q,{className:"ml-auto text-muted-foreground"})]})}function Me({repo:r,selected:e,expanded:i,onSelect:s,onToggle:o,children:c}){return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("button",{onClick:()=>{s(),o();},className:k("flex w-full items-center gap-2 rounded-md px-2 py-2 text-left text-sm font-medium transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),children:[jsxRuntime.jsx(Q,{open:i}),jsxRuntime.jsx(lucideReact.FileText,{className:"h-4 w-4 shrink-0"}),jsxRuntime.jsx("span",{className:"truncate",children:r.name})]}),i&&c]})}function ze({entry:r,content:e,loading:i,repoName:s}){let[o,c]=react.useState(false),t=react.useRef(null);react.useEffect(()=>()=>{t.current&&clearTimeout(t.current);},[]);let[a,l]=react.useState(false),d=async()=>{if(e)try{await navigator.clipboard.writeText(e),c(!0),l(!1),t.current&&clearTimeout(t.current),t.current=setTimeout(()=>c(!1),2e3);}catch{l(true),t.current&&clearTimeout(t.current),t.current=setTimeout(()=>l(false),2e3);}};if(!r)return jsxRuntime.jsx("div",{className:"flex h-full items-center justify-center text-sm text-muted-foreground",children:"Select a file to view its content"});if(i)return jsxRuntime.jsx("div",{className:"flex h-full items-center justify-center",children:jsxRuntime.jsx(lucideReact.Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})});let u=r.path.split("/").pop()||r.path,p=/\.(md|mdx)$/i.test(u);return jsxRuntime.jsxs("div",{className:"flex h-full flex-col px-3",children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between px-4 py-3",children:[jsxRuntime.jsx("h3",{className:"text-sm sm:text-lg font-semibold text-foreground",children:u}),jsxRuntime.jsx("button",{onClick:d,"aria-label":"Copy file content",className:k("rounded p-1 transition-colors",o?"text-green-500":a?"text-red-500":"text-muted-foreground hover:text-foreground"),children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M12.5 3A1.5 1.5 0 0 1 14 4.5V6h1.5A1.5 1.5 0 0 1 17 7.5v8a1.5 1.5 0 0 1-1.5 1.5h-8A1.5 1.5 0 0 1 6 15.5V14H4.5A1.5 1.5 0 0 1 3 12.5v-8A1.5 1.5 0 0 1 4.5 3zm1.5 9.5a1.5 1.5 0 0 1-1.5 1.5H7v1.5a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5H14zM4.5 4a.5.5 0 0 0-.5.5v8a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5z"})})})]}),jsxRuntime.jsx("div",{className:"flex-1 overflow-auto p-4",children:p?jsxRuntime.jsx(B,{content:e||""}):jsxRuntime.jsx("pre",{className:"whitespace-pre-wrap text-sm text-foreground font-mono leading-relaxed",children:e||""})})]})}function $e({config:r,category:e,className:i,style:s}){let{repos:o,loading:c,error:t,refresh:a}=Z(r),[l,d]=react.useState(null),[u,p]=react.useState(null),[g,f]=react.useState(null),[w,S]=react.useState(null),[N,C]=react.useState(false),[y,U]=react.useState(""),[te,D]=react.useState(false),[O,j]=react.useState(false),[F,$]=react.useState(null),re=o.find(h=>h.repo_id===l),{entries:ne,getFileContent:H}=W(r,u),V=o.filter(h=>!y||h.name.toLowerCase().includes(y.toLowerCase())),se=react.useCallback(async h=>{if(!h.isDir){f(h),C(true);try{let R=await H(h.cid);S(R);}catch(R){let ae=R instanceof Error?R.message:"Unknown error";S(`Failed to load file: ${ae}`);}finally{C(false);}}},[H]);react.useEffect(()=>{o.length>0&&!l&&(d(o[0].repo_id),p(o[0].repo_id));},[o,l]);let oe=h=>{h==="create-with-geoff"?window.open(`https://www.geoff.ai/?p=${encodeURIComponent("Let's create a skill together using your skill-creator skill. First ask me what the skill should do.")}`,"_blank","noopener,noreferrer"):$(h);};return jsxRuntime.jsxs("div",{className:k("flex flex-1 h-full min-h-0",i),style:s,children:[jsxRuntime.jsxs("div",{className:"relative flex w-96 shrink-0 flex-col border-r",children:[jsxRuntime.jsx("div",{className:"flex h-12 items-center gap-2 px-3",children:te?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{className:"flex flex-1 items-center gap-2 rounded-md border bg-muted/50 px-2 py-1",children:[jsxRuntime.jsx(q,{size:16,className:"shrink-0 text-muted-foreground"}),jsxRuntime.jsx("input",{type:"text",value:y,onChange:h=>U(h.target.value),placeholder:"Search",autoFocus:true,"aria-label":"Search items",className:"flex-1 bg-transparent text-xs text-foreground placeholder:text-muted-foreground focus:outline-none"})]}),jsxRuntime.jsx("button",{onClick:()=>{D(false),U("");},className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsxRuntime.jsx(L,{size:16})})]}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("h3",{className:"flex-1 text-sm sm:text-lg font-semibold text-foreground capitalize",children:e||"Items"}),jsxRuntime.jsx("button",{onClick:()=>D(true),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Search",children:jsxRuntime.jsx(q,{size:20})}),jsxRuntime.jsx("button",{onClick:()=>j(!O),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Add new",children:jsxRuntime.jsx(Y,{size:20})})]})}),O&&jsxRuntime.jsx(Te,{onClose:()=>j(false),onSelect:oe}),jsxRuntime.jsx("div",{className:"flex-1 overflow-y-auto p-2",children:c?jsxRuntime.jsx("div",{className:"flex items-center justify-center py-8",children:jsxRuntime.jsx(lucideReact.Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})}):t?jsxRuntime.jsx("p",{className:"px-2 py-4 text-xs text-red-500",children:t}):V.length===0?jsxRuntime.jsx("p",{className:"px-2 py-4 text-xs text-muted-foreground",children:y?"No matching items":"No items yet"}):jsxRuntime.jsx("div",{className:"space-y-0.5",children:V.map(h=>jsxRuntime.jsx(Me,{repo:h,selected:l===h.repo_id,expanded:u===h.repo_id,onSelect:()=>{d(h.repo_id),f(null),S(null);},onToggle:()=>p(u===h.repo_id?null:h.repo_id),children:jsxRuntime.jsx("div",{className:"ml-10 pl-1",children:ne.map(R=>jsxRuntime.jsx(Ee,{entry:R,selected:g?.path===R.path,onSelect:se,depth:R.path.split("/").length-1},R.path))})},h.repo_id))})})]}),jsxRuntime.jsx("div",{className:"flex-1 min-w-0",children:jsxRuntime.jsx(ze,{entry:g,content:w,loading:N,repoName:re?.name||""})}),F==="write"&&jsxRuntime.jsx(Ce,{config:r,onClose:()=>$(null),onCreated:a}),F==="upload"&&jsxRuntime.jsx(Se,{config:r,onClose:()=>$(null),onCreated:a})]})}
10
- exports.Markdown=B;exports.RackBrowser=$e;
9
+ ${a.trim()}`,N=await fetch(`${w}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:s.trim(),description:c.trim(),skill_md:S,content_type:"code"})});if(!N.ok){let C=`Failed to register skill (${N.status})`;try{let y=await N.json();y.error&&(C=y.error);}catch{}throw new Error(C)}e?.(),r();}catch(w){g(w instanceof Error?w.message:"Failed to create skill");}finally{u(false);}}},disabled:d||!s.trim(),className:"rounded-lg bg-zinc-600 px-4 py-2 text-sm font-medium text-white hover:bg-zinc-500 disabled:opacity-50",children:d?"Creating...":"Create"})]})]})})}function Se({onClose:r,onCreated:e,config:i}){let s=react.useRef(null),[o,c]=react.useState(false),[t,a]=react.useState(false),[l,d]=react.useState(null),u=async g=>{a(true),d(null);try{let f=await g.text(),w=i.apiBaseUrl||"",S=g.name.replace(/\.[^.]+$/,"").replace(/[^a-zA-Z0-9-_]/g,"-"),N=await fetch(`${w}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:S,skill_md:f,content_type:"code"})});if(!N.ok){let C=`Failed to register skill (${N.status})`;try{let y=await N.json();y.error&&(C=y.error);}catch{}throw new Error(C)}e?.(),r();}catch(f){d(f instanceof Error?f.message:"Upload failed");}finally{a(false);}};return jsxRuntime.jsx(ee,{title:"Upload skill",onClose:r,children:jsxRuntime.jsxs("div",{className:"space-y-4",children:[jsxRuntime.jsxs("div",{onDragOver:g=>{g.preventDefault(),c(true);},onDragLeave:()=>c(false),onDrop:g=>{g.preventDefault(),c(false);let f=g.dataTransfer.files[0];f&&u(f);},onClick:()=>s.current?.click(),className:k("flex cursor-pointer flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed p-10 transition-colors",o?"border-zinc-400 bg-zinc-800/50":"border-zinc-700 hover:border-zinc-500"),children:[jsxRuntime.jsx("div",{className:"rounded-lg border border-zinc-600 p-2",children:jsxRuntime.jsx(Y,{size:20,className:"text-muted-foreground"})}),jsxRuntime.jsx("p",{className:"text-sm text-muted-foreground",children:t?"Uploading...":"Drag and drop or click to upload"})]}),jsxRuntime.jsx("input",{ref:s,type:"file",accept:".md,.zip,.skill,.txt,.yml,.yaml",className:"hidden","aria-label":"Upload skill file",onChange:g=>{let f=g.target.files?.[0];f&&u(f);}}),l&&jsxRuntime.jsx("p",{className:"text-sm text-red-500",children:l}),jsxRuntime.jsxs("div",{className:"space-y-2 text-xs text-muted-foreground",children:[jsxRuntime.jsx("p",{className:"font-medium text-foreground/70",children:"File requirements"}),jsxRuntime.jsxs("ul",{className:"list-disc pl-5 space-y-1",children:[jsxRuntime.jsx("li",{children:".md file must contain skill name and description formatted in YAML"}),jsxRuntime.jsx("li",{children:".zip or .skill file must include a SKILL.md file"})]})]})]})})}function Te({onClose:r,onSelect:e}){let i=X(),s=react.useRef(null),o=react.useRef(r);o.current=r,react.useEffect(()=>{if(i)return;let t=a=>{s.current&&a.target instanceof Node&&!s.current.contains(a.target)&&o.current();};return document.addEventListener("mousedown",t),()=>document.removeEventListener("mousedown",t)},[i]);let c=[{id:"create-with-geoff",icon:jsxRuntime.jsx(ke,{}),label:"Create with Geoff"},{id:"write",icon:jsxRuntime.jsx(Ne,{}),label:"Write skill instructions"},{id:"upload",icon:jsxRuntime.jsx(Re,{}),label:"Upload a skill"}];return i?jsxRuntime.jsxs("div",{className:"fixed inset-0 z-50 flex items-end",onClick:r,children:[jsxRuntime.jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxRuntime.jsxs("div",{className:"relative z-10 w-full rounded-t-2xl bg-[#1a1a1a] p-4 pb-8 animate-in slide-in-from-bottom duration-200",onClick:t=>t.stopPropagation(),children:[jsxRuntime.jsx("div",{className:"mx-auto mb-3 h-1 w-10 rounded-full bg-zinc-600"}),c.map(t=>jsxRuntime.jsxs("button",{onClick:()=>{e(t.id),r();},className:"flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-800",children:[t.icon,t.label]},t.id))]})]}):jsxRuntime.jsx("div",{ref:s,className:"absolute right-2 top-11 z-50 w-56 overflow-hidden rounded-xl border border-zinc-700 bg-[#2a2a2a] shadow-xl animate-in fade-in zoom-in-95 duration-100",children:c.map(t=>jsxRuntime.jsxs("button",{onClick:()=>{e(t.id),r();},className:"flex w-full items-center gap-3 px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-700/50",children:[t.icon,t.label]},t.id))})}function Ee({entry:r,selected:e,onSelect:i,depth:s=0}){return jsxRuntime.jsxs("button",{onClick:()=>i(r),className:k("flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),style:{paddingLeft:`${8+s*16}px`},children:[jsxRuntime.jsx("span",{className:"truncate flex-1",children:r.path.split("/").pop()}),r.isDir&&jsxRuntime.jsx(Q,{className:"ml-auto text-muted-foreground"})]})}function Pe({repo:r,selected:e,expanded:i,onSelect:s,onToggle:o,children:c}){return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("button",{onClick:()=>{s(),o();},className:k("flex w-full items-center gap-2 rounded-md px-2 py-2 text-left text-sm font-medium transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),children:[jsxRuntime.jsx(Q,{open:i}),jsxRuntime.jsx(lucideReact.FileText,{className:"h-4 w-4 shrink-0"}),jsxRuntime.jsx("span",{className:"truncate",children:r.name})]}),i&&c]})}function Me({entry:r,content:e,loading:i,repoName:s}){let[o,c]=react.useState(false),t=react.useRef(null);react.useEffect(()=>()=>{t.current&&clearTimeout(t.current);},[]);let[a,l]=react.useState(false),d=async()=>{if(e)try{await navigator.clipboard.writeText(e),c(!0),l(!1),t.current&&clearTimeout(t.current),t.current=setTimeout(()=>c(!1),2e3);}catch{l(true),t.current&&clearTimeout(t.current),t.current=setTimeout(()=>l(false),2e3);}};if(!r)return jsxRuntime.jsx("div",{className:"flex h-full items-center justify-center text-sm text-muted-foreground",children:"Select a file to view its content"});if(i)return jsxRuntime.jsx("div",{className:"flex h-full items-center justify-center",children:jsxRuntime.jsx(lucideReact.Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})});let u=r.path.split("/").pop()||r.path,p=/\.(md|mdx)$/i.test(u);return jsxRuntime.jsxs("div",{className:"flex h-full flex-col px-3",children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between px-4 py-3",children:[jsxRuntime.jsx("h3",{className:"text-sm sm:text-lg font-semibold text-foreground",children:u}),jsxRuntime.jsx("button",{onClick:d,"aria-label":"Copy file content",className:k("rounded p-1 transition-colors",o?"text-green-500":a?"text-red-500":"text-muted-foreground hover:text-foreground"),children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M12.5 3A1.5 1.5 0 0 1 14 4.5V6h1.5A1.5 1.5 0 0 1 17 7.5v8a1.5 1.5 0 0 1-1.5 1.5h-8A1.5 1.5 0 0 1 6 15.5V14H4.5A1.5 1.5 0 0 1 3 12.5v-8A1.5 1.5 0 0 1 4.5 3zm1.5 9.5a1.5 1.5 0 0 1-1.5 1.5H7v1.5a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5H14zM4.5 4a.5.5 0 0 0-.5.5v8a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5z"})})})]}),jsxRuntime.jsx("div",{className:"flex-1 overflow-auto p-4",children:p?jsxRuntime.jsx(L,{content:e||""}):jsxRuntime.jsx("pre",{className:"whitespace-pre-wrap text-sm text-foreground font-mono leading-relaxed",children:e||""})})]})}function ze({config:r,category:e,className:i,style:s}){let{repos:o,loading:c,error:t,refresh:a}=Z(r),[l,d]=react.useState(null),[u,p]=react.useState(null),[g,f]=react.useState(null),[w,S]=react.useState(null),[N,C]=react.useState(false),[y,U]=react.useState(""),[te,D]=react.useState(false),[O,j]=react.useState(false),[F,z]=react.useState(null),re=o.find(h=>h.repo_id===l),{entries:ne,getFileContent:H}=W(r,u),V=o.filter(h=>!y||h.name.toLowerCase().includes(y.toLowerCase())),se=react.useCallback(async h=>{if(!h.isDir){f(h),C(true);try{let R=await H(h.cid);S(R);}catch(R){let ae=R instanceof Error?R.message:"Unknown error";S(`Failed to load file: ${ae}`);}finally{C(false);}}},[H]);react.useEffect(()=>{o.length>0&&!l&&(d(o[0].repo_id),p(o[0].repo_id));},[o,l]);let oe=h=>{h==="create-with-geoff"?window.open(`https://www.geoff.ai/?p=${encodeURIComponent("Let's create a skill together using your skill-creator skill. First ask me what the skill should do.")}`,"_blank","noopener,noreferrer"):z(h);};return jsxRuntime.jsxs("div",{className:k("flex flex-1 h-full min-h-0",i),style:s,children:[jsxRuntime.jsxs("div",{className:"relative flex w-96 shrink-0 flex-col border-r",children:[jsxRuntime.jsx("div",{className:"flex h-12 items-center gap-2 px-3",children:te?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{className:"flex flex-1 items-center gap-2 rounded-md border bg-muted/50 px-2 py-1",children:[jsxRuntime.jsx(q,{size:16,className:"shrink-0 text-muted-foreground"}),jsxRuntime.jsx("input",{type:"text",value:y,onChange:h=>U(h.target.value),placeholder:"Search",autoFocus:true,"aria-label":"Search items",className:"flex-1 bg-transparent text-xs text-foreground placeholder:text-muted-foreground focus:outline-none"})]}),jsxRuntime.jsx("button",{onClick:()=>{D(false),U("");},className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsxRuntime.jsx(B,{size:16})})]}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("h3",{className:"flex-1 text-sm sm:text-lg font-semibold text-foreground capitalize",children:e||"Items"}),jsxRuntime.jsx("button",{onClick:()=>D(true),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Search",children:jsxRuntime.jsx(q,{size:20})}),jsxRuntime.jsx("button",{onClick:()=>j(!O),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Add new",children:jsxRuntime.jsx(Y,{size:20})})]})}),O&&jsxRuntime.jsx(Te,{onClose:()=>j(false),onSelect:oe}),jsxRuntime.jsx("div",{className:"flex-1 overflow-y-auto p-2",children:c?jsxRuntime.jsx("div",{className:"flex items-center justify-center py-8",children:jsxRuntime.jsx(lucideReact.Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})}):t?jsxRuntime.jsx("p",{className:"px-2 py-4 text-xs text-red-500",children:t}):V.length===0?jsxRuntime.jsx("p",{className:"px-2 py-4 text-xs text-muted-foreground",children:y?"No matching items":"No items yet"}):jsxRuntime.jsx("div",{className:"space-y-0.5",children:V.map(h=>jsxRuntime.jsx(Pe,{repo:h,selected:l===h.repo_id,expanded:u===h.repo_id,onSelect:()=>{d(h.repo_id),f(null),S(null);},onToggle:()=>p(u===h.repo_id?null:h.repo_id),children:jsxRuntime.jsx("div",{className:"ml-10 pl-1",children:ne.map(R=>jsxRuntime.jsx(Ee,{entry:R,selected:g?.path===R.path,onSelect:se,depth:R.path.split("/").length-1},R.path))})},h.repo_id))})})]}),jsxRuntime.jsx("div",{className:"flex-1 min-w-0",children:jsxRuntime.jsx(Me,{entry:g,content:w,loading:N,repoName:re?.name||""})}),F==="write"&&jsxRuntime.jsx(Ce,{config:r,onClose:()=>z(null),onCreated:a}),F==="upload"&&jsxRuntime.jsx(Se,{config:r,onClose:()=>z(null),onCreated:a})]})}
10
+ exports.Markdown=L;exports.RackBrowser=ze;
@@ -1,10 +1,10 @@
1
- import {useState,useCallback,useEffect,useRef,useMemo}from'react';import {Loader2,FileText}from'lucide-react';import {clsx}from'clsx';import {twMerge}from'tailwind-merge';import {jsx,jsxs,Fragment}from'react/jsx-runtime';function k(...r){return twMerge(clsx(r))}async function v(r,e,i,s){let o={"Content-Type":"application/json",...i?.headers};s&&(o.Authorization=`Bearer ${s}`);let c=await fetch(`${r}${e}`,{...i,headers:o});if(!c.ok){let t=`HTTP ${c.status}`;try{let a=await c.json();a.error&&(t=a.error);}catch{}throw new Error(t)}return c.json()}function P(r){let e=r.indexOf(":");return {mode:r.slice(0,e),cid:r.slice(e+1)}}function M(r){let e=r.apiBaseUrl,i=r.authorMid,s=r.ownerMid,o=r.apiKey,c=r.stacknetUrl||r.apiBaseUrl;return useMemo(()=>({async listRepos(t){let a=t||s?`?owner=${encodeURIComponent(t||s)}`:"";return (await v(e,`/api/rack/repos${a}`,void 0,o)).repos||[]},async initRepo(t){return v(e,"/api/rack/init",{method:"POST",body:JSON.stringify({...t,owner_mid:s})},o)},async push(t,a){return v(e,`/api/rack/${t}/push`,{method:"POST",body:JSON.stringify({...a,author_mid:i})},o)},async getTree(t,a="main"){let l=await v(e,`/api/rack/${t}/tree/${a}`,void 0,o);return {tree:l.tree,commit_cid:l.commit_cid}},async getBlob(t,a){return (await v(e,`/api/rack/${t}/blob/${a}`,void 0,o)).content},async getLog(t,a,l){let d=new URLSearchParams;a&&d.set("ref",a),l&&d.set("max_count",String(l));let u=d.toString()?`?${d}`:"";return (await v(e,`/api/rack/${t}/log${u}`,void 0,o)).commits||[]},async getBranches(t){return (await v(e,`/api/rack/${t}/branches`,void 0,o)).branches||[]},async createBranch(t,a,l){return v(e,`/api/rack/${t}/branch`,{method:"POST",body:JSON.stringify({branch_name:a,from_ref:l})},o)},async merge(t,a,l){return v(e,`/api/rack/${t}/merge`,{method:"POST",body:JSON.stringify({source_branch:a,target_branch:l})},o)},async getDiff(t,a,l){return (await v(e,`/api/rack/${t}/diff/${a}/${l}`,void 0,o)).diff?.entries||[]},async starRepo(t){return v(e,`/api/rack/${t}/star`,{method:"POST"},o)},async unstarRepo(t){return v(e,`/api/rack/${t}/star`,{method:"DELETE"},o)},async getStarInfo(t){return v(e,`/api/rack/${t}/stars`,void 0,o)},async getSkillStats(t){let a={meta:null,tokenCount:null,usageCount:null};try{let{tree:l}=await this.getTree(t,"main");if(!l?.entries)return a;if(l.entries["META.json"]){let p=P(l.entries["META.json"]).cid,g=await this.getBlob(t,p);a.meta=JSON.parse(g);}let d=0,u=Object.values(l.entries).map(async p=>{try{let g=P(p).cid,f=await this.getBlob(t,g);d+=f.length;}catch{}});await Promise.all(u),d>0&&(a.tokenCount=Math.ceil(d/4)),a.meta?.skill_id&&(a.usageCount=await this.getSkillUsageCount(a.meta.skill_id));}catch{}return a},async getSkillUsageCount(t){try{let a=await fetch(`${c}/v1/skills/${encodeURIComponent(t)}`);if(a.ok){let d=await a.json();return d.usage_count??d.usageCount??null}let l=await fetch(`${c}/v1/skills?scope=public`);if(l.ok){let u=((await l.json()).skills||[]).find(p=>p.name===t||p.id===t);if(u)return u.usage_count??u.usageCount??0}return 0}catch{return null}},async getTensorStats(t){let a={meta:null,sizeMB:null};try{let{tree:l}=await this.getTree(t,"main");if(!l?.entries)return a;if(l.entries["TENSOR_META.json"]){let d=P(l.entries["TENSOR_META.json"]).cid,u=await this.getBlob(t,d);a.meta=JSON.parse(u),a.sizeMB=a.meta?.tensor_size_mb??null;}}catch{}return a},async getNetworkStats(){try{return (await v(e,"/api/rack/stats",void 0,o)).stats||null}catch{return null}},async getTrending(t=5,a=1){try{return (await v(e,`/api/rack/trending?limit=${t}&days=${a}`,void 0,o)).trending||[]}catch{return []}}}),[e,i,s,o,c])}function Z(r){let e=M(r),i=useRef(e);i.current=e;let[s,o]=useState([]),[c,t]=useState(true),[a,l]=useState(null),d=useRef(true),u=useRef(null),p=useCallback(async()=>{u.current?.abort();let g=new AbortController;u.current=g;try{d.current&&(t(!0),l(null));let f=await i.current.listRepos();d.current&&!g.signal.aborted&&o(f);}catch(f){d.current&&!g.signal.aborted&&l(f instanceof Error?f.message:"Failed to load repos");}finally{d.current&&!g.signal.aborted&&t(false);}},[]);return useEffect(()=>(d.current=true,p(),()=>{d.current=false,u.current?.abort();}),[p]),{repos:s,loading:c,error:a,refresh:p}}function ge(r){return Object.entries(r).map(([e,i])=>{let s=i.indexOf(":"),o=s>0?i.slice(0,s):"100644",c=s>0?i.slice(s+1):i;return {path:e,mode:o,cid:c,isDir:o==="040000"}}).sort((e,i)=>e.isDir!==i.isDir?e.isDir?-1:1:e.path.localeCompare(i.path))}function W(r,e,i="main"){let s=M(r),[o,c]=useState([]),[t,a]=useState(false),[l,d]=useState(null),u=useRef(true),p=useCallback(async()=>{if(e)try{u.current&&(a(!0),d(null));let{tree:f}=await s.getTree(e,i);u.current&&c(ge(f.entries));}catch(f){u.current&&d(f instanceof Error?f.message:"Failed to load tree");}finally{u.current&&a(false);}},[s,e,i]);useEffect(()=>(u.current=true,p(),()=>{u.current=false;}),[p]);let g=useCallback(async f=>{if(!e)throw new Error("No repo selected");return s.getBlob(e,f)},[s,e]);return {entries:o,loading:t,error:l,refresh:p,getFileContent:g}}var pe=/^(https?:\/\/|mailto:|\/[^/])/i;function he(r){let e=r.trim();return pe.test(e)?e:null}function z(r){let e=[],i=/(`[^`]+`)|(\*\*(.+?)\*\*)|(\*(.+?)\*)|(_(.+?)_)|(\[([^\]]+)\]\(([^)]+)\))/g,s=0,o,c=0;for(;(o=i.exec(r))!==null;){o.index>s&&e.push(r.slice(s,o.index));let t=`i${c++}`;if(o[1])e.push(jsx("code",{className:"rounded bg-muted px-1.5 py-0.5 text-[0.85em] font-mono text-pink-400",children:o[1].slice(1,-1)},t));else if(o[2])e.push(jsx("strong",{children:o[3]},t));else if(o[4])e.push(jsx("em",{children:o[5]},t));else if(o[6])e.push(jsx("em",{children:o[7]},t));else if(o[8]){let a=he(o[10]);a?e.push(jsx("a",{href:a,className:"text-blue-400 underline hover:text-blue-300",target:"_blank",rel:"noopener noreferrer",children:o[9]},t)):e.push(o[9]);}s=o.index+o[0].length;}return s<r.length&&e.push(r.slice(s)),e.length>0?e:[r]}function xe(r){let e=r.split(`
1
+ import {useState,useCallback,useEffect,useRef,useMemo}from'react';import {Loader2,FileText}from'lucide-react';import {clsx}from'clsx';import {twMerge}from'tailwind-merge';import {jsx,jsxs,Fragment}from'react/jsx-runtime';function k(...r){return twMerge(clsx(r))}async function v(r,e,i,s){let o={"Content-Type":"application/json",...i?.headers};s&&(o.Authorization=`Bearer ${s}`);let c=await fetch(`${r}${e}`,{...i,headers:o});if(!c.ok){let t=`HTTP ${c.status}`;try{let a=await c.json();a.error&&(t=a.error);}catch{}throw new Error(t)}return c.json()}function $(r){let e=r.indexOf(":");return {mode:r.slice(0,e),cid:r.slice(e+1)}}function P(r){let e=r.apiBaseUrl,i=r.authorMid,s=r.ownerMid,o=r.apiKey,c=r.stacknetUrl||r.apiBaseUrl;return useMemo(()=>({async listRepos(t,a){let l=new URLSearchParams;(t||s)&&l.set("owner",t||s),a?.limit&&l.set("limit",String(a.limit)),a?.cursor&&l.set("cursor",a.cursor);let d=l.toString()?`?${l}`:"",u=await v(e,`/api/rack/repos${d}`,void 0,o);return {items:u.repos||[],pagination:u.pagination||{total:(u.repos||[]).length,limit:50,has_more:false,next_cursor:null}}},async initRepo(t){return v(e,"/api/rack/init",{method:"POST",body:JSON.stringify({...t,owner_mid:s})},o)},async push(t,a){return v(e,`/api/rack/${t}/push`,{method:"POST",body:JSON.stringify({...a,author_mid:i})},o)},async getTree(t,a="main"){let l=await v(e,`/api/rack/${t}/tree/${a}`,void 0,o);return {tree:l.tree,commit_cid:l.commit_cid}},async getBlob(t,a){return (await v(e,`/api/rack/${t}/blob/${a}`,void 0,o)).content},async getLog(t,a,l){let d=new URLSearchParams;a&&d.set("ref",a),l&&d.set("max_count",String(l));let u=d.toString()?`?${d}`:"";return (await v(e,`/api/rack/${t}/log${u}`,void 0,o)).commits||[]},async getBranches(t){return (await v(e,`/api/rack/${t}/branches`,void 0,o)).branches||[]},async createBranch(t,a,l){return v(e,`/api/rack/${t}/branch`,{method:"POST",body:JSON.stringify({branch_name:a,from_ref:l})},o)},async merge(t,a,l){return v(e,`/api/rack/${t}/merge`,{method:"POST",body:JSON.stringify({source_branch:a,target_branch:l})},o)},async getDiff(t,a,l){return (await v(e,`/api/rack/${t}/diff/${a}/${l}`,void 0,o)).diff?.entries||[]},async starRepo(t){return v(e,`/api/rack/${t}/star`,{method:"POST"},o)},async unstarRepo(t){return v(e,`/api/rack/${t}/star`,{method:"DELETE"},o)},async getStarInfo(t){return v(e,`/api/rack/${t}/stars`,void 0,o)},async getSkillStats(t){let a={meta:null,tokenCount:null,usageCount:null};try{let{tree:l}=await this.getTree(t,"main");if(!l?.entries)return a;if(l.entries["META.json"]){let p=$(l.entries["META.json"]).cid,g=await this.getBlob(t,p);a.meta=JSON.parse(g);}let d=0,u=Object.values(l.entries).map(async p=>{try{let g=$(p).cid,f=await this.getBlob(t,g);d+=f.length;}catch{}});await Promise.all(u),d>0&&(a.tokenCount=Math.ceil(d/4)),a.meta?.skill_id&&(a.usageCount=await this.getSkillUsageCount(a.meta.skill_id));}catch{}return a},async getSkillUsageCount(t){try{let a=await fetch(`${c}/v1/skills/${encodeURIComponent(t)}`);if(a.ok){let d=await a.json();return d.usage_count??d.usageCount??null}let l=await fetch(`${c}/v1/skills?scope=public`);if(l.ok){let u=((await l.json()).skills||[]).find(p=>p.name===t||p.id===t);if(u)return u.usage_count??u.usageCount??0}return 0}catch{return null}},async getTensorStats(t){let a={meta:null,sizeMB:null};try{let{tree:l}=await this.getTree(t,"main");if(!l?.entries)return a;if(l.entries["TENSOR_META.json"]){let d=$(l.entries["TENSOR_META.json"]).cid,u=await this.getBlob(t,d);a.meta=JSON.parse(u),a.sizeMB=a.meta?.tensor_size_mb??null;}}catch{}return a},async getNetworkStats(){try{return (await v(e,"/api/rack/stats",void 0,o)).stats||null}catch{return null}},async getTrending(t=5,a=1,l){try{let d=new URLSearchParams({limit:String(t),days:String(a)});l&&d.set("cursor",l);let u=await v(e,`/api/rack/trending?${d}`,void 0,o);return {items:u.trending||[],pagination:u.pagination||{total:(u.trending||[]).length,limit:t,has_more:!1,next_cursor:null}}}catch{return {items:[],pagination:{total:0,limit:t,has_more:false,next_cursor:null}}}}}),[e,i,s,o,c])}function Z(r){let e=P(r),i=useRef(e);i.current=e;let[s,o]=useState([]),[c,t]=useState(true),[a,l]=useState(null),d=useRef(true),u=useRef(null),p=useCallback(async()=>{u.current?.abort();let g=new AbortController;u.current=g;try{d.current&&(t(!0),l(null));let f=await i.current.listRepos();d.current&&!g.signal.aborted&&o(f.items);}catch(f){d.current&&!g.signal.aborted&&l(f instanceof Error?f.message:"Failed to load repos");}finally{d.current&&!g.signal.aborted&&t(false);}},[]);return useEffect(()=>(d.current=true,p(),()=>{d.current=false,u.current?.abort();}),[p]),{repos:s,loading:c,error:a,refresh:p}}function ge(r){return Object.entries(r).map(([e,i])=>{let s=i.indexOf(":"),o=s>0?i.slice(0,s):"100644",c=s>0?i.slice(s+1):i;return {path:e,mode:o,cid:c,isDir:o==="040000"}}).sort((e,i)=>e.isDir!==i.isDir?e.isDir?-1:1:e.path.localeCompare(i.path))}function W(r,e,i="main"){let s=P(r),[o,c]=useState([]),[t,a]=useState(false),[l,d]=useState(null),u=useRef(true),p=useCallback(async()=>{if(e)try{u.current&&(a(!0),d(null));let{tree:f}=await s.getTree(e,i);u.current&&c(ge(f.entries));}catch(f){u.current&&d(f instanceof Error?f.message:"Failed to load tree");}finally{u.current&&a(false);}},[s,e,i]);useEffect(()=>(u.current=true,p(),()=>{u.current=false;}),[p]);let g=useCallback(async f=>{if(!e)throw new Error("No repo selected");return s.getBlob(e,f)},[s,e]);return {entries:o,loading:t,error:l,refresh:p,getFileContent:g}}var pe=/^(https?:\/\/|mailto:|\/[^/])/i;function he(r){let e=r.trim();return pe.test(e)?e:null}function M(r){let e=[],i=/(`[^`]+`)|(\*\*(.+?)\*\*)|(\*(.+?)\*)|(_(.+?)_)|(\[([^\]]+)\]\(([^)]+)\))/g,s=0,o,c=0;for(;(o=i.exec(r))!==null;){o.index>s&&e.push(r.slice(s,o.index));let t=`i${c++}`;if(o[1])e.push(jsx("code",{className:"rounded bg-muted px-1.5 py-0.5 text-[0.85em] font-mono text-pink-400",children:o[1].slice(1,-1)},t));else if(o[2])e.push(jsx("strong",{children:o[3]},t));else if(o[4])e.push(jsx("em",{children:o[5]},t));else if(o[6])e.push(jsx("em",{children:o[7]},t));else if(o[8]){let a=he(o[10]);a?e.push(jsx("a",{href:a,className:"text-blue-400 underline hover:text-blue-300",target:"_blank",rel:"noopener noreferrer",children:o[9]},t)):e.push(o[9]);}s=o.index+o[0].length;}return s<r.length&&e.push(r.slice(s)),e.length>0?e:[r]}function xe(r){let e=r.split(`
2
2
  `),i=[],s=0;for(;s<e.length;){let o=e[s];if(o.trim()===""){s++;continue}if(/^(-{3,}|\*{3,}|_{3,})$/.test(o.trim())){i.push({type:"hr"}),s++;continue}let c=o.match(/^(#{1,6})\s+(.+)/);if(c){i.push({type:"heading",level:c[1].length,content:c[2]}),s++;continue}if(o.trim().startsWith("```")){let a=o.trim().slice(3).trim(),l=[];for(s++;s<e.length&&!e[s].trim().startsWith("```");)l.push(e[s]),s++;i.push({type:"code",content:l.join(`
3
- `),lang:a||void 0}),s++;continue}if(/^\s*[-*+]\s/.test(o)){let a=[];for(;s<e.length&&/^\s*[-*+]\s/.test(e[s]);)a.push(e[s].replace(/^\s*[-*+]\s+/,"")),s++;i.push({type:"ul",items:a});continue}if(/^\s*\d+[.)]\s/.test(o)){let a=[];for(;s<e.length&&/^\s*\d+[.)]\s/.test(e[s]);)a.push(e[s].replace(/^\s*\d+[.)]\s+/,"")),s++;i.push({type:"ol",items:a});continue}let t=[];for(;s<e.length&&e[s].trim()!==""&&!e[s].match(/^#{1,6}\s/)&&!e[s].trim().startsWith("```")&&!/^\s*[-*+]\s/.test(e[s])&&!/^\s*\d+[.)]\s/.test(e[s]);)t.push(e[s]),s++;t.length>0&&i.push({type:"paragraph",content:t.join(" ")});}return i}var ve={1:"text-2xl font-bold mt-6 mb-3",2:"text-xl font-bold mt-5 mb-2",3:"text-lg font-semibold mt-4 mb-2",4:"text-base font-semibold mt-3 mb-1",5:"text-sm font-semibold mt-2 mb-1",6:"text-sm font-medium mt-2 mb-1"};function be(r,e){switch(r.type){case "hr":return jsx("hr",{className:"my-4 border-border"},`b${e}`);case "heading":{let i=Math.min(Math.max(r.level||1,1),6),s=`h${i}`;return jsx(s,{className:k("text-foreground",ve[i]),children:z(r.content||"")},`b${e}`)}case "paragraph":return jsx("p",{className:"mb-3 leading-relaxed text-foreground",children:z(r.content||"")},`b${e}`);case "code":return jsx("pre",{className:"mb-3 overflow-x-auto rounded-lg bg-muted p-4 text-sm font-mono leading-relaxed text-foreground",children:jsx("code",{children:r.content})},`b${e}`);case "ul":return jsx("ul",{className:"mb-3 ml-5 list-disc space-y-1 text-foreground",children:r.items?.map((i,s)=>jsx("li",{className:"leading-relaxed",children:z(i)},`li${e}-${s}`))},`b${e}`);case "ol":return jsx("ol",{className:"mb-3 ml-5 list-decimal space-y-1 text-foreground",children:r.items?.map((i,s)=>jsx("li",{className:"leading-relaxed",children:z(i)},`li${e}-${s}`))},`b${e}`);default:return null}}function B({content:r,className:e}){let i=xe(r);return jsx("div",{className:k("text-sm",e),children:i.map((s,o)=>be(s,o))})}function Q({open:r,className:e}){return jsx("svg",{width:"16",height:"16",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:k("shrink-0 transition-transform duration-150",r?"rotate-0":"-rotate-90",e),children:jsx("path",{d:"M16.134 6.16a.5.5 0 1 1 .732.68l-6.5 7-.077.068a.5.5 0 0 1-.655-.068l-6.5-7-.062-.08a.5.5 0 0 1 .718-.667l.076.067L10 12.767z"})})}function q({size:r=20,className:e}){return jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsx("path",{d:"M8.5 2a6.5 6.5 0 0 1 4.935 10.728l4.419 4.419.064.078a.5.5 0 0 1-.693.693l-.079-.064-4.419-4.42A6.5 6.5 0 1 1 8.5 2m0 1a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11"})})}function L({size:r=20,className:e}){return jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsx("path",{d:"M15.147 4.146a.5.5 0 0 1 .707.707L10.707 10l5.147 5.147a.5.5 0 0 1-.63.771l-.078-.064L10 10.707l-5.146 5.147a.5.5 0 0 1-.708-.707L9.293 10 4.146 4.853a.5.5 0 0 1 .708-.707L10 9.293z"})})}function Y({size:r=20,className:e}){return jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsx("path",{d:"M10 3a.5.5 0 0 1 .5.5v6h6l.1.01a.5.5 0 0 1 0 .98l-.1.01h-6v6a.5.5 0 0 1-1 0v-6h-6a.5.5 0 0 1 0-1h6v-6A.5.5 0 0 1 10 3"})})}function ke(){return jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M6.5 3A2.5 2.5 0 0 0 4 5.5v9A2.5 2.5 0 0 0 6.5 17h7a2.5 2.5 0 0 0 2.5-2.5v-7A2.5 2.5 0 0 0 13.5 5H11V3.5a.5.5 0 0 0-1 0V5H6.5ZM5 5.5A1.5 1.5 0 0 1 6.5 4H9v1H6.5A1.5 1.5 0 0 0 5 6.5v8A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-7A1.5 1.5 0 0 0 13.5 6H11V4h2.5A2.5 2.5 0 0 1 16 6.5v8a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-9Z"})})}function Ne(){return jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M5.5 3A2.5 2.5 0 0 0 3 5.5v9A2.5 2.5 0 0 0 5.5 17h9a2.5 2.5 0 0 0 2.5-2.5v-9A2.5 2.5 0 0 0 14.5 3h-9ZM4 5.5A1.5 1.5 0 0 1 5.5 4h9A1.5 1.5 0 0 1 16 5.5v9a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 4 14.5v-9ZM7 7.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5Z"})})}function Re(){return jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M10 2a.5.5 0 0 1 .354.146l3 3a.5.5 0 0 1-.708.708L10.5 3.707V12.5a.5.5 0 0 1-1 0V3.707L7.354 5.854a.5.5 0 1 1-.708-.708l3-3A.5.5 0 0 1 10 2ZM4 13.5a.5.5 0 0 1 1 0v1A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-1a.5.5 0 0 1 1 0v1a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-1Z"})})}function X(){let[r,e]=useState(false);return useEffect(()=>{if(typeof window>"u")return;let i=()=>e(window.innerWidth<768);return i(),window.addEventListener("resize",i),()=>window.removeEventListener("resize",i)},[]),r}function ee({onClose:r,children:e,title:i}){let s=X(),o=useRef(r);return o.current=r,useEffect(()=>{let c=t=>{t.key==="Escape"&&o.current();};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[]),s?jsxs("div",{className:"fixed inset-0 z-50 flex items-end justify-center",onClick:r,children:[jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxs("div",{className:"relative z-10 w-full max-h-[90vh] overflow-y-auto rounded-t-2xl bg-[#1a1a1a] p-5 pb-8 animate-in slide-in-from-bottom duration-200",onClick:c=>c.stopPropagation(),children:[jsx("div",{className:"mx-auto mb-4 h-1 w-10 rounded-full bg-zinc-600"}),jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsx("h2",{className:"text-lg font-semibold text-foreground",children:i}),jsx("button",{onClick:r,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsx(L,{size:20})})]}),e]})]}):jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center",onClick:r,children:[jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxs("div",{className:"relative z-10 w-full max-w-lg overflow-y-auto rounded-2xl bg-[#1a1a1a] p-6 shadow-2xl animate-in fade-in zoom-in-95 duration-150",onClick:c=>c.stopPropagation(),children:[jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsx("h2",{className:"text-lg font-semibold text-foreground",children:i}),jsx("button",{onClick:r,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsx(L,{size:20})})]}),e]})]})}function Ce({onClose:r,onCreated:e,config:i}){let[s,o]=useState(""),[c,t]=useState(""),[a,l]=useState(""),[d,u]=useState(false),[p,g]=useState(null);return jsx(ee,{title:"Write skill instructions",onClose:r,children:jsxs("div",{className:"space-y-4",children:[jsxs("div",{className:"space-y-1.5",children:[jsx("label",{htmlFor:"skill-name",className:"text-sm text-muted-foreground",children:"Skill name"}),jsx("input",{id:"skill-name",value:s,onChange:w=>o(w.target.value),placeholder:"weekly-status-report",className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxs("div",{className:"space-y-1.5",children:[jsx("label",{htmlFor:"skill-desc",className:"text-sm text-muted-foreground",children:"Description"}),jsx("textarea",{id:"skill-desc",value:c,onChange:w=>t(w.target.value),placeholder:"Generate weekly status reports from recent work.",rows:3,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxs("div",{className:"space-y-1.5",children:[jsx("label",{htmlFor:"skill-instructions",className:"text-sm text-muted-foreground",children:"Instructions"}),jsx("textarea",{id:"skill-instructions",value:a,onChange:w=>l(w.target.value),placeholder:"Summarize my recent work in three sections: wins, blockers, and next steps.",rows:8,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),p&&jsx("p",{className:"text-sm text-red-500",children:p}),jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[jsx("button",{onClick:r,className:"rounded-lg border border-zinc-700 px-4 py-2 text-sm text-foreground hover:bg-zinc-800",children:"Cancel"}),jsx("button",{onClick:async()=>{if(s.trim()){u(true),g(null);try{let w=i.apiBaseUrl||"",S=`# ${s.trim()}
3
+ `),lang:a||void 0}),s++;continue}if(/^\s*[-*+]\s/.test(o)){let a=[];for(;s<e.length&&/^\s*[-*+]\s/.test(e[s]);)a.push(e[s].replace(/^\s*[-*+]\s+/,"")),s++;i.push({type:"ul",items:a});continue}if(/^\s*\d+[.)]\s/.test(o)){let a=[];for(;s<e.length&&/^\s*\d+[.)]\s/.test(e[s]);)a.push(e[s].replace(/^\s*\d+[.)]\s+/,"")),s++;i.push({type:"ol",items:a});continue}let t=[];for(;s<e.length&&e[s].trim()!==""&&!e[s].match(/^#{1,6}\s/)&&!e[s].trim().startsWith("```")&&!/^\s*[-*+]\s/.test(e[s])&&!/^\s*\d+[.)]\s/.test(e[s]);)t.push(e[s]),s++;t.length>0&&i.push({type:"paragraph",content:t.join(" ")});}return i}var ve={1:"text-2xl font-bold mt-6 mb-3",2:"text-xl font-bold mt-5 mb-2",3:"text-lg font-semibold mt-4 mb-2",4:"text-base font-semibold mt-3 mb-1",5:"text-sm font-semibold mt-2 mb-1",6:"text-sm font-medium mt-2 mb-1"};function be(r,e){switch(r.type){case "hr":return jsx("hr",{className:"my-4 border-border"},`b${e}`);case "heading":{let i=Math.min(Math.max(r.level||1,1),6),s=`h${i}`;return jsx(s,{className:k("text-foreground",ve[i]),children:M(r.content||"")},`b${e}`)}case "paragraph":return jsx("p",{className:"mb-3 leading-relaxed text-foreground",children:M(r.content||"")},`b${e}`);case "code":return jsx("pre",{className:"mb-3 overflow-x-auto rounded-lg bg-muted p-4 text-sm font-mono leading-relaxed text-foreground",children:jsx("code",{children:r.content})},`b${e}`);case "ul":return jsx("ul",{className:"mb-3 ml-5 list-disc space-y-1 text-foreground",children:r.items?.map((i,s)=>jsx("li",{className:"leading-relaxed",children:M(i)},`li${e}-${s}`))},`b${e}`);case "ol":return jsx("ol",{className:"mb-3 ml-5 list-decimal space-y-1 text-foreground",children:r.items?.map((i,s)=>jsx("li",{className:"leading-relaxed",children:M(i)},`li${e}-${s}`))},`b${e}`);default:return null}}function L({content:r,className:e}){let i=xe(r);return jsx("div",{className:k("text-sm",e),children:i.map((s,o)=>be(s,o))})}function Q({open:r,className:e}){return jsx("svg",{width:"16",height:"16",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:k("shrink-0 transition-transform duration-150",r?"rotate-0":"-rotate-90",e),children:jsx("path",{d:"M16.134 6.16a.5.5 0 1 1 .732.68l-6.5 7-.077.068a.5.5 0 0 1-.655-.068l-6.5-7-.062-.08a.5.5 0 0 1 .718-.667l.076.067L10 12.767z"})})}function q({size:r=20,className:e}){return jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsx("path",{d:"M8.5 2a6.5 6.5 0 0 1 4.935 10.728l4.419 4.419.064.078a.5.5 0 0 1-.693.693l-.079-.064-4.419-4.42A6.5 6.5 0 1 1 8.5 2m0 1a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11"})})}function B({size:r=20,className:e}){return jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsx("path",{d:"M15.147 4.146a.5.5 0 0 1 .707.707L10.707 10l5.147 5.147a.5.5 0 0 1-.63.771l-.078-.064L10 10.707l-5.146 5.147a.5.5 0 0 1-.708-.707L9.293 10 4.146 4.853a.5.5 0 0 1 .708-.707L10 9.293z"})})}function Y({size:r=20,className:e}){return jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsx("path",{d:"M10 3a.5.5 0 0 1 .5.5v6h6l.1.01a.5.5 0 0 1 0 .98l-.1.01h-6v6a.5.5 0 0 1-1 0v-6h-6a.5.5 0 0 1 0-1h6v-6A.5.5 0 0 1 10 3"})})}function ke(){return jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M6.5 3A2.5 2.5 0 0 0 4 5.5v9A2.5 2.5 0 0 0 6.5 17h7a2.5 2.5 0 0 0 2.5-2.5v-7A2.5 2.5 0 0 0 13.5 5H11V3.5a.5.5 0 0 0-1 0V5H6.5ZM5 5.5A1.5 1.5 0 0 1 6.5 4H9v1H6.5A1.5 1.5 0 0 0 5 6.5v8A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-7A1.5 1.5 0 0 0 13.5 6H11V4h2.5A2.5 2.5 0 0 1 16 6.5v8a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-9Z"})})}function Ne(){return jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M5.5 3A2.5 2.5 0 0 0 3 5.5v9A2.5 2.5 0 0 0 5.5 17h9a2.5 2.5 0 0 0 2.5-2.5v-9A2.5 2.5 0 0 0 14.5 3h-9ZM4 5.5A1.5 1.5 0 0 1 5.5 4h9A1.5 1.5 0 0 1 16 5.5v9a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 4 14.5v-9ZM7 7.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5Z"})})}function Re(){return jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M10 2a.5.5 0 0 1 .354.146l3 3a.5.5 0 0 1-.708.708L10.5 3.707V12.5a.5.5 0 0 1-1 0V3.707L7.354 5.854a.5.5 0 1 1-.708-.708l3-3A.5.5 0 0 1 10 2ZM4 13.5a.5.5 0 0 1 1 0v1A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-1a.5.5 0 0 1 1 0v1a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-1Z"})})}function X(){let[r,e]=useState(false);return useEffect(()=>{if(typeof window>"u")return;let i=()=>e(window.innerWidth<768);return i(),window.addEventListener("resize",i),()=>window.removeEventListener("resize",i)},[]),r}function ee({onClose:r,children:e,title:i}){let s=X(),o=useRef(r);return o.current=r,useEffect(()=>{let c=t=>{t.key==="Escape"&&o.current();};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[]),s?jsxs("div",{className:"fixed inset-0 z-50 flex items-end justify-center",onClick:r,children:[jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxs("div",{className:"relative z-10 w-full max-h-[90vh] overflow-y-auto rounded-t-2xl bg-[#1a1a1a] p-5 pb-8 animate-in slide-in-from-bottom duration-200",onClick:c=>c.stopPropagation(),children:[jsx("div",{className:"mx-auto mb-4 h-1 w-10 rounded-full bg-zinc-600"}),jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsx("h2",{className:"text-lg font-semibold text-foreground",children:i}),jsx("button",{onClick:r,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsx(B,{size:20})})]}),e]})]}):jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center",onClick:r,children:[jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxs("div",{className:"relative z-10 w-full max-w-lg overflow-y-auto rounded-2xl bg-[#1a1a1a] p-6 shadow-2xl animate-in fade-in zoom-in-95 duration-150",onClick:c=>c.stopPropagation(),children:[jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsx("h2",{className:"text-lg font-semibold text-foreground",children:i}),jsx("button",{onClick:r,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsx(B,{size:20})})]}),e]})]})}function Ce({onClose:r,onCreated:e,config:i}){let[s,o]=useState(""),[c,t]=useState(""),[a,l]=useState(""),[d,u]=useState(false),[p,g]=useState(null);return jsx(ee,{title:"Write skill instructions",onClose:r,children:jsxs("div",{className:"space-y-4",children:[jsxs("div",{className:"space-y-1.5",children:[jsx("label",{htmlFor:"skill-name",className:"text-sm text-muted-foreground",children:"Skill name"}),jsx("input",{id:"skill-name",value:s,onChange:w=>o(w.target.value),placeholder:"weekly-status-report",className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxs("div",{className:"space-y-1.5",children:[jsx("label",{htmlFor:"skill-desc",className:"text-sm text-muted-foreground",children:"Description"}),jsx("textarea",{id:"skill-desc",value:c,onChange:w=>t(w.target.value),placeholder:"Generate weekly status reports from recent work.",rows:3,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxs("div",{className:"space-y-1.5",children:[jsx("label",{htmlFor:"skill-instructions",className:"text-sm text-muted-foreground",children:"Instructions"}),jsx("textarea",{id:"skill-instructions",value:a,onChange:w=>l(w.target.value),placeholder:"Summarize my recent work in three sections: wins, blockers, and next steps.",rows:8,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),p&&jsx("p",{className:"text-sm text-red-500",children:p}),jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[jsx("button",{onClick:r,className:"rounded-lg border border-zinc-700 px-4 py-2 text-sm text-foreground hover:bg-zinc-800",children:"Cancel"}),jsx("button",{onClick:async()=>{if(s.trim()){u(true),g(null);try{let w=i.apiBaseUrl||"",S=`# ${s.trim()}
4
4
 
5
5
  ${c.trim()}
6
6
 
7
7
  ---
8
8
 
9
- ${a.trim()}`,N=await fetch(`${w}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:s.trim(),description:c.trim(),skill_md:S,content_type:"code"})});if(!N.ok){let C=`Failed to register skill (${N.status})`;try{let y=await N.json();y.error&&(C=y.error);}catch{}throw new Error(C)}e?.(),r();}catch(w){g(w instanceof Error?w.message:"Failed to create skill");}finally{u(false);}}},disabled:d||!s.trim(),className:"rounded-lg bg-zinc-600 px-4 py-2 text-sm font-medium text-white hover:bg-zinc-500 disabled:opacity-50",children:d?"Creating...":"Create"})]})]})})}function Se({onClose:r,onCreated:e,config:i}){let s=useRef(null),[o,c]=useState(false),[t,a]=useState(false),[l,d]=useState(null),u=async g=>{a(true),d(null);try{let f=await g.text(),w=i.apiBaseUrl||"",S=g.name.replace(/\.[^.]+$/,"").replace(/[^a-zA-Z0-9-_]/g,"-"),N=await fetch(`${w}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:S,skill_md:f,content_type:"code"})});if(!N.ok){let C=`Failed to register skill (${N.status})`;try{let y=await N.json();y.error&&(C=y.error);}catch{}throw new Error(C)}e?.(),r();}catch(f){d(f instanceof Error?f.message:"Upload failed");}finally{a(false);}};return jsx(ee,{title:"Upload skill",onClose:r,children:jsxs("div",{className:"space-y-4",children:[jsxs("div",{onDragOver:g=>{g.preventDefault(),c(true);},onDragLeave:()=>c(false),onDrop:g=>{g.preventDefault(),c(false);let f=g.dataTransfer.files[0];f&&u(f);},onClick:()=>s.current?.click(),className:k("flex cursor-pointer flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed p-10 transition-colors",o?"border-zinc-400 bg-zinc-800/50":"border-zinc-700 hover:border-zinc-500"),children:[jsx("div",{className:"rounded-lg border border-zinc-600 p-2",children:jsx(Y,{size:20,className:"text-muted-foreground"})}),jsx("p",{className:"text-sm text-muted-foreground",children:t?"Uploading...":"Drag and drop or click to upload"})]}),jsx("input",{ref:s,type:"file",accept:".md,.zip,.skill,.txt,.yml,.yaml",className:"hidden","aria-label":"Upload skill file",onChange:g=>{let f=g.target.files?.[0];f&&u(f);}}),l&&jsx("p",{className:"text-sm text-red-500",children:l}),jsxs("div",{className:"space-y-2 text-xs text-muted-foreground",children:[jsx("p",{className:"font-medium text-foreground/70",children:"File requirements"}),jsxs("ul",{className:"list-disc pl-5 space-y-1",children:[jsx("li",{children:".md file must contain skill name and description formatted in YAML"}),jsx("li",{children:".zip or .skill file must include a SKILL.md file"})]})]})]})})}function Te({onClose:r,onSelect:e}){let i=X(),s=useRef(null),o=useRef(r);o.current=r,useEffect(()=>{if(i)return;let t=a=>{s.current&&a.target instanceof Node&&!s.current.contains(a.target)&&o.current();};return document.addEventListener("mousedown",t),()=>document.removeEventListener("mousedown",t)},[i]);let c=[{id:"create-with-geoff",icon:jsx(ke,{}),label:"Create with Geoff"},{id:"write",icon:jsx(Ne,{}),label:"Write skill instructions"},{id:"upload",icon:jsx(Re,{}),label:"Upload a skill"}];return i?jsxs("div",{className:"fixed inset-0 z-50 flex items-end",onClick:r,children:[jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxs("div",{className:"relative z-10 w-full rounded-t-2xl bg-[#1a1a1a] p-4 pb-8 animate-in slide-in-from-bottom duration-200",onClick:t=>t.stopPropagation(),children:[jsx("div",{className:"mx-auto mb-3 h-1 w-10 rounded-full bg-zinc-600"}),c.map(t=>jsxs("button",{onClick:()=>{e(t.id),r();},className:"flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-800",children:[t.icon,t.label]},t.id))]})]}):jsx("div",{ref:s,className:"absolute right-2 top-11 z-50 w-56 overflow-hidden rounded-xl border border-zinc-700 bg-[#2a2a2a] shadow-xl animate-in fade-in zoom-in-95 duration-100",children:c.map(t=>jsxs("button",{onClick:()=>{e(t.id),r();},className:"flex w-full items-center gap-3 px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-700/50",children:[t.icon,t.label]},t.id))})}function Ee({entry:r,selected:e,onSelect:i,depth:s=0}){return jsxs("button",{onClick:()=>i(r),className:k("flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),style:{paddingLeft:`${8+s*16}px`},children:[jsx("span",{className:"truncate flex-1",children:r.path.split("/").pop()}),r.isDir&&jsx(Q,{className:"ml-auto text-muted-foreground"})]})}function Me({repo:r,selected:e,expanded:i,onSelect:s,onToggle:o,children:c}){return jsxs("div",{children:[jsxs("button",{onClick:()=>{s(),o();},className:k("flex w-full items-center gap-2 rounded-md px-2 py-2 text-left text-sm font-medium transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),children:[jsx(Q,{open:i}),jsx(FileText,{className:"h-4 w-4 shrink-0"}),jsx("span",{className:"truncate",children:r.name})]}),i&&c]})}function ze({entry:r,content:e,loading:i,repoName:s}){let[o,c]=useState(false),t=useRef(null);useEffect(()=>()=>{t.current&&clearTimeout(t.current);},[]);let[a,l]=useState(false),d=async()=>{if(e)try{await navigator.clipboard.writeText(e),c(!0),l(!1),t.current&&clearTimeout(t.current),t.current=setTimeout(()=>c(!1),2e3);}catch{l(true),t.current&&clearTimeout(t.current),t.current=setTimeout(()=>l(false),2e3);}};if(!r)return jsx("div",{className:"flex h-full items-center justify-center text-sm text-muted-foreground",children:"Select a file to view its content"});if(i)return jsx("div",{className:"flex h-full items-center justify-center",children:jsx(Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})});let u=r.path.split("/").pop()||r.path,p=/\.(md|mdx)$/i.test(u);return jsxs("div",{className:"flex h-full flex-col px-3",children:[jsxs("div",{className:"flex items-center justify-between px-4 py-3",children:[jsx("h3",{className:"text-sm sm:text-lg font-semibold text-foreground",children:u}),jsx("button",{onClick:d,"aria-label":"Copy file content",className:k("rounded p-1 transition-colors",o?"text-green-500":a?"text-red-500":"text-muted-foreground hover:text-foreground"),children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M12.5 3A1.5 1.5 0 0 1 14 4.5V6h1.5A1.5 1.5 0 0 1 17 7.5v8a1.5 1.5 0 0 1-1.5 1.5h-8A1.5 1.5 0 0 1 6 15.5V14H4.5A1.5 1.5 0 0 1 3 12.5v-8A1.5 1.5 0 0 1 4.5 3zm1.5 9.5a1.5 1.5 0 0 1-1.5 1.5H7v1.5a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5H14zM4.5 4a.5.5 0 0 0-.5.5v8a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5z"})})})]}),jsx("div",{className:"flex-1 overflow-auto p-4",children:p?jsx(B,{content:e||""}):jsx("pre",{className:"whitespace-pre-wrap text-sm text-foreground font-mono leading-relaxed",children:e||""})})]})}function $e({config:r,category:e,className:i,style:s}){let{repos:o,loading:c,error:t,refresh:a}=Z(r),[l,d]=useState(null),[u,p]=useState(null),[g,f]=useState(null),[w,S]=useState(null),[N,C]=useState(false),[y,U]=useState(""),[te,D]=useState(false),[O,j]=useState(false),[F,$]=useState(null),re=o.find(h=>h.repo_id===l),{entries:ne,getFileContent:H}=W(r,u),V=o.filter(h=>!y||h.name.toLowerCase().includes(y.toLowerCase())),se=useCallback(async h=>{if(!h.isDir){f(h),C(true);try{let R=await H(h.cid);S(R);}catch(R){let ae=R instanceof Error?R.message:"Unknown error";S(`Failed to load file: ${ae}`);}finally{C(false);}}},[H]);useEffect(()=>{o.length>0&&!l&&(d(o[0].repo_id),p(o[0].repo_id));},[o,l]);let oe=h=>{h==="create-with-geoff"?window.open(`https://www.geoff.ai/?p=${encodeURIComponent("Let's create a skill together using your skill-creator skill. First ask me what the skill should do.")}`,"_blank","noopener,noreferrer"):$(h);};return jsxs("div",{className:k("flex flex-1 h-full min-h-0",i),style:s,children:[jsxs("div",{className:"relative flex w-96 shrink-0 flex-col border-r",children:[jsx("div",{className:"flex h-12 items-center gap-2 px-3",children:te?jsxs(Fragment,{children:[jsxs("div",{className:"flex flex-1 items-center gap-2 rounded-md border bg-muted/50 px-2 py-1",children:[jsx(q,{size:16,className:"shrink-0 text-muted-foreground"}),jsx("input",{type:"text",value:y,onChange:h=>U(h.target.value),placeholder:"Search",autoFocus:true,"aria-label":"Search items",className:"flex-1 bg-transparent text-xs text-foreground placeholder:text-muted-foreground focus:outline-none"})]}),jsx("button",{onClick:()=>{D(false),U("");},className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsx(L,{size:16})})]}):jsxs(Fragment,{children:[jsx("h3",{className:"flex-1 text-sm sm:text-lg font-semibold text-foreground capitalize",children:e||"Items"}),jsx("button",{onClick:()=>D(true),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Search",children:jsx(q,{size:20})}),jsx("button",{onClick:()=>j(!O),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Add new",children:jsx(Y,{size:20})})]})}),O&&jsx(Te,{onClose:()=>j(false),onSelect:oe}),jsx("div",{className:"flex-1 overflow-y-auto p-2",children:c?jsx("div",{className:"flex items-center justify-center py-8",children:jsx(Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})}):t?jsx("p",{className:"px-2 py-4 text-xs text-red-500",children:t}):V.length===0?jsx("p",{className:"px-2 py-4 text-xs text-muted-foreground",children:y?"No matching items":"No items yet"}):jsx("div",{className:"space-y-0.5",children:V.map(h=>jsx(Me,{repo:h,selected:l===h.repo_id,expanded:u===h.repo_id,onSelect:()=>{d(h.repo_id),f(null),S(null);},onToggle:()=>p(u===h.repo_id?null:h.repo_id),children:jsx("div",{className:"ml-10 pl-1",children:ne.map(R=>jsx(Ee,{entry:R,selected:g?.path===R.path,onSelect:se,depth:R.path.split("/").length-1},R.path))})},h.repo_id))})})]}),jsx("div",{className:"flex-1 min-w-0",children:jsx(ze,{entry:g,content:w,loading:N,repoName:re?.name||""})}),F==="write"&&jsx(Ce,{config:r,onClose:()=>$(null),onCreated:a}),F==="upload"&&jsx(Se,{config:r,onClose:()=>$(null),onCreated:a})]})}
10
- export{B as Markdown,$e as RackBrowser};
9
+ ${a.trim()}`,N=await fetch(`${w}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:s.trim(),description:c.trim(),skill_md:S,content_type:"code"})});if(!N.ok){let C=`Failed to register skill (${N.status})`;try{let y=await N.json();y.error&&(C=y.error);}catch{}throw new Error(C)}e?.(),r();}catch(w){g(w instanceof Error?w.message:"Failed to create skill");}finally{u(false);}}},disabled:d||!s.trim(),className:"rounded-lg bg-zinc-600 px-4 py-2 text-sm font-medium text-white hover:bg-zinc-500 disabled:opacity-50",children:d?"Creating...":"Create"})]})]})})}function Se({onClose:r,onCreated:e,config:i}){let s=useRef(null),[o,c]=useState(false),[t,a]=useState(false),[l,d]=useState(null),u=async g=>{a(true),d(null);try{let f=await g.text(),w=i.apiBaseUrl||"",S=g.name.replace(/\.[^.]+$/,"").replace(/[^a-zA-Z0-9-_]/g,"-"),N=await fetch(`${w}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:S,skill_md:f,content_type:"code"})});if(!N.ok){let C=`Failed to register skill (${N.status})`;try{let y=await N.json();y.error&&(C=y.error);}catch{}throw new Error(C)}e?.(),r();}catch(f){d(f instanceof Error?f.message:"Upload failed");}finally{a(false);}};return jsx(ee,{title:"Upload skill",onClose:r,children:jsxs("div",{className:"space-y-4",children:[jsxs("div",{onDragOver:g=>{g.preventDefault(),c(true);},onDragLeave:()=>c(false),onDrop:g=>{g.preventDefault(),c(false);let f=g.dataTransfer.files[0];f&&u(f);},onClick:()=>s.current?.click(),className:k("flex cursor-pointer flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed p-10 transition-colors",o?"border-zinc-400 bg-zinc-800/50":"border-zinc-700 hover:border-zinc-500"),children:[jsx("div",{className:"rounded-lg border border-zinc-600 p-2",children:jsx(Y,{size:20,className:"text-muted-foreground"})}),jsx("p",{className:"text-sm text-muted-foreground",children:t?"Uploading...":"Drag and drop or click to upload"})]}),jsx("input",{ref:s,type:"file",accept:".md,.zip,.skill,.txt,.yml,.yaml",className:"hidden","aria-label":"Upload skill file",onChange:g=>{let f=g.target.files?.[0];f&&u(f);}}),l&&jsx("p",{className:"text-sm text-red-500",children:l}),jsxs("div",{className:"space-y-2 text-xs text-muted-foreground",children:[jsx("p",{className:"font-medium text-foreground/70",children:"File requirements"}),jsxs("ul",{className:"list-disc pl-5 space-y-1",children:[jsx("li",{children:".md file must contain skill name and description formatted in YAML"}),jsx("li",{children:".zip or .skill file must include a SKILL.md file"})]})]})]})})}function Te({onClose:r,onSelect:e}){let i=X(),s=useRef(null),o=useRef(r);o.current=r,useEffect(()=>{if(i)return;let t=a=>{s.current&&a.target instanceof Node&&!s.current.contains(a.target)&&o.current();};return document.addEventListener("mousedown",t),()=>document.removeEventListener("mousedown",t)},[i]);let c=[{id:"create-with-geoff",icon:jsx(ke,{}),label:"Create with Geoff"},{id:"write",icon:jsx(Ne,{}),label:"Write skill instructions"},{id:"upload",icon:jsx(Re,{}),label:"Upload a skill"}];return i?jsxs("div",{className:"fixed inset-0 z-50 flex items-end",onClick:r,children:[jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxs("div",{className:"relative z-10 w-full rounded-t-2xl bg-[#1a1a1a] p-4 pb-8 animate-in slide-in-from-bottom duration-200",onClick:t=>t.stopPropagation(),children:[jsx("div",{className:"mx-auto mb-3 h-1 w-10 rounded-full bg-zinc-600"}),c.map(t=>jsxs("button",{onClick:()=>{e(t.id),r();},className:"flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-800",children:[t.icon,t.label]},t.id))]})]}):jsx("div",{ref:s,className:"absolute right-2 top-11 z-50 w-56 overflow-hidden rounded-xl border border-zinc-700 bg-[#2a2a2a] shadow-xl animate-in fade-in zoom-in-95 duration-100",children:c.map(t=>jsxs("button",{onClick:()=>{e(t.id),r();},className:"flex w-full items-center gap-3 px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-700/50",children:[t.icon,t.label]},t.id))})}function Ee({entry:r,selected:e,onSelect:i,depth:s=0}){return jsxs("button",{onClick:()=>i(r),className:k("flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),style:{paddingLeft:`${8+s*16}px`},children:[jsx("span",{className:"truncate flex-1",children:r.path.split("/").pop()}),r.isDir&&jsx(Q,{className:"ml-auto text-muted-foreground"})]})}function Pe({repo:r,selected:e,expanded:i,onSelect:s,onToggle:o,children:c}){return jsxs("div",{children:[jsxs("button",{onClick:()=>{s(),o();},className:k("flex w-full items-center gap-2 rounded-md px-2 py-2 text-left text-sm font-medium transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),children:[jsx(Q,{open:i}),jsx(FileText,{className:"h-4 w-4 shrink-0"}),jsx("span",{className:"truncate",children:r.name})]}),i&&c]})}function Me({entry:r,content:e,loading:i,repoName:s}){let[o,c]=useState(false),t=useRef(null);useEffect(()=>()=>{t.current&&clearTimeout(t.current);},[]);let[a,l]=useState(false),d=async()=>{if(e)try{await navigator.clipboard.writeText(e),c(!0),l(!1),t.current&&clearTimeout(t.current),t.current=setTimeout(()=>c(!1),2e3);}catch{l(true),t.current&&clearTimeout(t.current),t.current=setTimeout(()=>l(false),2e3);}};if(!r)return jsx("div",{className:"flex h-full items-center justify-center text-sm text-muted-foreground",children:"Select a file to view its content"});if(i)return jsx("div",{className:"flex h-full items-center justify-center",children:jsx(Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})});let u=r.path.split("/").pop()||r.path,p=/\.(md|mdx)$/i.test(u);return jsxs("div",{className:"flex h-full flex-col px-3",children:[jsxs("div",{className:"flex items-center justify-between px-4 py-3",children:[jsx("h3",{className:"text-sm sm:text-lg font-semibold text-foreground",children:u}),jsx("button",{onClick:d,"aria-label":"Copy file content",className:k("rounded p-1 transition-colors",o?"text-green-500":a?"text-red-500":"text-muted-foreground hover:text-foreground"),children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M12.5 3A1.5 1.5 0 0 1 14 4.5V6h1.5A1.5 1.5 0 0 1 17 7.5v8a1.5 1.5 0 0 1-1.5 1.5h-8A1.5 1.5 0 0 1 6 15.5V14H4.5A1.5 1.5 0 0 1 3 12.5v-8A1.5 1.5 0 0 1 4.5 3zm1.5 9.5a1.5 1.5 0 0 1-1.5 1.5H7v1.5a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5H14zM4.5 4a.5.5 0 0 0-.5.5v8a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5z"})})})]}),jsx("div",{className:"flex-1 overflow-auto p-4",children:p?jsx(L,{content:e||""}):jsx("pre",{className:"whitespace-pre-wrap text-sm text-foreground font-mono leading-relaxed",children:e||""})})]})}function ze({config:r,category:e,className:i,style:s}){let{repos:o,loading:c,error:t,refresh:a}=Z(r),[l,d]=useState(null),[u,p]=useState(null),[g,f]=useState(null),[w,S]=useState(null),[N,C]=useState(false),[y,U]=useState(""),[te,D]=useState(false),[O,j]=useState(false),[F,z]=useState(null),re=o.find(h=>h.repo_id===l),{entries:ne,getFileContent:H}=W(r,u),V=o.filter(h=>!y||h.name.toLowerCase().includes(y.toLowerCase())),se=useCallback(async h=>{if(!h.isDir){f(h),C(true);try{let R=await H(h.cid);S(R);}catch(R){let ae=R instanceof Error?R.message:"Unknown error";S(`Failed to load file: ${ae}`);}finally{C(false);}}},[H]);useEffect(()=>{o.length>0&&!l&&(d(o[0].repo_id),p(o[0].repo_id));},[o,l]);let oe=h=>{h==="create-with-geoff"?window.open(`https://www.geoff.ai/?p=${encodeURIComponent("Let's create a skill together using your skill-creator skill. First ask me what the skill should do.")}`,"_blank","noopener,noreferrer"):z(h);};return jsxs("div",{className:k("flex flex-1 h-full min-h-0",i),style:s,children:[jsxs("div",{className:"relative flex w-96 shrink-0 flex-col border-r",children:[jsx("div",{className:"flex h-12 items-center gap-2 px-3",children:te?jsxs(Fragment,{children:[jsxs("div",{className:"flex flex-1 items-center gap-2 rounded-md border bg-muted/50 px-2 py-1",children:[jsx(q,{size:16,className:"shrink-0 text-muted-foreground"}),jsx("input",{type:"text",value:y,onChange:h=>U(h.target.value),placeholder:"Search",autoFocus:true,"aria-label":"Search items",className:"flex-1 bg-transparent text-xs text-foreground placeholder:text-muted-foreground focus:outline-none"})]}),jsx("button",{onClick:()=>{D(false),U("");},className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsx(B,{size:16})})]}):jsxs(Fragment,{children:[jsx("h3",{className:"flex-1 text-sm sm:text-lg font-semibold text-foreground capitalize",children:e||"Items"}),jsx("button",{onClick:()=>D(true),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Search",children:jsx(q,{size:20})}),jsx("button",{onClick:()=>j(!O),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Add new",children:jsx(Y,{size:20})})]})}),O&&jsx(Te,{onClose:()=>j(false),onSelect:oe}),jsx("div",{className:"flex-1 overflow-y-auto p-2",children:c?jsx("div",{className:"flex items-center justify-center py-8",children:jsx(Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})}):t?jsx("p",{className:"px-2 py-4 text-xs text-red-500",children:t}):V.length===0?jsx("p",{className:"px-2 py-4 text-xs text-muted-foreground",children:y?"No matching items":"No items yet"}):jsx("div",{className:"space-y-0.5",children:V.map(h=>jsx(Pe,{repo:h,selected:l===h.repo_id,expanded:u===h.repo_id,onSelect:()=>{d(h.repo_id),f(null),S(null);},onToggle:()=>p(u===h.repo_id?null:h.repo_id),children:jsx("div",{className:"ml-10 pl-1",children:ne.map(R=>jsx(Ee,{entry:R,selected:g?.path===R.path,onSelect:se,depth:R.path.split("/").length-1},R.path))})},h.repo_id))})})]}),jsx("div",{className:"flex-1 min-w-0",children:jsx(Me,{entry:g,content:w,loading:N,repoName:re?.name||""})}),F==="write"&&jsx(Ce,{config:r,onClose:()=>z(null),onCreated:a}),F==="upload"&&jsx(Se,{config:r,onClose:()=>z(null),onCreated:a})]})}
10
+ export{L as Markdown,ze as RackBrowser};
@@ -1 +1 @@
1
- 'use strict';var react=require('react');async function d(u,t,i,l){let c={"Content-Type":"application/json",...i?.headers};l&&(c.Authorization=`Bearer ${l}`);let g=await fetch(`${u}${t}`,{...i,headers:c});if(!g.ok){let e=`HTTP ${g.status}`;try{let r=await g.json();r.error&&(e=r.error);}catch{}throw new Error(e)}return g.json()}function k(u){let t=u.indexOf(":");return {mode:u.slice(0,t),cid:u.slice(t+1)}}function p(u){let t=u.apiBaseUrl,i=u.authorMid,l=u.ownerMid,c=u.apiKey,g=u.stacknetUrl||u.apiBaseUrl;return react.useMemo(()=>({async listRepos(e){let r=e||l?`?owner=${encodeURIComponent(e||l)}`:"";return (await d(t,`/api/rack/repos${r}`,void 0,c)).repos||[]},async initRepo(e){return d(t,"/api/rack/init",{method:"POST",body:JSON.stringify({...e,owner_mid:l})},c)},async push(e,r){return d(t,`/api/rack/${e}/push`,{method:"POST",body:JSON.stringify({...r,author_mid:i})},c)},async getTree(e,r="main"){let n=await d(t,`/api/rack/${e}/tree/${r}`,void 0,c);return {tree:n.tree,commit_cid:n.commit_cid}},async getBlob(e,r){return (await d(t,`/api/rack/${e}/blob/${r}`,void 0,c)).content},async getLog(e,r,n){let s=new URLSearchParams;r&&s.set("ref",r),n&&s.set("max_count",String(n));let a=s.toString()?`?${s}`:"";return (await d(t,`/api/rack/${e}/log${a}`,void 0,c)).commits||[]},async getBranches(e){return (await d(t,`/api/rack/${e}/branches`,void 0,c)).branches||[]},async createBranch(e,r,n){return d(t,`/api/rack/${e}/branch`,{method:"POST",body:JSON.stringify({branch_name:r,from_ref:n})},c)},async merge(e,r,n){return d(t,`/api/rack/${e}/merge`,{method:"POST",body:JSON.stringify({source_branch:r,target_branch:n})},c)},async getDiff(e,r,n){return (await d(t,`/api/rack/${e}/diff/${r}/${n}`,void 0,c)).diff?.entries||[]},async starRepo(e){return d(t,`/api/rack/${e}/star`,{method:"POST"},c)},async unstarRepo(e){return d(t,`/api/rack/${e}/star`,{method:"DELETE"},c)},async getStarInfo(e){return d(t,`/api/rack/${e}/stars`,void 0,c)},async getSkillStats(e){let r={meta:null,tokenCount:null,usageCount:null};try{let{tree:n}=await this.getTree(e,"main");if(!n?.entries)return r;if(n.entries["META.json"]){let o=k(n.entries["META.json"]).cid,f=await this.getBlob(e,o);r.meta=JSON.parse(f);}let s=0,a=Object.values(n.entries).map(async o=>{try{let f=k(o).cid,m=await this.getBlob(e,f);s+=m.length;}catch{}});await Promise.all(a),s>0&&(r.tokenCount=Math.ceil(s/4)),r.meta?.skill_id&&(r.usageCount=await this.getSkillUsageCount(r.meta.skill_id));}catch{}return r},async getSkillUsageCount(e){try{let r=await fetch(`${g}/v1/skills/${encodeURIComponent(e)}`);if(r.ok){let s=await r.json();return s.usage_count??s.usageCount??null}let n=await fetch(`${g}/v1/skills?scope=public`);if(n.ok){let a=((await n.json()).skills||[]).find(o=>o.name===e||o.id===e);if(a)return a.usage_count??a.usageCount??0}return 0}catch{return null}},async getTensorStats(e){let r={meta:null,sizeMB:null};try{let{tree:n}=await this.getTree(e,"main");if(!n?.entries)return r;if(n.entries["TENSOR_META.json"]){let s=k(n.entries["TENSOR_META.json"]).cid,a=await this.getBlob(e,s);r.meta=JSON.parse(a),r.sizeMB=r.meta?.tensor_size_mb??null;}}catch{}return r},async getNetworkStats(){try{return (await d(t,"/api/rack/stats",void 0,c)).stats||null}catch{return null}},async getTrending(e=5,r=1){try{return (await d(t,`/api/rack/trending?limit=${e}&days=${r}`,void 0,c)).trending||[]}catch{return []}}}),[t,i,l,c,g])}function J(u){let t=p(u),i=react.useRef(t);i.current=t;let[l,c]=react.useState([]),[g,e]=react.useState(true),[r,n]=react.useState(null),s=react.useRef(true),a=react.useRef(null),o=react.useCallback(async()=>{a.current?.abort();let f=new AbortController;a.current=f;try{s.current&&(e(!0),n(null));let m=await i.current.listRepos();s.current&&!f.signal.aborted&&c(m);}catch(m){s.current&&!f.signal.aborted&&n(m instanceof Error?m.message:"Failed to load repos");}finally{s.current&&!f.signal.aborted&&e(false);}},[]);return react.useEffect(()=>(s.current=true,o(),()=>{s.current=false,a.current?.abort();}),[o]),{repos:l,loading:g,error:r,refresh:o}}function H(u){return Object.entries(u).map(([t,i])=>{let l=i.indexOf(":"),c=l>0?i.slice(0,l):"100644",g=l>0?i.slice(l+1):i;return {path:t,mode:c,cid:g,isDir:c==="040000"}}).sort((t,i)=>t.isDir!==i.isDir?t.isDir?-1:1:t.path.localeCompare(i.path))}function W(u,t,i="main"){let l=p(u),[c,g]=react.useState([]),[e,r]=react.useState(false),[n,s]=react.useState(null),a=react.useRef(true),o=react.useCallback(async()=>{if(t)try{a.current&&(r(!0),s(null));let{tree:m}=await l.getTree(t,i);a.current&&g(H(m.entries));}catch(m){a.current&&s(m instanceof Error?m.message:"Failed to load tree");}finally{a.current&&r(false);}},[l,t,i]);react.useEffect(()=>(a.current=true,o(),()=>{a.current=false;}),[o]);let f=react.useCallback(async m=>{if(!t)throw new Error("No repo selected");return l.getBlob(t,m)},[l,t]);return {entries:c,loading:e,error:n,refresh:o,getFileContent:f}}function Q(u){let t=p(u),[i,l]=react.useState(false),[c,g]=react.useState(null),e=react.useRef(true);return react.useEffect(()=>(e.current=true,()=>{e.current=false;}),[]),{push:react.useCallback(async(n,s,a,o)=>{try{return e.current&&(l(!0),g(null)),await t.push(n,{files:s,message:a,branch:o})}catch(f){let m=f instanceof Error?f.message:"Push failed";return e.current&&g(m),null}finally{e.current&&l(false);}},[t]),pushing:i,error:c}}var w="stacknet-rack-apikey";function X(u){let t=u.stacknetUrl||u.apiBaseUrl,[i,l]=react.useState({authenticated:false}),[c,g]=react.useState(null),[e,r]=react.useState(false),n=react.useCallback(f=>({"Content-Type":"application/json",...f||u.apiKey?{Authorization:`Bearer ${f||u.apiKey}`}:{}}),[u.apiKey]),s=react.useCallback(async f=>{r(true);try{let m=await fetch(`${t}/health`,{headers:n(f)});if(!m.ok)throw new Error(`Authentication failed: ${m.status}`);let R={authenticated:!0,apiKey:f,permission:f.startsWith("gk_")?"write":"read"};l(R);try{localStorage.setItem(w,f);}catch{}return R}catch(m){throw l({authenticated:false}),m}finally{r(false);}},[t,n]),a=react.useCallback(()=>{l({authenticated:false}),g(null);try{localStorage.removeItem(w);}catch{}},[]),o=react.useCallback(async()=>{let f=i.apiKey||u.apiKey;if(!f)return null;try{let m=await fetch(`${t}/network/usage`,{headers:n(f)});if(!m.ok)return null;let R=await m.json(),I={planAllocation:R.plan_allocation??R.planAllocation??0,inferenceUsed:R.inference_used??R.inferenceUsed??0,ledgerSpent:R.ledger_spent??R.ledgerSpent??0,totalUsed:R.total_used??R.totalUsed??0,remaining:R.remaining??0,percent:R.percent??0,exceeded:R.exceeded??!1};return g(I),I}catch{return null}},[i.apiKey,u.apiKey,t,n]);return react.useEffect(()=>{let f=u.apiKey;if(f){l({authenticated:true,apiKey:f,permission:f.startsWith("gk_")?"write":"read"});return}try{let m=localStorage.getItem(w);m&&l({authenticated:!0,apiKey:m,permission:m.startsWith("gk_")?"write":"read"});}catch{}},[u.apiKey]),{session:i,budget:c,loading:e,login:s,logout:a,refreshBudget:o}}var B=1e3,M=1e3,j=100;function L(u,t){if(u==="skill"){let c=j+Math.ceil(t/4);return {type:u,totalBytes:t,totalMegabytes:t/1e6,baseCost:c,multiplier:B,registrationCostTokens:c*B}}let i=Math.ceil(t/1e6),l=j+i;return {type:u,totalBytes:t,totalMegabytes:i,baseCost:l,multiplier:M,registrationCostTokens:l*M}}function Z(u){let t=u.stacknetUrl||u.apiBaseUrl,i=u.apiKey,[l,c]=react.useState(false),[g,e]=react.useState(null),r=react.useCallback(()=>{if(!i)throw new Error("API key required for registration. Call login() first.");return {"Content-Type":"application/json",Authorization:`Bearer ${i}`}},[i]),n=react.useCallback(async a=>{c(true),e(null);try{let o=await fetch(`${t}/skills`,{method:"POST",headers:r(),body:JSON.stringify(a)});if(!o.ok){let f=await o.json().catch(()=>({error:`HTTP ${o.status}`}));throw new Error(f.error||`Registration failed: ${o.status}`)}return await o.json()}catch(o){throw e(o.message),o}finally{c(false);}},[t,r]),s=react.useCallback(async a=>{c(true),e(null);try{let o=await fetch(`${t}/tensors`,{method:"POST",headers:r(),body:JSON.stringify(a)});if(!o.ok){let f=await o.json().catch(()=>({error:`HTTP ${o.status}`}));throw new Error(f.error||`Registration failed: ${o.status}`)}return await o.json()}catch(o){throw e(o.message),o}finally{c(false);}},[t,r]);return {registerSkill:n,registerTensor:s,estimateCost:L,registering:l,error:g}}function nt(u,t){let i=p(u),[l,c]=react.useState({meta:null,tokenCount:null,usageCount:null}),[g,e]=react.useState(false),[r,n]=react.useState(null),s=react.useRef(true),a=react.useCallback(async()=>{if(t){e(true),n(null);try{let o=await i.getSkillStats(t);s.current&&c(o);}catch(o){s.current&&n(o.message);}finally{s.current&&e(false);}}},[i,t]);return react.useEffect(()=>(s.current=true,a(),()=>{s.current=false;}),[a]),{stats:l,loading:g,error:r,refresh:a}}function it(u,t){let i=p(u),[l,c]=react.useState({meta:null,sizeMB:null}),[g,e]=react.useState(false),[r,n]=react.useState(null),s=react.useRef(true),a=react.useCallback(async()=>{if(t){e(true),n(null);try{let o=await i.getTensorStats(t);s.current&&c(o);}catch(o){s.current&&n(o.message);}finally{s.current&&e(false);}}},[i,t]);return react.useEffect(()=>(s.current=true,a(),()=>{s.current=false;}),[a]),{stats:l,loading:g,error:r,refresh:a}}function ft(u){let t=p(u),[i,l]=react.useState(null),[c,g]=react.useState(false),[e,r]=react.useState(null),n=react.useRef(true),s=react.useCallback(async()=>{g(true),r(null);try{let a=await t.getNetworkStats();n.current&&l(a);}catch(a){n.current&&r(a.message);}finally{n.current&&g(false);}},[t]);return react.useEffect(()=>(n.current=true,s(),()=>{n.current=false;}),[s]),{stats:i,loading:c,error:e,refresh:s}}function dt(u,t=5,i=1){let l=p(u),[c,g]=react.useState([]),[e,r]=react.useState(false),[n,s]=react.useState(null),a=react.useRef(true),o=react.useCallback(async f=>{r(true),s(null);try{let m=await l.getTrending(t,f??i);a.current&&g(m);}catch(m){a.current&&s(m.message);}finally{a.current&&r(false);}},[l,t,i]);return react.useEffect(()=>(a.current=true,o(),()=>{a.current=false;}),[o]),{repos:c,loading:e,error:n,refresh:o}}function kt(u,t){let i=p(u),[l,c]=react.useState({stars:0,starred:false,repo_id:t||""}),[g,e]=react.useState(false),[r,n]=react.useState(null),s=react.useRef(true),a=react.useCallback(async()=>{if(t)try{let f=await i.getStarInfo(t);s.current&&c(f);}catch{}},[i,t]);react.useEffect(()=>(s.current=true,a(),()=>{s.current=false;}),[a]);let o=react.useCallback(async()=>{if(t){e(true),n(null);try{let f=l.starred?await i.unstarRepo(t):await i.starRepo(t);s.current&&c({stars:f.stars,starred:f.starred,repo_id:t});}catch(f){s.current&&n(f.message);}finally{s.current&&e(false);}}},[i,t,l.starred]);return {...l,loading:g,error:r,toggle:o,refresh:a}}exports.estimateCost=L;exports.useNetworkStats=ft;exports.useRackClient=p;exports.useRackRegister=Z;exports.useRackSession=X;exports.useRepoPush=Q;exports.useRepoTree=W;exports.useRepos=J;exports.useSkillStats=nt;exports.useStar=kt;exports.useTensorStats=it;exports.useTrending=dt;
1
+ 'use strict';var react=require('react');async function R(f,t,o,l){let c={"Content-Type":"application/json",...o?.headers};l&&(c.Authorization=`Bearer ${l}`);let p=await fetch(`${f}${t}`,{...o,headers:c});if(!p.ok){let e=`HTTP ${p.status}`;try{let r=await p.json();r.error&&(e=r.error);}catch{}throw new Error(e)}return p.json()}function T(f){let t=f.indexOf(":");return {mode:f.slice(0,t),cid:f.slice(t+1)}}function d(f){let t=f.apiBaseUrl,o=f.authorMid,l=f.ownerMid,c=f.apiKey,p=f.stacknetUrl||f.apiBaseUrl;return react.useMemo(()=>({async listRepos(e,r){let n=new URLSearchParams;(e||l)&&n.set("owner",e||l),r?.limit&&n.set("limit",String(r.limit)),r?.cursor&&n.set("cursor",r.cursor);let s=n.toString()?`?${n}`:"",a=await R(t,`/api/rack/repos${s}`,void 0,c);return {items:a.repos||[],pagination:a.pagination||{total:(a.repos||[]).length,limit:50,has_more:false,next_cursor:null}}},async initRepo(e){return R(t,"/api/rack/init",{method:"POST",body:JSON.stringify({...e,owner_mid:l})},c)},async push(e,r){return R(t,`/api/rack/${e}/push`,{method:"POST",body:JSON.stringify({...r,author_mid:o})},c)},async getTree(e,r="main"){let n=await R(t,`/api/rack/${e}/tree/${r}`,void 0,c);return {tree:n.tree,commit_cid:n.commit_cid}},async getBlob(e,r){return (await R(t,`/api/rack/${e}/blob/${r}`,void 0,c)).content},async getLog(e,r,n){let s=new URLSearchParams;r&&s.set("ref",r),n&&s.set("max_count",String(n));let a=s.toString()?`?${s}`:"";return (await R(t,`/api/rack/${e}/log${a}`,void 0,c)).commits||[]},async getBranches(e){return (await R(t,`/api/rack/${e}/branches`,void 0,c)).branches||[]},async createBranch(e,r,n){return R(t,`/api/rack/${e}/branch`,{method:"POST",body:JSON.stringify({branch_name:r,from_ref:n})},c)},async merge(e,r,n){return R(t,`/api/rack/${e}/merge`,{method:"POST",body:JSON.stringify({source_branch:r,target_branch:n})},c)},async getDiff(e,r,n){return (await R(t,`/api/rack/${e}/diff/${r}/${n}`,void 0,c)).diff?.entries||[]},async starRepo(e){return R(t,`/api/rack/${e}/star`,{method:"POST"},c)},async unstarRepo(e){return R(t,`/api/rack/${e}/star`,{method:"DELETE"},c)},async getStarInfo(e){return R(t,`/api/rack/${e}/stars`,void 0,c)},async getSkillStats(e){let r={meta:null,tokenCount:null,usageCount:null};try{let{tree:n}=await this.getTree(e,"main");if(!n?.entries)return r;if(n.entries["META.json"]){let i=T(n.entries["META.json"]).cid,u=await this.getBlob(e,i);r.meta=JSON.parse(u);}let s=0,a=Object.values(n.entries).map(async i=>{try{let u=T(i).cid,g=await this.getBlob(e,u);s+=g.length;}catch{}});await Promise.all(a),s>0&&(r.tokenCount=Math.ceil(s/4)),r.meta?.skill_id&&(r.usageCount=await this.getSkillUsageCount(r.meta.skill_id));}catch{}return r},async getSkillUsageCount(e){try{let r=await fetch(`${p}/v1/skills/${encodeURIComponent(e)}`);if(r.ok){let s=await r.json();return s.usage_count??s.usageCount??null}let n=await fetch(`${p}/v1/skills?scope=public`);if(n.ok){let a=((await n.json()).skills||[]).find(i=>i.name===e||i.id===e);if(a)return a.usage_count??a.usageCount??0}return 0}catch{return null}},async getTensorStats(e){let r={meta:null,sizeMB:null};try{let{tree:n}=await this.getTree(e,"main");if(!n?.entries)return r;if(n.entries["TENSOR_META.json"]){let s=T(n.entries["TENSOR_META.json"]).cid,a=await this.getBlob(e,s);r.meta=JSON.parse(a),r.sizeMB=r.meta?.tensor_size_mb??null;}}catch{}return r},async getNetworkStats(){try{return (await R(t,"/api/rack/stats",void 0,c)).stats||null}catch{return null}},async getTrending(e=5,r=1,n){try{let s=new URLSearchParams({limit:String(e),days:String(r)});n&&s.set("cursor",n);let a=await R(t,`/api/rack/trending?${s}`,void 0,c);return {items:a.trending||[],pagination:a.pagination||{total:(a.trending||[]).length,limit:e,has_more:!1,next_cursor:null}}}catch{return {items:[],pagination:{total:0,limit:e,has_more:false,next_cursor:null}}}}}),[t,o,l,c,p])}function Z(f){let t=d(f),o=react.useRef(t);o.current=t;let[l,c]=react.useState([]),[p,e]=react.useState(true),[r,n]=react.useState(null),s=react.useRef(true),a=react.useRef(null),i=react.useCallback(async()=>{a.current?.abort();let u=new AbortController;a.current=u;try{s.current&&(e(!0),n(null));let g=await o.current.listRepos();s.current&&!u.signal.aborted&&c(g.items);}catch(g){s.current&&!u.signal.aborted&&n(g instanceof Error?g.message:"Failed to load repos");}finally{s.current&&!u.signal.aborted&&e(false);}},[]);return react.useEffect(()=>(s.current=true,i(),()=>{s.current=false,a.current?.abort();}),[i]),{repos:l,loading:p,error:r,refresh:i}}function rt(f){return Object.entries(f).map(([t,o])=>{let l=o.indexOf(":"),c=l>0?o.slice(0,l):"100644",p=l>0?o.slice(l+1):o;return {path:t,mode:c,cid:p,isDir:c==="040000"}}).sort((t,o)=>t.isDir!==o.isDir?t.isDir?-1:1:t.path.localeCompare(o.path))}function nt(f,t,o="main"){let l=d(f),[c,p]=react.useState([]),[e,r]=react.useState(false),[n,s]=react.useState(null),a=react.useRef(true),i=react.useCallback(async()=>{if(t)try{a.current&&(r(!0),s(null));let{tree:g}=await l.getTree(t,o);a.current&&p(rt(g.entries));}catch(g){a.current&&s(g instanceof Error?g.message:"Failed to load tree");}finally{a.current&&r(false);}},[l,t,o]);react.useEffect(()=>(a.current=true,i(),()=>{a.current=false;}),[i]);let u=react.useCallback(async g=>{if(!t)throw new Error("No repo selected");return l.getBlob(t,g)},[l,t]);return {entries:c,loading:e,error:n,refresh:i,getFileContent:u}}function it(f){let t=d(f),[o,l]=react.useState(false),[c,p]=react.useState(null),e=react.useRef(true);return react.useEffect(()=>(e.current=true,()=>{e.current=false;}),[]),{push:react.useCallback(async(n,s,a,i)=>{try{return e.current&&(l(!0),p(null)),await t.push(n,{files:s,message:a,branch:i})}catch(u){let g=u instanceof Error?u.message:"Push failed";return e.current&&p(g),null}finally{e.current&&l(false);}},[t]),pushing:o,error:c}}function ut(f,t={}){let{pageSize:o=50,owner:l}=t,c=d(f),[p,e]=react.useState([]),[r,n]=react.useState(null),[s,a]=react.useState(false),[i,u]=react.useState(null),g=react.useRef(null),m=react.useRef(true),h=react.useCallback(async(W,G=false)=>{a(true),u(null);try{let S=await c.listRepos(l,{limit:o,cursor:W||void 0});m.current&&(e(Y=>G?[...Y,...S.items]:S.items),n(S.pagination),g.current=S.pagination.next_cursor);}catch(S){m.current&&u(S.message);}finally{m.current&&a(false);}},[c,l,o]),y=react.useCallback(async()=>{!g.current||s||await h(g.current,true);},[h,s]),k=react.useCallback(async()=>{g.current=null,await h(void 0,false);},[h]);return react.useEffect(()=>(m.current=true,h(),()=>{m.current=false;}),[h]),{repos:p,hasMore:r?.has_more??false,total:r?.total??0,loading:s,error:i,loadMore:y,reset:k,pagination:r}}var $="stacknet-rack-apikey";function ft(f){let t=f.stacknetUrl||f.apiBaseUrl,[o,l]=react.useState({authenticated:false}),[c,p]=react.useState(null),[e,r]=react.useState(false),n=react.useCallback(u=>({"Content-Type":"application/json",...u||f.apiKey?{Authorization:`Bearer ${u||f.apiKey}`}:{}}),[f.apiKey]),s=react.useCallback(async u=>{r(true);try{let g=await fetch(`${t}/health`,{headers:n(u)});if(!g.ok)throw new Error(`Authentication failed: ${g.status}`);let m={authenticated:!0,apiKey:u,permission:u.startsWith("gk_")?"write":"read"};l(m);try{localStorage.setItem($,u);}catch{}return m}catch(g){throw l({authenticated:false}),g}finally{r(false);}},[t,n]),a=react.useCallback(()=>{l({authenticated:false}),p(null);try{localStorage.removeItem($);}catch{}},[]),i=react.useCallback(async()=>{let u=o.apiKey||f.apiKey;if(!u)return null;try{let g=await fetch(`${t}/network/usage`,{headers:n(u)});if(!g.ok)return null;let m=await g.json(),h={planAllocation:m.plan_allocation??m.planAllocation??0,inferenceUsed:m.inference_used??m.inferenceUsed??0,ledgerSpent:m.ledger_spent??m.ledgerSpent??0,totalUsed:m.total_used??m.totalUsed??0,remaining:m.remaining??0,percent:m.percent??0,exceeded:m.exceeded??!1};return p(h),h}catch{return null}},[o.apiKey,f.apiKey,t,n]);return react.useEffect(()=>{let u=f.apiKey;if(u){l({authenticated:true,apiKey:u,permission:u.startsWith("gk_")?"write":"read"});return}try{let g=localStorage.getItem($);g&&l({authenticated:!0,apiKey:g,permission:g.startsWith("gk_")?"write":"read"});}catch{}},[f.apiKey]),{session:o,budget:c,loading:e,login:s,logout:a,refreshBudget:i}}var D=1e3,z=1e3,F=100;function J(f,t){if(f==="skill"){let c=F+Math.ceil(t/4);return {type:f,totalBytes:t,totalMegabytes:t/1e6,baseCost:c,multiplier:D,registrationCostTokens:c*D}}let o=Math.ceil(t/1e6),l=F+o;return {type:f,totalBytes:t,totalMegabytes:o,baseCost:l,multiplier:z,registrationCostTokens:l*z}}function gt(f){let t=f.stacknetUrl||f.apiBaseUrl,o=f.apiKey,[l,c]=react.useState(false),[p,e]=react.useState(null),r=react.useCallback(()=>{if(!o)throw new Error("API key required for registration. Call login() first.");return {"Content-Type":"application/json",Authorization:`Bearer ${o}`}},[o]),n=react.useCallback(async a=>{c(true),e(null);try{let i=await fetch(`${t}/skills`,{method:"POST",headers:r(),body:JSON.stringify(a)});if(!i.ok){let u=await i.json().catch(()=>({error:`HTTP ${i.status}`}));throw new Error(u.error||`Registration failed: ${i.status}`)}return await i.json()}catch(i){throw e(i.message),i}finally{c(false);}},[t,r]),s=react.useCallback(async a=>{c(true),e(null);try{let i=await fetch(`${t}/tensors`,{method:"POST",headers:r(),body:JSON.stringify(a)});if(!i.ok){let u=await i.json().catch(()=>({error:`HTTP ${i.status}`}));throw new Error(u.error||`Registration failed: ${i.status}`)}return await i.json()}catch(i){throw e(i.message),i}finally{c(false);}},[t,r]);return {registerSkill:n,registerTensor:s,estimateCost:J,registering:l,error:p}}function Rt(f,t){let o=d(f),[l,c]=react.useState({meta:null,tokenCount:null,usageCount:null}),[p,e]=react.useState(false),[r,n]=react.useState(null),s=react.useRef(true),a=react.useCallback(async()=>{if(t){e(true),n(null);try{let i=await o.getSkillStats(t);s.current&&c(i);}catch(i){s.current&&n(i.message);}finally{s.current&&e(false);}}},[o,t]);return react.useEffect(()=>(s.current=true,a(),()=>{s.current=false;}),[a]),{stats:l,loading:p,error:r,refresh:a}}function St(f,t){let o=d(f),[l,c]=react.useState({meta:null,sizeMB:null}),[p,e]=react.useState(false),[r,n]=react.useState(null),s=react.useRef(true),a=react.useCallback(async()=>{if(t){e(true),n(null);try{let i=await o.getTensorStats(t);s.current&&c(i);}catch(i){s.current&&n(i.message);}finally{s.current&&e(false);}}},[o,t]);return react.useEffect(()=>(s.current=true,a(),()=>{s.current=false;}),[a]),{stats:l,loading:p,error:r,refresh:a}}function Tt(f){let t=d(f),[o,l]=react.useState(null),[c,p]=react.useState(false),[e,r]=react.useState(null),n=react.useRef(true),s=react.useCallback(async()=>{p(true),r(null);try{let a=await t.getNetworkStats();n.current&&l(a);}catch(a){n.current&&r(a.message);}finally{n.current&&p(false);}},[t]);return react.useEffect(()=>(n.current=true,s(),()=>{n.current=false;}),[s]),{stats:o,loading:c,error:e,refresh:s}}function Et(f,t=5,o=1){let l=d(f),[c,p]=react.useState([]),[e,r]=react.useState(null),[n,s]=react.useState(false),[a,i]=react.useState(null),u=react.useRef(true),g=react.useRef(null),m=react.useCallback(async y=>{s(true),i(null),g.current=null;try{let k=await l.getTrending(t,y??o);u.current&&(p(k.items),r(k.pagination),g.current=k.pagination.next_cursor);}catch(k){u.current&&i(k.message);}finally{u.current&&s(false);}},[l,t,o]),h=react.useCallback(async()=>{if(!(!g.current||n)){s(true);try{let y=await l.getTrending(t,o,g.current);u.current&&(p(k=>[...k,...y.items]),r(y.pagination),g.current=y.pagination.next_cursor);}catch(y){u.current&&i(y.message);}finally{u.current&&s(false);}}},[l,t,o,n]);return react.useEffect(()=>(u.current=true,m(),()=>{u.current=false;}),[m]),{repos:c,hasMore:e?.has_more??false,total:e?.total??0,loading:n,error:a,refresh:m,loadMore:h}}function xt(f,t){let o=d(f),[l,c]=react.useState({stars:0,starred:false,repo_id:t||""}),[p,e]=react.useState(false),[r,n]=react.useState(null),s=react.useRef(true),a=react.useCallback(async()=>{if(t)try{let u=await o.getStarInfo(t);s.current&&c(u);}catch{}},[o,t]);react.useEffect(()=>(s.current=true,a(),()=>{s.current=false;}),[a]);let i=react.useCallback(async()=>{if(t){e(true),n(null);try{let u=l.starred?await o.unstarRepo(t):await o.starRepo(t);s.current&&c({stars:u.stars,starred:u.starred,repo_id:t});}catch(u){s.current&&n(u.message);}finally{s.current&&e(false);}}},[o,t,l.starred]);return {...l,loading:p,error:r,toggle:i,refresh:a}}exports.estimateCost=J;exports.useNetworkStats=Tt;exports.usePaginatedRepos=ut;exports.useRackClient=d;exports.useRackRegister=gt;exports.useRackSession=ft;exports.useRepoPush=it;exports.useRepoTree=nt;exports.useRepos=Z;exports.useSkillStats=Rt;exports.useStar=xt;exports.useTensorStats=St;exports.useTrending=Et;
@@ -1,7 +1,7 @@
1
- import { RepoInfo, InitResult, RepoFile, PushResult, RepoTree, RepoCommit, DiffEntry, StarResult, StarInfo, SkillStats, TensorStats, NetworkStats, TrendingRepo, RackConfig, TreeEntry, RackSession, TokenBudget, CostEstimate, SkillRegistrationInput, SkillRegistrationResult, TensorRegistrationInput, TensorRegistrationResult } from '../types/index.cjs';
1
+ import { PaginationParams, PaginatedResult, RepoInfo, InitResult, RepoFile, PushResult, RepoTree, RepoCommit, DiffEntry, StarResult, StarInfo, SkillStats, TensorStats, NetworkStats, TrendingRepo, RackConfig, TreeEntry, PaginationInfo, RackSession, TokenBudget, CostEstimate, SkillRegistrationInput, SkillRegistrationResult, TensorRegistrationInput, TensorRegistrationResult } from '../types/index.cjs';
2
2
 
3
3
  interface RackClient {
4
- listRepos: (owner?: string) => Promise<RepoInfo[]>;
4
+ listRepos: (owner?: string, pagination?: PaginationParams) => Promise<PaginatedResult<RepoInfo>>;
5
5
  initRepo: (params: {
6
6
  name: string;
7
7
  description?: string;
@@ -36,7 +36,7 @@ interface RackClient {
36
36
  getSkillUsageCount: (skillId: string) => Promise<number | null>;
37
37
  getTensorStats: (repoId: string) => Promise<TensorStats>;
38
38
  getNetworkStats: () => Promise<NetworkStats | null>;
39
- getTrending: (limit?: number, days?: number) => Promise<TrendingRepo[]>;
39
+ getTrending: (limit?: number, days?: number, cursor?: string) => Promise<PaginatedResult<TrendingRepo>>;
40
40
  }
41
41
  /**
42
42
  * Low-level hook returning a rack API client.
@@ -68,6 +68,40 @@ interface UseRepoPushReturn {
68
68
  }
69
69
  declare function useRepoPush(config: RackConfig): UseRepoPushReturn;
70
70
 
71
+ interface UsePaginatedReposOptions {
72
+ /** Items per page (default 50, max 100) */
73
+ pageSize?: number;
74
+ /** Filter by owner */
75
+ owner?: string;
76
+ }
77
+ interface UsePaginatedReposReturn {
78
+ /** Current page of repos */
79
+ repos: RepoInfo[];
80
+ /** Whether more pages exist */
81
+ hasMore: boolean;
82
+ /** Total repos across all pages */
83
+ total: number;
84
+ /** Loading state */
85
+ loading: boolean;
86
+ /** Error message */
87
+ error: string | null;
88
+ /** Load the next page (appends to existing repos) */
89
+ loadMore: () => Promise<void>;
90
+ /** Reset to the first page */
91
+ reset: () => Promise<void>;
92
+ /** Pagination metadata from the server */
93
+ pagination: PaginationInfo | null;
94
+ }
95
+ /**
96
+ * Cursor-based paginated repo listing.
97
+ * Uses opaque server-issued cursors — no page number enumeration possible.
98
+ *
99
+ * Usage:
100
+ * const { repos, hasMore, loadMore, loading } = usePaginatedRepos(config, { pageSize: 25 });
101
+ * // repos grows as loadMore() is called — infinite scroll pattern
102
+ */
103
+ declare function usePaginatedRepos(config: RackConfig, options?: UsePaginatedReposOptions): UsePaginatedReposReturn;
104
+
71
105
  /**
72
106
  * Session hook for authenticated Rack operations.
73
107
  * Manages API key persistence, session validation, and token budget.
@@ -131,14 +165,17 @@ declare function useNetworkStats(config: RackConfig): {
131
165
  };
132
166
 
133
167
  /**
134
- * Fetch trending repos with time-windowed scoring.
168
+ * Fetch trending repos with time-windowed scoring and cursor pagination.
135
169
  * Score = (usage × 100) + (stars × 1)
136
170
  */
137
171
  declare function useTrending(config: RackConfig, limit?: number, days?: number): {
138
172
  repos: TrendingRepo[];
173
+ hasMore: boolean;
174
+ total: number;
139
175
  loading: boolean;
140
176
  error: string | null;
141
177
  refresh: (newDays?: number) => Promise<void>;
178
+ loadMore: () => Promise<void>;
142
179
  };
143
180
 
144
181
  /**
@@ -155,4 +192,4 @@ declare function useStar(config: RackConfig, repoId: string | null): {
155
192
  repo_id: string;
156
193
  };
157
194
 
158
- export { type RackClient, estimateCost, useNetworkStats, useRackClient, useRackRegister, useRackSession, useRepoPush, useRepoTree, useRepos, useSkillStats, useStar, useTensorStats, useTrending };
195
+ export { type RackClient, estimateCost, useNetworkStats, usePaginatedRepos, useRackClient, useRackRegister, useRackSession, useRepoPush, useRepoTree, useRepos, useSkillStats, useStar, useTensorStats, useTrending };
@@ -1,7 +1,7 @@
1
- import { RepoInfo, InitResult, RepoFile, PushResult, RepoTree, RepoCommit, DiffEntry, StarResult, StarInfo, SkillStats, TensorStats, NetworkStats, TrendingRepo, RackConfig, TreeEntry, RackSession, TokenBudget, CostEstimate, SkillRegistrationInput, SkillRegistrationResult, TensorRegistrationInput, TensorRegistrationResult } from '../types/index.js';
1
+ import { PaginationParams, PaginatedResult, RepoInfo, InitResult, RepoFile, PushResult, RepoTree, RepoCommit, DiffEntry, StarResult, StarInfo, SkillStats, TensorStats, NetworkStats, TrendingRepo, RackConfig, TreeEntry, PaginationInfo, RackSession, TokenBudget, CostEstimate, SkillRegistrationInput, SkillRegistrationResult, TensorRegistrationInput, TensorRegistrationResult } from '../types/index.js';
2
2
 
3
3
  interface RackClient {
4
- listRepos: (owner?: string) => Promise<RepoInfo[]>;
4
+ listRepos: (owner?: string, pagination?: PaginationParams) => Promise<PaginatedResult<RepoInfo>>;
5
5
  initRepo: (params: {
6
6
  name: string;
7
7
  description?: string;
@@ -36,7 +36,7 @@ interface RackClient {
36
36
  getSkillUsageCount: (skillId: string) => Promise<number | null>;
37
37
  getTensorStats: (repoId: string) => Promise<TensorStats>;
38
38
  getNetworkStats: () => Promise<NetworkStats | null>;
39
- getTrending: (limit?: number, days?: number) => Promise<TrendingRepo[]>;
39
+ getTrending: (limit?: number, days?: number, cursor?: string) => Promise<PaginatedResult<TrendingRepo>>;
40
40
  }
41
41
  /**
42
42
  * Low-level hook returning a rack API client.
@@ -68,6 +68,40 @@ interface UseRepoPushReturn {
68
68
  }
69
69
  declare function useRepoPush(config: RackConfig): UseRepoPushReturn;
70
70
 
71
+ interface UsePaginatedReposOptions {
72
+ /** Items per page (default 50, max 100) */
73
+ pageSize?: number;
74
+ /** Filter by owner */
75
+ owner?: string;
76
+ }
77
+ interface UsePaginatedReposReturn {
78
+ /** Current page of repos */
79
+ repos: RepoInfo[];
80
+ /** Whether more pages exist */
81
+ hasMore: boolean;
82
+ /** Total repos across all pages */
83
+ total: number;
84
+ /** Loading state */
85
+ loading: boolean;
86
+ /** Error message */
87
+ error: string | null;
88
+ /** Load the next page (appends to existing repos) */
89
+ loadMore: () => Promise<void>;
90
+ /** Reset to the first page */
91
+ reset: () => Promise<void>;
92
+ /** Pagination metadata from the server */
93
+ pagination: PaginationInfo | null;
94
+ }
95
+ /**
96
+ * Cursor-based paginated repo listing.
97
+ * Uses opaque server-issued cursors — no page number enumeration possible.
98
+ *
99
+ * Usage:
100
+ * const { repos, hasMore, loadMore, loading } = usePaginatedRepos(config, { pageSize: 25 });
101
+ * // repos grows as loadMore() is called — infinite scroll pattern
102
+ */
103
+ declare function usePaginatedRepos(config: RackConfig, options?: UsePaginatedReposOptions): UsePaginatedReposReturn;
104
+
71
105
  /**
72
106
  * Session hook for authenticated Rack operations.
73
107
  * Manages API key persistence, session validation, and token budget.
@@ -131,14 +165,17 @@ declare function useNetworkStats(config: RackConfig): {
131
165
  };
132
166
 
133
167
  /**
134
- * Fetch trending repos with time-windowed scoring.
168
+ * Fetch trending repos with time-windowed scoring and cursor pagination.
135
169
  * Score = (usage × 100) + (stars × 1)
136
170
  */
137
171
  declare function useTrending(config: RackConfig, limit?: number, days?: number): {
138
172
  repos: TrendingRepo[];
173
+ hasMore: boolean;
174
+ total: number;
139
175
  loading: boolean;
140
176
  error: string | null;
141
177
  refresh: (newDays?: number) => Promise<void>;
178
+ loadMore: () => Promise<void>;
142
179
  };
143
180
 
144
181
  /**
@@ -155,4 +192,4 @@ declare function useStar(config: RackConfig, repoId: string | null): {
155
192
  repo_id: string;
156
193
  };
157
194
 
158
- export { type RackClient, estimateCost, useNetworkStats, useRackClient, useRackRegister, useRackSession, useRepoPush, useRepoTree, useRepos, useSkillStats, useStar, useTensorStats, useTrending };
195
+ export { type RackClient, estimateCost, useNetworkStats, usePaginatedRepos, useRackClient, useRackRegister, useRackSession, useRepoPush, useRepoTree, useRepos, useSkillStats, useStar, useTensorStats, useTrending };
@@ -1 +1 @@
1
- import {useMemo,useRef,useState,useCallback,useEffect}from'react';async function d(u,t,i,l){let c={"Content-Type":"application/json",...i?.headers};l&&(c.Authorization=`Bearer ${l}`);let g=await fetch(`${u}${t}`,{...i,headers:c});if(!g.ok){let e=`HTTP ${g.status}`;try{let r=await g.json();r.error&&(e=r.error);}catch{}throw new Error(e)}return g.json()}function k(u){let t=u.indexOf(":");return {mode:u.slice(0,t),cid:u.slice(t+1)}}function p(u){let t=u.apiBaseUrl,i=u.authorMid,l=u.ownerMid,c=u.apiKey,g=u.stacknetUrl||u.apiBaseUrl;return useMemo(()=>({async listRepos(e){let r=e||l?`?owner=${encodeURIComponent(e||l)}`:"";return (await d(t,`/api/rack/repos${r}`,void 0,c)).repos||[]},async initRepo(e){return d(t,"/api/rack/init",{method:"POST",body:JSON.stringify({...e,owner_mid:l})},c)},async push(e,r){return d(t,`/api/rack/${e}/push`,{method:"POST",body:JSON.stringify({...r,author_mid:i})},c)},async getTree(e,r="main"){let n=await d(t,`/api/rack/${e}/tree/${r}`,void 0,c);return {tree:n.tree,commit_cid:n.commit_cid}},async getBlob(e,r){return (await d(t,`/api/rack/${e}/blob/${r}`,void 0,c)).content},async getLog(e,r,n){let s=new URLSearchParams;r&&s.set("ref",r),n&&s.set("max_count",String(n));let a=s.toString()?`?${s}`:"";return (await d(t,`/api/rack/${e}/log${a}`,void 0,c)).commits||[]},async getBranches(e){return (await d(t,`/api/rack/${e}/branches`,void 0,c)).branches||[]},async createBranch(e,r,n){return d(t,`/api/rack/${e}/branch`,{method:"POST",body:JSON.stringify({branch_name:r,from_ref:n})},c)},async merge(e,r,n){return d(t,`/api/rack/${e}/merge`,{method:"POST",body:JSON.stringify({source_branch:r,target_branch:n})},c)},async getDiff(e,r,n){return (await d(t,`/api/rack/${e}/diff/${r}/${n}`,void 0,c)).diff?.entries||[]},async starRepo(e){return d(t,`/api/rack/${e}/star`,{method:"POST"},c)},async unstarRepo(e){return d(t,`/api/rack/${e}/star`,{method:"DELETE"},c)},async getStarInfo(e){return d(t,`/api/rack/${e}/stars`,void 0,c)},async getSkillStats(e){let r={meta:null,tokenCount:null,usageCount:null};try{let{tree:n}=await this.getTree(e,"main");if(!n?.entries)return r;if(n.entries["META.json"]){let o=k(n.entries["META.json"]).cid,f=await this.getBlob(e,o);r.meta=JSON.parse(f);}let s=0,a=Object.values(n.entries).map(async o=>{try{let f=k(o).cid,m=await this.getBlob(e,f);s+=m.length;}catch{}});await Promise.all(a),s>0&&(r.tokenCount=Math.ceil(s/4)),r.meta?.skill_id&&(r.usageCount=await this.getSkillUsageCount(r.meta.skill_id));}catch{}return r},async getSkillUsageCount(e){try{let r=await fetch(`${g}/v1/skills/${encodeURIComponent(e)}`);if(r.ok){let s=await r.json();return s.usage_count??s.usageCount??null}let n=await fetch(`${g}/v1/skills?scope=public`);if(n.ok){let a=((await n.json()).skills||[]).find(o=>o.name===e||o.id===e);if(a)return a.usage_count??a.usageCount??0}return 0}catch{return null}},async getTensorStats(e){let r={meta:null,sizeMB:null};try{let{tree:n}=await this.getTree(e,"main");if(!n?.entries)return r;if(n.entries["TENSOR_META.json"]){let s=k(n.entries["TENSOR_META.json"]).cid,a=await this.getBlob(e,s);r.meta=JSON.parse(a),r.sizeMB=r.meta?.tensor_size_mb??null;}}catch{}return r},async getNetworkStats(){try{return (await d(t,"/api/rack/stats",void 0,c)).stats||null}catch{return null}},async getTrending(e=5,r=1){try{return (await d(t,`/api/rack/trending?limit=${e}&days=${r}`,void 0,c)).trending||[]}catch{return []}}}),[t,i,l,c,g])}function J(u){let t=p(u),i=useRef(t);i.current=t;let[l,c]=useState([]),[g,e]=useState(true),[r,n]=useState(null),s=useRef(true),a=useRef(null),o=useCallback(async()=>{a.current?.abort();let f=new AbortController;a.current=f;try{s.current&&(e(!0),n(null));let m=await i.current.listRepos();s.current&&!f.signal.aborted&&c(m);}catch(m){s.current&&!f.signal.aborted&&n(m instanceof Error?m.message:"Failed to load repos");}finally{s.current&&!f.signal.aborted&&e(false);}},[]);return useEffect(()=>(s.current=true,o(),()=>{s.current=false,a.current?.abort();}),[o]),{repos:l,loading:g,error:r,refresh:o}}function H(u){return Object.entries(u).map(([t,i])=>{let l=i.indexOf(":"),c=l>0?i.slice(0,l):"100644",g=l>0?i.slice(l+1):i;return {path:t,mode:c,cid:g,isDir:c==="040000"}}).sort((t,i)=>t.isDir!==i.isDir?t.isDir?-1:1:t.path.localeCompare(i.path))}function W(u,t,i="main"){let l=p(u),[c,g]=useState([]),[e,r]=useState(false),[n,s]=useState(null),a=useRef(true),o=useCallback(async()=>{if(t)try{a.current&&(r(!0),s(null));let{tree:m}=await l.getTree(t,i);a.current&&g(H(m.entries));}catch(m){a.current&&s(m instanceof Error?m.message:"Failed to load tree");}finally{a.current&&r(false);}},[l,t,i]);useEffect(()=>(a.current=true,o(),()=>{a.current=false;}),[o]);let f=useCallback(async m=>{if(!t)throw new Error("No repo selected");return l.getBlob(t,m)},[l,t]);return {entries:c,loading:e,error:n,refresh:o,getFileContent:f}}function Q(u){let t=p(u),[i,l]=useState(false),[c,g]=useState(null),e=useRef(true);return useEffect(()=>(e.current=true,()=>{e.current=false;}),[]),{push:useCallback(async(n,s,a,o)=>{try{return e.current&&(l(!0),g(null)),await t.push(n,{files:s,message:a,branch:o})}catch(f){let m=f instanceof Error?f.message:"Push failed";return e.current&&g(m),null}finally{e.current&&l(false);}},[t]),pushing:i,error:c}}var w="stacknet-rack-apikey";function X(u){let t=u.stacknetUrl||u.apiBaseUrl,[i,l]=useState({authenticated:false}),[c,g]=useState(null),[e,r]=useState(false),n=useCallback(f=>({"Content-Type":"application/json",...f||u.apiKey?{Authorization:`Bearer ${f||u.apiKey}`}:{}}),[u.apiKey]),s=useCallback(async f=>{r(true);try{let m=await fetch(`${t}/health`,{headers:n(f)});if(!m.ok)throw new Error(`Authentication failed: ${m.status}`);let R={authenticated:!0,apiKey:f,permission:f.startsWith("gk_")?"write":"read"};l(R);try{localStorage.setItem(w,f);}catch{}return R}catch(m){throw l({authenticated:false}),m}finally{r(false);}},[t,n]),a=useCallback(()=>{l({authenticated:false}),g(null);try{localStorage.removeItem(w);}catch{}},[]),o=useCallback(async()=>{let f=i.apiKey||u.apiKey;if(!f)return null;try{let m=await fetch(`${t}/network/usage`,{headers:n(f)});if(!m.ok)return null;let R=await m.json(),I={planAllocation:R.plan_allocation??R.planAllocation??0,inferenceUsed:R.inference_used??R.inferenceUsed??0,ledgerSpent:R.ledger_spent??R.ledgerSpent??0,totalUsed:R.total_used??R.totalUsed??0,remaining:R.remaining??0,percent:R.percent??0,exceeded:R.exceeded??!1};return g(I),I}catch{return null}},[i.apiKey,u.apiKey,t,n]);return useEffect(()=>{let f=u.apiKey;if(f){l({authenticated:true,apiKey:f,permission:f.startsWith("gk_")?"write":"read"});return}try{let m=localStorage.getItem(w);m&&l({authenticated:!0,apiKey:m,permission:m.startsWith("gk_")?"write":"read"});}catch{}},[u.apiKey]),{session:i,budget:c,loading:e,login:s,logout:a,refreshBudget:o}}var B=1e3,M=1e3,j=100;function L(u,t){if(u==="skill"){let c=j+Math.ceil(t/4);return {type:u,totalBytes:t,totalMegabytes:t/1e6,baseCost:c,multiplier:B,registrationCostTokens:c*B}}let i=Math.ceil(t/1e6),l=j+i;return {type:u,totalBytes:t,totalMegabytes:i,baseCost:l,multiplier:M,registrationCostTokens:l*M}}function Z(u){let t=u.stacknetUrl||u.apiBaseUrl,i=u.apiKey,[l,c]=useState(false),[g,e]=useState(null),r=useCallback(()=>{if(!i)throw new Error("API key required for registration. Call login() first.");return {"Content-Type":"application/json",Authorization:`Bearer ${i}`}},[i]),n=useCallback(async a=>{c(true),e(null);try{let o=await fetch(`${t}/skills`,{method:"POST",headers:r(),body:JSON.stringify(a)});if(!o.ok){let f=await o.json().catch(()=>({error:`HTTP ${o.status}`}));throw new Error(f.error||`Registration failed: ${o.status}`)}return await o.json()}catch(o){throw e(o.message),o}finally{c(false);}},[t,r]),s=useCallback(async a=>{c(true),e(null);try{let o=await fetch(`${t}/tensors`,{method:"POST",headers:r(),body:JSON.stringify(a)});if(!o.ok){let f=await o.json().catch(()=>({error:`HTTP ${o.status}`}));throw new Error(f.error||`Registration failed: ${o.status}`)}return await o.json()}catch(o){throw e(o.message),o}finally{c(false);}},[t,r]);return {registerSkill:n,registerTensor:s,estimateCost:L,registering:l,error:g}}function nt(u,t){let i=p(u),[l,c]=useState({meta:null,tokenCount:null,usageCount:null}),[g,e]=useState(false),[r,n]=useState(null),s=useRef(true),a=useCallback(async()=>{if(t){e(true),n(null);try{let o=await i.getSkillStats(t);s.current&&c(o);}catch(o){s.current&&n(o.message);}finally{s.current&&e(false);}}},[i,t]);return useEffect(()=>(s.current=true,a(),()=>{s.current=false;}),[a]),{stats:l,loading:g,error:r,refresh:a}}function it(u,t){let i=p(u),[l,c]=useState({meta:null,sizeMB:null}),[g,e]=useState(false),[r,n]=useState(null),s=useRef(true),a=useCallback(async()=>{if(t){e(true),n(null);try{let o=await i.getTensorStats(t);s.current&&c(o);}catch(o){s.current&&n(o.message);}finally{s.current&&e(false);}}},[i,t]);return useEffect(()=>(s.current=true,a(),()=>{s.current=false;}),[a]),{stats:l,loading:g,error:r,refresh:a}}function ft(u){let t=p(u),[i,l]=useState(null),[c,g]=useState(false),[e,r]=useState(null),n=useRef(true),s=useCallback(async()=>{g(true),r(null);try{let a=await t.getNetworkStats();n.current&&l(a);}catch(a){n.current&&r(a.message);}finally{n.current&&g(false);}},[t]);return useEffect(()=>(n.current=true,s(),()=>{n.current=false;}),[s]),{stats:i,loading:c,error:e,refresh:s}}function dt(u,t=5,i=1){let l=p(u),[c,g]=useState([]),[e,r]=useState(false),[n,s]=useState(null),a=useRef(true),o=useCallback(async f=>{r(true),s(null);try{let m=await l.getTrending(t,f??i);a.current&&g(m);}catch(m){a.current&&s(m.message);}finally{a.current&&r(false);}},[l,t,i]);return useEffect(()=>(a.current=true,o(),()=>{a.current=false;}),[o]),{repos:c,loading:e,error:n,refresh:o}}function kt(u,t){let i=p(u),[l,c]=useState({stars:0,starred:false,repo_id:t||""}),[g,e]=useState(false),[r,n]=useState(null),s=useRef(true),a=useCallback(async()=>{if(t)try{let f=await i.getStarInfo(t);s.current&&c(f);}catch{}},[i,t]);useEffect(()=>(s.current=true,a(),()=>{s.current=false;}),[a]);let o=useCallback(async()=>{if(t){e(true),n(null);try{let f=l.starred?await i.unstarRepo(t):await i.starRepo(t);s.current&&c({stars:f.stars,starred:f.starred,repo_id:t});}catch(f){s.current&&n(f.message);}finally{s.current&&e(false);}}},[i,t,l.starred]);return {...l,loading:g,error:r,toggle:o,refresh:a}}export{L as estimateCost,ft as useNetworkStats,p as useRackClient,Z as useRackRegister,X as useRackSession,Q as useRepoPush,W as useRepoTree,J as useRepos,nt as useSkillStats,kt as useStar,it as useTensorStats,dt as useTrending};
1
+ import {useMemo,useRef,useState,useCallback,useEffect}from'react';async function R(f,t,o,l){let c={"Content-Type":"application/json",...o?.headers};l&&(c.Authorization=`Bearer ${l}`);let p=await fetch(`${f}${t}`,{...o,headers:c});if(!p.ok){let e=`HTTP ${p.status}`;try{let r=await p.json();r.error&&(e=r.error);}catch{}throw new Error(e)}return p.json()}function T(f){let t=f.indexOf(":");return {mode:f.slice(0,t),cid:f.slice(t+1)}}function d(f){let t=f.apiBaseUrl,o=f.authorMid,l=f.ownerMid,c=f.apiKey,p=f.stacknetUrl||f.apiBaseUrl;return useMemo(()=>({async listRepos(e,r){let n=new URLSearchParams;(e||l)&&n.set("owner",e||l),r?.limit&&n.set("limit",String(r.limit)),r?.cursor&&n.set("cursor",r.cursor);let s=n.toString()?`?${n}`:"",a=await R(t,`/api/rack/repos${s}`,void 0,c);return {items:a.repos||[],pagination:a.pagination||{total:(a.repos||[]).length,limit:50,has_more:false,next_cursor:null}}},async initRepo(e){return R(t,"/api/rack/init",{method:"POST",body:JSON.stringify({...e,owner_mid:l})},c)},async push(e,r){return R(t,`/api/rack/${e}/push`,{method:"POST",body:JSON.stringify({...r,author_mid:o})},c)},async getTree(e,r="main"){let n=await R(t,`/api/rack/${e}/tree/${r}`,void 0,c);return {tree:n.tree,commit_cid:n.commit_cid}},async getBlob(e,r){return (await R(t,`/api/rack/${e}/blob/${r}`,void 0,c)).content},async getLog(e,r,n){let s=new URLSearchParams;r&&s.set("ref",r),n&&s.set("max_count",String(n));let a=s.toString()?`?${s}`:"";return (await R(t,`/api/rack/${e}/log${a}`,void 0,c)).commits||[]},async getBranches(e){return (await R(t,`/api/rack/${e}/branches`,void 0,c)).branches||[]},async createBranch(e,r,n){return R(t,`/api/rack/${e}/branch`,{method:"POST",body:JSON.stringify({branch_name:r,from_ref:n})},c)},async merge(e,r,n){return R(t,`/api/rack/${e}/merge`,{method:"POST",body:JSON.stringify({source_branch:r,target_branch:n})},c)},async getDiff(e,r,n){return (await R(t,`/api/rack/${e}/diff/${r}/${n}`,void 0,c)).diff?.entries||[]},async starRepo(e){return R(t,`/api/rack/${e}/star`,{method:"POST"},c)},async unstarRepo(e){return R(t,`/api/rack/${e}/star`,{method:"DELETE"},c)},async getStarInfo(e){return R(t,`/api/rack/${e}/stars`,void 0,c)},async getSkillStats(e){let r={meta:null,tokenCount:null,usageCount:null};try{let{tree:n}=await this.getTree(e,"main");if(!n?.entries)return r;if(n.entries["META.json"]){let i=T(n.entries["META.json"]).cid,u=await this.getBlob(e,i);r.meta=JSON.parse(u);}let s=0,a=Object.values(n.entries).map(async i=>{try{let u=T(i).cid,g=await this.getBlob(e,u);s+=g.length;}catch{}});await Promise.all(a),s>0&&(r.tokenCount=Math.ceil(s/4)),r.meta?.skill_id&&(r.usageCount=await this.getSkillUsageCount(r.meta.skill_id));}catch{}return r},async getSkillUsageCount(e){try{let r=await fetch(`${p}/v1/skills/${encodeURIComponent(e)}`);if(r.ok){let s=await r.json();return s.usage_count??s.usageCount??null}let n=await fetch(`${p}/v1/skills?scope=public`);if(n.ok){let a=((await n.json()).skills||[]).find(i=>i.name===e||i.id===e);if(a)return a.usage_count??a.usageCount??0}return 0}catch{return null}},async getTensorStats(e){let r={meta:null,sizeMB:null};try{let{tree:n}=await this.getTree(e,"main");if(!n?.entries)return r;if(n.entries["TENSOR_META.json"]){let s=T(n.entries["TENSOR_META.json"]).cid,a=await this.getBlob(e,s);r.meta=JSON.parse(a),r.sizeMB=r.meta?.tensor_size_mb??null;}}catch{}return r},async getNetworkStats(){try{return (await R(t,"/api/rack/stats",void 0,c)).stats||null}catch{return null}},async getTrending(e=5,r=1,n){try{let s=new URLSearchParams({limit:String(e),days:String(r)});n&&s.set("cursor",n);let a=await R(t,`/api/rack/trending?${s}`,void 0,c);return {items:a.trending||[],pagination:a.pagination||{total:(a.trending||[]).length,limit:e,has_more:!1,next_cursor:null}}}catch{return {items:[],pagination:{total:0,limit:e,has_more:false,next_cursor:null}}}}}),[t,o,l,c,p])}function Z(f){let t=d(f),o=useRef(t);o.current=t;let[l,c]=useState([]),[p,e]=useState(true),[r,n]=useState(null),s=useRef(true),a=useRef(null),i=useCallback(async()=>{a.current?.abort();let u=new AbortController;a.current=u;try{s.current&&(e(!0),n(null));let g=await o.current.listRepos();s.current&&!u.signal.aborted&&c(g.items);}catch(g){s.current&&!u.signal.aborted&&n(g instanceof Error?g.message:"Failed to load repos");}finally{s.current&&!u.signal.aborted&&e(false);}},[]);return useEffect(()=>(s.current=true,i(),()=>{s.current=false,a.current?.abort();}),[i]),{repos:l,loading:p,error:r,refresh:i}}function rt(f){return Object.entries(f).map(([t,o])=>{let l=o.indexOf(":"),c=l>0?o.slice(0,l):"100644",p=l>0?o.slice(l+1):o;return {path:t,mode:c,cid:p,isDir:c==="040000"}}).sort((t,o)=>t.isDir!==o.isDir?t.isDir?-1:1:t.path.localeCompare(o.path))}function nt(f,t,o="main"){let l=d(f),[c,p]=useState([]),[e,r]=useState(false),[n,s]=useState(null),a=useRef(true),i=useCallback(async()=>{if(t)try{a.current&&(r(!0),s(null));let{tree:g}=await l.getTree(t,o);a.current&&p(rt(g.entries));}catch(g){a.current&&s(g instanceof Error?g.message:"Failed to load tree");}finally{a.current&&r(false);}},[l,t,o]);useEffect(()=>(a.current=true,i(),()=>{a.current=false;}),[i]);let u=useCallback(async g=>{if(!t)throw new Error("No repo selected");return l.getBlob(t,g)},[l,t]);return {entries:c,loading:e,error:n,refresh:i,getFileContent:u}}function it(f){let t=d(f),[o,l]=useState(false),[c,p]=useState(null),e=useRef(true);return useEffect(()=>(e.current=true,()=>{e.current=false;}),[]),{push:useCallback(async(n,s,a,i)=>{try{return e.current&&(l(!0),p(null)),await t.push(n,{files:s,message:a,branch:i})}catch(u){let g=u instanceof Error?u.message:"Push failed";return e.current&&p(g),null}finally{e.current&&l(false);}},[t]),pushing:o,error:c}}function ut(f,t={}){let{pageSize:o=50,owner:l}=t,c=d(f),[p,e]=useState([]),[r,n]=useState(null),[s,a]=useState(false),[i,u]=useState(null),g=useRef(null),m=useRef(true),h=useCallback(async(W,G=false)=>{a(true),u(null);try{let S=await c.listRepos(l,{limit:o,cursor:W||void 0});m.current&&(e(Y=>G?[...Y,...S.items]:S.items),n(S.pagination),g.current=S.pagination.next_cursor);}catch(S){m.current&&u(S.message);}finally{m.current&&a(false);}},[c,l,o]),y=useCallback(async()=>{!g.current||s||await h(g.current,true);},[h,s]),k=useCallback(async()=>{g.current=null,await h(void 0,false);},[h]);return useEffect(()=>(m.current=true,h(),()=>{m.current=false;}),[h]),{repos:p,hasMore:r?.has_more??false,total:r?.total??0,loading:s,error:i,loadMore:y,reset:k,pagination:r}}var $="stacknet-rack-apikey";function ft(f){let t=f.stacknetUrl||f.apiBaseUrl,[o,l]=useState({authenticated:false}),[c,p]=useState(null),[e,r]=useState(false),n=useCallback(u=>({"Content-Type":"application/json",...u||f.apiKey?{Authorization:`Bearer ${u||f.apiKey}`}:{}}),[f.apiKey]),s=useCallback(async u=>{r(true);try{let g=await fetch(`${t}/health`,{headers:n(u)});if(!g.ok)throw new Error(`Authentication failed: ${g.status}`);let m={authenticated:!0,apiKey:u,permission:u.startsWith("gk_")?"write":"read"};l(m);try{localStorage.setItem($,u);}catch{}return m}catch(g){throw l({authenticated:false}),g}finally{r(false);}},[t,n]),a=useCallback(()=>{l({authenticated:false}),p(null);try{localStorage.removeItem($);}catch{}},[]),i=useCallback(async()=>{let u=o.apiKey||f.apiKey;if(!u)return null;try{let g=await fetch(`${t}/network/usage`,{headers:n(u)});if(!g.ok)return null;let m=await g.json(),h={planAllocation:m.plan_allocation??m.planAllocation??0,inferenceUsed:m.inference_used??m.inferenceUsed??0,ledgerSpent:m.ledger_spent??m.ledgerSpent??0,totalUsed:m.total_used??m.totalUsed??0,remaining:m.remaining??0,percent:m.percent??0,exceeded:m.exceeded??!1};return p(h),h}catch{return null}},[o.apiKey,f.apiKey,t,n]);return useEffect(()=>{let u=f.apiKey;if(u){l({authenticated:true,apiKey:u,permission:u.startsWith("gk_")?"write":"read"});return}try{let g=localStorage.getItem($);g&&l({authenticated:!0,apiKey:g,permission:g.startsWith("gk_")?"write":"read"});}catch{}},[f.apiKey]),{session:o,budget:c,loading:e,login:s,logout:a,refreshBudget:i}}var D=1e3,z=1e3,F=100;function J(f,t){if(f==="skill"){let c=F+Math.ceil(t/4);return {type:f,totalBytes:t,totalMegabytes:t/1e6,baseCost:c,multiplier:D,registrationCostTokens:c*D}}let o=Math.ceil(t/1e6),l=F+o;return {type:f,totalBytes:t,totalMegabytes:o,baseCost:l,multiplier:z,registrationCostTokens:l*z}}function gt(f){let t=f.stacknetUrl||f.apiBaseUrl,o=f.apiKey,[l,c]=useState(false),[p,e]=useState(null),r=useCallback(()=>{if(!o)throw new Error("API key required for registration. Call login() first.");return {"Content-Type":"application/json",Authorization:`Bearer ${o}`}},[o]),n=useCallback(async a=>{c(true),e(null);try{let i=await fetch(`${t}/skills`,{method:"POST",headers:r(),body:JSON.stringify(a)});if(!i.ok){let u=await i.json().catch(()=>({error:`HTTP ${i.status}`}));throw new Error(u.error||`Registration failed: ${i.status}`)}return await i.json()}catch(i){throw e(i.message),i}finally{c(false);}},[t,r]),s=useCallback(async a=>{c(true),e(null);try{let i=await fetch(`${t}/tensors`,{method:"POST",headers:r(),body:JSON.stringify(a)});if(!i.ok){let u=await i.json().catch(()=>({error:`HTTP ${i.status}`}));throw new Error(u.error||`Registration failed: ${i.status}`)}return await i.json()}catch(i){throw e(i.message),i}finally{c(false);}},[t,r]);return {registerSkill:n,registerTensor:s,estimateCost:J,registering:l,error:p}}function Rt(f,t){let o=d(f),[l,c]=useState({meta:null,tokenCount:null,usageCount:null}),[p,e]=useState(false),[r,n]=useState(null),s=useRef(true),a=useCallback(async()=>{if(t){e(true),n(null);try{let i=await o.getSkillStats(t);s.current&&c(i);}catch(i){s.current&&n(i.message);}finally{s.current&&e(false);}}},[o,t]);return useEffect(()=>(s.current=true,a(),()=>{s.current=false;}),[a]),{stats:l,loading:p,error:r,refresh:a}}function St(f,t){let o=d(f),[l,c]=useState({meta:null,sizeMB:null}),[p,e]=useState(false),[r,n]=useState(null),s=useRef(true),a=useCallback(async()=>{if(t){e(true),n(null);try{let i=await o.getTensorStats(t);s.current&&c(i);}catch(i){s.current&&n(i.message);}finally{s.current&&e(false);}}},[o,t]);return useEffect(()=>(s.current=true,a(),()=>{s.current=false;}),[a]),{stats:l,loading:p,error:r,refresh:a}}function Tt(f){let t=d(f),[o,l]=useState(null),[c,p]=useState(false),[e,r]=useState(null),n=useRef(true),s=useCallback(async()=>{p(true),r(null);try{let a=await t.getNetworkStats();n.current&&l(a);}catch(a){n.current&&r(a.message);}finally{n.current&&p(false);}},[t]);return useEffect(()=>(n.current=true,s(),()=>{n.current=false;}),[s]),{stats:o,loading:c,error:e,refresh:s}}function Et(f,t=5,o=1){let l=d(f),[c,p]=useState([]),[e,r]=useState(null),[n,s]=useState(false),[a,i]=useState(null),u=useRef(true),g=useRef(null),m=useCallback(async y=>{s(true),i(null),g.current=null;try{let k=await l.getTrending(t,y??o);u.current&&(p(k.items),r(k.pagination),g.current=k.pagination.next_cursor);}catch(k){u.current&&i(k.message);}finally{u.current&&s(false);}},[l,t,o]),h=useCallback(async()=>{if(!(!g.current||n)){s(true);try{let y=await l.getTrending(t,o,g.current);u.current&&(p(k=>[...k,...y.items]),r(y.pagination),g.current=y.pagination.next_cursor);}catch(y){u.current&&i(y.message);}finally{u.current&&s(false);}}},[l,t,o,n]);return useEffect(()=>(u.current=true,m(),()=>{u.current=false;}),[m]),{repos:c,hasMore:e?.has_more??false,total:e?.total??0,loading:n,error:a,refresh:m,loadMore:h}}function xt(f,t){let o=d(f),[l,c]=useState({stars:0,starred:false,repo_id:t||""}),[p,e]=useState(false),[r,n]=useState(null),s=useRef(true),a=useCallback(async()=>{if(t)try{let u=await o.getStarInfo(t);s.current&&c(u);}catch{}},[o,t]);useEffect(()=>(s.current=true,a(),()=>{s.current=false;}),[a]);let i=useCallback(async()=>{if(t){e(true),n(null);try{let u=l.starred?await o.unstarRepo(t):await o.starRepo(t);s.current&&c({stars:u.stars,starred:u.starred,repo_id:t});}catch(u){s.current&&n(u.message);}finally{s.current&&e(false);}}},[o,t,l.starred]);return {...l,loading:p,error:r,toggle:i,refresh:a}}export{J as estimateCost,Tt as useNetworkStats,ut as usePaginatedRepos,d as useRackClient,gt as useRackRegister,ft as useRackSession,it as useRepoPush,nt as useRepoTree,Z as useRepos,Rt as useSkillStats,xt as useStar,St as useTensorStats,Et as useTrending};
package/dist/index.cjs CHANGED
@@ -1,10 +1,10 @@
1
- 'use strict';var react=require('react'),lucideReact=require('lucide-react'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),jsxRuntime=require('react/jsx-runtime');async function w(t,e,o,n){let s={"Content-Type":"application/json",...o?.headers};n&&(s.Authorization=`Bearer ${n}`);let u=await fetch(`${t}${e}`,{...o,headers:s});if(!u.ok){let r=`HTTP ${u.status}`;try{let a=await u.json();a.error&&(r=a.error);}catch{}throw new Error(r)}return u.json()}function I(t){let e=t.indexOf(":");return {mode:t.slice(0,e),cid:t.slice(e+1)}}function x(t){let e=t.apiBaseUrl,o=t.authorMid,n=t.ownerMid,s=t.apiKey,u=t.stacknetUrl||t.apiBaseUrl;return react.useMemo(()=>({async listRepos(r){let a=r||n?`?owner=${encodeURIComponent(r||n)}`:"";return (await w(e,`/api/rack/repos${a}`,void 0,s)).repos||[]},async initRepo(r){return w(e,"/api/rack/init",{method:"POST",body:JSON.stringify({...r,owner_mid:n})},s)},async push(r,a){return w(e,`/api/rack/${r}/push`,{method:"POST",body:JSON.stringify({...a,author_mid:o})},s)},async getTree(r,a="main"){let l=await w(e,`/api/rack/${r}/tree/${a}`,void 0,s);return {tree:l.tree,commit_cid:l.commit_cid}},async getBlob(r,a){return (await w(e,`/api/rack/${r}/blob/${a}`,void 0,s)).content},async getLog(r,a,l){let c=new URLSearchParams;a&&c.set("ref",a),l&&c.set("max_count",String(l));let d=c.toString()?`?${c}`:"";return (await w(e,`/api/rack/${r}/log${d}`,void 0,s)).commits||[]},async getBranches(r){return (await w(e,`/api/rack/${r}/branches`,void 0,s)).branches||[]},async createBranch(r,a,l){return w(e,`/api/rack/${r}/branch`,{method:"POST",body:JSON.stringify({branch_name:a,from_ref:l})},s)},async merge(r,a,l){return w(e,`/api/rack/${r}/merge`,{method:"POST",body:JSON.stringify({source_branch:a,target_branch:l})},s)},async getDiff(r,a,l){return (await w(e,`/api/rack/${r}/diff/${a}/${l}`,void 0,s)).diff?.entries||[]},async starRepo(r){return w(e,`/api/rack/${r}/star`,{method:"POST"},s)},async unstarRepo(r){return w(e,`/api/rack/${r}/star`,{method:"DELETE"},s)},async getStarInfo(r){return w(e,`/api/rack/${r}/stars`,void 0,s)},async getSkillStats(r){let a={meta:null,tokenCount:null,usageCount:null};try{let{tree:l}=await this.getTree(r,"main");if(!l?.entries)return a;if(l.entries["META.json"]){let f=I(l.entries["META.json"]).cid,m=await this.getBlob(r,f);a.meta=JSON.parse(m);}let c=0,d=Object.values(l.entries).map(async f=>{try{let m=I(f).cid,g=await this.getBlob(r,m);c+=g.length;}catch{}});await Promise.all(d),c>0&&(a.tokenCount=Math.ceil(c/4)),a.meta?.skill_id&&(a.usageCount=await this.getSkillUsageCount(a.meta.skill_id));}catch{}return a},async getSkillUsageCount(r){try{let a=await fetch(`${u}/v1/skills/${encodeURIComponent(r)}`);if(a.ok){let c=await a.json();return c.usage_count??c.usageCount??null}let l=await fetch(`${u}/v1/skills?scope=public`);if(l.ok){let d=((await l.json()).skills||[]).find(f=>f.name===r||f.id===r);if(d)return d.usage_count??d.usageCount??0}return 0}catch{return null}},async getTensorStats(r){let a={meta:null,sizeMB:null};try{let{tree:l}=await this.getTree(r,"main");if(!l?.entries)return a;if(l.entries["TENSOR_META.json"]){let c=I(l.entries["TENSOR_META.json"]).cid,d=await this.getBlob(r,c);a.meta=JSON.parse(d),a.sizeMB=a.meta?.tensor_size_mb??null;}}catch{}return a},async getNetworkStats(){try{return (await w(e,"/api/rack/stats",void 0,s)).stats||null}catch{return null}},async getTrending(r=5,a=1){try{return (await w(e,`/api/rack/trending?limit=${r}&days=${a}`,void 0,s)).trending||[]}catch{return []}}}),[e,o,n,s,u])}function A(t){let e=x(t),o=react.useRef(e);o.current=e;let[n,s]=react.useState([]),[u,r]=react.useState(true),[a,l]=react.useState(null),c=react.useRef(true),d=react.useRef(null),f=react.useCallback(async()=>{d.current?.abort();let m=new AbortController;d.current=m;try{c.current&&(r(!0),l(null));let g=await o.current.listRepos();c.current&&!m.signal.aborted&&s(g);}catch(g){c.current&&!m.signal.aborted&&l(g instanceof Error?g.message:"Failed to load repos");}finally{c.current&&!m.signal.aborted&&r(false);}},[]);return react.useEffect(()=>(c.current=true,f(),()=>{c.current=false,d.current?.abort();}),[f]),{repos:n,loading:u,error:a,refresh:f}}function Ee(t){return Object.entries(t).map(([e,o])=>{let n=o.indexOf(":"),s=n>0?o.slice(0,n):"100644",u=n>0?o.slice(n+1):o;return {path:e,mode:s,cid:u,isDir:s==="040000"}}).sort((e,o)=>e.isDir!==o.isDir?e.isDir?-1:1:e.path.localeCompare(o.path))}function U(t,e,o="main"){let n=x(t),[s,u]=react.useState([]),[r,a]=react.useState(false),[l,c]=react.useState(null),d=react.useRef(true),f=react.useCallback(async()=>{if(e)try{d.current&&(a(!0),c(null));let{tree:g}=await n.getTree(e,o);d.current&&u(Ee(g.entries));}catch(g){d.current&&c(g instanceof Error?g.message:"Failed to load tree");}finally{d.current&&a(false);}},[n,e,o]);react.useEffect(()=>(d.current=true,f(),()=>{d.current=false;}),[f]);let m=react.useCallback(async g=>{if(!e)throw new Error("No repo selected");return n.getBlob(e,g)},[n,e]);return {entries:s,loading:r,error:l,refresh:f,getFileContent:m}}function Me(t){let e=x(t),[o,n]=react.useState(false),[s,u]=react.useState(null),r=react.useRef(true);return react.useEffect(()=>(r.current=true,()=>{r.current=false;}),[]),{push:react.useCallback(async(l,c,d,f)=>{try{return r.current&&(n(!0),u(null)),await e.push(l,{files:c,message:d,branch:f})}catch(m){let g=m instanceof Error?m.message:"Push failed";return r.current&&u(g),null}finally{r.current&&n(false);}},[e]),pushing:o,error:s}}var j="stacknet-rack-apikey";function ze(t){let e=t.stacknetUrl||t.apiBaseUrl,[o,n]=react.useState({authenticated:false}),[s,u]=react.useState(null),[r,a]=react.useState(false),l=react.useCallback(m=>({"Content-Type":"application/json",...m||t.apiKey?{Authorization:`Bearer ${m||t.apiKey}`}:{}}),[t.apiKey]),c=react.useCallback(async m=>{a(true);try{let g=await fetch(`${e}/health`,{headers:l(m)});if(!g.ok)throw new Error(`Authentication failed: ${g.status}`);let p={authenticated:!0,apiKey:m,permission:m.startsWith("gk_")?"write":"read"};n(p);try{localStorage.setItem(j,m);}catch{}return p}catch(g){throw n({authenticated:false}),g}finally{a(false);}},[e,l]),d=react.useCallback(()=>{n({authenticated:false}),u(null);try{localStorage.removeItem(j);}catch{}},[]),f=react.useCallback(async()=>{let m=o.apiKey||t.apiKey;if(!m)return null;try{let g=await fetch(`${e}/network/usage`,{headers:l(m)});if(!g.ok)return null;let p=await g.json(),v={planAllocation:p.plan_allocation??p.planAllocation??0,inferenceUsed:p.inference_used??p.inferenceUsed??0,ledgerSpent:p.ledger_spent??p.ledgerSpent??0,totalUsed:p.total_used??p.totalUsed??0,remaining:p.remaining??0,percent:p.percent??0,exceeded:p.exceeded??!1};return u(v),v}catch{return null}},[o.apiKey,t.apiKey,e,l]);return react.useEffect(()=>{let m=t.apiKey;if(m){n({authenticated:true,apiKey:m,permission:m.startsWith("gk_")?"write":"read"});return}try{let g=localStorage.getItem(j);g&&n({authenticated:!0,apiKey:g,permission:g.startsWith("gk_")?"write":"read"});}catch{}},[t.apiKey]),{session:o,budget:s,loading:r,login:c,logout:d,refreshBudget:f}}var oe=1e3,ae=1e3,ie=100;function le(t,e){if(t==="skill"){let s=ie+Math.ceil(e/4);return {type:t,totalBytes:e,totalMegabytes:e/1e6,baseCost:s,multiplier:oe,registrationCostTokens:s*oe}}let o=Math.ceil(e/1e6),n=ie+o;return {type:t,totalBytes:e,totalMegabytes:o,baseCost:n,multiplier:ae,registrationCostTokens:n*ae}}function Le(t){let e=t.stacknetUrl||t.apiBaseUrl,o=t.apiKey,[n,s]=react.useState(false),[u,r]=react.useState(null),a=react.useCallback(()=>{if(!o)throw new Error("API key required for registration. Call login() first.");return {"Content-Type":"application/json",Authorization:`Bearer ${o}`}},[o]),l=react.useCallback(async d=>{s(true),r(null);try{let f=await fetch(`${e}/skills`,{method:"POST",headers:a(),body:JSON.stringify(d)});if(!f.ok){let m=await f.json().catch(()=>({error:`HTTP ${f.status}`}));throw new Error(m.error||`Registration failed: ${f.status}`)}return await f.json()}catch(f){throw r(f.message),f}finally{s(false);}},[e,a]),c=react.useCallback(async d=>{s(true),r(null);try{let f=await fetch(`${e}/tensors`,{method:"POST",headers:a(),body:JSON.stringify(d)});if(!f.ok){let m=await f.json().catch(()=>({error:`HTTP ${f.status}`}));throw new Error(m.error||`Registration failed: ${f.status}`)}return await f.json()}catch(f){throw r(f.message),f}finally{s(false);}},[e,a]);return {registerSkill:l,registerTensor:c,estimateCost:le,registering:n,error:u}}function Oe(t,e){let o=x(t),[n,s]=react.useState({meta:null,tokenCount:null,usageCount:null}),[u,r]=react.useState(false),[a,l]=react.useState(null),c=react.useRef(true),d=react.useCallback(async()=>{if(e){r(true),l(null);try{let f=await o.getSkillStats(e);c.current&&s(f);}catch(f){c.current&&l(f.message);}finally{c.current&&r(false);}}},[o,e]);return react.useEffect(()=>(c.current=true,d(),()=>{c.current=false;}),[d]),{stats:n,loading:u,error:a,refresh:d}}function He(t,e){let o=x(t),[n,s]=react.useState({meta:null,sizeMB:null}),[u,r]=react.useState(false),[a,l]=react.useState(null),c=react.useRef(true),d=react.useCallback(async()=>{if(e){r(true),l(null);try{let f=await o.getTensorStats(e);c.current&&s(f);}catch(f){c.current&&l(f.message);}finally{c.current&&r(false);}}},[o,e]);return react.useEffect(()=>(c.current=true,d(),()=>{c.current=false;}),[d]),{stats:n,loading:u,error:a,refresh:d}}function Ve(t){let e=x(t),[o,n]=react.useState(null),[s,u]=react.useState(false),[r,a]=react.useState(null),l=react.useRef(true),c=react.useCallback(async()=>{u(true),a(null);try{let d=await e.getNetworkStats();l.current&&n(d);}catch(d){l.current&&a(d.message);}finally{l.current&&u(false);}},[e]);return react.useEffect(()=>(l.current=true,c(),()=>{l.current=false;}),[c]),{stats:o,loading:s,error:r,refresh:c}}function Ye(t,e=5,o=1){let n=x(t),[s,u]=react.useState([]),[r,a]=react.useState(false),[l,c]=react.useState(null),d=react.useRef(true),f=react.useCallback(async m=>{a(true),c(null);try{let g=await n.getTrending(e,m??o);d.current&&u(g);}catch(g){d.current&&c(g.message);}finally{d.current&&a(false);}},[n,e,o]);return react.useEffect(()=>(d.current=true,f(),()=>{d.current=false;}),[f]),{repos:s,loading:r,error:l,refresh:f}}function et(t,e){let o=x(t),[n,s]=react.useState({stars:0,starred:false,repo_id:e||""}),[u,r]=react.useState(false),[a,l]=react.useState(null),c=react.useRef(true),d=react.useCallback(async()=>{if(e)try{let m=await o.getStarInfo(e);c.current&&s(m);}catch{}},[o,e]);react.useEffect(()=>(c.current=true,d(),()=>{c.current=false;}),[d]);let f=react.useCallback(async()=>{if(e){r(true),l(null);try{let m=n.starred?await o.unstarRepo(e):await o.starRepo(e);c.current&&s({stars:m.stars,starred:m.starred,repo_id:e});}catch(m){c.current&&l(m.message);}finally{c.current&&r(false);}}},[o,e,n.starred]);return {...n,loading:u,error:a,toggle:f,refresh:d}}function C(...t){return tailwindMerge.twMerge(clsx.clsx(t))}var nt=/^(https?:\/\/|mailto:|\/[^/])/i;function st(t){let e=t.trim();return nt.test(e)?e:null}function _(t){let e=[],o=/(`[^`]+`)|(\*\*(.+?)\*\*)|(\*(.+?)\*)|(_(.+?)_)|(\[([^\]]+)\]\(([^)]+)\))/g,n=0,s,u=0;for(;(s=o.exec(t))!==null;){s.index>n&&e.push(t.slice(n,s.index));let r=`i${u++}`;if(s[1])e.push(jsxRuntime.jsx("code",{className:"rounded bg-muted px-1.5 py-0.5 text-[0.85em] font-mono text-pink-400",children:s[1].slice(1,-1)},r));else if(s[2])e.push(jsxRuntime.jsx("strong",{children:s[3]},r));else if(s[4])e.push(jsxRuntime.jsx("em",{children:s[5]},r));else if(s[6])e.push(jsxRuntime.jsx("em",{children:s[7]},r));else if(s[8]){let a=st(s[10]);a?e.push(jsxRuntime.jsx("a",{href:a,className:"text-blue-400 underline hover:text-blue-300",target:"_blank",rel:"noopener noreferrer",children:s[9]},r)):e.push(s[9]);}n=s.index+s[0].length;}return n<t.length&&e.push(t.slice(n)),e.length>0?e:[t]}function ot(t){let e=t.split(`
2
- `),o=[],n=0;for(;n<e.length;){let s=e[n];if(s.trim()===""){n++;continue}if(/^(-{3,}|\*{3,}|_{3,})$/.test(s.trim())){o.push({type:"hr"}),n++;continue}let u=s.match(/^(#{1,6})\s+(.+)/);if(u){o.push({type:"heading",level:u[1].length,content:u[2]}),n++;continue}if(s.trim().startsWith("```")){let a=s.trim().slice(3).trim(),l=[];for(n++;n<e.length&&!e[n].trim().startsWith("```");)l.push(e[n]),n++;o.push({type:"code",content:l.join(`
3
- `),lang:a||void 0}),n++;continue}if(/^\s*[-*+]\s/.test(s)){let a=[];for(;n<e.length&&/^\s*[-*+]\s/.test(e[n]);)a.push(e[n].replace(/^\s*[-*+]\s+/,"")),n++;o.push({type:"ul",items:a});continue}if(/^\s*\d+[.)]\s/.test(s)){let a=[];for(;n<e.length&&/^\s*\d+[.)]\s/.test(e[n]);)a.push(e[n].replace(/^\s*\d+[.)]\s+/,"")),n++;o.push({type:"ol",items:a});continue}let r=[];for(;n<e.length&&e[n].trim()!==""&&!e[n].match(/^#{1,6}\s/)&&!e[n].trim().startsWith("```")&&!/^\s*[-*+]\s/.test(e[n])&&!/^\s*\d+[.)]\s/.test(e[n]);)r.push(e[n]),n++;r.length>0&&o.push({type:"paragraph",content:r.join(" ")});}return o}var at={1:"text-2xl font-bold mt-6 mb-3",2:"text-xl font-bold mt-5 mb-2",3:"text-lg font-semibold mt-4 mb-2",4:"text-base font-semibold mt-3 mb-1",5:"text-sm font-semibold mt-2 mb-1",6:"text-sm font-medium mt-2 mb-1"};function it(t,e){switch(t.type){case "hr":return jsxRuntime.jsx("hr",{className:"my-4 border-border"},`b${e}`);case "heading":{let o=Math.min(Math.max(t.level||1,1),6),n=`h${o}`;return jsxRuntime.jsx(n,{className:C("text-foreground",at[o]),children:_(t.content||"")},`b${e}`)}case "paragraph":return jsxRuntime.jsx("p",{className:"mb-3 leading-relaxed text-foreground",children:_(t.content||"")},`b${e}`);case "code":return jsxRuntime.jsx("pre",{className:"mb-3 overflow-x-auto rounded-lg bg-muted p-4 text-sm font-mono leading-relaxed text-foreground",children:jsxRuntime.jsx("code",{children:t.content})},`b${e}`);case "ul":return jsxRuntime.jsx("ul",{className:"mb-3 ml-5 list-disc space-y-1 text-foreground",children:t.items?.map((o,n)=>jsxRuntime.jsx("li",{className:"leading-relaxed",children:_(o)},`li${e}-${n}`))},`b${e}`);case "ol":return jsxRuntime.jsx("ol",{className:"mb-3 ml-5 list-decimal space-y-1 text-foreground",children:t.items?.map((o,n)=>jsxRuntime.jsx("li",{className:"leading-relaxed",children:_(o)},`li${e}-${n}`))},`b${e}`);default:return null}}function V({content:t,className:e}){let o=ot(t);return jsxRuntime.jsx("div",{className:C("text-sm",e),children:o.map((n,s)=>it(n,s))})}function me({open:t,className:e}){return jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:C("shrink-0 transition-transform duration-150",t?"rotate-0":"-rotate-90",e),children:jsxRuntime.jsx("path",{d:"M16.134 6.16a.5.5 0 1 1 .732.68l-6.5 7-.077.068a.5.5 0 0 1-.655-.068l-6.5-7-.062-.08a.5.5 0 0 1 .718-.667l.076.067L10 12.767z"})})}function ue({size:t=20,className:e}){return jsxRuntime.jsx("svg",{width:t,height:t,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsxRuntime.jsx("path",{d:"M8.5 2a6.5 6.5 0 0 1 4.935 10.728l4.419 4.419.064.078a.5.5 0 0 1-.693.693l-.079-.064-4.419-4.42A6.5 6.5 0 1 1 8.5 2m0 1a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11"})})}function Z({size:t=20,className:e}){return jsxRuntime.jsx("svg",{width:t,height:t,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsxRuntime.jsx("path",{d:"M15.147 4.146a.5.5 0 0 1 .707.707L10.707 10l5.147 5.147a.5.5 0 0 1-.63.771l-.078-.064L10 10.707l-5.146 5.147a.5.5 0 0 1-.708-.707L9.293 10 4.146 4.853a.5.5 0 0 1 .708-.707L10 9.293z"})})}function ge({size:t=20,className:e}){return jsxRuntime.jsx("svg",{width:t,height:t,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsxRuntime.jsx("path",{d:"M10 3a.5.5 0 0 1 .5.5v6h6l.1.01a.5.5 0 0 1 0 .98l-.1.01h-6v6a.5.5 0 0 1-1 0v-6h-6a.5.5 0 0 1 0-1h6v-6A.5.5 0 0 1 10 3"})})}function ut(){return jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M6.5 3A2.5 2.5 0 0 0 4 5.5v9A2.5 2.5 0 0 0 6.5 17h7a2.5 2.5 0 0 0 2.5-2.5v-7A2.5 2.5 0 0 0 13.5 5H11V3.5a.5.5 0 0 0-1 0V5H6.5ZM5 5.5A1.5 1.5 0 0 1 6.5 4H9v1H6.5A1.5 1.5 0 0 0 5 6.5v8A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-7A1.5 1.5 0 0 0 13.5 6H11V4h2.5A2.5 2.5 0 0 1 16 6.5v8a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-9Z"})})}function dt(){return jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M5.5 3A2.5 2.5 0 0 0 3 5.5v9A2.5 2.5 0 0 0 5.5 17h9a2.5 2.5 0 0 0 2.5-2.5v-9A2.5 2.5 0 0 0 14.5 3h-9ZM4 5.5A1.5 1.5 0 0 1 5.5 4h9A1.5 1.5 0 0 1 16 5.5v9a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 4 14.5v-9ZM7 7.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5Z"})})}function ft(){return jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M10 2a.5.5 0 0 1 .354.146l3 3a.5.5 0 0 1-.708.708L10.5 3.707V12.5a.5.5 0 0 1-1 0V3.707L7.354 5.854a.5.5 0 1 1-.708-.708l3-3A.5.5 0 0 1 10 2ZM4 13.5a.5.5 0 0 1 1 0v1A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-1a.5.5 0 0 1 1 0v1a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-1Z"})})}function pe(){let[t,e]=react.useState(false);return react.useEffect(()=>{if(typeof window>"u")return;let o=()=>e(window.innerWidth<768);return o(),window.addEventListener("resize",o),()=>window.removeEventListener("resize",o)},[]),t}function he({onClose:t,children:e,title:o}){let n=pe(),s=react.useRef(t);return s.current=t,react.useEffect(()=>{let u=r=>{r.key==="Escape"&&s.current();};return window.addEventListener("keydown",u),()=>window.removeEventListener("keydown",u)},[]),n?jsxRuntime.jsxs("div",{className:"fixed inset-0 z-50 flex items-end justify-center",onClick:t,children:[jsxRuntime.jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxRuntime.jsxs("div",{className:"relative z-10 w-full max-h-[90vh] overflow-y-auto rounded-t-2xl bg-[#1a1a1a] p-5 pb-8 animate-in slide-in-from-bottom duration-200",onClick:u=>u.stopPropagation(),children:[jsxRuntime.jsx("div",{className:"mx-auto mb-4 h-1 w-10 rounded-full bg-zinc-600"}),jsxRuntime.jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsxRuntime.jsx("h2",{className:"text-lg font-semibold text-foreground",children:o}),jsxRuntime.jsx("button",{onClick:t,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsxRuntime.jsx(Z,{size:20})})]}),e]})]}):jsxRuntime.jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center",onClick:t,children:[jsxRuntime.jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxRuntime.jsxs("div",{className:"relative z-10 w-full max-w-lg overflow-y-auto rounded-2xl bg-[#1a1a1a] p-6 shadow-2xl animate-in fade-in zoom-in-95 duration-150",onClick:u=>u.stopPropagation(),children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsxRuntime.jsx("h2",{className:"text-lg font-semibold text-foreground",children:o}),jsxRuntime.jsx("button",{onClick:t,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsxRuntime.jsx(Z,{size:20})})]}),e]})]})}function mt({onClose:t,onCreated:e,config:o}){let[n,s]=react.useState(""),[u,r]=react.useState(""),[a,l]=react.useState(""),[c,d]=react.useState(false),[f,m]=react.useState(null);return jsxRuntime.jsx(he,{title:"Write skill instructions",onClose:t,children:jsxRuntime.jsxs("div",{className:"space-y-4",children:[jsxRuntime.jsxs("div",{className:"space-y-1.5",children:[jsxRuntime.jsx("label",{htmlFor:"skill-name",className:"text-sm text-muted-foreground",children:"Skill name"}),jsxRuntime.jsx("input",{id:"skill-name",value:n,onChange:p=>s(p.target.value),placeholder:"weekly-status-report",className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxRuntime.jsxs("div",{className:"space-y-1.5",children:[jsxRuntime.jsx("label",{htmlFor:"skill-desc",className:"text-sm text-muted-foreground",children:"Description"}),jsxRuntime.jsx("textarea",{id:"skill-desc",value:u,onChange:p=>r(p.target.value),placeholder:"Generate weekly status reports from recent work.",rows:3,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxRuntime.jsxs("div",{className:"space-y-1.5",children:[jsxRuntime.jsx("label",{htmlFor:"skill-instructions",className:"text-sm text-muted-foreground",children:"Instructions"}),jsxRuntime.jsx("textarea",{id:"skill-instructions",value:a,onChange:p=>l(p.target.value),placeholder:"Summarize my recent work in three sections: wins, blockers, and next steps.",rows:8,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),f&&jsxRuntime.jsx("p",{className:"text-sm text-red-500",children:f}),jsxRuntime.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[jsxRuntime.jsx("button",{onClick:t,className:"rounded-lg border border-zinc-700 px-4 py-2 text-sm text-foreground hover:bg-zinc-800",children:"Cancel"}),jsxRuntime.jsx("button",{onClick:async()=>{if(n.trim()){d(true),m(null);try{let p=o.apiBaseUrl||"",v=`# ${n.trim()}
1
+ 'use strict';var react=require('react'),lucideReact=require('lucide-react'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),jsxRuntime=require('react/jsx-runtime');async function v(r,e,o,n){let s={"Content-Type":"application/json",...o?.headers};n&&(s.Authorization=`Bearer ${n}`);let f=await fetch(`${r}${e}`,{...o,headers:s});if(!f.ok){let t=`HTTP ${f.status}`;try{let a=await f.json();a.error&&(t=a.error);}catch{}throw new Error(t)}return f.json()}function B(r){let e=r.indexOf(":");return {mode:r.slice(0,e),cid:r.slice(e+1)}}function b(r){let e=r.apiBaseUrl,o=r.authorMid,n=r.ownerMid,s=r.apiKey,f=r.stacknetUrl||r.apiBaseUrl;return react.useMemo(()=>({async listRepos(t,a){let l=new URLSearchParams;(t||n)&&l.set("owner",t||n),a?.limit&&l.set("limit",String(a.limit)),a?.cursor&&l.set("cursor",a.cursor);let c=l.toString()?`?${l}`:"",u=await v(e,`/api/rack/repos${c}`,void 0,s);return {items:u.repos||[],pagination:u.pagination||{total:(u.repos||[]).length,limit:50,has_more:false,next_cursor:null}}},async initRepo(t){return v(e,"/api/rack/init",{method:"POST",body:JSON.stringify({...t,owner_mid:n})},s)},async push(t,a){return v(e,`/api/rack/${t}/push`,{method:"POST",body:JSON.stringify({...a,author_mid:o})},s)},async getTree(t,a="main"){let l=await v(e,`/api/rack/${t}/tree/${a}`,void 0,s);return {tree:l.tree,commit_cid:l.commit_cid}},async getBlob(t,a){return (await v(e,`/api/rack/${t}/blob/${a}`,void 0,s)).content},async getLog(t,a,l){let c=new URLSearchParams;a&&c.set("ref",a),l&&c.set("max_count",String(l));let u=c.toString()?`?${c}`:"";return (await v(e,`/api/rack/${t}/log${u}`,void 0,s)).commits||[]},async getBranches(t){return (await v(e,`/api/rack/${t}/branches`,void 0,s)).branches||[]},async createBranch(t,a,l){return v(e,`/api/rack/${t}/branch`,{method:"POST",body:JSON.stringify({branch_name:a,from_ref:l})},s)},async merge(t,a,l){return v(e,`/api/rack/${t}/merge`,{method:"POST",body:JSON.stringify({source_branch:a,target_branch:l})},s)},async getDiff(t,a,l){return (await v(e,`/api/rack/${t}/diff/${a}/${l}`,void 0,s)).diff?.entries||[]},async starRepo(t){return v(e,`/api/rack/${t}/star`,{method:"POST"},s)},async unstarRepo(t){return v(e,`/api/rack/${t}/star`,{method:"DELETE"},s)},async getStarInfo(t){return v(e,`/api/rack/${t}/stars`,void 0,s)},async getSkillStats(t){let a={meta:null,tokenCount:null,usageCount:null};try{let{tree:l}=await this.getTree(t,"main");if(!l?.entries)return a;if(l.entries["META.json"]){let m=B(l.entries["META.json"]).cid,d=await this.getBlob(t,m);a.meta=JSON.parse(d);}let c=0,u=Object.values(l.entries).map(async m=>{try{let d=B(m).cid,g=await this.getBlob(t,d);c+=g.length;}catch{}});await Promise.all(u),c>0&&(a.tokenCount=Math.ceil(c/4)),a.meta?.skill_id&&(a.usageCount=await this.getSkillUsageCount(a.meta.skill_id));}catch{}return a},async getSkillUsageCount(t){try{let a=await fetch(`${f}/v1/skills/${encodeURIComponent(t)}`);if(a.ok){let c=await a.json();return c.usage_count??c.usageCount??null}let l=await fetch(`${f}/v1/skills?scope=public`);if(l.ok){let u=((await l.json()).skills||[]).find(m=>m.name===t||m.id===t);if(u)return u.usage_count??u.usageCount??0}return 0}catch{return null}},async getTensorStats(t){let a={meta:null,sizeMB:null};try{let{tree:l}=await this.getTree(t,"main");if(!l?.entries)return a;if(l.entries["TENSOR_META.json"]){let c=B(l.entries["TENSOR_META.json"]).cid,u=await this.getBlob(t,c);a.meta=JSON.parse(u),a.sizeMB=a.meta?.tensor_size_mb??null;}}catch{}return a},async getNetworkStats(){try{return (await v(e,"/api/rack/stats",void 0,s)).stats||null}catch{return null}},async getTrending(t=5,a=1,l){try{let c=new URLSearchParams({limit:String(t),days:String(a)});l&&c.set("cursor",l);let u=await v(e,`/api/rack/trending?${c}`,void 0,s);return {items:u.trending||[],pagination:u.pagination||{total:(u.trending||[]).length,limit:t,has_more:!1,next_cursor:null}}}catch{return {items:[],pagination:{total:0,limit:t,has_more:false,next_cursor:null}}}}}),[e,o,n,s,f])}function D(r){let e=b(r),o=react.useRef(e);o.current=e;let[n,s]=react.useState([]),[f,t]=react.useState(true),[a,l]=react.useState(null),c=react.useRef(true),u=react.useRef(null),m=react.useCallback(async()=>{u.current?.abort();let d=new AbortController;u.current=d;try{c.current&&(t(!0),l(null));let g=await o.current.listRepos();c.current&&!d.signal.aborted&&s(g.items);}catch(g){c.current&&!d.signal.aborted&&l(g instanceof Error?g.message:"Failed to load repos");}finally{c.current&&!d.signal.aborted&&t(false);}},[]);return react.useEffect(()=>(c.current=true,m(),()=>{c.current=false,u.current?.abort();}),[m]),{repos:n,loading:f,error:a,refresh:m}}function $e(r){return Object.entries(r).map(([e,o])=>{let n=o.indexOf(":"),s=n>0?o.slice(0,n):"100644",f=n>0?o.slice(n+1):o;return {path:e,mode:s,cid:f,isDir:s==="040000"}}).sort((e,o)=>e.isDir!==o.isDir?e.isDir?-1:1:e.path.localeCompare(o.path))}function H(r,e,o="main"){let n=b(r),[s,f]=react.useState([]),[t,a]=react.useState(false),[l,c]=react.useState(null),u=react.useRef(true),m=react.useCallback(async()=>{if(e)try{u.current&&(a(!0),c(null));let{tree:g}=await n.getTree(e,o);u.current&&f($e(g.entries));}catch(g){u.current&&c(g instanceof Error?g.message:"Failed to load tree");}finally{u.current&&a(false);}},[n,e,o]);react.useEffect(()=>(u.current=true,m(),()=>{u.current=false;}),[m]);let d=react.useCallback(async g=>{if(!e)throw new Error("No repo selected");return n.getBlob(e,g)},[n,e]);return {entries:s,loading:t,error:l,refresh:m,getFileContent:d}}function Ae(r){let e=b(r),[o,n]=react.useState(false),[s,f]=react.useState(null),t=react.useRef(true);return react.useEffect(()=>(t.current=true,()=>{t.current=false;}),[]),{push:react.useCallback(async(l,c,u,m)=>{try{return t.current&&(n(!0),f(null)),await e.push(l,{files:c,message:u,branch:m})}catch(d){let g=d instanceof Error?d.message:"Push failed";return t.current&&f(g),null}finally{t.current&&n(false);}},[e]),pushing:o,error:s}}function Oe(r,e={}){let{pageSize:o=50,owner:n}=e,s=b(r),[f,t]=react.useState([]),[a,l]=react.useState(null),[c,u]=react.useState(false),[m,d]=react.useState(null),g=react.useRef(null),p=react.useRef(true),x=react.useCallback(async(C,I=false)=>{u(true),d(null);try{let P=await s.listRepos(n,{limit:o,cursor:C||void 0});p.current&&(t(M=>I?[...M,...P.items]:P.items),l(P.pagination),g.current=P.pagination.next_cursor);}catch(P){p.current&&d(P.message);}finally{p.current&&u(false);}},[s,n,o]),w=react.useCallback(async()=>{!g.current||c||await x(g.current,true);},[x,c]),R=react.useCallback(async()=>{g.current=null,await x(void 0,false);},[x]);return react.useEffect(()=>(p.current=true,x(),()=>{p.current=false;}),[x]),{repos:f,hasMore:a?.has_more??false,total:a?.total??0,loading:c,error:m,loadMore:w,reset:R,pagination:a}}var J="stacknet-rack-apikey";function De(r){let e=r.stacknetUrl||r.apiBaseUrl,[o,n]=react.useState({authenticated:false}),[s,f]=react.useState(null),[t,a]=react.useState(false),l=react.useCallback(d=>({"Content-Type":"application/json",...d||r.apiKey?{Authorization:`Bearer ${d||r.apiKey}`}:{}}),[r.apiKey]),c=react.useCallback(async d=>{a(true);try{let g=await fetch(`${e}/health`,{headers:l(d)});if(!g.ok)throw new Error(`Authentication failed: ${g.status}`);let p={authenticated:!0,apiKey:d,permission:d.startsWith("gk_")?"write":"read"};n(p);try{localStorage.setItem(J,d);}catch{}return p}catch(g){throw n({authenticated:false}),g}finally{a(false);}},[e,l]),u=react.useCallback(()=>{n({authenticated:false}),f(null);try{localStorage.removeItem(J);}catch{}},[]),m=react.useCallback(async()=>{let d=o.apiKey||r.apiKey;if(!d)return null;try{let g=await fetch(`${e}/network/usage`,{headers:l(d)});if(!g.ok)return null;let p=await g.json(),x={planAllocation:p.plan_allocation??p.planAllocation??0,inferenceUsed:p.inference_used??p.inferenceUsed??0,ledgerSpent:p.ledger_spent??p.ledgerSpent??0,totalUsed:p.total_used??p.totalUsed??0,remaining:p.remaining??0,percent:p.percent??0,exceeded:p.exceeded??!1};return f(x),x}catch{return null}},[o.apiKey,r.apiKey,e,l]);return react.useEffect(()=>{let d=r.apiKey;if(d){n({authenticated:true,apiKey:d,permission:d.startsWith("gk_")?"write":"read"});return}try{let g=localStorage.getItem(J);g&&n({authenticated:!0,apiKey:g,permission:g.startsWith("gk_")?"write":"read"});}catch{}},[r.apiKey]),{session:o,budget:s,loading:t,login:c,logout:u,refreshBudget:m}}var ce=1e3,ue=1e3,de=100;function fe(r,e){if(r==="skill"){let s=de+Math.ceil(e/4);return {type:r,totalBytes:e,totalMegabytes:e/1e6,baseCost:s,multiplier:ce,registrationCostTokens:s*ce}}let o=Math.ceil(e/1e6),n=de+o;return {type:r,totalBytes:e,totalMegabytes:o,baseCost:n,multiplier:ue,registrationCostTokens:n*ue}}function Fe(r){let e=r.stacknetUrl||r.apiBaseUrl,o=r.apiKey,[n,s]=react.useState(false),[f,t]=react.useState(null),a=react.useCallback(()=>{if(!o)throw new Error("API key required for registration. Call login() first.");return {"Content-Type":"application/json",Authorization:`Bearer ${o}`}},[o]),l=react.useCallback(async u=>{s(true),t(null);try{let m=await fetch(`${e}/skills`,{method:"POST",headers:a(),body:JSON.stringify(u)});if(!m.ok){let d=await m.json().catch(()=>({error:`HTTP ${m.status}`}));throw new Error(d.error||`Registration failed: ${m.status}`)}return await m.json()}catch(m){throw t(m.message),m}finally{s(false);}},[e,a]),c=react.useCallback(async u=>{s(true),t(null);try{let m=await fetch(`${e}/tensors`,{method:"POST",headers:a(),body:JSON.stringify(u)});if(!m.ok){let d=await m.json().catch(()=>({error:`HTTP ${m.status}`}));throw new Error(d.error||`Registration failed: ${m.status}`)}return await m.json()}catch(m){throw t(m.message),m}finally{s(false);}},[e,a]);return {registerSkill:l,registerTensor:c,estimateCost:fe,registering:n,error:f}}function Je(r,e){let o=b(r),[n,s]=react.useState({meta:null,tokenCount:null,usageCount:null}),[f,t]=react.useState(false),[a,l]=react.useState(null),c=react.useRef(true),u=react.useCallback(async()=>{if(e){t(true),l(null);try{let m=await o.getSkillStats(e);c.current&&s(m);}catch(m){c.current&&l(m.message);}finally{c.current&&t(false);}}},[o,e]);return react.useEffect(()=>(c.current=true,u(),()=>{c.current=false;}),[u]),{stats:n,loading:f,error:a,refresh:u}}function Ge(r,e){let o=b(r),[n,s]=react.useState({meta:null,sizeMB:null}),[f,t]=react.useState(false),[a,l]=react.useState(null),c=react.useRef(true),u=react.useCallback(async()=>{if(e){t(true),l(null);try{let m=await o.getTensorStats(e);c.current&&s(m);}catch(m){c.current&&l(m.message);}finally{c.current&&t(false);}}},[o,e]);return react.useEffect(()=>(c.current=true,u(),()=>{c.current=false;}),[u]),{stats:n,loading:f,error:a,refresh:u}}function et(r){let e=b(r),[o,n]=react.useState(null),[s,f]=react.useState(false),[t,a]=react.useState(null),l=react.useRef(true),c=react.useCallback(async()=>{f(true),a(null);try{let u=await e.getNetworkStats();l.current&&n(u);}catch(u){l.current&&a(u.message);}finally{l.current&&f(false);}},[e]);return react.useEffect(()=>(l.current=true,c(),()=>{l.current=false;}),[c]),{stats:o,loading:s,error:t,refresh:c}}function rt(r,e=5,o=1){let n=b(r),[s,f]=react.useState([]),[t,a]=react.useState(null),[l,c]=react.useState(false),[u,m]=react.useState(null),d=react.useRef(true),g=react.useRef(null),p=react.useCallback(async w=>{c(true),m(null),g.current=null;try{let R=await n.getTrending(e,w??o);d.current&&(f(R.items),a(R.pagination),g.current=R.pagination.next_cursor);}catch(R){d.current&&m(R.message);}finally{d.current&&c(false);}},[n,e,o]),x=react.useCallback(async()=>{if(!(!g.current||l)){c(true);try{let w=await n.getTrending(e,o,g.current);d.current&&(f(R=>[...R,...w.items]),a(w.pagination),g.current=w.pagination.next_cursor);}catch(w){d.current&&m(w.message);}finally{d.current&&c(false);}}},[n,e,o,l]);return react.useEffect(()=>(d.current=true,p(),()=>{d.current=false;}),[p]),{repos:s,hasMore:t?.has_more??false,total:t?.total??0,loading:l,error:u,refresh:p,loadMore:x}}function ot(r,e){let o=b(r),[n,s]=react.useState({stars:0,starred:false,repo_id:e||""}),[f,t]=react.useState(false),[a,l]=react.useState(null),c=react.useRef(true),u=react.useCallback(async()=>{if(e)try{let d=await o.getStarInfo(e);c.current&&s(d);}catch{}},[o,e]);react.useEffect(()=>(c.current=true,u(),()=>{c.current=false;}),[u]);let m=react.useCallback(async()=>{if(e){t(true),l(null);try{let d=n.starred?await o.unstarRepo(e):await o.starRepo(e);c.current&&s({stars:d.stars,starred:d.starred,repo_id:e});}catch(d){c.current&&l(d.message);}finally{c.current&&t(false);}}},[o,e,n.starred]);return {...n,loading:f,error:a,toggle:m,refresh:u}}function N(...r){return tailwindMerge.twMerge(clsx.clsx(r))}var lt=/^(https?:\/\/|mailto:|\/[^/])/i;function ct(r){let e=r.trim();return lt.test(e)?e:null}function U(r){let e=[],o=/(`[^`]+`)|(\*\*(.+?)\*\*)|(\*(.+?)\*)|(_(.+?)_)|(\[([^\]]+)\]\(([^)]+)\))/g,n=0,s,f=0;for(;(s=o.exec(r))!==null;){s.index>n&&e.push(r.slice(n,s.index));let t=`i${f++}`;if(s[1])e.push(jsxRuntime.jsx("code",{className:"rounded bg-muted px-1.5 py-0.5 text-[0.85em] font-mono text-pink-400",children:s[1].slice(1,-1)},t));else if(s[2])e.push(jsxRuntime.jsx("strong",{children:s[3]},t));else if(s[4])e.push(jsxRuntime.jsx("em",{children:s[5]},t));else if(s[6])e.push(jsxRuntime.jsx("em",{children:s[7]},t));else if(s[8]){let a=ct(s[10]);a?e.push(jsxRuntime.jsx("a",{href:a,className:"text-blue-400 underline hover:text-blue-300",target:"_blank",rel:"noopener noreferrer",children:s[9]},t)):e.push(s[9]);}n=s.index+s[0].length;}return n<r.length&&e.push(r.slice(n)),e.length>0?e:[r]}function ut(r){let e=r.split(`
2
+ `),o=[],n=0;for(;n<e.length;){let s=e[n];if(s.trim()===""){n++;continue}if(/^(-{3,}|\*{3,}|_{3,})$/.test(s.trim())){o.push({type:"hr"}),n++;continue}let f=s.match(/^(#{1,6})\s+(.+)/);if(f){o.push({type:"heading",level:f[1].length,content:f[2]}),n++;continue}if(s.trim().startsWith("```")){let a=s.trim().slice(3).trim(),l=[];for(n++;n<e.length&&!e[n].trim().startsWith("```");)l.push(e[n]),n++;o.push({type:"code",content:l.join(`
3
+ `),lang:a||void 0}),n++;continue}if(/^\s*[-*+]\s/.test(s)){let a=[];for(;n<e.length&&/^\s*[-*+]\s/.test(e[n]);)a.push(e[n].replace(/^\s*[-*+]\s+/,"")),n++;o.push({type:"ul",items:a});continue}if(/^\s*\d+[.)]\s/.test(s)){let a=[];for(;n<e.length&&/^\s*\d+[.)]\s/.test(e[n]);)a.push(e[n].replace(/^\s*\d+[.)]\s+/,"")),n++;o.push({type:"ol",items:a});continue}let t=[];for(;n<e.length&&e[n].trim()!==""&&!e[n].match(/^#{1,6}\s/)&&!e[n].trim().startsWith("```")&&!/^\s*[-*+]\s/.test(e[n])&&!/^\s*\d+[.)]\s/.test(e[n]);)t.push(e[n]),n++;t.length>0&&o.push({type:"paragraph",content:t.join(" ")});}return o}var dt={1:"text-2xl font-bold mt-6 mb-3",2:"text-xl font-bold mt-5 mb-2",3:"text-lg font-semibold mt-4 mb-2",4:"text-base font-semibold mt-3 mb-1",5:"text-sm font-semibold mt-2 mb-1",6:"text-sm font-medium mt-2 mb-1"};function ft(r,e){switch(r.type){case "hr":return jsxRuntime.jsx("hr",{className:"my-4 border-border"},`b${e}`);case "heading":{let o=Math.min(Math.max(r.level||1,1),6),n=`h${o}`;return jsxRuntime.jsx(n,{className:N("text-foreground",dt[o]),children:U(r.content||"")},`b${e}`)}case "paragraph":return jsxRuntime.jsx("p",{className:"mb-3 leading-relaxed text-foreground",children:U(r.content||"")},`b${e}`);case "code":return jsxRuntime.jsx("pre",{className:"mb-3 overflow-x-auto rounded-lg bg-muted p-4 text-sm font-mono leading-relaxed text-foreground",children:jsxRuntime.jsx("code",{children:r.content})},`b${e}`);case "ul":return jsxRuntime.jsx("ul",{className:"mb-3 ml-5 list-disc space-y-1 text-foreground",children:r.items?.map((o,n)=>jsxRuntime.jsx("li",{className:"leading-relaxed",children:U(o)},`li${e}-${n}`))},`b${e}`);case "ol":return jsxRuntime.jsx("ol",{className:"mb-3 ml-5 list-decimal space-y-1 text-foreground",children:r.items?.map((o,n)=>jsxRuntime.jsx("li",{className:"leading-relaxed",children:U(o)},`li${e}-${n}`))},`b${e}`);default:return null}}function Q({content:r,className:e}){let o=ut(r);return jsxRuntime.jsx("div",{className:N("text-sm",e),children:o.map((n,s)=>ft(n,s))})}function xe({open:r,className:e}){return jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:N("shrink-0 transition-transform duration-150",r?"rotate-0":"-rotate-90",e),children:jsxRuntime.jsx("path",{d:"M16.134 6.16a.5.5 0 1 1 .732.68l-6.5 7-.077.068a.5.5 0 0 1-.655-.068l-6.5-7-.062-.08a.5.5 0 0 1 .718-.667l.076.067L10 12.767z"})})}function he({size:r=20,className:e}){return jsxRuntime.jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsxRuntime.jsx("path",{d:"M8.5 2a6.5 6.5 0 0 1 4.935 10.728l4.419 4.419.064.078a.5.5 0 0 1-.693.693l-.079-.064-4.419-4.42A6.5 6.5 0 1 1 8.5 2m0 1a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11"})})}function X({size:r=20,className:e}){return jsxRuntime.jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsxRuntime.jsx("path",{d:"M15.147 4.146a.5.5 0 0 1 .707.707L10.707 10l5.147 5.147a.5.5 0 0 1-.63.771l-.078-.064L10 10.707l-5.146 5.147a.5.5 0 0 1-.708-.707L9.293 10 4.146 4.853a.5.5 0 0 1 .708-.707L10 9.293z"})})}function we({size:r=20,className:e}){return jsxRuntime.jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsxRuntime.jsx("path",{d:"M10 3a.5.5 0 0 1 .5.5v6h6l.1.01a.5.5 0 0 1 0 .98l-.1.01h-6v6a.5.5 0 0 1-1 0v-6h-6a.5.5 0 0 1 0-1h6v-6A.5.5 0 0 1 10 3"})})}function pt(){return jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M6.5 3A2.5 2.5 0 0 0 4 5.5v9A2.5 2.5 0 0 0 6.5 17h7a2.5 2.5 0 0 0 2.5-2.5v-7A2.5 2.5 0 0 0 13.5 5H11V3.5a.5.5 0 0 0-1 0V5H6.5ZM5 5.5A1.5 1.5 0 0 1 6.5 4H9v1H6.5A1.5 1.5 0 0 0 5 6.5v8A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-7A1.5 1.5 0 0 0 13.5 6H11V4h2.5A2.5 2.5 0 0 1 16 6.5v8a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-9Z"})})}function ht(){return jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M5.5 3A2.5 2.5 0 0 0 3 5.5v9A2.5 2.5 0 0 0 5.5 17h9a2.5 2.5 0 0 0 2.5-2.5v-9A2.5 2.5 0 0 0 14.5 3h-9ZM4 5.5A1.5 1.5 0 0 1 5.5 4h9A1.5 1.5 0 0 1 16 5.5v9a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 4 14.5v-9ZM7 7.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5Z"})})}function yt(){return jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M10 2a.5.5 0 0 1 .354.146l3 3a.5.5 0 0 1-.708.708L10.5 3.707V12.5a.5.5 0 0 1-1 0V3.707L7.354 5.854a.5.5 0 1 1-.708-.708l3-3A.5.5 0 0 1 10 2ZM4 13.5a.5.5 0 0 1 1 0v1A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-1a.5.5 0 0 1 1 0v1a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-1Z"})})}function be(){let[r,e]=react.useState(false);return react.useEffect(()=>{if(typeof window>"u")return;let o=()=>e(window.innerWidth<768);return o(),window.addEventListener("resize",o),()=>window.removeEventListener("resize",o)},[]),r}function Re({onClose:r,children:e,title:o}){let n=be(),s=react.useRef(r);return s.current=r,react.useEffect(()=>{let f=t=>{t.key==="Escape"&&s.current();};return window.addEventListener("keydown",f),()=>window.removeEventListener("keydown",f)},[]),n?jsxRuntime.jsxs("div",{className:"fixed inset-0 z-50 flex items-end justify-center",onClick:r,children:[jsxRuntime.jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxRuntime.jsxs("div",{className:"relative z-10 w-full max-h-[90vh] overflow-y-auto rounded-t-2xl bg-[#1a1a1a] p-5 pb-8 animate-in slide-in-from-bottom duration-200",onClick:f=>f.stopPropagation(),children:[jsxRuntime.jsx("div",{className:"mx-auto mb-4 h-1 w-10 rounded-full bg-zinc-600"}),jsxRuntime.jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsxRuntime.jsx("h2",{className:"text-lg font-semibold text-foreground",children:o}),jsxRuntime.jsx("button",{onClick:r,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsxRuntime.jsx(X,{size:20})})]}),e]})]}):jsxRuntime.jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center",onClick:r,children:[jsxRuntime.jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxRuntime.jsxs("div",{className:"relative z-10 w-full max-w-lg overflow-y-auto rounded-2xl bg-[#1a1a1a] p-6 shadow-2xl animate-in fade-in zoom-in-95 duration-150",onClick:f=>f.stopPropagation(),children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsxRuntime.jsx("h2",{className:"text-lg font-semibold text-foreground",children:o}),jsxRuntime.jsx("button",{onClick:r,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsxRuntime.jsx(X,{size:20})})]}),e]})]})}function kt({onClose:r,onCreated:e,config:o}){let[n,s]=react.useState(""),[f,t]=react.useState(""),[a,l]=react.useState(""),[c,u]=react.useState(false),[m,d]=react.useState(null);return jsxRuntime.jsx(Re,{title:"Write skill instructions",onClose:r,children:jsxRuntime.jsxs("div",{className:"space-y-4",children:[jsxRuntime.jsxs("div",{className:"space-y-1.5",children:[jsxRuntime.jsx("label",{htmlFor:"skill-name",className:"text-sm text-muted-foreground",children:"Skill name"}),jsxRuntime.jsx("input",{id:"skill-name",value:n,onChange:p=>s(p.target.value),placeholder:"weekly-status-report",className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxRuntime.jsxs("div",{className:"space-y-1.5",children:[jsxRuntime.jsx("label",{htmlFor:"skill-desc",className:"text-sm text-muted-foreground",children:"Description"}),jsxRuntime.jsx("textarea",{id:"skill-desc",value:f,onChange:p=>t(p.target.value),placeholder:"Generate weekly status reports from recent work.",rows:3,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxRuntime.jsxs("div",{className:"space-y-1.5",children:[jsxRuntime.jsx("label",{htmlFor:"skill-instructions",className:"text-sm text-muted-foreground",children:"Instructions"}),jsxRuntime.jsx("textarea",{id:"skill-instructions",value:a,onChange:p=>l(p.target.value),placeholder:"Summarize my recent work in three sections: wins, blockers, and next steps.",rows:8,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),m&&jsxRuntime.jsx("p",{className:"text-sm text-red-500",children:m}),jsxRuntime.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[jsxRuntime.jsx("button",{onClick:r,className:"rounded-lg border border-zinc-700 px-4 py-2 text-sm text-foreground hover:bg-zinc-800",children:"Cancel"}),jsxRuntime.jsx("button",{onClick:async()=>{if(n.trim()){u(true),d(null);try{let p=o.apiBaseUrl||"",x=`# ${n.trim()}
4
4
 
5
- ${u.trim()}
5
+ ${f.trim()}
6
6
 
7
7
  ---
8
8
 
9
- ${a.trim()}`,S=await fetch(`${p}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:n.trim(),description:u.trim(),skill_md:v,content_type:"code"})});if(!S.ok){let T=`Failed to register skill (${S.status})`;try{let R=await S.json();R.error&&(T=R.error);}catch{}throw new Error(T)}e?.(),t();}catch(p){m(p instanceof Error?p.message:"Failed to create skill");}finally{d(false);}}},disabled:c||!n.trim(),className:"rounded-lg bg-zinc-600 px-4 py-2 text-sm font-medium text-white hover:bg-zinc-500 disabled:opacity-50",children:c?"Creating...":"Create"})]})]})})}function gt({onClose:t,onCreated:e,config:o}){let n=react.useRef(null),[s,u]=react.useState(false),[r,a]=react.useState(false),[l,c]=react.useState(null),d=async m=>{a(true),c(null);try{let g=await m.text(),p=o.apiBaseUrl||"",v=m.name.replace(/\.[^.]+$/,"").replace(/[^a-zA-Z0-9-_]/g,"-"),S=await fetch(`${p}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:v,skill_md:g,content_type:"code"})});if(!S.ok){let T=`Failed to register skill (${S.status})`;try{let R=await S.json();R.error&&(T=R.error);}catch{}throw new Error(T)}e?.(),t();}catch(g){c(g instanceof Error?g.message:"Upload failed");}finally{a(false);}};return jsxRuntime.jsx(he,{title:"Upload skill",onClose:t,children:jsxRuntime.jsxs("div",{className:"space-y-4",children:[jsxRuntime.jsxs("div",{onDragOver:m=>{m.preventDefault(),u(true);},onDragLeave:()=>u(false),onDrop:m=>{m.preventDefault(),u(false);let g=m.dataTransfer.files[0];g&&d(g);},onClick:()=>n.current?.click(),className:C("flex cursor-pointer flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed p-10 transition-colors",s?"border-zinc-400 bg-zinc-800/50":"border-zinc-700 hover:border-zinc-500"),children:[jsxRuntime.jsx("div",{className:"rounded-lg border border-zinc-600 p-2",children:jsxRuntime.jsx(ge,{size:20,className:"text-muted-foreground"})}),jsxRuntime.jsx("p",{className:"text-sm text-muted-foreground",children:r?"Uploading...":"Drag and drop or click to upload"})]}),jsxRuntime.jsx("input",{ref:n,type:"file",accept:".md,.zip,.skill,.txt,.yml,.yaml",className:"hidden","aria-label":"Upload skill file",onChange:m=>{let g=m.target.files?.[0];g&&d(g);}}),l&&jsxRuntime.jsx("p",{className:"text-sm text-red-500",children:l}),jsxRuntime.jsxs("div",{className:"space-y-2 text-xs text-muted-foreground",children:[jsxRuntime.jsx("p",{className:"font-medium text-foreground/70",children:"File requirements"}),jsxRuntime.jsxs("ul",{className:"list-disc pl-5 space-y-1",children:[jsxRuntime.jsx("li",{children:".md file must contain skill name and description formatted in YAML"}),jsxRuntime.jsx("li",{children:".zip or .skill file must include a SKILL.md file"})]})]})]})})}function pt({onClose:t,onSelect:e}){let o=pe(),n=react.useRef(null),s=react.useRef(t);s.current=t,react.useEffect(()=>{if(o)return;let r=a=>{n.current&&a.target instanceof Node&&!n.current.contains(a.target)&&s.current();};return document.addEventListener("mousedown",r),()=>document.removeEventListener("mousedown",r)},[o]);let u=[{id:"create-with-geoff",icon:jsxRuntime.jsx(ut,{}),label:"Create with Geoff"},{id:"write",icon:jsxRuntime.jsx(dt,{}),label:"Write skill instructions"},{id:"upload",icon:jsxRuntime.jsx(ft,{}),label:"Upload a skill"}];return o?jsxRuntime.jsxs("div",{className:"fixed inset-0 z-50 flex items-end",onClick:t,children:[jsxRuntime.jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxRuntime.jsxs("div",{className:"relative z-10 w-full rounded-t-2xl bg-[#1a1a1a] p-4 pb-8 animate-in slide-in-from-bottom duration-200",onClick:r=>r.stopPropagation(),children:[jsxRuntime.jsx("div",{className:"mx-auto mb-3 h-1 w-10 rounded-full bg-zinc-600"}),u.map(r=>jsxRuntime.jsxs("button",{onClick:()=>{e(r.id),t();},className:"flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-800",children:[r.icon,r.label]},r.id))]})]}):jsxRuntime.jsx("div",{ref:n,className:"absolute right-2 top-11 z-50 w-56 overflow-hidden rounded-xl border border-zinc-700 bg-[#2a2a2a] shadow-xl animate-in fade-in zoom-in-95 duration-100",children:u.map(r=>jsxRuntime.jsxs("button",{onClick:()=>{e(r.id),t();},className:"flex w-full items-center gap-3 px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-700/50",children:[r.icon,r.label]},r.id))})}function ht({entry:t,selected:e,onSelect:o,depth:n=0}){return jsxRuntime.jsxs("button",{onClick:()=>o(t),className:C("flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),style:{paddingLeft:`${8+n*16}px`},children:[jsxRuntime.jsx("span",{className:"truncate flex-1",children:t.path.split("/").pop()}),t.isDir&&jsxRuntime.jsx(me,{className:"ml-auto text-muted-foreground"})]})}function yt({repo:t,selected:e,expanded:o,onSelect:n,onToggle:s,children:u}){return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("button",{onClick:()=>{n(),s();},className:C("flex w-full items-center gap-2 rounded-md px-2 py-2 text-left text-sm font-medium transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),children:[jsxRuntime.jsx(me,{open:o}),jsxRuntime.jsx(lucideReact.FileText,{className:"h-4 w-4 shrink-0"}),jsxRuntime.jsx("span",{className:"truncate",children:t.name})]}),o&&u]})}function kt({entry:t,content:e,loading:o,repoName:n}){let[s,u]=react.useState(false),r=react.useRef(null);react.useEffect(()=>()=>{r.current&&clearTimeout(r.current);},[]);let[a,l]=react.useState(false),c=async()=>{if(e)try{await navigator.clipboard.writeText(e),u(!0),l(!1),r.current&&clearTimeout(r.current),r.current=setTimeout(()=>u(!1),2e3);}catch{l(true),r.current&&clearTimeout(r.current),r.current=setTimeout(()=>l(false),2e3);}};if(!t)return jsxRuntime.jsx("div",{className:"flex h-full items-center justify-center text-sm text-muted-foreground",children:"Select a file to view its content"});if(o)return jsxRuntime.jsx("div",{className:"flex h-full items-center justify-center",children:jsxRuntime.jsx(lucideReact.Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})});let d=t.path.split("/").pop()||t.path,f=/\.(md|mdx)$/i.test(d);return jsxRuntime.jsxs("div",{className:"flex h-full flex-col px-3",children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between px-4 py-3",children:[jsxRuntime.jsx("h3",{className:"text-sm sm:text-lg font-semibold text-foreground",children:d}),jsxRuntime.jsx("button",{onClick:c,"aria-label":"Copy file content",className:C("rounded p-1 transition-colors",s?"text-green-500":a?"text-red-500":"text-muted-foreground hover:text-foreground"),children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M12.5 3A1.5 1.5 0 0 1 14 4.5V6h1.5A1.5 1.5 0 0 1 17 7.5v8a1.5 1.5 0 0 1-1.5 1.5h-8A1.5 1.5 0 0 1 6 15.5V14H4.5A1.5 1.5 0 0 1 3 12.5v-8A1.5 1.5 0 0 1 4.5 3zm1.5 9.5a1.5 1.5 0 0 1-1.5 1.5H7v1.5a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5H14zM4.5 4a.5.5 0 0 0-.5.5v8a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5z"})})})]}),jsxRuntime.jsx("div",{className:"flex-1 overflow-auto p-4",children:f?jsxRuntime.jsx(V,{content:e||""}):jsxRuntime.jsx("pre",{className:"whitespace-pre-wrap text-sm text-foreground font-mono leading-relaxed",children:e||""})})]})}function xt({config:t,category:e,className:o,style:n}){let{repos:s,loading:u,error:r,refresh:a}=A(t),[l,c]=react.useState(null),[d,f]=react.useState(null),[m,g]=react.useState(null),[p,v]=react.useState(null),[S,T]=react.useState(false),[R,q]=react.useState(""),[ye,G]=react.useState(false),[Y,Q]=react.useState(false),[X,M]=react.useState(null),ke=s.find(y=>y.repo_id===l),{entries:xe,getFileContent:ee}=U(t,d),te=s.filter(y=>!R||y.name.toLowerCase().includes(R.toLowerCase())),we=react.useCallback(async y=>{if(!y.isDir){g(y),T(true);try{let N=await ee(y.cid);v(N);}catch(N){let ve=N instanceof Error?N.message:"Unknown error";v(`Failed to load file: ${ve}`);}finally{T(false);}}},[ee]);react.useEffect(()=>{s.length>0&&!l&&(c(s[0].repo_id),f(s[0].repo_id));},[s,l]);let be=y=>{y==="create-with-geoff"?window.open(`https://www.geoff.ai/?p=${encodeURIComponent("Let's create a skill together using your skill-creator skill. First ask me what the skill should do.")}`,"_blank","noopener,noreferrer"):M(y);};return jsxRuntime.jsxs("div",{className:C("flex flex-1 h-full min-h-0",o),style:n,children:[jsxRuntime.jsxs("div",{className:"relative flex w-96 shrink-0 flex-col border-r",children:[jsxRuntime.jsx("div",{className:"flex h-12 items-center gap-2 px-3",children:ye?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{className:"flex flex-1 items-center gap-2 rounded-md border bg-muted/50 px-2 py-1",children:[jsxRuntime.jsx(ue,{size:16,className:"shrink-0 text-muted-foreground"}),jsxRuntime.jsx("input",{type:"text",value:R,onChange:y=>q(y.target.value),placeholder:"Search",autoFocus:true,"aria-label":"Search items",className:"flex-1 bg-transparent text-xs text-foreground placeholder:text-muted-foreground focus:outline-none"})]}),jsxRuntime.jsx("button",{onClick:()=>{G(false),q("");},className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsxRuntime.jsx(Z,{size:16})})]}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("h3",{className:"flex-1 text-sm sm:text-lg font-semibold text-foreground capitalize",children:e||"Items"}),jsxRuntime.jsx("button",{onClick:()=>G(true),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Search",children:jsxRuntime.jsx(ue,{size:20})}),jsxRuntime.jsx("button",{onClick:()=>Q(!Y),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Add new",children:jsxRuntime.jsx(ge,{size:20})})]})}),Y&&jsxRuntime.jsx(pt,{onClose:()=>Q(false),onSelect:be}),jsxRuntime.jsx("div",{className:"flex-1 overflow-y-auto p-2",children:u?jsxRuntime.jsx("div",{className:"flex items-center justify-center py-8",children:jsxRuntime.jsx(lucideReact.Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})}):r?jsxRuntime.jsx("p",{className:"px-2 py-4 text-xs text-red-500",children:r}):te.length===0?jsxRuntime.jsx("p",{className:"px-2 py-4 text-xs text-muted-foreground",children:R?"No matching items":"No items yet"}):jsxRuntime.jsx("div",{className:"space-y-0.5",children:te.map(y=>jsxRuntime.jsx(yt,{repo:y,selected:l===y.repo_id,expanded:d===y.repo_id,onSelect:()=>{c(y.repo_id),g(null),v(null);},onToggle:()=>f(d===y.repo_id?null:y.repo_id),children:jsxRuntime.jsx("div",{className:"ml-10 pl-1",children:xe.map(N=>jsxRuntime.jsx(ht,{entry:N,selected:m?.path===N.path,onSelect:we,depth:N.path.split("/").length-1},N.path))})},y.repo_id))})})]}),jsxRuntime.jsx("div",{className:"flex-1 min-w-0",children:jsxRuntime.jsx(kt,{entry:m,content:p,loading:S,repoName:ke?.name||""})}),X==="write"&&jsxRuntime.jsx(mt,{config:t,onClose:()=>M(null),onCreated:a}),X==="upload"&&jsxRuntime.jsx(gt,{config:t,onClose:()=>M(null),onCreated:a})]})}
10
- exports.Markdown=V;exports.RackBrowser=xt;exports.estimateCost=le;exports.useNetworkStats=Ve;exports.useRackClient=x;exports.useRackRegister=Le;exports.useRackSession=ze;exports.useRepoPush=Me;exports.useRepoTree=U;exports.useRepos=A;exports.useSkillStats=Oe;exports.useStar=et;exports.useTensorStats=He;exports.useTrending=Ye;
9
+ ${a.trim()}`,w=await fetch(`${p}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:n.trim(),description:f.trim(),skill_md:x,content_type:"code"})});if(!w.ok){let R=`Failed to register skill (${w.status})`;try{let C=await w.json();C.error&&(R=C.error);}catch{}throw new Error(R)}e?.(),r();}catch(p){d(p instanceof Error?p.message:"Failed to create skill");}finally{u(false);}}},disabled:c||!n.trim(),className:"rounded-lg bg-zinc-600 px-4 py-2 text-sm font-medium text-white hover:bg-zinc-500 disabled:opacity-50",children:c?"Creating...":"Create"})]})]})})}function xt({onClose:r,onCreated:e,config:o}){let n=react.useRef(null),[s,f]=react.useState(false),[t,a]=react.useState(false),[l,c]=react.useState(null),u=async d=>{a(true),c(null);try{let g=await d.text(),p=o.apiBaseUrl||"",x=d.name.replace(/\.[^.]+$/,"").replace(/[^a-zA-Z0-9-_]/g,"-"),w=await fetch(`${p}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:x,skill_md:g,content_type:"code"})});if(!w.ok){let R=`Failed to register skill (${w.status})`;try{let C=await w.json();C.error&&(R=C.error);}catch{}throw new Error(R)}e?.(),r();}catch(g){c(g instanceof Error?g.message:"Upload failed");}finally{a(false);}};return jsxRuntime.jsx(Re,{title:"Upload skill",onClose:r,children:jsxRuntime.jsxs("div",{className:"space-y-4",children:[jsxRuntime.jsxs("div",{onDragOver:d=>{d.preventDefault(),f(true);},onDragLeave:()=>f(false),onDrop:d=>{d.preventDefault(),f(false);let g=d.dataTransfer.files[0];g&&u(g);},onClick:()=>n.current?.click(),className:N("flex cursor-pointer flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed p-10 transition-colors",s?"border-zinc-400 bg-zinc-800/50":"border-zinc-700 hover:border-zinc-500"),children:[jsxRuntime.jsx("div",{className:"rounded-lg border border-zinc-600 p-2",children:jsxRuntime.jsx(we,{size:20,className:"text-muted-foreground"})}),jsxRuntime.jsx("p",{className:"text-sm text-muted-foreground",children:t?"Uploading...":"Drag and drop or click to upload"})]}),jsxRuntime.jsx("input",{ref:n,type:"file",accept:".md,.zip,.skill,.txt,.yml,.yaml",className:"hidden","aria-label":"Upload skill file",onChange:d=>{let g=d.target.files?.[0];g&&u(g);}}),l&&jsxRuntime.jsx("p",{className:"text-sm text-red-500",children:l}),jsxRuntime.jsxs("div",{className:"space-y-2 text-xs text-muted-foreground",children:[jsxRuntime.jsx("p",{className:"font-medium text-foreground/70",children:"File requirements"}),jsxRuntime.jsxs("ul",{className:"list-disc pl-5 space-y-1",children:[jsxRuntime.jsx("li",{children:".md file must contain skill name and description formatted in YAML"}),jsxRuntime.jsx("li",{children:".zip or .skill file must include a SKILL.md file"})]})]})]})})}function wt({onClose:r,onSelect:e}){let o=be(),n=react.useRef(null),s=react.useRef(r);s.current=r,react.useEffect(()=>{if(o)return;let t=a=>{n.current&&a.target instanceof Node&&!n.current.contains(a.target)&&s.current();};return document.addEventListener("mousedown",t),()=>document.removeEventListener("mousedown",t)},[o]);let f=[{id:"create-with-geoff",icon:jsxRuntime.jsx(pt,{}),label:"Create with Geoff"},{id:"write",icon:jsxRuntime.jsx(ht,{}),label:"Write skill instructions"},{id:"upload",icon:jsxRuntime.jsx(yt,{}),label:"Upload a skill"}];return o?jsxRuntime.jsxs("div",{className:"fixed inset-0 z-50 flex items-end",onClick:r,children:[jsxRuntime.jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxRuntime.jsxs("div",{className:"relative z-10 w-full rounded-t-2xl bg-[#1a1a1a] p-4 pb-8 animate-in slide-in-from-bottom duration-200",onClick:t=>t.stopPropagation(),children:[jsxRuntime.jsx("div",{className:"mx-auto mb-3 h-1 w-10 rounded-full bg-zinc-600"}),f.map(t=>jsxRuntime.jsxs("button",{onClick:()=>{e(t.id),r();},className:"flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-800",children:[t.icon,t.label]},t.id))]})]}):jsxRuntime.jsx("div",{ref:n,className:"absolute right-2 top-11 z-50 w-56 overflow-hidden rounded-xl border border-zinc-700 bg-[#2a2a2a] shadow-xl animate-in fade-in zoom-in-95 duration-100",children:f.map(t=>jsxRuntime.jsxs("button",{onClick:()=>{e(t.id),r();},className:"flex w-full items-center gap-3 px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-700/50",children:[t.icon,t.label]},t.id))})}function bt({entry:r,selected:e,onSelect:o,depth:n=0}){return jsxRuntime.jsxs("button",{onClick:()=>o(r),className:N("flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),style:{paddingLeft:`${8+n*16}px`},children:[jsxRuntime.jsx("span",{className:"truncate flex-1",children:r.path.split("/").pop()}),r.isDir&&jsxRuntime.jsx(xe,{className:"ml-auto text-muted-foreground"})]})}function Rt({repo:r,selected:e,expanded:o,onSelect:n,onToggle:s,children:f}){return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("button",{onClick:()=>{n(),s();},className:N("flex w-full items-center gap-2 rounded-md px-2 py-2 text-left text-sm font-medium transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),children:[jsxRuntime.jsx(xe,{open:o}),jsxRuntime.jsx(lucideReact.FileText,{className:"h-4 w-4 shrink-0"}),jsxRuntime.jsx("span",{className:"truncate",children:r.name})]}),o&&f]})}function vt({entry:r,content:e,loading:o,repoName:n}){let[s,f]=react.useState(false),t=react.useRef(null);react.useEffect(()=>()=>{t.current&&clearTimeout(t.current);},[]);let[a,l]=react.useState(false),c=async()=>{if(e)try{await navigator.clipboard.writeText(e),f(!0),l(!1),t.current&&clearTimeout(t.current),t.current=setTimeout(()=>f(!1),2e3);}catch{l(true),t.current&&clearTimeout(t.current),t.current=setTimeout(()=>l(false),2e3);}};if(!r)return jsxRuntime.jsx("div",{className:"flex h-full items-center justify-center text-sm text-muted-foreground",children:"Select a file to view its content"});if(o)return jsxRuntime.jsx("div",{className:"flex h-full items-center justify-center",children:jsxRuntime.jsx(lucideReact.Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})});let u=r.path.split("/").pop()||r.path,m=/\.(md|mdx)$/i.test(u);return jsxRuntime.jsxs("div",{className:"flex h-full flex-col px-3",children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between px-4 py-3",children:[jsxRuntime.jsx("h3",{className:"text-sm sm:text-lg font-semibold text-foreground",children:u}),jsxRuntime.jsx("button",{onClick:c,"aria-label":"Copy file content",className:N("rounded p-1 transition-colors",s?"text-green-500":a?"text-red-500":"text-muted-foreground hover:text-foreground"),children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsxRuntime.jsx("path",{d:"M12.5 3A1.5 1.5 0 0 1 14 4.5V6h1.5A1.5 1.5 0 0 1 17 7.5v8a1.5 1.5 0 0 1-1.5 1.5h-8A1.5 1.5 0 0 1 6 15.5V14H4.5A1.5 1.5 0 0 1 3 12.5v-8A1.5 1.5 0 0 1 4.5 3zm1.5 9.5a1.5 1.5 0 0 1-1.5 1.5H7v1.5a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5H14zM4.5 4a.5.5 0 0 0-.5.5v8a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5z"})})})]}),jsxRuntime.jsx("div",{className:"flex-1 overflow-auto p-4",children:m?jsxRuntime.jsx(Q,{content:e||""}):jsxRuntime.jsx("pre",{className:"whitespace-pre-wrap text-sm text-foreground font-mono leading-relaxed",children:e||""})})]})}function St({config:r,category:e,className:o,style:n}){let{repos:s,loading:f,error:t,refresh:a}=D(r),[l,c]=react.useState(null),[u,m]=react.useState(null),[d,g]=react.useState(null),[p,x]=react.useState(null),[w,R]=react.useState(false),[C,I]=react.useState(""),[P,M]=react.useState(false),[ee,te]=react.useState(false),[re,A]=react.useState(null),ve=s.find(y=>y.repo_id===l),{entries:Se,getFileContent:ne}=H(r,u),se=s.filter(y=>!C||y.name.toLowerCase().includes(C.toLowerCase())),Ce=react.useCallback(async y=>{if(!y.isDir){g(y),R(true);try{let T=await ne(y.cid);x(T);}catch(T){let Te=T instanceof Error?T.message:"Unknown error";x(`Failed to load file: ${Te}`);}finally{R(false);}}},[ne]);react.useEffect(()=>{s.length>0&&!l&&(c(s[0].repo_id),m(s[0].repo_id));},[s,l]);let Ne=y=>{y==="create-with-geoff"?window.open(`https://www.geoff.ai/?p=${encodeURIComponent("Let's create a skill together using your skill-creator skill. First ask me what the skill should do.")}`,"_blank","noopener,noreferrer"):A(y);};return jsxRuntime.jsxs("div",{className:N("flex flex-1 h-full min-h-0",o),style:n,children:[jsxRuntime.jsxs("div",{className:"relative flex w-96 shrink-0 flex-col border-r",children:[jsxRuntime.jsx("div",{className:"flex h-12 items-center gap-2 px-3",children:P?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{className:"flex flex-1 items-center gap-2 rounded-md border bg-muted/50 px-2 py-1",children:[jsxRuntime.jsx(he,{size:16,className:"shrink-0 text-muted-foreground"}),jsxRuntime.jsx("input",{type:"text",value:C,onChange:y=>I(y.target.value),placeholder:"Search",autoFocus:true,"aria-label":"Search items",className:"flex-1 bg-transparent text-xs text-foreground placeholder:text-muted-foreground focus:outline-none"})]}),jsxRuntime.jsx("button",{onClick:()=>{M(false),I("");},className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsxRuntime.jsx(X,{size:16})})]}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("h3",{className:"flex-1 text-sm sm:text-lg font-semibold text-foreground capitalize",children:e||"Items"}),jsxRuntime.jsx("button",{onClick:()=>M(true),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Search",children:jsxRuntime.jsx(he,{size:20})}),jsxRuntime.jsx("button",{onClick:()=>te(!ee),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Add new",children:jsxRuntime.jsx(we,{size:20})})]})}),ee&&jsxRuntime.jsx(wt,{onClose:()=>te(false),onSelect:Ne}),jsxRuntime.jsx("div",{className:"flex-1 overflow-y-auto p-2",children:f?jsxRuntime.jsx("div",{className:"flex items-center justify-center py-8",children:jsxRuntime.jsx(lucideReact.Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})}):t?jsxRuntime.jsx("p",{className:"px-2 py-4 text-xs text-red-500",children:t}):se.length===0?jsxRuntime.jsx("p",{className:"px-2 py-4 text-xs text-muted-foreground",children:C?"No matching items":"No items yet"}):jsxRuntime.jsx("div",{className:"space-y-0.5",children:se.map(y=>jsxRuntime.jsx(Rt,{repo:y,selected:l===y.repo_id,expanded:u===y.repo_id,onSelect:()=>{c(y.repo_id),g(null),x(null);},onToggle:()=>m(u===y.repo_id?null:y.repo_id),children:jsxRuntime.jsx("div",{className:"ml-10 pl-1",children:Se.map(T=>jsxRuntime.jsx(bt,{entry:T,selected:d?.path===T.path,onSelect:Ce,depth:T.path.split("/").length-1},T.path))})},y.repo_id))})})]}),jsxRuntime.jsx("div",{className:"flex-1 min-w-0",children:jsxRuntime.jsx(vt,{entry:d,content:p,loading:w,repoName:ve?.name||""})}),re==="write"&&jsxRuntime.jsx(kt,{config:r,onClose:()=>A(null),onCreated:a}),re==="upload"&&jsxRuntime.jsx(xt,{config:r,onClose:()=>A(null),onCreated:a})]})}
10
+ exports.Markdown=Q;exports.RackBrowser=St;exports.estimateCost=fe;exports.useNetworkStats=et;exports.usePaginatedRepos=Oe;exports.useRackClient=b;exports.useRackRegister=Fe;exports.useRackSession=De;exports.useRepoPush=Ae;exports.useRepoTree=H;exports.useRepos=D;exports.useSkillStats=Je;exports.useStar=ot;exports.useTensorStats=Ge;exports.useTrending=rt;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- export { CostEstimate, DiffEntry, InitResult, NetworkStats, PushResult, RackConfig, RackSession, RepoCommit, RepoFile, RepoInfo, RepoTree, SkillMeta, SkillRegistrationInput, SkillRegistrationResult, SkillStats, StarInfo, StarResult, TensorMeta, TensorRegistrationInput, TensorRegistrationResult, TensorStats, TokenBudget, TreeEntry, TrendingRepo } from './types/index.cjs';
2
- export { RackClient, estimateCost, useNetworkStats, useRackClient, useRackRegister, useRackSession, useRepoPush, useRepoTree, useRepos, useSkillStats, useStar, useTensorStats, useTrending } from './hooks/index.cjs';
1
+ export { CostEstimate, DiffEntry, InitResult, NetworkStats, PaginatedResult, PaginationInfo, PaginationParams, PushResult, RackConfig, RackSession, RepoCommit, RepoFile, RepoInfo, RepoTree, SkillMeta, SkillRegistrationInput, SkillRegistrationResult, SkillStats, StarInfo, StarResult, TensorMeta, TensorRegistrationInput, TensorRegistrationResult, TensorStats, TokenBudget, TreeEntry, TrendingRepo } from './types/index.cjs';
2
+ export { RackClient, estimateCost, useNetworkStats, usePaginatedRepos, useRackClient, useRackRegister, useRackSession, useRepoPush, useRepoTree, useRepos, useSkillStats, useStar, useTensorStats, useTrending } from './hooks/index.cjs';
3
3
  export { Markdown, RackBrowser, RackBrowserProps } from './components/index.cjs';
4
4
  import 'react/jsx-runtime';
5
5
  import 'react';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { CostEstimate, DiffEntry, InitResult, NetworkStats, PushResult, RackConfig, RackSession, RepoCommit, RepoFile, RepoInfo, RepoTree, SkillMeta, SkillRegistrationInput, SkillRegistrationResult, SkillStats, StarInfo, StarResult, TensorMeta, TensorRegistrationInput, TensorRegistrationResult, TensorStats, TokenBudget, TreeEntry, TrendingRepo } from './types/index.js';
2
- export { RackClient, estimateCost, useNetworkStats, useRackClient, useRackRegister, useRackSession, useRepoPush, useRepoTree, useRepos, useSkillStats, useStar, useTensorStats, useTrending } from './hooks/index.js';
1
+ export { CostEstimate, DiffEntry, InitResult, NetworkStats, PaginatedResult, PaginationInfo, PaginationParams, PushResult, RackConfig, RackSession, RepoCommit, RepoFile, RepoInfo, RepoTree, SkillMeta, SkillRegistrationInput, SkillRegistrationResult, SkillStats, StarInfo, StarResult, TensorMeta, TensorRegistrationInput, TensorRegistrationResult, TensorStats, TokenBudget, TreeEntry, TrendingRepo } from './types/index.js';
2
+ export { RackClient, estimateCost, useNetworkStats, usePaginatedRepos, useRackClient, useRackRegister, useRackSession, useRepoPush, useRepoTree, useRepos, useSkillStats, useStar, useTensorStats, useTrending } from './hooks/index.js';
3
3
  export { Markdown, RackBrowser, RackBrowserProps } from './components/index.js';
4
4
  import 'react/jsx-runtime';
5
5
  import 'react';
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import {useMemo,useRef,useState,useCallback,useEffect}from'react';import {Loader2,FileText}from'lucide-react';import {clsx}from'clsx';import {twMerge}from'tailwind-merge';import {jsx,jsxs,Fragment}from'react/jsx-runtime';async function w(t,e,o,n){let s={"Content-Type":"application/json",...o?.headers};n&&(s.Authorization=`Bearer ${n}`);let u=await fetch(`${t}${e}`,{...o,headers:s});if(!u.ok){let r=`HTTP ${u.status}`;try{let a=await u.json();a.error&&(r=a.error);}catch{}throw new Error(r)}return u.json()}function I(t){let e=t.indexOf(":");return {mode:t.slice(0,e),cid:t.slice(e+1)}}function x(t){let e=t.apiBaseUrl,o=t.authorMid,n=t.ownerMid,s=t.apiKey,u=t.stacknetUrl||t.apiBaseUrl;return useMemo(()=>({async listRepos(r){let a=r||n?`?owner=${encodeURIComponent(r||n)}`:"";return (await w(e,`/api/rack/repos${a}`,void 0,s)).repos||[]},async initRepo(r){return w(e,"/api/rack/init",{method:"POST",body:JSON.stringify({...r,owner_mid:n})},s)},async push(r,a){return w(e,`/api/rack/${r}/push`,{method:"POST",body:JSON.stringify({...a,author_mid:o})},s)},async getTree(r,a="main"){let l=await w(e,`/api/rack/${r}/tree/${a}`,void 0,s);return {tree:l.tree,commit_cid:l.commit_cid}},async getBlob(r,a){return (await w(e,`/api/rack/${r}/blob/${a}`,void 0,s)).content},async getLog(r,a,l){let c=new URLSearchParams;a&&c.set("ref",a),l&&c.set("max_count",String(l));let d=c.toString()?`?${c}`:"";return (await w(e,`/api/rack/${r}/log${d}`,void 0,s)).commits||[]},async getBranches(r){return (await w(e,`/api/rack/${r}/branches`,void 0,s)).branches||[]},async createBranch(r,a,l){return w(e,`/api/rack/${r}/branch`,{method:"POST",body:JSON.stringify({branch_name:a,from_ref:l})},s)},async merge(r,a,l){return w(e,`/api/rack/${r}/merge`,{method:"POST",body:JSON.stringify({source_branch:a,target_branch:l})},s)},async getDiff(r,a,l){return (await w(e,`/api/rack/${r}/diff/${a}/${l}`,void 0,s)).diff?.entries||[]},async starRepo(r){return w(e,`/api/rack/${r}/star`,{method:"POST"},s)},async unstarRepo(r){return w(e,`/api/rack/${r}/star`,{method:"DELETE"},s)},async getStarInfo(r){return w(e,`/api/rack/${r}/stars`,void 0,s)},async getSkillStats(r){let a={meta:null,tokenCount:null,usageCount:null};try{let{tree:l}=await this.getTree(r,"main");if(!l?.entries)return a;if(l.entries["META.json"]){let f=I(l.entries["META.json"]).cid,m=await this.getBlob(r,f);a.meta=JSON.parse(m);}let c=0,d=Object.values(l.entries).map(async f=>{try{let m=I(f).cid,g=await this.getBlob(r,m);c+=g.length;}catch{}});await Promise.all(d),c>0&&(a.tokenCount=Math.ceil(c/4)),a.meta?.skill_id&&(a.usageCount=await this.getSkillUsageCount(a.meta.skill_id));}catch{}return a},async getSkillUsageCount(r){try{let a=await fetch(`${u}/v1/skills/${encodeURIComponent(r)}`);if(a.ok){let c=await a.json();return c.usage_count??c.usageCount??null}let l=await fetch(`${u}/v1/skills?scope=public`);if(l.ok){let d=((await l.json()).skills||[]).find(f=>f.name===r||f.id===r);if(d)return d.usage_count??d.usageCount??0}return 0}catch{return null}},async getTensorStats(r){let a={meta:null,sizeMB:null};try{let{tree:l}=await this.getTree(r,"main");if(!l?.entries)return a;if(l.entries["TENSOR_META.json"]){let c=I(l.entries["TENSOR_META.json"]).cid,d=await this.getBlob(r,c);a.meta=JSON.parse(d),a.sizeMB=a.meta?.tensor_size_mb??null;}}catch{}return a},async getNetworkStats(){try{return (await w(e,"/api/rack/stats",void 0,s)).stats||null}catch{return null}},async getTrending(r=5,a=1){try{return (await w(e,`/api/rack/trending?limit=${r}&days=${a}`,void 0,s)).trending||[]}catch{return []}}}),[e,o,n,s,u])}function A(t){let e=x(t),o=useRef(e);o.current=e;let[n,s]=useState([]),[u,r]=useState(true),[a,l]=useState(null),c=useRef(true),d=useRef(null),f=useCallback(async()=>{d.current?.abort();let m=new AbortController;d.current=m;try{c.current&&(r(!0),l(null));let g=await o.current.listRepos();c.current&&!m.signal.aborted&&s(g);}catch(g){c.current&&!m.signal.aborted&&l(g instanceof Error?g.message:"Failed to load repos");}finally{c.current&&!m.signal.aborted&&r(false);}},[]);return useEffect(()=>(c.current=true,f(),()=>{c.current=false,d.current?.abort();}),[f]),{repos:n,loading:u,error:a,refresh:f}}function Ee(t){return Object.entries(t).map(([e,o])=>{let n=o.indexOf(":"),s=n>0?o.slice(0,n):"100644",u=n>0?o.slice(n+1):o;return {path:e,mode:s,cid:u,isDir:s==="040000"}}).sort((e,o)=>e.isDir!==o.isDir?e.isDir?-1:1:e.path.localeCompare(o.path))}function U(t,e,o="main"){let n=x(t),[s,u]=useState([]),[r,a]=useState(false),[l,c]=useState(null),d=useRef(true),f=useCallback(async()=>{if(e)try{d.current&&(a(!0),c(null));let{tree:g}=await n.getTree(e,o);d.current&&u(Ee(g.entries));}catch(g){d.current&&c(g instanceof Error?g.message:"Failed to load tree");}finally{d.current&&a(false);}},[n,e,o]);useEffect(()=>(d.current=true,f(),()=>{d.current=false;}),[f]);let m=useCallback(async g=>{if(!e)throw new Error("No repo selected");return n.getBlob(e,g)},[n,e]);return {entries:s,loading:r,error:l,refresh:f,getFileContent:m}}function Me(t){let e=x(t),[o,n]=useState(false),[s,u]=useState(null),r=useRef(true);return useEffect(()=>(r.current=true,()=>{r.current=false;}),[]),{push:useCallback(async(l,c,d,f)=>{try{return r.current&&(n(!0),u(null)),await e.push(l,{files:c,message:d,branch:f})}catch(m){let g=m instanceof Error?m.message:"Push failed";return r.current&&u(g),null}finally{r.current&&n(false);}},[e]),pushing:o,error:s}}var j="stacknet-rack-apikey";function ze(t){let e=t.stacknetUrl||t.apiBaseUrl,[o,n]=useState({authenticated:false}),[s,u]=useState(null),[r,a]=useState(false),l=useCallback(m=>({"Content-Type":"application/json",...m||t.apiKey?{Authorization:`Bearer ${m||t.apiKey}`}:{}}),[t.apiKey]),c=useCallback(async m=>{a(true);try{let g=await fetch(`${e}/health`,{headers:l(m)});if(!g.ok)throw new Error(`Authentication failed: ${g.status}`);let p={authenticated:!0,apiKey:m,permission:m.startsWith("gk_")?"write":"read"};n(p);try{localStorage.setItem(j,m);}catch{}return p}catch(g){throw n({authenticated:false}),g}finally{a(false);}},[e,l]),d=useCallback(()=>{n({authenticated:false}),u(null);try{localStorage.removeItem(j);}catch{}},[]),f=useCallback(async()=>{let m=o.apiKey||t.apiKey;if(!m)return null;try{let g=await fetch(`${e}/network/usage`,{headers:l(m)});if(!g.ok)return null;let p=await g.json(),v={planAllocation:p.plan_allocation??p.planAllocation??0,inferenceUsed:p.inference_used??p.inferenceUsed??0,ledgerSpent:p.ledger_spent??p.ledgerSpent??0,totalUsed:p.total_used??p.totalUsed??0,remaining:p.remaining??0,percent:p.percent??0,exceeded:p.exceeded??!1};return u(v),v}catch{return null}},[o.apiKey,t.apiKey,e,l]);return useEffect(()=>{let m=t.apiKey;if(m){n({authenticated:true,apiKey:m,permission:m.startsWith("gk_")?"write":"read"});return}try{let g=localStorage.getItem(j);g&&n({authenticated:!0,apiKey:g,permission:g.startsWith("gk_")?"write":"read"});}catch{}},[t.apiKey]),{session:o,budget:s,loading:r,login:c,logout:d,refreshBudget:f}}var oe=1e3,ae=1e3,ie=100;function le(t,e){if(t==="skill"){let s=ie+Math.ceil(e/4);return {type:t,totalBytes:e,totalMegabytes:e/1e6,baseCost:s,multiplier:oe,registrationCostTokens:s*oe}}let o=Math.ceil(e/1e6),n=ie+o;return {type:t,totalBytes:e,totalMegabytes:o,baseCost:n,multiplier:ae,registrationCostTokens:n*ae}}function Le(t){let e=t.stacknetUrl||t.apiBaseUrl,o=t.apiKey,[n,s]=useState(false),[u,r]=useState(null),a=useCallback(()=>{if(!o)throw new Error("API key required for registration. Call login() first.");return {"Content-Type":"application/json",Authorization:`Bearer ${o}`}},[o]),l=useCallback(async d=>{s(true),r(null);try{let f=await fetch(`${e}/skills`,{method:"POST",headers:a(),body:JSON.stringify(d)});if(!f.ok){let m=await f.json().catch(()=>({error:`HTTP ${f.status}`}));throw new Error(m.error||`Registration failed: ${f.status}`)}return await f.json()}catch(f){throw r(f.message),f}finally{s(false);}},[e,a]),c=useCallback(async d=>{s(true),r(null);try{let f=await fetch(`${e}/tensors`,{method:"POST",headers:a(),body:JSON.stringify(d)});if(!f.ok){let m=await f.json().catch(()=>({error:`HTTP ${f.status}`}));throw new Error(m.error||`Registration failed: ${f.status}`)}return await f.json()}catch(f){throw r(f.message),f}finally{s(false);}},[e,a]);return {registerSkill:l,registerTensor:c,estimateCost:le,registering:n,error:u}}function Oe(t,e){let o=x(t),[n,s]=useState({meta:null,tokenCount:null,usageCount:null}),[u,r]=useState(false),[a,l]=useState(null),c=useRef(true),d=useCallback(async()=>{if(e){r(true),l(null);try{let f=await o.getSkillStats(e);c.current&&s(f);}catch(f){c.current&&l(f.message);}finally{c.current&&r(false);}}},[o,e]);return useEffect(()=>(c.current=true,d(),()=>{c.current=false;}),[d]),{stats:n,loading:u,error:a,refresh:d}}function He(t,e){let o=x(t),[n,s]=useState({meta:null,sizeMB:null}),[u,r]=useState(false),[a,l]=useState(null),c=useRef(true),d=useCallback(async()=>{if(e){r(true),l(null);try{let f=await o.getTensorStats(e);c.current&&s(f);}catch(f){c.current&&l(f.message);}finally{c.current&&r(false);}}},[o,e]);return useEffect(()=>(c.current=true,d(),()=>{c.current=false;}),[d]),{stats:n,loading:u,error:a,refresh:d}}function Ve(t){let e=x(t),[o,n]=useState(null),[s,u]=useState(false),[r,a]=useState(null),l=useRef(true),c=useCallback(async()=>{u(true),a(null);try{let d=await e.getNetworkStats();l.current&&n(d);}catch(d){l.current&&a(d.message);}finally{l.current&&u(false);}},[e]);return useEffect(()=>(l.current=true,c(),()=>{l.current=false;}),[c]),{stats:o,loading:s,error:r,refresh:c}}function Ye(t,e=5,o=1){let n=x(t),[s,u]=useState([]),[r,a]=useState(false),[l,c]=useState(null),d=useRef(true),f=useCallback(async m=>{a(true),c(null);try{let g=await n.getTrending(e,m??o);d.current&&u(g);}catch(g){d.current&&c(g.message);}finally{d.current&&a(false);}},[n,e,o]);return useEffect(()=>(d.current=true,f(),()=>{d.current=false;}),[f]),{repos:s,loading:r,error:l,refresh:f}}function et(t,e){let o=x(t),[n,s]=useState({stars:0,starred:false,repo_id:e||""}),[u,r]=useState(false),[a,l]=useState(null),c=useRef(true),d=useCallback(async()=>{if(e)try{let m=await o.getStarInfo(e);c.current&&s(m);}catch{}},[o,e]);useEffect(()=>(c.current=true,d(),()=>{c.current=false;}),[d]);let f=useCallback(async()=>{if(e){r(true),l(null);try{let m=n.starred?await o.unstarRepo(e):await o.starRepo(e);c.current&&s({stars:m.stars,starred:m.starred,repo_id:e});}catch(m){c.current&&l(m.message);}finally{c.current&&r(false);}}},[o,e,n.starred]);return {...n,loading:u,error:a,toggle:f,refresh:d}}function C(...t){return twMerge(clsx(t))}var nt=/^(https?:\/\/|mailto:|\/[^/])/i;function st(t){let e=t.trim();return nt.test(e)?e:null}function _(t){let e=[],o=/(`[^`]+`)|(\*\*(.+?)\*\*)|(\*(.+?)\*)|(_(.+?)_)|(\[([^\]]+)\]\(([^)]+)\))/g,n=0,s,u=0;for(;(s=o.exec(t))!==null;){s.index>n&&e.push(t.slice(n,s.index));let r=`i${u++}`;if(s[1])e.push(jsx("code",{className:"rounded bg-muted px-1.5 py-0.5 text-[0.85em] font-mono text-pink-400",children:s[1].slice(1,-1)},r));else if(s[2])e.push(jsx("strong",{children:s[3]},r));else if(s[4])e.push(jsx("em",{children:s[5]},r));else if(s[6])e.push(jsx("em",{children:s[7]},r));else if(s[8]){let a=st(s[10]);a?e.push(jsx("a",{href:a,className:"text-blue-400 underline hover:text-blue-300",target:"_blank",rel:"noopener noreferrer",children:s[9]},r)):e.push(s[9]);}n=s.index+s[0].length;}return n<t.length&&e.push(t.slice(n)),e.length>0?e:[t]}function ot(t){let e=t.split(`
2
- `),o=[],n=0;for(;n<e.length;){let s=e[n];if(s.trim()===""){n++;continue}if(/^(-{3,}|\*{3,}|_{3,})$/.test(s.trim())){o.push({type:"hr"}),n++;continue}let u=s.match(/^(#{1,6})\s+(.+)/);if(u){o.push({type:"heading",level:u[1].length,content:u[2]}),n++;continue}if(s.trim().startsWith("```")){let a=s.trim().slice(3).trim(),l=[];for(n++;n<e.length&&!e[n].trim().startsWith("```");)l.push(e[n]),n++;o.push({type:"code",content:l.join(`
3
- `),lang:a||void 0}),n++;continue}if(/^\s*[-*+]\s/.test(s)){let a=[];for(;n<e.length&&/^\s*[-*+]\s/.test(e[n]);)a.push(e[n].replace(/^\s*[-*+]\s+/,"")),n++;o.push({type:"ul",items:a});continue}if(/^\s*\d+[.)]\s/.test(s)){let a=[];for(;n<e.length&&/^\s*\d+[.)]\s/.test(e[n]);)a.push(e[n].replace(/^\s*\d+[.)]\s+/,"")),n++;o.push({type:"ol",items:a});continue}let r=[];for(;n<e.length&&e[n].trim()!==""&&!e[n].match(/^#{1,6}\s/)&&!e[n].trim().startsWith("```")&&!/^\s*[-*+]\s/.test(e[n])&&!/^\s*\d+[.)]\s/.test(e[n]);)r.push(e[n]),n++;r.length>0&&o.push({type:"paragraph",content:r.join(" ")});}return o}var at={1:"text-2xl font-bold mt-6 mb-3",2:"text-xl font-bold mt-5 mb-2",3:"text-lg font-semibold mt-4 mb-2",4:"text-base font-semibold mt-3 mb-1",5:"text-sm font-semibold mt-2 mb-1",6:"text-sm font-medium mt-2 mb-1"};function it(t,e){switch(t.type){case "hr":return jsx("hr",{className:"my-4 border-border"},`b${e}`);case "heading":{let o=Math.min(Math.max(t.level||1,1),6),n=`h${o}`;return jsx(n,{className:C("text-foreground",at[o]),children:_(t.content||"")},`b${e}`)}case "paragraph":return jsx("p",{className:"mb-3 leading-relaxed text-foreground",children:_(t.content||"")},`b${e}`);case "code":return jsx("pre",{className:"mb-3 overflow-x-auto rounded-lg bg-muted p-4 text-sm font-mono leading-relaxed text-foreground",children:jsx("code",{children:t.content})},`b${e}`);case "ul":return jsx("ul",{className:"mb-3 ml-5 list-disc space-y-1 text-foreground",children:t.items?.map((o,n)=>jsx("li",{className:"leading-relaxed",children:_(o)},`li${e}-${n}`))},`b${e}`);case "ol":return jsx("ol",{className:"mb-3 ml-5 list-decimal space-y-1 text-foreground",children:t.items?.map((o,n)=>jsx("li",{className:"leading-relaxed",children:_(o)},`li${e}-${n}`))},`b${e}`);default:return null}}function V({content:t,className:e}){let o=ot(t);return jsx("div",{className:C("text-sm",e),children:o.map((n,s)=>it(n,s))})}function me({open:t,className:e}){return jsx("svg",{width:"16",height:"16",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:C("shrink-0 transition-transform duration-150",t?"rotate-0":"-rotate-90",e),children:jsx("path",{d:"M16.134 6.16a.5.5 0 1 1 .732.68l-6.5 7-.077.068a.5.5 0 0 1-.655-.068l-6.5-7-.062-.08a.5.5 0 0 1 .718-.667l.076.067L10 12.767z"})})}function ue({size:t=20,className:e}){return jsx("svg",{width:t,height:t,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsx("path",{d:"M8.5 2a6.5 6.5 0 0 1 4.935 10.728l4.419 4.419.064.078a.5.5 0 0 1-.693.693l-.079-.064-4.419-4.42A6.5 6.5 0 1 1 8.5 2m0 1a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11"})})}function Z({size:t=20,className:e}){return jsx("svg",{width:t,height:t,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsx("path",{d:"M15.147 4.146a.5.5 0 0 1 .707.707L10.707 10l5.147 5.147a.5.5 0 0 1-.63.771l-.078-.064L10 10.707l-5.146 5.147a.5.5 0 0 1-.708-.707L9.293 10 4.146 4.853a.5.5 0 0 1 .708-.707L10 9.293z"})})}function ge({size:t=20,className:e}){return jsx("svg",{width:t,height:t,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsx("path",{d:"M10 3a.5.5 0 0 1 .5.5v6h6l.1.01a.5.5 0 0 1 0 .98l-.1.01h-6v6a.5.5 0 0 1-1 0v-6h-6a.5.5 0 0 1 0-1h6v-6A.5.5 0 0 1 10 3"})})}function ut(){return jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M6.5 3A2.5 2.5 0 0 0 4 5.5v9A2.5 2.5 0 0 0 6.5 17h7a2.5 2.5 0 0 0 2.5-2.5v-7A2.5 2.5 0 0 0 13.5 5H11V3.5a.5.5 0 0 0-1 0V5H6.5ZM5 5.5A1.5 1.5 0 0 1 6.5 4H9v1H6.5A1.5 1.5 0 0 0 5 6.5v8A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-7A1.5 1.5 0 0 0 13.5 6H11V4h2.5A2.5 2.5 0 0 1 16 6.5v8a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-9Z"})})}function dt(){return jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M5.5 3A2.5 2.5 0 0 0 3 5.5v9A2.5 2.5 0 0 0 5.5 17h9a2.5 2.5 0 0 0 2.5-2.5v-9A2.5 2.5 0 0 0 14.5 3h-9ZM4 5.5A1.5 1.5 0 0 1 5.5 4h9A1.5 1.5 0 0 1 16 5.5v9a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 4 14.5v-9ZM7 7.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5Z"})})}function ft(){return jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M10 2a.5.5 0 0 1 .354.146l3 3a.5.5 0 0 1-.708.708L10.5 3.707V12.5a.5.5 0 0 1-1 0V3.707L7.354 5.854a.5.5 0 1 1-.708-.708l3-3A.5.5 0 0 1 10 2ZM4 13.5a.5.5 0 0 1 1 0v1A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-1a.5.5 0 0 1 1 0v1a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-1Z"})})}function pe(){let[t,e]=useState(false);return useEffect(()=>{if(typeof window>"u")return;let o=()=>e(window.innerWidth<768);return o(),window.addEventListener("resize",o),()=>window.removeEventListener("resize",o)},[]),t}function he({onClose:t,children:e,title:o}){let n=pe(),s=useRef(t);return s.current=t,useEffect(()=>{let u=r=>{r.key==="Escape"&&s.current();};return window.addEventListener("keydown",u),()=>window.removeEventListener("keydown",u)},[]),n?jsxs("div",{className:"fixed inset-0 z-50 flex items-end justify-center",onClick:t,children:[jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxs("div",{className:"relative z-10 w-full max-h-[90vh] overflow-y-auto rounded-t-2xl bg-[#1a1a1a] p-5 pb-8 animate-in slide-in-from-bottom duration-200",onClick:u=>u.stopPropagation(),children:[jsx("div",{className:"mx-auto mb-4 h-1 w-10 rounded-full bg-zinc-600"}),jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsx("h2",{className:"text-lg font-semibold text-foreground",children:o}),jsx("button",{onClick:t,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsx(Z,{size:20})})]}),e]})]}):jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center",onClick:t,children:[jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxs("div",{className:"relative z-10 w-full max-w-lg overflow-y-auto rounded-2xl bg-[#1a1a1a] p-6 shadow-2xl animate-in fade-in zoom-in-95 duration-150",onClick:u=>u.stopPropagation(),children:[jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsx("h2",{className:"text-lg font-semibold text-foreground",children:o}),jsx("button",{onClick:t,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsx(Z,{size:20})})]}),e]})]})}function mt({onClose:t,onCreated:e,config:o}){let[n,s]=useState(""),[u,r]=useState(""),[a,l]=useState(""),[c,d]=useState(false),[f,m]=useState(null);return jsx(he,{title:"Write skill instructions",onClose:t,children:jsxs("div",{className:"space-y-4",children:[jsxs("div",{className:"space-y-1.5",children:[jsx("label",{htmlFor:"skill-name",className:"text-sm text-muted-foreground",children:"Skill name"}),jsx("input",{id:"skill-name",value:n,onChange:p=>s(p.target.value),placeholder:"weekly-status-report",className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxs("div",{className:"space-y-1.5",children:[jsx("label",{htmlFor:"skill-desc",className:"text-sm text-muted-foreground",children:"Description"}),jsx("textarea",{id:"skill-desc",value:u,onChange:p=>r(p.target.value),placeholder:"Generate weekly status reports from recent work.",rows:3,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxs("div",{className:"space-y-1.5",children:[jsx("label",{htmlFor:"skill-instructions",className:"text-sm text-muted-foreground",children:"Instructions"}),jsx("textarea",{id:"skill-instructions",value:a,onChange:p=>l(p.target.value),placeholder:"Summarize my recent work in three sections: wins, blockers, and next steps.",rows:8,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),f&&jsx("p",{className:"text-sm text-red-500",children:f}),jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[jsx("button",{onClick:t,className:"rounded-lg border border-zinc-700 px-4 py-2 text-sm text-foreground hover:bg-zinc-800",children:"Cancel"}),jsx("button",{onClick:async()=>{if(n.trim()){d(true),m(null);try{let p=o.apiBaseUrl||"",v=`# ${n.trim()}
1
+ import {useMemo,useRef,useState,useCallback,useEffect}from'react';import {Loader2,FileText}from'lucide-react';import {clsx}from'clsx';import {twMerge}from'tailwind-merge';import {jsx,jsxs,Fragment}from'react/jsx-runtime';async function v(r,e,o,n){let s={"Content-Type":"application/json",...o?.headers};n&&(s.Authorization=`Bearer ${n}`);let f=await fetch(`${r}${e}`,{...o,headers:s});if(!f.ok){let t=`HTTP ${f.status}`;try{let a=await f.json();a.error&&(t=a.error);}catch{}throw new Error(t)}return f.json()}function B(r){let e=r.indexOf(":");return {mode:r.slice(0,e),cid:r.slice(e+1)}}function b(r){let e=r.apiBaseUrl,o=r.authorMid,n=r.ownerMid,s=r.apiKey,f=r.stacknetUrl||r.apiBaseUrl;return useMemo(()=>({async listRepos(t,a){let l=new URLSearchParams;(t||n)&&l.set("owner",t||n),a?.limit&&l.set("limit",String(a.limit)),a?.cursor&&l.set("cursor",a.cursor);let c=l.toString()?`?${l}`:"",u=await v(e,`/api/rack/repos${c}`,void 0,s);return {items:u.repos||[],pagination:u.pagination||{total:(u.repos||[]).length,limit:50,has_more:false,next_cursor:null}}},async initRepo(t){return v(e,"/api/rack/init",{method:"POST",body:JSON.stringify({...t,owner_mid:n})},s)},async push(t,a){return v(e,`/api/rack/${t}/push`,{method:"POST",body:JSON.stringify({...a,author_mid:o})},s)},async getTree(t,a="main"){let l=await v(e,`/api/rack/${t}/tree/${a}`,void 0,s);return {tree:l.tree,commit_cid:l.commit_cid}},async getBlob(t,a){return (await v(e,`/api/rack/${t}/blob/${a}`,void 0,s)).content},async getLog(t,a,l){let c=new URLSearchParams;a&&c.set("ref",a),l&&c.set("max_count",String(l));let u=c.toString()?`?${c}`:"";return (await v(e,`/api/rack/${t}/log${u}`,void 0,s)).commits||[]},async getBranches(t){return (await v(e,`/api/rack/${t}/branches`,void 0,s)).branches||[]},async createBranch(t,a,l){return v(e,`/api/rack/${t}/branch`,{method:"POST",body:JSON.stringify({branch_name:a,from_ref:l})},s)},async merge(t,a,l){return v(e,`/api/rack/${t}/merge`,{method:"POST",body:JSON.stringify({source_branch:a,target_branch:l})},s)},async getDiff(t,a,l){return (await v(e,`/api/rack/${t}/diff/${a}/${l}`,void 0,s)).diff?.entries||[]},async starRepo(t){return v(e,`/api/rack/${t}/star`,{method:"POST"},s)},async unstarRepo(t){return v(e,`/api/rack/${t}/star`,{method:"DELETE"},s)},async getStarInfo(t){return v(e,`/api/rack/${t}/stars`,void 0,s)},async getSkillStats(t){let a={meta:null,tokenCount:null,usageCount:null};try{let{tree:l}=await this.getTree(t,"main");if(!l?.entries)return a;if(l.entries["META.json"]){let m=B(l.entries["META.json"]).cid,d=await this.getBlob(t,m);a.meta=JSON.parse(d);}let c=0,u=Object.values(l.entries).map(async m=>{try{let d=B(m).cid,g=await this.getBlob(t,d);c+=g.length;}catch{}});await Promise.all(u),c>0&&(a.tokenCount=Math.ceil(c/4)),a.meta?.skill_id&&(a.usageCount=await this.getSkillUsageCount(a.meta.skill_id));}catch{}return a},async getSkillUsageCount(t){try{let a=await fetch(`${f}/v1/skills/${encodeURIComponent(t)}`);if(a.ok){let c=await a.json();return c.usage_count??c.usageCount??null}let l=await fetch(`${f}/v1/skills?scope=public`);if(l.ok){let u=((await l.json()).skills||[]).find(m=>m.name===t||m.id===t);if(u)return u.usage_count??u.usageCount??0}return 0}catch{return null}},async getTensorStats(t){let a={meta:null,sizeMB:null};try{let{tree:l}=await this.getTree(t,"main");if(!l?.entries)return a;if(l.entries["TENSOR_META.json"]){let c=B(l.entries["TENSOR_META.json"]).cid,u=await this.getBlob(t,c);a.meta=JSON.parse(u),a.sizeMB=a.meta?.tensor_size_mb??null;}}catch{}return a},async getNetworkStats(){try{return (await v(e,"/api/rack/stats",void 0,s)).stats||null}catch{return null}},async getTrending(t=5,a=1,l){try{let c=new URLSearchParams({limit:String(t),days:String(a)});l&&c.set("cursor",l);let u=await v(e,`/api/rack/trending?${c}`,void 0,s);return {items:u.trending||[],pagination:u.pagination||{total:(u.trending||[]).length,limit:t,has_more:!1,next_cursor:null}}}catch{return {items:[],pagination:{total:0,limit:t,has_more:false,next_cursor:null}}}}}),[e,o,n,s,f])}function D(r){let e=b(r),o=useRef(e);o.current=e;let[n,s]=useState([]),[f,t]=useState(true),[a,l]=useState(null),c=useRef(true),u=useRef(null),m=useCallback(async()=>{u.current?.abort();let d=new AbortController;u.current=d;try{c.current&&(t(!0),l(null));let g=await o.current.listRepos();c.current&&!d.signal.aborted&&s(g.items);}catch(g){c.current&&!d.signal.aborted&&l(g instanceof Error?g.message:"Failed to load repos");}finally{c.current&&!d.signal.aborted&&t(false);}},[]);return useEffect(()=>(c.current=true,m(),()=>{c.current=false,u.current?.abort();}),[m]),{repos:n,loading:f,error:a,refresh:m}}function $e(r){return Object.entries(r).map(([e,o])=>{let n=o.indexOf(":"),s=n>0?o.slice(0,n):"100644",f=n>0?o.slice(n+1):o;return {path:e,mode:s,cid:f,isDir:s==="040000"}}).sort((e,o)=>e.isDir!==o.isDir?e.isDir?-1:1:e.path.localeCompare(o.path))}function H(r,e,o="main"){let n=b(r),[s,f]=useState([]),[t,a]=useState(false),[l,c]=useState(null),u=useRef(true),m=useCallback(async()=>{if(e)try{u.current&&(a(!0),c(null));let{tree:g}=await n.getTree(e,o);u.current&&f($e(g.entries));}catch(g){u.current&&c(g instanceof Error?g.message:"Failed to load tree");}finally{u.current&&a(false);}},[n,e,o]);useEffect(()=>(u.current=true,m(),()=>{u.current=false;}),[m]);let d=useCallback(async g=>{if(!e)throw new Error("No repo selected");return n.getBlob(e,g)},[n,e]);return {entries:s,loading:t,error:l,refresh:m,getFileContent:d}}function Ae(r){let e=b(r),[o,n]=useState(false),[s,f]=useState(null),t=useRef(true);return useEffect(()=>(t.current=true,()=>{t.current=false;}),[]),{push:useCallback(async(l,c,u,m)=>{try{return t.current&&(n(!0),f(null)),await e.push(l,{files:c,message:u,branch:m})}catch(d){let g=d instanceof Error?d.message:"Push failed";return t.current&&f(g),null}finally{t.current&&n(false);}},[e]),pushing:o,error:s}}function Oe(r,e={}){let{pageSize:o=50,owner:n}=e,s=b(r),[f,t]=useState([]),[a,l]=useState(null),[c,u]=useState(false),[m,d]=useState(null),g=useRef(null),p=useRef(true),x=useCallback(async(C,I=false)=>{u(true),d(null);try{let P=await s.listRepos(n,{limit:o,cursor:C||void 0});p.current&&(t(M=>I?[...M,...P.items]:P.items),l(P.pagination),g.current=P.pagination.next_cursor);}catch(P){p.current&&d(P.message);}finally{p.current&&u(false);}},[s,n,o]),w=useCallback(async()=>{!g.current||c||await x(g.current,true);},[x,c]),R=useCallback(async()=>{g.current=null,await x(void 0,false);},[x]);return useEffect(()=>(p.current=true,x(),()=>{p.current=false;}),[x]),{repos:f,hasMore:a?.has_more??false,total:a?.total??0,loading:c,error:m,loadMore:w,reset:R,pagination:a}}var J="stacknet-rack-apikey";function De(r){let e=r.stacknetUrl||r.apiBaseUrl,[o,n]=useState({authenticated:false}),[s,f]=useState(null),[t,a]=useState(false),l=useCallback(d=>({"Content-Type":"application/json",...d||r.apiKey?{Authorization:`Bearer ${d||r.apiKey}`}:{}}),[r.apiKey]),c=useCallback(async d=>{a(true);try{let g=await fetch(`${e}/health`,{headers:l(d)});if(!g.ok)throw new Error(`Authentication failed: ${g.status}`);let p={authenticated:!0,apiKey:d,permission:d.startsWith("gk_")?"write":"read"};n(p);try{localStorage.setItem(J,d);}catch{}return p}catch(g){throw n({authenticated:false}),g}finally{a(false);}},[e,l]),u=useCallback(()=>{n({authenticated:false}),f(null);try{localStorage.removeItem(J);}catch{}},[]),m=useCallback(async()=>{let d=o.apiKey||r.apiKey;if(!d)return null;try{let g=await fetch(`${e}/network/usage`,{headers:l(d)});if(!g.ok)return null;let p=await g.json(),x={planAllocation:p.plan_allocation??p.planAllocation??0,inferenceUsed:p.inference_used??p.inferenceUsed??0,ledgerSpent:p.ledger_spent??p.ledgerSpent??0,totalUsed:p.total_used??p.totalUsed??0,remaining:p.remaining??0,percent:p.percent??0,exceeded:p.exceeded??!1};return f(x),x}catch{return null}},[o.apiKey,r.apiKey,e,l]);return useEffect(()=>{let d=r.apiKey;if(d){n({authenticated:true,apiKey:d,permission:d.startsWith("gk_")?"write":"read"});return}try{let g=localStorage.getItem(J);g&&n({authenticated:!0,apiKey:g,permission:g.startsWith("gk_")?"write":"read"});}catch{}},[r.apiKey]),{session:o,budget:s,loading:t,login:c,logout:u,refreshBudget:m}}var ce=1e3,ue=1e3,de=100;function fe(r,e){if(r==="skill"){let s=de+Math.ceil(e/4);return {type:r,totalBytes:e,totalMegabytes:e/1e6,baseCost:s,multiplier:ce,registrationCostTokens:s*ce}}let o=Math.ceil(e/1e6),n=de+o;return {type:r,totalBytes:e,totalMegabytes:o,baseCost:n,multiplier:ue,registrationCostTokens:n*ue}}function Fe(r){let e=r.stacknetUrl||r.apiBaseUrl,o=r.apiKey,[n,s]=useState(false),[f,t]=useState(null),a=useCallback(()=>{if(!o)throw new Error("API key required for registration. Call login() first.");return {"Content-Type":"application/json",Authorization:`Bearer ${o}`}},[o]),l=useCallback(async u=>{s(true),t(null);try{let m=await fetch(`${e}/skills`,{method:"POST",headers:a(),body:JSON.stringify(u)});if(!m.ok){let d=await m.json().catch(()=>({error:`HTTP ${m.status}`}));throw new Error(d.error||`Registration failed: ${m.status}`)}return await m.json()}catch(m){throw t(m.message),m}finally{s(false);}},[e,a]),c=useCallback(async u=>{s(true),t(null);try{let m=await fetch(`${e}/tensors`,{method:"POST",headers:a(),body:JSON.stringify(u)});if(!m.ok){let d=await m.json().catch(()=>({error:`HTTP ${m.status}`}));throw new Error(d.error||`Registration failed: ${m.status}`)}return await m.json()}catch(m){throw t(m.message),m}finally{s(false);}},[e,a]);return {registerSkill:l,registerTensor:c,estimateCost:fe,registering:n,error:f}}function Je(r,e){let o=b(r),[n,s]=useState({meta:null,tokenCount:null,usageCount:null}),[f,t]=useState(false),[a,l]=useState(null),c=useRef(true),u=useCallback(async()=>{if(e){t(true),l(null);try{let m=await o.getSkillStats(e);c.current&&s(m);}catch(m){c.current&&l(m.message);}finally{c.current&&t(false);}}},[o,e]);return useEffect(()=>(c.current=true,u(),()=>{c.current=false;}),[u]),{stats:n,loading:f,error:a,refresh:u}}function Ge(r,e){let o=b(r),[n,s]=useState({meta:null,sizeMB:null}),[f,t]=useState(false),[a,l]=useState(null),c=useRef(true),u=useCallback(async()=>{if(e){t(true),l(null);try{let m=await o.getTensorStats(e);c.current&&s(m);}catch(m){c.current&&l(m.message);}finally{c.current&&t(false);}}},[o,e]);return useEffect(()=>(c.current=true,u(),()=>{c.current=false;}),[u]),{stats:n,loading:f,error:a,refresh:u}}function et(r){let e=b(r),[o,n]=useState(null),[s,f]=useState(false),[t,a]=useState(null),l=useRef(true),c=useCallback(async()=>{f(true),a(null);try{let u=await e.getNetworkStats();l.current&&n(u);}catch(u){l.current&&a(u.message);}finally{l.current&&f(false);}},[e]);return useEffect(()=>(l.current=true,c(),()=>{l.current=false;}),[c]),{stats:o,loading:s,error:t,refresh:c}}function rt(r,e=5,o=1){let n=b(r),[s,f]=useState([]),[t,a]=useState(null),[l,c]=useState(false),[u,m]=useState(null),d=useRef(true),g=useRef(null),p=useCallback(async w=>{c(true),m(null),g.current=null;try{let R=await n.getTrending(e,w??o);d.current&&(f(R.items),a(R.pagination),g.current=R.pagination.next_cursor);}catch(R){d.current&&m(R.message);}finally{d.current&&c(false);}},[n,e,o]),x=useCallback(async()=>{if(!(!g.current||l)){c(true);try{let w=await n.getTrending(e,o,g.current);d.current&&(f(R=>[...R,...w.items]),a(w.pagination),g.current=w.pagination.next_cursor);}catch(w){d.current&&m(w.message);}finally{d.current&&c(false);}}},[n,e,o,l]);return useEffect(()=>(d.current=true,p(),()=>{d.current=false;}),[p]),{repos:s,hasMore:t?.has_more??false,total:t?.total??0,loading:l,error:u,refresh:p,loadMore:x}}function ot(r,e){let o=b(r),[n,s]=useState({stars:0,starred:false,repo_id:e||""}),[f,t]=useState(false),[a,l]=useState(null),c=useRef(true),u=useCallback(async()=>{if(e)try{let d=await o.getStarInfo(e);c.current&&s(d);}catch{}},[o,e]);useEffect(()=>(c.current=true,u(),()=>{c.current=false;}),[u]);let m=useCallback(async()=>{if(e){t(true),l(null);try{let d=n.starred?await o.unstarRepo(e):await o.starRepo(e);c.current&&s({stars:d.stars,starred:d.starred,repo_id:e});}catch(d){c.current&&l(d.message);}finally{c.current&&t(false);}}},[o,e,n.starred]);return {...n,loading:f,error:a,toggle:m,refresh:u}}function N(...r){return twMerge(clsx(r))}var lt=/^(https?:\/\/|mailto:|\/[^/])/i;function ct(r){let e=r.trim();return lt.test(e)?e:null}function U(r){let e=[],o=/(`[^`]+`)|(\*\*(.+?)\*\*)|(\*(.+?)\*)|(_(.+?)_)|(\[([^\]]+)\]\(([^)]+)\))/g,n=0,s,f=0;for(;(s=o.exec(r))!==null;){s.index>n&&e.push(r.slice(n,s.index));let t=`i${f++}`;if(s[1])e.push(jsx("code",{className:"rounded bg-muted px-1.5 py-0.5 text-[0.85em] font-mono text-pink-400",children:s[1].slice(1,-1)},t));else if(s[2])e.push(jsx("strong",{children:s[3]},t));else if(s[4])e.push(jsx("em",{children:s[5]},t));else if(s[6])e.push(jsx("em",{children:s[7]},t));else if(s[8]){let a=ct(s[10]);a?e.push(jsx("a",{href:a,className:"text-blue-400 underline hover:text-blue-300",target:"_blank",rel:"noopener noreferrer",children:s[9]},t)):e.push(s[9]);}n=s.index+s[0].length;}return n<r.length&&e.push(r.slice(n)),e.length>0?e:[r]}function ut(r){let e=r.split(`
2
+ `),o=[],n=0;for(;n<e.length;){let s=e[n];if(s.trim()===""){n++;continue}if(/^(-{3,}|\*{3,}|_{3,})$/.test(s.trim())){o.push({type:"hr"}),n++;continue}let f=s.match(/^(#{1,6})\s+(.+)/);if(f){o.push({type:"heading",level:f[1].length,content:f[2]}),n++;continue}if(s.trim().startsWith("```")){let a=s.trim().slice(3).trim(),l=[];for(n++;n<e.length&&!e[n].trim().startsWith("```");)l.push(e[n]),n++;o.push({type:"code",content:l.join(`
3
+ `),lang:a||void 0}),n++;continue}if(/^\s*[-*+]\s/.test(s)){let a=[];for(;n<e.length&&/^\s*[-*+]\s/.test(e[n]);)a.push(e[n].replace(/^\s*[-*+]\s+/,"")),n++;o.push({type:"ul",items:a});continue}if(/^\s*\d+[.)]\s/.test(s)){let a=[];for(;n<e.length&&/^\s*\d+[.)]\s/.test(e[n]);)a.push(e[n].replace(/^\s*\d+[.)]\s+/,"")),n++;o.push({type:"ol",items:a});continue}let t=[];for(;n<e.length&&e[n].trim()!==""&&!e[n].match(/^#{1,6}\s/)&&!e[n].trim().startsWith("```")&&!/^\s*[-*+]\s/.test(e[n])&&!/^\s*\d+[.)]\s/.test(e[n]);)t.push(e[n]),n++;t.length>0&&o.push({type:"paragraph",content:t.join(" ")});}return o}var dt={1:"text-2xl font-bold mt-6 mb-3",2:"text-xl font-bold mt-5 mb-2",3:"text-lg font-semibold mt-4 mb-2",4:"text-base font-semibold mt-3 mb-1",5:"text-sm font-semibold mt-2 mb-1",6:"text-sm font-medium mt-2 mb-1"};function ft(r,e){switch(r.type){case "hr":return jsx("hr",{className:"my-4 border-border"},`b${e}`);case "heading":{let o=Math.min(Math.max(r.level||1,1),6),n=`h${o}`;return jsx(n,{className:N("text-foreground",dt[o]),children:U(r.content||"")},`b${e}`)}case "paragraph":return jsx("p",{className:"mb-3 leading-relaxed text-foreground",children:U(r.content||"")},`b${e}`);case "code":return jsx("pre",{className:"mb-3 overflow-x-auto rounded-lg bg-muted p-4 text-sm font-mono leading-relaxed text-foreground",children:jsx("code",{children:r.content})},`b${e}`);case "ul":return jsx("ul",{className:"mb-3 ml-5 list-disc space-y-1 text-foreground",children:r.items?.map((o,n)=>jsx("li",{className:"leading-relaxed",children:U(o)},`li${e}-${n}`))},`b${e}`);case "ol":return jsx("ol",{className:"mb-3 ml-5 list-decimal space-y-1 text-foreground",children:r.items?.map((o,n)=>jsx("li",{className:"leading-relaxed",children:U(o)},`li${e}-${n}`))},`b${e}`);default:return null}}function Q({content:r,className:e}){let o=ut(r);return jsx("div",{className:N("text-sm",e),children:o.map((n,s)=>ft(n,s))})}function xe({open:r,className:e}){return jsx("svg",{width:"16",height:"16",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:N("shrink-0 transition-transform duration-150",r?"rotate-0":"-rotate-90",e),children:jsx("path",{d:"M16.134 6.16a.5.5 0 1 1 .732.68l-6.5 7-.077.068a.5.5 0 0 1-.655-.068l-6.5-7-.062-.08a.5.5 0 0 1 .718-.667l.076.067L10 12.767z"})})}function he({size:r=20,className:e}){return jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsx("path",{d:"M8.5 2a6.5 6.5 0 0 1 4.935 10.728l4.419 4.419.064.078a.5.5 0 0 1-.693.693l-.079-.064-4.419-4.42A6.5 6.5 0 1 1 8.5 2m0 1a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11"})})}function X({size:r=20,className:e}){return jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsx("path",{d:"M15.147 4.146a.5.5 0 0 1 .707.707L10.707 10l5.147 5.147a.5.5 0 0 1-.63.771l-.078-.064L10 10.707l-5.146 5.147a.5.5 0 0 1-.708-.707L9.293 10 4.146 4.853a.5.5 0 0 1 .708-.707L10 9.293z"})})}function we({size:r=20,className:e}){return jsx("svg",{width:r,height:r,viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:e,children:jsx("path",{d:"M10 3a.5.5 0 0 1 .5.5v6h6l.1.01a.5.5 0 0 1 0 .98l-.1.01h-6v6a.5.5 0 0 1-1 0v-6h-6a.5.5 0 0 1 0-1h6v-6A.5.5 0 0 1 10 3"})})}function pt(){return jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M6.5 3A2.5 2.5 0 0 0 4 5.5v9A2.5 2.5 0 0 0 6.5 17h7a2.5 2.5 0 0 0 2.5-2.5v-7A2.5 2.5 0 0 0 13.5 5H11V3.5a.5.5 0 0 0-1 0V5H6.5ZM5 5.5A1.5 1.5 0 0 1 6.5 4H9v1H6.5A1.5 1.5 0 0 0 5 6.5v8A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-7A1.5 1.5 0 0 0 13.5 6H11V4h2.5A2.5 2.5 0 0 1 16 6.5v8a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-9Z"})})}function ht(){return jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M5.5 3A2.5 2.5 0 0 0 3 5.5v9A2.5 2.5 0 0 0 5.5 17h9a2.5 2.5 0 0 0 2.5-2.5v-9A2.5 2.5 0 0 0 14.5 3h-9ZM4 5.5A1.5 1.5 0 0 1 5.5 4h9A1.5 1.5 0 0 1 16 5.5v9a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 4 14.5v-9ZM7 7.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Zm0 3a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5Z"})})}function yt(){return jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M10 2a.5.5 0 0 1 .354.146l3 3a.5.5 0 0 1-.708.708L10.5 3.707V12.5a.5.5 0 0 1-1 0V3.707L7.354 5.854a.5.5 0 1 1-.708-.708l3-3A.5.5 0 0 1 10 2ZM4 13.5a.5.5 0 0 1 1 0v1A1.5 1.5 0 0 0 6.5 16h7a1.5 1.5 0 0 0 1.5-1.5v-1a.5.5 0 0 1 1 0v1a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 4 14.5v-1Z"})})}function be(){let[r,e]=useState(false);return useEffect(()=>{if(typeof window>"u")return;let o=()=>e(window.innerWidth<768);return o(),window.addEventListener("resize",o),()=>window.removeEventListener("resize",o)},[]),r}function Re({onClose:r,children:e,title:o}){let n=be(),s=useRef(r);return s.current=r,useEffect(()=>{let f=t=>{t.key==="Escape"&&s.current();};return window.addEventListener("keydown",f),()=>window.removeEventListener("keydown",f)},[]),n?jsxs("div",{className:"fixed inset-0 z-50 flex items-end justify-center",onClick:r,children:[jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxs("div",{className:"relative z-10 w-full max-h-[90vh] overflow-y-auto rounded-t-2xl bg-[#1a1a1a] p-5 pb-8 animate-in slide-in-from-bottom duration-200",onClick:f=>f.stopPropagation(),children:[jsx("div",{className:"mx-auto mb-4 h-1 w-10 rounded-full bg-zinc-600"}),jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsx("h2",{className:"text-lg font-semibold text-foreground",children:o}),jsx("button",{onClick:r,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsx(X,{size:20})})]}),e]})]}):jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center",onClick:r,children:[jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxs("div",{className:"relative z-10 w-full max-w-lg overflow-y-auto rounded-2xl bg-[#1a1a1a] p-6 shadow-2xl animate-in fade-in zoom-in-95 duration-150",onClick:f=>f.stopPropagation(),children:[jsxs("div",{className:"flex items-center justify-between mb-5",children:[jsx("h2",{className:"text-lg font-semibold text-foreground",children:o}),jsx("button",{onClick:r,className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsx(X,{size:20})})]}),e]})]})}function kt({onClose:r,onCreated:e,config:o}){let[n,s]=useState(""),[f,t]=useState(""),[a,l]=useState(""),[c,u]=useState(false),[m,d]=useState(null);return jsx(Re,{title:"Write skill instructions",onClose:r,children:jsxs("div",{className:"space-y-4",children:[jsxs("div",{className:"space-y-1.5",children:[jsx("label",{htmlFor:"skill-name",className:"text-sm text-muted-foreground",children:"Skill name"}),jsx("input",{id:"skill-name",value:n,onChange:p=>s(p.target.value),placeholder:"weekly-status-report",className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxs("div",{className:"space-y-1.5",children:[jsx("label",{htmlFor:"skill-desc",className:"text-sm text-muted-foreground",children:"Description"}),jsx("textarea",{id:"skill-desc",value:f,onChange:p=>t(p.target.value),placeholder:"Generate weekly status reports from recent work.",rows:3,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),jsxs("div",{className:"space-y-1.5",children:[jsx("label",{htmlFor:"skill-instructions",className:"text-sm text-muted-foreground",children:"Instructions"}),jsx("textarea",{id:"skill-instructions",value:a,onChange:p=>l(p.target.value),placeholder:"Summarize my recent work in three sections: wins, blockers, and next steps.",rows:8,className:"w-full rounded-lg border border-zinc-700 bg-[#252525] px-3 py-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-zinc-500"})]}),m&&jsx("p",{className:"text-sm text-red-500",children:m}),jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[jsx("button",{onClick:r,className:"rounded-lg border border-zinc-700 px-4 py-2 text-sm text-foreground hover:bg-zinc-800",children:"Cancel"}),jsx("button",{onClick:async()=>{if(n.trim()){u(true),d(null);try{let p=o.apiBaseUrl||"",x=`# ${n.trim()}
4
4
 
5
- ${u.trim()}
5
+ ${f.trim()}
6
6
 
7
7
  ---
8
8
 
9
- ${a.trim()}`,S=await fetch(`${p}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:n.trim(),description:u.trim(),skill_md:v,content_type:"code"})});if(!S.ok){let T=`Failed to register skill (${S.status})`;try{let R=await S.json();R.error&&(T=R.error);}catch{}throw new Error(T)}e?.(),t();}catch(p){m(p instanceof Error?p.message:"Failed to create skill");}finally{d(false);}}},disabled:c||!n.trim(),className:"rounded-lg bg-zinc-600 px-4 py-2 text-sm font-medium text-white hover:bg-zinc-500 disabled:opacity-50",children:c?"Creating...":"Create"})]})]})})}function gt({onClose:t,onCreated:e,config:o}){let n=useRef(null),[s,u]=useState(false),[r,a]=useState(false),[l,c]=useState(null),d=async m=>{a(true),c(null);try{let g=await m.text(),p=o.apiBaseUrl||"",v=m.name.replace(/\.[^.]+$/,"").replace(/[^a-zA-Z0-9-_]/g,"-"),S=await fetch(`${p}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:v,skill_md:g,content_type:"code"})});if(!S.ok){let T=`Failed to register skill (${S.status})`;try{let R=await S.json();R.error&&(T=R.error);}catch{}throw new Error(T)}e?.(),t();}catch(g){c(g instanceof Error?g.message:"Upload failed");}finally{a(false);}};return jsx(he,{title:"Upload skill",onClose:t,children:jsxs("div",{className:"space-y-4",children:[jsxs("div",{onDragOver:m=>{m.preventDefault(),u(true);},onDragLeave:()=>u(false),onDrop:m=>{m.preventDefault(),u(false);let g=m.dataTransfer.files[0];g&&d(g);},onClick:()=>n.current?.click(),className:C("flex cursor-pointer flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed p-10 transition-colors",s?"border-zinc-400 bg-zinc-800/50":"border-zinc-700 hover:border-zinc-500"),children:[jsx("div",{className:"rounded-lg border border-zinc-600 p-2",children:jsx(ge,{size:20,className:"text-muted-foreground"})}),jsx("p",{className:"text-sm text-muted-foreground",children:r?"Uploading...":"Drag and drop or click to upload"})]}),jsx("input",{ref:n,type:"file",accept:".md,.zip,.skill,.txt,.yml,.yaml",className:"hidden","aria-label":"Upload skill file",onChange:m=>{let g=m.target.files?.[0];g&&d(g);}}),l&&jsx("p",{className:"text-sm text-red-500",children:l}),jsxs("div",{className:"space-y-2 text-xs text-muted-foreground",children:[jsx("p",{className:"font-medium text-foreground/70",children:"File requirements"}),jsxs("ul",{className:"list-disc pl-5 space-y-1",children:[jsx("li",{children:".md file must contain skill name and description formatted in YAML"}),jsx("li",{children:".zip or .skill file must include a SKILL.md file"})]})]})]})})}function pt({onClose:t,onSelect:e}){let o=pe(),n=useRef(null),s=useRef(t);s.current=t,useEffect(()=>{if(o)return;let r=a=>{n.current&&a.target instanceof Node&&!n.current.contains(a.target)&&s.current();};return document.addEventListener("mousedown",r),()=>document.removeEventListener("mousedown",r)},[o]);let u=[{id:"create-with-geoff",icon:jsx(ut,{}),label:"Create with Geoff"},{id:"write",icon:jsx(dt,{}),label:"Write skill instructions"},{id:"upload",icon:jsx(ft,{}),label:"Upload a skill"}];return o?jsxs("div",{className:"fixed inset-0 z-50 flex items-end",onClick:t,children:[jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxs("div",{className:"relative z-10 w-full rounded-t-2xl bg-[#1a1a1a] p-4 pb-8 animate-in slide-in-from-bottom duration-200",onClick:r=>r.stopPropagation(),children:[jsx("div",{className:"mx-auto mb-3 h-1 w-10 rounded-full bg-zinc-600"}),u.map(r=>jsxs("button",{onClick:()=>{e(r.id),t();},className:"flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-800",children:[r.icon,r.label]},r.id))]})]}):jsx("div",{ref:n,className:"absolute right-2 top-11 z-50 w-56 overflow-hidden rounded-xl border border-zinc-700 bg-[#2a2a2a] shadow-xl animate-in fade-in zoom-in-95 duration-100",children:u.map(r=>jsxs("button",{onClick:()=>{e(r.id),t();},className:"flex w-full items-center gap-3 px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-700/50",children:[r.icon,r.label]},r.id))})}function ht({entry:t,selected:e,onSelect:o,depth:n=0}){return jsxs("button",{onClick:()=>o(t),className:C("flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),style:{paddingLeft:`${8+n*16}px`},children:[jsx("span",{className:"truncate flex-1",children:t.path.split("/").pop()}),t.isDir&&jsx(me,{className:"ml-auto text-muted-foreground"})]})}function yt({repo:t,selected:e,expanded:o,onSelect:n,onToggle:s,children:u}){return jsxs("div",{children:[jsxs("button",{onClick:()=>{n(),s();},className:C("flex w-full items-center gap-2 rounded-md px-2 py-2 text-left text-sm font-medium transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),children:[jsx(me,{open:o}),jsx(FileText,{className:"h-4 w-4 shrink-0"}),jsx("span",{className:"truncate",children:t.name})]}),o&&u]})}function kt({entry:t,content:e,loading:o,repoName:n}){let[s,u]=useState(false),r=useRef(null);useEffect(()=>()=>{r.current&&clearTimeout(r.current);},[]);let[a,l]=useState(false),c=async()=>{if(e)try{await navigator.clipboard.writeText(e),u(!0),l(!1),r.current&&clearTimeout(r.current),r.current=setTimeout(()=>u(!1),2e3);}catch{l(true),r.current&&clearTimeout(r.current),r.current=setTimeout(()=>l(false),2e3);}};if(!t)return jsx("div",{className:"flex h-full items-center justify-center text-sm text-muted-foreground",children:"Select a file to view its content"});if(o)return jsx("div",{className:"flex h-full items-center justify-center",children:jsx(Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})});let d=t.path.split("/").pop()||t.path,f=/\.(md|mdx)$/i.test(d);return jsxs("div",{className:"flex h-full flex-col px-3",children:[jsxs("div",{className:"flex items-center justify-between px-4 py-3",children:[jsx("h3",{className:"text-sm sm:text-lg font-semibold text-foreground",children:d}),jsx("button",{onClick:c,"aria-label":"Copy file content",className:C("rounded p-1 transition-colors",s?"text-green-500":a?"text-red-500":"text-muted-foreground hover:text-foreground"),children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M12.5 3A1.5 1.5 0 0 1 14 4.5V6h1.5A1.5 1.5 0 0 1 17 7.5v8a1.5 1.5 0 0 1-1.5 1.5h-8A1.5 1.5 0 0 1 6 15.5V14H4.5A1.5 1.5 0 0 1 3 12.5v-8A1.5 1.5 0 0 1 4.5 3zm1.5 9.5a1.5 1.5 0 0 1-1.5 1.5H7v1.5a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5H14zM4.5 4a.5.5 0 0 0-.5.5v8a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5z"})})})]}),jsx("div",{className:"flex-1 overflow-auto p-4",children:f?jsx(V,{content:e||""}):jsx("pre",{className:"whitespace-pre-wrap text-sm text-foreground font-mono leading-relaxed",children:e||""})})]})}function xt({config:t,category:e,className:o,style:n}){let{repos:s,loading:u,error:r,refresh:a}=A(t),[l,c]=useState(null),[d,f]=useState(null),[m,g]=useState(null),[p,v]=useState(null),[S,T]=useState(false),[R,q]=useState(""),[ye,G]=useState(false),[Y,Q]=useState(false),[X,M]=useState(null),ke=s.find(y=>y.repo_id===l),{entries:xe,getFileContent:ee}=U(t,d),te=s.filter(y=>!R||y.name.toLowerCase().includes(R.toLowerCase())),we=useCallback(async y=>{if(!y.isDir){g(y),T(true);try{let N=await ee(y.cid);v(N);}catch(N){let ve=N instanceof Error?N.message:"Unknown error";v(`Failed to load file: ${ve}`);}finally{T(false);}}},[ee]);useEffect(()=>{s.length>0&&!l&&(c(s[0].repo_id),f(s[0].repo_id));},[s,l]);let be=y=>{y==="create-with-geoff"?window.open(`https://www.geoff.ai/?p=${encodeURIComponent("Let's create a skill together using your skill-creator skill. First ask me what the skill should do.")}`,"_blank","noopener,noreferrer"):M(y);};return jsxs("div",{className:C("flex flex-1 h-full min-h-0",o),style:n,children:[jsxs("div",{className:"relative flex w-96 shrink-0 flex-col border-r",children:[jsx("div",{className:"flex h-12 items-center gap-2 px-3",children:ye?jsxs(Fragment,{children:[jsxs("div",{className:"flex flex-1 items-center gap-2 rounded-md border bg-muted/50 px-2 py-1",children:[jsx(ue,{size:16,className:"shrink-0 text-muted-foreground"}),jsx("input",{type:"text",value:R,onChange:y=>q(y.target.value),placeholder:"Search",autoFocus:true,"aria-label":"Search items",className:"flex-1 bg-transparent text-xs text-foreground placeholder:text-muted-foreground focus:outline-none"})]}),jsx("button",{onClick:()=>{G(false),q("");},className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsx(Z,{size:16})})]}):jsxs(Fragment,{children:[jsx("h3",{className:"flex-1 text-sm sm:text-lg font-semibold text-foreground capitalize",children:e||"Items"}),jsx("button",{onClick:()=>G(true),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Search",children:jsx(ue,{size:20})}),jsx("button",{onClick:()=>Q(!Y),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Add new",children:jsx(ge,{size:20})})]})}),Y&&jsx(pt,{onClose:()=>Q(false),onSelect:be}),jsx("div",{className:"flex-1 overflow-y-auto p-2",children:u?jsx("div",{className:"flex items-center justify-center py-8",children:jsx(Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})}):r?jsx("p",{className:"px-2 py-4 text-xs text-red-500",children:r}):te.length===0?jsx("p",{className:"px-2 py-4 text-xs text-muted-foreground",children:R?"No matching items":"No items yet"}):jsx("div",{className:"space-y-0.5",children:te.map(y=>jsx(yt,{repo:y,selected:l===y.repo_id,expanded:d===y.repo_id,onSelect:()=>{c(y.repo_id),g(null),v(null);},onToggle:()=>f(d===y.repo_id?null:y.repo_id),children:jsx("div",{className:"ml-10 pl-1",children:xe.map(N=>jsx(ht,{entry:N,selected:m?.path===N.path,onSelect:we,depth:N.path.split("/").length-1},N.path))})},y.repo_id))})})]}),jsx("div",{className:"flex-1 min-w-0",children:jsx(kt,{entry:m,content:p,loading:S,repoName:ke?.name||""})}),X==="write"&&jsx(mt,{config:t,onClose:()=>M(null),onCreated:a}),X==="upload"&&jsx(gt,{config:t,onClose:()=>M(null),onCreated:a})]})}
10
- export{V as Markdown,xt as RackBrowser,le as estimateCost,Ve as useNetworkStats,x as useRackClient,Le as useRackRegister,ze as useRackSession,Me as useRepoPush,U as useRepoTree,A as useRepos,Oe as useSkillStats,et as useStar,He as useTensorStats,Ye as useTrending};
9
+ ${a.trim()}`,w=await fetch(`${p}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:n.trim(),description:f.trim(),skill_md:x,content_type:"code"})});if(!w.ok){let R=`Failed to register skill (${w.status})`;try{let C=await w.json();C.error&&(R=C.error);}catch{}throw new Error(R)}e?.(),r();}catch(p){d(p instanceof Error?p.message:"Failed to create skill");}finally{u(false);}}},disabled:c||!n.trim(),className:"rounded-lg bg-zinc-600 px-4 py-2 text-sm font-medium text-white hover:bg-zinc-500 disabled:opacity-50",children:c?"Creating...":"Create"})]})]})})}function xt({onClose:r,onCreated:e,config:o}){let n=useRef(null),[s,f]=useState(false),[t,a]=useState(false),[l,c]=useState(null),u=async d=>{a(true),c(null);try{let g=await d.text(),p=o.apiBaseUrl||"",x=d.name.replace(/\.[^.]+$/,"").replace(/[^a-zA-Z0-9-_]/g,"-"),w=await fetch(`${p}/api/skills`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:x,skill_md:g,content_type:"code"})});if(!w.ok){let R=`Failed to register skill (${w.status})`;try{let C=await w.json();C.error&&(R=C.error);}catch{}throw new Error(R)}e?.(),r();}catch(g){c(g instanceof Error?g.message:"Upload failed");}finally{a(false);}};return jsx(Re,{title:"Upload skill",onClose:r,children:jsxs("div",{className:"space-y-4",children:[jsxs("div",{onDragOver:d=>{d.preventDefault(),f(true);},onDragLeave:()=>f(false),onDrop:d=>{d.preventDefault(),f(false);let g=d.dataTransfer.files[0];g&&u(g);},onClick:()=>n.current?.click(),className:N("flex cursor-pointer flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed p-10 transition-colors",s?"border-zinc-400 bg-zinc-800/50":"border-zinc-700 hover:border-zinc-500"),children:[jsx("div",{className:"rounded-lg border border-zinc-600 p-2",children:jsx(we,{size:20,className:"text-muted-foreground"})}),jsx("p",{className:"text-sm text-muted-foreground",children:t?"Uploading...":"Drag and drop or click to upload"})]}),jsx("input",{ref:n,type:"file",accept:".md,.zip,.skill,.txt,.yml,.yaml",className:"hidden","aria-label":"Upload skill file",onChange:d=>{let g=d.target.files?.[0];g&&u(g);}}),l&&jsx("p",{className:"text-sm text-red-500",children:l}),jsxs("div",{className:"space-y-2 text-xs text-muted-foreground",children:[jsx("p",{className:"font-medium text-foreground/70",children:"File requirements"}),jsxs("ul",{className:"list-disc pl-5 space-y-1",children:[jsx("li",{children:".md file must contain skill name and description formatted in YAML"}),jsx("li",{children:".zip or .skill file must include a SKILL.md file"})]})]})]})})}function wt({onClose:r,onSelect:e}){let o=be(),n=useRef(null),s=useRef(r);s.current=r,useEffect(()=>{if(o)return;let t=a=>{n.current&&a.target instanceof Node&&!n.current.contains(a.target)&&s.current();};return document.addEventListener("mousedown",t),()=>document.removeEventListener("mousedown",t)},[o]);let f=[{id:"create-with-geoff",icon:jsx(pt,{}),label:"Create with Geoff"},{id:"write",icon:jsx(ht,{}),label:"Write skill instructions"},{id:"upload",icon:jsx(yt,{}),label:"Upload a skill"}];return o?jsxs("div",{className:"fixed inset-0 z-50 flex items-end",onClick:r,children:[jsx("div",{className:"fixed inset-0 bg-black/50"}),jsxs("div",{className:"relative z-10 w-full rounded-t-2xl bg-[#1a1a1a] p-4 pb-8 animate-in slide-in-from-bottom duration-200",onClick:t=>t.stopPropagation(),children:[jsx("div",{className:"mx-auto mb-3 h-1 w-10 rounded-full bg-zinc-600"}),f.map(t=>jsxs("button",{onClick:()=>{e(t.id),r();},className:"flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-800",children:[t.icon,t.label]},t.id))]})]}):jsx("div",{ref:n,className:"absolute right-2 top-11 z-50 w-56 overflow-hidden rounded-xl border border-zinc-700 bg-[#2a2a2a] shadow-xl animate-in fade-in zoom-in-95 duration-100",children:f.map(t=>jsxs("button",{onClick:()=>{e(t.id),r();},className:"flex w-full items-center gap-3 px-4 py-3 text-sm text-foreground transition-colors hover:bg-zinc-700/50",children:[t.icon,t.label]},t.id))})}function bt({entry:r,selected:e,onSelect:o,depth:n=0}){return jsxs("button",{onClick:()=>o(r),className:N("flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),style:{paddingLeft:`${8+n*16}px`},children:[jsx("span",{className:"truncate flex-1",children:r.path.split("/").pop()}),r.isDir&&jsx(xe,{className:"ml-auto text-muted-foreground"})]})}function Rt({repo:r,selected:e,expanded:o,onSelect:n,onToggle:s,children:f}){return jsxs("div",{children:[jsxs("button",{onClick:()=>{n(),s();},className:N("flex w-full items-center gap-2 rounded-md px-2 py-2 text-left text-sm font-medium transition-colors",e?"bg-[#141414] text-foreground":"text-muted-foreground hover:bg-muted/50 hover:text-foreground"),children:[jsx(xe,{open:o}),jsx(FileText,{className:"h-4 w-4 shrink-0"}),jsx("span",{className:"truncate",children:r.name})]}),o&&f]})}function vt({entry:r,content:e,loading:o,repoName:n}){let[s,f]=useState(false),t=useRef(null);useEffect(()=>()=>{t.current&&clearTimeout(t.current);},[]);let[a,l]=useState(false),c=async()=>{if(e)try{await navigator.clipboard.writeText(e),f(!0),l(!1),t.current&&clearTimeout(t.current),t.current=setTimeout(()=>f(!1),2e3);}catch{l(true),t.current&&clearTimeout(t.current),t.current=setTimeout(()=>l(false),2e3);}};if(!r)return jsx("div",{className:"flex h-full items-center justify-center text-sm text-muted-foreground",children:"Select a file to view its content"});if(o)return jsx("div",{className:"flex h-full items-center justify-center",children:jsx(Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})});let u=r.path.split("/").pop()||r.path,m=/\.(md|mdx)$/i.test(u);return jsxs("div",{className:"flex h-full flex-col px-3",children:[jsxs("div",{className:"flex items-center justify-between px-4 py-3",children:[jsx("h3",{className:"text-sm sm:text-lg font-semibold text-foreground",children:u}),jsx("button",{onClick:c,"aria-label":"Copy file content",className:N("rounded p-1 transition-colors",s?"text-green-500":a?"text-red-500":"text-muted-foreground hover:text-foreground"),children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"currentColor",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",className:"shrink-0",children:jsx("path",{d:"M12.5 3A1.5 1.5 0 0 1 14 4.5V6h1.5A1.5 1.5 0 0 1 17 7.5v8a1.5 1.5 0 0 1-1.5 1.5h-8A1.5 1.5 0 0 1 6 15.5V14H4.5A1.5 1.5 0 0 1 3 12.5v-8A1.5 1.5 0 0 1 4.5 3zm1.5 9.5a1.5 1.5 0 0 1-1.5 1.5H7v1.5a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5H14zM4.5 4a.5.5 0 0 0-.5.5v8a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5z"})})})]}),jsx("div",{className:"flex-1 overflow-auto p-4",children:m?jsx(Q,{content:e||""}):jsx("pre",{className:"whitespace-pre-wrap text-sm text-foreground font-mono leading-relaxed",children:e||""})})]})}function St({config:r,category:e,className:o,style:n}){let{repos:s,loading:f,error:t,refresh:a}=D(r),[l,c]=useState(null),[u,m]=useState(null),[d,g]=useState(null),[p,x]=useState(null),[w,R]=useState(false),[C,I]=useState(""),[P,M]=useState(false),[ee,te]=useState(false),[re,A]=useState(null),ve=s.find(y=>y.repo_id===l),{entries:Se,getFileContent:ne}=H(r,u),se=s.filter(y=>!C||y.name.toLowerCase().includes(C.toLowerCase())),Ce=useCallback(async y=>{if(!y.isDir){g(y),R(true);try{let T=await ne(y.cid);x(T);}catch(T){let Te=T instanceof Error?T.message:"Unknown error";x(`Failed to load file: ${Te}`);}finally{R(false);}}},[ne]);useEffect(()=>{s.length>0&&!l&&(c(s[0].repo_id),m(s[0].repo_id));},[s,l]);let Ne=y=>{y==="create-with-geoff"?window.open(`https://www.geoff.ai/?p=${encodeURIComponent("Let's create a skill together using your skill-creator skill. First ask me what the skill should do.")}`,"_blank","noopener,noreferrer"):A(y);};return jsxs("div",{className:N("flex flex-1 h-full min-h-0",o),style:n,children:[jsxs("div",{className:"relative flex w-96 shrink-0 flex-col border-r",children:[jsx("div",{className:"flex h-12 items-center gap-2 px-3",children:P?jsxs(Fragment,{children:[jsxs("div",{className:"flex flex-1 items-center gap-2 rounded-md border bg-muted/50 px-2 py-1",children:[jsx(he,{size:16,className:"shrink-0 text-muted-foreground"}),jsx("input",{type:"text",value:C,onChange:y=>I(y.target.value),placeholder:"Search",autoFocus:true,"aria-label":"Search items",className:"flex-1 bg-transparent text-xs text-foreground placeholder:text-muted-foreground focus:outline-none"})]}),jsx("button",{onClick:()=>{M(false),I("");},className:"rounded p-1 text-muted-foreground hover:text-foreground",children:jsx(X,{size:16})})]}):jsxs(Fragment,{children:[jsx("h3",{className:"flex-1 text-sm sm:text-lg font-semibold text-foreground capitalize",children:e||"Items"}),jsx("button",{onClick:()=>M(true),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Search",children:jsx(he,{size:20})}),jsx("button",{onClick:()=>te(!ee),className:"rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground","aria-label":"Add new",children:jsx(we,{size:20})})]})}),ee&&jsx(wt,{onClose:()=>te(false),onSelect:Ne}),jsx("div",{className:"flex-1 overflow-y-auto p-2",children:f?jsx("div",{className:"flex items-center justify-center py-8",children:jsx(Loader2,{className:"h-5 w-5 animate-spin text-muted-foreground"})}):t?jsx("p",{className:"px-2 py-4 text-xs text-red-500",children:t}):se.length===0?jsx("p",{className:"px-2 py-4 text-xs text-muted-foreground",children:C?"No matching items":"No items yet"}):jsx("div",{className:"space-y-0.5",children:se.map(y=>jsx(Rt,{repo:y,selected:l===y.repo_id,expanded:u===y.repo_id,onSelect:()=>{c(y.repo_id),g(null),x(null);},onToggle:()=>m(u===y.repo_id?null:y.repo_id),children:jsx("div",{className:"ml-10 pl-1",children:Se.map(T=>jsx(bt,{entry:T,selected:d?.path===T.path,onSelect:Ce,depth:T.path.split("/").length-1},T.path))})},y.repo_id))})})]}),jsx("div",{className:"flex-1 min-w-0",children:jsx(vt,{entry:d,content:p,loading:w,repoName:ve?.name||""})}),re==="write"&&jsx(kt,{config:r,onClose:()=>A(null),onCreated:a}),re==="upload"&&jsx(xt,{config:r,onClose:()=>A(null),onCreated:a})]})}
10
+ export{Q as Markdown,St as RackBrowser,fe as estimateCost,et as useNetworkStats,Oe as usePaginatedRepos,b as useRackClient,Fe as useRackRegister,De as useRackSession,Ae as useRepoPush,H as useRepoTree,D as useRepos,Je as useSkillStats,ot as useStar,Ge as useTensorStats,rt as useTrending};
@@ -230,6 +230,26 @@ interface TrendingRepo extends RepoInfo {
230
230
  usage: number;
231
231
  score: number;
232
232
  }
233
+ interface PaginationInfo {
234
+ /** Total items across all pages */
235
+ total: number;
236
+ /** Items per page */
237
+ limit: number;
238
+ /** Whether more items exist beyond this page */
239
+ has_more: boolean;
240
+ /** Opaque cursor for fetching the next page (null if no more) */
241
+ next_cursor: string | null;
242
+ }
243
+ interface PaginatedResult<T> {
244
+ items: T[];
245
+ pagination: PaginationInfo;
246
+ }
247
+ interface PaginationParams {
248
+ /** Max items to return (default 50, max 100) */
249
+ limit?: number;
250
+ /** Opaque cursor from a previous response's next_cursor */
251
+ cursor?: string;
252
+ }
233
253
  interface CostEstimate {
234
254
  type: 'skill' | 'tensor';
235
255
  totalBytes: number;
@@ -239,4 +259,4 @@ interface CostEstimate {
239
259
  registrationCostTokens: number;
240
260
  }
241
261
 
242
- export type { CostEstimate, DiffEntry, InitResult, NetworkStats, PushResult, RackConfig, RackSession, RepoCommit, RepoFile, RepoInfo, RepoTree, SkillMeta, SkillRegistrationInput, SkillRegistrationResult, SkillStats, StarInfo, StarResult, TensorMeta, TensorRegistrationInput, TensorRegistrationResult, TensorStats, TokenBudget, TreeEntry, TrendingRepo };
262
+ export type { CostEstimate, DiffEntry, InitResult, NetworkStats, PaginatedResult, PaginationInfo, PaginationParams, PushResult, RackConfig, RackSession, RepoCommit, RepoFile, RepoInfo, RepoTree, SkillMeta, SkillRegistrationInput, SkillRegistrationResult, SkillStats, StarInfo, StarResult, TensorMeta, TensorRegistrationInput, TensorRegistrationResult, TensorStats, TokenBudget, TreeEntry, TrendingRepo };
@@ -230,6 +230,26 @@ interface TrendingRepo extends RepoInfo {
230
230
  usage: number;
231
231
  score: number;
232
232
  }
233
+ interface PaginationInfo {
234
+ /** Total items across all pages */
235
+ total: number;
236
+ /** Items per page */
237
+ limit: number;
238
+ /** Whether more items exist beyond this page */
239
+ has_more: boolean;
240
+ /** Opaque cursor for fetching the next page (null if no more) */
241
+ next_cursor: string | null;
242
+ }
243
+ interface PaginatedResult<T> {
244
+ items: T[];
245
+ pagination: PaginationInfo;
246
+ }
247
+ interface PaginationParams {
248
+ /** Max items to return (default 50, max 100) */
249
+ limit?: number;
250
+ /** Opaque cursor from a previous response's next_cursor */
251
+ cursor?: string;
252
+ }
233
253
  interface CostEstimate {
234
254
  type: 'skill' | 'tensor';
235
255
  totalBytes: number;
@@ -239,4 +259,4 @@ interface CostEstimate {
239
259
  registrationCostTokens: number;
240
260
  }
241
261
 
242
- export type { CostEstimate, DiffEntry, InitResult, NetworkStats, PushResult, RackConfig, RackSession, RepoCommit, RepoFile, RepoInfo, RepoTree, SkillMeta, SkillRegistrationInput, SkillRegistrationResult, SkillStats, StarInfo, StarResult, TensorMeta, TensorRegistrationInput, TensorRegistrationResult, TensorStats, TokenBudget, TreeEntry, TrendingRepo };
262
+ export type { CostEstimate, DiffEntry, InitResult, NetworkStats, PaginatedResult, PaginationInfo, PaginationParams, PushResult, RackConfig, RackSession, RepoCommit, RepoFile, RepoInfo, RepoTree, SkillMeta, SkillRegistrationInput, SkillRegistrationResult, SkillStats, StarInfo, StarResult, TensorMeta, TensorRegistrationInput, TensorRegistrationResult, TensorStats, TokenBudget, TreeEntry, TrendingRepo };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stacknet/rackutils",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "React hooks and components for reading and writing StackNet Racks",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",