diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f008844 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Railly Hugo + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..4fa1a8c --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +# Agentfiles + +Discover, organize, and edit AI agent skills, commands, and agents across Claude Code, Cursor, Codex, Windsurf, and more — from inside Obsidian. + +## Features + +- **Multi-tool discovery** — Scans 13 tools: Claude Code, Cursor, Windsurf, Codex, Copilot, Amp, OpenCode, Aider, and more +- **Three-column view** — Sidebar filters, skill list with search, and detail panel with markdown preview +- **Built-in editor** — Edit skills in place with Cmd+S save +- **Real-time file watching** — Automatically detects changes to skill files +- **Full-text search** — Search across skill names, descriptions, and content +- **Frontmatter metadata** — View parsed YAML properties at a glance +- **Token estimation** — See character count and estimated token usage per skill +- **Tool logos** — Real SVG logos for each supported coding agent +- **Favorites & collections** — Organize skills your way +- **Symlink deduplication** — Same skill installed in multiple tools shows once + +## Supported tools + +| Tool | Skills | Commands | Agents | +|------|--------|----------|--------| +| Claude Code | `~/.claude/skills/` | `~/.claude/commands/` | `~/.claude/agents/` | +| Cursor | `~/.cursor/skills/` | | `~/.cursor/agents/` | +| Codex | `~/.codex/skills/` | | `~/.codex/agents/` | +| Windsurf | `~/.codeium/windsurf/memories/` | | | +| Copilot | `~/.copilot/skills/` | | | +| Amp | `~/.config/amp/skills/` | | | +| OpenCode | `~/.config/opencode/skills/` | | | +| Global | `~/.agents/skills/` | | | + +## Installation + +Search **Agentfiles** in Obsidian's Community plugins browser, or install manually: + +1. Download `main.js`, `manifest.json`, and `styles.css` from the [latest release](https://github.com/Railly/obsidian-agent-skills/releases) +2. Create `~/.obsidian/plugins/agentfiles/` in your vault +3. Copy the three files into that folder +4. Enable the plugin in Settings > Community plugins + +## Usage + +1. Click the CPU icon in the ribbon, or run **Agentfiles: Open Agentfiles** from the command palette +2. Browse skills by tool or type in the sidebar +3. Click any skill to preview its content +4. Click the pencil icon to edit, Cmd+S to save + +## Desktop only + +This plugin requires desktop Obsidian (macOS, Windows, Linux) because it reads files outside your vault. + +## License + +MIT diff --git a/main.js b/main.js index 025a0e5..1b3371a 100644 --- a/main.js +++ b/main.js @@ -1 +1 @@ -var W=Object.defineProperty;var et=Object.getOwnPropertyDescriptor;var it=Object.getOwnPropertyNames;var st=Object.prototype.hasOwnProperty;var nt=(n,t)=>{for(var e in t)W(n,e,{get:t[e],enumerable:!0})},rt=(n,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of it(t))!st.call(n,s)&&s!==e&&W(n,s,{get:()=>t[s],enumerable:!(i=et(t,s))||i.enumerable});return n};var ot=n=>rt(W({},"__esModule",{value:!0}),n);var vt={};nt(vt,{default:()=>_});module.exports=ot(vt);var J=require("obsidian");var R=require("obsidian");var L=require("obsidian");var G=require("os"),m=require("fs"),a=require("path"),l=(0,G.homedir)(),b=process.env.XDG_CONFIG_HOME||(0,a.join)(l,".config");function C(n){return(0,m.existsSync)(`/Applications/${n}.app`)||(0,m.existsSync)((0,a.join)(l,"Applications",`${n}.app`))}function v(n){let t=[`/usr/local/bin/${n}`,`/opt/homebrew/bin/${n}`,(0,a.join)(l,".local","bin",n)];for(let i of t)if((0,m.existsSync)(i))return!0;let e=(0,a.join)(l,".nvm","versions","node");try{let{readdirSync:i}=require("fs");for(let s of i(e))if((0,m.existsSync)((0,a.join)(e,s,"bin",n)))return!0}catch{}return!1}var g=[{id:"claude-code",name:"Claude Code",color:"#f97316",icon:"brain",paths:[{baseDir:(0,a.join)(l,".claude","skills"),type:"skill",pattern:"directory-with-skillmd"},{baseDir:(0,a.join)(l,".claude","commands"),type:"command",pattern:"flat-md"}],agentPaths:[{baseDir:(0,a.join)(l,".claude","agents"),type:"agent",pattern:"flat-md"}],isInstalled:()=>(0,m.existsSync)((0,a.join)(l,".claude","settings.json"))||(0,m.existsSync)((0,a.join)(l,".claude","CLAUDE.md"))||v("claude")},{id:"cursor",name:"Cursor",color:"#3b82f6",icon:"mouse-pointer",paths:[{baseDir:(0,a.join)(l,".cursor","skills"),type:"skill",pattern:"directory-with-skillmd"},{baseDir:(0,a.join)(l,".cursor","rules"),type:"rule",pattern:"flat-md"}],agentPaths:[{baseDir:(0,a.join)(l,".cursor","agents"),type:"agent",pattern:"flat-md"}],isInstalled:()=>C("Cursor")||(0,m.existsSync)((0,a.join)(l,".cursor","argv.json"))},{id:"windsurf",name:"Windsurf",color:"#14b8a6",icon:"wind",paths:[{baseDir:(0,a.join)(l,".codeium","windsurf","memories"),type:"memory",pattern:"flat-md"},{baseDir:(0,a.join)(l,".windsurf","rules"),type:"rule",pattern:"flat-md"}],agentPaths:[],isInstalled:()=>C("Windsurf")||(0,m.existsSync)((0,a.join)(l,".codeium","windsurf","argv.json"))},{id:"codex",name:"Codex",color:"#22c55e",icon:"book",paths:[{baseDir:(0,a.join)(l,".codex","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[{baseDir:(0,a.join)(l,".codex","agents"),type:"agent",pattern:"flat-md"}],isInstalled:()=>(0,m.existsSync)((0,a.join)(l,".codex","config.toml"))||(0,m.existsSync)((0,a.join)(l,".codex","auth.json"))||v("codex")},{id:"copilot",name:"Copilot",color:"#a855f7",icon:"plane",paths:[{baseDir:(0,a.join)(l,".copilot","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>(0,m.existsSync)((0,a.join)(l,".copilot"))||v("copilot")},{id:"amp",name:"Amp",color:"#ec4899",icon:"zap",paths:[{baseDir:(0,a.join)(b,"amp","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>(0,m.existsSync)((0,a.join)(b,"amp","config.json"))||(0,m.existsSync)((0,a.join)(b,"amp","settings.json"))||v("amp")},{id:"opencode",name:"OpenCode",color:"#ef4444",icon:"terminal",paths:[{baseDir:(0,a.join)(b,"opencode","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>C("OpenCode")||(0,m.existsSync)((0,a.join)(b,"opencode","opencode.json"))||(0,m.existsSync)((0,a.join)(b,"opencode","opencode.jsonc"))||v("opencode")},{id:"pi",name:"Pi",color:"#06b6d4",icon:"sparkles",paths:[{baseDir:(0,a.join)(l,".pi","agent","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>v("pi")},{id:"antigravity",name:"Antigravity",color:"#ef4444",icon:"arrow-up-circle",paths:[{baseDir:(0,a.join)(l,".gemini","antigravity","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>C("Antigravity")||(0,m.existsSync)((0,a.join)(l,".gemini","antigravity","skills"))||v("antigravity")},{id:"claude-desktop",name:"Claude Desktop",color:"#f97316",icon:"monitor",paths:[],agentPaths:[],isInstalled:()=>C("Claude")},{id:"global-agents",name:"Global",color:"#a3e635",icon:"globe",paths:[{baseDir:(0,a.join)(l,".agents","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>(0,m.existsSync)((0,a.join)(l,".agents","skills"))},{id:"aider",name:"Aider",color:"#eab308",icon:"wrench",paths:[],agentPaths:[],isInstalled:()=>v("aider")}];var S={"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:''}};function k(n,t,e=16){let i=S[t];if(!i)return;let s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("viewBox",i.viewBox),s.setAttribute("width",String(e)),s.setAttribute("height",String(e)),s.setAttribute("fill","none"),s.classList.add("as-tool-svg"),s.innerHTML=i.paths,n.appendChild(s)}var P=class{containerEl;store;constructor(t,e){this.containerEl=t,this.store=e}render(){this.containerEl.empty(),this.containerEl.addClass("as-sidebar"),this.renderSection("Library",[{label:"All Skills",icon:"layers",filter:{kind:"all"}},{label:"Favorites",icon:"star",filter:{kind:"favorites"}}]),this.renderTypeSection(),this.renderToolSection(),this.renderCollectionSection()}renderSection(t,e){let i=this.containerEl.createDiv("as-sidebar-section");i.createDiv({cls:"as-sidebar-title",text:t});for(let s of e){let o=i.createDiv("as-sidebar-item");this.isActive(s.filter)&&o.addClass("is-active");let r=o.createSpan("as-sidebar-icon");(0,L.setIcon)(r,s.icon),o.createSpan({cls:"as-sidebar-label",text:s.label}),s.count!==void 0&&o.createSpan({cls:"as-sidebar-count",text:String(s.count)}),o.addEventListener("click",()=>{this.store.setFilter(s.filter)})}}renderTypeSection(){let t=this.store.getTypeCounts(),i=[{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(s=>t.has(s.type)).map(s=>({label:s.label,icon:s.icon,filter:{kind:"type",type:s.type},count:t.get(s.type)||0}));i.length>0&&this.renderSection("Types",i)}renderToolSection(){let t=this.store.getToolCounts(),e=g.filter(s=>s.isInstalled()&&t.has(s.id));if(e.length===0)return;let i=this.containerEl.createDiv("as-sidebar-section");i.createDiv({cls:"as-sidebar-title",text:"Tools"});for(let s of e){let o={kind:"tool",toolId:s.id},r=i.createDiv("as-sidebar-item");this.isActive(o)&&r.addClass("is-active");let d=r.createSpan("as-sidebar-icon");S[s.id]?k(d,s.id,14):(0,L.setIcon)(d,s.icon),r.createSpan({cls:"as-sidebar-label",text:s.name}),r.createSpan({cls:"as-sidebar-count",text:String(t.get(s.id)||0)}),r.addEventListener("click",()=>this.store.setFilter(o))}}renderCollectionSection(){let t=this.containerEl.createDiv("as-sidebar-section");t.createDiv({cls:"as-sidebar-title",text:"Collections"});let e=new Set;for(let i of this.store.allItems)for(let s of i.collections)e.add(s);if(e.size===0){t.createDiv({cls:"as-sidebar-empty",text:"No collections yet"});return}for(let i of e){let s={kind:"collection",name:i},o=t.createDiv("as-sidebar-item");this.isActive(s)&&o.addClass("is-active");let r=o.createSpan("as-sidebar-icon");(0,L.setIcon)(r,"folder"),o.createSpan({cls:"as-sidebar-label",text:i}),o.addEventListener("click",()=>this.store.setFilter(s))}}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:!0}};var z=require("obsidian");var F=class{containerEl;store;onSelect;selectedId=null;constructor(t,e,i){this.containerEl=t,this.store=e,this.onSelect=i}setSelected(t){this.selectedId=t}render(){this.containerEl.empty(),this.containerEl.addClass("as-list");let e=this.containerEl.createDiv("as-search").createEl("input",{type:"text",placeholder:"Search skills...",cls:"as-search-input"});e.value=this.store.searchQuery,e.addEventListener("input",()=>{this.store.setSearch(e.value)});let i=this.containerEl.createDiv("as-list-items"),s=this.store.filteredItems;if(s.length===0){i.createDiv({cls:"as-list-empty",text:"No skills found"});return}for(let o of s)this.renderCard(i,o)}renderCard(t,e){let i=t.createDiv("as-skill-card");e.id===this.selectedId&&i.addClass("is-selected");let s=i.createDiv("as-skill-header"),o=s.createSpan({cls:"as-skill-name",text:e.name});if(e.isFavorite){let p=s.createSpan("as-skill-star");(0,z.setIcon)(p,"star")}e.description&&i.createDiv({cls:"as-skill-desc",text:e.description.length>80?e.description.slice(0,80)+"...":e.description});let r=i.createDiv("as-skill-meta"),d=r.createSpan({cls:`as-type-tag as-type-${e.type}`,text:e.type});for(let p of e.tools){let c=g.find(N=>N.id===p);if(!c)continue;let h=r.createSpan("as-tool-badge");h.title=c.name,h.setAttribute("aria-label",c.name),S[p]?(h.style.color=c.color,k(h,p,12)):(h.style.backgroundColor=c.color,h.addClass("as-tool-badge-dot"))}i.addEventListener("click",()=>{this.selectedId=e.id,this.onSelect(e)})}};var y=require("obsidian"),j=require("fs");function at(n){return Math.ceil(n.length/4)}function lt(n){return n<1024?`${n} B`:n<1024*1024?`${(n/1024).toFixed(1)} KB`:`${(n/(1024*1024)).toFixed(1)} MB`}function $(n){return n>=1e3?`${(n/1e3).toFixed(1)}k`:String(n)}function ct(n){return new Date(n).toLocaleDateString(void 0,{month:"short",day:"numeric",year:"numeric"})}var M=class{containerEl;store;settings;saveSettings;currentItem=null;isEditing=!1;component;constructor(t,e,i,s,o){this.containerEl=t,this.store=e,this.settings=i,this.saveSettings=s,this.component=o}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"),i=e.createDiv("as-toolbar-top"),s=i.createDiv("as-toolbar-left");s.createSpan({cls:"as-detail-title",text:t.name});for(let E of t.tools){let T=g.find(tt=>tt.id===E);if(!T)continue;let D=s.createSpan("as-tool-name-badge");D.style.borderColor=T.color,D.style.color=T.color,S[E]&&k(D,E,12),D.createSpan({text:T.name})}let o=i.createDiv("as-toolbar-right"),r=o.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 d=o.createEl("button",{cls:"as-toolbar-btn",attr:{"aria-label":this.isEditing?"Preview":"Edit"}});(0,y.setIcon)(d,this.isEditing?"eye":"pencil"),d.addEventListener("click",()=>{this.isEditing=!this.isEditing,this.render()});let p=o.createEl("button",{cls:"as-toolbar-btn",attr:{"aria-label":"Open in Finder"}});(0,y.setIcon)(p,"folder-open"),p.addEventListener("click",()=>{let{shell:E}=require("electron");E.showItemInFolder(t.filePath)});let c=e.createDiv("as-detail-meta-bar"),h=at(t.content),N=t.content.length;c.createSpan({cls:"as-meta-item",text:lt(t.fileSize)}),c.createSpan({cls:"as-meta-item",text:`${$(N)} chars`}),c.createSpan({cls:"as-meta-item",text:`~${$(h)} tokens`}),c.createSpan({cls:"as-meta-item",text:ct(t.lastModified)}),c.createSpan({cls:"as-meta-item as-meta-type",text:t.type})}renderFrontmatter(t,e){let i=Object.keys(e.frontmatter);if(i.length===0)return;let s=t.createDiv("as-frontmatter");for(let o of i){let r=e.frontmatter[o];if(r==null)continue;let d=s.createDiv("as-fm-prop");d.createSpan({cls:"as-fm-key",text:o});let p=typeof r=="object"?JSON.stringify(r):String(r);p.length>200?d.createDiv({cls:"as-fm-value-long"}).setText(p):d.createSpan({cls:"as-fm-value"}).setText(p)}}renderPreview(t){let e=this.containerEl.createDiv("as-detail-body");this.renderFrontmatter(e,t);let i=e.createDiv("as-detail-preview markdown-rendered");y.MarkdownRenderer.render(this.component.app||globalThis.app,t.content,i,t.filePath,this.component)}renderEditor(t){let e=this.containerEl.createDiv("as-detail-body as-detail-body-editor"),i=e.createEl("textarea",{cls:"as-editor-textarea"});i.value=t.content,i.spellcheck=!1,i.addEventListener("keydown",r=>{if((r.metaKey||r.ctrlKey)&&r.key==="s"&&(r.preventDefault(),this.saveFile(t,i.value)),r.key==="Tab"){r.preventDefault();let d=i.selectionStart,p=i.selectionEnd;i.value=i.value.substring(0,d)+" "+i.value.substring(p),i.selectionStart=i.selectionEnd=d+1}});let s=e.createDiv("as-save-bar");s.createEl("button",{cls:"as-save-btn",text:"Save"}).addEventListener("click",()=>{this.saveFile(t,i.value)}),s.createSpan({cls:"as-save-hint",text:"Cmd+S to save"})}saveFile(t,e){try{(0,j.writeFileSync)(t.filePath,e,"utf-8"),t.content=e;let{Notice:i}=require("obsidian");new i(`Saved ${t.name}`)}catch(i){let{Notice:s}=require("obsidian");new s(`Failed to save: ${i instanceof Error?i.message:String(i)}`)}}};var I="agent-skills-view",O=class extends R.ItemView{store;settings;saveSettings;sidebarPanel;listPanel;detailPanel;sidebarEl;listEl;detailEl;constructor(t,e,i,s){super(t),this.store=e,this.settings=i,this.saveSettings=s}getViewType(){return I}getDisplayText(){return"Agent Skills"}getIcon(){return"cpu"}async 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.sidebarPanel=new P(this.sidebarEl,this.store),this.listPanel=new F(this.listEl,this.store,e=>this.onSelectItem(e)),this.detailPanel=new M(this.detailEl,this.store,this.settings,this.saveSettings,this),this.store.on("updated",()=>this.renderAll()),this.renderAll()}renderAll(){this.sidebarPanel.render(),this.listPanel.render(),this.store.filteredItems.length||this.detailPanel.clear()}onSelectItem(t){this.listPanel.setSelected(t.id),this.listPanel.render(),this.detailPanel.show(t)}async onClose(){this.store.offref(this.store.on("updated",()=>{}))}};var Y=require("obsidian");var u=require("fs"),f=require("path"),K=require("obsidian"),Q=require("crypto");var Z=new Set(["readme.md","license","license.md","changelog.md",".ds_store","thumbs.db"]);function dt(n){return(0,Q.createHash)("sha256").update(n).digest("hex").slice(0,12)}function pt(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,K.parseYaml)(t[1]);return{frontmatter:typeof e=="object"&&e?e:{},content:t[2]}}catch{return{frontmatter:{},content:n}}}function ht(n,t,e){if(typeof n.name=="string"&&n.name)return n.name;let i=t.match(/^#\s+(.+)$/m);if(i)return i[1].trim();let s=(0,f.basename)(e,(0,f.extname)(e));return s==="SKILL"?(0,f.basename)((0,f.join)(e,"..")):s}function mt(n,t,e){if(!(0,u.existsSync)(n))return[];let i=[];for(let s of(0,u.readdirSync)(n,{withFileTypes:!0})){if(!s.isDirectory())continue;let o=(0,f.join)(n,s.name,"SKILL.md");if(!(0,u.existsSync)(o))continue;let r=x(o,t,e);r&&i.push(r)}return i}function ut(n,t,e){if(!(0,u.existsSync)(n))return[];let i=[];for(let s of(0,u.readdirSync)(n,{withFileTypes:!0})){if(s.isDirectory()){let d=(0,f.join)(n,s.name,"SKILL.md");if((0,u.existsSync)(d)){let h=x(d,t,e);h&&i.push(h);continue}let p=(0,u.readdirSync)((0,f.join)(n,s.name)).filter(h=>h.endsWith(".md")&&!Z.has(h.toLowerCase())),c=p.find(h=>h.toLowerCase()===`${s.name.toLowerCase()}.md`)||p[0];if(c){let h=x((0,f.join)(n,s.name,c),t,e);h&&i.push(h)}continue}let o=s.name.toLowerCase();if(!o.endsWith(".md")||Z.has(o))continue;let r=x((0,f.join)(n,s.name),t,e);r&&i.push(r)}return i}function ft(n,t,e){if(!(0,u.existsSync)(n))return[];let i=[];for(let s of(0,u.readdirSync)(n,{withFileTypes:!0})){if(!s.name.endsWith(".mdc")&&!s.name.endsWith(".md")||s.isDirectory())continue;let o=x((0,f.join)(n,s.name),t,e);o&&i.push(o)}return i}function x(n,t,e){try{let i=(0,u.readFileSync)(n,"utf-8"),s=(0,u.statSync)(n),{frontmatter:o,content:r}=pt(i),d=ht(o,r,n),p=typeof o.description=="string"?o.description:"",c;try{c=(0,u.realpathSync)(n)}catch{c=n}return{id:dt(c),name:d,description:p,type:t,tools:[e],filePath:n,realPath:c,dirPath:(0,f.join)(n,".."),content:i,frontmatter:o,lastModified:s.mtimeMs,fileSize:s.size,isFavorite:!1,collections:[]}}catch{return null}}function gt(n,t){switch(n.pattern){case"directory-with-skillmd":return mt(n.baseDir,n.type,t);case"flat-md":return ut(n.baseDir,n.type,t);case"mdc":return ft(n.baseDir,n.type,t)}}function q(n){let t=new Map;for(let e of g){if(!e.isInstalled())continue;let i=n.tools[e.id];if(i&&!i.enabled)continue;let s=[...e.paths,...e.agentPaths];for(let o of s)for(let r of gt(o,e.id)){let d=t.get(r.id);if(d)d.tools.includes(e.id)||d.tools.push(e.id);else{r.isFavorite=n.favorites.includes(r.id);for(let[p,c]of Object.entries(n.collections))c.includes(r.id)&&r.collections.push(p);t.set(r.id,r)}}}return t}function U(){let n=[];for(let t of g)if(t.isInstalled())for(let e of[...t.paths,...t.agentPaths])(0,u.existsSync)(e.baseDir)&&n.push(e.baseDir);return n}var A=class extends Y.Events{items=new Map;_filter={kind:"all"};_searchQuery="";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}if(this._searchQuery){let e=this._searchQuery.toLowerCase();t=t.filter(i=>i.name.toLowerCase().includes(e)||i.description.toLowerCase().includes(e)||i.content.toLowerCase().includes(e))}return t.sort((e,i)=>e.name.localeCompare(i.name))}getItem(t){return this.items.get(t)}refresh(t){this.items=q(t),this.trigger("updated")}setFilter(t){this._filter=t,this.trigger("updated")}setSearch(t){this._searchQuery=t,this.trigger("updated")}toggleFavorite(t,e){let i=this.items.get(t);i&&(i.isFavorite=!i.isFavorite,i.isFavorite?e.favorites.includes(t)||e.favorites.push(t):e.favorites=e.favorites.filter(s=>s!==t),this.trigger("updated"))}getToolCounts(){let t=new Map;for(let e of this.items.values())for(let i of e.tools)t.set(i,(t.get(i)||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}};var X=require("fs"),H=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 i=(0,X.watch)(e,{recursive:!0},()=>this.scheduleUpdate());this.watchers.push(i)}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 w=require("obsidian");var V=class extends w.PluginSettingTab{plugin;constructor(t,e){super(t,e),this.plugin=e}display(){let{containerEl:t}=this;t.empty(),t.createEl("h2",{text:"Agent Skills"}),new w.Setting(t).setName("File watching").setDesc("Automatically detect changes to skill files").addToggle(e=>e.setValue(this.plugin.settings.watchEnabled).onChange(async i=>{this.plugin.settings.watchEnabled=i,await this.plugin.saveSettings(),this.plugin.restartWatcher()})),new w.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 i=>{let s=parseInt(i);!isNaN(s)&&s>=100&&(this.plugin.settings.watchDebounceMs=s,await this.plugin.saveSettings())})),t.createEl("h3",{text:"Tools"});for(let e of g){let i=e.isInstalled(),s=this.plugin.settings.tools[e.id]||{enabled:!0,customPaths:[]};new w.Setting(t).setName(e.name).setDesc(i?"Installed":"Not detected").addToggle(o=>o.setValue(i&&s.enabled).setDisabled(!i).onChange(async r=>{this.plugin.settings.tools[e.id]={...s,enabled:r},await this.plugin.saveSettings(),this.plugin.refreshStore()}))}}};var B={tools:{},watchEnabled:!0,watchDebounceMs:500,favorites:[],collections:{},customScanPaths:[]};var _=class extends J.Plugin{settings=B;store=new A;watcher=null;async onload(){await this.loadSettings(),this.registerView(I,t=>new O(t,this.store,this.settings,()=>this.saveSettings())),this.addRibbonIcon("cpu","Agent Skills",()=>this.activateView()),this.addCommand({id:"open-agent-skills",name:"Open Agent Skills",callback:()=>this.activateView()}),this.addSettingTab(new V(this.app,this)),this.refreshStore(),this.startWatcher()}onunload(){this.stopWatcher()}refreshStore(){this.store.refresh(this.settings)}startWatcher(){this.settings.watchEnabled&&(this.watcher=new H(this.settings.watchDebounceMs,()=>this.refreshStore()),this.watcher.watchPaths(U()))}stopWatcher(){this.watcher&&(this.watcher.close(),this.watcher=null)}restartWatcher(){this.stopWatcher(),this.startWatcher()}async activateView(){let t=this.app.workspace.getLeavesOfType(I);if(t.length>0){this.app.workspace.revealLeaf(t[0]);return}let e=this.app.workspace.getLeaf("tab");await e.setViewState({type:I,active:!0}),this.app.workspace.revealLeaf(e)}async loadSettings(){this.settings=Object.assign({},B,await this.loadData())}async saveSettings(){await this.saveData(this.settings)}}; +var W=Object.defineProperty;var et=Object.getOwnPropertyDescriptor;var it=Object.getOwnPropertyNames;var st=Object.prototype.hasOwnProperty;var nt=(n,t)=>{for(var e in t)W(n,e,{get:t[e],enumerable:!0})},rt=(n,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of it(t))!st.call(n,s)&&s!==e&&W(n,s,{get:()=>t[s],enumerable:!(i=et(t,s))||i.enumerable});return n};var ot=n=>rt(W({},"__esModule",{value:!0}),n);var vt={};nt(vt,{default:()=>_});module.exports=ot(vt);var J=require("obsidian");var R=require("obsidian");var L=require("obsidian");var G=require("os"),m=require("fs"),a=require("path"),l=(0,G.homedir)(),b=process.env.XDG_CONFIG_HOME||(0,a.join)(l,".config");function C(n){return(0,m.existsSync)(`/Applications/${n}.app`)||(0,m.existsSync)((0,a.join)(l,"Applications",`${n}.app`))}function v(n){let t=[`/usr/local/bin/${n}`,`/opt/homebrew/bin/${n}`,(0,a.join)(l,".local","bin",n)];for(let i of t)if((0,m.existsSync)(i))return!0;let e=(0,a.join)(l,".nvm","versions","node");try{let{readdirSync:i}=require("fs");for(let s of i(e))if((0,m.existsSync)((0,a.join)(e,s,"bin",n)))return!0}catch{}return!1}var g=[{id:"claude-code",name:"Claude Code",color:"#f97316",icon:"brain",paths:[{baseDir:(0,a.join)(l,".claude","skills"),type:"skill",pattern:"directory-with-skillmd"},{baseDir:(0,a.join)(l,".claude","commands"),type:"command",pattern:"flat-md"}],agentPaths:[{baseDir:(0,a.join)(l,".claude","agents"),type:"agent",pattern:"flat-md"}],isInstalled:()=>(0,m.existsSync)((0,a.join)(l,".claude","settings.json"))||(0,m.existsSync)((0,a.join)(l,".claude","CLAUDE.md"))||v("claude")},{id:"cursor",name:"Cursor",color:"#3b82f6",icon:"mouse-pointer",paths:[{baseDir:(0,a.join)(l,".cursor","skills"),type:"skill",pattern:"directory-with-skillmd"},{baseDir:(0,a.join)(l,".cursor","rules"),type:"rule",pattern:"flat-md"}],agentPaths:[{baseDir:(0,a.join)(l,".cursor","agents"),type:"agent",pattern:"flat-md"}],isInstalled:()=>C("Cursor")||(0,m.existsSync)((0,a.join)(l,".cursor","argv.json"))},{id:"windsurf",name:"Windsurf",color:"#14b8a6",icon:"wind",paths:[{baseDir:(0,a.join)(l,".codeium","windsurf","memories"),type:"memory",pattern:"flat-md"},{baseDir:(0,a.join)(l,".windsurf","rules"),type:"rule",pattern:"flat-md"}],agentPaths:[],isInstalled:()=>C("Windsurf")||(0,m.existsSync)((0,a.join)(l,".codeium","windsurf","argv.json"))},{id:"codex",name:"Codex",color:"#22c55e",icon:"book",paths:[{baseDir:(0,a.join)(l,".codex","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[{baseDir:(0,a.join)(l,".codex","agents"),type:"agent",pattern:"flat-md"}],isInstalled:()=>(0,m.existsSync)((0,a.join)(l,".codex","config.toml"))||(0,m.existsSync)((0,a.join)(l,".codex","auth.json"))||v("codex")},{id:"copilot",name:"Copilot",color:"#a855f7",icon:"plane",paths:[{baseDir:(0,a.join)(l,".copilot","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>(0,m.existsSync)((0,a.join)(l,".copilot"))||v("copilot")},{id:"amp",name:"Amp",color:"#ec4899",icon:"zap",paths:[{baseDir:(0,a.join)(b,"amp","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>(0,m.existsSync)((0,a.join)(b,"amp","config.json"))||(0,m.existsSync)((0,a.join)(b,"amp","settings.json"))||v("amp")},{id:"opencode",name:"OpenCode",color:"#ef4444",icon:"terminal",paths:[{baseDir:(0,a.join)(b,"opencode","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>C("OpenCode")||(0,m.existsSync)((0,a.join)(b,"opencode","opencode.json"))||(0,m.existsSync)((0,a.join)(b,"opencode","opencode.jsonc"))||v("opencode")},{id:"pi",name:"Pi",color:"#06b6d4",icon:"sparkles",paths:[{baseDir:(0,a.join)(l,".pi","agent","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>v("pi")},{id:"antigravity",name:"Antigravity",color:"#ef4444",icon:"arrow-up-circle",paths:[{baseDir:(0,a.join)(l,".gemini","antigravity","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>C("Antigravity")||(0,m.existsSync)((0,a.join)(l,".gemini","antigravity","skills"))||v("antigravity")},{id:"claude-desktop",name:"Claude Desktop",color:"#f97316",icon:"monitor",paths:[],agentPaths:[],isInstalled:()=>C("Claude")},{id:"global-agents",name:"Global",color:"#a3e635",icon:"globe",paths:[{baseDir:(0,a.join)(l,".agents","skills"),type:"skill",pattern:"directory-with-skillmd"}],agentPaths:[],isInstalled:()=>(0,m.existsSync)((0,a.join)(l,".agents","skills"))},{id:"aider",name:"Aider",color:"#eab308",icon:"wrench",paths:[],agentPaths:[],isInstalled:()=>v("aider")}];var S={"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:''}};function k(n,t,e=16){let i=S[t];if(!i)return;let s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("viewBox",i.viewBox),s.setAttribute("width",String(e)),s.setAttribute("height",String(e)),s.setAttribute("fill","none"),s.classList.add("as-tool-svg"),s.innerHTML=i.paths,n.appendChild(s)}var P=class{containerEl;store;constructor(t,e){this.containerEl=t,this.store=e}render(){this.containerEl.empty(),this.containerEl.addClass("as-sidebar"),this.renderSection("Library",[{label:"All Skills",icon:"layers",filter:{kind:"all"}},{label:"Favorites",icon:"star",filter:{kind:"favorites"}}]),this.renderTypeSection(),this.renderToolSection(),this.renderCollectionSection()}renderSection(t,e){let i=this.containerEl.createDiv("as-sidebar-section");i.createDiv({cls:"as-sidebar-title",text:t});for(let s of e){let o=i.createDiv("as-sidebar-item");this.isActive(s.filter)&&o.addClass("is-active");let r=o.createSpan("as-sidebar-icon");(0,L.setIcon)(r,s.icon),o.createSpan({cls:"as-sidebar-label",text:s.label}),s.count!==void 0&&o.createSpan({cls:"as-sidebar-count",text:String(s.count)}),o.addEventListener("click",()=>{this.store.setFilter(s.filter)})}}renderTypeSection(){let t=this.store.getTypeCounts(),i=[{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(s=>t.has(s.type)).map(s=>({label:s.label,icon:s.icon,filter:{kind:"type",type:s.type},count:t.get(s.type)||0}));i.length>0&&this.renderSection("Types",i)}renderToolSection(){let t=this.store.getToolCounts(),e=g.filter(s=>s.isInstalled()&&t.has(s.id));if(e.length===0)return;let i=this.containerEl.createDiv("as-sidebar-section");i.createDiv({cls:"as-sidebar-title",text:"Tools"});for(let s of e){let o={kind:"tool",toolId:s.id},r=i.createDiv("as-sidebar-item");this.isActive(o)&&r.addClass("is-active");let d=r.createSpan("as-sidebar-icon");S[s.id]?k(d,s.id,14):(0,L.setIcon)(d,s.icon),r.createSpan({cls:"as-sidebar-label",text:s.name}),r.createSpan({cls:"as-sidebar-count",text:String(t.get(s.id)||0)}),r.addEventListener("click",()=>this.store.setFilter(o))}}renderCollectionSection(){let t=this.containerEl.createDiv("as-sidebar-section");t.createDiv({cls:"as-sidebar-title",text:"Collections"});let e=new Set;for(let i of this.store.allItems)for(let s of i.collections)e.add(s);if(e.size===0){t.createDiv({cls:"as-sidebar-empty",text:"No collections yet"});return}for(let i of e){let s={kind:"collection",name:i},o=t.createDiv("as-sidebar-item");this.isActive(s)&&o.addClass("is-active");let r=o.createSpan("as-sidebar-icon");(0,L.setIcon)(r,"folder"),o.createSpan({cls:"as-sidebar-label",text:i}),o.addEventListener("click",()=>this.store.setFilter(s))}}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:!0}};var z=require("obsidian");var F=class{containerEl;store;onSelect;selectedId=null;constructor(t,e,i){this.containerEl=t,this.store=e,this.onSelect=i}setSelected(t){this.selectedId=t}render(){this.containerEl.empty(),this.containerEl.addClass("as-list");let e=this.containerEl.createDiv("as-search").createEl("input",{type:"text",placeholder:"Search skills...",cls:"as-search-input"});e.value=this.store.searchQuery,e.addEventListener("input",()=>{this.store.setSearch(e.value)});let i=this.containerEl.createDiv("as-list-items"),s=this.store.filteredItems;if(s.length===0){i.createDiv({cls:"as-list-empty",text:"No skills found"});return}for(let o of s)this.renderCard(i,o)}renderCard(t,e){let i=t.createDiv("as-skill-card");e.id===this.selectedId&&i.addClass("is-selected");let s=i.createDiv("as-skill-header"),o=s.createSpan({cls:"as-skill-name",text:e.name});if(e.isFavorite){let p=s.createSpan("as-skill-star");(0,z.setIcon)(p,"star")}e.description&&i.createDiv({cls:"as-skill-desc",text:e.description.length>80?e.description.slice(0,80)+"...":e.description});let r=i.createDiv("as-skill-meta"),d=r.createSpan({cls:`as-type-tag as-type-${e.type}`,text:e.type});for(let p of e.tools){let c=g.find(N=>N.id===p);if(!c)continue;let h=r.createSpan("as-tool-badge");h.title=c.name,h.setAttribute("aria-label",c.name),S[p]?(h.style.color=c.color,k(h,p,12)):(h.style.backgroundColor=c.color,h.addClass("as-tool-badge-dot"))}i.addEventListener("click",()=>{this.selectedId=e.id,this.onSelect(e)})}};var y=require("obsidian"),j=require("fs");function at(n){return Math.ceil(n.length/4)}function lt(n){return n<1024?`${n} B`:n<1024*1024?`${(n/1024).toFixed(1)} KB`:`${(n/(1024*1024)).toFixed(1)} MB`}function $(n){return n>=1e3?`${(n/1e3).toFixed(1)}k`:String(n)}function ct(n){return new Date(n).toLocaleDateString(void 0,{month:"short",day:"numeric",year:"numeric"})}var M=class{containerEl;store;settings;saveSettings;currentItem=null;isEditing=!1;component;constructor(t,e,i,s,o){this.containerEl=t,this.store=e,this.settings=i,this.saveSettings=s,this.component=o}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"),i=e.createDiv("as-toolbar-top"),s=i.createDiv("as-toolbar-left");s.createSpan({cls:"as-detail-title",text:t.name});for(let E of t.tools){let T=g.find(tt=>tt.id===E);if(!T)continue;let D=s.createSpan("as-tool-name-badge");D.style.borderColor=T.color,D.style.color=T.color,S[E]&&k(D,E,12),D.createSpan({text:T.name})}let o=i.createDiv("as-toolbar-right"),r=o.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 d=o.createEl("button",{cls:"as-toolbar-btn",attr:{"aria-label":this.isEditing?"Preview":"Edit"}});(0,y.setIcon)(d,this.isEditing?"eye":"pencil"),d.addEventListener("click",()=>{this.isEditing=!this.isEditing,this.render()});let p=o.createEl("button",{cls:"as-toolbar-btn",attr:{"aria-label":"Open in Finder"}});(0,y.setIcon)(p,"folder-open"),p.addEventListener("click",()=>{let{shell:E}=require("electron");E.showItemInFolder(t.filePath)});let c=e.createDiv("as-detail-meta-bar"),h=at(t.content),N=t.content.length;c.createSpan({cls:"as-meta-item",text:lt(t.fileSize)}),c.createSpan({cls:"as-meta-item",text:`${$(N)} chars`}),c.createSpan({cls:"as-meta-item",text:`~${$(h)} tokens`}),c.createSpan({cls:"as-meta-item",text:ct(t.lastModified)}),c.createSpan({cls:"as-meta-item as-meta-type",text:t.type})}renderFrontmatter(t,e){let i=Object.keys(e.frontmatter);if(i.length===0)return;let s=t.createDiv("as-frontmatter");for(let o of i){let r=e.frontmatter[o];if(r==null)continue;let d=s.createDiv("as-fm-prop");d.createSpan({cls:"as-fm-key",text:o});let p=typeof r=="object"?JSON.stringify(r):String(r);p.length>200?d.createDiv({cls:"as-fm-value-long"}).setText(p):d.createSpan({cls:"as-fm-value"}).setText(p)}}renderPreview(t){let e=this.containerEl.createDiv("as-detail-body");this.renderFrontmatter(e,t);let i=e.createDiv("as-detail-preview markdown-rendered");y.MarkdownRenderer.render(this.component.app||globalThis.app,t.content,i,t.filePath,this.component)}renderEditor(t){let e=this.containerEl.createDiv("as-detail-body as-detail-body-editor"),i=e.createEl("textarea",{cls:"as-editor-textarea"});i.value=t.content,i.spellcheck=!1,i.addEventListener("keydown",r=>{if((r.metaKey||r.ctrlKey)&&r.key==="s"&&(r.preventDefault(),this.saveFile(t,i.value)),r.key==="Tab"){r.preventDefault();let d=i.selectionStart,p=i.selectionEnd;i.value=i.value.substring(0,d)+" "+i.value.substring(p),i.selectionStart=i.selectionEnd=d+1}});let s=e.createDiv("as-save-bar");s.createEl("button",{cls:"as-save-btn",text:"Save"}).addEventListener("click",()=>{this.saveFile(t,i.value)}),s.createSpan({cls:"as-save-hint",text:"Cmd+S to save"})}saveFile(t,e){try{(0,j.writeFileSync)(t.filePath,e,"utf-8"),t.content=e;let{Notice:i}=require("obsidian");new i(`Saved ${t.name}`)}catch(i){let{Notice:s}=require("obsidian");new s(`Failed to save: ${i instanceof Error?i.message:String(i)}`)}}};var I="agentfiles-view",O=class extends R.ItemView{store;settings;saveSettings;sidebarPanel;listPanel;detailPanel;sidebarEl;listEl;detailEl;constructor(t,e,i,s){super(t),this.store=e,this.settings=i,this.saveSettings=s}getViewType(){return I}getDisplayText(){return"Agentfiles"}getIcon(){return"cpu"}async 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.sidebarPanel=new P(this.sidebarEl,this.store),this.listPanel=new F(this.listEl,this.store,e=>this.onSelectItem(e)),this.detailPanel=new M(this.detailEl,this.store,this.settings,this.saveSettings,this),this.store.on("updated",()=>this.renderAll()),this.renderAll()}renderAll(){this.sidebarPanel.render(),this.listPanel.render(),this.store.filteredItems.length||this.detailPanel.clear()}onSelectItem(t){this.listPanel.setSelected(t.id),this.listPanel.render(),this.detailPanel.show(t)}async onClose(){this.store.offref(this.store.on("updated",()=>{}))}};var Y=require("obsidian");var u=require("fs"),f=require("path"),K=require("obsidian"),Q=require("crypto");var Z=new Set(["readme.md","license","license.md","changelog.md",".ds_store","thumbs.db"]);function dt(n){return(0,Q.createHash)("sha256").update(n).digest("hex").slice(0,12)}function pt(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,K.parseYaml)(t[1]);return{frontmatter:typeof e=="object"&&e?e:{},content:t[2]}}catch{return{frontmatter:{},content:n}}}function ht(n,t,e){if(typeof n.name=="string"&&n.name)return n.name;let i=t.match(/^#\s+(.+)$/m);if(i)return i[1].trim();let s=(0,f.basename)(e,(0,f.extname)(e));return s==="SKILL"?(0,f.basename)((0,f.join)(e,"..")):s}function mt(n,t,e){if(!(0,u.existsSync)(n))return[];let i=[];for(let s of(0,u.readdirSync)(n,{withFileTypes:!0})){if(!s.isDirectory())continue;let o=(0,f.join)(n,s.name,"SKILL.md");if(!(0,u.existsSync)(o))continue;let r=x(o,t,e);r&&i.push(r)}return i}function ut(n,t,e){if(!(0,u.existsSync)(n))return[];let i=[];for(let s of(0,u.readdirSync)(n,{withFileTypes:!0})){if(s.isDirectory()){let d=(0,f.join)(n,s.name,"SKILL.md");if((0,u.existsSync)(d)){let h=x(d,t,e);h&&i.push(h);continue}let p=(0,u.readdirSync)((0,f.join)(n,s.name)).filter(h=>h.endsWith(".md")&&!Z.has(h.toLowerCase())),c=p.find(h=>h.toLowerCase()===`${s.name.toLowerCase()}.md`)||p[0];if(c){let h=x((0,f.join)(n,s.name,c),t,e);h&&i.push(h)}continue}let o=s.name.toLowerCase();if(!o.endsWith(".md")||Z.has(o))continue;let r=x((0,f.join)(n,s.name),t,e);r&&i.push(r)}return i}function ft(n,t,e){if(!(0,u.existsSync)(n))return[];let i=[];for(let s of(0,u.readdirSync)(n,{withFileTypes:!0})){if(!s.name.endsWith(".mdc")&&!s.name.endsWith(".md")||s.isDirectory())continue;let o=x((0,f.join)(n,s.name),t,e);o&&i.push(o)}return i}function x(n,t,e){try{let i=(0,u.readFileSync)(n,"utf-8"),s=(0,u.statSync)(n),{frontmatter:o,content:r}=pt(i),d=ht(o,r,n),p=typeof o.description=="string"?o.description:"",c;try{c=(0,u.realpathSync)(n)}catch{c=n}return{id:dt(c),name:d,description:p,type:t,tools:[e],filePath:n,realPath:c,dirPath:(0,f.join)(n,".."),content:i,frontmatter:o,lastModified:s.mtimeMs,fileSize:s.size,isFavorite:!1,collections:[]}}catch{return null}}function gt(n,t){switch(n.pattern){case"directory-with-skillmd":return mt(n.baseDir,n.type,t);case"flat-md":return ut(n.baseDir,n.type,t);case"mdc":return ft(n.baseDir,n.type,t)}}function q(n){let t=new Map;for(let e of g){if(!e.isInstalled())continue;let i=n.tools[e.id];if(i&&!i.enabled)continue;let s=[...e.paths,...e.agentPaths];for(let o of s)for(let r of gt(o,e.id)){let d=t.get(r.id);if(d)d.tools.includes(e.id)||d.tools.push(e.id);else{r.isFavorite=n.favorites.includes(r.id);for(let[p,c]of Object.entries(n.collections))c.includes(r.id)&&r.collections.push(p);t.set(r.id,r)}}}return t}function U(){let n=[];for(let t of g)if(t.isInstalled())for(let e of[...t.paths,...t.agentPaths])(0,u.existsSync)(e.baseDir)&&n.push(e.baseDir);return n}var A=class extends Y.Events{items=new Map;_filter={kind:"all"};_searchQuery="";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}if(this._searchQuery){let e=this._searchQuery.toLowerCase();t=t.filter(i=>i.name.toLowerCase().includes(e)||i.description.toLowerCase().includes(e)||i.content.toLowerCase().includes(e))}return t.sort((e,i)=>e.name.localeCompare(i.name))}getItem(t){return this.items.get(t)}refresh(t){this.items=q(t),this.trigger("updated")}setFilter(t){this._filter=t,this.trigger("updated")}setSearch(t){this._searchQuery=t,this.trigger("updated")}toggleFavorite(t,e){let i=this.items.get(t);i&&(i.isFavorite=!i.isFavorite,i.isFavorite?e.favorites.includes(t)||e.favorites.push(t):e.favorites=e.favorites.filter(s=>s!==t),this.trigger("updated"))}getToolCounts(){let t=new Map;for(let e of this.items.values())for(let i of e.tools)t.set(i,(t.get(i)||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}};var X=require("fs"),H=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 i=(0,X.watch)(e,{recursive:!0},()=>this.scheduleUpdate());this.watchers.push(i)}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 w=require("obsidian");var V=class extends w.PluginSettingTab{plugin;constructor(t,e){super(t,e),this.plugin=e}display(){let{containerEl:t}=this;t.empty(),t.createEl("h2",{text:"Agentfiles"}),new w.Setting(t).setName("File watching").setDesc("Automatically detect changes to skill files").addToggle(e=>e.setValue(this.plugin.settings.watchEnabled).onChange(async i=>{this.plugin.settings.watchEnabled=i,await this.plugin.saveSettings(),this.plugin.restartWatcher()})),new w.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 i=>{let s=parseInt(i);!isNaN(s)&&s>=100&&(this.plugin.settings.watchDebounceMs=s,await this.plugin.saveSettings())})),t.createEl("h3",{text:"Tools"});for(let e of g){let i=e.isInstalled(),s=this.plugin.settings.tools[e.id]||{enabled:!0,customPaths:[]};new w.Setting(t).setName(e.name).setDesc(i?"Installed":"Not detected").addToggle(o=>o.setValue(i&&s.enabled).setDisabled(!i).onChange(async r=>{this.plugin.settings.tools[e.id]={...s,enabled:r},await this.plugin.saveSettings(),this.plugin.refreshStore()}))}}};var B={tools:{},watchEnabled:!0,watchDebounceMs:500,favorites:[],collections:{},customScanPaths:[]};var _=class extends J.Plugin{settings=B;store=new A;watcher=null;async onload(){await this.loadSettings(),this.registerView(I,t=>new O(t,this.store,this.settings,()=>this.saveSettings())),this.addRibbonIcon("cpu","Agentfiles",()=>this.activateView()),this.addCommand({id:"open-agentfiles",name:"Open Agentfiles",callback:()=>this.activateView()}),this.addSettingTab(new V(this.app,this)),this.refreshStore(),this.startWatcher()}onunload(){this.stopWatcher()}refreshStore(){this.store.refresh(this.settings)}startWatcher(){this.settings.watchEnabled&&(this.watcher=new H(this.settings.watchDebounceMs,()=>this.refreshStore()),this.watcher.watchPaths(U()))}stopWatcher(){this.watcher&&(this.watcher.close(),this.watcher=null)}restartWatcher(){this.stopWatcher(),this.startWatcher()}async activateView(){let t=this.app.workspace.getLeavesOfType(I);if(t.length>0){this.app.workspace.revealLeaf(t[0]);return}let e=this.app.workspace.getLeaf("tab");await e.setViewState({type:I,active:!0}),this.app.workspace.revealLeaf(e)}async loadSettings(){this.settings=Object.assign({},B,await this.loadData())}async saveSettings(){await this.saveData(this.settings)}}; diff --git a/manifest.json b/manifest.json index 760c2aa..0969fd5 100644 --- a/manifest.json +++ b/manifest.json @@ -1,9 +1,9 @@ { - "id": "obsidian-agent-skills", - "name": "Agent Skills", + "id": "agentfiles", + "name": "Agentfiles", "version": "0.1.0", "minAppVersion": "1.4.11", - "description": "Discover, organize, and edit AI coding agent skills across Claude Code, Cursor, Codex, Windsurf, and more.", + "description": "Discover, organize, and edit AI agent skills, commands, and agents across Claude Code, Cursor, Codex, Windsurf, and more.", "author": "Railly Hugo", "authorUrl": "https://railly.dev", "isDesktopOnly": true diff --git a/package.json b/package.json index dabff2a..1edb578 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "obsidian-agent-skills", + "name": "agentfiles", "version": "0.1.0", "description": "AI Skills Manager for Obsidian", "main": "main.js", diff --git a/src/main.ts b/src/main.ts index 7759421..7a624db 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,12 +1,12 @@ -import { Plugin, type WorkspaceLeaf } from "obsidian"; -import { AgentSkillsView, VIEW_TYPE } from "./views/main-view"; +import { Plugin } from "obsidian"; +import { AgentfilesView, VIEW_TYPE } from "./views/main-view"; import { SkillStore } from "./store"; import { SkillWatcher } from "./watcher"; import { getWatchPaths } from "./scanner"; -import { AgentSkillsSettingTab } from "./settings"; +import { AgentfilesSettingTab } from "./settings"; import { DEFAULT_SETTINGS, type ChopsSettings } from "./types"; -export default class AgentSkillsPlugin extends Plugin { +export default class AgentfilesPlugin extends Plugin { settings: ChopsSettings = DEFAULT_SETTINGS; store: SkillStore = new SkillStore(); private watcher: SkillWatcher | null = null; @@ -15,7 +15,7 @@ export default class AgentSkillsPlugin extends Plugin { await this.loadSettings(); this.registerView(VIEW_TYPE, (leaf) => - new AgentSkillsView( + new AgentfilesView( leaf, this.store, this.settings, @@ -23,15 +23,15 @@ export default class AgentSkillsPlugin extends Plugin { ) ); - this.addRibbonIcon("cpu", "Agent Skills", () => this.activateView()); + this.addRibbonIcon("cpu", "Agentfiles", () => this.activateView()); this.addCommand({ - id: "open-agent-skills", - name: "Open Agent Skills", + id: "open-agentfiles", + name: "Open Agentfiles", callback: () => this.activateView(), }); - this.addSettingTab(new AgentSkillsSettingTab(this.app, this)); + this.addSettingTab(new AgentfilesSettingTab(this.app, this)); this.refreshStore(); this.startWatcher(); diff --git a/src/settings.ts b/src/settings.ts index f68a501..9a04e6d 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,12 +1,12 @@ import { PluginSettingTab, Setting, type App } from "obsidian"; import { TOOL_CONFIGS } from "./tool-configs"; import type { ChopsSettings } from "./types"; -import type AgentSkillsPlugin from "./main"; +import type AgentfilesPlugin from "./main"; -export class AgentSkillsSettingTab extends PluginSettingTab { - plugin: AgentSkillsPlugin; +export class AgentfilesSettingTab extends PluginSettingTab { + plugin: AgentfilesPlugin; - constructor(app: App, plugin: AgentSkillsPlugin) { + constructor(app: App, plugin: AgentfilesPlugin) { super(app, plugin); this.plugin = plugin; } @@ -15,7 +15,7 @@ export class AgentSkillsSettingTab extends PluginSettingTab { const { containerEl } = this; containerEl.empty(); - containerEl.createEl("h2", { text: "Agent Skills" }); + containerEl.createEl("h2", { text: "Agentfiles" }); new Setting(containerEl) .setName("File watching") diff --git a/src/views/main-view.ts b/src/views/main-view.ts index ca3153b..a195d72 100644 --- a/src/views/main-view.ts +++ b/src/views/main-view.ts @@ -5,9 +5,9 @@ import { SidebarPanel } from "./sidebar"; import { ListPanel } from "./list"; import { DetailPanel } from "./detail"; -export const VIEW_TYPE = "agent-skills-view"; +export const VIEW_TYPE = "agentfiles-view"; -export class AgentSkillsView extends ItemView { +export class AgentfilesView extends ItemView { private store: SkillStore; private settings: ChopsSettings; private saveSettings: () => Promise; @@ -37,7 +37,7 @@ export class AgentSkillsView extends ItemView { } getDisplayText(): string { - return "Agent Skills"; + return "Agentfiles"; } getIcon(): string { diff --git a/versions.json b/versions.json new file mode 100644 index 0000000..4487595 --- /dev/null +++ b/versions.json @@ -0,0 +1,3 @@ +{ + "0.1.0": "1.4.11" +}