superpowers-mcp 6.3.7 → 6.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,29 +1,29 @@
1
- "use strict";var T=Object.create;var b=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var W=Object.getOwnPropertyNames;var q=Object.getPrototypeOf,N=Object.prototype.hasOwnProperty;var L=(t,e)=>{for(var o in e)b(t,o,{get:e[o],enumerable:!0})},_=(t,e,o,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of W(e))!N.call(t,r)&&r!==o&&b(t,r,{get:()=>e[r],enumerable:!(s=O(e,r))||s.enumerable});return t};var P=(t,e,o)=>(o=t!=null?T(q(t)):{},_(e||!t||!t.__esModule?b(o,"default",{value:t,enumerable:!0}):o,t)),H=t=>_(b({},"__esModule",{value:!0}),t);var J={};L(J,{HARNESS_CONFIGS:()=>k,isPlainObject:()=>A,runSetup:()=>U,runSetupCli:()=>K,safeWriteConfig:()=>D,stripJsonComments:()=>R,updateJsonConfig:()=>I,updateYamlConfig:()=>E});module.exports=H(J);var p=P(require("fs")),n=P(require("path")),v=P(require("os")),$=P(require("crypto")),k={copilot:{name:"GitHub Copilot (VS Code)",aliases:["vscode","code","copilot"],getConfigPath:(t,e,o,s)=>t==="win32"?n.join(o||n.join(e,"AppData","Roaming"),"Code","User","mcp.json"):t==="darwin"?n.join(e,"Library","Application Support","Code","User","mcp.json"):n.join(e,".config","Code","User","mcp.json"),type:"json-servers",defaultConfig:(t,e)=>({command:t,args:e,type:"stdio"})},"copilot-insiders":{name:"GitHub Copilot (VS Code Insiders)",aliases:["vscode-insiders","code-insiders","insiders","insider","vscode-insider","code-insider","copilot-insider"],getConfigPath:(t,e,o,s)=>t==="win32"?n.join(o||n.join(e,"AppData","Roaming"),"Code - Insiders","User","mcp.json"):t==="darwin"?n.join(e,"Library","Application Support","Code - Insiders","User","mcp.json"):n.join(e,".config","Code - Insiders","User","mcp.json"),type:"json-servers",defaultConfig:(t,e)=>({command:t,args:e,type:"stdio"})},cursor:{name:"Cursor",aliases:["cursor"],getConfigPath:(t,e)=>n.join(e,".cursor","mcp.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},hermes:{name:"Hermes Desktop / Agent",aliases:["hermes","hermes-desktop"],getConfigPath:(t,e,o,s)=>{if(t==="win32"){let r=s||n.join(e,"AppData","Local");return n.join(r,"hermes","config.yaml")}return n.join(e,".hermes","config.yaml")},type:"yaml",defaultConfig:(t,e)=>({command:t,args:e})},kimi:{name:"Kimi Work / Kimi Code",aliases:["kimi","kimi-work","kimi-code"],getConfigPath:(t,e)=>n.join(e,".kimi-code","mcp.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},claude:{name:"Claude Desktop",aliases:["claude","claude-desktop"],getConfigPath:(t,e,o)=>t==="win32"?n.join(o||n.join(e,"AppData","Roaming"),"Claude","claude_desktop_config.json"):t==="darwin"?n.join(e,"Library","Application Support","Claude","claude_desktop_config.json"):n.join(e,".config","Claude","claude_desktop_config.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},devin:{name:"Devin Desktop (formerly Windsurf)",aliases:["devin","devin-desktop","windsurf","codeium"],getConfigPath:(t,e)=>{let o=n.join(e,".config","devin","mcp_config.json");return p.existsSync(o)?o:n.join(e,".codeium","windsurf","mcp_config.json")},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},antigravity:{name:"Antigravity (Google DeepMind)",aliases:["antigravity","agy","gemini"],getConfigPath:(t,e)=>n.join(e,".gemini","config","mcp_config.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},"pi-desktop":{name:"Pi Desktop / Pi Agent",aliases:["pi-desktop","pi","pi-agent"],getConfigPath:(t,e,o)=>{if(t==="win32"){let f=n.join(o||n.join(e,"AppData","Roaming"),".pi","agent","mcp.json");if(p.existsSync(f))return f;let a=n.join(e,".pi","agent","mcp.json");if(p.existsSync(a))return a;let g=n.join(e,".pi","mcp.json");return p.existsSync(g)?g:a}let s=n.join(e,".pi","agent","mcp.json");if(p.existsSync(s))return s;let r=n.join(e,".pi","mcp.json");return p.existsSync(r)?r:s},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},qwenpaw:{name:"QwenPaw (Personal Agent Workstation)",aliases:["qwenpaw","qwen-paw","copaw"],getConfigPath:(t,e)=>{let o=n.join(e,".qwenpaw","config.json");if(p.existsSync(o))return o;let s=n.join(e,".copaw","config.json");return p.existsSync(s)?s:o},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},cline:{name:"Cline (VS Code / CLI)",aliases:["cline","claude-dev"],getConfigPath:(t,e,o)=>{let s="";if(t==="win32"?s=n.join(o||n.join(e,"AppData","Roaming"),"Code","User","globalStorage","saoudrizwan.claude-dev","settings","cline_mcp_settings.json"):t==="darwin"?s=n.join(e,"Library","Application Support","Code","User","globalStorage","saoudrizwan.claude-dev","settings","cline_mcp_settings.json"):s=n.join(e,".config","Code","User","globalStorage","saoudrizwan.claude-dev","settings","cline_mcp_settings.json"),p.existsSync(s))return s;let r=n.join(e,".cline","data","settings","cline_mcp_settings.json");return p.existsSync(r)?r:s},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},kilo:{name:"Kilo Code",aliases:["kilo","kilocode","kilo-code"],getConfigPath:(t,e)=>{let o=n.join(e,".config","kilo","kilo.jsonc");if(p.existsSync(o))return o;let s=n.join(e,".config","kilo","kilo.json");return p.existsSync(s)?s:o},type:"json-mcp",defaultConfig:(t,e)=>({type:"local",command:[t,...e],enabled:!0})},qoder:{name:"Qoder",aliases:["qoder"],getConfigPath:(t,e)=>n.join(e,".qoder","settings.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},kiro:{name:"Kiro",aliases:["kiro","kiro-code"],getConfigPath:(t,e)=>n.join(e,".kiro","settings","mcp.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},trae:{name:"Trae",aliases:["trae"],getConfigPath:(t,e,o)=>{if(t==="win32"){let s=n.join(o||n.join(e,"AppData","Roaming"),"Trae","User","mcp.json");if(p.existsSync(s))return s;let r=n.join(o||n.join(e,"AppData","Roaming"),"Trae CN","User","mcp.json");return p.existsSync(r)?r:s}else if(t==="darwin"){let s=n.join(e,"Library","Application Support","Trae","User","mcp.json");if(p.existsSync(s))return s;let r=n.join(e,"Library","Application Support","Trae CN","User","mcp.json");return p.existsSync(r)?r:s}else{let s=n.join(e,".config","Trae","User","mcp.json");if(p.existsSync(s))return s;let r=n.join(e,".config","Trae CN","User","mcp.json");return p.existsSync(r)?r:s}},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})}};function A(t){return Object.prototype.toString.call(t)==="[object Object]"}function R(t,e=!1){if(!t)return"";if(!e)try{return JSON.parse(t),t}catch{}let o=t.length,s=[],r=!1,f=!1,a=!1,g=!1,l=-1;for(let c=0;c<o;c++){let i=t[c],u=c+1<o?t[c+1]:"";if(a){(i===`
2
- `||i==="\r")&&(a=!1,s.push(i));continue}if(g){i==="*"&&u==="/"&&(g=!1,c++);continue}if(r){s.push(i),f?f=!1:i==="\\"?f=!0:i==='"'&&(r=!1);continue}if(i==='"'){r=!0,f=!1,l=-1,s.push(i);continue}if(i==="/"&&u==="/"){a=!0,c++;continue}if(i==="/"&&u==="*"){g=!0,c++;continue}if(i===","){l=s.length,s.push(i);continue}if(i==="}"||i==="]"){l!==-1&&(s[l]=" ",l=-1),s.push(i);continue}i!==" "&&i!==" "&&i!==`
3
- `&&i!=="\r"&&(l=-1),s.push(i)}return s.join("")}function E(t,e,o,s=!1){let r=t?t.split(/\r?\n/):[];if(s){let u=[],d=!1,h=0,m=!1,w=0;for(let j=0;j<r.length;j++){let y=r[j],C=y.match(/^(\s*)mcp_servers:\s*$/);if(C){d=!0,h=C[1].length,u.push(y);continue}if(d){let S=y.match(/^(\s*)/)?.[1].length||0;if(y.trim()!==""&&S<=h)d=!1,m=!1;else{let x=y.match(/^(\s*)superpowers:\s*$/);if(x&&x[1].length>h){m=!0,w=x[1].length;continue}if(m){if(S>w||y.trim()==="")continue;m=!1}}}u.push(y)}return u.join(`
4
- `)}let f=" ";for(let u of r){let d=u.match(/^(\s+)[a-zA-Z0-9_-]+:/);if(d&&d[1].length>0){f=d[1];break}}let a=JSON.stringify(e),g=JSON.stringify(o),l=[`${f}superpowers:`,`${f}${f}command: ${a}`,`${f}${f}args: ${g}`];if(!t||t.trim()==="")return`mcp_servers:
5
- ${l.join(`
1
+ "use strict";var N=Object.create;var P=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var J=Object.getPrototypeOf,M=Object.prototype.hasOwnProperty;var H=(t,e)=>{for(var r in e)P(t,r,{get:e[r],enumerable:!0})},$=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of L(e))!M.call(t,o)&&o!==r&&P(t,o,{get:()=>e[o],enumerable:!(n=q(e,o))||n.enumerable});return t};var A=(t,e,r)=>(r=t!=null?N(J(t)):{},$(e||!t||!t.__esModule?P(r,"default",{value:t,enumerable:!0}):r,t)),K=t=>$(P({},"__esModule",{value:!0}),t);var G={};H(G,{HARNESS_CONFIGS:()=>b,isPlainObject:()=>_,runSetup:()=>O,runSetupCli:()=>F,safeWriteConfig:()=>T,stripJsonComments:()=>D,updateJsonConfig:()=>I,updateYamlConfig:()=>W});module.exports=K(G);var a=A(require("fs")),s=A(require("path")),x=A(require("os")),R=A(require("crypto")),b={copilot:{name:"GitHub Copilot (VS Code)",aliases:["vscode","code","copilot"],getConfigPath:(t,e,r,n)=>t==="win32"?s.join(r||s.join(e,"AppData","Roaming"),"Code","User","mcp.json"):t==="darwin"?s.join(e,"Library","Application Support","Code","User","mcp.json"):s.join(e,".config","Code","User","mcp.json"),type:"json-servers",defaultConfig:(t,e)=>({command:t,args:e,type:"stdio"})},"copilot-insiders":{name:"GitHub Copilot (VS Code Insiders)",aliases:["vscode-insiders","code-insiders","insiders","insider","vscode-insider","code-insider","copilot-insider"],getConfigPath:(t,e,r,n)=>t==="win32"?s.join(r||s.join(e,"AppData","Roaming"),"Code - Insiders","User","mcp.json"):t==="darwin"?s.join(e,"Library","Application Support","Code - Insiders","User","mcp.json"):s.join(e,".config","Code - Insiders","User","mcp.json"),type:"json-servers",defaultConfig:(t,e)=>({command:t,args:e,type:"stdio"})},cursor:{name:"Cursor",aliases:["cursor"],getConfigPath:(t,e)=>s.join(e,".cursor","mcp.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},hermes:{name:"Hermes Desktop / Agent",aliases:["hermes","hermes-desktop"],getConfigPath:(t,e,r,n)=>{if(t==="win32"){let o=n||s.join(e,"AppData","Local");return s.join(o,"hermes","config.yaml")}return s.join(e,".hermes","config.yaml")},type:"yaml",defaultConfig:(t,e)=>({command:t,args:e})},kimi:{name:"Kimi Work / Kimi Code",aliases:["kimi","kimi-work","kimi-code"],getConfigPath:(t,e)=>s.join(e,".kimi-code","mcp.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},claude:{name:"Claude Desktop",aliases:["claude","claude-desktop"],getConfigPath:(t,e,r)=>t==="win32"?s.join(r||s.join(e,"AppData","Roaming"),"Claude","claude_desktop_config.json"):t==="darwin"?s.join(e,"Library","Application Support","Claude","claude_desktop_config.json"):s.join(e,".config","Claude","claude_desktop_config.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},devin:{name:"Devin Desktop (formerly Windsurf)",aliases:["devin","devin-desktop","windsurf","codeium"],getConfigPath:(t,e)=>{let r=s.join(e,".config","devin","mcp_config.json");return a.existsSync(r)?r:s.join(e,".codeium","windsurf","mcp_config.json")},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},antigravity:{name:"Antigravity (Google DeepMind)",aliases:["antigravity","agy","gemini"],getConfigPath:(t,e)=>s.join(e,".gemini","config","mcp_config.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},"pi-desktop":{name:"Pi Desktop / Pi Agent",aliases:["pi-desktop","pi","pi-agent"],getConfigPath:(t,e,r)=>{if(t==="win32"){let p=s.join(r||s.join(e,"AppData","Roaming"),".pi","agent","mcp.json");if(a.existsSync(p))return p;let i=s.join(e,".pi","agent","mcp.json");if(a.existsSync(i))return i;let d=s.join(e,".pi","mcp.json");return a.existsSync(d)?d:i}let n=s.join(e,".pi","agent","mcp.json");if(a.existsSync(n))return n;let o=s.join(e,".pi","mcp.json");return a.existsSync(o)?o:n},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},qwenpaw:{name:"QwenPaw (Personal Agent Workstation)",aliases:["qwenpaw","qwen-paw","copaw"],getConfigPath:(t,e)=>{let r=s.join(e,".qwenpaw","config.json");if(a.existsSync(r))return r;let n=s.join(e,".copaw","config.json");return a.existsSync(n)?n:r},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},cline:{name:"Cline (VS Code / CLI)",aliases:["cline","claude-dev"],getConfigPath:(t,e,r)=>{let n="";if(t==="win32"?n=s.join(r||s.join(e,"AppData","Roaming"),"Code","User","globalStorage","saoudrizwan.claude-dev","settings","cline_mcp_settings.json"):t==="darwin"?n=s.join(e,"Library","Application Support","Code","User","globalStorage","saoudrizwan.claude-dev","settings","cline_mcp_settings.json"):n=s.join(e,".config","Code","User","globalStorage","saoudrizwan.claude-dev","settings","cline_mcp_settings.json"),a.existsSync(n))return n;let o=s.join(e,".cline","data","settings","cline_mcp_settings.json");return a.existsSync(o)?o:n},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},kilo:{name:"Kilo Code",aliases:["kilo","kilocode","kilo-code"],getConfigPath:(t,e)=>{let r=s.join(e,".config","kilo","kilo.jsonc");if(a.existsSync(r))return r;let n=s.join(e,".config","kilo","kilo.json");return a.existsSync(n)?n:r},type:"json-mcp",defaultConfig:(t,e)=>({type:"local",command:[t,...e],enabled:!0})},qoder:{name:"Qoder",aliases:["qoder"],getConfigPath:(t,e)=>s.join(e,".qoder","settings.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},kiro:{name:"Kiro",aliases:["kiro","kiro-code"],getConfigPath:(t,e)=>s.join(e,".kiro","settings","mcp.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},trae:{name:"Trae",aliases:["trae"],getConfigPath:(t,e,r)=>{if(t==="win32"){let n=s.join(r||s.join(e,"AppData","Roaming"),"Trae","User","mcp.json");if(a.existsSync(n))return n;let o=s.join(r||s.join(e,"AppData","Roaming"),"Trae CN","User","mcp.json");return a.existsSync(o)?o:n}else if(t==="darwin"){let n=s.join(e,"Library","Application Support","Trae","User","mcp.json");if(a.existsSync(n))return n;let o=s.join(e,"Library","Application Support","Trae CN","User","mcp.json");return a.existsSync(o)?o:n}else{let n=s.join(e,".config","Trae","User","mcp.json");if(a.existsSync(n))return n;let o=s.join(e,".config","Trae CN","User","mcp.json");return a.existsSync(o)?o:n}},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})}};function _(t){return Object.prototype.toString.call(t)==="[object Object]"}function D(t,e=!1){if(!t)return"";if(!e)try{return JSON.parse(t),t}catch{}let r=t.length,n=[],o=!1,p=!1,i=!1,d=!1,h=-1;for(let u=0;u<r;u++){let c=t[u],m=u+1<r?t[u+1]:"";if(i){(c===`
2
+ `||c==="\r")&&(i=!1,n.push(c));continue}if(d){c==="*"&&m==="/"&&(d=!1,u++);continue}if(o){n.push(c),p?p=!1:c==="\\"?p=!0:c==='"'&&(o=!1);continue}if(c==='"'){o=!0,p=!1,h=-1,n.push(c);continue}if(c==="/"&&m==="/"){i=!0,u++;continue}if(c==="/"&&m==="*"){d=!0,u++;continue}if(c===","){h=n.length,n.push(c);continue}if(c==="}"||c==="]"){h!==-1&&(n[h]=" ",h=-1),n.push(c);continue}c!==" "&&c!==" "&&c!==`
3
+ `&&c!=="\r"&&(h=-1),n.push(c)}return n.join("")}function W(t,e,r,n=!1){let o=t?t.split(/\r?\n/):[],p=o.map((g,y)=>({index:y,match:g.match(/^(\s*)mcp_servers:\s*(.*?)\s*$/)})).filter(g=>g.match!==null);if(p.length>1)throw new Error("Cannot safely update YAML with duplicate mcp_servers keys");if(p.length===1){let g=p[0].match;if(g[1]!==""||g[2]!=="")throw new Error("Cannot safely update YAML unless mcp_servers is a root-level block mapping")}let i=" ";if(p.length===1)for(let g=p[0].index+1;g<o.length;g++){if(o[g].trim()===""||o[g].trimStart().startsWith("#"))continue;if(/^[^\s]/.test(o[g]))break;let y=o[g].match(/^(\s+)[a-zA-Z0-9_-]+:/);y&&(i=y[1]);break}if(n){let g=[],y=!1,v=0,w=!1,C=0;for(let S=0;S<o.length;S++){let l=o[S],f=l.match(/^(\s*)mcp_servers:\s*$/);if(f){y=!0,v=f[1].length,g.push(l);continue}if(y){let j=l.match(/^(\s*)/)?.[1].length||0;if(l.trim()!==""&&j<=v)y=!1,w=!1;else{let k=l.match(/^(\s*)superpowers:\s*$/);if(k&&k[1]===i){w=!0,C=k[1].length;continue}if(w){if(j>C||l.trim()==="")continue;w=!1}}}g.push(l)}return g.join(`
4
+ `)}let d=JSON.stringify(e),h=JSON.stringify(r),u=[`${i}superpowers:`,`${i}${i}command: ${d}`,`${i}${i}args: ${h}`];if(!t||t.trim()==="")return`mcp_servers:
5
+ ${u.join(`
6
6
  `)}
7
- `;let c=r.findIndex(u=>/^\s*mcp_servers:\s*$/.test(u));if(c===-1)return`${t.trimEnd()}
7
+ `;let c=p.length===1?p[0].index:-1;if(c===-1)return`${t.trimEnd()}
8
8
 
9
9
  mcp_servers:
10
- ${l.join(`
10
+ ${u.join(`
11
11
  `)}
12
- `;let i=-1;for(let u=c+1;u<r.length;u++){let d=r[u];if(/^[^\s#]/.test(d))break;if(/^\s+superpowers:\s*$/.test(d)){i=u;break}}if(i!==-1){let u=r[i].match(/^(\s*)/)?.[1].length||2,d=i+1;for(;d<r.length;){let h=r[d];if((h.match(/^(\s*)/)?.[1].length||0)>u||h.trim()==="")d++;else break}return r.splice(i,d-i,...l),r.join(`
13
- `)}else return r.splice(c+1,0,...l),r.join(`
14
- `)}function I(t,e,o,s,r=!1,f){let a={};if(t&&t.trim()!=="")try{let c=JSON.parse(t);A(c)?a=c:a={}}catch{try{let i=R(t,!0),u=JSON.parse(i);A(u)?a=u:a={}}catch(i){let u=i instanceof Error?i.message:String(i);throw new Error(`Failed to parse existing JSON: ${u}`)}}let g="mcpServers";e==="json-servers"?g="servers":e==="json-mcp"&&(g="mcp"),A(a[g])||(a[g]={});let l=a[g];return r?delete l.superpowers:f?l.superpowers=f:e==="json-servers"?l.superpowers={command:o,args:s,type:"stdio"}:e==="json-mcp"?l.superpowers={type:"local",command:[o,...s],enabled:!0}:l.superpowers={command:o,args:s},JSON.stringify(a,null,2)+`
15
- `}function D(t,e,o=!1){let s=t;try{let l=p.lstatSync(t,{throwIfNoEntry:!1});if(l&&l.isSymbolicLink()){try{s=p.realpathSync(t)}catch{let m=p.readlinkSync(t);s=n.resolve(n.dirname(t),m)}let c=n.normalize(n.resolve(s)).toLowerCase(),i=n.normalize(n.resolve(v.tmpdir())).toLowerCase();if(!(c===i||c.startsWith(i+n.sep))&&(["/etc","/bin","/sbin","/usr","/root","/sys","/proc","/dev","/private/etc","c:\\windows"].some(h=>c===h||c.startsWith(h+n.sep))||c==="/var"||c.startsWith("/var"+n.sep)&&!c.startsWith("/var/folders"+n.sep)||c==="/private/var"||c.startsWith("/private/var"+n.sep)&&!c.startsWith("/private/var/folders"+n.sep)))throw new Error(`Refusing to write to unsafe symlink target: ${s}`)}}catch(l){if(l instanceof Error&&l.message.includes("Refusing to write to unsafe symlink target"))throw l}let r=n.dirname(s);p.existsSync(r)||p.mkdirSync(r,{recursive:!0,mode:448});let f=384;if(p.existsSync(s)){try{f=p.statSync(s).mode}catch{}if(o){let l=p.readFileSync(s,"utf8"),c=`${s}.${Date.now()}.bak`;try{p.writeFileSync(c,l,{encoding:"utf8",mode:f})}catch(i){let u=i instanceof Error?i.message:String(i);throw new Error(`Failed to create safe backup before write: ${u}`)}}}let a=$.randomBytes(8).toString("hex"),g=n.join(r,`.tmp.${n.basename(s)}.${process.pid}.${a}`);try{p.writeFileSync(g,e,{encoding:"utf8",mode:f,flag:"wx"}),p.renameSync(g,s)}catch(l){try{p.existsSync(g)&&p.unlinkSync(g)}catch{}throw l}}async function U(t={}){let e=t.platform||v.platform(),o=t.homeDir||v.homedir(),s=t.appData||process.env.APPDATA,r=t.localAppData||process.env.LOCALAPPDATA,f=!!t.dryRun,a=!!t.remove,g=!!t.bun,l=t.target?t.target.toLowerCase():null,c=g?"bunx":"npx",i=["-y","superpowers-mcp"],u=[];if(!l)throw new Error(`No target client specified. Please specify which client to configure using --target <${Object.keys(k).join("|")}>.`);let d=Object.keys(k).find(m=>m===l||k[m].aliases.includes(l));if(!d)throw new Error(`Unknown harness target: "${l}". Supported targets: ${Object.keys(k).join(", ")}`);let h=[d];for(let m of h){let w=k[m],j=w.getConfigPath(e,o,s,r),y=p.existsSync(j);if(a&&!y){u.push({target:m,name:w.name,path:j,status:"up-to-date",message:"Already not configured (file does not exist)"});continue}try{let C="";y&&(C=p.readFileSync(j,"utf8"));let S="";if(w.type==="yaml")S=E(C,c,i,a);else{let x=typeof w.defaultConfig=="function"?w.defaultConfig(c,i):void 0;S=I(C,w.type,c,i,a,x)}if(C.trim()===S.trim()&&y){u.push({target:m,name:w.name,path:j,status:"up-to-date",message:a?"Already not configured":"Already configured and up-to-date"});continue}f||D(j,S,!!t.backup),u.push({target:m,name:w.name,path:j,status:a?"removed":y?"updated":"created",message:f?`[Dry Run] Would ${a?"remove from":y?"update":"create"} ${j}`:`Successfully ${a?"removed from":y?"updated":"configured"}!`})}catch(C){let S=C instanceof Error?C.message:String(C);u.push({target:m,name:w.name,path:j,status:"error",message:S})}}return u}async function K(t=process.argv.slice(2)){let e={dryRun:!1,remove:!1,bun:!1,backup:!1,target:null};for(let o=0;o<t.length;o++){let s=t[o];if(!(s==="setup"||s==="--setup"))if(s==="--dry-run")e.dryRun=!0;else if(s==="--remove"||s==="--uninstall")e.remove=!0;else if(s==="--bun")e.bun=!0;else if(s==="--backup")e.backup=!0;else if(s==="--target"||s==="-t"){let r=t[o+1];(!r||r.startsWith("-"))&&(console.error(`\u274C Error: Missing value for --target flag.
16
- `),process.exit(1)),e.target=t[++o]}else if(s.startsWith("--target=")){let r=s.split("=")[1];r||(console.error(`\u274C Error: Missing value for --target flag.
17
- `),process.exit(1)),e.target=r}else if(s==="--help"||s==="-h"){M();return}else!s.startsWith("-")&&!e.target&&s!=="setup"?e.target=s:s.startsWith("-")&&(console.error(`\u274C Error: Unknown option "${s}". Use --help for usage.
12
+ `;let m=-1;for(let g=c+1;g<o.length;g++){let y=o[g];if(/^[^\s#]/.test(y))break;if((y.match(/^(\s*)/)?.[1]||"")===i&&/^\s+superpowers:\s*$/.test(y)){m=g;break}}if(m!==-1){let g=o[m].match(/^(\s*)/)?.[1].length||2,y=m+1;for(;y<o.length;){let v=o[y];if((v.match(/^(\s*)/)?.[1].length||0)>g||v.trim()==="")y++;else break}return o.splice(m,y-m,...u),o.join(`
13
+ `)}else return o.splice(c+1,0,...u),o.join(`
14
+ `)}function I(t,e,r,n,o=!1,p){let i={};if(t&&t.trim()!=="")try{let u=JSON.parse(t);if(!_(u))throw new Error("Existing JSON root must be an object");i=u}catch{try{let c=D(t,!0),m=JSON.parse(c);if(!_(m))throw new Error("Existing JSON root must be an object");i=m}catch(c){let m=c instanceof Error?c.message:String(c);throw new Error(`Failed to parse existing JSON: ${m}`)}}let d="mcpServers";if(e==="json-servers"?d="servers":e==="json-mcp"&&(d="mcp"),i[d]!==void 0&&!_(i[d]))throw new Error(`Existing JSON field "${d}" must be an object`);i[d]===void 0&&(i[d]={});let h=i[d];return o?delete h.superpowers:p?h.superpowers=p:e==="json-servers"?h.superpowers={command:r,args:n,type:"stdio"}:e==="json-mcp"?h.superpowers={type:"local",command:[r,...n],enabled:!0}:h.superpowers={command:r,args:n},JSON.stringify(i,null,2)+`
15
+ `}function T(t,e,r=!1,n=[],o){if(n.length===0)throw new Error("safeWriteConfig requires at least one allowed destination root");let p=t;try{let l=a.lstatSync(t,{throwIfNoEntry:!1});if(l&&l.isSymbolicLink()){try{p=a.realpathSync(t)}catch{let U=a.readlinkSync(t);p=s.resolve(s.dirname(t),U)}let f=s.normalize(s.resolve(p)).toLowerCase(),j=s.normalize(s.resolve(x.tmpdir())).toLowerCase();if(!(f===j||f.startsWith(j+s.sep))&&(["/etc","/bin","/sbin","/usr","/root","/sys","/proc","/dev","/private/etc","c:\\windows"].some(E=>f===E||f.startsWith(E+s.sep))||f==="/var"||f.startsWith("/var"+s.sep)&&!f.startsWith("/var/folders"+s.sep)||f==="/private/var"||f.startsWith("/private/var"+s.sep)&&!f.startsWith("/private/var/folders"+s.sep)))throw new Error(`Refusing to write to unsafe symlink target: ${p}`)}}catch(l){if(l instanceof Error&&l.message.includes("Refusing to write to unsafe symlink target"))throw l}let i=s.dirname(p);a.existsSync(i)||a.mkdirSync(i,{recursive:!0,mode:448});let d=a.realpathSync(i),h=a.statSync(d);p=s.join(d,s.basename(p));let u=s.normalize(s.resolve(p)).toLowerCase(),c=s.normalize(s.resolve(x.tmpdir())).toLowerCase(),m=u===c||u.startsWith(c+s.sep),y=["/etc","/bin","/sbin","/usr","/root","/sys","/proc","/dev","/private/etc","c:\\windows"].some(l=>u===l||u.startsWith(l+s.sep))||u==="/var"||u.startsWith("/var"+s.sep)&&!u.startsWith("/var/folders"+s.sep)||u==="/private/var"||u.startsWith("/private/var"+s.sep)&&!u.startsWith("/private/var/folders"+s.sep);if(!m&&y)throw new Error(`Refusing to write to unsafe configuration target: ${p}`);if(!n.some(l=>{if(!l)return!1;let f=s.resolve(l);try{f=a.realpathSync(f)}catch{}let j=s.relative(f,p);return j!==".."&&!j.startsWith(`..${s.sep}`)&&!s.isAbsolute(j)}))throw new Error(`Refusing to write configuration outside allowed roots: ${p}`);let w=384;if(a.existsSync(p)){try{w=a.statSync(p).mode}catch{}if(r){let l=a.readFileSync(p,"utf8"),f=`${p}.${Date.now()}.bak`;try{a.writeFileSync(f,l,{encoding:"utf8",mode:w})}catch(j){let k=j instanceof Error?j.message:String(j);throw new Error(`Failed to create safe backup before write: ${k}`)}}}let C=R.randomBytes(8).toString("hex"),S=s.join(d,`.tmp.${s.basename(p)}.${process.pid}.${C}`);try{a.writeFileSync(S,e,{encoding:"utf8",mode:w,flag:"wx"});let l=a.existsSync(p);if(o===null&&l)throw new Error("Configuration changed concurrently before it could be created");if(o!=null&&(!l||a.readFileSync(p,"utf8")!==o))throw new Error("Configuration changed concurrently; refusing to overwrite newer content");let f=a.realpathSync(i),j=a.statSync(f);if(f!==d||j.dev!==h.dev||j.ino!==h.ino)throw new Error("Configuration directory changed while writing");a.renameSync(S,p)}catch(l){try{a.existsSync(S)&&a.unlinkSync(S)}catch{}throw l}}async function O(t={}){let e=t.platform||x.platform(),r=t.homeDir||x.homedir(),n=t.appData||process.env.APPDATA,o=t.localAppData||process.env.LOCALAPPDATA,p=!!t.dryRun,i=!!t.remove,d=!!t.bun,h=t.target?t.target.toLowerCase():null,u=d?"bunx":"npx",c=["-y","superpowers-mcp"],m=[];if(!h)throw new Error(`No target client specified. Please specify which client to configure using --target <${Object.keys(b).join("|")}>.`);let g=Object.keys(b).find(v=>v===h||b[v].aliases.includes(h));if(!g)throw new Error(`Unknown harness target: "${h}". Supported targets: ${Object.keys(b).join(", ")}`);let y=[g];for(let v of y){let w=b[v],C=w.getConfigPath(e,r,n,o),S=a.existsSync(C);if(i&&!S){m.push({target:v,name:w.name,path:C,status:"up-to-date",message:"Already not configured (file does not exist)"});continue}try{let l="";S&&(l=a.readFileSync(C,"utf8"));let f="";if(w.type==="yaml")f=W(l,u,c,i);else{let j=typeof w.defaultConfig=="function"?w.defaultConfig(u,c):void 0;f=I(l,w.type,u,c,i,j)}if(l.trim()===f.trim()&&S){m.push({target:v,name:w.name,path:C,status:"up-to-date",message:i?"Already not configured":"Already configured and up-to-date"});continue}p||T(C,f,!!t.backup,[r,n||"",o||""],S?l:null),m.push({target:v,name:w.name,path:C,status:i?"removed":S?"updated":"created",message:p?`[Dry Run] Would ${i?"remove from":S?"update":"create"} ${C}`:`Successfully ${i?"removed from":S?"updated":"configured"}!`})}catch(l){let f=l instanceof Error?l.message:String(l);m.push({target:v,name:w.name,path:C,status:"error",message:f})}}return m}async function F(t=process.argv.slice(2)){let e={dryRun:!1,remove:!1,bun:!1,backup:!1,target:null};for(let r=0;r<t.length;r++){let n=t[r];if(!(n==="setup"||n==="--setup"))if(n==="--dry-run")e.dryRun=!0;else if(n==="--remove"||n==="--uninstall")e.remove=!0;else if(n==="--bun")e.bun=!0;else if(n==="--backup")e.backup=!0;else if(n==="--target"||n==="-t"){let o=t[r+1];(!o||o.startsWith("-"))&&(console.error(`\u274C Error: Missing value for --target flag.
16
+ `),process.exit(1)),e.target=t[++r]}else if(n.startsWith("--target=")){let o=n.split("=")[1];o||(console.error(`\u274C Error: Missing value for --target flag.
17
+ `),process.exit(1)),e.target=o}else if(n==="--help"||n==="-h"){z();return}else!n.startsWith("-")&&!e.target&&n!=="setup"?e.target=n:n.startsWith("-")&&(console.error(`\u274C Error: Unknown option "${n}". Use --help for usage.
18
18
  `),process.exit(1))}if(console.log(`
19
19
  ========================================================`),console.log("\u26A1 Superpowers MCP - Targeted Client Setup"),console.log(`========================================================
20
20
  `),!e.target){console.log(`Please select which AI Agent client you would like to configure:
21
21
  `),console.log(" npx -y superpowers-mcp setup --target antigravity # Antigravity (~/.gemini/config/mcp_config.json)"),console.log(" npx -y superpowers-mcp setup --target pi-desktop # Pi Desktop / Pi Agent (~/.pi/agent/mcp.json)"),console.log(" npx -y superpowers-mcp setup --target cursor # Cursor (~/.cursor/mcp.json)"),console.log(" npx -y superpowers-mcp setup --target copilot # GitHub Copilot (VS Code mcp.json)"),console.log(" npx -y superpowers-mcp setup --target copilot-insiders # GitHub Copilot (VS Code Insiders mcp.json)"),console.log(" npx -y superpowers-mcp setup --target hermes # Hermes Desktop / Agent"),console.log(" npx -y superpowers-mcp setup --target kimi # Kimi Work / Kimi Code"),console.log(" npx -y superpowers-mcp setup --target claude # Claude Desktop"),console.log(" npx -y superpowers-mcp setup --target devin # Devin Desktop (formerly Windsurf)"),console.log(" npx -y superpowers-mcp setup --target qwenpaw # QwenPaw / CoPaw (~/.qwenpaw/config.json)"),console.log(" npx -y superpowers-mcp setup --target cline # Cline (~/.../cline_mcp_settings.json)"),console.log(" npx -y superpowers-mcp setup --target kilo # Kilo Code (~/.config/kilo/kilo.jsonc)"),console.log(" npx -y superpowers-mcp setup --target qoder # Qoder (~/.qoder/settings.json)"),console.log(" npx -y superpowers-mcp setup --target kiro # Kiro (~/.kiro/settings/mcp.json)"),console.log(` npx -y superpowers-mcp setup --target trae # Trae (~/.../Trae/User/mcp.json)
22
22
  `),console.log("\u{1F4A1} Tip:"),console.log(" You can run this setup command from ANY folder on your system."),console.log(` It automatically targets your global config files (~/...) without needing to clone this repo.
23
23
  `),console.log("\u{1F4A1} Privacy & Safety:"),console.log(" Superpowers MCP only configures the specific client you explicitly choose."),console.log(` It will NEVER silently scan or modify unselected environments.
24
- `);return}try{let o=await U(e),s=0,r=0,f=0;for(let a of o){let g=a.status==="created"||a.status==="updated"||a.status==="removed"?"\u2705":a.status==="up-to-date"?"\u2728":a.status==="skipped"?"\u23ED\uFE0F ":"\u274C";console.log(`${g} [${a.name}] (${a.status})`),console.log(` Path: ${a.path}`),console.log(` Info: ${a.message}
25
- `),a.status==="created"||a.status==="updated"||a.status==="up-to-date"||a.status==="removed"?s++:a.status==="skipped"?r++:a.status==="error"&&f++}console.log("--------------------------------------------------------"),f>0&&(console.error(`\u26A0\uFE0F Setup finished with errors: ${f} failure(s), ${s} succeeded.`),process.exit(1)),console.log(`\u{1F389} Setup complete! ${s} environment(s) ready.`)}catch(o){let s=o instanceof Error?o.message:String(o);console.error(`\u274C Setup failed: ${s}
26
- `),process.exit(1)}}function M(){console.log(`
24
+ `);return}try{let r=await O(e),n=0,o=0,p=0;for(let i of r){let d=i.status==="created"||i.status==="updated"||i.status==="removed"?"\u2705":i.status==="up-to-date"?"\u2728":i.status==="skipped"?"\u23ED\uFE0F ":"\u274C";console.log(`${d} [${i.name}] (${i.status})`),console.log(` Path: ${i.path}`),console.log(` Info: ${i.message}
25
+ `),i.status==="created"||i.status==="updated"||i.status==="up-to-date"||i.status==="removed"?n++:i.status==="skipped"?o++:i.status==="error"&&p++}console.log("--------------------------------------------------------"),p>0&&(console.error(`\u26A0\uFE0F Setup finished with errors: ${p} failure(s), ${n} succeeded.`),process.exit(1)),console.log(`\u{1F389} Setup complete! ${n} environment(s) ready.`)}catch(r){let n=r instanceof Error?r.message:String(r);console.error(`\u274C Setup failed: ${n}
26
+ `),process.exit(1)}}function z(){console.log(`
27
27
  Superpowers MCP - Targeted Global Setup
28
28
 
29
29
  Usage:
package/out/setup.js CHANGED
@@ -1,30 +1,30 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var O=Object.create;var b=Object.defineProperty;var W=Object.getOwnPropertyDescriptor;var q=Object.getOwnPropertyNames;var N=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty;var H=(t,e)=>{for(var o in e)b(t,o,{get:e[o],enumerable:!0})},$=(t,e,o,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of q(e))!L.call(t,r)&&r!==o&&b(t,r,{get:()=>e[r],enumerable:!(s=W(e,r))||s.enumerable});return t};var P=(t,e,o)=>(o=t!=null?O(N(t)):{},$(e||!t||!t.__esModule?b(o,"default",{value:t,enumerable:!0}):o,t)),K=t=>$(b({},"__esModule",{value:!0}),t);var F={};H(F,{HARNESS_CONFIGS:()=>k,isPlainObject:()=>A,runSetup:()=>T,runSetupCli:()=>_,safeWriteConfig:()=>U,stripJsonComments:()=>R,updateJsonConfig:()=>D,updateYamlConfig:()=>I});module.exports=K(F);var p=P(require("fs")),n=P(require("path")),v=P(require("os")),E=P(require("crypto")),k={copilot:{name:"GitHub Copilot (VS Code)",aliases:["vscode","code","copilot"],getConfigPath:(t,e,o,s)=>t==="win32"?n.join(o||n.join(e,"AppData","Roaming"),"Code","User","mcp.json"):t==="darwin"?n.join(e,"Library","Application Support","Code","User","mcp.json"):n.join(e,".config","Code","User","mcp.json"),type:"json-servers",defaultConfig:(t,e)=>({command:t,args:e,type:"stdio"})},"copilot-insiders":{name:"GitHub Copilot (VS Code Insiders)",aliases:["vscode-insiders","code-insiders","insiders","insider","vscode-insider","code-insider","copilot-insider"],getConfigPath:(t,e,o,s)=>t==="win32"?n.join(o||n.join(e,"AppData","Roaming"),"Code - Insiders","User","mcp.json"):t==="darwin"?n.join(e,"Library","Application Support","Code - Insiders","User","mcp.json"):n.join(e,".config","Code - Insiders","User","mcp.json"),type:"json-servers",defaultConfig:(t,e)=>({command:t,args:e,type:"stdio"})},cursor:{name:"Cursor",aliases:["cursor"],getConfigPath:(t,e)=>n.join(e,".cursor","mcp.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},hermes:{name:"Hermes Desktop / Agent",aliases:["hermes","hermes-desktop"],getConfigPath:(t,e,o,s)=>{if(t==="win32"){let r=s||n.join(e,"AppData","Local");return n.join(r,"hermes","config.yaml")}return n.join(e,".hermes","config.yaml")},type:"yaml",defaultConfig:(t,e)=>({command:t,args:e})},kimi:{name:"Kimi Work / Kimi Code",aliases:["kimi","kimi-work","kimi-code"],getConfigPath:(t,e)=>n.join(e,".kimi-code","mcp.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},claude:{name:"Claude Desktop",aliases:["claude","claude-desktop"],getConfigPath:(t,e,o)=>t==="win32"?n.join(o||n.join(e,"AppData","Roaming"),"Claude","claude_desktop_config.json"):t==="darwin"?n.join(e,"Library","Application Support","Claude","claude_desktop_config.json"):n.join(e,".config","Claude","claude_desktop_config.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},devin:{name:"Devin Desktop (formerly Windsurf)",aliases:["devin","devin-desktop","windsurf","codeium"],getConfigPath:(t,e)=>{let o=n.join(e,".config","devin","mcp_config.json");return p.existsSync(o)?o:n.join(e,".codeium","windsurf","mcp_config.json")},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},antigravity:{name:"Antigravity (Google DeepMind)",aliases:["antigravity","agy","gemini"],getConfigPath:(t,e)=>n.join(e,".gemini","config","mcp_config.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},"pi-desktop":{name:"Pi Desktop / Pi Agent",aliases:["pi-desktop","pi","pi-agent"],getConfigPath:(t,e,o)=>{if(t==="win32"){let f=n.join(o||n.join(e,"AppData","Roaming"),".pi","agent","mcp.json");if(p.existsSync(f))return f;let a=n.join(e,".pi","agent","mcp.json");if(p.existsSync(a))return a;let g=n.join(e,".pi","mcp.json");return p.existsSync(g)?g:a}let s=n.join(e,".pi","agent","mcp.json");if(p.existsSync(s))return s;let r=n.join(e,".pi","mcp.json");return p.existsSync(r)?r:s},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},qwenpaw:{name:"QwenPaw (Personal Agent Workstation)",aliases:["qwenpaw","qwen-paw","copaw"],getConfigPath:(t,e)=>{let o=n.join(e,".qwenpaw","config.json");if(p.existsSync(o))return o;let s=n.join(e,".copaw","config.json");return p.existsSync(s)?s:o},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},cline:{name:"Cline (VS Code / CLI)",aliases:["cline","claude-dev"],getConfigPath:(t,e,o)=>{let s="";if(t==="win32"?s=n.join(o||n.join(e,"AppData","Roaming"),"Code","User","globalStorage","saoudrizwan.claude-dev","settings","cline_mcp_settings.json"):t==="darwin"?s=n.join(e,"Library","Application Support","Code","User","globalStorage","saoudrizwan.claude-dev","settings","cline_mcp_settings.json"):s=n.join(e,".config","Code","User","globalStorage","saoudrizwan.claude-dev","settings","cline_mcp_settings.json"),p.existsSync(s))return s;let r=n.join(e,".cline","data","settings","cline_mcp_settings.json");return p.existsSync(r)?r:s},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},kilo:{name:"Kilo Code",aliases:["kilo","kilocode","kilo-code"],getConfigPath:(t,e)=>{let o=n.join(e,".config","kilo","kilo.jsonc");if(p.existsSync(o))return o;let s=n.join(e,".config","kilo","kilo.json");return p.existsSync(s)?s:o},type:"json-mcp",defaultConfig:(t,e)=>({type:"local",command:[t,...e],enabled:!0})},qoder:{name:"Qoder",aliases:["qoder"],getConfigPath:(t,e)=>n.join(e,".qoder","settings.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},kiro:{name:"Kiro",aliases:["kiro","kiro-code"],getConfigPath:(t,e)=>n.join(e,".kiro","settings","mcp.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},trae:{name:"Trae",aliases:["trae"],getConfigPath:(t,e,o)=>{if(t==="win32"){let s=n.join(o||n.join(e,"AppData","Roaming"),"Trae","User","mcp.json");if(p.existsSync(s))return s;let r=n.join(o||n.join(e,"AppData","Roaming"),"Trae CN","User","mcp.json");return p.existsSync(r)?r:s}else if(t==="darwin"){let s=n.join(e,"Library","Application Support","Trae","User","mcp.json");if(p.existsSync(s))return s;let r=n.join(e,"Library","Application Support","Trae CN","User","mcp.json");return p.existsSync(r)?r:s}else{let s=n.join(e,".config","Trae","User","mcp.json");if(p.existsSync(s))return s;let r=n.join(e,".config","Trae CN","User","mcp.json");return p.existsSync(r)?r:s}},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})}};function A(t){return Object.prototype.toString.call(t)==="[object Object]"}function R(t,e=!1){if(!t)return"";if(!e)try{return JSON.parse(t),t}catch{}let o=t.length,s=[],r=!1,f=!1,a=!1,g=!1,l=-1;for(let c=0;c<o;c++){let i=t[c],u=c+1<o?t[c+1]:"";if(a){(i===`
3
- `||i==="\r")&&(a=!1,s.push(i));continue}if(g){i==="*"&&u==="/"&&(g=!1,c++);continue}if(r){s.push(i),f?f=!1:i==="\\"?f=!0:i==='"'&&(r=!1);continue}if(i==='"'){r=!0,f=!1,l=-1,s.push(i);continue}if(i==="/"&&u==="/"){a=!0,c++;continue}if(i==="/"&&u==="*"){g=!0,c++;continue}if(i===","){l=s.length,s.push(i);continue}if(i==="}"||i==="]"){l!==-1&&(s[l]=" ",l=-1),s.push(i);continue}i!==" "&&i!==" "&&i!==`
4
- `&&i!=="\r"&&(l=-1),s.push(i)}return s.join("")}function I(t,e,o,s=!1){let r=t?t.split(/\r?\n/):[];if(s){let u=[],d=!1,h=0,m=!1,w=0;for(let j=0;j<r.length;j++){let y=r[j],C=y.match(/^(\s*)mcp_servers:\s*$/);if(C){d=!0,h=C[1].length,u.push(y);continue}if(d){let S=y.match(/^(\s*)/)?.[1].length||0;if(y.trim()!==""&&S<=h)d=!1,m=!1;else{let x=y.match(/^(\s*)superpowers:\s*$/);if(x&&x[1].length>h){m=!0,w=x[1].length;continue}if(m){if(S>w||y.trim()==="")continue;m=!1}}}u.push(y)}return u.join(`
5
- `)}let f=" ";for(let u of r){let d=u.match(/^(\s+)[a-zA-Z0-9_-]+:/);if(d&&d[1].length>0){f=d[1];break}}let a=JSON.stringify(e),g=JSON.stringify(o),l=[`${f}superpowers:`,`${f}${f}command: ${a}`,`${f}${f}args: ${g}`];if(!t||t.trim()==="")return`mcp_servers:
6
- ${l.join(`
2
+ "use strict";var q=Object.create;var P=Object.defineProperty;var L=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var M=Object.getPrototypeOf,F=Object.prototype.hasOwnProperty;var H=(t,e)=>{for(var r in e)P(t,r,{get:e[r],enumerable:!0})},R=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of J(e))!F.call(t,o)&&o!==r&&P(t,o,{get:()=>e[o],enumerable:!(n=L(e,o))||n.enumerable});return t};var A=(t,e,r)=>(r=t!=null?q(M(t)):{},R(e||!t||!t.__esModule?P(r,"default",{value:t,enumerable:!0}):r,t)),K=t=>R(P({},"__esModule",{value:!0}),t);var G={};H(G,{HARNESS_CONFIGS:()=>b,isPlainObject:()=>_,runSetup:()=>U,runSetupCli:()=>$,safeWriteConfig:()=>O,stripJsonComments:()=>W,updateJsonConfig:()=>T,updateYamlConfig:()=>I});module.exports=K(G);var a=A(require("fs")),s=A(require("path")),x=A(require("os")),D=A(require("crypto")),b={copilot:{name:"GitHub Copilot (VS Code)",aliases:["vscode","code","copilot"],getConfigPath:(t,e,r,n)=>t==="win32"?s.join(r||s.join(e,"AppData","Roaming"),"Code","User","mcp.json"):t==="darwin"?s.join(e,"Library","Application Support","Code","User","mcp.json"):s.join(e,".config","Code","User","mcp.json"),type:"json-servers",defaultConfig:(t,e)=>({command:t,args:e,type:"stdio"})},"copilot-insiders":{name:"GitHub Copilot (VS Code Insiders)",aliases:["vscode-insiders","code-insiders","insiders","insider","vscode-insider","code-insider","copilot-insider"],getConfigPath:(t,e,r,n)=>t==="win32"?s.join(r||s.join(e,"AppData","Roaming"),"Code - Insiders","User","mcp.json"):t==="darwin"?s.join(e,"Library","Application Support","Code - Insiders","User","mcp.json"):s.join(e,".config","Code - Insiders","User","mcp.json"),type:"json-servers",defaultConfig:(t,e)=>({command:t,args:e,type:"stdio"})},cursor:{name:"Cursor",aliases:["cursor"],getConfigPath:(t,e)=>s.join(e,".cursor","mcp.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},hermes:{name:"Hermes Desktop / Agent",aliases:["hermes","hermes-desktop"],getConfigPath:(t,e,r,n)=>{if(t==="win32"){let o=n||s.join(e,"AppData","Local");return s.join(o,"hermes","config.yaml")}return s.join(e,".hermes","config.yaml")},type:"yaml",defaultConfig:(t,e)=>({command:t,args:e})},kimi:{name:"Kimi Work / Kimi Code",aliases:["kimi","kimi-work","kimi-code"],getConfigPath:(t,e)=>s.join(e,".kimi-code","mcp.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},claude:{name:"Claude Desktop",aliases:["claude","claude-desktop"],getConfigPath:(t,e,r)=>t==="win32"?s.join(r||s.join(e,"AppData","Roaming"),"Claude","claude_desktop_config.json"):t==="darwin"?s.join(e,"Library","Application Support","Claude","claude_desktop_config.json"):s.join(e,".config","Claude","claude_desktop_config.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},devin:{name:"Devin Desktop (formerly Windsurf)",aliases:["devin","devin-desktop","windsurf","codeium"],getConfigPath:(t,e)=>{let r=s.join(e,".config","devin","mcp_config.json");return a.existsSync(r)?r:s.join(e,".codeium","windsurf","mcp_config.json")},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},antigravity:{name:"Antigravity (Google DeepMind)",aliases:["antigravity","agy","gemini"],getConfigPath:(t,e)=>s.join(e,".gemini","config","mcp_config.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},"pi-desktop":{name:"Pi Desktop / Pi Agent",aliases:["pi-desktop","pi","pi-agent"],getConfigPath:(t,e,r)=>{if(t==="win32"){let p=s.join(r||s.join(e,"AppData","Roaming"),".pi","agent","mcp.json");if(a.existsSync(p))return p;let i=s.join(e,".pi","agent","mcp.json");if(a.existsSync(i))return i;let d=s.join(e,".pi","mcp.json");return a.existsSync(d)?d:i}let n=s.join(e,".pi","agent","mcp.json");if(a.existsSync(n))return n;let o=s.join(e,".pi","mcp.json");return a.existsSync(o)?o:n},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},qwenpaw:{name:"QwenPaw (Personal Agent Workstation)",aliases:["qwenpaw","qwen-paw","copaw"],getConfigPath:(t,e)=>{let r=s.join(e,".qwenpaw","config.json");if(a.existsSync(r))return r;let n=s.join(e,".copaw","config.json");return a.existsSync(n)?n:r},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},cline:{name:"Cline (VS Code / CLI)",aliases:["cline","claude-dev"],getConfigPath:(t,e,r)=>{let n="";if(t==="win32"?n=s.join(r||s.join(e,"AppData","Roaming"),"Code","User","globalStorage","saoudrizwan.claude-dev","settings","cline_mcp_settings.json"):t==="darwin"?n=s.join(e,"Library","Application Support","Code","User","globalStorage","saoudrizwan.claude-dev","settings","cline_mcp_settings.json"):n=s.join(e,".config","Code","User","globalStorage","saoudrizwan.claude-dev","settings","cline_mcp_settings.json"),a.existsSync(n))return n;let o=s.join(e,".cline","data","settings","cline_mcp_settings.json");return a.existsSync(o)?o:n},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},kilo:{name:"Kilo Code",aliases:["kilo","kilocode","kilo-code"],getConfigPath:(t,e)=>{let r=s.join(e,".config","kilo","kilo.jsonc");if(a.existsSync(r))return r;let n=s.join(e,".config","kilo","kilo.json");return a.existsSync(n)?n:r},type:"json-mcp",defaultConfig:(t,e)=>({type:"local",command:[t,...e],enabled:!0})},qoder:{name:"Qoder",aliases:["qoder"],getConfigPath:(t,e)=>s.join(e,".qoder","settings.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},kiro:{name:"Kiro",aliases:["kiro","kiro-code"],getConfigPath:(t,e)=>s.join(e,".kiro","settings","mcp.json"),type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})},trae:{name:"Trae",aliases:["trae"],getConfigPath:(t,e,r)=>{if(t==="win32"){let n=s.join(r||s.join(e,"AppData","Roaming"),"Trae","User","mcp.json");if(a.existsSync(n))return n;let o=s.join(r||s.join(e,"AppData","Roaming"),"Trae CN","User","mcp.json");return a.existsSync(o)?o:n}else if(t==="darwin"){let n=s.join(e,"Library","Application Support","Trae","User","mcp.json");if(a.existsSync(n))return n;let o=s.join(e,"Library","Application Support","Trae CN","User","mcp.json");return a.existsSync(o)?o:n}else{let n=s.join(e,".config","Trae","User","mcp.json");if(a.existsSync(n))return n;let o=s.join(e,".config","Trae CN","User","mcp.json");return a.existsSync(o)?o:n}},type:"json-mcpServers",defaultConfig:(t,e)=>({command:t,args:e})}};function _(t){return Object.prototype.toString.call(t)==="[object Object]"}function W(t,e=!1){if(!t)return"";if(!e)try{return JSON.parse(t),t}catch{}let r=t.length,n=[],o=!1,p=!1,i=!1,d=!1,h=-1;for(let u=0;u<r;u++){let c=t[u],m=u+1<r?t[u+1]:"";if(i){(c===`
3
+ `||c==="\r")&&(i=!1,n.push(c));continue}if(d){c==="*"&&m==="/"&&(d=!1,u++);continue}if(o){n.push(c),p?p=!1:c==="\\"?p=!0:c==='"'&&(o=!1);continue}if(c==='"'){o=!0,p=!1,h=-1,n.push(c);continue}if(c==="/"&&m==="/"){i=!0,u++;continue}if(c==="/"&&m==="*"){d=!0,u++;continue}if(c===","){h=n.length,n.push(c);continue}if(c==="}"||c==="]"){h!==-1&&(n[h]=" ",h=-1),n.push(c);continue}c!==" "&&c!==" "&&c!==`
4
+ `&&c!=="\r"&&(h=-1),n.push(c)}return n.join("")}function I(t,e,r,n=!1){let o=t?t.split(/\r?\n/):[],p=o.map((g,y)=>({index:y,match:g.match(/^(\s*)mcp_servers:\s*(.*?)\s*$/)})).filter(g=>g.match!==null);if(p.length>1)throw new Error("Cannot safely update YAML with duplicate mcp_servers keys");if(p.length===1){let g=p[0].match;if(g[1]!==""||g[2]!=="")throw new Error("Cannot safely update YAML unless mcp_servers is a root-level block mapping")}let i=" ";if(p.length===1)for(let g=p[0].index+1;g<o.length;g++){if(o[g].trim()===""||o[g].trimStart().startsWith("#"))continue;if(/^[^\s]/.test(o[g]))break;let y=o[g].match(/^(\s+)[a-zA-Z0-9_-]+:/);y&&(i=y[1]);break}if(n){let g=[],y=!1,S=0,w=!1,C=0;for(let v=0;v<o.length;v++){let l=o[v],f=l.match(/^(\s*)mcp_servers:\s*$/);if(f){y=!0,S=f[1].length,g.push(l);continue}if(y){let j=l.match(/^(\s*)/)?.[1].length||0;if(l.trim()!==""&&j<=S)y=!1,w=!1;else{let k=l.match(/^(\s*)superpowers:\s*$/);if(k&&k[1]===i){w=!0,C=k[1].length;continue}if(w){if(j>C||l.trim()==="")continue;w=!1}}}g.push(l)}return g.join(`
5
+ `)}let d=JSON.stringify(e),h=JSON.stringify(r),u=[`${i}superpowers:`,`${i}${i}command: ${d}`,`${i}${i}args: ${h}`];if(!t||t.trim()==="")return`mcp_servers:
6
+ ${u.join(`
7
7
  `)}
8
- `;let c=r.findIndex(u=>/^\s*mcp_servers:\s*$/.test(u));if(c===-1)return`${t.trimEnd()}
8
+ `;let c=p.length===1?p[0].index:-1;if(c===-1)return`${t.trimEnd()}
9
9
 
10
10
  mcp_servers:
11
- ${l.join(`
11
+ ${u.join(`
12
12
  `)}
13
- `;let i=-1;for(let u=c+1;u<r.length;u++){let d=r[u];if(/^[^\s#]/.test(d))break;if(/^\s+superpowers:\s*$/.test(d)){i=u;break}}if(i!==-1){let u=r[i].match(/^(\s*)/)?.[1].length||2,d=i+1;for(;d<r.length;){let h=r[d];if((h.match(/^(\s*)/)?.[1].length||0)>u||h.trim()==="")d++;else break}return r.splice(i,d-i,...l),r.join(`
14
- `)}else return r.splice(c+1,0,...l),r.join(`
15
- `)}function D(t,e,o,s,r=!1,f){let a={};if(t&&t.trim()!=="")try{let c=JSON.parse(t);A(c)?a=c:a={}}catch{try{let i=R(t,!0),u=JSON.parse(i);A(u)?a=u:a={}}catch(i){let u=i instanceof Error?i.message:String(i);throw new Error(`Failed to parse existing JSON: ${u}`)}}let g="mcpServers";e==="json-servers"?g="servers":e==="json-mcp"&&(g="mcp"),A(a[g])||(a[g]={});let l=a[g];return r?delete l.superpowers:f?l.superpowers=f:e==="json-servers"?l.superpowers={command:o,args:s,type:"stdio"}:e==="json-mcp"?l.superpowers={type:"local",command:[o,...s],enabled:!0}:l.superpowers={command:o,args:s},JSON.stringify(a,null,2)+`
16
- `}function U(t,e,o=!1){let s=t;try{let l=p.lstatSync(t,{throwIfNoEntry:!1});if(l&&l.isSymbolicLink()){try{s=p.realpathSync(t)}catch{let m=p.readlinkSync(t);s=n.resolve(n.dirname(t),m)}let c=n.normalize(n.resolve(s)).toLowerCase(),i=n.normalize(n.resolve(v.tmpdir())).toLowerCase();if(!(c===i||c.startsWith(i+n.sep))&&(["/etc","/bin","/sbin","/usr","/root","/sys","/proc","/dev","/private/etc","c:\\windows"].some(h=>c===h||c.startsWith(h+n.sep))||c==="/var"||c.startsWith("/var"+n.sep)&&!c.startsWith("/var/folders"+n.sep)||c==="/private/var"||c.startsWith("/private/var"+n.sep)&&!c.startsWith("/private/var/folders"+n.sep)))throw new Error(`Refusing to write to unsafe symlink target: ${s}`)}}catch(l){if(l instanceof Error&&l.message.includes("Refusing to write to unsafe symlink target"))throw l}let r=n.dirname(s);p.existsSync(r)||p.mkdirSync(r,{recursive:!0,mode:448});let f=384;if(p.existsSync(s)){try{f=p.statSync(s).mode}catch{}if(o){let l=p.readFileSync(s,"utf8"),c=`${s}.${Date.now()}.bak`;try{p.writeFileSync(c,l,{encoding:"utf8",mode:f})}catch(i){let u=i instanceof Error?i.message:String(i);throw new Error(`Failed to create safe backup before write: ${u}`)}}}let a=E.randomBytes(8).toString("hex"),g=n.join(r,`.tmp.${n.basename(s)}.${process.pid}.${a}`);try{p.writeFileSync(g,e,{encoding:"utf8",mode:f,flag:"wx"}),p.renameSync(g,s)}catch(l){try{p.existsSync(g)&&p.unlinkSync(g)}catch{}throw l}}async function T(t={}){let e=t.platform||v.platform(),o=t.homeDir||v.homedir(),s=t.appData||process.env.APPDATA,r=t.localAppData||process.env.LOCALAPPDATA,f=!!t.dryRun,a=!!t.remove,g=!!t.bun,l=t.target?t.target.toLowerCase():null,c=g?"bunx":"npx",i=["-y","superpowers-mcp"],u=[];if(!l)throw new Error(`No target client specified. Please specify which client to configure using --target <${Object.keys(k).join("|")}>.`);let d=Object.keys(k).find(m=>m===l||k[m].aliases.includes(l));if(!d)throw new Error(`Unknown harness target: "${l}". Supported targets: ${Object.keys(k).join(", ")}`);let h=[d];for(let m of h){let w=k[m],j=w.getConfigPath(e,o,s,r),y=p.existsSync(j);if(a&&!y){u.push({target:m,name:w.name,path:j,status:"up-to-date",message:"Already not configured (file does not exist)"});continue}try{let C="";y&&(C=p.readFileSync(j,"utf8"));let S="";if(w.type==="yaml")S=I(C,c,i,a);else{let x=typeof w.defaultConfig=="function"?w.defaultConfig(c,i):void 0;S=D(C,w.type,c,i,a,x)}if(C.trim()===S.trim()&&y){u.push({target:m,name:w.name,path:j,status:"up-to-date",message:a?"Already not configured":"Already configured and up-to-date"});continue}f||U(j,S,!!t.backup),u.push({target:m,name:w.name,path:j,status:a?"removed":y?"updated":"created",message:f?`[Dry Run] Would ${a?"remove from":y?"update":"create"} ${j}`:`Successfully ${a?"removed from":y?"updated":"configured"}!`})}catch(C){let S=C instanceof Error?C.message:String(C);u.push({target:m,name:w.name,path:j,status:"error",message:S})}}return u}async function _(t=process.argv.slice(2)){let e={dryRun:!1,remove:!1,bun:!1,backup:!1,target:null};for(let o=0;o<t.length;o++){let s=t[o];if(!(s==="setup"||s==="--setup"))if(s==="--dry-run")e.dryRun=!0;else if(s==="--remove"||s==="--uninstall")e.remove=!0;else if(s==="--bun")e.bun=!0;else if(s==="--backup")e.backup=!0;else if(s==="--target"||s==="-t"){let r=t[o+1];(!r||r.startsWith("-"))&&(console.error(`\u274C Error: Missing value for --target flag.
17
- `),process.exit(1)),e.target=t[++o]}else if(s.startsWith("--target=")){let r=s.split("=")[1];r||(console.error(`\u274C Error: Missing value for --target flag.
18
- `),process.exit(1)),e.target=r}else if(s==="--help"||s==="-h"){M();return}else!s.startsWith("-")&&!e.target&&s!=="setup"?e.target=s:s.startsWith("-")&&(console.error(`\u274C Error: Unknown option "${s}". Use --help for usage.
13
+ `;let m=-1;for(let g=c+1;g<o.length;g++){let y=o[g];if(/^[^\s#]/.test(y))break;if((y.match(/^(\s*)/)?.[1]||"")===i&&/^\s+superpowers:\s*$/.test(y)){m=g;break}}if(m!==-1){let g=o[m].match(/^(\s*)/)?.[1].length||2,y=m+1;for(;y<o.length;){let S=o[y];if((S.match(/^(\s*)/)?.[1].length||0)>g||S.trim()==="")y++;else break}return o.splice(m,y-m,...u),o.join(`
14
+ `)}else return o.splice(c+1,0,...u),o.join(`
15
+ `)}function T(t,e,r,n,o=!1,p){let i={};if(t&&t.trim()!=="")try{let u=JSON.parse(t);if(!_(u))throw new Error("Existing JSON root must be an object");i=u}catch{try{let c=W(t,!0),m=JSON.parse(c);if(!_(m))throw new Error("Existing JSON root must be an object");i=m}catch(c){let m=c instanceof Error?c.message:String(c);throw new Error(`Failed to parse existing JSON: ${m}`)}}let d="mcpServers";if(e==="json-servers"?d="servers":e==="json-mcp"&&(d="mcp"),i[d]!==void 0&&!_(i[d]))throw new Error(`Existing JSON field "${d}" must be an object`);i[d]===void 0&&(i[d]={});let h=i[d];return o?delete h.superpowers:p?h.superpowers=p:e==="json-servers"?h.superpowers={command:r,args:n,type:"stdio"}:e==="json-mcp"?h.superpowers={type:"local",command:[r,...n],enabled:!0}:h.superpowers={command:r,args:n},JSON.stringify(i,null,2)+`
16
+ `}function O(t,e,r=!1,n=[],o){if(n.length===0)throw new Error("safeWriteConfig requires at least one allowed destination root");let p=t;try{let l=a.lstatSync(t,{throwIfNoEntry:!1});if(l&&l.isSymbolicLink()){try{p=a.realpathSync(t)}catch{let N=a.readlinkSync(t);p=s.resolve(s.dirname(t),N)}let f=s.normalize(s.resolve(p)).toLowerCase(),j=s.normalize(s.resolve(x.tmpdir())).toLowerCase();if(!(f===j||f.startsWith(j+s.sep))&&(["/etc","/bin","/sbin","/usr","/root","/sys","/proc","/dev","/private/etc","c:\\windows"].some(E=>f===E||f.startsWith(E+s.sep))||f==="/var"||f.startsWith("/var"+s.sep)&&!f.startsWith("/var/folders"+s.sep)||f==="/private/var"||f.startsWith("/private/var"+s.sep)&&!f.startsWith("/private/var/folders"+s.sep)))throw new Error(`Refusing to write to unsafe symlink target: ${p}`)}}catch(l){if(l instanceof Error&&l.message.includes("Refusing to write to unsafe symlink target"))throw l}let i=s.dirname(p);a.existsSync(i)||a.mkdirSync(i,{recursive:!0,mode:448});let d=a.realpathSync(i),h=a.statSync(d);p=s.join(d,s.basename(p));let u=s.normalize(s.resolve(p)).toLowerCase(),c=s.normalize(s.resolve(x.tmpdir())).toLowerCase(),m=u===c||u.startsWith(c+s.sep),y=["/etc","/bin","/sbin","/usr","/root","/sys","/proc","/dev","/private/etc","c:\\windows"].some(l=>u===l||u.startsWith(l+s.sep))||u==="/var"||u.startsWith("/var"+s.sep)&&!u.startsWith("/var/folders"+s.sep)||u==="/private/var"||u.startsWith("/private/var"+s.sep)&&!u.startsWith("/private/var/folders"+s.sep);if(!m&&y)throw new Error(`Refusing to write to unsafe configuration target: ${p}`);if(!n.some(l=>{if(!l)return!1;let f=s.resolve(l);try{f=a.realpathSync(f)}catch{}let j=s.relative(f,p);return j!==".."&&!j.startsWith(`..${s.sep}`)&&!s.isAbsolute(j)}))throw new Error(`Refusing to write configuration outside allowed roots: ${p}`);let w=384;if(a.existsSync(p)){try{w=a.statSync(p).mode}catch{}if(r){let l=a.readFileSync(p,"utf8"),f=`${p}.${Date.now()}.bak`;try{a.writeFileSync(f,l,{encoding:"utf8",mode:w})}catch(j){let k=j instanceof Error?j.message:String(j);throw new Error(`Failed to create safe backup before write: ${k}`)}}}let C=D.randomBytes(8).toString("hex"),v=s.join(d,`.tmp.${s.basename(p)}.${process.pid}.${C}`);try{a.writeFileSync(v,e,{encoding:"utf8",mode:w,flag:"wx"});let l=a.existsSync(p);if(o===null&&l)throw new Error("Configuration changed concurrently before it could be created");if(o!=null&&(!l||a.readFileSync(p,"utf8")!==o))throw new Error("Configuration changed concurrently; refusing to overwrite newer content");let f=a.realpathSync(i),j=a.statSync(f);if(f!==d||j.dev!==h.dev||j.ino!==h.ino)throw new Error("Configuration directory changed while writing");a.renameSync(v,p)}catch(l){try{a.existsSync(v)&&a.unlinkSync(v)}catch{}throw l}}async function U(t={}){let e=t.platform||x.platform(),r=t.homeDir||x.homedir(),n=t.appData||process.env.APPDATA,o=t.localAppData||process.env.LOCALAPPDATA,p=!!t.dryRun,i=!!t.remove,d=!!t.bun,h=t.target?t.target.toLowerCase():null,u=d?"bunx":"npx",c=["-y","superpowers-mcp"],m=[];if(!h)throw new Error(`No target client specified. Please specify which client to configure using --target <${Object.keys(b).join("|")}>.`);let g=Object.keys(b).find(S=>S===h||b[S].aliases.includes(h));if(!g)throw new Error(`Unknown harness target: "${h}". Supported targets: ${Object.keys(b).join(", ")}`);let y=[g];for(let S of y){let w=b[S],C=w.getConfigPath(e,r,n,o),v=a.existsSync(C);if(i&&!v){m.push({target:S,name:w.name,path:C,status:"up-to-date",message:"Already not configured (file does not exist)"});continue}try{let l="";v&&(l=a.readFileSync(C,"utf8"));let f="";if(w.type==="yaml")f=I(l,u,c,i);else{let j=typeof w.defaultConfig=="function"?w.defaultConfig(u,c):void 0;f=T(l,w.type,u,c,i,j)}if(l.trim()===f.trim()&&v){m.push({target:S,name:w.name,path:C,status:"up-to-date",message:i?"Already not configured":"Already configured and up-to-date"});continue}p||O(C,f,!!t.backup,[r,n||"",o||""],v?l:null),m.push({target:S,name:w.name,path:C,status:i?"removed":v?"updated":"created",message:p?`[Dry Run] Would ${i?"remove from":v?"update":"create"} ${C}`:`Successfully ${i?"removed from":v?"updated":"configured"}!`})}catch(l){let f=l instanceof Error?l.message:String(l);m.push({target:S,name:w.name,path:C,status:"error",message:f})}}return m}async function $(t=process.argv.slice(2)){let e={dryRun:!1,remove:!1,bun:!1,backup:!1,target:null};for(let r=0;r<t.length;r++){let n=t[r];if(!(n==="setup"||n==="--setup"))if(n==="--dry-run")e.dryRun=!0;else if(n==="--remove"||n==="--uninstall")e.remove=!0;else if(n==="--bun")e.bun=!0;else if(n==="--backup")e.backup=!0;else if(n==="--target"||n==="-t"){let o=t[r+1];(!o||o.startsWith("-"))&&(console.error(`\u274C Error: Missing value for --target flag.
17
+ `),process.exit(1)),e.target=t[++r]}else if(n.startsWith("--target=")){let o=n.split("=")[1];o||(console.error(`\u274C Error: Missing value for --target flag.
18
+ `),process.exit(1)),e.target=o}else if(n==="--help"||n==="-h"){z();return}else!n.startsWith("-")&&!e.target&&n!=="setup"?e.target=n:n.startsWith("-")&&(console.error(`\u274C Error: Unknown option "${n}". Use --help for usage.
19
19
  `),process.exit(1))}if(console.log(`
20
20
  ========================================================`),console.log("\u26A1 Superpowers MCP - Targeted Client Setup"),console.log(`========================================================
21
21
  `),!e.target){console.log(`Please select which AI Agent client you would like to configure:
22
22
  `),console.log(" npx -y superpowers-mcp setup --target antigravity # Antigravity (~/.gemini/config/mcp_config.json)"),console.log(" npx -y superpowers-mcp setup --target pi-desktop # Pi Desktop / Pi Agent (~/.pi/agent/mcp.json)"),console.log(" npx -y superpowers-mcp setup --target cursor # Cursor (~/.cursor/mcp.json)"),console.log(" npx -y superpowers-mcp setup --target copilot # GitHub Copilot (VS Code mcp.json)"),console.log(" npx -y superpowers-mcp setup --target copilot-insiders # GitHub Copilot (VS Code Insiders mcp.json)"),console.log(" npx -y superpowers-mcp setup --target hermes # Hermes Desktop / Agent"),console.log(" npx -y superpowers-mcp setup --target kimi # Kimi Work / Kimi Code"),console.log(" npx -y superpowers-mcp setup --target claude # Claude Desktop"),console.log(" npx -y superpowers-mcp setup --target devin # Devin Desktop (formerly Windsurf)"),console.log(" npx -y superpowers-mcp setup --target qwenpaw # QwenPaw / CoPaw (~/.qwenpaw/config.json)"),console.log(" npx -y superpowers-mcp setup --target cline # Cline (~/.../cline_mcp_settings.json)"),console.log(" npx -y superpowers-mcp setup --target kilo # Kilo Code (~/.config/kilo/kilo.jsonc)"),console.log(" npx -y superpowers-mcp setup --target qoder # Qoder (~/.qoder/settings.json)"),console.log(" npx -y superpowers-mcp setup --target kiro # Kiro (~/.kiro/settings/mcp.json)"),console.log(` npx -y superpowers-mcp setup --target trae # Trae (~/.../Trae/User/mcp.json)
23
23
  `),console.log("\u{1F4A1} Tip:"),console.log(" You can run this setup command from ANY folder on your system."),console.log(` It automatically targets your global config files (~/...) without needing to clone this repo.
24
24
  `),console.log("\u{1F4A1} Privacy & Safety:"),console.log(" Superpowers MCP only configures the specific client you explicitly choose."),console.log(` It will NEVER silently scan or modify unselected environments.
25
- `);return}try{let o=await T(e),s=0,r=0,f=0;for(let a of o){let g=a.status==="created"||a.status==="updated"||a.status==="removed"?"\u2705":a.status==="up-to-date"?"\u2728":a.status==="skipped"?"\u23ED\uFE0F ":"\u274C";console.log(`${g} [${a.name}] (${a.status})`),console.log(` Path: ${a.path}`),console.log(` Info: ${a.message}
26
- `),a.status==="created"||a.status==="updated"||a.status==="up-to-date"||a.status==="removed"?s++:a.status==="skipped"?r++:a.status==="error"&&f++}console.log("--------------------------------------------------------"),f>0&&(console.error(`\u26A0\uFE0F Setup finished with errors: ${f} failure(s), ${s} succeeded.`),process.exit(1)),console.log(`\u{1F389} Setup complete! ${s} environment(s) ready.`)}catch(o){let s=o instanceof Error?o.message:String(o);console.error(`\u274C Setup failed: ${s}
27
- `),process.exit(1)}}function M(){console.log(`
25
+ `);return}try{let r=await U(e),n=0,o=0,p=0;for(let i of r){let d=i.status==="created"||i.status==="updated"||i.status==="removed"?"\u2705":i.status==="up-to-date"?"\u2728":i.status==="skipped"?"\u23ED\uFE0F ":"\u274C";console.log(`${d} [${i.name}] (${i.status})`),console.log(` Path: ${i.path}`),console.log(` Info: ${i.message}
26
+ `),i.status==="created"||i.status==="updated"||i.status==="up-to-date"||i.status==="removed"?n++:i.status==="skipped"?o++:i.status==="error"&&p++}console.log("--------------------------------------------------------"),p>0&&(console.error(`\u26A0\uFE0F Setup finished with errors: ${p} failure(s), ${n} succeeded.`),process.exit(1)),console.log(`\u{1F389} Setup complete! ${n} environment(s) ready.`)}catch(r){let n=r instanceof Error?r.message:String(r);console.error(`\u274C Setup failed: ${n}
27
+ `),process.exit(1)}}function z(){console.log(`
28
28
  Superpowers MCP - Targeted Global Setup
29
29
 
30
30
  Usage:
@@ -67,4 +67,4 @@ Any Directory:
67
67
  Privacy & Safety:
68
68
  Superpowers MCP only touches the client you explicitly choose.
69
69
  It never bulk-modifies your environment without your consent.
70
- `)}_().catch(t=>{let e=t instanceof Error?t.message:String(t);console.error(`\u274C Fatal error: ${e}`),process.exit(1)});0&&(module.exports={HARNESS_CONFIGS,isPlainObject,runSetup,runSetupCli,safeWriteConfig,stripJsonComments,updateJsonConfig,updateYamlConfig});
70
+ `)}$().catch(t=>{let e=t instanceof Error?t.message:String(t);console.error(`\u274C Fatal error: ${e}`),process.exit(1)});0&&(module.exports={HARNESS_CONFIGS,isPlainObject,runSetup,runSetupCli,safeWriteConfig,stripJsonComments,updateJsonConfig,updateYamlConfig});
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "superpowers-mcp",
3
3
  "displayName": "Superpowers MCP",
4
4
  "description": "Superpowers skills library (TDD, debugging, collaboration workflows) as an MCP server for VSCode and Antigravity",
5
- "version": "6.3.7",
5
+ "version": "6.3.8",
6
6
  "engines": {
7
7
  "node": ">=18"
8
8
  },
@@ -34,7 +34,8 @@
34
34
  "out/setup.js",
35
35
  "out/setup-runner.js",
36
36
  "scripts",
37
- "skills"
37
+ "skills",
38
+ "docs"
38
39
  ],
39
40
  "overrides": {
40
41
  "@hono/node-server": "^2.1.1",
@@ -160,7 +160,7 @@
160
160
  // Expose API for explicit use
161
161
  window.brainstorm = {
162
162
  send: sendEvent,
163
- choice: (value, metadata = {}) => sendEvent({ type: 'choice', value, ...metadata })
163
+ choice: (value, metadata = {}) => sendEvent({ type: 'choice', ...metadata, choice: value })
164
164
  };
165
165
 
166
166
  connect();
@@ -6,7 +6,7 @@ const net = require('net');
6
6
 
7
7
  // ========== WebSocket Protocol (RFC 6455) ==========
8
8
 
9
- const OPCODES = { TEXT: 0x01, CLOSE: 0x08, PING: 0x09, PONG: 0x0A };
9
+ const OPCODES = { CONTINUATION: 0x00, TEXT: 0x01, CLOSE: 0x08, PING: 0x09, PONG: 0x0A };
10
10
  const WS_MAGIC = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
11
11
  const MAX_FRAME_PAYLOAD_BYTES = 10 * 1024 * 1024;
12
12
  // Bound concurrent WebSocket clients (each holds a frame buffer up to
@@ -52,6 +52,8 @@ function encodeFrame(opcode, payload) {
52
52
  function decodeFrame(buffer) {
53
53
  if (buffer.length < 2) return null;
54
54
 
55
+ const fin = (buffer[0] & 0x80) !== 0;
56
+ const rsv = buffer[0] & 0x70;
55
57
  const secondByte = buffer[1];
56
58
  const opcode = buffer[0] & 0x0F;
57
59
  const masked = (secondByte & 0x80) !== 0;
@@ -59,6 +61,10 @@ function decodeFrame(buffer) {
59
61
  let offset = 2;
60
62
 
61
63
  if (!masked) throw new Error('Client frames must be masked');
64
+ if (rsv !== 0) throw new Error('WebSocket extensions are not supported');
65
+ if (![OPCODES.CONTINUATION, OPCODES.TEXT, OPCODES.CLOSE, OPCODES.PING, OPCODES.PONG].includes(opcode)) {
66
+ throw new Error('Unsupported WebSocket opcode');
67
+ }
62
68
 
63
69
  if (payloadLen === 126) {
64
70
  if (buffer.length < 4) return null;
@@ -83,6 +89,9 @@ function decodeFrame(buffer) {
83
89
  if (opcode >= 0x8 && payloadLen > 125) {
84
90
  throw new Error('WebSocket control frame payload exceeds 125 bytes');
85
91
  }
92
+ if (opcode >= 0x8 && !fin) {
93
+ throw new Error('WebSocket control frames must not be fragmented');
94
+ }
86
95
 
87
96
  const maskOffset = offset;
88
97
  const dataOffset = offset + 4;
@@ -95,7 +104,7 @@ function decodeFrame(buffer) {
95
104
  data[i] = buffer[dataOffset + i] ^ mask[i % 4];
96
105
  }
97
106
 
98
- return { opcode, payload: data, bytesConsumed: totalLen };
107
+ return { fin, opcode, payload: data, bytesConsumed: totalLen };
99
108
  }
100
109
 
101
110
  // ========== Configuration ==========
@@ -351,7 +360,7 @@ function openPrivateAppendFile(filePath) {
351
360
  }
352
361
 
353
362
  let fd = null;
354
- const appendFlags = fs.constants.O_WRONLY | fs.constants.O_APPEND | fs.constants.O_CREAT | noFollow;
363
+ const appendFlags = fs.constants.O_RDWR | fs.constants.O_APPEND | fs.constants.O_CREAT | noFollow;
355
364
  try {
356
365
  if (!before) {
357
366
  try {
@@ -762,6 +771,9 @@ function handleUpgrade(req, socket) {
762
771
  let buffer = Buffer.alloc(0);
763
772
  let closed = false;
764
773
  let partialFrameTimer = null;
774
+ let fragmentedOpcode = null;
775
+ let fragmentedPayloads = [];
776
+ let fragmentedBytes = 0;
765
777
  clients.add(socket);
766
778
 
767
779
  const clearPartialFrameTimer = () => {
@@ -820,7 +832,36 @@ function handleUpgrade(req, socket) {
820
832
 
821
833
  switch (result.opcode) {
822
834
  case OPCODES.TEXT:
823
- handleMessage(result.payload.toString());
835
+ if (fragmentedOpcode !== null) {
836
+ closeSocket(1002);
837
+ return;
838
+ }
839
+ if (result.fin) {
840
+ handleMessage(result.payload.toString());
841
+ } else {
842
+ fragmentedOpcode = OPCODES.TEXT;
843
+ fragmentedPayloads = [result.payload];
844
+ fragmentedBytes = result.payload.length;
845
+ }
846
+ break;
847
+ case OPCODES.CONTINUATION:
848
+ if (fragmentedOpcode === null) {
849
+ closeSocket(1002);
850
+ return;
851
+ }
852
+ fragmentedBytes += result.payload.length;
853
+ if (fragmentedBytes > MAX_FRAME_PAYLOAD_BYTES) {
854
+ closeSocket(1009);
855
+ return;
856
+ }
857
+ fragmentedPayloads.push(result.payload);
858
+ if (result.fin) {
859
+ const message = Buffer.concat(fragmentedPayloads, fragmentedBytes);
860
+ fragmentedOpcode = null;
861
+ fragmentedPayloads = [];
862
+ fragmentedBytes = 0;
863
+ handleMessage(message.toString());
864
+ }
824
865
  break;
825
866
  case OPCODES.CLOSE:
826
867
  closeSocket();
@@ -834,6 +875,7 @@ function handleUpgrade(req, socket) {
834
875
  closeSocket(1003);
835
876
  return;
836
877
  }
878
+ if (fragmentedOpcode !== null) armPartialFrameTimer();
837
879
  }
838
880
  });
839
881
 
@@ -866,7 +908,16 @@ function appendEvent(event) {
866
908
  try {
867
909
  const current = fs.fstatSync(fd);
868
910
  if (current.size + lineBytes > MAX_EVENTS_FILE_BYTES) {
911
+ const keepBytes = MAX_EVENTS_FILE_BYTES - lineBytes;
912
+ const existing = Buffer.alloc(Math.min(current.size, MAX_EVENTS_FILE_BYTES));
913
+ const bytesRead = fs.readSync(fd, existing, 0, existing.length, Math.max(0, current.size - existing.length));
914
+ let retained = existing.subarray(Math.max(0, bytesRead - keepBytes), bytesRead);
915
+ if (retained.length < bytesRead) {
916
+ const firstNewline = retained.indexOf(0x0a);
917
+ retained = firstNewline >= 0 ? retained.subarray(firstNewline + 1) : Buffer.alloc(0);
918
+ }
869
919
  fs.ftruncateSync(fd, 0);
920
+ if (retained.length > 0) fs.writeSync(fd, retained);
870
921
  }
871
922
  fs.writeSync(fd, line);
872
923
  } catch (e) {
@@ -894,8 +945,12 @@ function handleMessage(text) {
894
945
  ? logLine
895
946
  : JSON.stringify({ source: 'user-event', truncated: true });
896
947
  console.log(logOutput);
897
- if (event && event.choice) {
898
- appendEvent(event);
948
+ if (event && typeof event === 'object') {
949
+ if (event.choice) {
950
+ appendEvent(event);
951
+ } else if (event.type === 'choice' && event.value) {
952
+ appendEvent({ ...event, choice: event.value });
953
+ }
899
954
  }
900
955
  }
901
956
 
@@ -46,13 +46,13 @@ if ! root=$(git rev-parse --show-toplevel 2>/dev/null); then
46
46
  root=$PWD
47
47
  echo "sdd-workspace: no git repository yet, using $root/.superpowers/sdd until this plan's first task creates one" >&2
48
48
  fi
49
- root=$(CDPATH= cd -- "$root" && pwd -P)
49
+ root=$(CDPATH='' cd -- "$root" && pwd -P)
50
50
  base="$root/.superpowers/sdd"
51
51
 
52
52
  # Normalize the plan path (physical directory, so relative/absolute/../
53
53
  # spellings of one plan compare equal) and express it as the marker value:
54
54
  # repo-relative when the plan lives under the repo root, absolute otherwise.
55
- plan_dir=$(CDPATH= cd -- "$(dirname -- "$plan")" && pwd -P)
55
+ plan_dir=$(CDPATH='' cd -- "$(dirname -- "$plan")" && pwd -P)
56
56
  plan_abs="$plan_dir/$(basename -- "$plan")"
57
57
  case "$plan_abs" in
58
58
  "$root"/*) plan_id=${plan_abs#"$root"/} ;;
@@ -83,4 +83,4 @@ if ! owns "$dir"; then
83
83
  fi
84
84
 
85
85
  printf '*\n' > "$base/.gitignore"
86
- CDPATH= cd -- "$dir" && pwd
86
+ CDPATH='' cd -- "$dir" && pwd
@@ -97,7 +97,11 @@ function Test-And-Claim-Workspace($targetDir, $id) {
97
97
  return ($existingId -eq $id)
98
98
  } else {
99
99
  New-Item -ItemType Directory -Force -Path $targetDir | Out-Null
100
- Set-Content -LiteralPath $markerPath -Value $id -Encoding ascii
100
+ [System.IO.File]::WriteAllText(
101
+ $markerPath,
102
+ $id + [Environment]::NewLine,
103
+ [System.Text.UTF8Encoding]::new($false)
104
+ )
101
105
  return $true
102
106
  }
103
107
  }
@@ -1,17 +1,19 @@
1
1
  #!/usr/bin/env pwsh
2
2
  # Bisection script to find which test creates unwanted files/state.
3
- # Usage: ./find-polluter.ps1 <file_or_dir_to_check> <test_pattern>
3
+ # Usage: ./find-polluter.ps1 <file_or_dir_to_check> <test_pattern> <test command and arguments>
4
4
 
5
5
  $ErrorActionPreference = "Stop"
6
6
 
7
- if ($args.Count -ne 2) {
8
- Write-Output "Usage: ./find-polluter.ps1 <file_to_check> <test_pattern>"
9
- Write-Output "Example: ./find-polluter.ps1 '.git' 'src/**/*.test.ts'"
7
+ if ($args.Count -lt 3) {
8
+ Write-Output "Usage: ./find-polluter.ps1 <file_to_check> <test_pattern> <test command and arguments>"
9
+ Write-Output "Example: ./find-polluter.ps1 '.git' 'src/**/*.test.ts' npx vitest run"
10
10
  exit 1
11
11
  }
12
12
 
13
13
  $pollutionCheck = $args[0]
14
14
  $testPattern = $args[1]
15
+ $testCommand = $args[2]
16
+ $testCommandArgs = if ($args.Count -gt 3) { @($args[3..($args.Count - 1)]) } else { @() }
15
17
 
16
18
  Write-Output "Searching for test that creates: $pollutionCheck"
17
19
  Write-Output "Test pattern: $testPattern"
@@ -53,7 +55,7 @@ foreach ($testFile in $testFiles) {
53
55
  }
54
56
 
55
57
  Write-Output "[$count/$total] Testing: $($testFile.FullName)"
56
- & npm test $testFile.FullName *> $null
58
+ & $testCommand @testCommandArgs $testFile.FullName *> $null
57
59
 
58
60
  if (Test-Path -LiteralPath $pollutionCheck) {
59
61
  Write-Output ""