@aggroot-team/aggroot 1.7.9 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.cjs +2 -2
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -1597,12 +1597,12 @@ ${r?`npx skillhub ${r} --help`:"npx skillhub --help"}
1597
1597
  `),s=/^---\n([\s\S]*?)\n---\n?/,a=r.match(s);if(!a)return null;let u=a[1];for(let f of u.split(`
1598
1598
  `)){let m=f.indexOf(":");if(m>0&&!/^\s/.test(f)&&f.slice(0,m).trim()==="description")return f.slice(m+1).trim()}return null}catch{return null}}async function eGr(n,e){let r=[],s=new Map;try{try{await(0,Ky.access)(n)}catch{return{skills:r,categories:s}}let a=await(0,Ky.readdir)(n,{withFileTypes:!0});for(let u of a)if(u.isFile()&&u.name.endsWith(".md")&&u.name!=="DESCRIPTION.md"){let f=(0,lx.join)(n,u.name),m=await Bde(f);m&&r.push(jde(m,e))}for(let u of a){if(!u.isDirectory()||u.name.startsWith("."))continue;let f=(0,lx.join)(n,u.name),m;try{m=await(0,Ky.readdir)(f,{withFileTypes:!0})}catch{continue}let g=!1;for(let A of m){if(!A.isDirectory()||A.name.startsWith("."))continue;let C=(0,lx.join)(f,A.name),L=(0,lx.join)(C,"SKILL.md");if((0,zde.existsSync)(L)){g=!0;let k=u.name,M=await Bde(L);M&&r.push(jde(M,e,k))}}let b=(0,lx.join)(f,"SKILL.md");if(!g&&(0,zde.existsSync)(b)){let A=await Bde(b);A&&r.push(jde(A,e))}let E=(0,lx.join)(f,"DESCRIPTION.md");if((0,zde.existsSync)(E)){let A=await Qjr(E);A&&s.set(u.name,A)}}jT.debug({dirPath:n,count:r.length},"Loaded skills from directory")}catch(a){a.code!=="ENOENT"&&jT.warn({dirPath:n,error:String(a)},"Failed to load skills from directory")}return{skills:r,categories:s}}async function tGr(n){let e={};async function r(s,a){let u;try{u=await(0,Ky.readdir)(s,{withFileTypes:!0})}catch{return}for(let f of u){if(f.name.startsWith("."))continue;let m=(0,lx.join)(s,f.name),g=a?`${a}/${f.name}`:f.name;if(f.isDirectory())await r(m,g);else if(f.name==="SKILL.md"||f.name==="DESCRIPTION.md")try{let b=await(0,Ky.stat)(m);e[g]={mtime:b.mtimeMs,size:b.size}}catch{}else if(f.isFile()&&f.name.endsWith(".md")&&a==="")try{let b=await(0,Ky.stat)(m);e[g]={mtime:b.mtimeMs,size:b.size}}catch{}}}return await r(n,""),e}async function nGr(n){let e=(0,lx.join)(n,".index.json");try{await(0,Ky.access)(e);let r=await(0,Ky.readFile)(e,"utf-8"),s=JSON.parse(r);return s.version!==1?null:s}catch{return null}}async function rGr(n,e){let r=(0,lx.join)(n,".index.json");try{await(0,Ky.mkdir)(n,{recursive:!0});let s=r+".tmp";await(0,Ky.writeFile)(s,JSON.stringify(e,null,2),"utf-8"),await(0,Ndn.rename)(s,r)}catch(s){jT.debug({error:String(s),dirPath:n},"Failed to write .index.json")}}function iGr(n,e){let r=Object.keys(n),s=Object.keys(e);if(r.length!==s.length)return!1;for(let a of r)if(!e[a]||n[a].mtime!==e[a].mtime||n[a].size!==e[a].size)return!1;return!0}async function kdn(n,e){try{await(0,Ky.access)(n)}catch{return{skills:[],categories:new Map}}let r=await tGr(n),s=await nGr(n);if(s&&iGr(r,s.manifest)){let m=[],g=new Map(Object.entries(s.categories));for(let b of s.skills){let E=(0,lx.join)(n,b.filePath),A=null,C=async L=>{if(A===null){let H=(await(0,Ky.readFile)(E,"utf-8")).replace(/\r\n/g,`
1599
1599
  `).replace(/\r/g,`
