@lousy-agents/mcp 5.9.6 → 5.10.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.
@@ -42426,11 +42426,14 @@ var external_node_path_ = __webpack_require__(6760);
42426
42426
  * List of known action names for convenience
42427
42427
  */ const KNOWN_ACTIONS = Object.keys(DEFAULT_ACTION_VERSIONS);
42428
42428
 
42429
+ // EXTERNAL MODULE: external "node:fs"
42430
+ var external_node_fs_ = __webpack_require__(3024);
42429
42431
  ;// CONCATENATED MODULE: ../core/src/gateways/file-system-utils.ts
42430
42432
  /**
42431
42433
  * Shared file system utilities for gateways.
42432
42434
  */
42433
42435
 
42436
+
42434
42437
  /**
42435
42438
  * Checks if a file or directory exists.
42436
42439
  */ async function file_system_utils_fileExists(path) {
@@ -42500,6 +42503,44 @@ function isPathWithinRoot(rootPath, candidatePath) {
42500
42503
  throw new Error(`${context} exceeds size limit (${fileStats.size} bytes > ${maxBytes} bytes)`);
42501
42504
  }
42502
42505
  }
42506
+ /**
42507
+ * Reads a file atomically with symlink and size protection.
42508
+ *
42509
+ * Uses `O_NOFOLLOW` (where available) to atomically reject symlinks at
42510
+ * the kernel level, eliminating the TOCTOU window between `lstat()` and
42511
+ * `readFile()`. Falls back to `lstat()` on platforms without `O_NOFOLLOW`.
42512
+ * Validates file size via `fstat()` on the opened file descriptor so the
42513
+ * size check and the read operate on the same inode.
42514
+ */ async function file_system_utils_readFileNoFollow(filePath, maxBytes) {
42515
+ const hasNoFollow = typeof external_node_fs_.constants.O_NOFOLLOW === "number" && external_node_fs_.constants.O_NOFOLLOW !== 0;
42516
+ const safePath = JSON.stringify(filePath);
42517
+ let fh;
42518
+ if (hasNoFollow) {
42519
+ try {
42520
+ fh = await (0,promises_.open)(filePath, external_node_fs_.constants.O_RDONLY | external_node_fs_.constants.O_NOFOLLOW);
42521
+ } catch (error) {
42522
+ if (error instanceof Error && "code" in error && error.code === "ELOOP") {
42523
+ throw new Error(`Symlinks are not allowed: ${safePath}`);
42524
+ }
42525
+ throw error;
42526
+ }
42527
+ } else {
42528
+ const stats = await (0,promises_.lstat)(filePath);
42529
+ if (stats.isSymbolicLink()) {
42530
+ throw new Error(`Symlinks are not allowed: ${safePath}`);
42531
+ }
42532
+ fh = await (0,promises_.open)(filePath, external_node_fs_.constants.O_RDONLY);
42533
+ }
42534
+ try {
42535
+ const fdStats = await fh.stat();
42536
+ if (fdStats.size > maxBytes) {
42537
+ throw new Error(`File ${safePath} exceeds size limit (${fdStats.size} bytes > ${maxBytes} bytes)`);
42538
+ }
42539
+ return await fh.readFile("utf-8");
42540
+ } finally{
42541
+ await fh.close();
42542
+ }
42543
+ }
42503
42544
 
42504
42545
  ;// CONCATENATED MODULE: ../core/src/gateways/agent-file-gateway.ts
