@complexthings/superpowers-agent 10.0.0 → 10.0.2
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.
- package/.agents/docs/SUPERPOWERS.md +1 -1
- package/.agents/superpowers-agent +68 -71
- package/.agents/superpowers-bootstrap.md +0 -32
- package/.agents/templates/AGENTS.md.template +1 -1
- package/.agents/templates/SUPERPOWERS.md.template +1 -1
- package/AGENTS.md +1 -1
- package/README.md +19 -10
- package/package.json +2 -2
|
@@ -21,7 +21,7 @@ Periodically, e.g. once per day check the version of superpowers-agent:
|
|
|
21
21
|
> Your superpowers-agent has updates (`CURRENT_VERSION` → `NPM_LATEST_VERSION`). Run:
|
|
22
22
|
> ```sh
|
|
23
23
|
> npm install -g @complexthings/superpowers-agent
|
|
24
|
-
> superpowers-agent
|
|
24
|
+
> superpowers-agent bootstrap && superpowers-agent setup-skills
|
|
25
25
|
> ```
|
|
26
26
|
If versions match, or either lookup fails (e.g. no network), continue silently.
|
|
27
27
|
|
|
@@ -1,111 +1,108 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
// 2>/dev/null; exec "$(command -v bun 2>/dev/null || echo node)" "$0" "$@"
|
|
3
|
-
import{readFileSync as
|
|
3
|
+
import{readFileSync as lz,writeFileSync as iz,existsSync as Uz}from"fs";import{join as l}from"path";import{execSync as dQ}from"child_process";import{homedir as cz,platform as kQ}from"os";import{join as w,parse as PQ,dirname as nz}from"path";import{existsSync as g}from"fs";import{fileURLToPath as gQ}from"url";var mQ=gQ(import.meta.url),Zz=nz(mQ),hQ=()=>{let z=cz();switch(kQ()){case"darwin":return w(z,"Library","Application Support","Code","User");case"win32":return w(z,"AppData","Roaming","Code","User");case"linux":return w(z,".config","Code","User");default:return w(z,".config","Code","User")}},uQ=()=>{let z=process.cwd(),Q=PQ(z).root;while(z!==Q){if(g(w(z,".agents")))return z;z=nz(z)}return process.cwd()},_={home:cz(),vscodeUserDir:hQ(),projectRoot:uQ(),get projectClaudeSkills(){return w(this.projectRoot,".claude","skills")},get projectAgentsSkills(){return w(this.projectRoot,".agents","skills")},get projectCopilotSkills(){return w(this.projectRoot,".copilot","skills")},get projectOpencodeSkills(){return w(this.projectRoot,".opencode","skill")},get projectSkillsDir(){return w(this.projectRoot,"skills")},get homePersonalSkills(){return w(this.home,".agents","skills")},get homeClaudeSkills(){return w(this.home,".claude","skills")},get homeCopilotSkills(){return w(this.home,".copilot","skills")},get claudeSettings(){return w(this.home,".claude","settings.json")},get copilotHooksDir(){return process.env.COPILOT_HOME?w(process.env.COPILOT_HOME,"hooks"):w(this.home,".copilot","hooks")},get homeOpencodeSkills(){return w(this.home,".config","opencode","skill")},get bootstrap(){return w(this.projectRoot,".agents","superpowers-bootstrap.md")},get superpowersRepo(){let z=w(Zz,"..","..","..");if(g(w(z,"skills"))&&g(w(z,".agents","superpowers-agent")))return z;let Q=w(Zz,"..");if(g(w(Q,"skills"))&&g(w(Q,".agents","superpowers-agent")))return Q;return w(this.home,".agents","superpowers")},get homeSuperpowersSkills(){return w(this.superpowersRepo,"skills")},get isSuperpowersRepo(){let z=w(Zz,"..","..","..");if(g(w(z,"skills"))&&g(w(z,".agents","superpowers-agent")))return!0;let Q=w(Zz,"..");return g(w(Q,"skills"))&&g(w(Q,".agents","superpowers-agent"))}};var Jz=()=>({auto_update:!0,last_update_check:null,last_updated_commit:null}),zz=()=>{let z=l(_.superpowersRepo,".config.json");try{if(!Uz(z))return Jz();let Q=lz(z,"utf8");return{...Jz(),...JSON.parse(Q)}}catch{return Jz()}},az=(z)=>{let Q=l(_.superpowersRepo,".config.json"),$={...zz(),...z};try{iz(Q,JSON.stringify($,null,2))}catch(Z){console.log(`Warning: couldn't save config: ${Z.message}`)}},S=(z)=>{let Q=z?l(_.home,".agents","config.json"):l(process.cwd(),".agents","config.json");if(!Uz(Q))return{};try{let X=lz(Q,"utf8");return JSON.parse(X)}catch(X){return{}}},m=(z,Q)=>{let X=Q?l(_.home,".agents"):l(process.cwd(),".agents"),$=l(X,"config.json");try{if(!Uz(X))dQ(`mkdir -p "${X}"`,{stdio:"pipe"});return iz($,JSON.stringify(z,null,2),"utf8"),!0}catch(Z){throw Error(`Failed to write config: ${Z.message}`)}},P=(z=!1)=>{return S(z).repositories||{}},oz=(z,Q,X)=>{let $=S(X);if(!$.repositories)$.repositories={};$.repositories[z]=Q,m($,X)};function rz(z=!0){return S(z).installedSkills||{}}function _z(z,Q=!0){let X=S(Q);if(X.installedSkills)delete X.installedSkills[z];m(X,Q)}function sz(){return S(!0).installedAgents||{}}import{readFileSync as pQ}from"fs";import{join as Iz,dirname as cQ}from"path";import{fileURLToPath as nQ}from"url";import{existsSync as tz}from"fs";import{execSync as lQ}from"child_process";var iQ=nQ(import.meta.url),Lz=cQ(iQ),k=()=>{try{let z=Iz(Lz,"package.json");if(!tz(z))z=Iz(Lz,"..","package.json");if(!tz(z))z=Iz(Lz,"..","..","package.json");return JSON.parse(pQ(z,"utf8")).version||"0.0.0"}catch{return"0.0.0"}},i=()=>{let z=k();console.log(`^^SAV:${z}^^`)},$z=async()=>{try{let Q=lQ('curl -sS "https://registry.npmjs.org/@complexthings/superpowers-agent/latest"',{encoding:"utf8",timeout:1e4}),X=JSON.parse(Q);if(!X.version)return k();return X.version}catch(z){throw Error(`Failed to fetch remote version: ${z.message}`)}},Yz=(z,Q)=>{let X=z.split(".").map(Number),$=Q.split(".").map(Number);for(let Z=0;Z<3;Z++){let Y=X[Z]||0,H=$[Z]||0;if(Y>H)return!0;if(Y<H)return!1}return!1};var ez=()=>{let z=zz();console.log("Current configuration:"),console.log(JSON.stringify(z,null,2))},zQ=()=>{let z=process.argv[3],Q=process.argv[4];if(!z||Q===void 0){console.log(`Usage: .agents/superpowers-agent config-set <key> <value>
|
|
4
4
|
|
|
5
5
|
Available keys:
|
|
6
6
|
auto_update (true/false) - Enable/disable automatic updates during bootstrap
|
|
7
7
|
|
|
8
8
|
Examples:
|
|
9
9
|
.agents/superpowers-agent config-set auto_update false
|
|
10
|
-
.agents/superpowers-agent config-set auto_update true`);return}let X=Q;if(Q==="true")X=!0;else if(Q==="false")X=!1;
|
|
10
|
+
.agents/superpowers-agent config-set auto_update true`);return}let X=Q;if(Q==="true")X=!0;else if(Q==="false")X=!1;az({[z]:X}),console.log(`✓ Set ${z} = ${X}`)},QQ=()=>{i();let z=P(!0),Q=P(!1),X=[];for(let[Y,H]of Object.entries(z))X.push({alias:Y,url:H,source:"global"});for(let[Y,H]of Object.entries(Q)){let q=X.findIndex((V)=>V.alias===Y);if(q>=0)X[q]={alias:Y,url:H,source:"project"};else X.push({alias:Y,url:H,source:"project"})}if(X.length===0){console.log(`No repository aliases configured.
|
|
11
11
|
|
|
12
12
|
Add a repository using:
|
|
13
13
|
superpowers-agent add-repository <git-url> [--as=@alias]`);return}let $=Math.max(5,...X.map((Y)=>Y.alias.length)),Z=Math.max(3,...X.map((Y)=>Y.url.length));console.log(`Repositories:
|
|
14
14
|
`),console.log(`${"Alias".padEnd($)} ${"URL".padEnd(Z)} Source`);for(let Y of X)console.log(`${Y.alias.padEnd($)} ${Y.url.padEnd(Z)} (${Y.source})`);console.log(`
|
|
15
|
-
Total: ${X.length} repository alias(es)`)};var qz=async()=>{try{let z=k(),Q=await $z();return{hasUpdates:Yz(Q,z),localVersion:z,remoteVersion:Q}}catch{return{hasUpdates:!1,localVersion:k(),remoteVersion:"",error:!0}}};
|
|
16
|
-
`);let
|
|
17
|
-
`)
|
|
18
|
-
`)
|
|
19
|
-
`);try{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
Running bootstrap to complete setup...
|
|
23
|
-
`);try{ez("superpowers-agent bootstrap --no-update",{stdio:"inherit"}),console.log(`
|
|
24
|
-
✓ Bootstrap complete!`)}catch(X){console.log(`
|
|
25
|
-
⚠️ Bootstrap step failed: ${X.message}`),console.log(" The update installed successfully. Run manually to finish setup:"),console.log(" superpowers-agent bootstrap")}},zQ=async()=>{i();let z=k();console.log(`Current version: ${z}`);try{let Q=await $z();if(console.log(`Latest version: ${Q}`),Yz(Q,z))console.log("Update available: Yes"),process.exit(1);else console.log("You are up to date"),process.exit(0)}catch(Q){console.log(`Error checking for updates: ${Q.message}`),process.exit(1)}},QQ=()=>{let z=k();console.log(z)};import{existsSync as v,readFileSync as s,writeFileSync as r,rmSync as Az,lstatSync as SX,readdirSync as fX}from"fs";import{join as M,dirname as Fz,parse as a}from"path";import{execSync as f}from"child_process";import{platform as kX}from"os";import{existsSync as aQ}from"fs";import{join as oQ}from"path";import{execSync as iQ}from"child_process";var p=(z)=>{try{return iQ(`which ${z}`,{stdio:"pipe",timeout:2000}),!0}catch{return!1}};var D={opencode:{check:()=>p("opencode"),cli:!0,name:"OpenCode",installUrl:"https://opencode.ai/docs/installation",bootstrapCommand:"install-opencode-commands"},claude:{check:()=>p("claude"),cli:!0,name:"Claude Code",installUrl:"https://code.claude.com/docs/en/installation",bootstrapCommand:"install-claude-commands"},copilot:{check:()=>p("copilot"),cli:!0,name:"GitHub Copilot",bootstrapCommand:"install-copilot-prompts"},pi:{check:()=>p("pi"),cli:!0,name:"Pi Coding Agent"},codex:{check:()=>p("codex"),cli:!0,name:"OpenAI Codex"}},XQ=()=>{let z=[];if(D.copilot.check())z.push("github-copilot");if(D.claude.check())z.push("claude-code");if(D.opencode.check())z.push("opencode");return z},ZQ={"claude-code":".claude","github-copilot":".github",opencode:".opencode",pi:".pi",codex:".codex"},rQ={"claude-code":"claude","github-copilot":"copilot",opencode:"opencode",pi:"pi",codex:"codex"},sQ=(z,Q)=>{let X=ZQ[Q];return X?aQ(oQ(z,X)):!1},$Q=(z)=>{return Object.keys(ZQ).filter((Q)=>{let X=rQ[Q];return sQ(z,Q)||D[X].check()})},YQ=["github-copilot","opencode","pi","codex"];import{existsSync as Oz,readdirSync as gZ,lstatSync as tQ,symlinkSync as qQ,unlinkSync as eQ,mkdirSync as zX,readlinkSync as QX}from"fs";import{join as Tz,dirname as uZ}from"path";import{platform as XX}from"os";var Mz=(z)=>{try{return tQ(z).isSymbolicLink()}catch{return!1}},ZX=(z,Q)=>{try{if(!Mz(z))return!1;return QX(z)===Q}catch{return!1}},WQ=()=>{let z=Tz(I.superpowersRepo,".opencode","plugins","superpowers-agent.js"),Q=Tz(I.home,".config","opencode","plugins"),X=Tz(Q,"superpowers-agent.js");if(console.log("Installing OpenCode plugin symlink..."),!Oz(z))return console.log("⚠️ Source plugin not found, skipping symlink creation"),console.log(` Expected at: ${z}`),{created:!1,error:"Source plugin not found"};if(ZX(X,z))return console.log("✓ Plugin symlink already exists and is correct"),{created:!1,existed:!0};if(Oz(X)&&!Mz(X))return console.log("⚠️ Warning: A file already exists at the destination path"),console.log(` Path: ${X}`),console.log(" Skipping symlink creation to avoid overwriting existing file"),console.log(" To use superpowers-agent plugin, manually remove or rename the existing file"),{created:!1,error:"File already exists at destination"};if(!Oz(Q))try{zX(Q,{recursive:!0}),console.log(`✓ Created ${Q.replace(I.home,"~")}`)}catch(Z){return console.log(`⚠️ Failed to create plugins directory: ${Z.message}`),{created:!1,error:`Failed to create directory: ${Z.message}`}}if(Mz(X))try{eQ(X)}catch(Z){return console.log(`⚠️ Failed to remove existing symlink: ${Z.message}`),{created:!1,error:`Failed to remove existing symlink: ${Z.message}`}}let $=XX();try{if($==="win32")qQ(z,X,"file");else qQ(z,X);let Z=z.replace(I.home,"~"),Y=X.replace(I.home,"~");return console.log(`✓ Created symlink: ${Y}`),console.log(` -> ${Z}`),{created:!0}}catch(Z){if($==="win32"&&Z.code==="EPERM")return console.log("⚠️ Windows requires Developer Mode or admin privileges for symlinks"),console.log(" Enable Developer Mode: Settings > Update & Security > For developers"),{created:!1,error:"Windows symlink permission denied"};return console.log(`⚠️ Failed to create symlink: ${Z.message}`),{created:!1,error:`Failed to create symlink: ${Z.message}`}}};import{existsSync as HQ,readdirSync as nZ,readFileSync as $X,writeFileSync as YX,mkdirSync as qX,copyFileSync as WX}from"fs";import{join as iZ,dirname as HX}from"path";var BX="superpowers-agent session-context",VX="superpowers-agent session-context --format=claude 2>/dev/null || true",EX="startup|resume|clear|compact",BQ=(z=I.claudeSettings)=>{let Q={},X=!1,$;if(HQ(z)){X=!0;let G;try{G=$X(z,"utf8")}catch(E){return{error:!0,message:`Failed to read settings.json: ${E.message}`}}try{Q=G.trim()?JSON.parse(G):{}}catch(E){return{error:!0,message:`settings.json is not valid JSON, leaving it untouched: ${E.message}`}}let H=new Date().toISOString().split("T")[0];$=`${z}.backup-${H}`;try{WX(z,$)}catch(E){return{error:!0,message:`Failed to back up settings.json: ${E.message}`}}}if(typeof Q!=="object"||Q===null||Array.isArray(Q))return{error:!0,message:"settings.json root is not an object"};Q.hooks=Q.hooks||{};let Z=Array.isArray(Q.hooks.SessionStart)?Q.hooks.SessionStart:[],Y=(G)=>{try{return JSON.stringify(G).includes(BX)}catch{return!1}},V=Z.some(Y),q=Z.filter((G)=>!Y(G)),B={matcher:EX,hooks:[{type:"command",command:VX}]};Q.hooks.SessionStart=[...q,B];let W=HX(z);if(!HQ(W))try{qX(W,{recursive:!0})}catch(G){return{error:!0,message:`Failed to create ${W}: ${G.message}`}}try{YX(z,JSON.stringify(Q,null,2)+`
|
|
26
|
-
`,"utf8")}catch(G){return{error:!0,message:`Failed to write settings.json: ${G.message}`}}if(!X)return{created:!0};if(V)return{existed:!0,updated:!0,backup:$};return{updated:!0,backup:$}};import{existsSync as Nz,readdirSync as sZ,readFileSync as KX,writeFileSync as GX,mkdirSync as JX}from"fs";import{join as UX}from"path";var IX="superpowers.json",_X=()=>({version:1,hooks:{sessionStart:[{type:"command",bash:"superpowers-agent session-context --format=copilot 2>/dev/null || true",powershell:"superpowers-agent session-context --format=copilot 2>$null; exit 0",timeoutSec:15}]}}),VQ=(z=I.copilotHooksDir)=>{let Q=UX(z,IX),X=JSON.stringify(_X(),null,2)+`
|
|
27
|
-
`;if(Nz(Q)){let Z;try{Z=KX(Q,"utf8")}catch(Y){return{error:!0,message:`Failed to read ${Q}: ${Y.message}`}}if(Z===X)return{existed:!0,path:Q}}if(!Nz(z))try{JX(z,{recursive:!0})}catch(Z){return{error:!0,message:`Failed to create ${z}: ${Z.message}`}}let $=Nz(Q);try{GX(Q,X,"utf8")}catch(Z){return{error:!0,message:`Failed to write ${Q}: ${Z.message}`}}return $?{updated:!0,path:Q}:{created:!0,path:Q}};import{existsSync as h,readdirSync as LX,lstatSync as wX,symlinkSync as Qz,unlinkSync as Wz,mkdirSync as EQ,readlinkSync as OX}from"fs";import{join as u,dirname as KQ,basename as TX}from"path";import{homedir as c,platform as GQ}from"os";var Hz=[{name:"claude",parentDir:()=>u(c(),".claude"),skillsDir:()=>u(c(),".claude","skills")},{name:"copilot",parentDir:()=>u(c(),".copilot"),skillsDir:()=>u(c(),".copilot","skills")},{name:"opencode",parentDir:()=>u(c(),".config","opencode"),skillsDir:()=>u(c(),".config","opencode","skill")}],n=(z)=>{try{return wX(z).isSymbolicLink()}catch{return!1}},JQ=(z,Q)=>{try{if(!n(z))return!1;return OX(z)===Q}catch{return!1}},UQ=(z,Q)=>{if(!h(z))return{created:!1,existed:!1,error:`Source does not exist: ${z}`};if(JQ(Q,z))return{created:!1,existed:!0};if(h(Q)||n(Q))if(n(Q))try{Wz(Q)}catch(Z){return{created:!1,existed:!1,error:`Failed to remove existing symlink: ${Z.message}`}}else return{created:!1,existed:!1,error:`Target exists and is not a symlink: ${Q}`};let X=KQ(Q);if(!h(X))try{EQ(X,{recursive:!0})}catch(Z){return{created:!1,existed:!1,error:`Failed to create parent directory: ${Z.message}`}}let $=GQ();try{if($==="win32")Qz(z,Q,"junction");else Qz(z,Q,"dir");return{created:!0,existed:!1}}catch(Z){if($==="win32"&&Z.code==="EPERM")return{created:!1,existed:!1,error:"Windows requires Developer Mode or admin privileges for symlinks. Enable Developer Mode: Settings > Update & Security > For developers"};return{created:!1,existed:!1,error:`Failed to create symlink: ${Z.message}`}}},vz=(z)=>{if(!h(z)&&!n(z))return{removed:!1,error:"Symlink does not exist"};if(!n(z))return{removed:!1,error:"Target is not a symlink"};try{return Wz(z),{removed:!0}}catch(Q){return{removed:!1,error:`Failed to remove symlink: ${Q.message}`}}};var IQ=(z,Q,X="skills")=>{let $=S(!0);if(!$.symlinks||!$.symlinks[z])return;if(X==="superpowers")$.symlinks[z].superpowers=null;else{let Z=$.symlinks[z].skills||[];$.symlinks[z].skills=Z.filter((Y)=>Y!==Q)}m($,!0)};var MX=[".claude/skills",".github/skills",".opencode/skill"],_Q=(z)=>{let Q={created:0,skipped:0};for(let X of MX){let $=u(z,X),Z=KQ($);if(!h(Z)){Q.skipped++;continue}if(h($)&&!n($)){Q.skipped++;continue}if(n($))try{Wz($)}catch{Q.skipped++;continue}try{Qz("../.agents/skills",$,"dir"),Q.created++}catch{Q.skipped++}}return Q},LQ=(z,Q=[])=>{let X;try{X=LX(z,{withFileTypes:!0})}catch{return Q}let $=!1,Z=[];for(let Y of X){if(!Y.isDirectory()&&Y.name==="SKILL.md")$=!0;if(Y.isDirectory()&&!Y.name.startsWith("."))Z.push(u(z,Y.name))}if($)Q.push(z);for(let Y of Z)LQ(Y,Q);return Q},wQ=()=>{let z=I.homeSuperpowersSkills,Q=I.homePersonalSkills;if(!h(z))return{created:0,existed:0,updated:0,errors:[`Skills directory not found: ${z}`]};if(!h(Q))try{EQ(Q,{recursive:!0})}catch(Z){return{created:0,existed:0,updated:0,errors:[`Failed to create ${Q}: ${Z.message}`]}}let X=LQ(z),$={created:0,existed:0,updated:0,errors:[]};for(let Z of X){let Y=TX(Z),V=u(Q,Y);if(JQ(V,Z)){$.existed++;continue}if(n(V))try{Wz(V),$.updated++}catch(B){$.errors.push(`Failed to remove stale symlink ${V}: ${B.message}`);continue}else if(h(V)){$.errors.push(`Skipped ${V}: path exists and is not a symlink`);continue}let q=GQ();try{if(q==="win32")Qz(Z,V,"junction");else Qz(Z,V,"dir");let B=V.replace(c(),"~"),W=Z.replace(c(),"~");console.log(` ✓ ${B} -> ${W}`),$.created++}catch(B){$.errors.push(`Failed to create symlink ${V}: ${B.message}`)}}return $};import{existsSync as NX,lstatSync as vX,readdirSync as AX,readlinkSync as FX,unlinkSync as bX}from"fs";import{basename as CX,join as jX,resolve as OQ,sep as xX}from"path";var DX=new Set(["preserving-productive-tensions","dispatching-parallel-agents","executing-plans","finishing-a-development-branch","receiving-code-review","requesting-code-review","subagent-driven-development","using-git-worktrees","writing-plans","defense-in-depth","root-cause-tracing","systematic-debugging","verification-before-completion","finding-skills","create-agents-md","creating-prompts","using-superpowers","writing-prompts","collision-zone-thinking","inversion-exercise","meta-pattern-recognition","scale-game","simplification-cascades","when-stuck","tracing-knowledge-lineages","condition-based-waiting","test-driven-development","testing-anti-patterns","using-a-skill"]),RX=(z,Q)=>z===Q||z.startsWith(`${Q}${xX}`),yX=({skillDir:z,bundledSkillsDir:Q,retiredSkillNames:X=DX})=>{let $=[],Z=0,Y=OQ(Q);if(!NX(z))return{removed:$,skipped:Z};let V;try{V=AX(z)}catch{return{removed:$,skipped:Z}}for(let q of V){let B=jX(z,q);try{if(!vX(B).isSymbolicLink())continue;let W=OQ(z,FX(B));if(!RX(W,Y)||!X.has(CX(W))){Z++;continue}bX(B),$.push(B)}catch{Z++}}return{removed:$,skipped:Z}},TQ=()=>yX({skillDir:I.homePersonalSkills,bundledSkillsDir:I.homeSuperpowersSkills});var bz=(z)=>{let Q=Fz(z),X=a(z).base;if(v(Q)){for(let Y of fX(Q))if(Y.startsWith(`${X}.backup`))Az(M(Q,Y))}let $=new Date().toISOString().split("T")[0],Z=`${z}.backup-${$}`;return f(`cp "${z}" "${Z}"`,{stdio:"pipe"}),Z},Bz=(z,Q,X,$=!0)=>{let Z=v(z);if(!Z&&!$)return{updated:!1,created:!1,skipped:!0};let Y=Q,V=new Date().toISOString().split("T")[0];Y=Y.replace(/\{\{DATE\}\}/g,V),Y=Y.replace(/\{\{SUPERPOWERS_PATH\}\}/g,I.superpowersRepo);let q=`<!-- SUPERPOWERS_SKILLS_START -->
|
|
15
|
+
Total: ${X.length} repository alias(es)`)};var qz=async()=>{try{let z=k(),Q=await $z();return{hasUpdates:Yz(Q,z),localVersion:z,remoteVersion:Q}}catch{return{hasUpdates:!1,localVersion:k(),remoteVersion:"",error:!0}}};var wz={npm:"npm install -g @complexthings/superpowers-agent",pnpm:"pnpm add -g @complexthings/superpowers-agent",yarn:"yarn global add @complexthings/superpowers-agent",bun:"bun add -g @complexthings/superpowers-agent",deno:"deno install -g -A -n superpowers-agent npm:@complexthings/superpowers-agent"},Oz=(z=_.superpowersRepo)=>{let Q=String(z).toLowerCase().replace(/\\/g,"/");if(Q.includes("/.bun/")||Q.includes("/bun/install"))return"bun";if(Q.includes("/pnpm"))return"pnpm";if(Q.includes("/yarn"))return"yarn";if(Q.includes("/.deno/")||Q.includes("/deno/"))return"deno";return"npm"},Tz=async()=>{console.log(`# Checking for Superpowers updates...
|
|
16
|
+
`);let z=await qz();if(z.error){console.log("⚠️ Could not check for updates (network issue)");return}if(!z.hasUpdates){console.log(`✓ Already up to date (v${z.localVersion})`);return}console.log(`\uD83D\uDCE6 Update available: v${z.localVersion} → v${z.remoteVersion}
|
|
17
|
+
`);let Q=Oz();console.log(` To update, run:
|
|
18
|
+
`),console.log(` ${wz[Q]}`),console.log(` superpowers-agent bootstrap && superpowers-agent setup-skills
|
|
19
|
+
`)},XQ=async()=>{i();let z=k();console.log(`Current version: ${z}`);try{let Q=await $z();if(console.log(`Latest version: ${Q}`),Yz(Q,z))console.log("Update available: Yes"),process.exit(1);else console.log("You are up to date"),process.exit(0)}catch(Q){console.log(`Error checking for updates: ${Q.message}`),process.exit(1)}},ZQ=()=>{let z=k();console.log(z)};import{existsSync as N,readFileSync as s,writeFileSync as r,rmSync as Cz,lstatSync as fX,readdirSync as kX}from"fs";import{join as M,dirname as jz,parse as a}from"path";import{execSync as f}from"child_process";import{platform as PX}from"os";import{existsSync as oQ}from"fs";import{join as rQ}from"path";import{execSync as aQ}from"child_process";var p=(z)=>{try{return aQ(`which ${z}`,{stdio:"pipe",timeout:2000}),!0}catch{return!1}};var D={opencode:{check:()=>p("opencode"),cli:!0,name:"OpenCode",installUrl:"https://opencode.ai/docs/installation",bootstrapCommand:"install-opencode-commands"},claude:{check:()=>p("claude"),cli:!0,name:"Claude Code",installUrl:"https://code.claude.com/docs/en/installation",bootstrapCommand:"install-claude-commands"},copilot:{check:()=>p("copilot"),cli:!0,name:"GitHub Copilot",bootstrapCommand:"install-copilot-prompts"},pi:{check:()=>p("pi"),cli:!0,name:"Pi Coding Agent"},codex:{check:()=>p("codex"),cli:!0,name:"OpenAI Codex"}},$Q=()=>{let z=[];if(D.copilot.check())z.push("github-copilot");if(D.claude.check())z.push("claude-code");if(D.opencode.check())z.push("opencode");return z},YQ={"claude-code":".claude","github-copilot":".github",opencode:".opencode",pi:".pi",codex:".codex"},sQ={"claude-code":"claude","github-copilot":"copilot",opencode:"opencode",pi:"pi",codex:"codex"},tQ=(z,Q)=>{let X=YQ[Q];return X?oQ(rQ(z,X)):!1},qQ=(z)=>{return Object.keys(YQ).filter((Q)=>{let X=sQ[Q];return tQ(z,Q)||D[X].check()})},WQ=["github-copilot","opencode","pi","codex"];import{existsSync as Mz,readdirSync as mZ,lstatSync as eQ,symlinkSync as HQ,unlinkSync as zX,mkdirSync as QX,readlinkSync as XX}from"fs";import{join as Nz,dirname as uZ}from"path";import{platform as ZX}from"os";var vz=(z)=>{try{return eQ(z).isSymbolicLink()}catch{return!1}},$X=(z,Q)=>{try{if(!vz(z))return!1;return XX(z)===Q}catch{return!1}},BQ=()=>{let z=Nz(_.superpowersRepo,".opencode","plugins","superpowers-agent.js"),Q=Nz(_.home,".config","opencode","plugins"),X=Nz(Q,"superpowers-agent.js");if(console.log("Installing OpenCode plugin symlink..."),!Mz(z))return console.log("⚠️ Source plugin not found, skipping symlink creation"),console.log(` Expected at: ${z}`),{created:!1,error:"Source plugin not found"};if($X(X,z))return console.log("✓ Plugin symlink already exists and is correct"),{created:!1,existed:!0};if(Mz(X)&&!vz(X))return console.log("⚠️ Warning: A file already exists at the destination path"),console.log(` Path: ${X}`),console.log(" Skipping symlink creation to avoid overwriting existing file"),console.log(" To use superpowers-agent plugin, manually remove or rename the existing file"),{created:!1,error:"File already exists at destination"};if(!Mz(Q))try{QX(Q,{recursive:!0}),console.log(`✓ Created ${Q.replace(_.home,"~")}`)}catch(Z){return console.log(`⚠️ Failed to create plugins directory: ${Z.message}`),{created:!1,error:`Failed to create directory: ${Z.message}`}}if(vz(X))try{zX(X)}catch(Z){return console.log(`⚠️ Failed to remove existing symlink: ${Z.message}`),{created:!1,error:`Failed to remove existing symlink: ${Z.message}`}}let $=ZX();try{if($==="win32")HQ(z,X,"file");else HQ(z,X);let Z=z.replace(_.home,"~"),Y=X.replace(_.home,"~");return console.log(`✓ Created symlink: ${Y}`),console.log(` -> ${Z}`),{created:!0}}catch(Z){if($==="win32"&&Z.code==="EPERM")return console.log("⚠️ Windows requires Developer Mode or admin privileges for symlinks"),console.log(" Enable Developer Mode: Settings > Update & Security > For developers"),{created:!1,error:"Windows symlink permission denied"};return console.log(`⚠️ Failed to create symlink: ${Z.message}`),{created:!1,error:`Failed to create symlink: ${Z.message}`}}};import{existsSync as VQ,readdirSync as lZ,readFileSync as YX,writeFileSync as qX,mkdirSync as WX,copyFileSync as HX}from"fs";import{join as aZ,dirname as BX}from"path";var VX="superpowers-agent session-context",EX="superpowers-agent session-context --format=claude 2>/dev/null || true",KX="startup|resume|clear|compact",EQ=(z=_.claudeSettings)=>{let Q={},X=!1,$;if(VQ(z)){X=!0;let G;try{G=YX(z,"utf8")}catch(E){return{error:!0,message:`Failed to read settings.json: ${E.message}`}}try{Q=G.trim()?JSON.parse(G):{}}catch(E){return{error:!0,message:`settings.json is not valid JSON, leaving it untouched: ${E.message}`}}let B=new Date().toISOString().split("T")[0];$=`${z}.backup-${B}`;try{HX(z,$)}catch(E){return{error:!0,message:`Failed to back up settings.json: ${E.message}`}}}if(typeof Q!=="object"||Q===null||Array.isArray(Q))return{error:!0,message:"settings.json root is not an object"};Q.hooks=Q.hooks||{};let Z=Array.isArray(Q.hooks.SessionStart)?Q.hooks.SessionStart:[],Y=(G)=>{try{return JSON.stringify(G).includes(VX)}catch{return!1}},H=Z.some(Y),q=Z.filter((G)=>!Y(G)),V={matcher:KX,hooks:[{type:"command",command:EX}]};Q.hooks.SessionStart=[...q,V];let W=BX(z);if(!VQ(W))try{WX(W,{recursive:!0})}catch(G){return{error:!0,message:`Failed to create ${W}: ${G.message}`}}try{qX(z,JSON.stringify(Q,null,2)+`
|
|
20
|
+
`,"utf8")}catch(G){return{error:!0,message:`Failed to write settings.json: ${G.message}`}}if(!X)return{created:!0};if(H)return{existed:!0,updated:!0,backup:$};return{updated:!0,backup:$}};import{existsSync as Az,readdirSync as tZ,readFileSync as GX,writeFileSync as JX,mkdirSync as UX}from"fs";import{join as _X}from"path";var IX="superpowers.json",LX=()=>({version:1,hooks:{sessionStart:[{type:"command",bash:"superpowers-agent session-context --format=copilot 2>/dev/null || true",powershell:"superpowers-agent session-context --format=copilot 2>$null; exit 0",timeoutSec:15}]}}),KQ=(z=_.copilotHooksDir)=>{let Q=_X(z,IX),X=JSON.stringify(LX(),null,2)+`
|
|
21
|
+
`;if(Az(Q)){let Z;try{Z=GX(Q,"utf8")}catch(Y){return{error:!0,message:`Failed to read ${Q}: ${Y.message}`}}if(Z===X)return{existed:!0,path:Q}}if(!Az(z))try{UX(z,{recursive:!0})}catch(Z){return{error:!0,message:`Failed to create ${z}: ${Z.message}`}}let $=Az(Q);try{JX(Q,X,"utf8")}catch(Z){return{error:!0,message:`Failed to write ${Q}: ${Z.message}`}}return $?{updated:!0,path:Q}:{created:!0,path:Q}};import{existsSync as u,readdirSync as wX,lstatSync as OX,symlinkSync as Qz,unlinkSync as Wz,mkdirSync as GQ,readlinkSync as TX}from"fs";import{join as h,dirname as JQ,basename as MX}from"path";import{homedir as c,platform as UQ}from"os";var Hz=[{name:"claude",parentDir:()=>h(c(),".claude"),skillsDir:()=>h(c(),".claude","skills")},{name:"copilot",parentDir:()=>h(c(),".copilot"),skillsDir:()=>h(c(),".copilot","skills")},{name:"opencode",parentDir:()=>h(c(),".config","opencode"),skillsDir:()=>h(c(),".config","opencode","skill")}],n=(z)=>{try{return OX(z).isSymbolicLink()}catch{return!1}},_Q=(z,Q)=>{try{if(!n(z))return!1;return TX(z)===Q}catch{return!1}},IQ=(z,Q)=>{if(!u(z))return{created:!1,existed:!1,error:`Source does not exist: ${z}`};if(_Q(Q,z))return{created:!1,existed:!0};if(u(Q)||n(Q))if(n(Q))try{Wz(Q)}catch(Z){return{created:!1,existed:!1,error:`Failed to remove existing symlink: ${Z.message}`}}else return{created:!1,existed:!1,error:`Target exists and is not a symlink: ${Q}`};let X=JQ(Q);if(!u(X))try{GQ(X,{recursive:!0})}catch(Z){return{created:!1,existed:!1,error:`Failed to create parent directory: ${Z.message}`}}let $=UQ();try{if($==="win32")Qz(z,Q,"junction");else Qz(z,Q,"dir");return{created:!0,existed:!1}}catch(Z){if($==="win32"&&Z.code==="EPERM")return{created:!1,existed:!1,error:"Windows requires Developer Mode or admin privileges for symlinks. Enable Developer Mode: Settings > Update & Security > For developers"};return{created:!1,existed:!1,error:`Failed to create symlink: ${Z.message}`}}},Fz=(z)=>{if(!u(z)&&!n(z))return{removed:!1,error:"Symlink does not exist"};if(!n(z))return{removed:!1,error:"Target is not a symlink"};try{return Wz(z),{removed:!0}}catch(Q){return{removed:!1,error:`Failed to remove symlink: ${Q.message}`}}};var LQ=(z,Q,X="skills")=>{let $=S(!0);if(!$.symlinks||!$.symlinks[z])return;if(X==="superpowers")$.symlinks[z].superpowers=null;else{let Z=$.symlinks[z].skills||[];$.symlinks[z].skills=Z.filter((Y)=>Y!==Q)}m($,!0)};var NX=[".claude/skills",".github/skills",".opencode/skill"],wQ=(z)=>{let Q={created:0,skipped:0};for(let X of NX){let $=h(z,X),Z=JQ($);if(!u(Z)){Q.skipped++;continue}if(u($)&&!n($)){Q.skipped++;continue}if(n($))try{Wz($)}catch{Q.skipped++;continue}try{Qz("../.agents/skills",$,"dir"),Q.created++}catch{Q.skipped++}}return Q},OQ=(z,Q=[])=>{let X;try{X=wX(z,{withFileTypes:!0})}catch{return Q}let $=!1,Z=[];for(let Y of X){if(!Y.isDirectory()&&Y.name==="SKILL.md")$=!0;if(Y.isDirectory()&&!Y.name.startsWith("."))Z.push(h(z,Y.name))}if($)Q.push(z);for(let Y of Z)OQ(Y,Q);return Q},bz=(z=_.homePersonalSkills)=>{let Q=_.homeSuperpowersSkills;if(!u(Q))return{created:0,existed:0,updated:0,errors:[`Skills directory not found: ${Q}`]};if(!u(z))try{GQ(z,{recursive:!0})}catch(Z){return{created:0,existed:0,updated:0,errors:[`Failed to create ${z}: ${Z.message}`]}}let X=OQ(Q),$={created:0,existed:0,updated:0,errors:[]};for(let Z of X){let Y=MX(Z),H=h(z,Y);if(_Q(H,Z)){$.existed++;continue}if(n(H))try{Wz(H),$.updated++}catch(V){$.errors.push(`Failed to remove stale symlink ${H}: ${V.message}`);continue}else if(u(H)){$.errors.push(`Skipped ${H}: path exists and is not a symlink`);continue}let q=UQ();try{if(q==="win32")Qz(Z,H,"junction");else Qz(Z,H,"dir");let V=H.replace(c(),"~"),W=Z.replace(c(),"~");console.log(` ✓ ${V} -> ${W}`),$.created++}catch(V){$.errors.push(`Failed to create symlink ${H}: ${V.message}`)}}return $};import{existsSync as vX,lstatSync as AX,readdirSync as FX,readlinkSync as bX,unlinkSync as CX}from"fs";import{basename as jX,join as xX,resolve as TQ,sep as DX}from"path";var RX=new Set(["preserving-productive-tensions","dispatching-parallel-agents","executing-plans","finishing-a-development-branch","receiving-code-review","requesting-code-review","subagent-driven-development","using-git-worktrees","writing-plans","defense-in-depth","root-cause-tracing","systematic-debugging","verification-before-completion","finding-skills","create-agents-md","creating-prompts","using-superpowers","writing-prompts","collision-zone-thinking","inversion-exercise","meta-pattern-recognition","scale-game","simplification-cascades","when-stuck","tracing-knowledge-lineages","condition-based-waiting","test-driven-development","testing-anti-patterns","using-a-skill"]),yX=(z,Q)=>z===Q||z.startsWith(`${Q}${DX}`),SX=({skillDir:z,bundledSkillsDir:Q,retiredSkillNames:X=RX})=>{let $=[],Z=0,Y=TQ(Q);if(!vX(z))return{removed:$,skipped:Z};let H;try{H=FX(z)}catch{return{removed:$,skipped:Z}}for(let q of H){let V=xX(z,q);try{if(!AX(V).isSymbolicLink())continue;let W=TQ(z,bX(V));if(!yX(W,Y)||!X.has(jX(W))){Z++;continue}CX(V),$.push(V)}catch{Z++}}return{removed:$,skipped:Z}},MQ=()=>{let z=[_.homePersonalSkills,_.homeClaudeSkills],Q=[],X=0;for(let $ of z){let Z=SX({skillDir:$,bundledSkillsDir:_.homeSuperpowersSkills});Q.push(...Z.removed),X+=Z.skipped}return{removed:Q,skipped:X}};var xz=(z)=>{let Q=jz(z),X=a(z).base;if(N(Q)){for(let Y of kX(Q))if(Y.startsWith(`${X}.backup`))Cz(M(Q,Y))}let $=new Date().toISOString().split("T")[0],Z=`${z}.backup-${$}`;return f(`cp "${z}" "${Z}"`,{stdio:"pipe"}),Z},Bz=(z,Q,X,$=!0)=>{let Z=N(z);if(!Z&&!$)return{updated:!1,created:!1,skipped:!0};let Y=Q,H=new Date().toISOString().split("T")[0];Y=Y.replace(/\{\{DATE\}\}/g,H),Y=Y.replace(/\{\{SUPERPOWERS_PATH\}\}/g,_.superpowersRepo);let q=`<!-- SUPERPOWERS_SKILLS_START -->
|
|
28
22
|
${Y}
|
|
29
|
-
<!-- SUPERPOWERS_SKILLS_END -->`;if(Z){let
|
|
23
|
+
<!-- SUPERPOWERS_SKILLS_END -->`;if(Z){let V;try{V=xz(z)}catch(J){return{updated:!1,error:!0,message:`Failed to backup: ${J.message}`}}let W;try{W=s(z,"utf8")}catch(J){return{updated:!1,error:!0,message:`Failed to read: ${J.message}`}}let G="<!-- SUPERPOWERS_SKILLS_START -->",B="<!-- SUPERPOWERS_SKILLS_END -->",E;if(W.includes(G)&&W.includes(B)){let J=new RegExp(`${G}[\\s\\S]*?${B}`,"g");E=W.replace(J,q)}else{let J=W.match(/^#\s+.+$/m);if(J){let O=W.indexOf(`
|
|
30
24
|
`,J.index)+1;E=W.slice(0,O)+`
|
|
31
25
|
`+q+`
|
|
32
26
|
`+W.slice(O)}else E=q+`
|
|
33
27
|
|
|
34
|
-
`+W}try{return r(z,E,"utf8"),{updated:!0,created:!1,backup:
|
|
28
|
+
`+W}try{return r(z,E,"utf8"),{updated:!0,created:!1,backup:V}}catch(J){return{updated:!1,error:!0,message:`Failed to write: ${J.message}`}}}else try{let V=jz(z);if(!N(V))f(`mkdir -p "${V}"`,{stdio:"pipe"});let B=`# ${a(z).base.toUpperCase()}
|
|
35
29
|
|
|
36
|
-
`+q;return r(z,
|
|
30
|
+
`+q;return r(z,B,"utf8"),{updated:!1,created:!0}}catch(V){return{updated:!1,created:!1,error:!0,message:`Failed to create: ${V.message}`}}},gX=()=>{console.log("Installing Unix aliases...");let z=M(_.superpowersRepo,".agents","superpowers-agent"),Q=M(_.home,".local","bin"),X=M(Q,"superpowers-agent"),$=M(Q,"superpowers");if(!N(z)){console.log("⚠️ superpowers-agent executable not found");return}if(!N(Q))try{f(`mkdir -p "${Q}"`,{stdio:"pipe"}),console.log(`✓ Created ${Q}`)}catch(Y){console.log(`⚠️ Failed to create ${Q}: ${Y.message}`);return}try{if(N(X))f(`rm "${X}"`,{stdio:"pipe"});f(`ln -s "${z}" "${X}"`,{stdio:"pipe"}),console.log(`✓ Created symlink: superpowers-agent -> ${z}`)}catch(Y){console.log(`⚠️ Failed to create superpowers-agent symlink: ${Y.message}`)}try{if(N($))f(`rm "${$}"`,{stdio:"pipe"});f(`ln -s "${z}" "${$}"`,{stdio:"pipe"}),console.log(`✓ Created symlink: superpowers -> ${z}`)}catch(Y){console.log(`⚠️ Failed to create superpowers symlink: ${Y.message}`)}if(!(process.env.PATH||"").includes(Q))console.log(`
|
|
37
31
|
⚠️ Warning: ${Q} is not in your PATH`),console.log(" Add this to your shell profile (~/.bashrc, ~/.zshrc, etc.):"),console.log(` export PATH="$HOME/.local/bin:$PATH"
|
|
38
|
-
`)},
|
|
39
|
-
`),z==="win32")return
|
|
32
|
+
`)},mX=()=>{console.log("Installing Windows aliases..."),console.log("✓ Windows alias installation (implementation pending)")},Dz=()=>{let z=PX();if(console.log(`## Installing Universal Aliases
|
|
33
|
+
`),z==="win32")return mX();else return gX()},hX=(z)=>{let Q=M(_.superpowersRepo,".github","copilot-instructions.md"),X=M(z,".github","copilot-instructions.md"),$="<!-- SUPERPOWERS_-_INSTRUCTIONS_START -->",Z="<!-- SUPERPOWERS_-_INSTRUCTIONS_END -->";if(!N(Q))return{error:!0,message:"Source template not found"};let Y;try{Y=s(Q,"utf8")}catch(V){return{error:!0,message:`Failed to read source template: ${V.message}`}}if(!Y.includes("<!-- SUPERPOWERS_-_INSTRUCTIONS_START -->")||!Y.includes("<!-- SUPERPOWERS_-_INSTRUCTIONS_END -->"))return{error:!0,message:"Template is missing required markers"};let H=Y.match(new RegExp("<!-- SUPERPOWERS_-_INSTRUCTIONS_START -->[\\s\\S]*?<!-- SUPERPOWERS_-_INSTRUCTIONS_END -->"))[0],q=jz(X);try{if(!N(q))f(`mkdir -p "${q}"`,{stdio:"pipe"})}catch(V){return{error:!0,message:`Failed to create .github directory: ${V.message}`}}if(N(X)){let V;try{V=s(X,"utf8")}catch(G){return{error:!0,message:`Failed to read existing file: ${G.message}`}}let W;try{W=xz(X)}catch(G){return{error:!0,message:`Failed to backup: ${G.message}`}}if(V.includes("<!-- SUPERPOWERS_-_INSTRUCTIONS_START -->")&&V.includes("<!-- SUPERPOWERS_-_INSTRUCTIONS_END -->")){let G=new RegExp("<!-- SUPERPOWERS_-_INSTRUCTIONS_START -->[\\s\\S]*?<!-- SUPERPOWERS_-_INSTRUCTIONS_END -->","g"),B=V.replace(G,H);try{return r(X,B,"utf8"),{updated:!0,backup:W}}catch(E){return{error:!0,message:`Failed to update: ${E.message}`}}}else{let G=V.trimEnd()+`
|
|
40
34
|
|
|
41
35
|
`+Y.trim()+`
|
|
42
|
-
`;try{return r(X,G,"utf8"),{updated:!0,backup:W}}catch(
|
|
43
|
-
`);let z=process.cwd(),Q=M(z,".agents"),X=M(Q,"skills"),$=M(z,"AGENTS.md"),Z=M(Q,"AGENTS.md"),Y=
|
|
44
|
-
Expected at: ${
|
|
45
|
-
Please update your Superpowers installation`);return}if(!
|
|
36
|
+
`;try{return r(X,G,"utf8"),{updated:!0,backup:W}}catch(B){return{error:!0,message:`Failed to append: ${B.message}`}}}}else try{return r(X,Y,"utf8"),{created:!0}}catch(V){return{error:!0,message:`Failed to create: ${V.message}`}}},NQ=()=>{i(),console.log(`# Setting up Superpowers skills for this project
|
|
37
|
+
`);let z=process.cwd(),Q=M(z,".agents"),X=M(Q,"skills"),$=M(z,"AGENTS.md"),Z=M(Q,"AGENTS.md"),Y=N($)?$:Z,H=M(_.superpowersRepo,".agents","templates","AGENTS.md.template");if(!N(H)){console.log(`✗ Error: AGENTS.md template not found
|
|
38
|
+
Expected at: ${H}
|
|
39
|
+
Please update your Superpowers installation`);return}if(!N(Q))try{f(`mkdir -p "${Q}"`,{stdio:"pipe"}),console.log("✓ Created .agents/ directory")}catch(L){console.log(`✗ Failed to create .agents/ directory: ${L.message}`);return}else console.log("✓ .agents/ directory exists");if(!N(X))try{f(`mkdir -p "${X}"`,{stdio:"pipe"}),f(`touch "${M(X,".gitkeep")}"`,{stdio:"pipe"}),console.log("✓ Created .agents/skills/ directory")}catch(L){console.log(`✗ Failed to create skills directory: ${L.message}`);return}else console.log("✓ .agents/skills/ directory exists");let q=wQ(z);console.log(`✓ Synced per-harness skills symlinks (${q.created} created, ${q.skipped} skipped)`);let V=M(Q,"docs"),W=M(V,"SUPERPOWERS.md"),G=M(_.superpowersRepo,".agents","templates","SUPERPOWERS.md.template");if(!N(V))try{f(`mkdir -p "${V}"`,{stdio:"pipe"}),console.log("✓ Created .agents/docs/ directory")}catch(L){console.log(`⚠️ Failed to create docs directory: ${L.message}`)}else console.log("✓ .agents/docs/ directory exists");let B=N(Y);if(B)try{let L=xz(Y);console.log(`✓ Backed up existing AGENTS.md to ${a(L).base}`)}catch(L){console.log(`✗ Failed to backup AGENTS.md: ${L.message}`);return}let E;try{E=s(H,"utf8")}catch(L){console.log(`✗ Failed to read template: ${L.message}`);return}let J=k();if(E=E.replace(/\{\{VERSION\}\}/g,J),N(G))try{let L=s(G,"utf8"),o=new Date().toISOString().split("T")[0];L=L.replace(/\{\{VERSION\}\}/g,J),L=L.replace(/\{\{DATE\}\}/g,o),r(W,L,"utf8"),console.log("✓ Created .agents/docs/SUPERPOWERS.md")}catch(L){console.log(`⚠️ Failed to create SUPERPOWERS.md: ${L.message}`)}else console.log("⚠️ SUPERPOWERS.md.template not found");let O=qQ(z),U=M(z,"CLAUDE.md"),v=M(Q,"CLAUDE.md");console.log(`
|
|
46
40
|
Detected platforms for project: ${O.join(", ")||"none"}
|
|
47
|
-
`);let C=O.filter((L)=>
|
|
41
|
+
`);let C=O.filter((L)=>WQ.includes(L)),j=Bz(Y,E,C,!B);if(j.created)console.log(`✓ Created AGENTS.md with platform tool mappings (${Y===$?"root":".agents/"})`);else if(j.updated)console.log(`✓ Updated AGENTS.md with platform tool mappings (${Y===$?"root":".agents/"})`);else if(j.error)console.log("⚠️ Failed to update AGENTS.md");let A=N(U)?U:v,R=Bz(A,E,["claude-code"],!1);if(R.created)console.log(`✓ Created CLAUDE.md with Claude Code tool mappings (${A===U?"root":".agents/"})`);else if(R.updated){if(console.log(`✓ Updated CLAUDE.md with Claude Code tool mappings (${A===U?"root":".agents/"})`),R.backup)console.log(` Backed up to ${a(R.backup).base}`)}else if(R.skipped)console.log("ℹ️ Skipped CLAUDE.md (does not exist)");else if(R.error)console.log("⚠️ Failed to update CLAUDE.md");let K=M(z,".github","copilot-instructions.md"),I={skipped:!0};if(O.includes("github-copilot")){if(I=hX(z),I.created)console.log("✓ Created .github/copilot-instructions.md with Superpowers instructions");else if(I.updated){if(console.log("✓ Updated .github/copilot-instructions.md with Superpowers instructions"),I.backup)console.log(` Backed up to ${a(I.backup).base}`)}else if(I.error)console.log(`⚠️ Failed to update .github/copilot-instructions.md: ${I.message||""}`)}else console.log("ℹ️ Skipped .github/copilot-instructions.md (GitHub Copilot not detected)");let y=!N($)&&!N(Z);if(N(K)&&y){let L=Bz(K,E,["github-copilot"],!1);if(L.updated){if(console.log("✓ Updated .github/copilot-instructions.md with GitHub Copilot tool mappings"),L.backup)console.log(` Backed up to ${a(L.backup).base}`)}else if(L.error)console.log("⚠️ Failed to update .github/copilot-instructions.md with tool mappings")}else if(N(K)&&!y)console.log("ℹ️ Skipped .github/copilot-instructions.md tool mappings (AGENTS.md exists, using that instead)");else if(!N(K)&&!O.includes("github-copilot"))console.log("ℹ️ Skipped .github/copilot-instructions.md tool mappings (does not exist)");let F=`
|
|
48
42
|
# Setup complete!
|
|
49
43
|
|
|
50
44
|
Your project now has:
|
|
51
45
|
- .agents/ directory structure`;if(j.updated||j.created)F+=`
|
|
52
46
|
- AGENTS.md with universal skills instructions`;if(R.updated||R.created)F+=`
|
|
53
|
-
- CLAUDE.md with Claude Code skills instructions`;if(
|
|
47
|
+
- CLAUDE.md with Claude Code skills instructions`;if(I.updated||I.created)F+=`
|
|
54
48
|
- .github/copilot-instructions.md with Superpowers instructions`;F+=`
|
|
55
49
|
- .agents/skills/ ready for project-specific skills`,F+=`
|
|
56
50
|
- .agents/docs/SUPERPOWERS.md for detailed reference
|
|
57
|
-
`,console.log(F)},uX=()=>{let z=[...["brainstorming.prompt.md","execute-plan.prompt.md","write-plan.prompt.md","setup-skills.prompt.md","create-meta-prompt.md","finding-skills.prompt.md","skills.prompt.md","use-skill.prompt.md","using-a-skill.prompt.md"].map((X)=>M(
|
|
51
|
+
`,console.log(F)},uX=()=>{let z=[...["brainstorming.prompt.md","execute-plan.prompt.md","write-plan.prompt.md","setup-skills.prompt.md","create-meta-prompt.md","finding-skills.prompt.md","skills.prompt.md","use-skill.prompt.md","using-a-skill.prompt.md"].map((X)=>M(_.vscodeUserDir,"prompts",X)),...["brainstorm.md","create-meta-prompt.md","execute-plan.md","finding-skills.md","skills.md","use-skill.md","using-a-skill.md","write-plan.md","setup-skills.md"].map((X)=>M(_.home,".claude","commands",X)),...["brainstorm.md","create-meta-prompt.md","execute-plan.md","finding-skills.md","skills.md","use-skill.md","using-a-skill.md","write-plan.md","setup-skills.md"].map((X)=>M(_.home,".config","opencode","command",X))],Q=0;for(let X of z)if(N(X))try{Cz(X),Q++}catch($){console.log(` ⚠️ Could not remove ${X}: ${$.message}`)}if(Q>0)console.log(`✓ Removed ${Q} legacy prompt/command file${Q!==1?"s":""}`);else console.log("✓ No legacy prompt/command files found")},dX=()=>{let z=0;for(let Q of Hz){let X=Q.skillsDir(),$=M(X,"superpowers");try{if(fX($).isSymbolicLink())Cz($),console.log(`✓ Removed legacy superpowers symlink from ${X.replace(_.home,"~")}`),z++}catch{}}if(z===0)console.log("✓ No legacy superpowers directory symlinks found")},vQ=async()=>{i(),console.log(`# Superpowers Bootstrap for Agents
|
|
58
52
|
# ==================================
|
|
59
|
-
`);let z=process.argv.includes("--no-update"),X=new Set(["copilot","claude","opencode"].filter((
|
|
53
|
+
`);let z=process.argv.includes("--no-update"),X=new Set(["copilot","claude","opencode"].filter((H)=>process.argv.includes(`--force-${H}`))),$=X.size>0;if(!z){let H=zz(),q=await qz();if(q.error)console.log(`## Update Check
|
|
60
54
|
|
|
61
55
|
⚠️ Could not check for updates (network issue)
|
|
62
56
|
|
|
63
57
|
---
|
|
64
58
|
`);else if(q.hasUpdates)console.log(`## Update Available
|
|
65
59
|
`),console.log(`⚠️ Update available: v${q.localVersion} → v${q.remoteVersion}
|
|
66
|
-
To update, run:
|
|
60
|
+
To update, run: \`${wz[Oz()]}\``),console.log(`
|
|
67
61
|
---
|
|
68
|
-
`)}if(!$)
|
|
62
|
+
`)}if(!$)Dz(),console.log(`---
|
|
69
63
|
`);if(!$)console.log(`## Cleaning Up Legacy Files
|
|
70
64
|
`),uX(),console.log(`
|
|
71
65
|
---
|
|
72
66
|
`);if(!$||X.has("copilot")){if(console.log(`## GitHub Copilot Integration
|
|
73
|
-
`),console.log("✓ Skill symlinks handled in sync step below"),p("copilot")||
|
|
67
|
+
`),console.log("✓ Skill symlinks handled in sync step below"),p("copilot")||N(M(_.home,".copilot"))||X.has("copilot")){let q=KQ();if(q.created)console.log(`✓ Installed Copilot sessionStart hook -> ${q.path.replace(_.home,"~")}`);else if(q.updated)console.log(`✓ Updated Copilot sessionStart hook -> ${q.path.replace(_.home,"~")}`);else if(q.existed)console.log("✓ Copilot sessionStart hook already up to date");else if(q.error)console.log(`⚠️ Failed to install Copilot sessionStart hook: ${q.message}`)}else console.log("ℹ️ Skipped Copilot sessionStart hook (Copilot CLI not detected; run with --force-copilot to install anyway)");console.log(`
|
|
74
68
|
---
|
|
75
69
|
`)}if(!$||X.has("claude")){if(console.log(`## Claude Code Integration
|
|
76
70
|
`),!D.claude.check()&&!X.has("claude"))console.log(`⚠️ Skipped (${D.claude.name} CLI not detected)
|
|
77
71
|
\uD83D\uDCA1 To enable Claude Code integration:
|
|
78
72
|
1. Install Claude Code: ${D.claude.installUrl}
|
|
79
|
-
2. Run: superpowers-agent bootstrap --force-claude`);else{console.log("✓ Skill symlinks handled in sync step below");let q=
|
|
73
|
+
2. Run: superpowers-agent bootstrap --force-claude`);else{console.log("✓ Skill symlinks handled in sync step below");let q=EQ();if(q.created)console.log(`✓ Installed SessionStart hook -> ${_.claudeSettings.replace(_.home,"~")}`);else if(q.updated){if(console.log(`✓ ${q.existed?"Refreshed":"Added"} SessionStart hook in ${_.claudeSettings.replace(_.home,"~")}`),q.backup)console.log(` Backed up to ${a(q.backup).base}`)}else if(q.error)console.log(`⚠️ Failed to install SessionStart hook: ${q.message}`)}console.log(`
|
|
80
74
|
---
|
|
81
75
|
`)}if(!$||X.has("opencode")){if(console.log(`## OpenCode Integration
|
|
82
|
-
`),D.opencode.check())
|
|
76
|
+
`),D.opencode.check())BQ();else console.log(`⚠️ Skipped (${D.opencode.name} CLI not detected)
|
|
83
77
|
\uD83D\uDCA1 To enable OpenCode integration:
|
|
84
78
|
1. Install OpenCode: ${D.opencode.installUrl}
|
|
85
79
|
2. Run: superpowers-agent ${D.opencode.bootstrapCommand}`);console.log(`
|
|
86
80
|
---
|
|
87
81
|
`)}if(!$){console.log(`## Generating Platform-Specific Files
|
|
88
|
-
`);let
|
|
89
|
-
`);let q=M(
|
|
90
|
-
`)}if(
|
|
82
|
+
`);let H=$Q();console.log(`Detected platforms: ${H.join(", ")||"none"}
|
|
83
|
+
`);let q=M(_.superpowersRepo,".agents","templates","AGENTS.md.template"),V="";try{V=s(q,"utf8")}catch(W){console.log(`⚠️ Could not read AGENTS.md template: ${W.message}
|
|
84
|
+
`)}if(V){let W=k();V=V.replace(/\{\{VERSION\}\}/g,W);let G=M(_.home,".agents","AGENTS.md"),B=Bz(G,V,H,!0);if(B.created)console.log(`✓ Created ${G}`);else if(B.updated)console.log(`✓ Updated ${G}`)}console.log(`
|
|
91
85
|
---
|
|
92
86
|
`)}console.log(`## Cleaning Up Legacy Superpowers Dir Symlinks
|
|
93
|
-
`),
|
|
87
|
+
`),dX(),console.log(`
|
|
94
88
|
---
|
|
95
89
|
`),console.log(`## Syncing Repo Skills -> ~/.agents/skills/
|
|
96
|
-
`);let Z=
|
|
90
|
+
`);let Z=bz();if(Z.created>0||Z.updated>0)console.log(` ✓ ${Z.created} created, ${Z.updated} updated, ${Z.existed} already current`);else if(Z.errors.length>0)for(let H of Z.errors)console.log(` ⚠️ ${H}`);else console.log(` ✓ ${Z.existed} skill symlinks already up to date`);if(console.log(`
|
|
97
91
|
---
|
|
98
|
-
`),console.log(`##
|
|
99
|
-
`);let
|
|
92
|
+
`),N(M(_.home,".claude"))){console.log(`## Syncing Repo Skills -> ~/.claude/skills/
|
|
93
|
+
`);let H=bz(_.homeClaudeSkills);if(H.created>0||H.updated>0)console.log(` ✓ ${H.created} created, ${H.updated} updated, ${H.existed} already current`);else if(H.errors.length>0)for(let q of H.errors)console.log(` ⚠️ ${q}`);else console.log(` ✓ ${H.existed} skill symlinks already up to date`);console.log(`
|
|
94
|
+
---
|
|
95
|
+
`)}console.log(`## Reconciling Retired Repo-Managed Skill Symlinks
|
|
96
|
+
`);let Y=MQ();if(Y.removed.length>0){console.log(` ✓ Removed ${Y.removed.length} retired skill symlink(s):`);for(let H of Y.removed)console.log(` - ${H}`)}else console.log(" ✓ No retired repo-managed skill symlinks found");console.log(`
|
|
100
97
|
---
|
|
101
98
|
`),console.log(`# Bootstrap Complete!
|
|
102
99
|
`),console.log("✓ All integrations installed"),console.log("✓ Skills system ready"),console.log(`✓ Skill symlinks synced
|
|
103
|
-
`),console.log("Next steps:"),console.log(" - Use your platform's native skill tool to see available skills"),console.log(" - Run `superpowers-agent setup-skills` in your project directory")};import{existsSync as b,readFileSync as Ez,mkdirSync as
|
|
104
|
-
⚠ Could not parse agents.json: ${J.message}`);return}let Z=
|
|
105
|
-
⚠ Invalid agents.json: ${Z.error}`);return}for(let J of Z.skippedPlatforms)console.log(` ⚠ Skipping unknown platform: ${J}`);let Y=$.repository||"unknown",
|
|
106
|
-
\uD83D\uDCE6 Found agents.json (${Y} v${
|
|
107
|
-
${q} ${J} agents:`);for(let U of O){let
|
|
108
|
-
${
|
|
100
|
+
`),console.log("Next steps:"),console.log(" - Use your platform's native skill tool to see available skills"),console.log(" - Run `superpowers-agent setup-skills` in your project directory")};import{existsSync as b,readFileSync as Ez,mkdirSync as sX,rmSync as gz,cpSync as tX,lstatSync as eX}from"fs";import{join as T,dirname as Kz,parse as Xz,sep as zZ}from"path";import{execSync as x}from"child_process";import{homedir as d}from"os";import{createInterface as QZ}from"readline";import{readFileSync as pX,existsSync as fz,unlinkSync as cX,lstatSync as nX,mkdirSync as lX}from"fs";import{join as iX,dirname as aX}from"path";import{join as t}from"path";import{homedir as Rz}from"os";var yz={github:{name:"github",sourceDir:".github/agents",sourceExt:".agent.md",getDestDir:()=>t(_.vscodeUserDir,"prompts"),getExtraDestDirs:()=>[t(Rz(),".copilot","agents")],destExt:".agent.md"},opencode:{name:"opencode",sourceDir:".opencode/agents",sourceExt:".md",getDestDir:()=>t(Rz(),".config","opencode","agents"),destExt:".md"},claude:{name:"claude",sourceDir:".claude/agents",sourceExt:".md",getDestDir:()=>t(Rz(),".claude","agents"),destExt:".md"}};function AQ(z,Q,X){let $=yz[Q];if(!$)return null;return t(z,$.sourceDir,`${X}${$.sourceExt}`)}function FQ(z,Q){let X=yz[z];if(!X)return[];return[X.getDestDir(),...X.getExtraDestDirs?X.getExtraDestDirs():[]].map((Z)=>t(Z,`${Q}${X.destExt}`))}function Sz(){return Object.keys(yz)}function oX(z){if(!z||typeof z!=="object")return{valid:!1,error:"agents.json must be a JSON object"};if(!z.version||typeof z.version!=="string")return{valid:!1,error:'agents.json must have a "version" string field'};if(!z.agents||typeof z.agents!=="object")return{valid:!1,error:'agents.json must have an "agents" object field'};let Q=Sz(),X=[];for(let[$,Z]of Object.entries(z.agents)){if(!Q.includes($)){X.push($);continue}if(!Array.isArray(Z))return{valid:!1,error:`agents.${$} must be an array of agent names`};for(let Y of Z)if(typeof Y!=="string")return{valid:!1,error:`agents.${$} must contain only string agent names`}}return{valid:!0,data:z,skippedPlatforms:X}}function rX(z,Q){if(!fz(z))return{installed:!1,error:`Source file not found: ${z}`};if(fz(Q))try{if(!nX(Q).isSymbolicLink())cX(Q)}catch($){}lX(aX(Q),{recursive:!0});let X=IQ(z,Q);if(X.error)return{installed:!1,error:X.error};return{installed:!0}}function kz(z,Q={}){let X=iX(z,"agents.json");if(!fz(X))return;let $;try{$=JSON.parse(pX(X,"utf8"))}catch(J){console.log(`
|
|
101
|
+
⚠ Could not parse agents.json: ${J.message}`);return}let Z=oX($);if(!Z.valid){console.log(`
|
|
102
|
+
⚠ Invalid agents.json: ${Z.error}`);return}for(let J of Z.skippedPlatforms)console.log(` ⚠ Skipping unknown platform: ${J}`);let Y=$.repository||"unknown",H=$.version,q=Q.isUpdate?"Updating":"Installing",V=Q.isUpdate?"Updated":"Installed";console.log(`
|
|
103
|
+
\uD83D\uDCE6 Found agents.json (${Y} v${H})`);let W=Sz(),G=0,B=0,E=[];for(let[J,O]of Object.entries($.agents)){if(!W.includes(J))continue;console.log(`
|
|
104
|
+
${q} ${J} agents:`);for(let U of O){let v=AQ(z,J,U),C=FQ(J,U),j=[],A=[];for(let R of C){let K=rX(v,R);if(K.installed)j.push(R);else A.push(K.error)}if(j.length>0)console.log(` ✓ ${U}`),E.push({platformKey:J,agentName:U,sourcePath:v,destPaths:j}),G++;else console.log(` ✗ ${U}: ${A.join("; ")}`),B++}}if(E.length>0){let J=S(!0);if(!J.installedAgents)J.installedAgents={};if(!J.installedAgents[Y])J.installedAgents[Y]={version:H,agents:{}};J.installedAgents[Y].version=H;for(let{platformKey:O,agentName:U,sourcePath:v,destPaths:C}of E){if(!J.installedAgents[Y].agents[O])J.installedAgents[Y].agents[O]={};J.installedAgents[Y].agents[O][U]={source:v,destination:C[0],destinations:C,installedAt:new Date().toISOString()}}m(J,!0)}if(G>0)console.log(`
|
|
105
|
+
${V} ${G} agent(s)${B>0?` (${B} failed)`:""}`)}var bQ=(z,Q)=>{if(Q.type==="local"){let $=z;for(let Z=0;Z<10;Z++){if(b(T($,"agents.json")))return $;let Y=Kz($);if(Y===$)break;$=Y}return z}let X=T(".agents","tmp");if(z.includes(X)){let $=z.indexOf(X),Y=z.substring($+X.length+1).split(zZ)[0];return T(z.substring(0,$),".agents","tmp",Y)}return z},CQ=(z,Q)=>{let X=T(d(),".agents","repos"),$=Q.replace(/^@/,"").replace(/[^a-zA-Z0-9_-]/g,"_"),Z=T(X,$);try{if(sX(X,{recursive:!0}),b(Z))gz(Z,{recursive:!0,force:!0});return tX(z,Z,{recursive:!0}),Z}catch(Y){return console.log(` Warning: Could not persist repository for agents: ${Y.message}`),null}},mz=(z)=>{let Q=z.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)$/);if(Q){let[,Z,Y,H,q]=Q;return{type:"git-tree",repoUrl:`https://github.com/${Z}/${Y}.git`,branch:H,path:q,original:z}}let X=z.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/);if(X){let[,Z,Y]=X;return{type:"git-repo",repoUrl:`git@github.com:${Z}/${Y}.git`,branch:null,path:null,original:z}}let $=z.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?$/);if($){let[,Z,Y]=$;return{type:"git-repo",repoUrl:`https://github.com/${Z}/${Y}.git`,branch:null,path:null,original:z}}if(b(z))return{type:"local",path:z,original:z};return null},hz=(z)=>{let Q=z.includes("--global")||z.includes("-g"),X=z.includes("--project")||z.includes("-p");if(Q)return T(d(),".agents","skills");if(X)return T(process.cwd(),".agents","skills");let $=T(process.cwd(),".agents","config.json"),Z=T(d(),".agents","config.json");for(let Y of[$,Z])if(b(Y))try{if(JSON.parse(Ez(Y,"utf8")).installLocation==="project")return T(process.cwd(),".agents","skills")}catch(H){}return T(d(),".agents","skills")},uz=(z,Q)=>{let X=T(d(),".agents","tmp",`skill-install-${Date.now()}`);try{if(x(`mkdir -p "${X}"`,{stdio:"pipe"}),Q)x(`git clone --branch ${Q} --depth 1 "${z}" "${X}"`,{stdio:"pipe",timeout:30000});else x(`git clone --depth 1 "${z}" "${X}"`,{stdio:"pipe",timeout:30000});return X}catch($){try{x(`rm -rf "${X}"`,{stdio:"pipe"})}catch{}throw Error(`Failed to clone repository: ${$.message}`)}},e=(z)=>{let Q=T(z,"skill.json");if(!b(Q))return null;try{let X=Ez(Q,"utf8");return JSON.parse(X)}catch(X){throw Error(`Failed to read skill.json: ${X.message}`)}},Vz=(z,Q,X,$)=>{let Z=T(z,Q);if(!b(Z)){$.errors.push(`Skill directory not found: ${Q}`);return}let Y=e(Z);if(!Y){$.errors.push(`No skill.json found in: ${Q}`);return}let H=Y.name||Q,q=H.split("/").pop()||H,V=T(X,q),W=Kz(V);try{x(`mkdir -p "${W}"`,{stdio:"pipe"})}catch(G){$.errors.push(`Failed to create directory ${W}: ${G.message}`);return}try{if(b(V))x(`rm -rf "${V}"`,{stdio:"pipe"});x(`cp -R "${Z}" "${V}"`,{stdio:"pipe"}),$.installed.push({name:q,path:V,title:Y.title||Y.description||q})}catch(G){$.errors.push(`Failed to install ${Q}: ${G.message}`)}},jQ=(z,Q,X,$,Z=null)=>{let Y=S($);if(!Y.installedSkills)Y.installedSkills={};let H={source:z,installBase:Q,installedAt:new Date().toISOString(),skills:X.installed.map((q)=>({name:q.name,path:q.path}))};if(Y.installedSkills[z]=H,Z&&Z!==z)Y.installedSkills[Z]=H;m(Y,$)},xQ=()=>{let z=process.argv.slice(3),Q=z.find((B)=>!B.startsWith("-")),X=z.filter((B)=>B.startsWith("-"));if(!Q){console.log(`Usage: superpowers-agent add <url-or-path|@alias> [skill-path] [options]
|
|
109
106
|
|
|
110
107
|
Options:
|
|
111
108
|
--global, -g Install skills globally in ~/.agents/skills/ (default)
|
|
@@ -127,18 +124,18 @@ Description:
|
|
|
127
124
|
|
|
128
125
|
Repository aliases can be added using:
|
|
129
126
|
superpowers-agent add-repository <git-url> [--as=@alias]`);return}console.log(`Installing skill(s)...
|
|
130
|
-
`);let $=!X.includes("--project")&&!X.includes("-p"),Z=null,Y=null,
|
|
127
|
+
`);let $=!X.includes("--project")&&!X.includes("-p"),Z=null,Y=null,H=null;if(Q.startsWith("@")){let B=Q;H=B,Y=z.find((U,v)=>v>0&&!U.startsWith("-")&&U!==B);let E=P(!1),J=P(!0);if(E[B])Z=E[B],console.log(`Using project repository alias: ${B}`);else if(J[B])Z=J[B],console.log(`Using global repository alias: ${B}`);else{console.log(`Error: Repository alias not found: ${B}`),console.log(`
|
|
131
128
|
Available aliases:`);let U={...J,...E};if(Object.keys(U).length===0)console.log(" (none)"),console.log(`
|
|
132
|
-
Add a repository using:`),console.log(" superpowers-agent add-repository <git-url>");else for(let[
|
|
129
|
+
Add a repository using:`),console.log(" superpowers-agent add-repository <git-url>");else for(let[v,C]of Object.entries(U))console.log(` ${v} -> ${C}`);return}let O=b(Z);if(Y)if(O)Q=T(Z,Y),console.log(`Repository path: ${Z}`),console.log(`Skill path: ${Y}
|
|
133
130
|
`);else Q=Z,console.log(`Repository URL: ${Z}`),console.log(`Skill path: ${Y}
|
|
134
131
|
`);else if(Q=Z,O)console.log(`Repository path: ${Z}
|
|
135
132
|
`);else console.log(`Repository URL: ${Z}
|
|
136
|
-
`)}let q=
|
|
137
|
-
`);let W,G=!1;try{if(q.type==="git-repo"||q.type==="git-tree"){if(console.log(`Cloning repository: ${q.repoUrl}`),q.branch)console.log(`Branch: ${q.branch}`);if(W=
|
|
138
|
-
`);for(let U of
|
|
133
|
+
`)}let q=mz(Q);if(!q){console.log(`Error: Invalid URL or path not found: ${Q}`);return}if(Y&&q.type==="git-repo"&&!q.path)q.path=Y;let V=hz(X);console.log(`Install location: ${V}
|
|
134
|
+
`);let W,G=!1;try{if(q.type==="git-repo"||q.type==="git-tree"){if(console.log(`Cloning repository: ${q.repoUrl}`),q.branch)console.log(`Branch: ${q.branch}`);if(W=uz(q.repoUrl,q.branch),G=!0,q.path){if(W=T(W,q.path),!b(W))throw Error(`Path not found in repository: ${q.path}`)}console.log("")}else W=q.path;let B=e(W);if(!B)throw Error("No skill.json found in source directory");let E={installed:[],errors:[],source:q.original};if(B.skills&&Array.isArray(B.skills)){console.log(`Found ${B.skills.length} skill(s) to install
|
|
135
|
+
`);for(let U of B.skills)Vz(W,U,V,E)}else{let U=B.name||Xz(W).base;Vz(Kz(W),Xz(W).base,V,E)}let J=bQ(W,q),O=T(J,"agents.json");if(b(O)){let U=J;if(G){let v;try{v=JSON.parse(Ez(O,"utf8"))}catch{}let C=v?.repository||q.original,j=CQ(J,C);if(j)U=j}kz(U,{isUpdate:!1})}if(G&&W)try{let U=W.split("/.agents/tmp/")[0]+"/.agents/tmp/"+W.split("/.agents/tmp/")[1].split("/")[0];x(`rm -rf "${U}"`,{stdio:"pipe"})}catch{}if(console.log(`
|
|
139
136
|
**Successfully installed skills:**`),console.log(`- Source: ${E.source}`),E.installed.length>0)for(let U of E.installed)console.log(` - Installed: ${U.name} at ${U.path}`),console.log(` ${U.title}`);if(E.errors.length>0){console.log(`
|
|
140
|
-
**Errors:**`);for(let U of E.errors)console.log(` - ${U}`)}if(E.installed.length===0&&E.errors.length===0)console.log(" No skills were installed");if(E.installed.length>0)
|
|
141
|
-
Error: ${
|
|
137
|
+
**Errors:**`);for(let U of E.errors)console.log(` - ${U}`)}if(E.installed.length===0&&E.errors.length===0)console.log(" No skills were installed");if(E.installed.length>0)jQ(q.original,V,E,$,H)}catch(B){if(G&&W)try{let E=W.split("/.agents/tmp/")[0]+"/.agents/tmp/"+W.split("/.agents/tmp/")[1].split("/")[0];x(`rm -rf "${E}"`,{stdio:"pipe"})}catch{}console.log(`
|
|
138
|
+
Error: ${B.message}`)}},DQ=()=>{let z=process.argv.slice(3),Q=z.find((B)=>!B.startsWith("-")),X=z.filter((B)=>B.startsWith("-"));if(!Q){console.log(`Usage: superpowers-agent pull <url-or-path|@alias> [skill-path] [options]
|
|
142
139
|
|
|
143
140
|
Options:
|
|
144
141
|
--global, -g Update skills globally in ~/.agents/skills/ (default)
|
|
@@ -163,18 +160,18 @@ Description:
|
|
|
163
160
|
|
|
164
161
|
Repository aliases can be added using:
|
|
165
162
|
superpowers-agent add-repository <git-url> [--as=@alias]`);return}console.log(`Updating skill(s)...
|
|
166
|
-
`);let $=!X.includes("--project")&&!X.includes("-p"),Z=null,Y=null,
|
|
163
|
+
`);let $=!X.includes("--project")&&!X.includes("-p"),Z=null,Y=null,H=null;if(Q.startsWith("@")){let B=Q;H=B,Y=z.find((U,v)=>v>0&&!U.startsWith("-")&&U!==B);let E=P(!1),J=P(!0);if(E[B])Z=E[B],console.log(`Using project repository alias: ${B}`);else if(J[B])Z=J[B],console.log(`Using global repository alias: ${B}`);else{console.log(`Error: Repository alias not found: ${B}`),console.log(`
|
|
167
164
|
Available aliases:`);let U={...J,...E};if(Object.keys(U).length===0)console.log(" (none)"),console.log(`
|
|
168
|
-
Add a repository using:`),console.log(" superpowers-agent add-repository <git-url>");else for(let[
|
|
165
|
+
Add a repository using:`),console.log(" superpowers-agent add-repository <git-url>");else for(let[v,C]of Object.entries(U))console.log(` ${v} -> ${C}`);return}let O=b(Z);if(Y)if(O)Q=T(Z,Y),console.log(`Repository path: ${Z}`),console.log(`Skill path: ${Y}
|
|
169
166
|
`);else Q=Z,console.log(`Repository URL: ${Z}`),console.log(`Skill path: ${Y}
|
|
170
167
|
`);else if(Q=Z,O)console.log(`Repository path: ${Z}
|
|
171
168
|
`);else console.log(`Repository URL: ${Z}
|
|
172
|
-
`)}let q=
|
|
173
|
-
`);let W,G=!1;try{if(q.type==="git-repo"||q.type==="git-tree"){if(console.log(`Cloning repository: ${q.repoUrl}`),q.branch)console.log(`Branch: ${q.branch}`);if(W=
|
|
174
|
-
`);for(let U of
|
|
169
|
+
`)}let q=mz(Q);if(!q){console.log(`Error: Invalid URL or path not found: ${Q}`);return}if(Y&&q.type==="git-repo"&&!q.path)q.path=Y;let V=hz(X);console.log(`Install location: ${V}
|
|
170
|
+
`);let W,G=!1;try{if(q.type==="git-repo"||q.type==="git-tree"){if(console.log(`Cloning repository: ${q.repoUrl}`),q.branch)console.log(`Branch: ${q.branch}`);if(W=uz(q.repoUrl,q.branch),G=!0,q.path){if(W=T(W,q.path),!b(W))throw Error(`Path not found in repository: ${q.path}`)}console.log("")}else W=q.path;let B=e(W);if(!B)throw Error("No skill.json found in source directory");let E={installed:[],errors:[],source:q.original};if(B.skills&&Array.isArray(B.skills)){console.log(`Found ${B.skills.length} skill(s) to update
|
|
171
|
+
`);for(let U of B.skills)Vz(W,U,V,E)}else{let U=B.name||Xz(W).base;Vz(Kz(W),Xz(W).base,V,E)}let J=bQ(W,q),O=T(J,"agents.json");if(b(O)){let U=J;if(G){let v;try{v=JSON.parse(Ez(O,"utf8"))}catch{}let C=v?.repository||q.original,j=CQ(J,C);if(j)U=j}kz(U,{isUpdate:!0})}if(G&&W)try{let U=W.split("/.agents/tmp/")[0]+"/.agents/tmp/"+W.split("/.agents/tmp/")[1].split("/")[0];x(`rm -rf "${U}"`,{stdio:"pipe"})}catch{}if(console.log(`
|
|
175
172
|
**Successfully updated skills:**`),console.log(`- Source: ${E.source}`),E.installed.length>0)for(let U of E.installed)console.log(` - Updated: ${U.name} at ${U.path}`),console.log(` ${U.title}`);if(E.errors.length>0){console.log(`
|
|
176
|
-
**Errors:**`);for(let U of E.errors)console.log(` - ${U}`)}if(E.installed.length===0&&E.errors.length===0)console.log(" No skills were updated");if(E.installed.length>0)
|
|
177
|
-
Error: ${
|
|
173
|
+
**Errors:**`);for(let U of E.errors)console.log(` - ${U}`)}if(E.installed.length===0&&E.errors.length===0)console.log(" No skills were updated");if(E.installed.length>0)jQ(q.original,V,E,$,H)}catch(B){if(G&&W)try{let E=W.split("/.agents/tmp/")[0]+"/.agents/tmp/"+W.split("/.agents/tmp/")[1].split("/")[0];x(`rm -rf "${E}"`,{stdio:"pipe"})}catch{}console.log(`
|
|
174
|
+
Error: ${B.message}`)}},XZ=(z)=>new Promise((Q)=>{let X=QZ({input:process.stdin,output:process.stdout});X.question(z,($)=>{X.close(),Q($.trim())})}),Pz=(z)=>{try{return eX(z).isSymbolicLink()}catch{return!1}},RQ=async()=>{let z=process.argv.slice(3),Q=z.find((K)=>!K.startsWith("-")),X=z.filter((K)=>K.startsWith("-"));if(!Q){console.log(`Usage: superpowers-agent rm <url-or-path|@alias> [options]
|
|
178
175
|
|
|
179
176
|
Options:
|
|
180
177
|
--global, -g Remove globally installed skills (default)
|
|
@@ -183,10 +180,10 @@ Options:
|
|
|
183
180
|
Examples:
|
|
184
181
|
superpowers-agent rm https://github.com/example/skills
|
|
185
182
|
superpowers-agent rm @myrepo
|
|
186
|
-
superpowers-agent rm ~/my-local-skills`);return}let $=!X.includes("--project")&&!X.includes("-p"),Z=Q,Y=null;if(Q.startsWith("@")){Y=Q;let K=P(!1),
|
|
187
|
-
`);let K=
|
|
188
|
-
Proceed? [y/N] `)).toLowerCase()!=="y"){console.log("Aborted.");return}for(let K of
|
|
189
|
-
Done.`)},
|
|
183
|
+
superpowers-agent rm ~/my-local-skills`);return}let $=!X.includes("--project")&&!X.includes("-p"),Z=Q,Y=null;if(Q.startsWith("@")){Y=Q;let K=P(!1),I=P(!0);if(K[Q])Z=K[Q];else if(I[Q])Z=I[Q];else{console.log(`Error: Repository alias not found: ${Q}`);return}}let H=rz($),q=H[Q]||H[Z],V=q?.installBase||hz(X),W=[];if(q)W=q.skills;else{console.log(`No tracking data found. Attempting to re-resolve skills from source...
|
|
184
|
+
`);let K=mz(Z);if(!K){console.log(`Error: Invalid URL or path not found: ${Z}`);return}let I,y=!1;try{if(K.type==="git-repo"||K.type==="git-tree"){if(console.log(`Cloning repository: ${K.repoUrl}`),I=uz(K.repoUrl,K.branch),y=!0,K.path){if(I=T(I,K.path),!b(I))throw Error(`Path not found in repository: ${K.path}`)}}else I=K.path;let F=e(I);if(!F)throw Error("No skill.json found in source");let L=F.skills&&Array.isArray(F.skills)?F.skills:[F.name||Xz(I).base];for(let o of L){let Gz=o;if(F.skills){let dz=T(I,o);if(b(dz)){let pz=e(dz);if(pz?.name)Gz=pz.name}}W.push({name:Gz,path:T(V,Gz)})}if(y)try{let o=I.split("/.agents/tmp/")[0]+"/.agents/tmp/"+I.split("/.agents/tmp/")[1].split("/")[0];x(`rm -rf "${o}"`,{stdio:"pipe"})}catch{}}catch(F){if(y&&I)try{let L=I.split("/.agents/tmp/")[0]+"/.agents/tmp/"+I.split("/.agents/tmp/")[1].split("/")[0];x(`rm -rf "${L}"`,{stdio:"pipe"})}catch{}console.log(`Error resolving source: ${F.message}`);return}}let G=W.filter((K)=>b(K.path)||Pz(K.path)),B=[];for(let K of W)for(let I of Hz){let y=T(I.skillsDir(),K.name);if(b(y)||Pz(y))B.push({platform:I.name,path:y})}let E=sz(),J=Y||Z,O=[];if(E[J])for(let[,K]of Object.entries(E[J].agents||{}))for(let[,I]of Object.entries(K)){let y=I.destinations||(I.destination?[I.destination]:[]);for(let F of y)if(F&&(b(F)||Pz(F)))O.push({path:F})}let U=J.replace(/^@/,"").replace(/[^a-zA-Z0-9_-]/g,"_"),v=T(d(),".agents","repos",U),C=b(v),j=d(),A=(K)=>K.replace(j,"~");if(G.length===0&&B.length===0&&O.length===0&&!C){console.log("Nothing to remove.");return}if(console.log("Will remove:"),G.length>0){console.log(" Skills:");for(let K of G)console.log(` ${A(K.path)}`)}if(B.length>0){console.log(" Platform symlinks:");for(let K of B)console.log(` ${A(K.path)}`)}if(O.length>0){console.log(" Agents:");for(let K of O)console.log(` ${A(K.path)}`)}if(C)console.log(" Persisted repo:"),console.log(` ${A(v)}`);if((await XZ(`
|
|
185
|
+
Proceed? [y/N] `)).toLowerCase()!=="y"){console.log("Aborted.");return}for(let K of B){let I=Fz(K.path);if(I.removed)console.log(`Removed symlink: ${A(K.path)}`),LQ(K.platform,K.path,"skills");else if(I.error==="Symlink does not exist")console.log(`Already removed: ${A(K.path)}`);else console.log(`Warning: ${A(K.path)}: ${I.error}`)}for(let K of O){let I=Fz(K.path);if(I.removed)console.log(`Removed agent: ${A(K.path)}`);else if(I.error==="Symlink does not exist")console.log(`Already removed: ${A(K.path)}`);else console.log(`Warning: ${A(K.path)}: ${I.error}`)}if(C)try{gz(v,{recursive:!0,force:!0}),console.log(`Removed persisted repo: ${A(v)}`)}catch(K){console.log(`Warning: Failed to remove persisted repo: ${K.message}`)}for(let K of G){if(!b(K.path)){console.log(`Already removed: ${A(K.path)}`);continue}try{gz(K.path,{recursive:!0,force:!0}),console.log(`Removed skill: ${A(K.path)}`)}catch(I){console.log(`Warning: Failed to remove ${A(K.path)}: ${I.message}`)}}if(_z(Q,$),Z!==Q)_z(Z,$);if(E[J]){let K=S(!0);if(K.installedAgents)delete K.installedAgents[J],m(K,!0)}console.log(`
|
|
186
|
+
Done.`)},yQ=()=>{let z=process.argv.slice(3),Q=z.find((W)=>!W.startsWith("-")),X=z.filter((W)=>W.startsWith("-"));if(!Q){console.log(`Usage: superpowers-agent add-repository <git-url> [options]
|
|
190
187
|
|
|
191
188
|
Options:
|
|
192
189
|
--global, -g Add repository globally in ~/.agents/config.json (default)
|
|
@@ -204,17 +201,17 @@ Description:
|
|
|
204
201
|
The repository's skill.json will be read to determine the default alias.
|
|
205
202
|
Use --as to specify a custom alias.
|
|
206
203
|
After adding, you can install skills using: superpowers-agent add @alias path/to/skill`);return}console.log(`Adding repository...
|
|
207
|
-
`);let $=X.some((W)=>W==="--global"||W==="-g"),Z=X.some((W)=>W==="--project"||W==="-p"),Y=X.find((W)=>W.startsWith("--as=")),
|
|
208
|
-
You can now install skills using:`),console.log(` superpowers-agent add ${G} <path-to-skill>`)}catch(W){if(
|
|
209
|
-
Error: ${W.message}`)}};var
|
|
204
|
+
`);let $=X.some((W)=>W==="--global"||W==="-g"),Z=X.some((W)=>W==="--project"||W==="-p"),Y=X.find((W)=>W.startsWith("--as=")),H=Y?Y.split("=")[1]:null,q=Z?!1:!0,V;try{console.log(`Cloning repository: ${Q}`),V=T(d(),".agents","tmp",`repo-add-${Date.now()}`),x(`mkdir -p "${V}"`,{stdio:"pipe"}),x(`git clone --depth 1 "${Q}" "${V}"`,{stdio:"pipe",timeout:30000}),console.log("");let W=e(V);if(!W)throw Error("No skill.json found in repository");let G;if(H)G=H;else if(W.repository)G=W.repository;else{let J=Q.match(/\/([^/]+?)(?:\.git)?$/);if(J)G="@"+J[1];else throw Error("Could not determine repository alias. Use --as=@alias to specify manually.")}oz(G,Q,q),x(`rm -rf "${V}"`,{stdio:"pipe"});let B=q?"globally":"in project",E=q?T(d(),".agents","config.json"):T(process.cwd(),".agents","config.json");console.log(`✓ Repository added ${B}`),console.log(` Alias: ${G}`),console.log(` URL: ${Q}`),console.log(` Config: ${E}`),console.log(`
|
|
205
|
+
You can now install skills using:`),console.log(` superpowers-agent add ${G} <path-to-skill>`)}catch(W){if(V)try{x(`rm -rf "${V}"`,{stdio:"pipe"})}catch{}console.log(`
|
|
206
|
+
Error: ${W.message}`)}};var ZZ=()=>`<EXTREMELY_IMPORTANT>
|
|
210
207
|
${"---\n\n**YOU MUST read and use the `leveraging-cli-tools` skill** the moment a task involves using BASH, searching code, parsing JSON/YAML, finding files, structural refactors, data wrangling, or any command that floods your context with verbose output (logs, CI logs, test runs). Load it with your skill tool BEFORE you reach for grep/find/sed or before you read large command output. It routes you to high-performance tools (rg, jq, fd, yq, ast-grep, gh, sd) and reduces output to just the signal — cutting token cost and latency 5-50x. Skipping it wastes tokens and time on work the right tool does instantly."}
|
|
211
|
-
</EXTREMELY_IMPORTANT
|
|
212
|
-
`)};var
|
|
208
|
+
</EXTREMELY_IMPORTANT>`,$Z=(z="raw")=>{let Q=ZZ();if(z==="claude")return JSON.stringify({hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:Q}});if(z==="copilot")return JSON.stringify({additionalContext:Q});return Q},SQ=()=>{let z=process.argv.find((X)=>X.startsWith("--format=")),Q=z?z.split("=")[1]:"raw";process.stdout.write($Z(Q)+`
|
|
209
|
+
`)};var fQ={bootstrap:vQ,version:ZQ,"check-updates":()=>{XQ().catch((z)=>{console.error(z.message),process.exit(1)})},update:()=>{Tz().catch((z)=>{console.error(z.message),process.exit(1)})},"config-get":ez,"config-set":zQ,"setup-skills":NQ,"session-context":SQ,add:xQ,"add-repository":yQ,"list-repositories":QQ,pull:DQ,rm:RQ,"install-aliases":Dz,default:()=>{console.log(`Superpowers for Agents
|
|
213
210
|
Usage:
|
|
214
211
|
superpowers-agent bootstrap [--no-update] [--force] # Run complete bootstrap
|
|
215
212
|
superpowers-agent version # Show current version
|
|
216
213
|
superpowers-agent check-updates # Check for updates
|
|
217
|
-
superpowers-agent update
|
|
214
|
+
superpowers-agent update # Show how to update to the latest version
|
|
218
215
|
superpowers-agent config-get # Show configuration
|
|
219
216
|
superpowers-agent config-set <key> <value> # Update configuration
|
|
220
217
|
superpowers-agent setup-skills # Initialize project skills
|
|
@@ -227,4 +224,4 @@ Usage:
|
|
|
227
224
|
superpowers-agent install-aliases # Install universal aliases (superpowers, superpowers-agent)
|
|
228
225
|
|
|
229
226
|
Documentation: https://github.com/complexthings/superpowers
|
|
230
|
-
`)}}
|
|
227
|
+
`)}},YZ=process.argv[2]||"default",qZ=fQ[YZ]||fQ.default;try{let z=qZ();if(z&&typeof z.then==="function")z.catch((Q)=>{console.error(`Error: ${Q.message}`),process.exit(1)})}catch(z){console.error(`Error: ${z.message}`),process.exit(1)}
|
|
@@ -6,37 +6,5 @@ You have superpowers. Superpowers teach you new skills and capabilities.
|
|
|
6
6
|
**Tool for running skills:**
|
|
7
7
|
- Use your platform's native skill tool, or read the skill's `SKILL.md` directly.
|
|
8
8
|
|
|
9
|
-
**Platform-specific tool mappings:**
|
|
10
|
-
Tool mappings for your detected platforms are automatically included in your platform-specific configuration files:
|
|
11
|
-
- GitHub Copilot: `~/.github/copilot-instructions.md`
|
|
12
|
-
- Cursor: Included in `AGENTS.md`
|
|
13
|
-
- Claude Code: `~/.claude/CLAUDE.md`
|
|
14
|
-
- Gemini: `~/.gemini/GEMINI.md`
|
|
15
|
-
- OpenCode: `~/.config/opencode/AGENTS.md`
|
|
16
|
-
- Codex: `~/.codex/AGENTS.md`
|
|
17
|
-
|
|
18
|
-
**Skills naming:**
|
|
19
|
-
- Project skills: `skill-name` (from .agents/skills/ - highest priority)
|
|
20
|
-
- Claude skills: `claude:skill-name` (from .claude/skills/)
|
|
21
|
-
- Personal skills: `skill-name` (from ~/.agents/skills/)
|
|
22
|
-
- Superpowers skills: `superpowers:skill-name` (from ~/.agents/superpowers/skills/)
|
|
23
|
-
|
|
24
|
-
**Skills priority:**
|
|
25
|
-
Project skills override Claude skills, which override personal skills, which override superpowers skills when names match.
|
|
26
|
-
|
|
27
|
-
**Critical Rules:**
|
|
28
|
-
- Before ANY task, review the skills list (shown at bootstrap)
|
|
29
|
-
- If a relevant skill exists, you MUST load it with your platform's native skill tool and follow its instructions.
|
|
30
|
-
- YOU MUST USE YOUR `Read` TOOL TO READ THE SKILL FILE. YOU MUST NOT `cat` or print it to yourself.
|
|
31
|
-
- Announce: "I've read the [Skill Name] skill and I'm using it to [purpose]"
|
|
32
|
-
- Skills with checklists require `manage_todo_list` todos for each item (or manual tracking if unavailable)
|
|
33
|
-
- NEVER skip mandatory workflows (brainstorming before coding, TDD, systematic debugging)
|
|
34
|
-
|
|
35
|
-
**Skills location:**
|
|
36
|
-
- Project skills: .agents/skills/ (project-specific, highest priority)
|
|
37
|
-
- Claude skills: .claude/skills/ (project's existing skill system)
|
|
38
|
-
- Personal skills: ~/.agents/skills/ (your personal cross-project skills)
|
|
39
|
-
- Superpowers skills: ~/.agents/superpowers/skills/ (shared community skills)
|
|
40
|
-
|
|
41
9
|
IF A SKILL APPLIES TO YOUR TASK, YOU DO NOT HAVE A CHOICE. YOU MUST USE IT.
|
|
42
10
|
</EXTREMELY_IMPORTANT>
|
|
@@ -20,7 +20,7 @@ Once per day, check for updates:
|
|
|
20
20
|
> Your superpowers-agent has updates (`CURRENT_VERSION` → `NPM_LATEST_VERSION`). Run:
|
|
21
21
|
> ```sh
|
|
22
22
|
> npm install -g @complexthings/superpowers-agent
|
|
23
|
-
> superpowers-agent
|
|
23
|
+
> superpowers-agent bootstrap && superpowers-agent setup-skills
|
|
24
24
|
> ```
|
|
25
25
|
Match, or a lookup fails → stay silent.
|
|
26
26
|
|
|
@@ -21,7 +21,7 @@ Once per day, check for updates:
|
|
|
21
21
|
> Your superpowers-agent has updates (`CURRENT_VERSION` → `NPM_LATEST_VERSION`). Run:
|
|
22
22
|
> ```sh
|
|
23
23
|
> npm install -g @complexthings/superpowers-agent
|
|
24
|
-
> superpowers-agent
|
|
24
|
+
> superpowers-agent bootstrap && superpowers-agent setup-skills
|
|
25
25
|
> ```
|
|
26
26
|
Match, or a lookup fails → stay silent.
|
|
27
27
|
|
package/AGENTS.md
CHANGED
|
@@ -44,7 +44,7 @@ Periodically, e.g. once per day check the version of superpowers-agent:
|
|
|
44
44
|
> Your superpowers-agent has updates (`CURRENT_VERSION` → `NPM_LATEST_VERSION`). Run:
|
|
45
45
|
> ```sh
|
|
46
46
|
> npm install -g @complexthings/superpowers-agent
|
|
47
|
-
> superpowers-agent
|
|
47
|
+
> superpowers-agent bootstrap && superpowers-agent setup-skills
|
|
48
48
|
> ```
|
|
49
49
|
If versions match, or either lookup fails (e.g. no network), continue silently.
|
|
50
50
|
|
package/README.md
CHANGED
|
@@ -6,6 +6,13 @@ A comprehensive skills library of proven techniques, patterns, and workflows for
|
|
|
6
6
|
|
|
7
7
|
## What's New
|
|
8
8
|
|
|
9
|
+
**v10.0.2 (July 12, 2026):**
|
|
10
|
+
|
|
11
|
+
- **Claude Code skill discovery fixed** — `bootstrap` now mirrors the repo's skills into `~/.claude/skills` (Claude ignores `~/.agents/skills`), gated on `~/.claude` existing, so Claude Code actually finds the bundled skills.
|
|
12
|
+
- **`update` is now print-only and package-manager–aware** — it no longer runs a global install for you. It detects how the CLI was installed (npm/pnpm/yarn/bun/deno) and prints the exact command plus `bootstrap && setup-skills`.
|
|
13
|
+
- **Retired-skill cleanup extended to `~/.claude/skills`** — the stale-skill cleaner prunes retired skills there too, proving ownership per-link so your own skills are untouched.
|
|
14
|
+
- **Node.js versions refreshed** — Node 20 (EOL) dropped, Node 26 added. Supported engines are now `^22 || ^24 || ^26`.
|
|
15
|
+
|
|
9
16
|
**v10.0.0 (July 12, 2026):**
|
|
10
17
|
|
|
11
18
|
- ⚠️ **Leaner bundled surface** — most bundled skills were retired. The package now ships only four: `brainstorming`, `leveraging-cli-tools`, `create-skill-json`, and `setup-skills`. Install anything else with `superpowers-agent add`.
|
|
@@ -260,14 +267,15 @@ superpowers-agent pull @my-agents
|
|
|
260
267
|
|
|
261
268
|
### Skill Storage
|
|
262
269
|
|
|
263
|
-
|
|
270
|
+
Skills live in a small set of canonical locations and the supported agents discover them there directly:
|
|
264
271
|
|
|
265
272
|
- **Global skills** — bundled Superpowers skills in `~/.agents/superpowers/skills/` and personal skills in `~/.agents/skills/`
|
|
266
273
|
- **Project skills** — `.agents/skills/` inside a project (created/managed by `setup-skills`)
|
|
274
|
+
- **Claude Code mirror** — because Claude Code ignores `~/.agents/skills`, `bootstrap` also mirrors the repo's skills into `~/.claude/skills` (only when `~/.claude` exists) so Claude can find them.
|
|
267
275
|
|
|
268
276
|
**Stale symlink cleanup:**
|
|
269
277
|
|
|
270
|
-
A one-time, `skill.json`-gated cleaner runs during `superpowers-agent bootstrap`. It scrubs deprecated per-platform skill symlink directories left behind by older versions — including legacy Cursor, Codex, and Gemini directories —
|
|
278
|
+
A one-time, `skill.json`-gated cleaner runs during `superpowers-agent bootstrap`. It scrubs deprecated per-platform skill symlink directories left behind by older versions — including legacy Cursor, Codex, and Gemini directories — and reconciles `~/.claude/skills` so retired skills are pruned there too. Ownership is proved per-link from the raw target, so agent personas in `~/.claude/agents/` and your own skills are never touched.
|
|
271
279
|
|
|
272
280
|
## Skill Priority
|
|
273
281
|
|
|
@@ -495,21 +503,22 @@ Supported flags: `--force-copilot`, `--force-claude`, `--force-opencode`
|
|
|
495
503
|
|
|
496
504
|
### Manual Updates
|
|
497
505
|
|
|
498
|
-
|
|
506
|
+
Check for updates anytime with the dedicated update command:
|
|
499
507
|
|
|
500
508
|
```bash
|
|
501
509
|
superpowers-agent update
|
|
502
510
|
```
|
|
503
511
|
|
|
504
|
-
This command:
|
|
505
|
-
-
|
|
506
|
-
- Detects
|
|
507
|
-
-
|
|
508
|
-
|
|
512
|
+
This command is **print-only** — it never runs a global install for you (that can need sudo/permissions and should be your explicit call). It:
|
|
513
|
+
- Checks the npm registry for a newer version
|
|
514
|
+
- Detects how the CLI was installed (npm/pnpm/yarn/bun/deno) from its install path
|
|
515
|
+
- Prints the exact install command for your package manager, followed by `superpowers-agent bootstrap && superpowers-agent setup-skills`
|
|
516
|
+
|
|
517
|
+
For example, with an npm install it prints:
|
|
509
518
|
|
|
510
|
-
**Update without reinstalling integrations:**
|
|
511
519
|
```bash
|
|
512
|
-
|
|
520
|
+
npm install -g @complexthings/superpowers-agent
|
|
521
|
+
superpowers-agent bootstrap && superpowers-agent setup-skills
|
|
513
522
|
```
|
|
514
523
|
|
|
515
524
|
### Configuration
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@complexthings/superpowers-agent",
|
|
3
|
-
"version": "10.0.
|
|
3
|
+
"version": "10.0.2",
|
|
4
4
|
"description": "Superpowers agent CLI — skills system for AI coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"LICENSE"
|
|
23
23
|
],
|
|
24
24
|
"engines": {
|
|
25
|
-
"node": "^
|
|
25
|
+
"node": "^22 || ^24 || ^26"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {},
|
|
28
28
|
"author": {
|