1600
- `).match(/^---\n[\s\S]*?\n---\n([\s\S]*)$/);A=H?H[1]:""}let k=A;for(let[M,U]of Object.entries(L)){let H=M.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");k=k.replace(new RegExp(`\\{\\{${H}\\}\\}`,"g"),String(U))}return k};m.push({name:b.name,description:b.description,source:b.source,category:b.category,whenToUse:b.whenToUse,arguments:b.arguments,allowedTools:b.allowedTools,model:b.model,context:b.context,agent:b.agent,userInvocable:b.userInvocable,platforms:b.platforms,filePath:E,getPrompt:C})}return jT.debug({dirPath:n,count:m.length,cached:!0},"Loaded skills from cache"),{skills:m,categories:g}}let a=await eGr(n,e),u=new Map;for(let m of a.skills)m.category?u.set(m.name,`${m.category}/${m.name}/SKILL.md`):u.set(m.name,`${m.name}/SKILL.md`);let f={version:1,manifest:r,skills:a.skills.map(m=>({name:m.name,description:m.description,category:m.category,source:m.source,whenToUse:m.whenToUse,userInvocable:m.userInvocable,platforms:m.platforms,arguments:m.arguments,allowedTools:m.allowedTools,model:m.model,context:m.context,agent:m.agent,filePath:u.get(m.name)||""})),categories:Object.fromEntries(a.categories),updatedAt:new Date().toISOString()};return await rGr(n,f),a}async function Mdn(n,e){let r=Date.now(),s=new wke;for(let g of e)s.register(g);jT.info(`[skill-load] builtin skills registered \u2014 ${Date.now()-r}ms, count: ${e.length}`);for(let g of xke)s.register(g);jT.info(`[skill-load] skillhub skills registered \u2014 ${Date.now()-r}ms, count: ${xke.length}`);let a=NC(n,"skills");jT.info(`[skill-load] before project skills \u2014 ${Date.now()-r}ms, dir: ${a}`);let u=await kdn(a,"project");for(let g of u.skills)s.register(g);u.categories.size>0&&s.updateCategories(u.categories),jT.info(`[skill-load] project skills loaded \u2014 ${Date.now()-r}ms, count: ${u.skills.length}`);let f=(0,lx.join)(Ks,"skills");jT.info(`[skill-load] before user skills \u2014 ${Date.now()-r}ms, dir: ${f}`);let m=await kdn(f,"user");for(let g of m.skills)s.has(g.name)||s.register(g);return m.categories.size>0&&s.updateCategories(m.categories),jT.info(`[skill-load] user skills loaded \u2014 ${Date.now()-r}ms, count: ${m.skills.length}`),jT.info({builtin:e.length,skillhub:xke.length,project:u.skills.length,user:m.skills.length,total:s.list().length},"Skills loaded"),s}function Ldn(){return new wke}async function tmt(n){let e=(0,lx.join)(n,".index.json");try{if((0,zde.existsSync)(e)){let{unlink:r}=await import("fs/promises");await r(e)}}catch{}}function nmt(n,e){return n.platforms&&n.platforms.length>0&&!n.platforms.includes(e.platform)?"unsupported":n.prerequisites?.env_vars&&n.prerequisites.env_vars.filter(s=>!e.hasEnvVar(s)).length>0||n.prerequisites?.commands&&n.prerequisites.commands.filter(s=>!e.hasCommand(s)).length>0||n.conditions?.requires_tools&&n.conditions.requires_tools.filter(s=>!e.availableTools.includes(s)).length>0||n.conditions?.requires_toolsets&&n.conditions.requires_toolsets.filter(s=>!e.availableToolsets.includes(s)).length>0?"setup_needed":"available"}function Odn(n,e){return n.filter(r=>!(r.platforms&&r.platforms.length>0&&!r.platforms.includes(e.platform)||r.conditions?.fallback_for_tools&&r.conditions.fallback_for_tools.some(a=>e.availableTools.includes(a))||r.conditions?.fallback_for_toolsets&&r.conditions.fallback_for_toolsets.some(a=>e.availableToolsets.includes(a))))}var Ky,lx,zde,Ndn,jT,wke,Ake=kt(()=>{"use strict";F();Ky=require("fs/promises"),lx=require("path"),zde=require("fs"),Ndn=require("fs/promises");HI();Tu();Ddn();Yf();jT=ks("skill-loader"),wke=class{skills=new Map;categories=new Map;eventHandlers=new Set;get(e){return this.skills.get(e)}has(e){return this.skills.has(e)}register(e){this.skills.set(e.name,e),this.emit({type:"skill_registered",skillName:e.name,source:e.source}),jT.debug({name:e.name,source:e.source},"Skill registered")}unregister(e){this.skills.delete(e),this.emit({type:"skill_unregistered",skillName:e}),jT.debug({name:e},"Skill unregistered")}list(){return Array.from(this.skills.values())}listBySource(e){return this.list().filter(r=>r.source===e)}search(e){let r=e.toLowerCase();return this.list().filter(s=>s.name.toLowerCase().includes(r)||s.description.toLowerCase().includes(r)||s.whenToUse?.toLowerCase().includes(r))}listByCategory(e){return this.list().filter(r=>r.category===e)}listCategories(){let e=new Set;for(let a of this.list())a.category&&e.add(a.category);let r=[],s=new Set;for(let[a,u]of this.categories)e.has(a)&&!s.has(a)&&(r.push(u),s.add(a));for(let a of e)s.has(a)||(r.push({name:a,description:void 0}),s.add(a));return r}updateCategories(e){for(let[r,s]of e)this.categories.set(r,{name:r,description:s||void 0})}onEvent(e){return this.eventHandlers.add(e),()=>this.eventHandlers.delete(e)}loadFrom(e){for(let r of e.list())this.skills.has(r.name)||this.skills.set(r.name,r)}emit(e){if(this.eventHandlers.size!==0)for(let r of this.eventHandlers)try{r(e)}catch(s){jT.warn({error:String(s)},"Error in skill event handler")}}}});var fY,rmt,imt,omt,dY,smt=kt(()=>{"use strict";F();fY=require("node:fs/promises"),rmt=require("node:path"),imt=require("node:fs"),omt=Do(require("node:https"),1);lP();lP();Yf();dY=class{_cachePath;_registryBase;_checkIntervalMs;_enabled;constructor(e){this._cachePath=(0,rmt.join)(e?.dataDir??Ks,GZt),this._registryBase=e?.registryBase??"https://registry.npmjs.org",this._checkIntervalMs=e?.checkIntervalMs??jZt,this._enabled=e?.enabled??!0}async checkForUpdate(e){if(!this._enabled)return null;if(!e?.force){let f=await this._loadCache();if(f&&Date.now()-new Date(f.lastCheckTime).getTime()<this._checkIntervalMs)return{hasUpdate:this._isNewer(f.latestVersion,ES),currentVersion:ES,latestVersion:f.latestVersion,checkedAt:f.lastCheckTime}}let r=await this._fetchLatestVersion();if(!r)return null;let s=this._isNewer(r,ES),a=new Date().toISOString(),u={lastCheckTime:a,latestVersion:r,currentVersionAtCheck:ES,hasUpdate:s};return await this._saveCache(u),{hasUpdate:s,currentVersion:ES,latestVersion:r,checkedAt:a}}async checkInBackground(){try{return await this.checkForUpdate()}catch{return null}}async getCachedResult(){let e=await this._loadCache();return e?{hasUpdate:this._isNewer(e.latestVersion,ES),currentVersion:ES,latestVersion:e.latestVersion,checkedAt:e.lastCheckTime}:null}_isNewer(e,r){let s=e.replace(/^v/,"").split(".").map(Number),a=r.replace(/^v/,"").split(".").map(Number);for(let u=0;u<3;u++){if((s[u]??0)>(a[u]??0))return!0;if((s[u]??0)<(a[u]??0))return!1}return!1}_fetchLatestVersion(){let e=`${this._registryBase}/aggroot/latest`;return new Promise(r=>{let s=setTimeout(()=>{a.destroy(),r(null)},aat),a=omt.default.get(e,u=>{if(u.statusCode===301||u.statusCode===302){let m=u.headers.location;if(m){clearTimeout(s),r(this._fetchFromUrl(m));return}}if(u.statusCode!==200){clearTimeout(s),u.resume(),r(null);return}let f="";u.on("data",m=>{f+=m.toString()}),u.on("end",()=>{clearTimeout(s);try{let m=JSON.parse(f);r(m.version??null)}catch{r(null)}}),u.on("error",()=>{clearTimeout(s),r(null)})});a.on("error",()=>{clearTimeout(s),r(null)})})}_fetchFromUrl(e){return new Promise(r=>{let s=setTimeout(()=>{a.destroy(),r(null)},aat),a=omt.default.get(e,u=>{if(u.statusCode!==200){clearTimeout(s),u.resume(),r(null);return}let f="";u.on("data",m=>{f+=m.toString()}),u.on("end",()=>{clearTimeout(s);try{let m=JSON.parse(f);r(m.version??null)}catch{r(null)}})});a.on("error",()=>{clearTimeout(s),r(null)})})}async _loadCache(){try{if(!(0,imt.existsSync)(this._cachePath))return null;let e=await(0,fY.readFile)(this._cachePath,"utf-8");return JSON.parse(e)}catch{return null}}async _saveCache(e){try{let r=(0,rmt.join)(this._cachePath,"..");(0,imt.existsSync)(r)||await(0,fY.mkdir)(r,{recursive:!0}),await(0,fY.writeFile)(this._cachePath,JSON.stringify(e,null,2),"utf-8")}catch{}}}});var mY,amt,Pke,zdn,Bdn,lGr,pY,lmt=kt(()=>{"use strict";F();mY=require("node:fs/promises"),amt=require("node:path"),Pke=require("node:fs"),zdn=require("node:child_process"),Bdn=require("node:util");Yf();lP();lGr=(0,Bdn.promisify)(zdn.execFile),pY=class{_rollbackPath;constructor(e){this._rollbackPath=(0,amt.join)(e??Ks,$Zt)}async createBackup(e,r){let s={previousVersion:e,upgradedFrom:e,upgradedTo:"",upgradedAt:new Date().toISOString(),installPath:r};await this._save(s)}async markUpgraded(e){let r=await this._load();r&&(r.upgradedTo=e,await this._save(r))}async isRollbackAvailable(){let e=await this._load();return e!==null&&!!e.previousVersion}async getRollbackInfo(){return this._load()}async rollback(e){let r=await this._load();if(!r||!r.previousVersion)return{success:!1,version:"",error:"\u6CA1\u6709\u53EF\u56DE\u6EDA\u7684\u7248\u672C\u4FE1\u606F"};let s=e??"npm";try{let{stdout:a,stderr:u}=await lGr(s,["install","-g",`aggroot@${r.previousVersion}`],{timeout:PIe,encoding:"utf-8",shell:!0}),f=u?.trim();return f&&!f.includes("WARN")&&!f.includes("warn")?{success:!1,version:r.previousVersion,error:f}:(await this.clearRollback(),{success:!0,version:r.previousVersion})}catch(a){return{success:!1,version:r.previousVersion,error:a.message??String(a)}}}async clearRollback(){try{if((0,Pke.existsSync)(this._rollbackPath)){let{unlink:e}=await import("node:fs/promises");await e(this._rollbackPath)}}catch{}}async _load(){try{if(!(0,Pke.existsSync)(this._rollbackPath))return null;let e=await(0,mY.readFile)(this._rollbackPath,"utf-8");return JSON.parse(e)}catch{return null}}async _save(e){try{let r=(0,amt.join)(this._rollbackPath,"..");(0,Pke.existsSync)(r)||await(0,mY.mkdir)(r,{recursive:!0}),await(0,mY.writeFile)(this._rollbackPath,JSON.stringify(e,null,2),"utf-8")}catch{}}}});var kke,jdn,Gdn,cmt,Rke,Dke,$dn=kt(()=>{"use strict";F();kke=require("node:child_process"),jdn=require("node:util"),Gdn=require("node:fs"),cmt=require("node:path");lP();lP();smt();lmt();Rke=(0,jdn.promisify)(kke.execFile),Dke=class{_updateChecker;_rollbackManager;constructor(e){this._updateChecker=new dY({dataDir:e?.dataDir}),this._rollbackManager=new pY(e?.dataDir)}get updateChecker(){return this._updateChecker}get rollbackManager(){return this._rollbackManager}async getInstallInfo(){let e=await this._findNpm(),r=await this._isNpmGlobalInstall(),s="";if(e)try{let{stdout:a}=await Rke(e,["root","-g"],{timeout:1e4,encoding:"utf-8",shell:!0});s=(0,cmt.join)(a.trim(),"aggroot")}catch{}return{isNpmGlobalInstall:r,installPath:s,version:ES,npmPath:e}}async upgrade(e,r,s){let a=ES;e?.({step:"checking-env",message:"\u6B63\u5728\u68C0\u67E5\u5347\u7EA7\u73AF\u5883...",percent:5});let u=r??await this.getInstallInfo();if(!u.npmPath)return{success:!1,fromVersion:a,toVersion:"",error:"\u672A\u627E\u5230 npm \u547D\u4EE4\uFF0C\u65E0\u6CD5\u6267\u884C\u5347\u7EA7\u3002\u8BF7\u786E\u4FDD npm \u5DF2\u5B89\u88C5\u5E76\u5728 PATH \u4E2D\u3002"};if(!u.isNpmGlobalInstall)return{success:!1,fromVersion:a,toVersion:"",error:"\u5F53\u524D\u975E npm \u5168\u5C40\u5B89\u88C5\uFF0C\u4E0D\u652F\u6301\u81EA\u52A8\u5347\u7EA7\u3002\u8BF7\u901A\u8FC7\u6E90\u7801\u65B9\u5F0F\u624B\u52A8\u66F4\u65B0\u3002"};e?.({step:"checking-version",message:"\u6B63\u5728\u68C0\u67E5\u6700\u65B0\u7248\u672C...",percent:15});let f=s??await this._updateChecker.checkForUpdate({force:!0});if(!f)return{success:!1,fromVersion:a,toVersion:"",error:"\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C\u4FE1\u606F\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u3002"};if(!f.hasUpdate)return{success:!1,fromVersion:a,toVersion:ES,error:`\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\u672C (${ES})`};let m=f.latestVersion;e?.({step:"backing-up",message:"\u6B63\u5728\u5907\u4EFD\u56DE\u6EDA\u4FE1\u606F...",percent:25}),await this._rollbackManager.createBackup(a,u.installPath),e?.({step:"downloading",message:`\u6B63\u5728\u4E0B\u8F7D aggroot@${m}...`,percent:30});let g=await this._spawnNpmInstall(m,e);return g.success?(e?.({step:"verifying",message:"\u6B63\u5728\u9A8C\u8BC1\u5B89\u88C5...",percent:90}),await this._verifyInstallation(u.npmPath,m)?(await this._rollbackManager.markUpgraded(m),e?.({step:"done",message:"\u5347\u7EA7\u5B8C\u6210",percent:100}),{success:!0,fromVersion:a,toVersion:m}):{success:!1,fromVersion:a,toVersion:m,error:"\u5B89\u88C5\u9A8C\u8BC1\u5931\u8D25\uFF0C\u65B0\u7248\u672C\u53EF\u80FD\u672A\u6B63\u786E\u5B89\u88C5\u3002\u8BF7\u624B\u52A8\u68C0\u67E5\u3002"}):{success:!1,fromVersion:a,toVersion:m,error:g.error??"npm \u5B89\u88C5\u5931\u8D25"}}async rollback(e){if(!(await this.getInstallInfo()).npmPath)return{success:!1,version:"",error:"\u672A\u627E\u5230 npm \u547D\u4EE4\uFF0C\u65E0\u6CD5\u6267\u884C\u56DE\u6EDA\u3002"};e?.({step:"installing",message:"\u6B63\u5728\u56DE\u6EDA\u5230\u4E0A\u4E00\u7248\u672C...",percent:30});let s=await this._rollbackManager.getRollbackInfo();if(!s)return{success:!1,version:"",error:"\u6CA1\u6709\u53EF\u56DE\u6EDA\u7684\u7248\u672C\u4FE1\u606F"};let a=await this._spawnNpmInstall(s.previousVersion,e);return a.success?(await this._rollbackManager.clearRollback(),e?.({step:"done",message:"\u56DE\u6EDA\u5B8C\u6210",percent:100}),{success:!0,version:s.previousVersion}):{success:!1,version:s.previousVersion,error:a.error}}async checkForUpdate(e){return this._updateChecker.checkForUpdate(e)}_spawnNpmInstall(e,r){return new Promise(s=>{let a=(0,kke.spawn)("npm",["install","-g",`aggroot@${e}`],{shell:!0,timeout:PIe}),u="";a.stdout?.on("data",f=>{let m=f.toString("utf-8");this._parseNpmProgress(m,e,r)}),a.stderr?.on("data",f=>{u+=f.toString("utf-8")}),a.on("close",f=>{if(f!==0){let g=u.split(`
1600
+ `).match(/^---\n[\s\S]*?\n---\n([\s\S]*)$/);A=H?H[1]:""}let k=A;for(let[M,U]of Object.entries(L)){let H=M.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");k=k.replace(new RegExp(`\\{\\{${H}\\}\\}`,"g"),String(U))}return k};m.push({name:b.name,description:b.description,source:b.source,category:b.category,whenToUse:b.whenToUse,arguments:b.arguments,allowedTools:b.allowedTools,model:b.model,context:b.context,agent:b.agent,userInvocable:b.userInvocable,platforms:b.platforms,filePath:E,getPrompt:C})}return jT.debug({dirPath:n,count:m.length,cached:!0},"Loaded skills from cache"),{skills:m,categories:g}}let a=await eGr(n,e),u=new Map;for(let m of a.skills)m.category?u.set(m.name,`${m.category}/${m.name}/SKILL.md`):u.set(m.name,`${m.name}/SKILL.md`);let f={version:1,manifest:r,skills:a.skills.map(m=>({name:m.name,description:m.description,category:m.category,source:m.source,whenToUse:m.whenToUse,userInvocable:m.userInvocable,platforms:m.platforms,arguments:m.arguments,allowedTools:m.allowedTools,model:m.model,context:m.context,agent:m.agent,filePath:u.get(m.name)||""})),categories:Object.fromEntries(a.categories),updatedAt:new Date().toISOString()};return await rGr(n,f),a}async function Mdn(n,e){let r=Date.now(),s=new wke;for(let g of e)s.register(g);jT.info(`[skill-load] builtin skills registered \u2014 ${Date.now()-r}ms, count: ${e.length}`);for(let g of xke)s.register(g);jT.info(`[skill-load] skillhub skills registered \u2014 ${Date.now()-r}ms, count: ${xke.length}`);let a=NC(n,"skills");jT.info(`[skill-load] before project skills \u2014 ${Date.now()-r}ms, dir: ${a}`);let u=await kdn(a,"project");for(let g of u.skills)s.register(g);u.categories.size>0&&s.updateCategories(u.categories),jT.info(`[skill-load] project skills loaded \u2014 ${Date.now()-r}ms, count: ${u.skills.length}`);let f=(0,lx.join)(Ks,"skills");jT.info(`[skill-load] before user skills \u2014 ${Date.now()-r}ms, dir: ${f}`);let m=await kdn(f,"user");for(let g of m.skills)s.has(g.name)||s.register(g);return m.categories.size>0&&s.updateCategories(m.categories),jT.info(`[skill-load] user skills loaded \u2014 ${Date.now()-r}ms, count: ${m.skills.length}`),jT.info({builtin:e.length,skillhub:xke.length,project:u.skills.length,user:m.skills.length,total:s.list().length},"Skills loaded"),s}function Ldn(){return new wke}async function tmt(n){let e=(0,lx.join)(n,".index.json");try{if((0,zde.existsSync)(e)){let{unlink:r}=await import("fs/promises");await r(e)}}catch{}}function nmt(n,e){return n.platforms&&n.platforms.length>0&&!n.platforms.includes(e.platform)?"unsupported":n.prerequisites?.env_vars&&n.prerequisites.env_vars.filter(s=>!e.hasEnvVar(s)).length>0||n.prerequisites?.commands&&n.prerequisites.commands.filter(s=>!e.hasCommand(s)).length>0||n.conditions?.requires_tools&&n.conditions.requires_tools.filter(s=>!e.availableTools.includes(s)).length>0||n.conditions?.requires_toolsets&&n.conditions.requires_toolsets.filter(s=>!e.availableToolsets.includes(s)).length>0?"setup_needed":"available"}function Odn(n,e){return n.filter(r=>!(r.platforms&&r.platforms.length>0&&!r.platforms.includes(e.platform)||r.conditions?.fallback_for_tools&&r.conditions.fallback_for_tools.some(a=>e.availableTools.includes(a))||r.conditions?.fallback_for_toolsets&&r.conditions.fallback_for_toolsets.some(a=>e.availableToolsets.includes(a))))}var Ky,lx,zde,Ndn,jT,wke,Ake=kt(()=>{"use strict";F();Ky=require("fs/promises"),lx=require("path"),zde=require("fs"),Ndn=require("fs/promises");HI();Tu();Ddn();Yf();jT=ks("skill-loader"),wke=class{skills=new Map;categories=new Map;eventHandlers=new Set;get(e){return this.skills.get(e)}has(e){return this.skills.has(e)}register(e){this.skills.set(e.name,e),this.emit({type:"skill_registered",skillName:e.name,source:e.source}),jT.debug({name:e.name,source:e.source},"Skill registered")}unregister(e){this.skills.delete(e),this.emit({type:"skill_unregistered",skillName:e}),jT.debug({name:e},"Skill unregistered")}list(){return Array.from(this.skills.values())}listBySource(e){return this.list().filter(r=>r.source===e)}search(e){let r=e.toLowerCase();return this.list().filter(s=>s.name.toLowerCase().includes(r)||s.description.toLowerCase().includes(r)||s.whenToUse?.toLowerCase().includes(r))}listByCategory(e){return this.list().filter(r=>r.category===e)}listCategories(){let e=new Set;for(let a of this.list())a.category&&e.add(a.category);let r=[],s=new Set;for(let[a,u]of this.categories)e.has(a)&&!s.has(a)&&(r.push(u),s.add(a));for(let a of e)s.has(a)||(r.push({name:a,description:void 0}),s.add(a));return r}updateCategories(e){for(let[r,s]of e)this.categories.set(r,{name:r,description:s||void 0})}onEvent(e){return this.eventHandlers.add(e),()=>this.eventHandlers.delete(e)}loadFrom(e){for(let r of e.list())this.skills.has(r.name)||this.skills.set(r.name,r)}emit(e){if(this.eventHandlers.size!==0)for(let r of this.eventHandlers)try{r(e)}catch(s){jT.warn({error:String(s)},"Error in skill event handler")}}}});var fY,rmt,imt,omt,dY,smt=kt(()=>{"use strict";F();fY=require("node:fs/promises"),rmt=require("node:path"),imt=require("node:fs"),omt=Do(require("node:https"),1);lP();lP();Yf();dY=class{_cachePath;_registryBase;_checkIntervalMs;_enabled;constructor(e){this._cachePath=(0,rmt.join)(e?.dataDir??Ks,GZt),this._registryBase=e?.registryBase??"https://registry.npmjs.org",this._checkIntervalMs=e?.checkIntervalMs??jZt,this._enabled=e?.enabled??!0}async checkForUpdate(e){if(!this._enabled)return null;if(!e?.force){let f=await this._loadCache();if(f&&Date.now()-new Date(f.lastCheckTime).getTime()<this._checkIntervalMs)return{hasUpdate:this._isNewer(f.latestVersion,ES),currentVersion:ES,latestVersion:f.latestVersion,checkedAt:f.lastCheckTime}}let r=await this._fetchLatestVersion();if(!r)return null;let s=this._isNewer(r,ES),a=new Date().toISOString(),u={lastCheckTime:a,latestVersion:r,currentVersionAtCheck:ES,hasUpdate:s};return await this._saveCache(u),{hasUpdate:s,currentVersion:ES,latestVersion:r,checkedAt:a}}async checkInBackground(){try{return await this.checkForUpdate()}catch{return null}}async getCachedResult(){let e=await this._loadCache();return e?{hasUpdate:this._isNewer(e.latestVersion,ES),currentVersion:ES,latestVersion:e.latestVersion,checkedAt:e.lastCheckTime}:null}_isNewer(e,r){let s=e.replace(/^v/,"").split(".").map(Number),a=r.replace(/^v/,"").split(".").map(Number);for(let u=0;u<3;u++){if((s[u]??0)>(a[u]??0))return!0;if((s[u]??0)<(a[u]??0))return!1}return!1}_fetchLatestVersion(){let e=`${this._registryBase}/aggroot/latest`;return new Promise(r=>{let s=setTimeout(()=>{a.destroy(),r(null)},aat),a=omt.default.get(e,u=>{if(u.statusCode===301||u.statusCode===302){let m=u.headers.location;if(m){clearTimeout(s),r(this._fetchFromUrl(m));return}}if(u.statusCode!==200){clearTimeout(s),u.resume(),r(null);return}let f="";u.on("data",m=>{f+=m.toString()}),u.on("end",()=>{clearTimeout(s);try{let m=JSON.parse(f);r(m.version??null)}catch{r(null)}}),u.on("error",()=>{clearTimeout(s),r(null)})});a.on("error",()=>{clearTimeout(s),r(null)})})}_fetchFromUrl(e){return new Promise(r=>{let s=setTimeout(()=>{a.destroy(),r(null)},aat),a=omt.default.get(e,u=>{if(u.statusCode!==200){clearTimeout(s),u.resume(),r(null);return}let f="";u.on("data",m=>{f+=m.toString()}),u.on("end",()=>{clearTimeout(s);try{let m=JSON.parse(f);r(m.version??null)}catch{r(null)}})});a.on("error",()=>{clearTimeout(s),r(null)})})}async _loadCache(){try{if(!(0,imt.existsSync)(this._cachePath))return null;let e=await(0,fY.readFile)(this._cachePath,"utf-8");return JSON.parse(e)}catch{return null}}async _saveCache(e){try{let r=(0,rmt.join)(this._cachePath,"..");(0,imt.existsSync)(r)||await(0,fY.mkdir)(r,{recursive:!0}),await(0,fY.writeFile)(this._cachePath,JSON.stringify(e,null,2),"utf-8")}catch{}}}});var mY,amt,Pke,zdn,Bdn,lGr,pY,lmt=kt(()=>{"use strict";F();mY=require("node:fs/promises"),amt=require("node:path"),Pke=require("node:fs"),zdn=require("node:child_process"),Bdn=require("node:util");Yf();lP();lGr=(0,Bdn.promisify)(zdn.execFile),pY=class{_rollbackPath;constructor(e){this._rollbackPath=(0,amt.join)(e??Ks,$Zt)}async createBackup(e,r){let s={previousVersion:e,upgradedFrom:e,upgradedTo:"",upgradedAt:new Date().toISOString(),installPath:r};await this._save(s)}async markUpgraded(e){let r=await this._load();r&&(r.upgradedTo=e,await this._save(r))}async isRollbackAvailable(){let e=await this._load();return e!==null&&!!e.previousVersion}async getRollbackInfo(){return this._load()}async rollback(e){let r=await this._load();if(!r||!r.previousVersion)return{success:!1,version:"",error:"\u6CA1\u6709\u53EF\u56DE\u6EDA\u7684\u7248\u672C\u4FE1\u606F"};let s=e??"npm";try{let{stdout:a,stderr:u}=await lGr(s,["install","-g",`aggroot@${r.previousVersion}`],{timeout:PIe,encoding:"utf-8",shell:!0}),f=u?.trim();return f&&!f.includes("WARN")&&!f.includes("warn")?{success:!1,version:r.previousVersion,error:f}:(await this.clearRollback(),{success:!0,version:r.previousVersion})}catch(a){return{success:!1,version:r.previousVersion,error:a.message??String(a)}}}async clearRollback(){try{if((0,Pke.existsSync)(this._rollbackPath)){let{unlink:e}=await import("node:fs/promises");await e(this._rollbackPath)}}catch{}}async _load(){try{if(!(0,Pke.existsSync)(this._rollbackPath))return null;let e=await(0,mY.readFile)(this._rollbackPath,"utf-8");return JSON.parse(e)}catch{return null}}async _save(e){try{let r=(0,amt.join)(this._rollbackPath,"..");(0,Pke.existsSync)(r)||await(0,mY.mkdir)(r,{recursive:!0}),await(0,mY.writeFile)(this._rollbackPath,JSON.stringify(e,null,2),"utf-8")}catch{}}}});var kke,jdn,Gdn,cmt,Rke,Dke,$dn=kt(()=>{"use strict";F();kke=require("node:child_process"),jdn=require("node:util"),Gdn=require("node:fs"),cmt=require("node:path");lP();lP();smt();lmt();Rke=(0,jdn.promisify)(kke.execFile),Dke=class{_updateChecker;_rollbackManager;constructor(e){this._updateChecker=new dY({dataDir:e?.dataDir}),this._rollbackManager=new pY(e?.dataDir)}get updateChecker(){return this._updateChecker}get rollbackManager(){return this._rollbackManager}async getInstallInfo(){let e=await this._findNpm(),r=await this._isNpmGlobalInstall(),s="";if(e)try{let{stdout:a}=await Rke(e,["root","-g"],{timeout:1e4,encoding:"utf-8",shell:!0});s=(0,cmt.join)(a.trim(),"@aggroot-team","aggroot")}catch{}return{isNpmGlobalInstall:r,installPath:s,version:ES,npmPath:e}}async upgrade(e,r,s){let a=ES;e?.({step:"checking-env",message:"\u6B63\u5728\u68C0\u67E5\u5347\u7EA7\u73AF\u5883...",percent:5});let u=r??await this.getInstallInfo();if(!u.npmPath)return{success:!1,fromVersion:a,toVersion:"",error:"\u672A\u627E\u5230 npm \u547D\u4EE4\uFF0C\u65E0\u6CD5\u6267\u884C\u5347\u7EA7\u3002\u8BF7\u786E\u4FDD npm \u5DF2\u5B89\u88C5\u5E76\u5728 PATH \u4E2D\u3002"};if(!u.isNpmGlobalInstall)return{success:!1,fromVersion:a,toVersion:"",error:"\u5F53\u524D\u975E npm \u5168\u5C40\u5B89\u88C5\uFF0C\u4E0D\u652F\u6301\u81EA\u52A8\u5347\u7EA7\u3002\u8BF7\u901A\u8FC7\u6E90\u7801\u65B9\u5F0F\u624B\u52A8\u66F4\u65B0\u3002"};e?.({step:"checking-version",message:"\u6B63\u5728\u68C0\u67E5\u6700\u65B0\u7248\u672C...",percent:15});let f=s??await this._updateChecker.checkForUpdate({force:!0});if(!f)return{success:!1,fromVersion:a,toVersion:"",error:"\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C\u4FE1\u606F\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u3002"};if(!f.hasUpdate)return{success:!1,fromVersion:a,toVersion:ES,error:`\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\u672C (${ES})`};let m=f.latestVersion;e?.({step:"backing-up",message:"\u6B63\u5728\u5907\u4EFD\u56DE\u6EDA\u4FE1\u606F...",percent:25}),await this._rollbackManager.createBackup(a,u.installPath),e?.({step:"downloading",message:`\u6B63\u5728\u4E0B\u8F7D aggroot@${m}...`,percent:30});let g=await this._spawnNpmInstall(m,e);return g.success?(e?.({step:"verifying",message:"\u6B63\u5728\u9A8C\u8BC1\u5B89\u88C5...",percent:90}),await this._verifyInstallation(u.npmPath,m)?(await this._rollbackManager.markUpgraded(m),e?.({step:"done",message:"\u5347\u7EA7\u5B8C\u6210",percent:100}),{success:!0,fromVersion:a,toVersion:m}):{success:!1,fromVersion:a,toVersion:m,error:"\u5B89\u88C5\u9A8C\u8BC1\u5931\u8D25\uFF0C\u65B0\u7248\u672C\u53EF\u80FD\u672A\u6B63\u786E\u5B89\u88C5\u3002\u8BF7\u624B\u52A8\u68C0\u67E5\u3002"}):{success:!1,fromVersion:a,toVersion:m,error:g.error??"npm \u5B89\u88C5\u5931\u8D25"}}async rollback(e){if(!(await this.getInstallInfo()).npmPath)return{success:!1,version:"",error:"\u672A\u627E\u5230 npm \u547D\u4EE4\uFF0C\u65E0\u6CD5\u6267\u884C\u56DE\u6EDA\u3002"};e?.({step:"installing",message:"\u6B63\u5728\u56DE\u6EDA\u5230\u4E0A\u4E00\u7248\u672C...",percent:30});let s=await this._rollbackManager.getRollbackInfo();if(!s)return{success:!1,version:"",error:"\u6CA1\u6709\u53EF\u56DE\u6EDA\u7684\u7248\u672C\u4FE1\u606F"};let a=await this._spawnNpmInstall(s.previousVersion,e);return a.success?(await this._rollbackManager.clearRollback(),e?.({step:"done",message:"\u56DE\u6EDA\u5B8C\u6210",percent:100}),{success:!0,version:s.previousVersion}):{success:!1,version:s.previousVersion,error:a.error}}async checkForUpdate(e){return this._updateChecker.checkForUpdate(e)}_spawnNpmInstall(e,r){return new Promise(s=>{let a=(0,kke.spawn)("npm",["install","-g",`@aggroot-team/aggroot@${e}`],{shell:!0,timeout:PIe}),u="";a.stdout?.on("data",f=>{let m=f.toString("utf-8");this._parseNpmProgress(m,e,r)}),a.stderr?.on("data",f=>{u+=f.toString("utf-8")}),a.on("close",f=>{if(f!==0){let g=u.split(`
1601
1601
  `).filter(b=>b.trim()&&!b.includes("WARN")&&!b.includes("warn"));u.includes("ERR!")?s({success:!1,error:`npm \u5B89\u88C5\u5931\u8D25: ${g.join(`
1602
1602
  `)}`}):s({success:!1,error:`npm \u5B89\u88C5\u5931\u8D25 (\u9000\u51FA\u7801: ${f})`});return}let m=u.split(`