42505
42546
  /**
@@ -42611,8 +42652,6 @@ function isPathWithinRoot(rootPath, candidatePath) {
42611
42652
  "pip"
42612
42653
  ];
42613
42654
 
42614
- // EXTERNAL MODULE: external "node:fs"
42615
- var external_node_fs_ = __webpack_require__(3024);
42616
42655
  ;// CONCATENATED MODULE: ../../node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs
42617
42656
  let _lazyMatch = () => { var __lib__=(()=>{var m=Object.defineProperty,V=Object.getOwnPropertyDescriptor,G=Object.getOwnPropertyNames,T=Object.prototype.hasOwnProperty,q=(r,e)=>{for(var n in e)m(r,n,{get:e[n],enumerable:true});},H=(r,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of G(e))!T.call(r,t)&&t!==n&&m(r,t,{get:()=>e[t],enumerable:!(a=V(e,t))||a.enumerable});return r},J=r=>H(m({},"__esModule",{value:true}),r),w={};q(w,{default:()=>re});var A=r=>Array.isArray(r),d=r=>typeof r=="function",Q=r=>r.length===0,W=r=>typeof r=="number",K=r=>typeof r=="object"&&r!==null,X=r=>r instanceof RegExp,b=r=>typeof r=="string",h=r=>r===void 0,Y=r=>{const e=new Map;return n=>{const a=e.get(n);if(a)return a;const t=r(n);return e.set(n,t),t}},rr=(r,e,n={})=>{const a={cache:{},input:r,index:0,indexMax:0,options:n,output:[]};if(v(e)(a)&&a.index===r.length)return a.output;throw new Error(`Failed to parse at index ${a.indexMax}`)},i=(r,e)=>A(r)?er(r,e):b(r)?ar(r,e):nr(r,e),er=(r,e)=>{const n={};for(const a of r){if(a.length!==1)throw new Error(`Invalid character: "${a}"`);const t=a.charCodeAt(0);n[t]=true;}return a=>{const t=a.index,o=a.input;for(;a.index<o.length&&o.charCodeAt(a.index)in n;)a.index+=1;const u=a.index;if(u>t){if(!h(e)&&!a.options.silent){const s=a.input.slice(t,u),c=d(e)?e(s,o,String(t)):e;h(c)||a.output.push(c);}a.indexMax=Math.max(a.indexMax,a.index);}return true}},nr=(r,e)=>{const n=r.source,a=r.flags.replace(/y|$/,"y"),t=new RegExp(n,a);return g(o=>{t.lastIndex=o.index;const u=t.exec(o.input);if(u){if(!h(e)&&!o.options.silent){const s=d(e)?e(...u,o.input,String(o.index)):e;h(s)||o.output.push(s);}return o.index+=u[0].length,o.indexMax=Math.max(o.indexMax,o.index),true}else return false})},ar=(r,e)=>n=>{if(n.input.startsWith(r,n.index)){if(!h(e)&&!n.options.silent){const t=d(e)?e(r,n.input,String(n.index)):e;h(t)||n.output.push(t);}return n.index+=r.length,n.indexMax=Math.max(n.indexMax,n.index),true}else return false},C=(r,e,n,a)=>{const t=v(r);return g(_(M(o=>{let u=0;for(;u<n;){const s=o.index;if(!t(o)||(u+=1,o.index===s))break}return u>=e})))},tr=(r,e)=>C(r,0,1),f=(r,e)=>C(r,0,1/0),x=(r,e)=>{const n=r.map(v);return g(_(M(a=>{for(let t=0,o=n.length;t<o;t++)if(!n[t](a))return false;return true})))},l=(r,e)=>{const n=r.map(v);return g(_(a=>{for(let t=0,o=n.length;t<o;t++)if(n[t](a))return true;return false}))},M=(r,e=false)=>{const n=v(r);return a=>{const t=a.index,o=a.output.length,u=n(a);return (!u||e)&&(a.index=t,a.output.length!==o&&(a.output.length=o)),u}},_=(r,e)=>{const n=v(r);return n},g=(()=>{let r=0;return e=>{const n=v(e),a=r+=1;return t=>{var o;if(t.options.memoization===false)return n(t);const u=t.index,s=(o=t.cache)[a]||(o[a]=new Map),c=s.get(u);if(c===false)return false;if(W(c))return t.index=c,true;if(c)return t.index=c.index,c.output?.length&&t.output.push(...c.output),true;{const Z=t.output.length;if(n(t)){const D=t.index,U=t.output.length;if(U>Z){const ee=t.output.slice(Z,U);s.set(u,{index:D,output:ee});}else s.set(u,D);return true}else return s.set(u,false),false}}}})(),E=r=>{let e;return n=>(e||(e=v(r())),e(n))},v=Y(r=>{if(d(r))return Q(r)?E(r):r;if(b(r)||X(r))return i(r);if(A(r))return x(r);if(K(r))return l(Object.values(r));throw new Error("Invalid rule")}),P="abcdefghijklmnopqrstuvwxyz",ir=r=>{let e="";for(;r>0;){const n=(r-1)%26;e=P[n]+e,r=Math.floor((r-1)/26);}return e},O=r=>{let e=0;for(let n=0,a=r.length;n<a;n++)e=e*26+P.indexOf(r[n])+1;return e},S=(r,e)=>{if(e<r)return S(e,r);const n=[];for(;r<=e;)n.push(r++);return n},or=(r,e,n)=>S(r,e).map(a=>String(a).padStart(n,"0")),R=(r,e)=>S(O(r),O(e)).map(ir),p=r=>r,z=r=>ur(e=>rr(e,r,{memoization:false}).join("")),ur=r=>{const e={};return n=>e[n]??(e[n]=r(n))},sr=i(/^\*\*\/\*$/,".*"),cr=i(/^\*\*\/(\*)?([ a-zA-Z0-9._-]+)$/,(r,e,n)=>`.*${e?"":"(?:^|/)"}${n.replaceAll(".","\\.")}`),lr=i(/^\*\*\/(\*)?([ a-zA-Z0-9._-]*)\{([ a-zA-Z0-9._-]+(?:,[ a-zA-Z0-9._-]+)*)\}$/,(r,e,n,a)=>`.*${e?"":"(?:^|/)"}${n.replaceAll(".","\\.")}(?:${a.replaceAll(",","|").replaceAll(".","\\.")})`),y=i(/\\./,p),pr=i(/[$.*+?^(){}[\]\|]/,r=>`\\${r}`),vr=i(/./,p),hr=i(/^(?:!!)*!(.*)$/,(r,e)=>`(?!^${L(e)}$).*?`),dr=i(/^(!!)+/,""),fr=l([hr,dr]),xr=i(/\/(\*\*\/)+/,"(?:/.+/|/)"),gr=i(/^(\*\*\/)+/,"(?:^|.*/)"),mr=i(/\/(\*\*)$/,"(?:/.*|$)"),_r=i(/\*\*/,".*"),j=l([xr,gr,mr,_r]),Sr=i(/\*\/(?!\*\*\/)/,"[^/]*/"),yr=i(/\*/,"[^/]*"),N=l([Sr,yr]),k=i("?","[^/]"),$r=i("[",p),wr=i("]",p),Ar=i(/[!^]/,"^/"),br=i(/[a-z]-[a-z]|[0-9]-[0-9]/i,p),Cr=i(/[$.*+?^(){}[\|]/,r=>`\\${r}`),Mr=i(/[^\]]/,p),Er=l([y,Cr,br,Mr]),B=x([$r,tr(Ar),f(Er),wr]),Pr=i("{","(?:"),Or=i("}",")"),Rr=i(/(\d+)\.\.(\d+)/,(r,e,n)=>or(+e,+n,Math.min(e.length,n.length)).join("|")),zr=i(/([a-z]+)\.\.([a-z]+)/,(r,e,n)=>R(e,n).join("|")),jr=i(/([A-Z]+)\.\.([A-Z]+)/,(r,e,n)=>R(e.toLowerCase(),n.toLowerCase()).join("|").toUpperCase()),Nr=l([Rr,zr,jr]),I=x([Pr,Nr,Or]),kr=i("{","(?:"),Br=i("}",")"),Ir=i(",","|"),Fr=i(/[$.*+?^(){[\]\|]/,r=>`\\${r}`),Lr=i(/[^}]/,p),Zr=E(()=>F),Dr=l([j,N,k,B,I,Zr,y,Fr,Ir,Lr]),F=x([kr,f(Dr),Br]),Ur=f(l([sr,cr,lr,fr,j,N,k,B,I,F,y,pr,vr])),Vr=Ur,Gr=z(Vr),L=Gr,Tr=i(/\\./,p),qr=i(/./,p),Hr=i(/\*\*\*+/,"*"),Jr=i(/([^/{[(!])\*\*/,(r,e)=>`${e}*`),Qr=i(/(^|.)\*\*(?=[^*/)\]}])/,(r,e)=>`${e}*`),Wr=f(l([Tr,Hr,Jr,Qr,qr])),Kr=Wr,Xr=z(Kr),Yr=Xr,$=(r,e)=>{const n=Array.isArray(r)?r:[r];if(!n.length)return false;const a=n.map($.compile),t=n.every(s=>/(\/(?:\*\*)?|\[\/\])$/.test(s)),o=e.replace(/[\\\/]+/g,"/").replace(/\/$/,t?"/":"");return a.some(s=>s.test(o))};$.compile=r=>new RegExp(`^${L(Yr(r))}$`,"s");var re=$;return J(w)})();
