From 4acb6cb06132a2675b9c9aef82ff78f255425742 Mon Sep 17 00:00:00 2001 From: Trevor Hart Date: Mon, 30 Mar 2026 17:41:12 -0400 Subject: [PATCH] feat: configurable skill naming mode (auto or filename-only) Add a NamingMode setting that controls how skill names are derived: - "auto" (default): uses frontmatter name, then H1 heading, then filename - "filename": always uses the filename, ignoring frontmatter/headings Co-Authored-By: Claude Opus 4.6 --- main.js | 6 +++--- src/scanner.ts | 52 ++++++++++++++++++++++++++++--------------------- src/settings.ts | 17 ++++++++++++++++ src/types.ts | 4 ++++ styles.css | 5 +++-- 5 files changed, 57 insertions(+), 27 deletions(-) diff --git a/main.js b/main.js index 69f0755..384e2d1 100644 --- a/main.js +++ b/main.js @@ -1,3 +1,3 @@ -var vt=Object.defineProperty;var De=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var Ce=Object.prototype.hasOwnProperty;var Le=(n,t)=>{for(var e in t)vt(n,e,{get:t[e],enumerable:!0})},Te=(n,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Ee(t))!Ce.call(n,i)&&i!==e&&vt(n,i,{get:()=>t[i],enumerable:!(s=De(t,i))||s.enumerable});return n};var Pe=n=>Te(vt({},"__esModule",{value:!0}),n);var as={};Le(as,{default:()=>ft});module.exports=Pe(as);var we=require("obsidian");var ke=require("obsidian");var O=require("obsidian"),jt=require("electron");var Ft=require("os"),g=require("fs"),p=require("path"),h=(0,Ft.homedir)(),W=process.env.XDG_CONFIG_HOME||(0,p.join)(h,".config");function K(n){return(0,g.existsSync)(`/Applications/${n}.app`)||(0,g.existsSync)((0,p.join)(h,"Applications",`${n}.app`))}function F(n){let t=[`/usr/local/bin/${n}`,`/opt/homebrew/bin/${n}`,(0,p.join)(h,".local","bin",n)];for(let s of t)if((0,g.existsSync)(s))return!0;let e=(0,p.join)(h,".nvm","versions","node");try{for(let s of(0,g.readdirSync)(e))if((0,g.existsSync)((0,p.join)(e,s,"bin",n)))return!0}catch{}return!1}var x=[{id:"claude-code",name:"Claude Code",color:"#f97316",icon:"brain",paths:[{baseDir:(0,p.join)(h,".claude","skills"),type:"skill",pattern:"directory-with-skillmd"},{baseDir:(0,p.join)(h,".claude","commands"),type:"command",pattern:"flat-md"}],agentPaths:[{baseDir:(0,p.join)(h,".claude","agents"),type:"agent",pattern:"flat-md"}],isInstalled:()=>(0,g.existsSync)((0,p.join)(h,".claude","settings.json"))||(0,g.existsSync)((0,p.join)(h,".claude","CLAUDE.md"))||F("claude")},{id:"cursor",name:"Cursor",color:"#3b82f6",icon:"mouse-pointer",paths:[{baseDir:(0,p.join)(h,".cursor","skills"),type:"skill",pattern:"directory-with-skillmd"},{baseDir:(0,p.join)(h,".cursor","rules"),type:"rule",pattern:"flat-md"}],agentPaths:[{baseDir:(0,p.join)(h,".cursor","agents"),type:"agent",pattern:"flat-md"}],isInstalled:()=>K("Cursor")||(0,g.existsSync)((0,p.join)(h,".cursor","argv.json"))},{id:"windsurf",name:"Windsurf",color:"#14b8a6",icon:"wind",paths:[{baseDir:(0,p.join)(h,".codeium","windsurf","memories"),type:"memory",pattern:"flat-md"},{baseDir:(0,p.join)(h,".windsurf","rules"),type:"rule",pattern:"flat-md"}],agentPaths:[],isInstalled:()=>K("Windsurf")||(0,g.existsSync)((0,p.join)(h,".codeium","windsurf","argv.json"))},{id:"codex",name:"Codex",color:"#22c55e",icon:"book",paths:[{baseDir:(0,p.join)(h,".codex","skills"),type:"skill",pattern:"directory-with-skillmd"},{baseDir:(0,p.join)(h,".codex","prompts"),type:"command",pattern:"flat-md"},{baseDir:(0,p.join)(h,".codex","memories"),type:"memory",pattern:"flat-md"}],agentPaths:[{baseDir:(0,p.join)(h,".codex","agents"),type:"agent",pattern:"flat-md"}],isInstalled:()=>(0,g.existsSync)((0,p.join)(h,".codex","config.toml"))||(0,g.existsSync)((0,p.join)(h,".codex","auth.json"))||F("codex")},{id:"copilot",name:"Copilot",color:"#a855f7",icon:"plane",paths:[{baseDir:(0,p.join)(h,".copilot","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>(0,g.existsSync)((0,p.join)(h,".copilot"))||F("copilot")},{id:"amp",name:"Amp",color:"#ec4899",icon:"zap",paths:[{baseDir:(0,p.join)(W,"amp","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>(0,g.existsSync)((0,p.join)(W,"amp","config.json"))||(0,g.existsSync)((0,p.join)(W,"amp","settings.json"))||F("amp")},{id:"opencode",name:"OpenCode",color:"#ef4444",icon:"terminal",paths:[{baseDir:(0,p.join)(W,"opencode","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>K("OpenCode")||(0,g.existsSync)((0,p.join)(W,"opencode","opencode.json"))||(0,g.existsSync)((0,p.join)(W,"opencode","opencode.jsonc"))||F("opencode")},{id:"pi",name:"Pi",color:"#06b6d4",icon:"sparkles",paths:[{baseDir:(0,p.join)(h,".pi","agent","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>F("pi")},{id:"antigravity",name:"Antigravity",color:"#ef4444",icon:"arrow-up-circle",paths:[{baseDir:(0,p.join)(h,".gemini","antigravity","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>K("Antigravity")||(0,g.existsSync)((0,p.join)(h,".gemini","antigravity","skills"))||F("antigravity")},{id:"claude-desktop",name:"Claude Desktop",color:"#f97316",icon:"monitor",paths:[],agentPaths:[],isInstalled:()=>K("Claude")},{id:"global-agents",name:"Global",color:"#a3e635",icon:"globe",paths:[{baseDir:(0,p.join)(h,".agents","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>(0,g.existsSync)((0,p.join)(h,".agents","skills"))},{id:"aider",name:"Aider",color:"#eab308",icon:"wrench",paths:[],agentPaths:[],isInstalled:()=>F("aider")}];var E={"claude-code":{viewBox:"0 0 24 24",paths:''},cursor:{viewBox:"0 0 466.73 532.09",paths:''},windsurf:{viewBox:"0 0 24 24",paths:''},codex:{viewBox:"0 0 24 24",paths:''},copilot:{viewBox:"0 0 24 24",paths:''},opencode:{viewBox:"0 0 24 36",paths:''},"claude-desktop":{viewBox:"0 0 24 24",paths:''},"global-agents":{viewBox:"0 0 24 24",paths:''},goose:{viewBox:"0 0 24 24",paths:''},cline:{viewBox:"0 0 24 24",paths:''},continue:{viewBox:"0 0 26 24",paths:''},"roo-code":{viewBox:"0 0 96 96",paths:''},replit:{viewBox:"0 0 24 24",paths:''},"gemini-cli":{viewBox:"0 0 24 24",paths:''}};function j(n,t,e=16){let s=E[t];if(!s)return;let i=document.createElementNS("http://www.w3.org/2000/svg","svg");i.setAttribute("viewBox",s.viewBox),i.setAttribute("width",String(e)),i.setAttribute("height",String(e)),i.setAttribute("fill","none"),i.classList.add("as-tool-svg"),i.innerHTML=s.paths,n.appendChild(i)}var tt=class{containerEl;store;onToggleDashboard;onToggleMarketplace;dashboardActive=!1;marketplaceActive=!1;constructor(t,e,s,i){this.containerEl=t,this.store=e,this.onToggleDashboard=s,this.onToggleMarketplace=i}setDashboardActive(t){this.dashboardActive=t,t&&(this.marketplaceActive=!1)}setMarketplaceActive(t){this.marketplaceActive=t,t&&(this.dashboardActive=!1)}render(){this.containerEl.empty(),this.containerEl.addClass("as-sidebar"),this.renderLibrarySection(),this.renderTypeSection(),this.renderToolSection(),this.renderProjectSection(),this.renderCollectionSection(),this.store.hasSkillkit||this.renderSkillkitCta()}renderSection(t,e){let s=this.containerEl.createDiv("as-sidebar-section");s.createDiv({cls:"as-sidebar-title",text:t});for(let i of e){let a=s.createDiv("as-sidebar-item");!this.dashboardActive&&this.isActive(i.filter)&&a.addClass("is-active");let r=a.createSpan("as-sidebar-icon");(0,O.setIcon)(r,i.icon),a.createSpan({cls:"as-sidebar-label",text:i.label}),i.count!==void 0&&a.createSpan({cls:"as-sidebar-count",text:String(i.count)}),a.addEventListener("click",()=>{this.dashboardActive&&this.onToggleDashboard(),this.marketplaceActive&&this.onToggleMarketplace(),this.store.setFilter(i.filter)})}}renderTypeSection(){let t=this.store.getTypeCounts(),s=[{label:"Skills",icon:"sparkles",type:"skill"},{label:"Commands",icon:"terminal",type:"command"},{label:"Agents",icon:"bot",type:"agent"},{label:"Rules",icon:"scroll",type:"rule"}].filter(i=>t.has(i.type)).map(i=>({label:i.label,icon:i.icon,filter:{kind:"type",type:i.type},count:t.get(i.type)||0}));s.length>0&&this.renderSection("Types",s)}renderToolSection(){let t=this.store.getToolCounts(),e=x.filter(i=>i.isInstalled()&&t.has(i.id));if(e.length===0)return;let s=this.containerEl.createDiv("as-sidebar-section");s.createDiv({cls:"as-sidebar-title",text:"Tools"});for(let i of e){let a={kind:"tool",toolId:i.id},r=s.createDiv("as-sidebar-item");!this.dashboardActive&&this.isActive(a)&&r.addClass("is-active");let l=r.createSpan("as-sidebar-icon");E[i.id]?j(l,i.id,14):(0,O.setIcon)(l,i.icon),r.createSpan({cls:"as-sidebar-label",text:i.name}),r.createSpan({cls:"as-sidebar-count",text:String(t.get(i.id)||0)}),r.addEventListener("click",()=>{this.dashboardActive&&this.onToggleDashboard(),this.store.setFilter(a)})}}renderProjectSection(){let t=this.store.getProjectCounts();if(t.size===0)return;let e=[];for(let[s,i]of t)e.push({label:s,icon:"folder-git-2",filter:{kind:"project",project:s},count:i});e.sort((s,i)=>s.label.localeCompare(i.label)),this.renderSection("Projects",e)}renderCollectionSection(){let t=this.containerEl.createDiv("as-sidebar-section");t.createDiv({cls:"as-sidebar-title",text:"Collections"});let e=new Set;for(let s of this.store.allItems)for(let i of s.collections)e.add(i);if(e.size===0){t.createDiv({cls:"as-sidebar-empty",text:"No collections yet"});return}for(let s of e){let i={kind:"collection",name:s},a=t.createDiv("as-sidebar-item");!this.dashboardActive&&this.isActive(i)&&a.addClass("is-active");let r=a.createSpan("as-sidebar-icon");(0,O.setIcon)(r,"folder"),a.createSpan({cls:"as-sidebar-label",text:s}),a.addEventListener("click",()=>{this.dashboardActive&&this.onToggleDashboard(),this.store.setFilter(i)})}}renderLibrarySection(){let t=this.containerEl.createDiv("as-sidebar-section");t.createDiv({cls:"as-sidebar-title",text:"Library"});let e=[{label:"All Skills",icon:"layers",filter:{kind:"all"}},{label:"Favorites",icon:"star",filter:{kind:"favorites"}}],s=this.dashboardActive||this.marketplaceActive;for(let o of e){let c=t.createDiv("as-sidebar-item");!s&&this.isActive(o.filter)&&c.addClass("is-active");let d=c.createSpan("as-sidebar-icon");(0,O.setIcon)(d,o.icon),c.createSpan({cls:"as-sidebar-label",text:o.label}),c.addEventListener("click",()=>{this.dashboardActive&&this.onToggleDashboard(),this.marketplaceActive&&this.onToggleMarketplace(),this.store.setFilter(o.filter)})}let i=t.createDiv("as-sidebar-item");this.dashboardActive&&i.addClass("is-active");let a=i.createSpan("as-sidebar-icon");(0,O.setIcon)(a,"bar-chart-2"),i.createSpan({cls:"as-sidebar-label",text:"Dashboard"}),i.addEventListener("click",()=>{this.marketplaceActive&&this.onToggleMarketplace(),this.dashboardActive||this.onToggleDashboard()});let r=t.createDiv("as-sidebar-item");this.marketplaceActive&&r.addClass("is-active");let l=r.createSpan("as-sidebar-icon");(0,O.setIcon)(l,"shopping-bag"),r.createSpan({cls:"as-sidebar-label",text:"Marketplace"}),r.addEventListener("click",()=>{this.dashboardActive&&this.onToggleDashboard(),this.marketplaceActive||this.onToggleMarketplace()})}renderSkillkitCta(){let t=this.containerEl.createDiv("as-skillkit-cta"),e=t.createDiv("as-skillkit-icon");(0,O.setIcon)(e,"bar-chart-2"),t.createDiv({cls:"as-skillkit-title",text:"Unlock analytics"}),t.createDiv({cls:"as-skillkit-desc",text:"Install skillkit to see usage stats, stale badges, and heavy skill warnings."}),t.createDiv("as-skillkit-cmd").createEl("code",{text:"npm i -g skillkit"}),t.createEl("a",{cls:"as-skillkit-link",text:"Learn more",href:"https://www.npmjs.com/package/skillkit"}).addEventListener("click",a=>{a.preventDefault(),jt.shell.openExternal("https://www.npmjs.com/package/skillkit")})}isActive(t){let e=this.store.filter;return e.kind!==t.kind?!1:e.kind==="tool"&&t.kind==="tool"?e.toolId===t.toolId:e.kind==="type"&&t.kind==="type"?e.type===t.type:e.kind==="collection"&&t.kind==="collection"?e.name===t.name:e.kind==="project"&&t.kind==="project"?e.project===t.project:!0}};var Q=require("obsidian");var et=class{containerEl;store;onSelect;selectedId=null;inputEl=null;listEl=null;typeFilter=null;sortBy="name";dropdownEl=null;constructor(t,e,s){this.containerEl=t,this.store=e,this.onSelect=s}setSelected(t){this.selectedId=t}render(){if(!this.inputEl){this.containerEl.empty(),this.containerEl.addClass("as-list");let t=this.containerEl.createDiv("as-search");this.inputEl=t.createEl("input",{type:"text",placeholder:"Search skills...",cls:"as-search-input"}),this.inputEl.addEventListener("input",()=>{this.store.setSearch(this.inputEl.value)});let e=t.createDiv("as-filter-btn");(0,Q.setIcon)(e,"filter"),e.setAttribute("aria-label","Filter by status"),e.addEventListener("click",i=>{i.stopPropagation(),this.toggleDropdown(e)});let s=t.createDiv("as-filter-btn");(0,Q.setIcon)(s,this.sortBy==="usage"?"arrow-down-wide-narrow":"arrow-down-a-z"),s.setAttribute("aria-label",this.sortBy==="usage"?"Sorted by usage":"Sorted by name"),s.addEventListener("click",()=>{this.sortBy=this.sortBy==="name"?"usage":"name",(0,Q.setIcon)(s,this.sortBy==="usage"?"arrow-down-wide-narrow":"arrow-down-a-z"),s.setAttribute("aria-label",this.sortBy==="usage"?"Sorted by usage":"Sorted by name"),this.renderList()}),this.listEl=this.containerEl.createDiv("as-list-items")}this.inputEl.value=this.store.searchQuery,this.renderList()}toggleDropdown(t){if(this.dropdownEl){this.dropdownEl.remove(),this.dropdownEl=null;return}this.dropdownEl=t.createDiv("as-filter-dropdown");let e=[{id:"all",label:"All",cls:""},{id:"stale",label:"Stale",cls:"as-badge-stale"},{id:"heavy",label:"Heavy",cls:"as-badge-heavy"},{id:"oversized",label:"Oversized",cls:"as-badge-warn"},{id:"conflict",label:"Conflict",cls:"as-badge-conflict"}];for(let i of e){let a=this.dropdownEl.createDiv("as-filter-option");(i.id==="all"&&!this.typeFilter||i.id===this.typeFilter)&&a.addClass("is-active"),i.cls?a.createSpan({cls:i.cls,text:i.label}):a.setText(i.label),a.addEventListener("click",r=>{r.stopPropagation(),this.typeFilter=i.id==="all"?null:i.id,this.dropdownEl&&(this.dropdownEl.remove(),this.dropdownEl=null),this.renderList()})}let s=()=>{this.dropdownEl&&(this.dropdownEl.remove(),this.dropdownEl=null),document.removeEventListener("click",s)};setTimeout(()=>document.addEventListener("click",s),0)}renderList(){if(!this.listEl)return;this.listEl.empty();let t=this.store.filteredItems;if(this.typeFilter)switch(this.typeFilter){case"stale":t=t.filter(e=>e.usage?.isStale);break;case"heavy":t=t.filter(e=>e.usage?.isHeavy);break;case"oversized":t=t.filter(e=>e.warnings?.oversized);break;case"conflict":t=t.filter(e=>e.conflicts&&e.conflicts.length>0);break}if(this.sortBy==="usage"&&(t=[...t].sort((e,s)=>(s.usage?.uses??0)-(e.usage?.uses??0))),this.typeFilter){let e={stale:"Stale",heavy:"Heavy",oversized:"Oversized",conflict:"Conflict"},s=this.listEl.createDiv("as-active-filter");s.createSpan({text:`Showing: ${e[this.typeFilter]??this.typeFilter}`}),s.createSpan({cls:"as-filter-clear",text:"Clear"}).addEventListener("click",()=>{this.typeFilter=null,this.renderList()})}if(t.length===0){this.listEl.createDiv({cls:"as-list-empty",text:"No skills found"});return}for(let e of t)this.renderCard(this.listEl,e)}renderCard(t,e){let s=t.createDiv("as-skill-card");e.id===this.selectedId&&s.addClass("is-selected");let i=s.createDiv("as-skill-header");if(i.createSpan({cls:"as-skill-name",text:e.name}),e.isFavorite){let r=i.createSpan("as-skill-star");(0,Q.setIcon)(r,"star")}e.description&&s.createDiv({cls:"as-skill-desc",text:e.description.length>80?e.description.slice(0,80)+"...":e.description});let a=s.createDiv("as-skill-meta");a.createSpan({cls:`as-type-tag as-type-${e.type}`,text:e.type});for(let r of e.tools){let l=x.find(c=>c.id===r);if(!l)continue;let o=a.createSpan("as-tool-badge");o.title=l.name,o.setAttribute("aria-label",l.name),o.setCssProps({"--tool-color":l.color}),E[r]?j(o,r,12):o.addClass("as-tool-badge-dot")}e.usage&&(e.usage.uses>0&&a.createSpan({cls:"as-usage-badge",text:`${e.usage.uses}`,attr:{"aria-label":`Used ${e.usage.uses} times`}}),e.usage.isStale&&a.createSpan({cls:"as-badge-stale",text:"stale"}),e.usage.isHeavy&&a.createSpan({cls:"as-badge-heavy",text:"heavy"})),e.warnings?.oversized&&a.createSpan({cls:"as-badge-warn",text:"oversized"}),e.conflicts&&e.conflicts.length>0&&a.createSpan({cls:"as-badge-conflict",text:"conflict"}),s.addEventListener("click",()=>{this.selectedId=e.id,this.onSelect(e)})}};var k=require("obsidian"),Jt=require("fs"),Zt=require("electron");var kt=require("child_process"),A=require("fs"),v=require("path"),Ot=require("os"),M=(0,Ot.homedir)(),Ie=(0,v.join)(M,".skillkit","analytics.db");function Rt(){let n=["/usr/local/bin","/opt/homebrew/bin",(0,v.join)(M,".local","bin"),(0,v.join)(M,".bun","bin")],t=(0,v.join)(M,".nvm","versions","node");try{for(let s of(0,A.readdirSync)(t))n.push((0,v.join)(t,s,"bin"))}catch{}let e=(0,v.join)(M,".local","share","mise","installs");for(let s of["node","bun"])try{for(let i of(0,A.readdirSync)((0,v.join)(e,s)))n.push((0,v.join)(e,s,i,"bin"))}catch{}return[...n,process.env.PATH||""].join(":")}function Me(){let n=["/usr/local/bin/skillkit","/opt/homebrew/bin/skillkit",(0,v.join)(M,".local","bin","skillkit"),(0,v.join)(M,".bun","bin","skillkit"),(0,v.join)(M,".local","share","mise","shims","skillkit")];for(let s of n)if((0,A.existsSync)(s))return s;let t=(0,v.join)(M,".nvm","versions","node");try{for(let s of(0,A.readdirSync)(t)){let i=(0,v.join)(t,s,"bin","skillkit");if((0,A.existsSync)(i))return i}}catch{}let e=(0,v.join)(M,".local","share","mise","installs");for(let s of["node","bun"])try{for(let i of(0,A.readdirSync)((0,v.join)(e,s))){let a=(0,v.join)(e,s,i,"bin","skillkit");if((0,A.existsSync)(a))return a}}catch{}return null}var bt;function St(){return bt===void 0&&(bt=Me()),bt}function C(){return St()!==null||(0,A.existsSync)(Ie)}function H(n){let t=St();if(!t)return null;try{let e=(0,kt.execSync)(`${t} ${n} --json`,{encoding:"utf-8",timeout:15e3,env:{...process.env,NO_COLOR:"1",PATH:Rt()},stdio:["pipe","pipe","pipe"]}).trim(),s=e.indexOf("{"),i=e.indexOf("["),a=s===-1?i:i===-1?s:Math.min(s,i);return a===-1?null:JSON.parse(e.slice(a))}catch{return null}}function Bt(){let n=new Map;if(!C())return n;let t=H("stats");if(!t?.top_skills)return n;let e=Date.now();for(let s of t.top_skills){let i=s.daily.length>0?s.daily[s.daily.length-1]?.date:null,a=null;i&&(a=Math.floor((e-new Date(i).getTime())/(1e3*60*60*24))),n.set(s.name,{uses:s.total,lastUsed:i||null,daysSinceUsed:a,isStale:a!==null&&a>30,isHeavy:!1,daily:s.daily})}return n}function Nt(){let n=new Map;if(!C())return n;let t=H("conflicts --dry-run");if(!t||!("pairs"in t))return n;for(let e of t.pairs)n.has(e.skill_a)||n.set(e.skill_a,[]),n.has(e.skill_b)||n.set(e.skill_b,[]),n.get(e.skill_a).push({skillName:e.skill_b,similarity:e.similarity}),n.get(e.skill_b).push({skillName:e.skill_a,similarity:e.similarity});return n}function zt(n){if(!C())return[];let t=H(`trace --list --skill ${n} --limit 5`);return Array.isArray(t)?t.map(e=>({traceId:e.trace_id,timestamp:e.timestamp,tokens:e.tokens_total,cost:e.cost_estimate,duration:e.duration_ms,model:e.model||"unknown"})):[]}function Vt(){if(!C())return{oversized:[],longDesc:[]};let n=H("health");return n?.warnings?{oversized:n.warnings.oversized||[],longDesc:n.warnings.long_descriptions||[]}:{oversized:[],longDesc:[]}}function U(n){let t=St();if(!t)return{success:!1,output:"skillkit not found"};try{return{success:!0,output:(0,kt.execSync)(`${t} ${n}`,{encoding:"utf-8",timeout:3e4,env:{...process.env,NO_COLOR:"1",PATH:Rt()},stdio:["pipe","pipe","pipe"]}).trim()}}catch(e){return{success:!1,output:e instanceof Error?e.message:"unknown error"}}}function yt(n){if(!n)return"never";let t=Date.now()-new Date(n).getTime(),e=Math.floor(t/6e4);if(e<60)return`${e}m ago`;let s=Math.floor(e/60);if(s<24)return`${s}h ago`;let i=Math.floor(s/24);return i<30?`${i}d ago`:`${Math.floor(i/30)}mo ago`}function Wt(n,t,e=48,s=16){if(t.length===0)return;let i=Math.max(...t,1),a=t.map((o,c)=>{let d=c/(t.length-1||1)*e,w=s-o/i*s;return`${d.toFixed(1)},${w.toFixed(1)}`}),r=document.createElementNS("http://www.w3.org/2000/svg","svg");r.setAttribute("viewBox",`0 0 ${e} ${s}`),r.setAttribute("width",String(e)),r.setAttribute("height",String(s)),r.classList.add("as-sparkline");let l=document.createElementNS("http://www.w3.org/2000/svg","polyline");l.setAttribute("points",a.join(" ")),l.setAttribute("fill","none"),l.setAttribute("stroke","currentColor"),l.setAttribute("stroke-width","1.5"),l.setAttribute("stroke-linecap","round"),l.setAttribute("stroke-linejoin","round"),r.appendChild(l),n.appendChild(r)}var Ut=require("obsidian");function N(n,t,e,s){new wt(n,t,e,s).open()}var wt=class extends Ut.Modal{title;message;onConfirm;constructor(t,e,s,i){super(t),this.title=e,this.message=s,this.onConfirm=i}onOpen(){let{contentEl:t}=this;t.addClass("as-confirm-modal"),t.createEl("p",{cls:"as-confirm-title",text:this.title}),t.createEl("p",{cls:"as-confirm-message",text:this.message});let e=t.createDiv("as-confirm-buttons");e.createEl("button",{cls:"as-confirm-cancel",text:"Cancel"}).addEventListener("click",()=>this.close()),e.createEl("button",{cls:"as-confirm-action mod-warning",text:"Confirm"}).addEventListener("click",()=>{this.close(),this.onConfirm()})}onClose(){this.contentEl.empty()}};function Ae(n){return Math.ceil(n.length/4)}function _e(n){return n<1024?`${n} B`:n<1024*1024?`${(n/1024).toFixed(1)} KB`:`${(n/(1024*1024)).toFixed(1)} MB`}function Gt(n){return n>=1e3?`${(n/1e3).toFixed(1)}k`:String(n)}function $e(n){return new Date(n).toLocaleDateString(void 0,{month:"short",day:"numeric",year:"numeric"})}var st=class{containerEl;store;settings;saveSettings;currentItem=null;isEditing=!1;app;constructor(t,e,s,i,a){this.containerEl=t,this.store=e,this.settings=s,this.saveSettings=i,this.app=a.app}show(t){this.currentItem=t,this.isEditing=!1,this.render()}clear(){this.currentItem=null,this.containerEl.empty(),this.containerEl.addClass("as-detail");let t=this.containerEl.createDiv("as-detail-empty");(0,k.setIcon)(t.createDiv("as-detail-empty-icon"),"file-text"),t.createDiv({text:"Select a skill to view"})}render(){this.containerEl.empty(),this.containerEl.addClass("as-detail");let t=this.currentItem;if(!t)return this.clear();this.renderToolbar(t),this.isEditing?this.renderEditor(t):this.renderPreview(t)}renderToolbar(t){let e=this.containerEl.createDiv("as-detail-toolbar"),s=e.createDiv("as-toolbar-top"),i=s.createDiv("as-toolbar-left");i.createSpan({cls:"as-detail-title",text:t.name});for(let u of t.tools){let D=x.find(gt=>gt.id===u);if(!D)continue;let V=i.createSpan("as-tool-name-badge");V.setCssProps({"--tool-color":D.color}),E[u]&&j(V,u,12),V.createSpan({text:D.name})}let a=s.createDiv("as-toolbar-right"),r=a.createEl("button",{cls:"as-toolbar-btn",attr:{"aria-label":"Toggle favorite"}});(0,k.setIcon)(r,t.isFavorite?"star":"star-off"),r.addEventListener("click",()=>{this.store.toggleFavorite(t.id,this.settings),this.saveSettings(),this.render()});let l=a.createEl("button",{cls:"as-toolbar-btn",attr:{"aria-label":this.isEditing?"Preview":"Edit"}});(0,k.setIcon)(l,this.isEditing?"eye":"pencil"),l.addEventListener("click",()=>{this.isEditing=!this.isEditing,this.render()});let o=a.createEl("button",{cls:"as-toolbar-btn",attr:{"aria-label":"Show in system explorer"}});if((0,k.setIcon)(o,"folder-open"),o.addEventListener("click",()=>{Zt.shell.showItemInFolder(t.filePath)}),C()){let u=a.createEl("button",{cls:"as-toolbar-btn as-toolbar-btn-danger",attr:{"aria-label":"Remove skill"}});(0,k.setIcon)(u,"trash-2"),u.addEventListener("click",()=>{N(this.app,"Remove skill",`Remove "${t.name}"? This will delete the skill files.`,()=>{let D=U(`prune --skill ${t.name} --yes`);D.success?(new k.Notice(`Removed ${t.name}`,5e3),this.store.refresh(this.settings),this.clear()):new k.Notice(`Failed to remove: ${D.output}`,5e3)})})}let c=e.createDiv("as-detail-meta-bar"),d=Ae(t.content),w=t.content.length;if(c.createSpan({cls:"as-meta-item",text:_e(t.fileSize)}),c.createSpan({cls:"as-meta-item",text:`${Gt(w)} chars`}),c.createSpan({cls:"as-meta-item",text:`~${Gt(d)} tokens`}),c.createSpan({cls:"as-meta-item",text:$e(t.lastModified)}),c.createSpan({cls:"as-meta-item as-meta-type",text:t.type}),t.usage&&t.usage.uses>0){let u=e.createDiv("as-detail-usage-bar");u.createSpan({cls:"as-usage-stat",text:`${t.usage.uses} uses`}),u.createSpan({cls:"as-usage-stat",text:`last: ${yt(t.usage.lastUsed)}`}),t.usage.isStale&&u.createSpan({cls:"as-badge-stale",text:"stale"}),t.usage.isHeavy&&u.createSpan({cls:"as-badge-heavy",text:"heavy"})}}renderFrontmatter(t,e){let s=Object.keys(e.frontmatter),i=t.createDiv("as-frontmatter");if(e.filePath){let a=i.createDiv("as-fm-prop");a.createSpan({cls:"as-fm-key",text:"path"}),a.createSpan({cls:"as-fm-value",text:e.filePath})}if(!(s.length===0&&!e.filePath))for(let a of s){let r=e.frontmatter[a];if(r==null)continue;let l=i.createDiv("as-fm-prop");l.createSpan({cls:"as-fm-key",text:a});let o=typeof r=="object"||Array.isArray(r)?JSON.stringify(r):String(r);o.length>200?l.createDiv({cls:"as-fm-value-long",text:o}):l.createSpan({cls:"as-fm-value",text:o})}}renderPreview(t){let e=this.containerEl.createDiv("as-detail-body");this.renderFrontmatter(e,t),this.renderWarnings(e,t),this.renderUsageSection(e,t),this.renderConflicts(e,t),this.renderTraces(e,t);let s=e.createDiv("as-detail-preview markdown-rendered");k.MarkdownRenderer.render(this.app,t.content,s,t.filePath,this)}renderWarnings(t,e){let s=[];if(e.warnings?.oversized&&s.push(`${e.warnings.lineCount} lines (recommended: <500)`),e.warnings?.longDesc&&s.push(`Description is ${e.warnings.descChars} chars (recommended: <1024)`),e.conflicts&&e.conflicts.length>0){let l=e.conflicts.map(o=>o.skillName).join(", ");s.push(`Conflicts with: ${l}`)}if(s.length===0)return;let i=t.createDiv("as-warnings"),a=i.createDiv("as-warnings-icon");(0,k.setIcon)(a,"alert-triangle");let r=i.createDiv("as-warnings-list");for(let l of s)r.createDiv({cls:"as-warnings-item",text:l})}renderUsageSection(t,e){if(!e.usage||e.usage.uses===0)return;let s=t.createDiv("as-usage-section"),i=s.createDiv("as-usage-left");if(i.createSpan({cls:"as-usage-count",text:String(e.usage.uses)}),i.createSpan({cls:"as-usage-label",text:"uses"}),i.createSpan({cls:"as-usage-last",text:yt(e.usage.lastUsed)}),e.usage.daily&&e.usage.daily.length>1){let a=s.createDiv("as-usage-spark");Wt(a,e.usage.daily.map(r=>r.count),80,20)}}renderConflicts(t,e){if(!e.conflicts||e.conflicts.length===0)return;let s=t.createDiv("as-conflicts-section");s.createDiv({cls:"as-section-title",text:`Conflicts (${e.conflicts.length})`});for(let i of e.conflicts){let a=s.createDiv("as-conflict-row");a.createSpan({cls:"as-conflict-name",text:i.skillName}),a.createDiv("as-conflict-bar-wrap").createDiv("as-conflict-bar").setCssProps({"--bar-w":`${(i.similarity*100).toFixed(0)}%`}),a.createSpan({cls:"as-conflict-score",text:`${(i.similarity*100).toFixed(0)}%`})}}renderTraces(t,e){if(!C())return;let s=zt(e.name);if(s.length===0)return;let i=t.createDiv("as-traces-section");i.createDiv({cls:"as-section-title",text:`Recent traces (${s.length})`});let a=i.createDiv("as-traces-table");for(let r of s){let l=a.createDiv("as-trace-row"),o=new Date(r.timestamp);l.createSpan({cls:"as-trace-date",text:o.toLocaleDateString(void 0,{month:"short",day:"numeric"})}),l.createSpan({cls:"as-trace-model",text:r.model.replace("claude-","").replace("-4-6","")}),l.createSpan({cls:"as-trace-tokens",text:`${(r.tokens/1e3).toFixed(1)}k`}),l.createSpan({cls:"as-trace-cost",text:r.cost>0?`$${r.cost.toFixed(2)}`:""}),l.createSpan({cls:"as-trace-duration",text:`${(r.duration/1e3).toFixed(1)}s`})}i.createDiv({cls:"as-traces-hint",text:"skillkit trace --list --skill "+e.name})}renderPruneAction(t,e){let s=t.createDiv("as-prune-section"),i=s.createEl("button",{cls:"as-prune-btn",text:"Remove this skill"});s.createSpan({cls:"as-prune-hint",text:"This skill hasn't been used in 30+ days"}),i.addEventListener("click",()=>{N(this.app,"Remove skill",`Remove "${e.name}"? This will delete the skill files.`,()=>{let a=U(`prune --skill ${e.name} --yes`);a.success?(new k.Notice(`Removed ${e.name}`,5e3),this.store.refresh(this.settings)):new k.Notice(`Failed to remove: ${a.output}`,5e3)})})}renderEditor(t){let e=this.containerEl.createDiv("as-detail-body as-detail-body-editor"),s=e.createEl("textarea",{cls:"as-editor-textarea"});s.value=t.content,s.spellcheck=!1,s.addEventListener("keydown",r=>{if((r.metaKey||r.ctrlKey)&&r.key==="s"&&(r.preventDefault(),this.saveFile(t,s.value)),r.key==="Tab"){r.preventDefault();let l=s.selectionStart,o=s.selectionEnd;s.value=s.value.substring(0,l)+" "+s.value.substring(o),s.selectionStart=s.selectionEnd=l+1}});let i=e.createDiv("as-save-bar");i.createEl("button",{cls:"as-save-btn",text:"Save"}).addEventListener("click",()=>{this.saveFile(t,s.value)}),i.createSpan({cls:"as-save-hint",text:"Cmd+S to save"})}saveFile(t,e){try{(0,Jt.writeFileSync)(t.filePath,e,"utf-8"),t.content=e,new k.Notice(`Saved ${t.name}`,5e3)}catch(s){new k.Notice(`Failed to save: ${s instanceof Error?s.message:String(s)}`,5e3)}}};var _=require("obsidian"),re=require("electron");var xt=require("child_process"),S=require("fs"),b=require("path"),Yt=require("os"),q=require("obsidian"),y=(0,Yt.homedir)(),Kt=(0,b.join)(y,".agents",".skill-lock.json"),He="https://skills.sh/api";async function Dt(n){if(n.length<2)return[];try{let e=(await(0,q.requestUrl)({url:`${He}/search?q=${encodeURIComponent(n)}&limit=30`})).json;if(!e.skills)return[];let s=se();return e.skills.map(i=>({...i,installed:s.has(i.name)}))}catch{return[]}}var Qt=new Map;async function Fe(n){let t=Qt.get(n);if(t)return t;let s=(await(0,q.requestUrl)({url:`https://api.github.com/repos/${n}`})).json.default_branch||"main",a=(await(0,q.requestUrl)({url:`https://api.github.com/repos/${n}/git/trees/${s}?recursive=1`})).json.tree.filter(l=>l.path.endsWith("/SKILL.md")).map(l=>l.path),r={branch:s,files:a};return Qt.set(n,r),r}function je(n,t,e){let s=t.split("/"),i=s[s.length-1]||n,a=new Set([i,n]);for(let r of e.split("/")){n.startsWith(r+"-")&&a.add(n.slice(r.length+1));for(let l of r.split("-"))n.startsWith(l+"-")&&a.add(n.slice(l.length+1))}return a}async function Xt(n,t,e){try{let{branch:s,files:i}=await Fe(n),a=je(t,e,n),r=i.find(c=>{let d=c.replace("/SKILL.md","").split("/").pop()||"";return a.has(d)});r||(r=i.find(c=>{let d=c.replace("/SKILL.md","").split("/").pop()||"";return t.includes(d)||d.includes(t)}));let l=r||`skills/${t}/SKILL.md`;return(await(0,q.requestUrl)({url:`https://raw.githubusercontent.com/${n}/${s}/${l}`})).text}catch{return null}}async function te(){let n=["react","next","clerk","stripe","ai"],t=new Set,e=[];for(let s of n){let i=await Dt(s);for(let a of i)t.has(a.id)||(t.add(a.id),e.push(a))}return e.sort((s,i)=>i.installs-s.installs).slice(0,20)}function Oe(){let n=["/usr/local/bin","/opt/homebrew/bin",(0,b.join)(y,".local","bin"),(0,b.join)(y,".bun","bin")],t=(0,b.join)(y,".nvm","versions","node");try{for(let e of(0,S.readdirSync)(t))n.push((0,b.join)(t,e,"bin"))}catch{}return[...n,process.env.PATH||""].join(":")}function qt(){let n=(0,b.join)(y,".bun","bin","bunx");return(0,S.existsSync)(n)?n:(0,S.existsSync)("/usr/local/bin/bunx")||(0,S.existsSync)("/opt/homebrew/bin/bunx")?"bunx":"npx"}function Et(n="auto"){return n==="npx"?"npx":qt()}var ee=[{id:"claude-code",label:"Claude Code"},{id:"cursor",label:"Cursor"},{id:"codex",label:"Codex"},{id:"github-copilot",label:"GitHub Copilot"},{id:"windsurf",label:"Windsurf"},{id:"amp",label:"Amp"},{id:"opencode",label:"OpenCode"},{id:"cline",label:"Cline"},{id:"gemini-cli",label:"Gemini CLI"},{id:"goose",label:"Goose"},{id:"kiro-cli",label:"Kiro"},{id:"roo",label:"Roo Code"},{id:"continue",label:"Continue"},{id:"antigravity",label:"Antigravity"},{id:"warp",label:"Warp"},{id:"pi",label:"Pi"},{id:"replit",label:"Replit"}],it={"claude-code":"claude-code",cursor:"cursor",codex:"codex",copilot:"github-copilot",windsurf:"windsurf",amp:"amp",opencode:"opencode",antigravity:"antigravity","claude-desktop":"claude-code",pi:"pi","global-agents":"claude-code",aider:"claude-code"};function se(){let n=new Set;if(!(0,S.existsSync)(Kt))return n;try{let t=JSON.parse((0,S.readFileSync)(Kt,"utf-8"));if(t.skills)for(let e of Object.keys(t.skills))n.add(e)}catch{}return n}var Re=[(0,b.join)(y,".claude","skills"),(0,b.join)(y,".cursor","skills"),(0,b.join)(y,".codex","skills"),(0,b.join)(y,".codeium","windsurf","skills"),(0,b.join)(y,".config","amp","skills"),(0,b.join)(y,".config","opencode","skills"),(0,b.join)(y,".copilot","skills"),(0,b.join)(y,".agents","skills")];function Be(n){for(let t of Re){let e=(0,b.join)(t,n);if((0,S.existsSync)(e))try{(0,S.rmSync)(e,{recursive:!0,force:!0})}catch{}}Ne(n)}function Ne(n){let t=(0,b.join)(y,".agents",".skill-lock.json");if((0,S.existsSync)(t))try{let e=JSON.parse((0,S.readFileSync)(t,"utf-8"));e.skills&&e.skills[n]&&(delete e.skills[n],(0,S.writeFileSync)(t,JSON.stringify(e,null,2)+` -`,"utf-8"))}catch{}}function nt(n){let t=se();for(let e of n)e.installed=t.has(e.name);return n}function Ct(n,t=12e4){return new Promise(e=>{(0,xt.exec)(n,{encoding:"utf-8",timeout:t,env:{...process.env,PATH:Oe(),NO_COLOR:"1"}},(s,i)=>{let a=String(i??"");!s||a.includes("Done")||a.includes("Installed")||a.includes("Removed")||a.includes("Updated")?e({success:!0,output:a}):e({success:!1,output:s?.message??"Command failed"})})})}async function ie(n,t,e={}){let s=t.length>0?`-a ${t.join(" ")}`:"-a '*'",i=e.global?"-g":"",r=`${Et(e.runner||"auto")} skills add ${n} ${s} ${i} -y`.replace(/\s+/g," ").trim();return Ct(r)}async function ne(n,t="auto"){let s=`${Et(t)} skills remove ${n} -y`,i=await Ct(s,3e4);return Be(n),{success:!0,output:i.output||`Cleaned ${n}`}}async function ae(n="auto"){let e=`${Et(n)} skills update`,s=await Ct(e),i=s.output.match(/Updated (\d+) skill/);return{...s,count:i?parseInt(i[1]):0}}function Lt(n){return n>=1e6?`${(n/1e6).toFixed(1)}M`:n>=1e3?`${(n/1e3).toFixed(1)}K`:String(n)}var G=require("fs"),oe=require("path"),le=require("os");function ze(){let n=H("stats"),t=H("health"),e=H("burn"),s=H("context");return{stats:n,health:t,burn:e&&e.length>0?e[0]:null,context:s}}var Tt=(0,oe.join)((0,le.homedir)(),".skillkit","dashboard-cache.json"),$=null,R=null;function Ve(){if(!$&&(0,G.existsSync)(Tt))try{let n=JSON.parse((0,G.readFileSync)(Tt,"utf-8"));$=n.data,R=n.cachedAt}catch{}}function We(){if($)try{(0,G.writeFileSync)(Tt,JSON.stringify({data:$,cachedAt:R},null,2),"utf-8")}catch{}}Ve();var at=class{containerEl;app;constructor(t,e){this.containerEl=t,this.app=e}render(){if(this.containerEl.empty(),this.containerEl.addClass("as-dashboard"),!C()){this.renderNoSkillkit();return}if($)this.renderDashboard($);else{let t=this.containerEl.createDiv("as-dash-loading");t.createDiv("as-dash-spinner"),t.createDiv({cls:"as-dash-loading-text",text:"Loading analytics..."}),setTimeout(()=>{let e=ze();$=e,R=Date.now(),We(),t.remove(),this.renderDashboard(e)},10)}}renderDashboard(t){if(this.renderActionBar(t),t.stats&&this.renderOverview(t.stats,t.health),t.stats&&this.renderTopSkills(t.stats),t.health||t.context){let e=this.containerEl.createDiv("as-dash-row");t.health&&this.renderHealth(t.health,e),t.context&&this.renderContext(t.context,e)}t.burn&&this.renderBurn(t.burn),t.health&&this.renderStale(t.health)}renderActionBar(t){let e=this.containerEl.createDiv("as-dash-action-bar");if(R){let r=Math.round((Date.now()-R)/1e3),l=r<5?"just now":r<60?`${r}s ago`:`${Math.round(r/60)}m ago`;e.createSpan({cls:"as-dash-updated",text:`Updated ${l}`})}let s=e.createDiv("as-dash-action-buttons"),i=s.createEl("button",{cls:"as-action-btn",text:"Update skills"});i.addEventListener("click",()=>{i.setText("Updating..."),i.disabled=!0,ae().then(r=>{if(r.success){let l=r.count>0?`Updated ${r.count} skill(s)`:"All skills up to date";new _.Notice(l,5e3),$=null,R=null,this.render()}else new _.Notice(`Update failed: ${r.output}`,5e3);i.setText("Update skills"),i.disabled=!1})});let a=s.createEl("button",{cls:"as-action-btn",text:"Scan sessions"});if(a.addEventListener("click",()=>{a.setText("Scanning..."),a.disabled=!0,setTimeout(()=>{let r=U("scan");r.success?(new _.Notice("Scan complete",5e3),$=null,R=null,this.render()):new _.Notice(`Scan failed: ${r.output}`,5e3),a.setText("Scan sessions"),a.disabled=!1},10)}),t.health&&t.health.usage.unused_30d>0){let r=s.createEl("button",{cls:"as-action-btn as-action-btn-danger",text:`Prune ${t.health.usage.unused_30d} stale`});r.addEventListener("click",()=>{N(this.app,"Prune stale skills",`Remove ${t.health.usage.unused_30d} unused skills? This cannot be undone.`,()=>{r.setText("Pruning..."),r.disabled=!0,setTimeout(()=>{let l=U("prune --yes");l.success?(new _.Notice("Pruned stale skills",5e3),$=null,R=null,this.render()):new _.Notice(`Prune failed: ${l.output}`,5e3),r.setText(`Prune ${t.health.usage.unused_30d} stale`),r.disabled=!1},10)})})}}renderNoSkillkit(){let t=this.containerEl.createDiv("as-dash-empty"),e=t.createDiv("as-dash-empty-icon");(0,_.setIcon)(e,"bar-chart-2"),t.createEl("h3",{text:"Dashboard requires skillkit"}),t.createEl("p",{text:"Install skillkit to unlock usage analytics, burn rate, context tax, and more."}),t.createDiv("as-dash-install-cmd").createEl("code",{text:"npm i -g @crafter/skillkit && skillkit scan"}),t.createEl("a",{cls:"as-skillkit-link",text:"Learn more",href:"https://www.npmjs.com/package/@crafter/skillkit"}).addEventListener("click",a=>{a.preventDefault(),re.shell.openExternal("https://www.npmjs.com/package/@crafter/skillkit")})}renderOverview(t,e){let s=this.containerEl.createDiv("as-dash-section");s.createDiv({cls:"as-dash-title",text:"Overview"});let i=s.createDiv("as-dash-stats");if(this.statCard(i,String(t.total_invocations),"invocations","activity"),this.statCard(i,String(t.unique_skills),"active skills","sparkles"),this.statCard(i,String(e?.installed??0),"installed","package"),this.statCard(i,String(e?.usage.unused_30d??0),"stale","alert-triangle"),t.streak&&t.streak.current>0){let a=s.createDiv("as-dash-streak-row");a.createSpan({cls:"as-streak-value",text:`${t.streak.current} day streak`}),t.streak.current>=7&&a.createSpan({cls:"as-streak-fire",text:"on fire"}),a.createSpan({cls:"as-streak-longest",text:`longest: ${t.streak.longest}d`})}if(t.velocity&&t.velocity.this_week>0){let a=s.createDiv("as-dash-velocity-row");a.createSpan({text:`This week: $${t.velocity.this_week.toFixed(0)}`}),a.createSpan({cls:"as-velocity-vs",text:`vs $${t.velocity.last_week.toFixed(0)} last week`});let r=t.velocity.change_pct,l=r>0?"as-velocity-up":r<0?"as-velocity-down":"",o=r>0?"+":"";a.createSpan({cls:`as-velocity-change ${l}`,text:`${o}${r.toFixed(0)}%`})}}statCard(t,e,s,i){let a=t.createDiv("as-stat-card"),r=a.createDiv("as-stat-icon");(0,_.setIcon)(r,i),a.createDiv({cls:"as-stat-value",text:e}),a.createDiv({cls:"as-stat-label",text:s})}renderTopSkills(t){if(t.top_skills.length===0)return;let e=this.containerEl.createDiv("as-dash-section");e.createDiv({cls:"as-dash-title",text:`Top Skills (${t.period.days}d)`});let s=t.top_skills[0]?.total||1,i=e.createDiv("as-dash-bars");for(let a of t.top_skills.slice(0,10)){let r=i.createDiv("as-bar-row");r.createSpan({cls:"as-bar-name",text:a.name}),r.createDiv("as-bar-wrap").createDiv("as-bar-fill").setCssProps({"--bar-w":`${a.total/s*100}%`}),r.createSpan({cls:"as-bar-count",text:String(a.total)})}}renderHealth(t,e){let s=(e||this.containerEl).createDiv("as-dash-section");s.createDiv({cls:"as-dash-title",text:"Health"});let i=t.usage.used_30d+t.usage.unused_30d,a=i>0?Math.round(t.usage.used_30d/i*100):0,r=s.createDiv("as-dash-health-row"),l=r.createDiv("as-donut");l.setCssProps({"--pct":`${a}`}),l.createDiv({cls:"as-donut-label",text:`${a}%`}),l.createDiv({cls:"as-donut-sub",text:"active"});let o=r.createDiv("as-health-details");o.createDiv({cls:"as-health-line",text:`${t.usage.used_30d} used in 30d`}),o.createDiv({cls:"as-health-line as-health-warn",text:`${t.usage.unused_30d} never triggered`});let d=o.createDiv("as-budget-bar").createDiv("as-budget-fill");d.setCssProps({"--bar-w":`${t.metadata.pct}%`}),t.metadata.pct>80&&d.addClass("as-budget-over"),o.createDiv({cls:"as-health-line",text:`Metadata budget: ${t.metadata.pct}%`})}renderBurn(t){let e=this.containerEl.createDiv("as-dash-section");e.createDiv({cls:"as-dash-title",text:`Burn Rate \u2014 ${t.agent} (${t.period.days}d)`});let s=e.createDiv("as-dash-stats as-dash-stats-sm");if(this.statCard(s,`$${Math.round(t.cost.total).toLocaleString()}`,"total cost","flame"),this.statCard(s,`$${Math.round(t.cost.total/(t.period.days||1)).toLocaleString()}`,"daily avg","trending-up"),this.statCard(s,`${(t.period.sessions||0).toLocaleString()}`,"sessions","terminal"),this.statCard(s,`${((t.period.api_calls||0)/1e3).toFixed(0)}k`,"API calls","zap"),t.by_model&&t.by_model.length>0){let l=e.createDiv("as-model-breakdown");for(let o of t.by_model.slice(0,4)){let c=l.createDiv("as-model-row");c.createSpan({cls:"as-model-name",text:o.model}),c.createSpan({cls:"as-model-calls",text:`${o.apiCalls.toLocaleString()} calls`}),o.costUsd>0&&c.createSpan({cls:"as-model-cost",text:`$${Math.round(o.costUsd).toLocaleString()}`})}}let i=t.by_day.slice(-14);if(i.length===0)return;let a=Math.max(...i.map(l=>l.costUsd),1),r=e.createDiv("as-burn-chart");for(let l of i){let o=r.createDiv("as-burn-col"),c=o.createDiv("as-burn-bar"),d=Math.max(2,l.costUsd/a*100);c.setCssProps({"--bar-h":`${d}%`}),c.title=`${l.date}: $${l.costUsd.toFixed(0)}`,o.createDiv({cls:"as-burn-date",text:l.date.slice(8)})}}renderContext(t,e){let s=(e||this.containerEl).createDiv("as-dash-section");s.createDiv({cls:"as-dash-title",text:"Context Tax"});let i=t.always_loaded.total_tokens,a=[{label:"CLAUDE.md",tokens:t.always_loaded.claude_md_tokens,cls:"as-ctx-claude"},{label:"Skills metadata",tokens:t.always_loaded.skill_metadata_tokens,cls:"as-ctx-skills"},{label:"Memory",tokens:t.always_loaded.memory_tokens,cls:"as-ctx-memory"}],r=s.createDiv("as-ctx-bar");for(let c of a){let d=r.createDiv(`as-ctx-part ${c.cls}`);d.setCssProps({"--bar-w":`${c.tokens/i*100}%`}),d.title=`${c.label}: ${(c.tokens/1e3).toFixed(1)}k tokens`}let l=s.createDiv("as-ctx-legend");for(let c of a){let d=l.createDiv("as-ctx-legend-item");d.createSpan({cls:`as-ctx-dot ${c.cls}`}),d.createSpan({text:`${c.label}: ${(c.tokens/1e3).toFixed(1)}k`})}let o=s.createDiv("as-ctx-costs");o.createDiv({text:`Per session (cached): $${t.session_estimate.with_cache.toFixed(2)}`}),o.createDiv({text:`Without cache: $${t.session_estimate.without_cache.toFixed(2)}`}),o.createDiv({cls:"as-ctx-savings",text:`Cache saves ${t.session_estimate.savings_pct.toFixed(0)}%`})}renderStale(t){if(t.usage.never_used.length===0)return;let e=this.containerEl.createDiv("as-dash-section");e.createDiv({cls:"as-dash-title",text:`Stale skills (${t.usage.unused_30d})`});let s=e.createDiv("as-stale-list");for(let i of t.usage.never_used.slice(0,20))s.createDiv("as-stale-item").createSpan({text:i});t.usage.never_used.length>20&&s.createDiv({cls:"as-stale-more",text:`+${t.usage.never_used.length-20} more`})}};var I=require("obsidian"),Z=require("fs"),ve=require("path"),be=require("os");var T=require("obsidian"),J=require("fs"),fe=require("path"),ge=require("os");var m=require("fs"),f=require("path"),rt=require("os"),de=require("obsidian"),pe=require("crypto");var ce=new Set(["readme.md","license","license.md","changelog.md",".ds_store","thumbs.db"]);function Ue(n){return(0,pe.createHash)("sha256").update(n).digest("hex").slice(0,12)}function Ge(n){let t=n.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);if(!t)return{frontmatter:{},content:n};try{let e=(0,de.parseYaml)(t[1]);return{frontmatter:typeof e=="object"&&e?e:{},content:t[2]}}catch{return{frontmatter:{},content:n}}}function Je(n,t,e,s){if(typeof n.name=="string"&&n.name)return n.name;let i=(0,f.basename)(e,(0,f.extname)(e));if(i==="SKILL")return(0,f.basename)((0,f.join)(e,".."));if(s==="flat-md"||s==="mdc")return i;let a=t.match(/^#\s+(.+)$/m);return a?a[1].trim():i}function Ze(n,t,e){if(!(0,m.existsSync)(n))return[];let s=[];for(let i of(0,m.readdirSync)(n,{withFileTypes:!0})){let a=(0,f.join)(n,i.name);if(!(i.isDirectory()||i.isSymbolicLink()&&(0,m.statSync)(a,{throwIfNoEntry:!1})?.isDirectory()))continue;let l=(0,f.join)(a,"SKILL.md");if(!(0,m.existsSync)(l))continue;let o=Y(l,t,e);o&&s.push(o)}return s}function Ke(n,t,e){if(!(0,m.existsSync)(n))return[];let s=[];for(let i of(0,m.readdirSync)(n,{withFileTypes:!0})){let a=(0,f.join)(n,i.name);if(i.isDirectory()||i.isSymbolicLink()&&(0,m.statSync)(a,{throwIfNoEntry:!1})?.isDirectory()){let c=(0,f.join)(a,"SKILL.md");if((0,m.existsSync)(c)){let u=Y(c,t,e);u&&s.push(u);continue}let d=(0,m.readdirSync)(a).filter(u=>u.endsWith(".md")&&!ce.has(u.toLowerCase())),w=d.find(u=>u.toLowerCase()===`${i.name.toLowerCase()}.md`)||d[0];if(w){let u=Y((0,f.join)(a,w),t,e);u&&s.push(u)}continue}let l=i.name.toLowerCase();if(!l.endsWith(".md")||ce.has(l))continue;let o=Y(a,t,e,"flat-md");o&&s.push(o)}return s}function Qe(n,t,e){if(!(0,m.existsSync)(n))return[];let s=[];for(let i of(0,m.readdirSync)(n,{withFileTypes:!0})){if(!i.name.endsWith(".mdc")&&!i.name.endsWith(".md")||i.isDirectory())continue;let a=Y((0,f.join)(n,i.name),t,e,"mdc");a&&s.push(a)}return s}function Y(n,t,e,s="directory-with-skillmd"){try{let i=(0,m.readFileSync)(n,"utf-8"),a=(0,m.statSync)(n),{frontmatter:r,content:l}=Ge(i),o=Je(r,l,n,s),c=typeof r.description=="string"?r.description:"",d;try{d=(0,m.realpathSync)(n)}catch{d=n}return{id:Ue(d),name:o,description:c,type:t,tools:[e],filePath:n,realPath:d,dirPath:(0,f.join)(n,".."),content:i,frontmatter:r,lastModified:a.mtimeMs,fileSize:a.size,isFavorite:!1,collections:[]}}catch{return null}}function Pt(n,t){switch(n.pattern){case"directory-with-skillmd":return Ze(n.baseDir,n.type,t);case"flat-md":return Ke(n.baseDir,n.type,t);case"mdc":return Qe(n.baseDir,n.type,t)}}function qe(n,t){let e=[],s=[{sub:".claude/skills",type:"skill",pattern:"directory-with-skillmd"},{sub:".claude/commands",type:"command",pattern:"flat-md"},{sub:".claude/agents",type:"agent",pattern:"flat-md"},{sub:".cursor/skills",type:"skill",pattern:"directory-with-skillmd"},{sub:".codex/skills",type:"skill",pattern:"directory-with-skillmd"}];for(let i of s){let a=(0,f.join)(n,i.sub);if(!(0,m.existsSync)(a))continue;let r={baseDir:a,type:i.type,pattern:i.pattern};e.push(...Pt(r,t))}return e}function ue(n){return n.projectsHomeDir||(0,rt.homedir)()}function Ye(n,t){let e=(0,rt.homedir)(),s=[];for(let i of[...t.paths,...t.agentPaths]){let a=(0,f.relative)(e,i.baseDir);if(a.startsWith("..")||a.startsWith("/"))continue;let r=(0,f.join)(n,a);if((0,m.existsSync)(r))try{s.push(...Pt({...i,baseDir:r},t.id))}catch{}}return s}function Xe(n){let t=ue(n);if(!(0,m.existsSync)(t))return[];let e=[];try{let s=new Set(["node_modules",".Trash","Library","Applications","Music","Movies","Pictures","Public"]);for(let i of(0,m.readdirSync)(t,{withFileTypes:!0})){if(!i.isDirectory()&&!i.isSymbolicLink()||s.has(i.name))continue;let a=(0,f.join)(t,i.name);for(let r of x){if(!r.isInstalled())continue;let l=n.tools[r.id];if(l&&!l.enabled)continue;let o=Ye(a,r);o.length>0&&e.push({items:o,toolId:r.id})}}}catch{}return e}function It(n,t){let e=t||(0,rt.homedir)();if(!n.startsWith(e+"/"))return"global";let i=n.slice(e.length+1).split("/");return i.length>1&&!i[0].startsWith(".")?i[0]:"global"}function he(n){let t=new Map,e=new Map;function s(i,a){let r=t.get(i.id);if(r){r.tools.includes(a)||r.tools.push(a);return}let l=e.get(i.name);if(l){let o=t.get(l);o&&!o.tools.includes(a)&&o.tools.push(a);return}i.isFavorite=n.favorites.includes(i.id);for(let[o,c]of Object.entries(n.collections))c.includes(i.id)&&i.collections.push(o);t.set(i.id,i),e.set(i.name,i.id)}for(let i of x){if(!i.isInstalled())continue;let a=n.tools[i.id];if(a&&!a.enabled)continue;let r=[...i.paths,...i.agentPaths];for(let l of r)for(let o of Pt(l,i.id))s(o,i.id)}for(let i of n.customScanPaths)if((0,m.existsSync)(i))for(let a of qe(i,"claude-code"))s(a,"claude-code");if(n.projectScanEnabled)for(let{items:i,toolId:a}of Xe(n))for(let r of i)s(r,a);return t}function Mt(){return x.filter(n=>n.isInstalled()).map(n=>n.id)}function me(n){let t=[];for(let e of x)if(e.isInstalled())for(let s of[...e.paths,...e.agentPaths])(0,m.existsSync)(s.baseDir)&&t.push(s.baseDir);if(n?.projectScanEnabled){let e=ue(n),s=new Set(["node_modules",".Trash","Library","Applications","Music","Movies","Pictures","Public"]);try{for(let i of(0,m.readdirSync)(e,{withFileTypes:!0})){if(!i.isDirectory()&&!i.isSymbolicLink()||s.has(i.name))continue;let a=(0,f.join)(e,i.name);for(let r of[".claude/skills",".claude/commands",".claude/agents",".cursor/skills",".codex/skills"]){let l=(0,f.join)(a,r);(0,m.existsSync)(l)&&t.push(l)}}}catch{}}return t}var At={};for(let[n,t]of Object.entries(it))At[t]||(At[t]=n);var _t=(0,fe.join)((0,ge.homedir)(),".skillkit","install-prefs.json"),z=null,ot=!0;function ts(){if(!z&&(0,J.existsSync)(_t))try{let n=JSON.parse((0,J.readFileSync)(_t,"utf-8"));z=new Set(n.agents||[]),ot=n.global??!0}catch{}}function es(){try{(0,J.writeFileSync)(_t,JSON.stringify({agents:z?[...z]:[],global:ot}),"utf-8")}catch{}}ts();var lt=class extends T.Modal{skill;settings;onInstalled;selectedAgents;isGlobal;constructor(t,e,s,i){if(super(t),this.skill=e,this.settings=s,this.onInstalled=i,z)this.selectedAgents=new Set(z);else{this.selectedAgents=new Set;let a=Mt();for(let r of a){let l=it[r];l&&this.selectedAgents.add(l)}}this.isGlobal=ot}onOpen(){let{contentEl:t}=this;t.addClass("as-install-modal"),t.createEl("h3",{text:`Install ${this.skill.name}`}),t.createEl("p",{cls:"as-install-source",text:this.skill.source}),new T.Setting(t).setName("Install globally").setDesc("Shared across all projects (~/.agents/skills/)").addToggle(o=>o.setValue(this.isGlobal).onChange(c=>{this.isGlobal=c})),new T.Setting(t).setName("Agents").setHeading();let e=t.createDiv("as-install-scroll"),s=Mt(),i=new Set(s.map(o=>it[o]).filter(Boolean));for(let o of ee){let c=i.has(o.id),d=At[o.id],u=new T.Setting(e).addToggle(gt=>gt.setValue(this.selectedAgents.has(o.id)).onChange(xe=>{xe?this.selectedAgents.add(o.id):this.selectedAgents.delete(o.id)})).nameEl,D=d&&E[d]?d:E[o.id]?o.id:E[o.id+"-code"]?o.id+"-code":E[o.id+"-cli"]?o.id+"-cli":null,V=u.createSpan("as-install-agent-icon");D?j(V,D,14):V.addClass("as-install-agent-placeholder"),u.createSpan({text:o.label}),c&&u.createSpan({cls:"as-install-detected",text:"detected"})}let a=t.createDiv("as-install-footer");a.createEl("button",{text:"Cancel"}).addEventListener("click",()=>this.close());let l=a.createEl("button",{cls:"mod-cta",text:"Install"});l.addEventListener("click",()=>this.doInstall(l))}doInstall(t){let e=[...this.selectedAgents];if(e.length===0){new T.Notice("Select at least one agent",5e3);return}z=new Set(this.selectedAgents),ot=this.isGlobal,es(),this.close(),new T.Notice(`Installing ${this.skill.name}...`,3e3),ie(this.skill.source,e,{runner:this.settings.packageRunner,global:this.isGlobal}).then(s=>{s.success?(new T.Notice(`Installed ${this.skill.name}`,5e3),this.skill.installed=!0,this.onInstalled()):new T.Notice(`Failed to install ${this.skill.name}`,5e3)})}onClose(){this.contentEl.empty()}};var $t=(0,ve.join)((0,be.homedir)(),".skillkit","marketplace-popular.json"),P=null,ct="",B=null,ss=new I.Component;function is(){if(!P&&(0,Z.existsSync)($t))try{let n=JSON.parse((0,Z.readFileSync)($t,"utf-8"));P=nt(n)}catch{}}function ns(){if(P)try{(0,Z.writeFileSync)($t,JSON.stringify(P),"utf-8")}catch{}}is();var dt=class{containerEl;inputEl=null;listEl=null;previewEl=null;searchTimer=null;selectedSkill=null;app;settings;onRefresh;constructor(t,e,s,i){this.containerEl=t,this.app=e.app,this.settings=s,this.onRefresh=i}render(){if(!this.inputEl){this.containerEl.empty(),this.containerEl.addClass("as-marketplace");let t=this.containerEl.createDiv("as-mp-search");this.inputEl=t.createEl("input",{type:"text",placeholder:"Search skills on skills.sh...",cls:"as-mp-search-input"}),this.inputEl.addEventListener("input",()=>{this.searchTimer&&clearTimeout(this.searchTimer),this.searchTimer=setTimeout(()=>{this.doSearch(this.inputEl.value)},300)});let e=this.containerEl.createDiv("as-mp-body");this.listEl=e.createDiv("as-mp-list"),this.previewEl=e.createDiv("as-mp-preview"),this.previewEl.createDiv({cls:"as-mp-hint",text:"Select a skill to preview."})}this.inputEl.value=ct,ct.length>=2&&B?this.showResults(B):P?this.showPopular():this.loadPopular()}async loadPopular(){if(!this.listEl)return;this.listEl.empty(),this.listEl.createDiv({cls:"as-mp-loading",text:"Loading popular skills..."}),P=await te(),ns(),this.showPopular()}refreshList(){P&&nt(P),B&&nt(B),ct.length>=2&&B?this.showResults(B):this.showPopular()}showPopular(){if(this.listEl){if(this.listEl.empty(),!P||P.length===0){this.listEl.createDiv({cls:"as-mp-hint",text:"Search for skills to browse and install."});return}this.listEl.createDiv({cls:"as-mp-section-title",text:"Popular"});for(let t of P)this.renderSkillCard(t)}}showResults(t){if(this.listEl){if(this.listEl.empty(),t.length===0){this.listEl.createDiv({cls:"as-mp-hint",text:"No skills found."});return}for(let e of t)this.renderSkillCard(e)}}async doSearch(t){if(!this.listEl)return;if(ct=t,t.length<2){B=null,this.showPopular();return}this.listEl.empty(),this.listEl.createDiv({cls:"as-mp-loading",text:"Searching..."});let e=await Dt(t);B=e,this.showResults(e)}renderSkillCard(t){if(!this.listEl)return;let e=this.listEl.createDiv("as-mp-card");this.selectedSkill?.id===t.id&&e.addClass("is-selected");let s=e.createDiv("as-mp-card-header");s.createSpan({cls:"as-mp-card-name",text:t.name}),t.installed&&s.createSpan({cls:"as-mp-installed-badge",text:"Installed"}),e.createDiv({cls:"as-mp-card-source",text:t.source});let i=e.createDiv("as-mp-card-meta"),a=i.createSpan("as-mp-dl-icon");(0,I.setIcon)(a,"download"),i.createSpan({cls:"as-mp-card-installs",text:Lt(t.installs)}),e.addEventListener("click",()=>{this.selectedSkill=t,this.listEl&&this.listEl.querySelectorAll(".as-mp-card").forEach(r=>r.removeClass("is-selected")),e.addClass("is-selected"),this.showPreview(t)})}async showPreview(t){if(!this.previewEl)return;this.previewEl.empty();let s=this.previewEl.createDiv("as-mp-preview-header").createDiv("as-mp-preview-top"),i=s.createDiv("as-mp-preview-left");i.createDiv({cls:"as-mp-preview-name",text:t.name});let a=i.createDiv("as-mp-preview-meta");a.createSpan({cls:"as-mp-preview-source",text:t.source});let r=a.createSpan("as-mp-dl-icon");(0,I.setIcon)(r,"download"),a.createSpan({cls:"as-mp-preview-installs",text:Lt(t.installs)});let l=s.createDiv("as-mp-preview-right");if(!t.installed)this.renderInstallButton(l,t);else{l.createSpan({cls:"as-mp-installed-label",text:"Installed"});let d=l.createEl("button",{cls:"as-mp-uninstall-btn",text:"Uninstall"});d.addEventListener("click",()=>{N(this.app,"Uninstall skill",`Remove "${t.name}" from all agents?`,()=>{d.setText("Removing..."),d.disabled=!0,new I.Notice(`Removing ${t.name}...`,3e3),ne(t.name,this.settings.packageRunner).then(w=>{w.success?(new I.Notice(`Removed ${t.name}`,5e3),t.installed=!1,this.refreshList(),this.showPreview(t)):(new I.Notice(`Failed to remove ${t.name}`,5e3),d.setText("Uninstall"),d.disabled=!1)})})})}let o=this.previewEl.createDiv("as-mp-preview-content");o.createDiv({cls:"as-mp-loading",text:"Loading skill content..."});let c=await Xt(t.source,t.name,t.id);if(o.empty(),c){t.content=c;let d=o.createDiv("as-mp-rendered markdown-rendered");I.MarkdownRenderer.render(this.app,c,d,"",ss)}else o.createDiv({cls:"as-mp-hint",text:"Could not load skill content."})}renderInstallButton(t,e){t.createEl("button",{cls:"as-mp-install-btn",text:"Install"}).addEventListener("click",()=>{new lt(this.app,e,this.settings,()=>{this.refreshList(),this.showPreview(e)}).open()})}};var X="agentfiles-view",pt=class extends ke.ItemView{store;settings;saveSettings;sidebarPanel;listPanel;detailPanel;dashboardPanel;marketplacePanel;sidebarEl;listEl;detailEl;dashboardEl;marketplaceEl;isDashboard=!1;isMarketplace=!1;updateRef=null;constructor(t,e,s,i){super(t),this.store=e,this.settings=s,this.saveSettings=i}getViewType(){return X}getDisplayText(){return"Agentfiles"}getIcon(){return"cpu"}onOpen(){let t=this.contentEl;t.empty(),t.addClass("as-container"),this.sidebarEl=t.createDiv("as-panel as-panel-sidebar"),this.listEl=t.createDiv("as-panel as-panel-list"),this.detailEl=t.createDiv("as-panel as-panel-detail"),this.dashboardEl=t.createDiv("as-panel as-panel-dashboard as-hidden"),this.marketplaceEl=t.createDiv("as-panel as-panel-marketplace as-hidden"),this.sidebarPanel=new tt(this.sidebarEl,this.store,()=>this.toggleDashboard(),()=>this.toggleMarketplace()),this.listPanel=new et(this.listEl,this.store,e=>this.onSelectItem(e)),this.detailPanel=new st(this.detailEl,this.store,this.settings,this.saveSettings,this),this.dashboardPanel=new at(this.dashboardEl,this.app),this.marketplacePanel=new dt(this.marketplaceEl,this,this.settings,()=>{this.store.refresh(this.settings)}),this.updateRef=this.store.on("updated",()=>this.renderAll()),this.renderAll()}toggleDashboard(){this.isDashboard=!this.isDashboard,this.isMarketplace&&(this.isMarketplace=!1,this.marketplaceEl.addClass("as-hidden")),this.isDashboard?(this.listEl.addClass("as-hidden"),this.detailEl.addClass("as-hidden"),this.dashboardEl.removeClass("as-hidden"),this.dashboardPanel.render()):(this.listEl.removeClass("as-hidden"),this.detailEl.removeClass("as-hidden"),this.dashboardEl.addClass("as-hidden")),this.sidebarPanel.setDashboardActive(this.isDashboard),this.sidebarPanel.render()}toggleMarketplace(){this.isMarketplace=!this.isMarketplace,this.isDashboard&&(this.isDashboard=!1,this.dashboardEl.addClass("as-hidden")),this.isMarketplace?(this.listEl.addClass("as-hidden"),this.detailEl.addClass("as-hidden"),this.marketplaceEl.removeClass("as-hidden"),this.marketplacePanel.render()):(this.listEl.removeClass("as-hidden"),this.detailEl.removeClass("as-hidden"),this.marketplaceEl.addClass("as-hidden")),this.sidebarPanel.setMarketplaceActive(this.isMarketplace),this.sidebarPanel.render()}renderAll(){this.sidebarPanel.render(),!this.isDashboard&&!this.isMarketplace&&(this.listPanel.render(),this.store.filteredItems.length||this.detailPanel.clear())}onSelectItem(t){this.isDashboard&&this.toggleDashboard(),this.isMarketplace&&this.toggleMarketplace(),this.listPanel.setSelected(t.id),this.listPanel.render(),this.detailPanel.show(t)}onClose(){this.updateRef&&this.store.offref(this.updateRef)}};var Se=require("obsidian");var ut=class extends Se.Events{items=new Map;_filter={kind:"all"};_searchQuery="";_projectsHomeDir="";get filter(){return this._filter}get searchQuery(){return this._searchQuery}get allItems(){return Array.from(this.items.values())}get filteredItems(){let t=this.allItems;switch(this._filter.kind){case"favorites":t=t.filter(e=>e.isFavorite);break;case"tool":t=t.filter(e=>e.tools.includes(this._filter.toolId));break;case"type":t=t.filter(e=>e.type===this._filter.type);break;case"collection":t=t.filter(e=>e.collections.includes(this._filter.name));break;case"project":t=t.filter(e=>It(e.filePath,this._projectsHomeDir)===this._filter.project);break}if(this._searchQuery){let e=this._searchQuery.toLowerCase();t=t.filter(s=>s.name.toLowerCase().includes(e))}return t.sort((e,s)=>e.name.localeCompare(s.name))}getItem(t){return this.items.get(t)}get hasSkillkit(){return C()}refresh(t){this._projectsHomeDir=t.projectsHomeDir,this.items=he(t),this.enrichWithSkillkit(),this.trigger("updated")}enrichWithSkillkit(){if(!C())return;let t=Bt(),e=Nt(),s=Vt(),i=new Set(s.oversized.map(o=>o.name)),a=new Set(s.longDesc.map(o=>o.name)),r=new Map(s.oversized.map(o=>[o.name,o.lines])),l=new Map(s.longDesc.map(o=>[o.name,o.chars]));for(let o of this.items.values()){let c=o.filePath.split("/").slice(-2,-1)[0],d=o.name.toLowerCase().replace(/\s+/g,"-"),w=t.get(o.name)||t.get(c)||t.get(d);w?(w.isHeavy=o.content.length>5e3,o.usage=w):o.usage={uses:0,lastUsed:null,daysSinceUsed:null,isStale:!0,isHeavy:o.content.length>5e3};let u=o.content.split(` -`).length,D=o.description.length;o.warnings={oversized:i.has(o.name)||u>500,longDesc:a.has(o.name)||D>1024,lineCount:r.get(o.name)??u,descChars:l.get(o.name)??D},o.conflicts=e.get(o.name)||e.get(c)||[]}}setFilter(t){this._filter=t,this.trigger("updated")}setSearch(t){this._searchQuery=t,this.trigger("updated")}toggleFavorite(t,e){let s=this.items.get(t);s&&(s.isFavorite=!s.isFavorite,s.isFavorite?e.favorites.includes(t)||e.favorites.push(t):e.favorites=e.favorites.filter(i=>i!==t),this.trigger("updated"))}getToolCounts(){let t=new Map;for(let e of this.items.values())for(let s of e.tools)t.set(s,(t.get(s)||0)+1);return t}getTypeCounts(){let t=new Map;for(let e of this.items.values())t.set(e.type,(t.get(e.type)||0)+1);return t}getProjectCounts(){let t=new Map;for(let e of this.items.values()){let s=It(e.filePath,this._projectsHomeDir);t.set(s,(t.get(s)||0)+1)}return t}};var ye=require("fs"),ht=class{watchers=[];debounceTimer=null;debounceMs;onChange;constructor(t,e){this.debounceMs=t,this.onChange=e}watchPaths(t){this.close();for(let e of t)try{let s=(0,ye.watch)(e,{recursive:!0},()=>this.scheduleUpdate());this.watchers.push(s)}catch{}}scheduleUpdate(){this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.onChange()},this.debounceMs)}close(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null);for(let t of this.watchers)try{t.close()}catch{}this.watchers=[]}};var L=require("obsidian");var mt=class extends L.PluginSettingTab{plugin;constructor(t,e){super(t,e),this.plugin=e}display(){let{containerEl:t}=this;t.empty(),new L.Setting(t).setName("File watching").setDesc("Automatically detect changes to skill files").addToggle(e=>e.setValue(this.plugin.settings.watchEnabled).onChange(async s=>{this.plugin.settings.watchEnabled=s,await this.plugin.saveSettings(),this.plugin.restartWatcher()})),new L.Setting(t).setName("Watch debounce (ms)").setDesc("Delay before re-scanning after file changes").addText(e=>e.setValue(String(this.plugin.settings.watchDebounceMs)).onChange(async s=>{let i=parseInt(s);!isNaN(i)&&i>=100&&(this.plugin.settings.watchDebounceMs=i,await this.plugin.saveSettings())})),new L.Setting(t).setName("Marketplace").setHeading(),new L.Setting(t).setName("Package runner").setDesc("Command used to install skills from the marketplace").addDropdown(e=>e.addOptions({auto:"Auto-detect",npx:"npx",bunx:"bunx"}).setValue(this.plugin.settings.packageRunner).onChange(async s=>{this.plugin.settings.packageRunner=s,await this.plugin.saveSettings()})),new L.Setting(t).setName("Project scanning").setHeading(),new L.Setting(t).setName("Scan projects").setDesc("Scan all directories under the projects home folder for project-level skills").addToggle(e=>e.setValue(this.plugin.settings.projectScanEnabled).onChange(async s=>{this.plugin.settings.projectScanEnabled=s,await this.plugin.saveSettings(),this.plugin.refreshStore(),this.plugin.restartWatcher()})),new L.Setting(t).setName("Projects home directory").setDesc("Root directory to scan for project-level skills. Leave empty for home directory (~).").addText(e=>e.setPlaceholder("~").setValue(this.plugin.settings.projectsHomeDir).onChange(async s=>{this.plugin.settings.projectsHomeDir=s,await this.plugin.saveSettings(),this.plugin.refreshStore(),this.plugin.restartWatcher()})),new L.Setting(t).setName("Tools").setHeading();for(let e of x){let s=e.isInstalled(),i=this.plugin.settings.tools[e.id]||{enabled:!0,customPaths:[]};new L.Setting(t).setName(e.name).setDesc(s?"Installed":"Not detected").addToggle(a=>a.setValue(s&&i.enabled).setDisabled(!s).onChange(async r=>{this.plugin.settings.tools[e.id]={...i,enabled:r},await this.plugin.saveSettings(),this.plugin.refreshStore()}))}}};var Ht={tools:{},watchEnabled:!0,watchDebounceMs:500,favorites:[],collections:{},customScanPaths:[],projectScanEnabled:!0,projectsHomeDir:"",packageRunner:"auto"};var ft=class extends we.Plugin{settings=Ht;store=new ut;watcher=null;async onload(){await this.loadSettings(),this.addVaultPath(),this.registerView(X,t=>new pt(t,this.store,this.settings,()=>this.saveSettings())),this.addRibbonIcon("cpu","Agentfiles",()=>this.activateView()),this.addCommand({id:"open",name:"Open",callback:()=>this.activateView()}),this.addSettingTab(new mt(this.app,this)),this.refreshStore(),this.startWatcher()}addVaultPath(){let t=this.app.vault.adapter;if(!t.getBasePath)return;let e=t.getBasePath();this.settings.customScanPaths.includes(e)||this.settings.customScanPaths.push(e)}onunload(){this.stopWatcher()}refreshStore(){this.store.refresh(this.settings)}startWatcher(){this.settings.watchEnabled&&(this.watcher=new ht(this.settings.watchDebounceMs,()=>this.refreshStore()),this.watcher.watchPaths(me(this.settings)))}stopWatcher(){this.watcher&&(this.watcher.close(),this.watcher=null)}restartWatcher(){this.stopWatcher(),this.startWatcher()}async activateView(){let t=this.app.workspace.getLeavesOfType(X);if(t.length>0){await this.app.workspace.revealLeaf(t[0]);return}let e=this.app.workspace.getLeaf("tab");await e.setViewState({type:X,active:!0}),await this.app.workspace.revealLeaf(e)}async loadSettings(){this.settings=Object.assign({},Ht,await this.loadData())}async saveSettings(){await this.saveData(this.settings)}}; +var vt=Object.defineProperty;var De=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var Ce=Object.prototype.hasOwnProperty;var Le=(n,t)=>{for(var e in t)vt(n,e,{get:t[e],enumerable:!0})},Te=(n,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Ee(t))!Ce.call(n,i)&&i!==e&&vt(n,i,{get:()=>t[i],enumerable:!(s=De(t,i))||s.enumerable});return n};var Pe=n=>Te(vt({},"__esModule",{value:!0}),n);var as={};Le(as,{default:()=>gt});module.exports=Pe(as);var we=require("obsidian");var ke=require("obsidian");var O=require("obsidian"),jt=require("electron");var Ft=require("os"),v=require("fs"),p=require("path"),u=(0,Ft.homedir)(),W=process.env.XDG_CONFIG_HOME||(0,p.join)(u,".config");function K(n){return(0,v.existsSync)(`/Applications/${n}.app`)||(0,v.existsSync)((0,p.join)(u,"Applications",`${n}.app`))}function F(n){let t=[`/usr/local/bin/${n}`,`/opt/homebrew/bin/${n}`,(0,p.join)(u,".local","bin",n)];for(let s of t)if((0,v.existsSync)(s))return!0;let e=(0,p.join)(u,".nvm","versions","node");try{for(let s of(0,v.readdirSync)(e))if((0,v.existsSync)((0,p.join)(e,s,"bin",n)))return!0}catch{}return!1}var D=[{id:"claude-code",name:"Claude Code",color:"#f97316",icon:"brain",paths:[{baseDir:(0,p.join)(u,".claude","skills"),type:"skill",pattern:"directory-with-skillmd"},{baseDir:(0,p.join)(u,".claude","commands"),type:"command",pattern:"flat-md"}],agentPaths:[{baseDir:(0,p.join)(u,".claude","agents"),type:"agent",pattern:"flat-md"}],isInstalled:()=>(0,v.existsSync)((0,p.join)(u,".claude","settings.json"))||(0,v.existsSync)((0,p.join)(u,".claude","CLAUDE.md"))||F("claude")},{id:"cursor",name:"Cursor",color:"#3b82f6",icon:"mouse-pointer",paths:[{baseDir:(0,p.join)(u,".cursor","skills"),type:"skill",pattern:"directory-with-skillmd"},{baseDir:(0,p.join)(u,".cursor","rules"),type:"rule",pattern:"flat-md"}],agentPaths:[{baseDir:(0,p.join)(u,".cursor","agents"),type:"agent",pattern:"flat-md"}],isInstalled:()=>K("Cursor")||(0,v.existsSync)((0,p.join)(u,".cursor","argv.json"))},{id:"windsurf",name:"Windsurf",color:"#14b8a6",icon:"wind",paths:[{baseDir:(0,p.join)(u,".codeium","windsurf","memories"),type:"memory",pattern:"flat-md"},{baseDir:(0,p.join)(u,".windsurf","rules"),type:"rule",pattern:"flat-md"}],agentPaths:[],isInstalled:()=>K("Windsurf")||(0,v.existsSync)((0,p.join)(u,".codeium","windsurf","argv.json"))},{id:"codex",name:"Codex",color:"#22c55e",icon:"book",paths:[{baseDir:(0,p.join)(u,".codex","skills"),type:"skill",pattern:"directory-with-skillmd"},{baseDir:(0,p.join)(u,".codex","prompts"),type:"command",pattern:"flat-md"},{baseDir:(0,p.join)(u,".codex","memories"),type:"memory",pattern:"flat-md"}],agentPaths:[{baseDir:(0,p.join)(u,".codex","agents"),type:"agent",pattern:"flat-md"}],isInstalled:()=>(0,v.existsSync)((0,p.join)(u,".codex","config.toml"))||(0,v.existsSync)((0,p.join)(u,".codex","auth.json"))||F("codex")},{id:"copilot",name:"Copilot",color:"#a855f7",icon:"plane",paths:[{baseDir:(0,p.join)(u,".copilot","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>(0,v.existsSync)((0,p.join)(u,".copilot"))||F("copilot")},{id:"amp",name:"Amp",color:"#ec4899",icon:"zap",paths:[{baseDir:(0,p.join)(W,"amp","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>(0,v.existsSync)((0,p.join)(W,"amp","config.json"))||(0,v.existsSync)((0,p.join)(W,"amp","settings.json"))||F("amp")},{id:"opencode",name:"OpenCode",color:"#ef4444",icon:"terminal",paths:[{baseDir:(0,p.join)(W,"opencode","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>K("OpenCode")||(0,v.existsSync)((0,p.join)(W,"opencode","opencode.json"))||(0,v.existsSync)((0,p.join)(W,"opencode","opencode.jsonc"))||F("opencode")},{id:"pi",name:"Pi",color:"#06b6d4",icon:"sparkles",paths:[{baseDir:(0,p.join)(u,".pi","agent","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>F("pi")},{id:"antigravity",name:"Antigravity",color:"#ef4444",icon:"arrow-up-circle",paths:[{baseDir:(0,p.join)(u,".gemini","antigravity","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>K("Antigravity")||(0,v.existsSync)((0,p.join)(u,".gemini","antigravity","skills"))||F("antigravity")},{id:"claude-desktop",name:"Claude Desktop",color:"#f97316",icon:"monitor",paths:[],agentPaths:[],isInstalled:()=>K("Claude")},{id:"global-agents",name:"Global",color:"#a3e635",icon:"globe",paths:[{baseDir:(0,p.join)(u,".agents","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>(0,v.existsSync)((0,p.join)(u,".agents","skills"))},{id:"aider",name:"Aider",color:"#eab308",icon:"wrench",paths:[],agentPaths:[],isInstalled:()=>F("aider")}];var C={"claude-code":{viewBox:"0 0 24 24",paths:''},cursor:{viewBox:"0 0 466.73 532.09",paths:''},windsurf:{viewBox:"0 0 24 24",paths:''},codex:{viewBox:"0 0 24 24",paths:''},copilot:{viewBox:"0 0 24 24",paths:''},opencode:{viewBox:"0 0 24 36",paths:''},"claude-desktop":{viewBox:"0 0 24 24",paths:''},"global-agents":{viewBox:"0 0 24 24",paths:''},goose:{viewBox:"0 0 24 24",paths:''},cline:{viewBox:"0 0 24 24",paths:''},continue:{viewBox:"0 0 26 24",paths:''},"roo-code":{viewBox:"0 0 96 96",paths:''},replit:{viewBox:"0 0 24 24",paths:''},"gemini-cli":{viewBox:"0 0 24 24",paths:''}};function j(n,t,e=16){let s=C[t];if(!s)return;let i=document.createElementNS("http://www.w3.org/2000/svg","svg");i.setAttribute("viewBox",s.viewBox),i.setAttribute("width",String(e)),i.setAttribute("height",String(e)),i.setAttribute("fill","none"),i.classList.add("as-tool-svg"),i.innerHTML=s.paths,n.appendChild(i)}var tt=class{containerEl;store;onToggleDashboard;onToggleMarketplace;dashboardActive=!1;marketplaceActive=!1;constructor(t,e,s,i){this.containerEl=t,this.store=e,this.onToggleDashboard=s,this.onToggleMarketplace=i}setDashboardActive(t){this.dashboardActive=t,t&&(this.marketplaceActive=!1)}setMarketplaceActive(t){this.marketplaceActive=t,t&&(this.dashboardActive=!1)}render(){this.containerEl.empty(),this.containerEl.addClass("as-sidebar"),this.renderLibrarySection(),this.renderTypeSection(),this.renderToolSection(),this.renderProjectSection(),this.renderCollectionSection(),this.store.hasSkillkit||this.renderSkillkitCta()}renderSection(t,e){let s=this.containerEl.createDiv("as-sidebar-section");s.createDiv({cls:"as-sidebar-title",text:t});for(let i of e){let a=s.createDiv("as-sidebar-item");!this.dashboardActive&&this.isActive(i.filter)&&a.addClass("is-active");let r=a.createSpan("as-sidebar-icon");(0,O.setIcon)(r,i.icon),a.createSpan({cls:"as-sidebar-label",text:i.label}),i.count!==void 0&&a.createSpan({cls:"as-sidebar-count",text:String(i.count)}),a.addEventListener("click",()=>{this.dashboardActive&&this.onToggleDashboard(),this.marketplaceActive&&this.onToggleMarketplace(),this.store.setFilter(i.filter)})}}renderTypeSection(){let t=this.store.getTypeCounts(),s=[{label:"Skills",icon:"sparkles",type:"skill"},{label:"Commands",icon:"terminal",type:"command"},{label:"Agents",icon:"bot",type:"agent"},{label:"Rules",icon:"scroll",type:"rule"}].filter(i=>t.has(i.type)).map(i=>({label:i.label,icon:i.icon,filter:{kind:"type",type:i.type},count:t.get(i.type)||0}));s.length>0&&this.renderSection("Types",s)}renderToolSection(){let t=this.store.getToolCounts(),e=D.filter(i=>i.isInstalled()&&t.has(i.id));if(e.length===0)return;let s=this.containerEl.createDiv("as-sidebar-section");s.createDiv({cls:"as-sidebar-title",text:"Tools"});for(let i of e){let a={kind:"tool",toolId:i.id},r=s.createDiv("as-sidebar-item");!this.dashboardActive&&this.isActive(a)&&r.addClass("is-active");let l=r.createSpan("as-sidebar-icon");C[i.id]?j(l,i.id,14):(0,O.setIcon)(l,i.icon),r.createSpan({cls:"as-sidebar-label",text:i.name}),r.createSpan({cls:"as-sidebar-count",text:String(t.get(i.id)||0)}),r.addEventListener("click",()=>{this.dashboardActive&&this.onToggleDashboard(),this.store.setFilter(a)})}}renderProjectSection(){let t=this.store.getProjectCounts();if(t.size===0)return;let e=[];for(let[s,i]of t)e.push({label:s,icon:"folder-git-2",filter:{kind:"project",project:s},count:i});e.sort((s,i)=>s.label.localeCompare(i.label)),this.renderSection("Projects",e)}renderCollectionSection(){let t=this.containerEl.createDiv("as-sidebar-section");t.createDiv({cls:"as-sidebar-title",text:"Collections"});let e=new Set;for(let s of this.store.allItems)for(let i of s.collections)e.add(i);if(e.size===0){t.createDiv({cls:"as-sidebar-empty",text:"No collections yet"});return}for(let s of e){let i={kind:"collection",name:s},a=t.createDiv("as-sidebar-item");!this.dashboardActive&&this.isActive(i)&&a.addClass("is-active");let r=a.createSpan("as-sidebar-icon");(0,O.setIcon)(r,"folder"),a.createSpan({cls:"as-sidebar-label",text:s}),a.addEventListener("click",()=>{this.dashboardActive&&this.onToggleDashboard(),this.store.setFilter(i)})}}renderLibrarySection(){let t=this.containerEl.createDiv("as-sidebar-section");t.createDiv({cls:"as-sidebar-title",text:"Library"});let e=[{label:"All Skills",icon:"layers",filter:{kind:"all"}},{label:"Favorites",icon:"star",filter:{kind:"favorites"}}],s=this.dashboardActive||this.marketplaceActive;for(let o of e){let c=t.createDiv("as-sidebar-item");!s&&this.isActive(o.filter)&&c.addClass("is-active");let d=c.createSpan("as-sidebar-icon");(0,O.setIcon)(d,o.icon),c.createSpan({cls:"as-sidebar-label",text:o.label}),c.addEventListener("click",()=>{this.dashboardActive&&this.onToggleDashboard(),this.marketplaceActive&&this.onToggleMarketplace(),this.store.setFilter(o.filter)})}let i=t.createDiv("as-sidebar-item");this.dashboardActive&&i.addClass("is-active");let a=i.createSpan("as-sidebar-icon");(0,O.setIcon)(a,"bar-chart-2"),i.createSpan({cls:"as-sidebar-label",text:"Dashboard"}),i.addEventListener("click",()=>{this.marketplaceActive&&this.onToggleMarketplace(),this.dashboardActive||this.onToggleDashboard()});let r=t.createDiv("as-sidebar-item");this.marketplaceActive&&r.addClass("is-active");let l=r.createSpan("as-sidebar-icon");(0,O.setIcon)(l,"shopping-bag"),r.createSpan({cls:"as-sidebar-label",text:"Marketplace"}),r.addEventListener("click",()=>{this.dashboardActive&&this.onToggleDashboard(),this.marketplaceActive||this.onToggleMarketplace()})}renderSkillkitCta(){let t=this.containerEl.createDiv("as-skillkit-cta"),e=t.createDiv("as-skillkit-icon");(0,O.setIcon)(e,"bar-chart-2"),t.createDiv({cls:"as-skillkit-title",text:"Unlock analytics"}),t.createDiv({cls:"as-skillkit-desc",text:"Install skillkit to see usage stats, stale badges, and heavy skill warnings."}),t.createDiv("as-skillkit-cmd").createEl("code",{text:"npm i -g skillkit"}),t.createEl("a",{cls:"as-skillkit-link",text:"Learn more",href:"https://www.npmjs.com/package/skillkit"}).addEventListener("click",a=>{a.preventDefault(),jt.shell.openExternal("https://www.npmjs.com/package/skillkit")})}isActive(t){let e=this.store.filter;return e.kind!==t.kind?!1:e.kind==="tool"&&t.kind==="tool"?e.toolId===t.toolId:e.kind==="type"&&t.kind==="type"?e.type===t.type:e.kind==="collection"&&t.kind==="collection"?e.name===t.name:e.kind==="project"&&t.kind==="project"?e.project===t.project:!0}};var Q=require("obsidian");var et=class{containerEl;store;onSelect;selectedId=null;inputEl=null;listEl=null;typeFilter=null;sortBy="name";dropdownEl=null;constructor(t,e,s){this.containerEl=t,this.store=e,this.onSelect=s}setSelected(t){this.selectedId=t}render(){if(!this.inputEl){this.containerEl.empty(),this.containerEl.addClass("as-list");let t=this.containerEl.createDiv("as-search");this.inputEl=t.createEl("input",{type:"text",placeholder:"Search skills...",cls:"as-search-input"}),this.inputEl.addEventListener("input",()=>{this.store.setSearch(this.inputEl.value)});let e=t.createDiv("as-filter-btn");(0,Q.setIcon)(e,"filter"),e.setAttribute("aria-label","Filter by status"),e.addEventListener("click",i=>{i.stopPropagation(),this.toggleDropdown(e)});let s=t.createDiv("as-filter-btn");(0,Q.setIcon)(s,this.sortBy==="usage"?"arrow-down-wide-narrow":"arrow-down-a-z"),s.setAttribute("aria-label",this.sortBy==="usage"?"Sorted by usage":"Sorted by name"),s.addEventListener("click",()=>{this.sortBy=this.sortBy==="name"?"usage":"name",(0,Q.setIcon)(s,this.sortBy==="usage"?"arrow-down-wide-narrow":"arrow-down-a-z"),s.setAttribute("aria-label",this.sortBy==="usage"?"Sorted by usage":"Sorted by name"),this.renderList()}),this.listEl=this.containerEl.createDiv("as-list-items")}this.inputEl.value=this.store.searchQuery,this.renderList()}toggleDropdown(t){if(this.dropdownEl){this.dropdownEl.remove(),this.dropdownEl=null;return}this.dropdownEl=t.createDiv("as-filter-dropdown");let e=[{id:"all",label:"All",cls:""},{id:"stale",label:"Stale",cls:"as-badge-stale"},{id:"heavy",label:"Heavy",cls:"as-badge-heavy"},{id:"oversized",label:"Oversized",cls:"as-badge-warn"},{id:"conflict",label:"Conflict",cls:"as-badge-conflict"}];for(let i of e){let a=this.dropdownEl.createDiv("as-filter-option");(i.id==="all"&&!this.typeFilter||i.id===this.typeFilter)&&a.addClass("is-active"),i.cls?a.createSpan({cls:i.cls,text:i.label}):a.setText(i.label),a.addEventListener("click",r=>{r.stopPropagation(),this.typeFilter=i.id==="all"?null:i.id,this.dropdownEl&&(this.dropdownEl.remove(),this.dropdownEl=null),this.renderList()})}let s=()=>{this.dropdownEl&&(this.dropdownEl.remove(),this.dropdownEl=null),document.removeEventListener("click",s)};setTimeout(()=>document.addEventListener("click",s),0)}renderList(){if(!this.listEl)return;this.listEl.empty();let t=this.store.filteredItems;if(this.typeFilter)switch(this.typeFilter){case"stale":t=t.filter(e=>e.usage?.isStale);break;case"heavy":t=t.filter(e=>e.usage?.isHeavy);break;case"oversized":t=t.filter(e=>e.warnings?.oversized);break;case"conflict":t=t.filter(e=>e.conflicts&&e.conflicts.length>0);break}if(this.sortBy==="usage"&&(t=[...t].sort((e,s)=>(s.usage?.uses??0)-(e.usage?.uses??0))),this.typeFilter){let e={stale:"Stale",heavy:"Heavy",oversized:"Oversized",conflict:"Conflict"},s=this.listEl.createDiv("as-active-filter");s.createSpan({text:`Showing: ${e[this.typeFilter]??this.typeFilter}`}),s.createSpan({cls:"as-filter-clear",text:"Clear"}).addEventListener("click",()=>{this.typeFilter=null,this.renderList()})}if(t.length===0){this.listEl.createDiv({cls:"as-list-empty",text:"No skills found"});return}for(let e of t)this.renderCard(this.listEl,e)}renderCard(t,e){let s=t.createDiv("as-skill-card");e.id===this.selectedId&&s.addClass("is-selected");let i=s.createDiv("as-skill-header");if(i.createSpan({cls:"as-skill-name",text:e.name}),e.isFavorite){let r=i.createSpan("as-skill-star");(0,Q.setIcon)(r,"star")}e.description&&s.createDiv({cls:"as-skill-desc",text:e.description.length>80?e.description.slice(0,80)+"...":e.description});let a=s.createDiv("as-skill-meta");a.createSpan({cls:`as-type-tag as-type-${e.type}`,text:e.type});for(let r of e.tools){let l=D.find(c=>c.id===r);if(!l)continue;let o=a.createSpan("as-tool-badge");o.title=l.name,o.setAttribute("aria-label",l.name),o.setCssProps({"--tool-color":l.color}),C[r]?j(o,r,12):o.addClass("as-tool-badge-dot")}e.usage&&(e.usage.uses>0&&a.createSpan({cls:"as-usage-badge",text:`${e.usage.uses}`,attr:{"aria-label":`Used ${e.usage.uses} times`}}),e.usage.isStale&&a.createSpan({cls:"as-badge-stale",text:"stale"}),e.usage.isHeavy&&a.createSpan({cls:"as-badge-heavy",text:"heavy"})),e.warnings?.oversized&&a.createSpan({cls:"as-badge-warn",text:"oversized"}),e.conflicts&&e.conflicts.length>0&&a.createSpan({cls:"as-badge-conflict",text:"conflict"}),s.addEventListener("click",()=>{this.selectedId=e.id,this.onSelect(e)})}};var y=require("obsidian"),Jt=require("fs"),Zt=require("electron");var kt=require("child_process"),A=require("fs"),k=require("path"),Ot=require("os"),I=(0,Ot.homedir)(),Me=(0,k.join)(I,".skillkit","analytics.db");function Rt(){let n=["/usr/local/bin","/opt/homebrew/bin",(0,k.join)(I,".local","bin"),(0,k.join)(I,".bun","bin")],t=(0,k.join)(I,".nvm","versions","node");try{for(let s of(0,A.readdirSync)(t))n.push((0,k.join)(t,s,"bin"))}catch{}let e=(0,k.join)(I,".local","share","mise","installs");for(let s of["node","bun"])try{for(let i of(0,A.readdirSync)((0,k.join)(e,s)))n.push((0,k.join)(e,s,i,"bin"))}catch{}return[...n,process.env.PATH||""].join(":")}function Ie(){let n=["/usr/local/bin/skillkit","/opt/homebrew/bin/skillkit",(0,k.join)(I,".local","bin","skillkit"),(0,k.join)(I,".bun","bin","skillkit"),(0,k.join)(I,".local","share","mise","shims","skillkit")];for(let s of n)if((0,A.existsSync)(s))return s;let t=(0,k.join)(I,".nvm","versions","node");try{for(let s of(0,A.readdirSync)(t)){let i=(0,k.join)(t,s,"bin","skillkit");if((0,A.existsSync)(i))return i}}catch{}let e=(0,k.join)(I,".local","share","mise","installs");for(let s of["node","bun"])try{for(let i of(0,A.readdirSync)((0,k.join)(e,s))){let a=(0,k.join)(e,s,i,"bin","skillkit");if((0,A.existsSync)(a))return a}}catch{}return null}var bt;function St(){return bt===void 0&&(bt=Ie()),bt}function L(){return St()!==null||(0,A.existsSync)(Me)}function H(n){let t=St();if(!t)return null;try{let e=(0,kt.execSync)(`${t} ${n} --json`,{encoding:"utf-8",timeout:15e3,env:{...process.env,NO_COLOR:"1",PATH:Rt()},stdio:["pipe","pipe","pipe"]}).trim(),s=e.indexOf("{"),i=e.indexOf("["),a=s===-1?i:i===-1?s:Math.min(s,i);return a===-1?null:JSON.parse(e.slice(a))}catch{return null}}function Bt(){let n=new Map;if(!L())return n;let t=H("stats");if(!t?.top_skills)return n;let e=Date.now();for(let s of t.top_skills){let i=s.daily.length>0?s.daily[s.daily.length-1]?.date:null,a=null;i&&(a=Math.floor((e-new Date(i).getTime())/(1e3*60*60*24))),n.set(s.name,{uses:s.total,lastUsed:i||null,daysSinceUsed:a,isStale:a!==null&&a>30,isHeavy:!1,daily:s.daily})}return n}function Nt(){let n=new Map;if(!L())return n;let t=H("conflicts --dry-run");if(!t||!("pairs"in t))return n;for(let e of t.pairs)n.has(e.skill_a)||n.set(e.skill_a,[]),n.has(e.skill_b)||n.set(e.skill_b,[]),n.get(e.skill_a).push({skillName:e.skill_b,similarity:e.similarity}),n.get(e.skill_b).push({skillName:e.skill_a,similarity:e.similarity});return n}function Vt(n){if(!L())return[];let t=H(`trace --list --skill ${n} --limit 5`);return Array.isArray(t)?t.map(e=>({traceId:e.trace_id,timestamp:e.timestamp,tokens:e.tokens_total,cost:e.cost_estimate,duration:e.duration_ms,model:e.model||"unknown"})):[]}function zt(){if(!L())return{oversized:[],longDesc:[]};let n=H("health");return n?.warnings?{oversized:n.warnings.oversized||[],longDesc:n.warnings.long_descriptions||[]}:{oversized:[],longDesc:[]}}function U(n){let t=St();if(!t)return{success:!1,output:"skillkit not found"};try{return{success:!0,output:(0,kt.execSync)(`${t} ${n}`,{encoding:"utf-8",timeout:3e4,env:{...process.env,NO_COLOR:"1",PATH:Rt()},stdio:["pipe","pipe","pipe"]}).trim()}}catch(e){return{success:!1,output:e instanceof Error?e.message:"unknown error"}}}function yt(n){if(!n)return"never";let t=Date.now()-new Date(n).getTime(),e=Math.floor(t/6e4);if(e<60)return`${e}m ago`;let s=Math.floor(e/60);if(s<24)return`${s}h ago`;let i=Math.floor(s/24);return i<30?`${i}d ago`:`${Math.floor(i/30)}mo ago`}function Wt(n,t,e=48,s=16){if(t.length===0)return;let i=Math.max(...t,1),a=t.map((o,c)=>{let d=c/(t.length-1||1)*e,b=s-o/i*s;return`${d.toFixed(1)},${b.toFixed(1)}`}),r=document.createElementNS("http://www.w3.org/2000/svg","svg");r.setAttribute("viewBox",`0 0 ${e} ${s}`),r.setAttribute("width",String(e)),r.setAttribute("height",String(s)),r.classList.add("as-sparkline");let l=document.createElementNS("http://www.w3.org/2000/svg","polyline");l.setAttribute("points",a.join(" ")),l.setAttribute("fill","none"),l.setAttribute("stroke","currentColor"),l.setAttribute("stroke-width","1.5"),l.setAttribute("stroke-linecap","round"),l.setAttribute("stroke-linejoin","round"),r.appendChild(l),n.appendChild(r)}var Ut=require("obsidian");function N(n,t,e,s){new wt(n,t,e,s).open()}var wt=class extends Ut.Modal{title;message;onConfirm;constructor(t,e,s,i){super(t),this.title=e,this.message=s,this.onConfirm=i}onOpen(){let{contentEl:t}=this;t.addClass("as-confirm-modal"),t.createEl("p",{cls:"as-confirm-title",text:this.title}),t.createEl("p",{cls:"as-confirm-message",text:this.message});let e=t.createDiv("as-confirm-buttons");e.createEl("button",{cls:"as-confirm-cancel",text:"Cancel"}).addEventListener("click",()=>this.close()),e.createEl("button",{cls:"as-confirm-action mod-warning",text:"Confirm"}).addEventListener("click",()=>{this.close(),this.onConfirm()})}onClose(){this.contentEl.empty()}};function Ae(n){return Math.ceil(n.length/4)}function _e(n){return n<1024?`${n} B`:n<1024*1024?`${(n/1024).toFixed(1)} KB`:`${(n/(1024*1024)).toFixed(1)} MB`}function Gt(n){return n>=1e3?`${(n/1e3).toFixed(1)}k`:String(n)}function $e(n){return new Date(n).toLocaleDateString(void 0,{month:"short",day:"numeric",year:"numeric"})}var st=class{containerEl;store;settings;saveSettings;currentItem=null;isEditing=!1;app;constructor(t,e,s,i,a){this.containerEl=t,this.store=e,this.settings=s,this.saveSettings=i,this.app=a.app}show(t){this.currentItem=t,this.isEditing=!1,this.render()}clear(){this.currentItem=null,this.containerEl.empty(),this.containerEl.addClass("as-detail");let t=this.containerEl.createDiv("as-detail-empty");(0,y.setIcon)(t.createDiv("as-detail-empty-icon"),"file-text"),t.createDiv({text:"Select a skill to view"})}render(){this.containerEl.empty(),this.containerEl.addClass("as-detail");let t=this.currentItem;if(!t)return this.clear();this.renderToolbar(t),this.isEditing?this.renderEditor(t):this.renderPreview(t)}renderToolbar(t){let e=this.containerEl.createDiv("as-detail-toolbar"),s=e.createDiv("as-toolbar-top"),i=s.createDiv("as-toolbar-left");i.createSpan({cls:"as-detail-title",text:t.name});for(let g of t.tools){let m=D.find(ft=>ft.id===g);if(!m)continue;let z=i.createSpan("as-tool-name-badge");z.setCssProps({"--tool-color":m.color}),C[g]&&j(z,g,12),z.createSpan({text:m.name})}let a=s.createDiv("as-toolbar-right"),r=a.createEl("button",{cls:"as-toolbar-btn",attr:{"aria-label":"Toggle favorite"}});(0,y.setIcon)(r,t.isFavorite?"star":"star-off"),r.addEventListener("click",()=>{this.store.toggleFavorite(t.id,this.settings),this.saveSettings(),this.render()});let l=a.createEl("button",{cls:"as-toolbar-btn",attr:{"aria-label":this.isEditing?"Preview":"Edit"}});(0,y.setIcon)(l,this.isEditing?"eye":"pencil"),l.addEventListener("click",()=>{this.isEditing=!this.isEditing,this.render()});let o=a.createEl("button",{cls:"as-toolbar-btn",attr:{"aria-label":"Show in system explorer"}});if((0,y.setIcon)(o,"folder-open"),o.addEventListener("click",()=>{Zt.shell.showItemInFolder(t.filePath)}),L()){let g=a.createEl("button",{cls:"as-toolbar-btn as-toolbar-btn-danger",attr:{"aria-label":"Remove skill"}});(0,y.setIcon)(g,"trash-2"),g.addEventListener("click",()=>{N(this.app,"Remove skill",`Remove "${t.name}"? This will delete the skill files.`,()=>{let m=U(`prune --skill ${t.name} --yes`);m.success?(new y.Notice(`Removed ${t.name}`,5e3),this.store.refresh(this.settings),this.clear()):new y.Notice(`Failed to remove: ${m.output}`,5e3)})})}let c=e.createDiv("as-detail-meta-bar"),d=Ae(t.content),b=t.content.length;if(c.createSpan({cls:"as-meta-item",text:_e(t.fileSize)}),c.createSpan({cls:"as-meta-item",text:`${Gt(b)} chars`}),c.createSpan({cls:"as-meta-item",text:`~${Gt(d)} tokens`}),c.createSpan({cls:"as-meta-item",text:$e(t.lastModified)}),c.createSpan({cls:"as-meta-item as-meta-type",text:t.type}),t.usage&&t.usage.uses>0){let g=e.createDiv("as-detail-usage-bar");g.createSpan({cls:"as-usage-stat",text:`${t.usage.uses} uses`}),g.createSpan({cls:"as-usage-stat",text:`last: ${yt(t.usage.lastUsed)}`}),t.usage.isStale&&g.createSpan({cls:"as-badge-stale",text:"stale"}),t.usage.isHeavy&&g.createSpan({cls:"as-badge-heavy",text:"heavy"})}}renderFrontmatter(t,e){let s=Object.keys(e.frontmatter),i=t.createDiv("as-frontmatter");if(e.filePath){let a=i.createDiv("as-fm-prop");a.createSpan({cls:"as-fm-key",text:"path"}),a.createSpan({cls:"as-fm-value",text:e.filePath})}if(!(s.length===0&&!e.filePath))for(let a of s){let r=e.frontmatter[a];if(r==null)continue;let l=i.createDiv("as-fm-prop");l.createSpan({cls:"as-fm-key",text:a});let o=typeof r=="object"||Array.isArray(r)?JSON.stringify(r):String(r);o.length>200?l.createDiv({cls:"as-fm-value-long",text:o}):l.createSpan({cls:"as-fm-value",text:o})}}renderPreview(t){let e=this.containerEl.createDiv("as-detail-body");this.renderFrontmatter(e,t),this.renderWarnings(e,t),this.renderUsageSection(e,t),this.renderConflicts(e,t),this.renderTraces(e,t);let s=e.createDiv("as-detail-preview markdown-rendered");y.MarkdownRenderer.render(this.app,t.content,s,t.filePath,this)}renderWarnings(t,e){let s=[];if(e.warnings?.oversized&&s.push(`${e.warnings.lineCount} lines (recommended: <500)`),e.warnings?.longDesc&&s.push(`Description is ${e.warnings.descChars} chars (recommended: <1024)`),e.conflicts&&e.conflicts.length>0){let l=e.conflicts.map(o=>o.skillName).join(", ");s.push(`Conflicts with: ${l}`)}if(s.length===0)return;let i=t.createDiv("as-warnings"),a=i.createDiv("as-warnings-icon");(0,y.setIcon)(a,"alert-triangle");let r=i.createDiv("as-warnings-list");for(let l of s)r.createDiv({cls:"as-warnings-item",text:l})}renderUsageSection(t,e){if(!e.usage||e.usage.uses===0)return;let s=t.createDiv("as-usage-section"),i=s.createDiv("as-usage-left");if(i.createSpan({cls:"as-usage-count",text:String(e.usage.uses)}),i.createSpan({cls:"as-usage-label",text:"uses"}),i.createSpan({cls:"as-usage-last",text:yt(e.usage.lastUsed)}),e.usage.daily&&e.usage.daily.length>1){let a=s.createDiv("as-usage-spark");Wt(a,e.usage.daily.map(r=>r.count),80,20)}}renderConflicts(t,e){if(!e.conflicts||e.conflicts.length===0)return;let s=t.createDiv("as-conflicts-section");s.createDiv({cls:"as-section-title",text:`Conflicts (${e.conflicts.length})`});for(let i of e.conflicts){let a=s.createDiv("as-conflict-row");a.createSpan({cls:"as-conflict-name",text:i.skillName}),a.createDiv("as-conflict-bar-wrap").createDiv("as-conflict-bar").setCssProps({"--bar-w":`${(i.similarity*100).toFixed(0)}%`}),a.createSpan({cls:"as-conflict-score",text:`${(i.similarity*100).toFixed(0)}%`})}}renderTraces(t,e){if(!L())return;let s=Vt(e.name);if(s.length===0)return;let i=t.createDiv("as-traces-section");i.createDiv({cls:"as-section-title",text:`Recent traces (${s.length})`});let a=i.createDiv("as-traces-table");for(let r of s){let l=a.createDiv("as-trace-row"),o=new Date(r.timestamp);l.createSpan({cls:"as-trace-date",text:o.toLocaleDateString(void 0,{month:"short",day:"numeric"})}),l.createSpan({cls:"as-trace-model",text:r.model.replace("claude-","").replace("-4-6","")}),l.createSpan({cls:"as-trace-tokens",text:`${(r.tokens/1e3).toFixed(1)}k`}),l.createSpan({cls:"as-trace-cost",text:r.cost>0?`$${r.cost.toFixed(2)}`:""}),l.createSpan({cls:"as-trace-duration",text:`${(r.duration/1e3).toFixed(1)}s`})}i.createDiv({cls:"as-traces-hint",text:"skillkit trace --list --skill "+e.name})}renderPruneAction(t,e){let s=t.createDiv("as-prune-section"),i=s.createEl("button",{cls:"as-prune-btn",text:"Remove this skill"});s.createSpan({cls:"as-prune-hint",text:"This skill hasn't been used in 30+ days"}),i.addEventListener("click",()=>{N(this.app,"Remove skill",`Remove "${e.name}"? This will delete the skill files.`,()=>{let a=U(`prune --skill ${e.name} --yes`);a.success?(new y.Notice(`Removed ${e.name}`,5e3),this.store.refresh(this.settings)):new y.Notice(`Failed to remove: ${a.output}`,5e3)})})}renderEditor(t){let e=this.containerEl.createDiv("as-detail-body as-detail-body-editor"),s=e.createEl("textarea",{cls:"as-editor-textarea"});s.value=t.content,s.spellcheck=!1,s.addEventListener("keydown",r=>{if((r.metaKey||r.ctrlKey)&&r.key==="s"&&(r.preventDefault(),this.saveFile(t,s.value)),r.key==="Tab"){r.preventDefault();let l=s.selectionStart,o=s.selectionEnd;s.value=s.value.substring(0,l)+" "+s.value.substring(o),s.selectionStart=s.selectionEnd=l+1}});let i=e.createDiv("as-save-bar");i.createEl("button",{cls:"as-save-btn",text:"Save"}).addEventListener("click",()=>{this.saveFile(t,s.value)}),i.createSpan({cls:"as-save-hint",text:"Cmd+S to save"})}saveFile(t,e){try{(0,Jt.writeFileSync)(t.filePath,e,"utf-8"),t.content=e,new y.Notice(`Saved ${t.name}`,5e3)}catch(s){new y.Notice(`Failed to save: ${s instanceof Error?s.message:String(s)}`,5e3)}}};var _=require("obsidian"),re=require("electron");var xt=require("child_process"),w=require("fs"),S=require("path"),Yt=require("os"),q=require("obsidian"),x=(0,Yt.homedir)(),Kt=(0,S.join)(x,".agents",".skill-lock.json"),He="https://skills.sh/api";async function Dt(n){if(n.length<2)return[];try{let e=(await(0,q.requestUrl)({url:`${He}/search?q=${encodeURIComponent(n)}&limit=30`})).json;if(!e.skills)return[];let s=se();return e.skills.map(i=>({...i,installed:s.has(i.name)}))}catch{return[]}}var Qt=new Map;async function Fe(n){let t=Qt.get(n);if(t)return t;let s=(await(0,q.requestUrl)({url:`https://api.github.com/repos/${n}`})).json.default_branch||"main",a=(await(0,q.requestUrl)({url:`https://api.github.com/repos/${n}/git/trees/${s}?recursive=1`})).json.tree.filter(l=>l.path.endsWith("/SKILL.md")).map(l=>l.path),r={branch:s,files:a};return Qt.set(n,r),r}function je(n,t,e){let s=t.split("/"),i=s[s.length-1]||n,a=new Set([i,n]);for(let r of e.split("/")){n.startsWith(r+"-")&&a.add(n.slice(r.length+1));for(let l of r.split("-"))n.startsWith(l+"-")&&a.add(n.slice(l.length+1))}return a}async function Xt(n,t,e){try{let{branch:s,files:i}=await Fe(n),a=je(t,e,n),r=i.find(c=>{let d=c.replace("/SKILL.md","").split("/").pop()||"";return a.has(d)});r||(r=i.find(c=>{let d=c.replace("/SKILL.md","").split("/").pop()||"";return t.includes(d)||d.includes(t)}));let l=r||`skills/${t}/SKILL.md`;return(await(0,q.requestUrl)({url:`https://raw.githubusercontent.com/${n}/${s}/${l}`})).text}catch{return null}}async function te(){let n=["react","next","clerk","stripe","ai"],t=new Set,e=[];for(let s of n){let i=await Dt(s);for(let a of i)t.has(a.id)||(t.add(a.id),e.push(a))}return e.sort((s,i)=>i.installs-s.installs).slice(0,20)}function Oe(){let n=["/usr/local/bin","/opt/homebrew/bin",(0,S.join)(x,".local","bin"),(0,S.join)(x,".bun","bin")],t=(0,S.join)(x,".nvm","versions","node");try{for(let e of(0,w.readdirSync)(t))n.push((0,S.join)(t,e,"bin"))}catch{}return[...n,process.env.PATH||""].join(":")}function qt(){let n=(0,S.join)(x,".bun","bin","bunx");return(0,w.existsSync)(n)?n:(0,w.existsSync)("/usr/local/bin/bunx")||(0,w.existsSync)("/opt/homebrew/bin/bunx")?"bunx":"npx"}function Et(n="auto"){return n==="npx"?"npx":qt()}var ee=[{id:"claude-code",label:"Claude Code"},{id:"cursor",label:"Cursor"},{id:"codex",label:"Codex"},{id:"github-copilot",label:"GitHub Copilot"},{id:"windsurf",label:"Windsurf"},{id:"amp",label:"Amp"},{id:"opencode",label:"OpenCode"},{id:"cline",label:"Cline"},{id:"gemini-cli",label:"Gemini CLI"},{id:"goose",label:"Goose"},{id:"kiro-cli",label:"Kiro"},{id:"roo",label:"Roo Code"},{id:"continue",label:"Continue"},{id:"antigravity",label:"Antigravity"},{id:"warp",label:"Warp"},{id:"pi",label:"Pi"},{id:"replit",label:"Replit"}],it={"claude-code":"claude-code",cursor:"cursor",codex:"codex",copilot:"github-copilot",windsurf:"windsurf",amp:"amp",opencode:"opencode",antigravity:"antigravity","claude-desktop":"claude-code",pi:"pi","global-agents":"claude-code",aider:"claude-code"};function se(){let n=new Set;if(!(0,w.existsSync)(Kt))return n;try{let t=JSON.parse((0,w.readFileSync)(Kt,"utf-8"));if(t.skills)for(let e of Object.keys(t.skills))n.add(e)}catch{}return n}var Re=[(0,S.join)(x,".claude","skills"),(0,S.join)(x,".cursor","skills"),(0,S.join)(x,".codex","skills"),(0,S.join)(x,".codeium","windsurf","skills"),(0,S.join)(x,".config","amp","skills"),(0,S.join)(x,".config","opencode","skills"),(0,S.join)(x,".copilot","skills"),(0,S.join)(x,".agents","skills")];function Be(n){for(let t of Re){let e=(0,S.join)(t,n);if((0,w.existsSync)(e))try{(0,w.rmSync)(e,{recursive:!0,force:!0})}catch{}}Ne(n)}function Ne(n){let t=(0,S.join)(x,".agents",".skill-lock.json");if((0,w.existsSync)(t))try{let e=JSON.parse((0,w.readFileSync)(t,"utf-8"));e.skills&&e.skills[n]&&(delete e.skills[n],(0,w.writeFileSync)(t,JSON.stringify(e,null,2)+` +`,"utf-8"))}catch{}}function nt(n){let t=se();for(let e of n)e.installed=t.has(e.name);return n}function Ct(n,t=12e4){return new Promise(e=>{(0,xt.exec)(n,{encoding:"utf-8",timeout:t,env:{...process.env,PATH:Oe(),NO_COLOR:"1"}},(s,i)=>{let a=String(i??"");!s||a.includes("Done")||a.includes("Installed")||a.includes("Removed")||a.includes("Updated")?e({success:!0,output:a}):e({success:!1,output:s?.message??"Command failed"})})})}async function ie(n,t,e={}){let s=t.length>0?`-a ${t.join(" ")}`:"-a '*'",i=e.global?"-g":"",r=`${Et(e.runner||"auto")} skills add ${n} ${s} ${i} -y`.replace(/\s+/g," ").trim();return Ct(r)}async function ne(n,t="auto"){let s=`${Et(t)} skills remove ${n} -y`,i=await Ct(s,3e4);return Be(n),{success:!0,output:i.output||`Cleaned ${n}`}}async function ae(n="auto"){let e=`${Et(n)} skills update`,s=await Ct(e),i=s.output.match(/Updated (\d+) skill/);return{...s,count:i?parseInt(i[1]):0}}function Lt(n){return n>=1e6?`${(n/1e6).toFixed(1)}M`:n>=1e3?`${(n/1e3).toFixed(1)}K`:String(n)}var G=require("fs"),oe=require("path"),le=require("os");function Ve(){let n=H("stats"),t=H("health"),e=H("burn"),s=H("context");return{stats:n,health:t,burn:e&&e.length>0?e[0]:null,context:s}}var Tt=(0,oe.join)((0,le.homedir)(),".skillkit","dashboard-cache.json"),$=null,R=null;function ze(){if(!$&&(0,G.existsSync)(Tt))try{let n=JSON.parse((0,G.readFileSync)(Tt,"utf-8"));$=n.data,R=n.cachedAt}catch{}}function We(){if($)try{(0,G.writeFileSync)(Tt,JSON.stringify({data:$,cachedAt:R},null,2),"utf-8")}catch{}}ze();var at=class{containerEl;app;constructor(t,e){this.containerEl=t,this.app=e}render(){if(this.containerEl.empty(),this.containerEl.addClass("as-dashboard"),!L()){this.renderNoSkillkit();return}if($)this.renderDashboard($);else{let t=this.containerEl.createDiv("as-dash-loading");t.createDiv("as-dash-spinner"),t.createDiv({cls:"as-dash-loading-text",text:"Loading analytics..."}),setTimeout(()=>{let e=Ve();$=e,R=Date.now(),We(),t.remove(),this.renderDashboard(e)},10)}}renderDashboard(t){if(this.renderActionBar(t),t.stats&&this.renderOverview(t.stats,t.health),t.stats&&this.renderTopSkills(t.stats),t.health||t.context){let e=this.containerEl.createDiv("as-dash-row");t.health&&this.renderHealth(t.health,e),t.context&&this.renderContext(t.context,e)}t.burn&&this.renderBurn(t.burn),t.health&&this.renderStale(t.health)}renderActionBar(t){let e=this.containerEl.createDiv("as-dash-action-bar");if(R){let r=Math.round((Date.now()-R)/1e3),l=r<5?"just now":r<60?`${r}s ago`:`${Math.round(r/60)}m ago`;e.createSpan({cls:"as-dash-updated",text:`Updated ${l}`})}let s=e.createDiv("as-dash-action-buttons"),i=s.createEl("button",{cls:"as-action-btn",text:"Update skills"});i.addEventListener("click",()=>{i.setText("Updating..."),i.disabled=!0,ae().then(r=>{if(r.success){let l=r.count>0?`Updated ${r.count} skill(s)`:"All skills up to date";new _.Notice(l,5e3),$=null,R=null,this.render()}else new _.Notice(`Update failed: ${r.output}`,5e3);i.setText("Update skills"),i.disabled=!1})});let a=s.createEl("button",{cls:"as-action-btn",text:"Scan sessions"});if(a.addEventListener("click",()=>{a.setText("Scanning..."),a.disabled=!0,setTimeout(()=>{let r=U("scan");r.success?(new _.Notice("Scan complete",5e3),$=null,R=null,this.render()):new _.Notice(`Scan failed: ${r.output}`,5e3),a.setText("Scan sessions"),a.disabled=!1},10)}),t.health&&t.health.usage.unused_30d>0){let r=s.createEl("button",{cls:"as-action-btn as-action-btn-danger",text:`Prune ${t.health.usage.unused_30d} stale`});r.addEventListener("click",()=>{N(this.app,"Prune stale skills",`Remove ${t.health.usage.unused_30d} unused skills? This cannot be undone.`,()=>{r.setText("Pruning..."),r.disabled=!0,setTimeout(()=>{let l=U("prune --yes");l.success?(new _.Notice("Pruned stale skills",5e3),$=null,R=null,this.render()):new _.Notice(`Prune failed: ${l.output}`,5e3),r.setText(`Prune ${t.health.usage.unused_30d} stale`),r.disabled=!1},10)})})}}renderNoSkillkit(){let t=this.containerEl.createDiv("as-dash-empty"),e=t.createDiv("as-dash-empty-icon");(0,_.setIcon)(e,"bar-chart-2"),t.createEl("h3",{text:"Dashboard requires skillkit"}),t.createEl("p",{text:"Install skillkit to unlock usage analytics, burn rate, context tax, and more."}),t.createDiv("as-dash-install-cmd").createEl("code",{text:"npm i -g @crafter/skillkit && skillkit scan"}),t.createEl("a",{cls:"as-skillkit-link",text:"Learn more",href:"https://www.npmjs.com/package/@crafter/skillkit"}).addEventListener("click",a=>{a.preventDefault(),re.shell.openExternal("https://www.npmjs.com/package/@crafter/skillkit")})}renderOverview(t,e){let s=this.containerEl.createDiv("as-dash-section");s.createDiv({cls:"as-dash-title",text:"Overview"});let i=s.createDiv("as-dash-stats");if(this.statCard(i,String(t.total_invocations),"invocations","activity"),this.statCard(i,String(t.unique_skills),"active skills","sparkles"),this.statCard(i,String(e?.installed??0),"installed","package"),this.statCard(i,String(e?.usage.unused_30d??0),"stale","alert-triangle"),t.streak&&t.streak.current>0){let a=s.createDiv("as-dash-streak-row");a.createSpan({cls:"as-streak-value",text:`${t.streak.current} day streak`}),t.streak.current>=7&&a.createSpan({cls:"as-streak-fire",text:"on fire"}),a.createSpan({cls:"as-streak-longest",text:`longest: ${t.streak.longest}d`})}if(t.velocity&&t.velocity.this_week>0){let a=s.createDiv("as-dash-velocity-row");a.createSpan({text:`This week: $${t.velocity.this_week.toFixed(0)}`}),a.createSpan({cls:"as-velocity-vs",text:`vs $${t.velocity.last_week.toFixed(0)} last week`});let r=t.velocity.change_pct,l=r>0?"as-velocity-up":r<0?"as-velocity-down":"",o=r>0?"+":"";a.createSpan({cls:`as-velocity-change ${l}`,text:`${o}${r.toFixed(0)}%`})}}statCard(t,e,s,i){let a=t.createDiv("as-stat-card"),r=a.createDiv("as-stat-icon");(0,_.setIcon)(r,i),a.createDiv({cls:"as-stat-value",text:e}),a.createDiv({cls:"as-stat-label",text:s})}renderTopSkills(t){if(t.top_skills.length===0)return;let e=this.containerEl.createDiv("as-dash-section");e.createDiv({cls:"as-dash-title",text:`Top Skills (${t.period.days}d)`});let s=t.top_skills[0]?.total||1,i=e.createDiv("as-dash-bars");for(let a of t.top_skills.slice(0,10)){let r=i.createDiv("as-bar-row");r.createSpan({cls:"as-bar-name",text:a.name}),r.createDiv("as-bar-wrap").createDiv("as-bar-fill").setCssProps({"--bar-w":`${a.total/s*100}%`}),r.createSpan({cls:"as-bar-count",text:String(a.total)})}}renderHealth(t,e){let s=(e||this.containerEl).createDiv("as-dash-section");s.createDiv({cls:"as-dash-title",text:"Health"});let i=t.usage.used_30d+t.usage.unused_30d,a=i>0?Math.round(t.usage.used_30d/i*100):0,r=s.createDiv("as-dash-health-row"),l=r.createDiv("as-donut");l.setCssProps({"--pct":`${a}`}),l.createDiv({cls:"as-donut-label",text:`${a}%`}),l.createDiv({cls:"as-donut-sub",text:"active"});let o=r.createDiv("as-health-details");o.createDiv({cls:"as-health-line",text:`${t.usage.used_30d} used in 30d`}),o.createDiv({cls:"as-health-line as-health-warn",text:`${t.usage.unused_30d} never triggered`});let d=o.createDiv("as-budget-bar").createDiv("as-budget-fill");d.setCssProps({"--bar-w":`${t.metadata.pct}%`}),t.metadata.pct>80&&d.addClass("as-budget-over"),o.createDiv({cls:"as-health-line",text:`Metadata budget: ${t.metadata.pct}%`})}renderBurn(t){let e=this.containerEl.createDiv("as-dash-section");e.createDiv({cls:"as-dash-title",text:`Burn Rate \u2014 ${t.agent} (${t.period.days}d)`});let s=e.createDiv("as-dash-stats as-dash-stats-sm");if(this.statCard(s,`$${Math.round(t.cost.total).toLocaleString()}`,"total cost","flame"),this.statCard(s,`$${Math.round(t.cost.total/(t.period.days||1)).toLocaleString()}`,"daily avg","trending-up"),this.statCard(s,`${(t.period.sessions||0).toLocaleString()}`,"sessions","terminal"),this.statCard(s,`${((t.period.api_calls||0)/1e3).toFixed(0)}k`,"API calls","zap"),t.by_model&&t.by_model.length>0){let l=e.createDiv("as-model-breakdown");for(let o of t.by_model.slice(0,4)){let c=l.createDiv("as-model-row");c.createSpan({cls:"as-model-name",text:o.model}),c.createSpan({cls:"as-model-calls",text:`${o.apiCalls.toLocaleString()} calls`}),o.costUsd>0&&c.createSpan({cls:"as-model-cost",text:`$${Math.round(o.costUsd).toLocaleString()}`})}}let i=t.by_day.slice(-14);if(i.length===0)return;let a=Math.max(...i.map(l=>l.costUsd),1),r=e.createDiv("as-burn-chart");for(let l of i){let o=r.createDiv("as-burn-col"),c=o.createDiv("as-burn-bar"),d=Math.max(2,l.costUsd/a*100);c.setCssProps({"--bar-h":`${d}%`}),c.title=`${l.date}: $${l.costUsd.toFixed(0)}`,o.createDiv({cls:"as-burn-date",text:l.date.slice(8)})}}renderContext(t,e){let s=(e||this.containerEl).createDiv("as-dash-section");s.createDiv({cls:"as-dash-title",text:"Context Tax"});let i=t.always_loaded.total_tokens,a=[{label:"CLAUDE.md",tokens:t.always_loaded.claude_md_tokens,cls:"as-ctx-claude"},{label:"Skills metadata",tokens:t.always_loaded.skill_metadata_tokens,cls:"as-ctx-skills"},{label:"Memory",tokens:t.always_loaded.memory_tokens,cls:"as-ctx-memory"}],r=s.createDiv("as-ctx-bar");for(let c of a){let d=r.createDiv(`as-ctx-part ${c.cls}`);d.setCssProps({"--bar-w":`${c.tokens/i*100}%`}),d.title=`${c.label}: ${(c.tokens/1e3).toFixed(1)}k tokens`}let l=s.createDiv("as-ctx-legend");for(let c of a){let d=l.createDiv("as-ctx-legend-item");d.createSpan({cls:`as-ctx-dot ${c.cls}`}),d.createSpan({text:`${c.label}: ${(c.tokens/1e3).toFixed(1)}k`})}let o=s.createDiv("as-ctx-costs");o.createDiv({text:`Per session (cached): $${t.session_estimate.with_cache.toFixed(2)}`}),o.createDiv({text:`Without cache: $${t.session_estimate.without_cache.toFixed(2)}`}),o.createDiv({cls:"as-ctx-savings",text:`Cache saves ${t.session_estimate.savings_pct.toFixed(0)}%`})}renderStale(t){if(t.usage.never_used.length===0)return;let e=this.containerEl.createDiv("as-dash-section");e.createDiv({cls:"as-dash-title",text:`Stale skills (${t.usage.unused_30d})`});let s=e.createDiv("as-stale-list");for(let i of t.usage.never_used.slice(0,20))s.createDiv("as-stale-item").createSpan({text:i});t.usage.never_used.length>20&&s.createDiv({cls:"as-stale-more",text:`+${t.usage.never_used.length-20} more`})}};var M=require("obsidian"),Z=require("fs"),ve=require("path"),be=require("os");var T=require("obsidian"),J=require("fs"),ge=require("path"),fe=require("os");var h=require("fs"),f=require("path"),rt=require("os"),de=require("obsidian"),pe=require("crypto");var ce=new Set(["readme.md","license","license.md","changelog.md",".ds_store","thumbs.db"]);function Ue(n){return(0,pe.createHash)("sha256").update(n).digest("hex").slice(0,12)}function Ge(n){let t=n.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);if(!t)return{frontmatter:{},content:n};try{let e=(0,de.parseYaml)(t[1]);return{frontmatter:typeof e=="object"&&e?e:{},content:t[2]}}catch{return{frontmatter:{},content:n}}}function Je(n,t,e,s="auto"){if(s==="auto"){if(typeof n.name=="string"&&n.name)return n.name;let a=t.match(/^#\s+(.+)$/m);if(a)return a[1].trim()}let i=(0,f.basename)(e,(0,f.extname)(e));return i==="SKILL"?(0,f.basename)((0,f.join)(e,"..")):i}function Ze(n,t,e,s="auto"){if(!(0,h.existsSync)(n))return[];let i=[];for(let a of(0,h.readdirSync)(n,{withFileTypes:!0})){let r=(0,f.join)(n,a.name);if(!(a.isDirectory()||a.isSymbolicLink()&&(0,h.statSync)(r,{throwIfNoEntry:!1})?.isDirectory()))continue;let o=(0,f.join)(r,"SKILL.md");if(!(0,h.existsSync)(o))continue;let c=Y(o,t,e,"directory-with-skillmd",s);c&&i.push(c)}return i}function Ke(n,t,e,s="auto"){if(!(0,h.existsSync)(n))return[];let i=[];for(let a of(0,h.readdirSync)(n,{withFileTypes:!0})){let r=(0,f.join)(n,a.name);if(a.isDirectory()||a.isSymbolicLink()&&(0,h.statSync)(r,{throwIfNoEntry:!1})?.isDirectory()){let d=(0,f.join)(r,"SKILL.md");if((0,h.existsSync)(d)){let m=Y(d,t,e,"flat-md",s);m&&i.push(m);continue}let b=(0,h.readdirSync)(r).filter(m=>m.endsWith(".md")&&!ce.has(m.toLowerCase())),g=b.find(m=>m.toLowerCase()===`${a.name.toLowerCase()}.md`)||b[0];if(g){let m=Y((0,f.join)(r,g),t,e,"flat-md",s);m&&i.push(m)}continue}let o=a.name.toLowerCase();if(!o.endsWith(".md")||ce.has(o))continue;let c=Y(r,t,e,"flat-md",s);c&&i.push(c)}return i}function Qe(n,t,e,s="auto"){if(!(0,h.existsSync)(n))return[];let i=[];for(let a of(0,h.readdirSync)(n,{withFileTypes:!0})){if(!a.name.endsWith(".mdc")&&!a.name.endsWith(".md")||a.isDirectory())continue;let r=Y((0,f.join)(n,a.name),t,e,"mdc",s);r&&i.push(r)}return i}function Y(n,t,e,s="directory-with-skillmd",i="auto"){try{let a=(0,h.readFileSync)(n,"utf-8"),r=(0,h.statSync)(n),{frontmatter:l,content:o}=Ge(a),c=Je(l,o,n,i),d=typeof l.description=="string"?l.description:"",b;try{b=(0,h.realpathSync)(n)}catch{b=n}return{id:Ue(b),name:c,description:d,type:t,tools:[e],filePath:n,realPath:b,dirPath:(0,f.join)(n,".."),content:a,frontmatter:l,lastModified:r.mtimeMs,fileSize:r.size,isFavorite:!1,collections:[]}}catch{return null}}function Pt(n,t,e="auto"){switch(n.pattern){case"directory-with-skillmd":return Ze(n.baseDir,n.type,t,e);case"flat-md":return Ke(n.baseDir,n.type,t,e);case"mdc":return Qe(n.baseDir,n.type,t,e)}}function qe(n,t){let e=[],s=[{sub:".claude/skills",type:"skill",pattern:"directory-with-skillmd"},{sub:".claude/commands",type:"command",pattern:"flat-md"},{sub:".claude/agents",type:"agent",pattern:"flat-md"},{sub:".cursor/skills",type:"skill",pattern:"directory-with-skillmd"},{sub:".codex/skills",type:"skill",pattern:"directory-with-skillmd"}];for(let i of s){let a=(0,f.join)(n,i.sub);if(!(0,h.existsSync)(a))continue;let r={baseDir:a,type:i.type,pattern:i.pattern};e.push(...Pt(r,t))}return e}function ue(n){return n.projectsHomeDir||(0,rt.homedir)()}function Ye(n,t){let e=(0,rt.homedir)(),s=[];for(let i of[...t.paths,...t.agentPaths]){let a=(0,f.relative)(e,i.baseDir);if(a.startsWith("..")||a.startsWith("/"))continue;let r=(0,f.join)(n,a);if((0,h.existsSync)(r))try{s.push(...Pt({...i,baseDir:r},t.id))}catch{}}return s}function Xe(n){let t=ue(n);if(!(0,h.existsSync)(t))return[];let e=[];try{let s=new Set(["node_modules",".Trash","Library","Applications","Music","Movies","Pictures","Public"]);for(let i of(0,h.readdirSync)(t,{withFileTypes:!0})){if(!i.isDirectory()&&!i.isSymbolicLink()||s.has(i.name))continue;let a=(0,f.join)(t,i.name);for(let r of D){if(!r.isInstalled())continue;let l=n.tools[r.id];if(l&&!l.enabled)continue;let o=Ye(a,r);o.length>0&&e.push({items:o,toolId:r.id})}}}catch{}return e}function Mt(n,t){let e=t||(0,rt.homedir)();if(!n.startsWith(e+"/"))return"global";let i=n.slice(e.length+1).split("/");return i.length>1&&!i[0].startsWith(".")?i[0]:"global"}function he(n){let t=n.namingMode||"auto",e=new Map,s=new Map;function i(a,r){let l=e.get(a.id);if(l){l.tools.includes(r)||l.tools.push(r);return}let o=s.get(a.name);if(o){let c=e.get(o);c&&!c.tools.includes(r)&&c.tools.push(r);return}a.isFavorite=n.favorites.includes(a.id);for(let[c,d]of Object.entries(n.collections))d.includes(a.id)&&a.collections.push(c);e.set(a.id,a),s.set(a.name,a.id)}for(let a of D){if(!a.isInstalled())continue;let r=n.tools[a.id];if(r&&!r.enabled)continue;let l=[...a.paths,...a.agentPaths];for(let o of l)for(let c of Pt(o,a.id,t))i(c,a.id)}for(let a of n.customScanPaths)if((0,h.existsSync)(a))for(let r of qe(a,"claude-code"))i(r,"claude-code");if(n.projectScanEnabled)for(let{items:a,toolId:r}of Xe(n))for(let l of a)i(l,r);return e}function It(){return D.filter(n=>n.isInstalled()).map(n=>n.id)}function me(n){let t=[];for(let e of D)if(e.isInstalled())for(let s of[...e.paths,...e.agentPaths])(0,h.existsSync)(s.baseDir)&&t.push(s.baseDir);if(n?.projectScanEnabled){let e=ue(n),s=new Set(["node_modules",".Trash","Library","Applications","Music","Movies","Pictures","Public"]);try{for(let i of(0,h.readdirSync)(e,{withFileTypes:!0})){if(!i.isDirectory()&&!i.isSymbolicLink()||s.has(i.name))continue;let a=(0,f.join)(e,i.name);for(let r of[".claude/skills",".claude/commands",".claude/agents",".cursor/skills",".codex/skills"]){let l=(0,f.join)(a,r);(0,h.existsSync)(l)&&t.push(l)}}}catch{}}return t}var At={};for(let[n,t]of Object.entries(it))At[t]||(At[t]=n);var _t=(0,ge.join)((0,fe.homedir)(),".skillkit","install-prefs.json"),V=null,ot=!0;function ts(){if(!V&&(0,J.existsSync)(_t))try{let n=JSON.parse((0,J.readFileSync)(_t,"utf-8"));V=new Set(n.agents||[]),ot=n.global??!0}catch{}}function es(){try{(0,J.writeFileSync)(_t,JSON.stringify({agents:V?[...V]:[],global:ot}),"utf-8")}catch{}}ts();var lt=class extends T.Modal{skill;settings;onInstalled;selectedAgents;isGlobal;constructor(t,e,s,i){if(super(t),this.skill=e,this.settings=s,this.onInstalled=i,V)this.selectedAgents=new Set(V);else{this.selectedAgents=new Set;let a=It();for(let r of a){let l=it[r];l&&this.selectedAgents.add(l)}}this.isGlobal=ot}onOpen(){let{contentEl:t}=this;t.addClass("as-install-modal"),t.createEl("h3",{text:`Install ${this.skill.name}`}),t.createEl("p",{cls:"as-install-source",text:this.skill.source}),new T.Setting(t).setName("Install globally").setDesc("Shared across all projects (~/.agents/skills/)").addToggle(o=>o.setValue(this.isGlobal).onChange(c=>{this.isGlobal=c})),new T.Setting(t).setName("Agents").setHeading();let e=t.createDiv("as-install-scroll"),s=It(),i=new Set(s.map(o=>it[o]).filter(Boolean));for(let o of ee){let c=i.has(o.id),d=At[o.id],g=new T.Setting(e).addToggle(ft=>ft.setValue(this.selectedAgents.has(o.id)).onChange(xe=>{xe?this.selectedAgents.add(o.id):this.selectedAgents.delete(o.id)})).nameEl,m=d&&C[d]?d:C[o.id]?o.id:C[o.id+"-code"]?o.id+"-code":C[o.id+"-cli"]?o.id+"-cli":null,z=g.createSpan("as-install-agent-icon");m?j(z,m,14):z.addClass("as-install-agent-placeholder"),g.createSpan({text:o.label}),c&&g.createSpan({cls:"as-install-detected",text:"detected"})}let a=t.createDiv("as-install-footer");a.createEl("button",{text:"Cancel"}).addEventListener("click",()=>this.close());let l=a.createEl("button",{cls:"mod-cta",text:"Install"});l.addEventListener("click",()=>this.doInstall(l))}doInstall(t){let e=[...this.selectedAgents];if(e.length===0){new T.Notice("Select at least one agent",5e3);return}V=new Set(this.selectedAgents),ot=this.isGlobal,es(),this.close(),new T.Notice(`Installing ${this.skill.name}...`,3e3),ie(this.skill.source,e,{runner:this.settings.packageRunner,global:this.isGlobal}).then(s=>{s.success?(new T.Notice(`Installed ${this.skill.name}`,5e3),this.skill.installed=!0,this.onInstalled()):new T.Notice(`Failed to install ${this.skill.name}`,5e3)})}onClose(){this.contentEl.empty()}};var $t=(0,ve.join)((0,be.homedir)(),".skillkit","marketplace-popular.json"),P=null,ct="",B=null,ss=new M.Component;function is(){if(!P&&(0,Z.existsSync)($t))try{let n=JSON.parse((0,Z.readFileSync)($t,"utf-8"));P=nt(n)}catch{}}function ns(){if(P)try{(0,Z.writeFileSync)($t,JSON.stringify(P),"utf-8")}catch{}}is();var dt=class{containerEl;inputEl=null;listEl=null;previewEl=null;searchTimer=null;selectedSkill=null;app;settings;onRefresh;constructor(t,e,s,i){this.containerEl=t,this.app=e.app,this.settings=s,this.onRefresh=i}render(){if(!this.inputEl){this.containerEl.empty(),this.containerEl.addClass("as-marketplace");let t=this.containerEl.createDiv("as-mp-search");this.inputEl=t.createEl("input",{type:"text",placeholder:"Search skills on skills.sh...",cls:"as-mp-search-input"}),this.inputEl.addEventListener("input",()=>{this.searchTimer&&clearTimeout(this.searchTimer),this.searchTimer=setTimeout(()=>{this.doSearch(this.inputEl.value)},300)});let e=this.containerEl.createDiv("as-mp-body");this.listEl=e.createDiv("as-mp-list"),this.previewEl=e.createDiv("as-mp-preview"),this.previewEl.createDiv({cls:"as-mp-hint",text:"Select a skill to preview."})}this.inputEl.value=ct,ct.length>=2&&B?this.showResults(B):P?this.showPopular():this.loadPopular()}async loadPopular(){if(!this.listEl)return;this.listEl.empty(),this.listEl.createDiv({cls:"as-mp-loading",text:"Loading popular skills..."}),P=await te(),ns(),this.showPopular()}refreshList(){P&&nt(P),B&&nt(B),ct.length>=2&&B?this.showResults(B):this.showPopular()}showPopular(){if(this.listEl){if(this.listEl.empty(),!P||P.length===0){this.listEl.createDiv({cls:"as-mp-hint",text:"Search for skills to browse and install."});return}this.listEl.createDiv({cls:"as-mp-section-title",text:"Popular"});for(let t of P)this.renderSkillCard(t)}}showResults(t){if(this.listEl){if(this.listEl.empty(),t.length===0){this.listEl.createDiv({cls:"as-mp-hint",text:"No skills found."});return}for(let e of t)this.renderSkillCard(e)}}async doSearch(t){if(!this.listEl)return;if(ct=t,t.length<2){B=null,this.showPopular();return}this.listEl.empty(),this.listEl.createDiv({cls:"as-mp-loading",text:"Searching..."});let e=await Dt(t);B=e,this.showResults(e)}renderSkillCard(t){if(!this.listEl)return;let e=this.listEl.createDiv("as-mp-card");this.selectedSkill?.id===t.id&&e.addClass("is-selected");let s=e.createDiv("as-mp-card-header");s.createSpan({cls:"as-mp-card-name",text:t.name}),t.installed&&s.createSpan({cls:"as-mp-installed-badge",text:"Installed"}),e.createDiv({cls:"as-mp-card-source",text:t.source});let i=e.createDiv("as-mp-card-meta"),a=i.createSpan("as-mp-dl-icon");(0,M.setIcon)(a,"download"),i.createSpan({cls:"as-mp-card-installs",text:Lt(t.installs)}),e.addEventListener("click",()=>{this.selectedSkill=t,this.listEl&&this.listEl.querySelectorAll(".as-mp-card").forEach(r=>r.removeClass("is-selected")),e.addClass("is-selected"),this.showPreview(t)})}async showPreview(t){if(!this.previewEl)return;this.previewEl.empty();let s=this.previewEl.createDiv("as-mp-preview-header").createDiv("as-mp-preview-top"),i=s.createDiv("as-mp-preview-left");i.createDiv({cls:"as-mp-preview-name",text:t.name});let a=i.createDiv("as-mp-preview-meta");a.createSpan({cls:"as-mp-preview-source",text:t.source});let r=a.createSpan("as-mp-dl-icon");(0,M.setIcon)(r,"download"),a.createSpan({cls:"as-mp-preview-installs",text:Lt(t.installs)});let l=s.createDiv("as-mp-preview-right");if(!t.installed)this.renderInstallButton(l,t);else{l.createSpan({cls:"as-mp-installed-label",text:"Installed"});let d=l.createEl("button",{cls:"as-mp-uninstall-btn",text:"Uninstall"});d.addEventListener("click",()=>{N(this.app,"Uninstall skill",`Remove "${t.name}" from all agents?`,()=>{d.setText("Removing..."),d.disabled=!0,new M.Notice(`Removing ${t.name}...`,3e3),ne(t.name,this.settings.packageRunner).then(b=>{b.success?(new M.Notice(`Removed ${t.name}`,5e3),t.installed=!1,this.refreshList(),this.showPreview(t)):(new M.Notice(`Failed to remove ${t.name}`,5e3),d.setText("Uninstall"),d.disabled=!1)})})})}let o=this.previewEl.createDiv("as-mp-preview-content");o.createDiv({cls:"as-mp-loading",text:"Loading skill content..."});let c=await Xt(t.source,t.name,t.id);if(o.empty(),c){t.content=c;let d=o.createDiv("as-mp-rendered markdown-rendered");M.MarkdownRenderer.render(this.app,c,d,"",ss)}else o.createDiv({cls:"as-mp-hint",text:"Could not load skill content."})}renderInstallButton(t,e){t.createEl("button",{cls:"as-mp-install-btn",text:"Install"}).addEventListener("click",()=>{new lt(this.app,e,this.settings,()=>{this.refreshList(),this.showPreview(e)}).open()})}};var X="agentfiles-view",pt=class extends ke.ItemView{store;settings;saveSettings;sidebarPanel;listPanel;detailPanel;dashboardPanel;marketplacePanel;sidebarEl;listEl;detailEl;dashboardEl;marketplaceEl;isDashboard=!1;isMarketplace=!1;updateRef=null;constructor(t,e,s,i){super(t),this.store=e,this.settings=s,this.saveSettings=i}getViewType(){return X}getDisplayText(){return"Agentfiles"}getIcon(){return"cpu"}onOpen(){let t=this.contentEl;t.empty(),t.addClass("as-container"),this.sidebarEl=t.createDiv("as-panel as-panel-sidebar"),this.listEl=t.createDiv("as-panel as-panel-list"),this.detailEl=t.createDiv("as-panel as-panel-detail"),this.dashboardEl=t.createDiv("as-panel as-panel-dashboard as-hidden"),this.marketplaceEl=t.createDiv("as-panel as-panel-marketplace as-hidden"),this.sidebarPanel=new tt(this.sidebarEl,this.store,()=>this.toggleDashboard(),()=>this.toggleMarketplace()),this.listPanel=new et(this.listEl,this.store,e=>this.onSelectItem(e)),this.detailPanel=new st(this.detailEl,this.store,this.settings,this.saveSettings,this),this.dashboardPanel=new at(this.dashboardEl,this.app),this.marketplacePanel=new dt(this.marketplaceEl,this,this.settings,()=>{this.store.refresh(this.settings)}),this.updateRef=this.store.on("updated",()=>this.renderAll()),this.renderAll()}toggleDashboard(){this.isDashboard=!this.isDashboard,this.isMarketplace&&(this.isMarketplace=!1,this.marketplaceEl.addClass("as-hidden")),this.isDashboard?(this.listEl.addClass("as-hidden"),this.detailEl.addClass("as-hidden"),this.dashboardEl.removeClass("as-hidden"),this.dashboardPanel.render()):(this.listEl.removeClass("as-hidden"),this.detailEl.removeClass("as-hidden"),this.dashboardEl.addClass("as-hidden")),this.sidebarPanel.setDashboardActive(this.isDashboard),this.sidebarPanel.render()}toggleMarketplace(){this.isMarketplace=!this.isMarketplace,this.isDashboard&&(this.isDashboard=!1,this.dashboardEl.addClass("as-hidden")),this.isMarketplace?(this.listEl.addClass("as-hidden"),this.detailEl.addClass("as-hidden"),this.marketplaceEl.removeClass("as-hidden"),this.marketplacePanel.render()):(this.listEl.removeClass("as-hidden"),this.detailEl.removeClass("as-hidden"),this.marketplaceEl.addClass("as-hidden")),this.sidebarPanel.setMarketplaceActive(this.isMarketplace),this.sidebarPanel.render()}renderAll(){this.sidebarPanel.render(),!this.isDashboard&&!this.isMarketplace&&(this.listPanel.render(),this.store.filteredItems.length||this.detailPanel.clear())}onSelectItem(t){this.isDashboard&&this.toggleDashboard(),this.isMarketplace&&this.toggleMarketplace(),this.listPanel.setSelected(t.id),this.listPanel.render(),this.detailPanel.show(t)}onClose(){this.updateRef&&this.store.offref(this.updateRef)}};var Se=require("obsidian");var ut=class extends Se.Events{items=new Map;_filter={kind:"all"};_searchQuery="";_projectsHomeDir="";get filter(){return this._filter}get searchQuery(){return this._searchQuery}get allItems(){return Array.from(this.items.values())}get filteredItems(){let t=this.allItems;switch(this._filter.kind){case"favorites":t=t.filter(e=>e.isFavorite);break;case"tool":t=t.filter(e=>e.tools.includes(this._filter.toolId));break;case"type":t=t.filter(e=>e.type===this._filter.type);break;case"collection":t=t.filter(e=>e.collections.includes(this._filter.name));break;case"project":t=t.filter(e=>Mt(e.filePath,this._projectsHomeDir)===this._filter.project);break}if(this._searchQuery){let e=this._searchQuery.toLowerCase();t=t.filter(s=>s.name.toLowerCase().includes(e))}return t.sort((e,s)=>e.name.localeCompare(s.name))}getItem(t){return this.items.get(t)}get hasSkillkit(){return L()}refresh(t){this._projectsHomeDir=t.projectsHomeDir,this.items=he(t),this.enrichWithSkillkit(),this.trigger("updated")}enrichWithSkillkit(){if(!L())return;let t=Bt(),e=Nt(),s=zt(),i=new Set(s.oversized.map(o=>o.name)),a=new Set(s.longDesc.map(o=>o.name)),r=new Map(s.oversized.map(o=>[o.name,o.lines])),l=new Map(s.longDesc.map(o=>[o.name,o.chars]));for(let o of this.items.values()){let c=o.filePath.split("/").slice(-2,-1)[0],d=o.name.toLowerCase().replace(/\s+/g,"-"),b=t.get(o.name)||t.get(c)||t.get(d);b?(b.isHeavy=o.content.length>5e3,o.usage=b):o.usage={uses:0,lastUsed:null,daysSinceUsed:null,isStale:!0,isHeavy:o.content.length>5e3};let g=o.content.split(` +`).length,m=o.description.length;o.warnings={oversized:i.has(o.name)||g>500,longDesc:a.has(o.name)||m>1024,lineCount:r.get(o.name)??g,descChars:l.get(o.name)??m},o.conflicts=e.get(o.name)||e.get(c)||[]}}setFilter(t){this._filter=t,this.trigger("updated")}setSearch(t){this._searchQuery=t,this.trigger("updated")}toggleFavorite(t,e){let s=this.items.get(t);s&&(s.isFavorite=!s.isFavorite,s.isFavorite?e.favorites.includes(t)||e.favorites.push(t):e.favorites=e.favorites.filter(i=>i!==t),this.trigger("updated"))}getToolCounts(){let t=new Map;for(let e of this.items.values())for(let s of e.tools)t.set(s,(t.get(s)||0)+1);return t}getTypeCounts(){let t=new Map;for(let e of this.items.values())t.set(e.type,(t.get(e.type)||0)+1);return t}getProjectCounts(){let t=new Map;for(let e of this.items.values()){let s=Mt(e.filePath,this._projectsHomeDir);t.set(s,(t.get(s)||0)+1)}return t}};var ye=require("fs"),ht=class{watchers=[];debounceTimer=null;debounceMs;onChange;constructor(t,e){this.debounceMs=t,this.onChange=e}watchPaths(t){this.close();for(let e of t)try{let s=(0,ye.watch)(e,{recursive:!0},()=>this.scheduleUpdate());this.watchers.push(s)}catch{}}scheduleUpdate(){this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.onChange()},this.debounceMs)}close(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null);for(let t of this.watchers)try{t.close()}catch{}this.watchers=[]}};var E=require("obsidian");var mt=class extends E.PluginSettingTab{plugin;constructor(t,e){super(t,e),this.plugin=e}display(){let{containerEl:t}=this;t.empty(),new E.Setting(t).setName("File watching").setDesc("Automatically detect changes to skill files").addToggle(e=>e.setValue(this.plugin.settings.watchEnabled).onChange(async s=>{this.plugin.settings.watchEnabled=s,await this.plugin.saveSettings(),this.plugin.restartWatcher()})),new E.Setting(t).setName("Watch debounce (ms)").setDesc("Delay before re-scanning after file changes").addText(e=>e.setValue(String(this.plugin.settings.watchDebounceMs)).onChange(async s=>{let i=parseInt(s);!isNaN(i)&&i>=100&&(this.plugin.settings.watchDebounceMs=i,await this.plugin.saveSettings())})),new E.Setting(t).setName("Display names").setDesc("How skill and command names are displayed in the list").addDropdown(e=>e.addOptions({auto:"Auto (frontmatter / heading / filename)",filename:"Filename only"}).setValue(this.plugin.settings.namingMode||"auto").onChange(async s=>{this.plugin.settings.namingMode=s,await this.plugin.saveSettings(),this.plugin.refreshStore()})),new E.Setting(t).setName("Marketplace").setHeading(),new E.Setting(t).setName("Package runner").setDesc("Command used to install skills from the marketplace").addDropdown(e=>e.addOptions({auto:"Auto-detect",npx:"npx",bunx:"bunx"}).setValue(this.plugin.settings.packageRunner).onChange(async s=>{this.plugin.settings.packageRunner=s,await this.plugin.saveSettings()})),new E.Setting(t).setName("Project scanning").setHeading(),new E.Setting(t).setName("Scan projects").setDesc("Scan all directories under the projects home folder for project-level skills").addToggle(e=>e.setValue(this.plugin.settings.projectScanEnabled).onChange(async s=>{this.plugin.settings.projectScanEnabled=s,await this.plugin.saveSettings(),this.plugin.refreshStore(),this.plugin.restartWatcher()})),new E.Setting(t).setName("Projects home directory").setDesc("Root directory to scan for project-level skills. Leave empty for home directory (~).").addText(e=>e.setPlaceholder("~").setValue(this.plugin.settings.projectsHomeDir).onChange(async s=>{this.plugin.settings.projectsHomeDir=s,await this.plugin.saveSettings(),this.plugin.refreshStore(),this.plugin.restartWatcher()})),new E.Setting(t).setName("Tools").setHeading();for(let e of D){let s=e.isInstalled(),i=this.plugin.settings.tools[e.id]||{enabled:!0,customPaths:[]};new E.Setting(t).setName(e.name).setDesc(s?"Installed":"Not detected").addToggle(a=>a.setValue(s&&i.enabled).setDisabled(!s).onChange(async r=>{this.plugin.settings.tools[e.id]={...i,enabled:r},await this.plugin.saveSettings(),this.plugin.refreshStore()}))}}};var Ht={tools:{},watchEnabled:!0,watchDebounceMs:500,favorites:[],collections:{},customScanPaths:[],namingMode:"auto",projectScanEnabled:!0,projectsHomeDir:"",packageRunner:"auto"};var gt=class extends we.Plugin{settings=Ht;store=new ut;watcher=null;async onload(){await this.loadSettings(),this.addVaultPath(),this.registerView(X,t=>new pt(t,this.store,this.settings,()=>this.saveSettings())),this.addRibbonIcon("cpu","Agentfiles",()=>this.activateView()),this.addCommand({id:"open",name:"Open",callback:()=>this.activateView()}),this.addSettingTab(new mt(this.app,this)),this.refreshStore(),this.startWatcher()}addVaultPath(){let t=this.app.vault.adapter;if(!t.getBasePath)return;let e=t.getBasePath();this.settings.customScanPaths.includes(e)||this.settings.customScanPaths.push(e)}onunload(){this.stopWatcher()}refreshStore(){this.store.refresh(this.settings)}startWatcher(){this.settings.watchEnabled&&(this.watcher=new ht(this.settings.watchDebounceMs,()=>this.refreshStore()),this.watcher.watchPaths(me(this.settings)))}stopWatcher(){this.watcher&&(this.watcher.close(),this.watcher=null)}restartWatcher(){this.stopWatcher(),this.startWatcher()}async activateView(){let t=this.app.workspace.getLeavesOfType(X);if(t.length>0){await this.app.workspace.revealLeaf(t[0]);return}let e=this.app.workspace.getLeaf("tab");await e.setViewState({type:X,active:!0}),await this.app.workspace.revealLeaf(e)}async loadSettings(){this.settings=Object.assign({},Ht,await this.loadData())}async saveSettings(){await this.saveData(this.settings)}}; diff --git a/src/scanner.ts b/src/scanner.ts index 084b91b..e5c84ca 100644 --- a/src/scanner.ts +++ b/src/scanner.ts @@ -10,7 +10,7 @@ import { homedir } from "os"; import { parseYaml } from "obsidian"; import { createHash } from "crypto"; import { TOOL_CONFIGS } from "./tool-configs"; -import type { SkillItem, SkillPath, SkillType, ChopsSettings, ToolConfig } from "./types"; +import type { SkillItem, SkillPath, SkillType, NamingMode, ScanPattern, ChopsSettings, ToolConfig } from "./types"; const IGNORED_FILES = new Set([ "readme.md", @@ -48,23 +48,25 @@ function extractName( frontmatter: Record, content: string, filePath: string, - pattern: ScanPattern + namingMode: NamingMode = "auto" ): string { - if (typeof frontmatter.name === "string" && frontmatter.name) { - return frontmatter.name; + if (namingMode === "auto") { + if (typeof frontmatter.name === "string" && frontmatter.name) { + return frontmatter.name; + } + const h1 = content.match(/^#\s+(.+)$/m); + if (h1) return h1[1].trim(); } const name = basename(filePath, extname(filePath)); if (name === "SKILL") return basename(join(filePath, "..")); - if (pattern === "flat-md" || pattern === "mdc") return name; - const h1 = content.match(/^#\s+(.+)$/m); - if (h1) return h1[1].trim(); return name; } function scanDirectoryWithSkillMd( baseDir: string, type: SkillType, - toolId: string + toolId: string, + namingMode: NamingMode = "auto" ): SkillItem[] { if (!existsSync(baseDir)) return []; const items: SkillItem[] = []; @@ -76,7 +78,7 @@ function scanDirectoryWithSkillMd( const skillFile = join(fullPath, "SKILL.md"); if (!existsSync(skillFile)) continue; - const item = parseSkillFile(skillFile, type, toolId); + const item = parseSkillFile(skillFile, type, toolId, "directory-with-skillmd", namingMode); if (item) items.push(item); } return items; @@ -85,7 +87,8 @@ function scanDirectoryWithSkillMd( function scanFlatMd( baseDir: string, type: SkillType, - toolId: string + toolId: string, + namingMode: NamingMode = "auto" ): SkillItem[] { if (!existsSync(baseDir)) return []; const items: SkillItem[] = []; @@ -97,7 +100,7 @@ function scanFlatMd( if (isDir) { const skillFile = join(fullPath, "SKILL.md"); if (existsSync(skillFile)) { - const item = parseSkillFile(skillFile, type, toolId); + const item = parseSkillFile(skillFile, type, toolId, "flat-md", namingMode); if (item) items.push(item); continue; } @@ -112,7 +115,9 @@ function scanFlatMd( const item = parseSkillFile( join(fullPath, preferred), type, - toolId + toolId, + "flat-md", + namingMode ); if (item) items.push(item); } @@ -121,7 +126,7 @@ function scanFlatMd( const fname = entry.name.toLowerCase(); if (!fname.endsWith(".md") || IGNORED_FILES.has(fname)) continue; - const item = parseSkillFile(fullPath, type, toolId, "flat-md"); + const item = parseSkillFile(fullPath, type, toolId, "flat-md", namingMode); if (item) items.push(item); } return items; @@ -130,7 +135,8 @@ function scanFlatMd( function scanMdc( baseDir: string, type: SkillType, - toolId: string + toolId: string, + namingMode: NamingMode = "auto" ): SkillItem[] { if (!existsSync(baseDir)) return []; const items: SkillItem[] = []; @@ -138,7 +144,7 @@ function scanMdc( for (const entry of readdirSync(baseDir, { withFileTypes: true })) { if (!entry.name.endsWith(".mdc") && !entry.name.endsWith(".md")) continue; if (entry.isDirectory()) continue; - const item = parseSkillFile(join(baseDir, entry.name), type, toolId, "mdc"); + const item = parseSkillFile(join(baseDir, entry.name), type, toolId, "mdc", namingMode); if (item) items.push(item); } return items; @@ -148,13 +154,14 @@ function parseSkillFile( filePath: string, type: SkillType, toolId: string, - pattern: ScanPattern = "directory-with-skillmd" + pattern: ScanPattern = "directory-with-skillmd", + namingMode: NamingMode = "auto" ): SkillItem | null { try { const raw = readFileSync(filePath, "utf-8"); const stat = statSync(filePath); const { frontmatter, content } = parseFrontmatter(raw); - const name = extractName(frontmatter, content, filePath, pattern); + const name = extractName(frontmatter, content, filePath, namingMode); const description = typeof frontmatter.description === "string" ? frontmatter.description @@ -188,14 +195,14 @@ function parseSkillFile( } } -function scanPath(sp: SkillPath, toolId: string): SkillItem[] { +function scanPath(sp: SkillPath, toolId: string, namingMode: NamingMode = "auto"): SkillItem[] { switch (sp.pattern) { case "directory-with-skillmd": - return scanDirectoryWithSkillMd(sp.baseDir, sp.type, toolId); + return scanDirectoryWithSkillMd(sp.baseDir, sp.type, toolId, namingMode); case "flat-md": - return scanFlatMd(sp.baseDir, sp.type, toolId); + return scanFlatMd(sp.baseDir, sp.type, toolId, namingMode); case "mdc": - return scanMdc(sp.baseDir, sp.type, toolId); + return scanMdc(sp.baseDir, sp.type, toolId, namingMode); } } @@ -276,6 +283,7 @@ export function getProjectName(filePath: string, projectsHomeDir: string): strin } export function scanAll(settings: ChopsSettings): Map { + const namingMode = settings.namingMode || "auto"; const items = new Map(); const nameMap = new Map(); @@ -314,7 +322,7 @@ export function scanAll(settings: ChopsSettings): Map { const allPaths = [...tool.paths, ...tool.agentPaths]; for (const sp of allPaths) { - for (const item of scanPath(sp, tool.id)) { + for (const item of scanPath(sp, tool.id, namingMode)) { addItem(item, tool.id); } } diff --git a/src/settings.ts b/src/settings.ts index 892e5d5..455617d 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -42,6 +42,23 @@ export class AgentfilesSettingTab extends PluginSettingTab { }) ); + new Setting(containerEl) + .setName("Display names") + .setDesc("How skill and command names are displayed in the list") + .addDropdown((drop) => + drop + .addOptions({ + auto: "Auto (frontmatter / heading / filename)", + filename: "Filename only", + }) + .setValue(this.plugin.settings.namingMode || "auto") + .onChange(async (value) => { + this.plugin.settings.namingMode = value as "auto" | "filename"; + await this.plugin.saveSettings(); + this.plugin.refreshStore(); + }) + ); + new Setting(containerEl).setName("Marketplace").setHeading(); new Setting(containerEl) diff --git a/src/types.ts b/src/types.ts index 8c56c95..688af70 100644 --- a/src/types.ts +++ b/src/types.ts @@ -66,6 +66,8 @@ export type SidebarFilter = | { kind: "collection"; name: string } | { kind: "project"; project: string }; +export type NamingMode = "auto" | "filename"; + export interface ChopsSettings { tools: Record; watchEnabled: boolean; @@ -73,6 +75,7 @@ export interface ChopsSettings { favorites: string[]; collections: Record; customScanPaths: string[]; + namingMode: NamingMode; projectScanEnabled: boolean; projectsHomeDir: string; packageRunner: "auto" | "npx" | "bunx"; @@ -85,6 +88,7 @@ export const DEFAULT_SETTINGS: ChopsSettings = { favorites: [], collections: {}, customScanPaths: [], + namingMode: "auto", projectScanEnabled: true, projectsHomeDir: "", packageRunner: "auto", diff --git a/styles.css b/styles.css index 13131b8..23ac23c 100644 --- a/styles.css +++ b/styles.css @@ -165,8 +165,8 @@ .as-skill-header { display: flex; - align-items: center; - gap: 4px; + align-items: baseline; + gap: 6px; } .as-skill-name { @@ -174,6 +174,7 @@ font-weight: 500; color: var(--text-normal); flex: 1; + min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;