1603
1603
  `).filter(g=>g.trim()&&!g.includes("WARN")&&!g.includes("warn"));if(m.length>0&&u.includes("ERR!")){s({success:!1,error:`npm \u5B89\u88C5\u5931\u8D25: ${m.join(`
1604
1604
  `)}`});return}s({success:!0})}),a.on("error",f=>{s({success:!1,error:`npm \u5B89\u88C5\u5931\u8D25: ${f.message}`})})})}_parseNpmProgress(e,r,s){if(!s)return;let a=e.split(`
1605
- `).filter(u=>u.trim());for(let u of a)u.includes("http")&&(u.includes("GET")||u.includes("fetch"))?s({step:"downloading",message:`\u6B63\u5728\u4E0B\u8F7D aggroot@${r}...`,percent:40}):u.includes("package")||u.includes("extract")||u.includes("preparing")?s({step:"installing",message:`\u6B63\u5728\u5B89\u88C5 aggroot@${r}...`,percent:60}):(u.includes("added")||u.includes("removed")||u.includes("changed"))&&s({step:"installing",message:`\u6B63\u5728\u5B8C\u6210\u5B89\u88C5 aggroot@${r}...`,percent:80})}async _findNpm(){try{return await Rke("npm",["--version"],{timeout:5e3,encoding:"utf-8",shell:!0}),"npm"}catch{return null}}async _isNpmGlobalInstall(){let e=await this._findNpm();if(!e)return!1;try{let{stdout:r}=await Rke(e,["root","-g"],{timeout:5e3,encoding:"utf-8",shell:!0}),s=r.trim();return(0,Gdn.existsSync)((0,cmt.join)(s,"aggroot"))}catch{return!1}}async _verifyInstallation(e,r){try{let{stdout:s}=await Rke("aggroot",["--version"],{timeout:1e4,encoding:"utf-8",shell:!0});return s.trim()===r}catch{return!0}}}});var Udn={};Gl(Udn,{RollbackManager:()=>pY,UpdateChecker:()=>dY,UpgradeExecutor:()=>Dke});var Vdn=kt(()=>{"use strict";F();smt();$dn();lmt()});var fmt={};Gl(fmt,{default:()=>Nke});function qC(n,e,r,s,a,u,f,m,g){return{id:`${n}:${e}`,type:"tool",pluginId:n,name:e,displayName:r,description:s,parameters:a,riskLevel:u,requiresConfirmation:f,execute:m,isConcurrencySafe:typeof g=="function"?g:()=>g??!1}}function Gde(n){let e=n.replace(/\0/g,""),r=[";","&","|","`","$","(",")","{","}","<",">",`
1605
+ `).filter(u=>u.trim());for(let u of a)u.includes("http")&&(u.includes("GET")||u.includes("fetch"))?s({step:"downloading",message:`\u6B63\u5728\u4E0B\u8F7D aggroot@${r}...`,percent:40}):u.includes("package")||u.includes("extract")||u.includes("preparing")?s({step:"installing",message:`\u6B63\u5728\u5B89\u88C5 aggroot@${r}...`,percent:60}):(u.includes("added")||u.includes("removed")||u.includes("changed"))&&s({step:"installing",message:`\u6B63\u5728\u5B8C\u6210\u5B89\u88C5 aggroot@${r}...`,percent:80})}async _findNpm(){try{return await Rke("npm",["--version"],{timeout:5e3,encoding:"utf-8",shell:!0}),"npm"}catch{return null}}async _isNpmGlobalInstall(){let e=await this._findNpm();if(!e)return!1;try{let{stdout:r}=await Rke(e,["root","-g"],{timeout:5e3,encoding:"utf-8",shell:!0}),s=r.trim();return(0,Gdn.existsSync)((0,cmt.join)(s,"@aggroot-team","aggroot"))}catch{return!1}}async _verifyInstallation(e,r){try{let{stdout:s}=await Rke("aggroot",["--version"],{timeout:1e4,encoding:"utf-8",shell:!0});return s.trim()===r}catch{return!0}}}});var Udn={};Gl(Udn,{RollbackManager:()=>pY,UpdateChecker:()=>dY,UpgradeExecutor:()=>Dke});var Vdn=kt(()=>{"use strict";F();smt();$dn();lmt()});var fmt={};Gl(fmt,{default:()=>Nke});function qC(n,e,r,s,a,u,f,m,g){return{id:`${n}:${e}`,type:"tool",pluginId:n,name:e,displayName:r,description:s,parameters:a,riskLevel:u,requiresConfirmation:f,execute:m,isConcurrencySafe:typeof g=="function"?g:()=>g??!1}}function Gde(n){let e=n.replace(/\0/g,""),r=[";","&","|","`","$","(",")","{","}","<",">",`
1606
1606
  `,"\r"];for(let s of r)if(e.includes(s))return{valid:!1,sanitized:"",error:`Invalid character in path: ${s}`};return e.includes("$(")||e.includes("`")?{valid:!1,sanitized:"",error:"Command substitution not allowed in path"}:e.includes("..")?{valid:!1,sanitized:"",error:"Path traversal not allowed"}:e.length>4096?{valid:!1,sanitized:"",error:"Path too long"}:{valid:!0,sanitized:e}}function cGr(n){if(!n||typeof n!="string")return{valid:!1,error:"Commit message is required",sanitized:""};let e=n.replace(/\0/g,"");return/\n.*--exec/i.test(e)?{valid:!1,error:"Invalid pattern in commit message: Git flag injection",sanitized:""}:e.length>4096?{valid:!1,error:"Commit message too long",sanitized:""}:{valid:!0,sanitized:e}}function cx(n,e){if(!n||typeof n!="string")return{valid:!1,error:`${e} is required`};let r=[";","&","|","`","$","(",")","{","}","<",">",'"',`