42618
42657
  return __lib__.default || __lib__; };
@@ -47728,6 +47767,7 @@ var yaml_dist = __webpack_require__(3519);
47728
47767
 
47729
47768
 
47730
47769
 
47770
+ /** Maximum skill file size: 1 MB */ const MAX_SKILL_FILE_BYTES = 1_048_576;
47731
47771
  /**
47732
47772
  * Skill directory locations to search for SKILL.md files.
47733
47773
  */ const SKILL_DIRECTORIES = [
@@ -47747,12 +47787,29 @@ var yaml_dist = __webpack_require__(3519);
47747
47787
  return skills;
47748
47788
  }
47749
47789
  async discoverSkillsInDir(skillsDir) {
47750
- if (!await fileExists(skillsDir)) {
47790
+ let dirStats;
47791
+ try {
47792
+ dirStats = await lstat(skillsDir);
47793
+ } catch (error) {
47794
+ if (error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
47795
+ return [];
47796
+ }
47797
+ throw error;
47798
+ }
47799
+ if (dirStats.isSymbolicLink() || !dirStats.isDirectory()) {
47751
47800
  return [];
47752
47801
  }
47753
- const entries = await readdir(skillsDir, {
47754
- withFileTypes: true
47755
- });
47802
+ let entries;
47803
+ try {
47804
+ entries = await readdir(skillsDir, {
47805
+ withFileTypes: true
47806
+ });
47807
+ } catch (error) {
47808
+ if (error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
47809
+ return [];
47810
+ }
47811
+ throw error;
47812
+ }
47756
47813
  const skills = [];
47757
47814
  for (const entry of entries){
47758
47815
  if (!entry.isDirectory()) {
@@ -47762,7 +47819,17 @@ var yaml_dist = __webpack_require__(3519);
47762
47819
  continue;
47763
47820
  }
47764
47821
  const skillFilePath = join(skillsDir, entry.name, "SKILL.md");
47765
- if (await fileExists(skillFilePath)) {
47822
+ let skillStat;
47823
+ try {
47824
+ skillStat = await lstat(skillFilePath);
47825
+ } catch (error) {
47826
+ if (error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
47827
+ skillStat = null;
47828
+ } else {
47829
+ throw error;
47830
+ }
47831
+ }
47832
+ if (skillStat && !skillStat.isSymbolicLink() && skillStat.isFile()) {
47766
47833
  skills.push({
47767
47834
  filePath: skillFilePath,
47768
47835
  skillName: entry.name
@@ -47772,7 +47839,7 @@ var yaml_dist = __webpack_require__(3519);
47772
47839
  return skills;
47773
47840
  }
47774
47841
  async readSkillFileContent(filePath) {
47775
- return readFile(filePath, "utf-8");
47842
+ return readFileNoFollow(filePath, MAX_SKILL_FILE_BYTES);
47776
47843
  }
47777
47844
  parseFrontmatter(content) {
47778
47845
  const lines = content.split("\n");
@@ -67314,11 +67381,12 @@ const remark = unified().use(remarkParse).use(remarkStringify).freeze()
67314
67381
  */
67315
67382
 
67316
67383
 
67384
+ /** Maximum instruction file size: 1 MB */ const MAX_INSTRUCTION_FILE_BYTES = 1_048_576;
67317
67385
  /**
67318
67386
  * Remark-based implementation of the Markdown AST gateway.
67319
67387
  */ class RemarkMarkdownAstGateway {
67320
67388
  async parseFile(filePath) {
67321
- const content = await (0,promises_.readFile)(filePath, "utf-8");
67389
+ const content = await file_system_utils_readFileNoFollow(filePath, MAX_INSTRUCTION_FILE_BYTES);
67322
67390
  return this.parseContent(content);
67323
67391
  }
67324
67392
  parseContent(content) {