1607
1607
  `,"\r","\0"];for(let s of r)if(n.includes(s))return{valid:!1,error:`Invalid character in ${e}: ${s}`};return n.startsWith("--")?{valid:!1,error:`${e} must not start with --`}:n.length>1024?{valid:!1,error:`${e} too long`}:{valid:!0}}function uGr(n){if(n===".")return{valid:!0,sanitized:"."};let e=n.split(/\s+/).filter(s=>s.length>0),r=[];for(let s of e){let a=Gde(s);if(!a.valid)return{valid:!1,sanitized:"",error:`Invalid file path "${s}": ${a.error}`};r.push(a.sanitized)}return{valid:!0,sanitized:r.join(" ")}}function dGr(n){let e=[],r="",s=!1,a="";for(let u=0;u<n.length;u++){let f=n[u];s?f===a?s=!1:r+=f:f==='"'||f==="'"?(s=!0,a=f):f===" "||f===" "?r&&(e.push(r),r=""):r+=f}return r&&e.push(r),e}async function sk(n,e){let r=process.platform==="win32";return new Promise(s=>{try{if(e){let M=Gde(e);if(!M.valid){s({stdout:"",stderr:`Invalid working directory: ${M.error}`});return}e=M.sanitized}let a=dGr(n),u=(0,hY.spawn)("git",a,{cwd:e,stdio:["ignore","pipe","pipe"],env:QX({LANG:"en_US.UTF-8",LC_ALL:"en_US.UTF-8"}),...!r&&{detached:!0}}),f=!1,m=async()=>{try{r?u.pid&&await new Promise(M=>{(0,hY.execFile)("taskkill",["/pid",String(u.pid),"/T","/F"],{windowsHide:!0,timeout:5e3},()=>M())}):u.pid&&process.kill(-u.pid)}catch{}},g=setTimeout(async()=>{f||(f=!0,await m(),s({stdout:"",stderr:"Git command timed out after 60s"}))},6e4),b="",E="";u.stdout?.setEncoding("utf8"),u.stderr?.setEncoding("utf8");let A=2e4,C=8e3,L=!1,k=!1;u.stdout?.on("data",M=>{b+=M,b.length>A&&(b=b.slice(-C),L=!0)}),u.stderr?.on("data",M=>{E+=M,E.length>A&&(E=E.slice(-C),k=!0)}),u.on("close",()=>{if(f)return;f=!0,clearTimeout(g);let M=(U,H)=>H?`[...output truncated...]
1608
1608
  ${U}`:U;s({stdout:M(b,L),stderr:M(E,k)})}),u.on("error",M=>{f||(f=!0,clearTimeout(g),s({stdout:b,stderr:M.message??"Unknown error"}))})}catch(a){s({stdout:"",stderr:a.message??"Unknown error"})}})}async function fGr(n,e){let r=process.platform==="win32";return new Promise(s=>{try{if(e){let k=Gde(e);if(!k.valid){s({stdout:"",stderr:`Invalid working directory: ${k.error}`});return}e=k.sanitized}let a=(0,hY.spawn)("git",n,{cwd:e,stdio:["ignore","pipe","pipe"],env:QX({LANG:"en_US.UTF-8",LC_ALL:"en_US.UTF-8"}),...!r&&{detached:!0}}),u=!1,f=async()=>{try{r?a.pid&&await new Promise(k=>{(0,hY.execFile)("taskkill",["/pid",String(a.pid),"/T","/F"],{windowsHide:!0,timeout:5e3},()=>k())}):a.pid&&process.kill(-a.pid)}catch{}},m=setTimeout(async()=>{u||(u=!0,await f(),s({stdout:"",stderr:"Git command timed out after 60s"}))},6e4),g="",b="",E=!1,A=!1,C=2e4,L=8e3;a.stdout?.setEncoding("utf8"),a.stderr?.setEncoding("utf8"),a.stdout?.on("data",k=>{g+=k,g.length>C&&(g=g.slice(-L),E=!0)}),a.stderr?.on("data",k=>{b+=k,b.length>C&&(b=b.slice(-L),A=!0)}),a.on("close",()=>{if(u)return;u=!0,clearTimeout(m);let k=(M,U)=>U?`[...output truncated...]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aggroot-team/aggroot",
3
- "version": "1.7.9",
3
+ "version": "1.8.0",
4
4
  "description": "AggRoot - AI Assistant (Node.js/TypeScript Version)",
5
5
  "keywords": [
6
6
  "ai",