@complexthings/superpowers-agent 9.1.0 → 9.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/docs/SUPERPOWERS.md +18 -23
- package/.agents/superpowers-agent +57 -57
- package/.agents/templates/AGENTS.md.template +29 -39
- package/.agents/templates/SUPERPOWERS.md.template +18 -23
- package/package.json +1 -1
- package/skills/meta/using-superpowers/SKILL.md +36 -50
- package/.agents/templates/TOOLS.md.template +0 -15
|
@@ -1,42 +1,37 @@
|
|
|
1
1
|
# SUPERPOWERS Reference Guide
|
|
2
2
|
|
|
3
|
-
You are an autonomous agent with access to the `superpowers-agent` system.
|
|
3
|
+
You are an autonomous agent with access to the `superpowers-agent` system.
|
|
4
4
|
|
|
5
|
-
>
|
|
6
|
-
> Load this file only when you need specific information not covered in AGENTS.md.
|
|
7
|
-
|
|
8
|
-
**Bootstrapped Version:** `^^SAV:7.1.2^^`
|
|
5
|
+
> Loaded at conversation start. `AGENTS.md` is the primary reference; this guide is the detailed supplement.
|
|
9
6
|
|
|
10
7
|
---
|
|
11
8
|
|
|
12
9
|
## Installation
|
|
13
10
|
|
|
14
|
-
If `superpowers-agent` is not available, install it:
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
npm install -g @complexthings/superpowers-agent
|
|
18
|
-
```
|
|
11
|
+
If `superpowers-agent` is not available, install it: `npm install -g @complexthings/superpowers-agent`
|
|
19
12
|
|
|
20
13
|
---
|
|
21
14
|
|
|
22
15
|
## Version Check
|
|
23
16
|
|
|
24
|
-
|
|
25
|
-
1.
|
|
26
|
-
2.
|
|
27
|
-
3. If
|
|
28
|
-
Your superpowers-agent
|
|
29
|
-
```sh
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
Periodically, e.g. once per day check the version of superpowers-agent:
|
|
18
|
+
1. **CURRENT_VERSION** — run a `superpowers-agent version` command and extract `X.Y.Z` from the `X.Y.Z` string in its output.
|
|
19
|
+
2. **NPM_LATEST_VERSION** — run `npm view @complexthings/superpowers-agent version`.
|
|
20
|
+
3. Compare by **semver precedence, not string comparison** (e.g. `9.10.0` > `9.9.0`). If NPM_LATEST_VERSION is newer, tell the user — do not run these yourself:
|
|
21
|
+
> Your superpowers-agent has updates (`CURRENT_VERSION` → `NPM_LATEST_VERSION`). Run:
|
|
22
|
+
> ```sh
|
|
23
|
+
> npm install -g @complexthings/superpowers-agent
|
|
24
|
+
> superpowers-agent update && superpowers-agent bootstrap && superpowers-agent setup-skills
|
|
25
|
+
> ```
|
|
26
|
+
If versions match, or either lookup fails (e.g. no network), continue silently.
|
|
32
27
|
|
|
33
28
|
---
|
|
34
29
|
|
|
35
30
|
## Skill Loading Rules
|
|
36
31
|
|
|
37
|
-
- Load skills **JIT only** — never preload to "understand" them
|
|
38
|
-
- Follow skill instructions **exactly as written** — no skimming, no shortcuts
|
|
39
|
-
- If a skill has a checklist, create a todo for **each item** — no mental tracking
|
|
40
|
-
- Simple tasks benefit from skills as much as complex ones
|
|
32
|
+
- Load skills **JIT only** — never preload to "understand" them.
|
|
33
|
+
- Follow skill instructions **exactly as written** — no skimming, no shortcuts.
|
|
34
|
+
- If a skill has a checklist, create a todo for **each item** — no mental tracking.
|
|
35
|
+
- Simple tasks benefit from skills as much as complex ones.
|
|
41
36
|
|
|
42
|
-
**Skill priority (highest to lowest):** Project → Personal → Superpowers
|
|
37
|
+
**Skill priority (highest to lowest):** Project → Personal → Superpowers
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
// 2>/dev/null; exec "$(command -v bun 2>/dev/null || echo node)" "$0" "$@"
|
|
3
|
-
import{relative as _Q,dirname as GQ,join as TX}from"path";import{existsSync as D$}from"fs";import{homedir as r$,platform as WX}from"os";import{join as
|
|
3
|
+
import{relative as _Q,dirname as GQ,join as TX}from"path";import{existsSync as D$}from"fs";import{homedir as r$,platform as WX}from"os";import{join as w,parse as zX,dirname as s$}from"path";import{existsSync as d}from"fs";import{fileURLToPath as HX}from"url";var EX=HX(import.meta.url),K$=s$(EX),KX=()=>{let $=r$();switch(WX()){case"darwin":return w($,"Library","Application Support","Code","User");case"win32":return w($,"AppData","Roaming","Code","User");case"linux":return w($,".config","Code","User");default:return w($,".config","Code","User")}},BX=()=>{let $=process.cwd(),Q=zX($).root;while($!==Q){if(d(w($,".agents")))return $;$=s$($)}return process.cwd()},H={home:r$(),vscodeUserDir:KX(),projectRoot:BX(),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 $=w(K$,"..","..","..");if(d(w($,"skills"))&&d(w($,".agents","superpowers-agent")))return $;let Q=w(K$,"..");if(d(w(Q,"skills"))&&d(w(Q,".agents","superpowers-agent")))return Q;return w(this.home,".agents","superpowers")},get homeSuperpowersSkills(){return w(this.superpowersRepo,"skills")},get isSuperpowersRepo(){let $=w(K$,"..","..","..");if(d(w($,"skills"))&&d(w($,".agents","superpowers-agent")))return!0;let Q=w(K$,"..");return d(w(Q,"skills"))&&d(w(Q,".agents","superpowers-agent"))}};import{readFileSync as t$}from"fs";var X$=($)=>{try{let X=t$($,"utf8").split(`
|
|
4
4
|
`),Z={name:"",description:"",whenToUse:""},Y=!1;for(let q of X){if(q.trim()==="---"){if(Y)break;Y=!0;continue}if(Y){let z=q.match(/^(\w+):\s*(.*)$/);if(z){let[,W,K]=z,E={name:"name",description:"description",when_to_use:"whenToUse"};if(E[W])Z[E[W]]=K.trim()}}}return Z}catch{return{name:"",description:"",whenToUse:""}}},M$=($)=>{try{let Q=t$($,"utf8"),X=X$($),Z=Q.split(`
|
|
5
5
|
`),Y=!1,q=!1,z=[];for(let W of Z){if(W.trim()==="---"){if(Y){q=!0;continue}Y=!0;continue}if(q||!Y)z.push(W)}return{content:z.join(`
|
|
6
|
-
`).trim(),frontmatter:X}}catch(Q){throw Error(`Error reading skill file: ${Q.message}`)}};import{existsSync as T$,readdirSync as QQ,statSync as XQ}from"fs";import{join as v$,relative as
|
|
6
|
+
`).trim(),frontmatter:X}}catch(Q){throw Error(`Error reading skill file: ${Q.message}`)}};import{existsSync as T$,readdirSync as QQ,statSync as XQ}from"fs";import{join as v$,relative as lY}from"path";import{readFileSync as _X,existsSync as GX}from"fs";import{join as e$}from"path";var Y$=($)=>{let Q=e$($,"skill.json");if(!GX(Q))return null;try{let X=_X(Q,"utf8");return JSON.parse(X)}catch(X){return null}};var A$=($)=>{if($.startsWith("superpowers:"))return{type:"superpowers",path:$.substring(12).replace(/^skills\//,"")};if($.startsWith("claude:"))return{type:"claude",path:$.substring(7).replace(/^skills\//,"")};if($.startsWith("copilot:"))return{type:"copilot",path:$.substring(8).replace(/^skills\//,"")};if($.startsWith("opencode:"))return{type:"opencode",path:$.substring(9).replace(/^skills\//,"")};return{type:null,path:$.replace(/^skills\//,"")}},$Q=($,Q)=>{let X=Y$($);if(!X||!X.helpers||!Array.isArray(X.helpers))return null;let Z=X.helpers,Y=Q.toLowerCase(),q=null,z=0;for(let W of Z){let K=W.toLowerCase();if(K===Y){q=W;break}if(K.includes(Y)){let B=Y.length/K.length;if(B>z)z=B,q=W}let E=W.split("/").pop().split(".")[0].toLowerCase();if(Y.includes(E)){let B=E.length/Y.length;if(B>z)z=B,q=W}}return q?e$($,q):null},r={project:{dir:"projectAgentsSkills",prefix:""},claude:{dir:"projectClaudeSkills",prefix:"claude:"},copilot:{dir:"projectCopilotSkills",prefix:"copilot:"},opencode:{dir:"projectOpencodeSkills",prefix:"opencode:"},personal:{dir:"homePersonalSkills",prefix:""},personalClaude:{dir:"homeClaudeSkills",prefix:"claude:"},personalCopilot:{dir:"homeCopilotSkills",prefix:"copilot:"},personalOpencode:{dir:"homeOpencodeSkills",prefix:"opencode:"},superpowers:{dir:"homeSuperpowersSkills",prefix:"superpowers:"}};var B$=($,Q,X=null)=>{let Z=[];if(!T$($))return Z;let Y=(q,z)=>{if(X!==null&&z>X)return;try{let W=QQ(q,{withFileTypes:!0});for(let K of W){if(K.name==="node_modules"||K.name===".git"||K.name.startsWith("."))continue;let E=v$(q,K.name),B=K.isDirectory();if(K.isSymbolicLink())try{B=XQ(E).isDirectory()}catch{continue}if(!B)continue;let _=v$(E,"SKILL.md");if(T$(_))Z.push(E);if(X===null||z<X)Y(E,z+1)}}catch{}};return Y($,0),Z};var YQ=($,Q)=>{if(!T$($))return[];let X=[],Z=Q.toLowerCase().replace(/\\/g,"/"),Y=(q,z="")=>{try{let W=QQ(q,{withFileTypes:!0});for(let K of W){let E=v$(q,K.name),B=z?`${z}/${K.name}`:K.name,_=K.isDirectory();if(K.isSymbolicLink())try{_=XQ(E).isDirectory()}catch{continue}if(_&&(K.name==="node_modules"||K.name===".git"||K.name.startsWith(".")))continue;if(_)Y(E,B);else if(K.name==="SKILL.md"){let G=z.toLowerCase().replace(/\\/g,"/");if(G===Z||G.endsWith("/"+Z)||G.endsWith(Z))X.push({file:E,path:z})}}}catch(W){}};return Y($),X},ZQ=($,Q,X)=>{let Z={project:"project skills (.agents/skills/)",claude:"claude skills (.claude/skills/)",copilot:"copilot skills (.copilot/skills/)",opencode:"opencode skills (.opencode/skill/)",personal:"personal skills (~/.agents/skills/)",personalClaude:"personal claude skills (~/.claude/skills/)",personalCopilot:"personal copilot skills (~/.copilot/skills/)",personalOpencode:"personal opencode skills (~/.config/opencode/skill/)",superpowers:"superpowers skills (~/.agents/superpowers/skills/)"}[X];console.log(`Error: Multiple skills match "${$}" in ${Z}:
|
|
7
7
|
`);for(let Y of Q){let z=r[X].prefix+Y.path;try{let W=X$(Y.file),K=W.description||W.whenToUse||"(no description)";console.log(` ${z}`),console.log(` ${K}
|
|
8
8
|
`)}catch(W){console.log(` ${z}`),console.log(` (unable to read description)
|
|
9
|
-
`)}}console.log("Please be more specific. Examples:");for(let Y of Q.slice(0,2)){let q=r[X].prefix;console.log(` superpowers-agent execute ${q}${Y.path}`)}};import{existsSync as N$}from"fs";import{join as VX,relative as LX}from"path";var UX=($)=>{let{type:Q,path:X}=A$($),Z={superpowers:[H.homeSuperpowersSkills],claude:[H.projectClaudeSkills,H.homeClaudeSkills],copilot:[H.projectCopilotSkills,H.homeCopilotSkills],opencode:[H.projectOpencodeSkills,H.homeOpencodeSkills],project:[H.projectAgentsSkills],personal:[H.homePersonalSkills]},Y;if(Q)Y=(Z[Q]||[]).map((z)=>({type:Q,dir:z}));else if(H.isSuperpowersRepo&&N$(H.projectSkillsDir))Y=[{type:"project",dir:H.projectSkillsDir},{type:"project",dir:H.projectAgentsSkills},{type:"claude",dir:H.projectClaudeSkills},{type:"copilot",dir:H.projectCopilotSkills},{type:"opencode",dir:H.projectOpencodeSkills},{type:"personal",dir:H.homePersonalSkills},{type:"personalClaude",dir:H.homeClaudeSkills},{type:"personalCopilot",dir:H.homeCopilotSkills},{type:"personalOpencode",dir:H.homeOpencodeSkills},{type:"superpowers",dir:H.homeSuperpowersSkills}];else Y=[{type:"project",dir:H.projectAgentsSkills},{type:"claude",dir:H.projectClaudeSkills},{type:"copilot",dir:H.projectCopilotSkills},{type:"opencode",dir:H.projectOpencodeSkills},{type:"personal",dir:H.homePersonalSkills},{type:"personalClaude",dir:H.homeClaudeSkills},{type:"personalCopilot",dir:H.homeCopilotSkills},{type:"personalOpencode",dir:H.homeOpencodeSkills},{type:"superpowers",dir:H.homeSuperpowersSkills}];for(let{type:q,dir:z}of Y){let W=YQ(z,X);if(W.length===1)return{skillFile:W[0].file,sourceType:q,actualSkillPath:W[0].path};if(W.length>1)ZQ(X,W,q)}return null},m=($)=>{let Q=UX($);if(Q)return Q;let{type:X,path:Z}=A$($),Y={superpowers:[H.homeSuperpowersSkills],claude:[H.projectClaudeSkills,H.homeClaudeSkills],copilot:[H.projectCopilotSkills,H.homeCopilotSkills],opencode:[H.projectOpencodeSkills,H.homeOpencodeSkills],project:[H.projectAgentsSkills],personal:[H.homePersonalSkills]},q;if(X)q=(Y[X]||[]).map((W)=>({type:X,dir:W}));else if(H.isSuperpowersRepo&&N$(H.projectSkillsDir))q=[{type:"project",dir:H.projectSkillsDir},{type:"project",dir:H.projectAgentsSkills},{type:"claude",dir:H.projectClaudeSkills},{type:"copilot",dir:H.projectCopilotSkills},{type:"opencode",dir:H.projectOpencodeSkills},{type:"personal",dir:H.homePersonalSkills},{type:"personalClaude",dir:H.homeClaudeSkills},{type:"personalCopilot",dir:H.homeCopilotSkills},{type:"personalOpencode",dir:H.homeOpencodeSkills},{type:"superpowers",dir:H.homeSuperpowersSkills}];else q=[{type:"project",dir:H.projectAgentsSkills},{type:"claude",dir:H.projectClaudeSkills},{type:"copilot",dir:H.projectCopilotSkills},{type:"opencode",dir:H.projectOpencodeSkills},{type:"personal",dir:H.homePersonalSkills},{type:"personalClaude",dir:H.homeClaudeSkills},{type:"personalCopilot",dir:H.homeCopilotSkills},{type:"personalOpencode",dir:H.homeOpencodeSkills},{type:"superpowers",dir:H.homeSuperpowersSkills}];for(let{type:z,dir:W}of q){if(!N$(W))continue;let K=B$(W,z,null);for(let E of K){let
|
|
9
|
+
`)}}console.log("Please be more specific. Examples:");for(let Y of Q.slice(0,2)){let q=r[X].prefix;console.log(` superpowers-agent execute ${q}${Y.path}`)}};import{existsSync as N$}from"fs";import{join as VX,relative as LX}from"path";var UX=($)=>{let{type:Q,path:X}=A$($),Z={superpowers:[H.homeSuperpowersSkills],claude:[H.projectClaudeSkills,H.homeClaudeSkills],copilot:[H.projectCopilotSkills,H.homeCopilotSkills],opencode:[H.projectOpencodeSkills,H.homeOpencodeSkills],project:[H.projectAgentsSkills],personal:[H.homePersonalSkills]},Y;if(Q)Y=(Z[Q]||[]).map((z)=>({type:Q,dir:z}));else if(H.isSuperpowersRepo&&N$(H.projectSkillsDir))Y=[{type:"project",dir:H.projectSkillsDir},{type:"project",dir:H.projectAgentsSkills},{type:"claude",dir:H.projectClaudeSkills},{type:"copilot",dir:H.projectCopilotSkills},{type:"opencode",dir:H.projectOpencodeSkills},{type:"personal",dir:H.homePersonalSkills},{type:"personalClaude",dir:H.homeClaudeSkills},{type:"personalCopilot",dir:H.homeCopilotSkills},{type:"personalOpencode",dir:H.homeOpencodeSkills},{type:"superpowers",dir:H.homeSuperpowersSkills}];else Y=[{type:"project",dir:H.projectAgentsSkills},{type:"claude",dir:H.projectClaudeSkills},{type:"copilot",dir:H.projectCopilotSkills},{type:"opencode",dir:H.projectOpencodeSkills},{type:"personal",dir:H.homePersonalSkills},{type:"personalClaude",dir:H.homeClaudeSkills},{type:"personalCopilot",dir:H.homeCopilotSkills},{type:"personalOpencode",dir:H.homeOpencodeSkills},{type:"superpowers",dir:H.homeSuperpowersSkills}];for(let{type:q,dir:z}of Y){let W=YQ(z,X);if(W.length===1)return{skillFile:W[0].file,sourceType:q,actualSkillPath:W[0].path};if(W.length>1)ZQ(X,W,q)}return null},m=($)=>{let Q=UX($);if(Q)return Q;let{type:X,path:Z}=A$($),Y={superpowers:[H.homeSuperpowersSkills],claude:[H.projectClaudeSkills,H.homeClaudeSkills],copilot:[H.projectCopilotSkills,H.homeCopilotSkills],opencode:[H.projectOpencodeSkills,H.homeOpencodeSkills],project:[H.projectAgentsSkills],personal:[H.homePersonalSkills]},q;if(X)q=(Y[X]||[]).map((W)=>({type:X,dir:W}));else if(H.isSuperpowersRepo&&N$(H.projectSkillsDir))q=[{type:"project",dir:H.projectSkillsDir},{type:"project",dir:H.projectAgentsSkills},{type:"claude",dir:H.projectClaudeSkills},{type:"copilot",dir:H.projectCopilotSkills},{type:"opencode",dir:H.projectOpencodeSkills},{type:"personal",dir:H.homePersonalSkills},{type:"personalClaude",dir:H.homeClaudeSkills},{type:"personalCopilot",dir:H.homeCopilotSkills},{type:"personalOpencode",dir:H.homeOpencodeSkills},{type:"superpowers",dir:H.homeSuperpowersSkills}];else q=[{type:"project",dir:H.projectAgentsSkills},{type:"claude",dir:H.projectClaudeSkills},{type:"copilot",dir:H.projectCopilotSkills},{type:"opencode",dir:H.projectOpencodeSkills},{type:"personal",dir:H.homePersonalSkills},{type:"personalClaude",dir:H.homeClaudeSkills},{type:"personalCopilot",dir:H.homeCopilotSkills},{type:"personalOpencode",dir:H.homeOpencodeSkills},{type:"superpowers",dir:H.homeSuperpowersSkills}];for(let{type:z,dir:W}of q){if(!N$(W))continue;let K=B$(W,z,null);for(let E of K){let B=Y$(E);if(B&&B.aliases&&Array.isArray(B.aliases)){let _=Z.toLowerCase();for(let G of B.aliases)if(G.toLowerCase()===_){let V=VX(E,"SKILL.md"),I=LX(W,E);return{skillFile:V,sourceType:z,actualSkillPath:I}}}}}return null};import{readFileSync as qQ,writeFileSync as WQ,existsSync as C$}from"fs";import{join as i}from"path";import{execSync as IX}from"child_process";var b$=()=>({auto_update:!0,last_update_check:null,last_updated_commit:null}),Z$=()=>{let $=i(H.superpowersRepo,".config.json");try{if(!C$($))return b$();let Q=qQ($,"utf8");return{...b$(),...JSON.parse(Q)}}catch{return b$()}},zQ=($)=>{let Q=i(H.superpowersRepo,".config.json"),Z={...Z$(),...$};try{WQ(Q,JSON.stringify(Z,null,2))}catch(Y){console.log(`Warning: couldn't save config: ${Y.message}`)}},y=($)=>{let Q=$?i(H.home,".agents","config.json"):i(process.cwd(),".agents","config.json");if(!C$(Q))return{};try{let X=qQ(Q,"utf8");return JSON.parse(X)}catch(X){return{}}},h=($,Q)=>{let X=Q?i(H.home,".agents"):i(process.cwd(),".agents"),Z=i(X,"config.json");try{if(!C$(X))IX(`mkdir -p "${X}"`,{stdio:"pipe"});return WQ(Z,JSON.stringify($,null,2),"utf8"),!0}catch(Y){throw Error(`Failed to write config: ${Y.message}`)}},k=($=!1)=>{return y($).repositories||{}},HQ=($,Q,X)=>{let Z=y(X);if(!Z.repositories)Z.repositories={};Z.repositories[$]=Q,h(Z,X)};function EQ($=!0){return y($).installedSkills||{}}function F$($,Q=!0){let X=y(Q);if(X.installedSkills)delete X.installedSkills[$];h(X,Q)}function KQ(){return y(!0).installedAgents||{}}import{readFileSync as JX}from"fs";import{join as j$,dirname as OX}from"path";import{fileURLToPath as wX}from"url";import{existsSync as BQ}from"fs";import{execSync as MX}from"child_process";var AX=wX(import.meta.url),x$=OX(AX),P=()=>{try{let $=j$(x$,"package.json");if(!BQ($))$=j$(x$,"..","package.json");if(!BQ($))$=j$(x$,"..","..","package.json");return JSON.parse(JX($,"utf8")).version||"0.0.0"}catch{return"0.0.0"}},u=()=>{let $=P();console.log(`^^SAV:${$}^^`)},_$=async()=>{try{let Q=MX('curl -sS "https://registry.npmjs.org/@complexthings/superpowers-agent/latest"',{encoding:"utf8",timeout:1e4}),X=JSON.parse(Q);if(!X.version)return P();return X.version}catch($){throw Error(`Failed to fetch remote version: ${$.message}`)}},G$=($,Q)=>{let X=$.split(".").map(Number),Z=Q.split(".").map(Number);for(let Y=0;Y<3;Y++){let q=X[Y]||0,z=Z[Y]||0;if(q>z)return!0;if(q<z)return!1}return!1};var vX={project:{dir:"projectAgentsSkills",prefix:""},claude:{dir:"projectClaudeSkills",prefix:"claude:"},copilot:{dir:"projectCopilotSkills",prefix:"copilot:"},opencode:{dir:"projectOpencodeSkills",prefix:"opencode:"},personal:{dir:"homePersonalSkills",prefix:""},personalClaude:{dir:"homeClaudeSkills",prefix:"claude:"},personalCopilot:{dir:"homeCopilotSkills",prefix:"copilot:"},personalOpencode:{dir:"homeOpencodeSkills",prefix:"opencode:"},superpowers:{dir:"homeSuperpowersSkills",prefix:"superpowers:"}},NX=($,Q)=>{let X=TX($,"SKILL.md"),{dir:Z,prefix:Y}=vX[Q],q=_Q(H[Z],$).replace(/\\/g,"/");console.log(`${Y}${q}`);let{description:z,whenToUse:W}=X$(X);if(z)console.log(` ${z}`);if(W)console.log(` When to use: ${W}`);console.log("")},s=()=>{u();let $=new Set,Q=[{type:"project",dir:H.projectAgentsSkills,maxDepth:null},{type:"claude",dir:H.projectClaudeSkills,maxDepth:null},{type:"copilot",dir:H.projectCopilotSkills,maxDepth:null},{type:"opencode",dir:H.projectOpencodeSkills,maxDepth:null},{type:"personal",dir:H.homePersonalSkills,maxDepth:null},{type:"personalClaude",dir:H.homeClaudeSkills,maxDepth:null},{type:"personalCopilot",dir:H.homeCopilotSkills,maxDepth:null},{type:"personalOpencode",dir:H.homeOpencodeSkills,maxDepth:null},{type:"superpowers",dir:H.homeSuperpowersSkills,maxDepth:null}];for(let{type:X,dir:Z,maxDepth:Y}of Q){let q=B$(Z,X,Y);for(let z of q){let W=_Q(Z,z);if(!$.has(W))$.add(W),NX(z,X)}}console.log(`Usage:
|
|
10
10
|
superpowers-agent execute <skill-name> # Load a specific skill`)},VQ=()=>{u();let $=process.argv[3];if(!$){console.log(`Usage: superpowers-agent execute <skill-name-or-alias>
|
|
11
11
|
|
|
12
12
|
Examples:
|
|
@@ -100,29 +100,29 @@ Total: ${X.length} repository alias(es)`)};var V$=async()=>{try{let $=P(),Q=awai
|
|
|
100
100
|
Running bootstrap to complete setup...
|
|
101
101
|
`);try{MQ("superpowers-agent bootstrap --no-update",{stdio:"inherit"}),console.log(`
|
|
102
102
|
✓ Bootstrap complete!`)}catch(X){console.log(`
|
|
103
|
-
⚠️ Bootstrap step failed: ${X.message}`),console.log(" The update installed successfully. Run manually to finish setup:"),console.log(" superpowers-agent bootstrap")}},AQ=async()=>{u();let $=P();console.log(`Current version: ${$}`);try{let Q=await _$();if(console.log(`Latest version: ${Q}`),G$(Q,$))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)}},TQ=()=>{let $=P();console.log($)};import{existsSync as A,readFileSync as
|
|
104
|
-
`,"utf8")}catch(
|
|
105
|
-
`;if(P$(Q)){let Y;try{Y=mX(Q,"utf8")}catch(q){return{error:!0,message:`Failed to read ${Q}: ${q.message}`}}if(Y===X)return{existed:!0,path:Q}}if(!P$($))try{pX($,{recursive:!0})}catch(Y){return{error:!0,message:`Failed to create ${$}: ${Y.message}`}}let Z=P$(Q);try{hX(Q,X,"utf8")}catch(Y){return{error:!0,message:`Failed to write ${Q}: ${Y.message}`}}return Z?{updated:!0,path:Q}:{created:!0,path:Q}};import{existsSync as
|
|
106
|
-
${
|
|
107
|
-
<!-- SUPERPOWERS_SKILLS_END -->`;if(Y){let
|
|
108
|
-
`,
|
|
109
|
-
`+
|
|
110
|
-
`+B.slice(
|
|
111
|
-
|
|
112
|
-
`+B}try{return $$($,
|
|
113
|
-
|
|
114
|
-
`+
|
|
103
|
+
⚠️ Bootstrap step failed: ${X.message}`),console.log(" The update installed successfully. Run manually to finish setup:"),console.log(" superpowers-agent bootstrap")}},AQ=async()=>{u();let $=P();console.log(`Current version: ${$}`);try{let Q=await _$();if(console.log(`Latest version: ${Q}`),G$(Q,$))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)}},TQ=()=>{let $=P();console.log($)};import{existsSync as A,readFileSync as a,writeFileSync as $$,rmSync as mQ,lstatSync as EY}from"fs";import{join as v,dirname as hQ,parse as e}from"path";import{execSync as R}from"child_process";import{platform as KY}from"os";import{execSync as bX}from"child_process";var q$=($)=>{try{return bX(`which ${$}`,{stdio:"pipe",timeout:2000}),!0}catch{return!1}};var D={opencode:{check:()=>q$("opencode"),cli:!0,name:"OpenCode",installUrl:"https://opencode.ai/docs/installation",bootstrapCommand:"install-opencode-commands"},claude:{check:()=>q$("claude"),cli:!0,name:"Claude Code",installUrl:"https://code.claude.com/docs/en/installation",bootstrapCommand:"install-claude-commands"},copilot:{check:()=>!0,cli:!1,name:"GitHub Copilot",bootstrapCommand:"install-copilot-prompts"}},vQ=()=>{let $=[];if(D.copilot.check())$.push("github-copilot");if(D.claude.check())$.push("claude-code");if(D.opencode.check())$.push("opencode");return $};import{existsSync as f$,readdirSync as gZ,lstatSync as CX,symlinkSync as NQ,unlinkSync as FX,mkdirSync as jX,readlinkSync as xX}from"fs";import{join as y$,dirname as uZ}from"path";import{platform as DX}from"os";var S$=($)=>{try{return CX($).isSymbolicLink()}catch{return!1}},RX=($,Q)=>{try{if(!S$($))return!1;return xX($)===Q}catch{return!1}},bQ=()=>{let $=y$(H.superpowersRepo,".opencode","plugins","superpowers-agent.js"),Q=y$(H.home,".config","opencode","plugins"),X=y$(Q,"superpowers-agent.js");if(console.log("Installing OpenCode plugin symlink..."),!f$($))return console.log("⚠️ Source plugin not found, skipping symlink creation"),console.log(` Expected at: ${$}`),{created:!1,error:"Source plugin not found"};if(RX(X,$))return console.log("✓ Plugin symlink already exists and is correct"),{created:!1,existed:!0};if(f$(X)&&!S$(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(!f$(Q))try{jX(Q,{recursive:!0}),console.log(`✓ Created ${Q.replace(H.home,"~")}`)}catch(Y){return console.log(`⚠️ Failed to create plugins directory: ${Y.message}`),{created:!1,error:`Failed to create directory: ${Y.message}`}}if(S$(X))try{FX(X)}catch(Y){return console.log(`⚠️ Failed to remove existing symlink: ${Y.message}`),{created:!1,error:`Failed to remove existing symlink: ${Y.message}`}}let Z=DX();try{if(Z==="win32")NQ($,X,"file");else NQ($,X);let Y=$.replace(H.home,"~"),q=X.replace(H.home,"~");return console.log(`✓ Created symlink: ${q}`),console.log(` -> ${Y}`),{created:!0}}catch(Y){if(Z==="win32"&&Y.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: ${Y.message}`),{created:!1,error:`Failed to create symlink: ${Y.message}`}}};import{existsSync as CQ,readdirSync as cZ,readFileSync as fX,writeFileSync as yX,mkdirSync as SX,copyFileSync as PX}from"fs";import{join as oZ,dirname as gX}from"path";var kX="superpowers-agent session-context",uX="superpowers-agent session-context --format=claude 2>/dev/null || true",dX="startup|resume|clear|compact",FQ=($=H.claudeSettings)=>{let Q={},X=!1,Z;if(CQ($)){X=!0;let B;try{B=fX($,"utf8")}catch(G){return{error:!0,message:`Failed to read settings.json: ${G.message}`}}try{Q=B.trim()?JSON.parse(B):{}}catch(G){return{error:!0,message:`settings.json is not valid JSON, leaving it untouched: ${G.message}`}}let _=new Date().toISOString().split("T")[0];Z=`${$}.backup-${_}`;try{PX($,Z)}catch(G){return{error:!0,message:`Failed to back up settings.json: ${G.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 Y=Array.isArray(Q.hooks.SessionStart)?Q.hooks.SessionStart:[],q=(B)=>{try{return JSON.stringify(B).includes(kX)}catch{return!1}},z=Y.some(q),W=Y.filter((B)=>!q(B)),K={matcher:dX,hooks:[{type:"command",command:uX}]};Q.hooks.SessionStart=[...W,K];let E=gX($);if(!CQ(E))try{SX(E,{recursive:!0})}catch(B){return{error:!0,message:`Failed to create ${E}: ${B.message}`}}try{yX($,JSON.stringify(Q,null,2)+`
|
|
104
|
+
`,"utf8")}catch(B){return{error:!0,message:`Failed to write settings.json: ${B.message}`}}if(!X)return{created:!0};if(z)return{existed:!0,updated:!0,backup:Z};return{updated:!0,backup:Z}};import{existsSync as P$,readdirSync as rZ,readFileSync as mX,writeFileSync as hX,mkdirSync as pX}from"fs";import{join as cX}from"path";var nX="superpowers.json",oX=()=>({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}]}}),jQ=($=H.copilotHooksDir)=>{let Q=cX($,nX),X=JSON.stringify(oX(),null,2)+`
|
|
105
|
+
`;if(P$(Q)){let Y;try{Y=mX(Q,"utf8")}catch(q){return{error:!0,message:`Failed to read ${Q}: ${q.message}`}}if(Y===X)return{existed:!0,path:Q}}if(!P$($))try{pX($,{recursive:!0})}catch(Y){return{error:!0,message:`Failed to create ${$}: ${Y.message}`}}let Z=P$(Q);try{hX(Q,X,"utf8")}catch(Y){return{error:!0,message:`Failed to write ${Q}: ${Y.message}`}}return Z?{updated:!0,path:Q}:{created:!0,path:Q}};import{existsSync as l,readdirSync as iX,lstatSync as lX,symlinkSync as L$,unlinkSync as g$,mkdirSync as xQ,readlinkSync as aX}from"fs";import{join as n,dirname as rX,basename as sX}from"path";import{homedir as o,platform as DQ}from"os";var U$=[{name:"claude",parentDir:()=>n(o(),".claude"),skillsDir:()=>n(o(),".claude","skills")},{name:"copilot",parentDir:()=>n(o(),".copilot"),skillsDir:()=>n(o(),".copilot","skills")},{name:"opencode",parentDir:()=>n(o(),".config","opencode"),skillsDir:()=>n(o(),".config","opencode","skill")}],t=($)=>{try{return lX($).isSymbolicLink()}catch{return!1}},RQ=($,Q)=>{try{if(!t($))return!1;return aX($)===Q}catch{return!1}},fQ=($,Q)=>{if(!l($))return{created:!1,existed:!1,error:`Source does not exist: ${$}`};if(RQ(Q,$))return{created:!1,existed:!0};if(l(Q)||t(Q))if(t(Q))try{g$(Q)}catch(Y){return{created:!1,existed:!1,error:`Failed to remove existing symlink: ${Y.message}`}}else return{created:!1,existed:!1,error:`Target exists and is not a symlink: ${Q}`};let X=rX(Q);if(!l(X))try{xQ(X,{recursive:!0})}catch(Y){return{created:!1,existed:!1,error:`Failed to create parent directory: ${Y.message}`}}let Z=DQ();try{if(Z==="win32")L$($,Q,"junction");else L$($,Q,"dir");return{created:!0,existed:!1}}catch(Y){if(Z==="win32"&&Y.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: ${Y.message}`}}},k$=($)=>{if(!l($)&&!t($))return{removed:!1,error:"Symlink does not exist"};if(!t($))return{removed:!1,error:"Target is not a symlink"};try{return g$($),{removed:!0}}catch(Q){return{removed:!1,error:`Failed to remove symlink: ${Q.message}`}}};var yQ=($,Q,X="skills")=>{let Z=y(!0);if(!Z.symlinks||!Z.symlinks[$])return;if(X==="superpowers")Z.symlinks[$].superpowers=null;else{let Y=Z.symlinks[$].skills||[];Z.symlinks[$].skills=Y.filter((q)=>q!==Q)}h(Z,!0)};var SQ=($,Q=[])=>{let X;try{X=iX($,{withFileTypes:!0})}catch{return Q}let Z=!1,Y=[];for(let q of X){if(!q.isDirectory()&&q.name==="SKILL.md")Z=!0;if(q.isDirectory()&&!q.name.startsWith("."))Y.push(n($,q.name))}if(Z)Q.push($);for(let q of Y)SQ(q,Q);return Q},PQ=()=>{let $=H.homeSuperpowersSkills,Q=H.homePersonalSkills;if(!l($))return{created:0,existed:0,updated:0,errors:[`Skills directory not found: ${$}`]};if(!l(Q))try{xQ(Q,{recursive:!0})}catch(Y){return{created:0,existed:0,updated:0,errors:[`Failed to create ${Q}: ${Y.message}`]}}let X=SQ($),Z={created:0,existed:0,updated:0,errors:[]};for(let Y of X){let q=sX(Y),z=n(Q,q);if(RQ(z,Y)){Z.existed++;continue}if(t(z))try{g$(z),Z.updated++}catch(K){Z.errors.push(`Failed to remove stale symlink ${z}: ${K.message}`);continue}else if(l(z)){Z.errors.push(`Skipped ${z}: path exists and is not a symlink`);continue}let W=DQ();try{if(W==="win32")L$(Y,z,"junction");else L$(Y,z,"dir");let K=z.replace(o(),"~"),E=Y.replace(o(),"~");console.log(` ✓ ${K} -> ${E}`),Z.created++}catch(K){Z.errors.push(`Failed to create symlink ${z}: ${K.message}`)}}return Z};import{existsSync as gQ,readdirSync as tX,lstatSync as eX,unlinkSync as $Y,realpathSync as kQ}from"fs";import{join as x}from"path";import{homedir as uQ}from"os";var QY=($)=>{try{return kQ($)}catch{return $}},XY=($)=>{try{return eX($).isSymbolicLink()}catch{return!1}},YY=($)=>{try{return kQ($)}catch{return null}},ZY=($,Q)=>{let X=Q.endsWith("/")?Q:Q+"/";return $.startsWith(X)||$===Q},qY=($,Q)=>Q.some((X)=>ZY($,X)),WY=($)=>{try{return gQ(x($,"skill.json"))}catch{return!1}},zY=({platformDirs:$,managedSkillRoots:Q})=>{let X=[],Z=0,Y=Q.map(QY);for(let q of $){if(!gQ(q))continue;let z;try{z=tX(q)}catch{continue}for(let W of z){let K=x(q,W);if(!XY(K))continue;let E=YY(K);if(!E||!qY(E,Y)){Z++;continue}if(!WY(E)){Z++;continue}try{$Y(K),X.push(K)}catch{Z++}}}return{removed:X,skipped:Z}},HY=($)=>{let Q=uQ(),X=[x(Q,".claude","skills"),x(Q,".copilot","skills"),x(Q,".config","opencode","skill"),x(Q,".cursor","skills"),x(Q,".gemini","skills"),x(Q,".codex","skills")];if(!$)return X;let Z=[x($,".claude","skills"),x($,".github","skills"),x($,".opencode","skill"),x($,".cursor","skills"),x($,".gemini","skills"),x($,".codex","skills")];return[...X,...Z]},dQ=($={})=>{let Q=uQ(),X=[x(Q,".agents","skills"),...$.projectRoot?[x($.projectRoot,".agents","skills")]:[]],Z=HY($.projectRoot);return zY({platformDirs:Z,managedSkillRoots:X})};var I$=($,Q,X,Z=!0)=>{let Y=A($);if(!Y&&!Z)return{updated:!1,created:!1,skipped:!0};let q=Q,z=new Date().toISOString().split("T")[0];q=q.replace(/\{\{DATE\}\}/g,z),q=q.replace(/\{\{SUPERPOWERS_PATH\}\}/g,H.superpowersRepo);let W=`<!-- SUPERPOWERS_SKILLS_START -->
|
|
106
|
+
${q}
|
|
107
|
+
<!-- SUPERPOWERS_SKILLS_END -->`;if(Y){let K=new Date().toISOString().split("T")[0],E=`${$}.backup-${K}`;try{R(`cp "${$}" "${E}"`,{stdio:"pipe"})}catch(I){return{updated:!1,error:!0,message:`Failed to backup: ${I.message}`}}let B;try{B=a($,"utf8")}catch(I){return{updated:!1,error:!0,message:`Failed to read: ${I.message}`}}let _="<!-- SUPERPOWERS_SKILLS_START -->",G="<!-- SUPERPOWERS_SKILLS_END -->",V;if(B.includes(_)&&B.includes(G)){let I=new RegExp(`${_}[\\s\\S]*?${G}`,"g");V=B.replace(I,W)}else{let I=B.match(/^#\s+.+$/m);if(I){let U=B.indexOf(`
|
|
108
|
+
`,I.index)+1;V=B.slice(0,U)+`
|
|
109
|
+
`+W+`
|
|
110
|
+
`+B.slice(U)}else V=W+`
|
|
111
|
+
|
|
112
|
+
`+B}try{return $$($,V,"utf8"),{updated:!0,created:!1,backup:E}}catch(I){return{updated:!1,error:!0,message:`Failed to write: ${I.message}`}}}else try{let K=hQ($);if(!A(K))R(`mkdir -p "${K}"`,{stdio:"pipe"});let _=`# ${e($).base.toUpperCase()}
|
|
113
|
+
|
|
114
|
+
`+W;return $$($,_,"utf8"),{updated:!1,created:!0}}catch(K){return{updated:!1,created:!1,error:!0,message:`Failed to create: ${K.message}`}}},BY=()=>{console.log("Installing Unix aliases...");let $=v(H.superpowersRepo,".agents","superpowers-agent"),Q=v(H.home,".local","bin"),X=v(Q,"superpowers-agent"),Z=v(Q,"superpowers");if(!A($)){console.log("⚠️ superpowers-agent executable not found");return}if(!A(Q))try{R(`mkdir -p "${Q}"`,{stdio:"pipe"}),console.log(`✓ Created ${Q}`)}catch(q){console.log(`⚠️ Failed to create ${Q}: ${q.message}`);return}try{if(A(X))R(`rm "${X}"`,{stdio:"pipe"});R(`ln -s "${$}" "${X}"`,{stdio:"pipe"}),console.log(`✓ Created symlink: superpowers-agent -> ${$}`)}catch(q){console.log(`⚠️ Failed to create superpowers-agent symlink: ${q.message}`)}try{if(A(Z))R(`rm "${Z}"`,{stdio:"pipe"});R(`ln -s "${$}" "${Z}"`,{stdio:"pipe"}),console.log(`✓ Created symlink: superpowers -> ${$}`)}catch(q){console.log(`⚠️ Failed to create superpowers symlink: ${q.message}`)}if(!(process.env.PATH||"").includes(Q))console.log(`
|
|
115
115
|
⚠️ 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"
|
|
116
|
-
`)},
|
|
117
|
-
`),$==="win32")return
|
|
116
|
+
`)},_Y=()=>{console.log("Installing Windows aliases..."),console.log("✓ Windows alias installation (implementation pending)")},u$=()=>{let $=KY();if(console.log(`## Installing Universal Aliases
|
|
117
|
+
`),$==="win32")return _Y();else return BY()},GY=($)=>{let Q=v(H.superpowersRepo,".github","copilot-instructions.md"),X=v(H.superpowersRepo,"skills","meta","using-superpowers","SKILL.md"),Z=v($,".github","copilot-instructions.md"),Y="<!-- SUPERPOWERS_-_INSTRUCTIONS_START -->",q="<!-- SUPERPOWERS_-_INSTRUCTIONS_END -->";if(!A(Q))return{error:!0,message:"Source template not found"};if(!A(X))return{error:!0,message:"using-superpowers SKILL.md not found"};let z,W;try{z=a(Q,"utf8"),W=a(X,"utf8")}catch(B){return{error:!0,message:`Failed to read source files: ${B.message}`}}let K=z.replace("${content}",W);if(!K.includes("<!-- SUPERPOWERS_-_INSTRUCTIONS_START -->")||!K.includes("<!-- SUPERPOWERS_-_INSTRUCTIONS_END -->"))return{error:!0,message:"Template is missing required markers"};let E=hQ(Z);try{if(!A(E))R(`mkdir -p "${E}"`,{stdio:"pipe"})}catch(B){return{error:!0,message:`Failed to create .github directory: ${B.message}`}}if(A(Z)){let B;try{B=a(Z,"utf8")}catch(V){return{error:!0,message:`Failed to read existing file: ${V.message}`}}let _=new Date().toISOString().replace(/[:.]/g,"-"),G=`${Z}.backup-${_}`;try{R(`cp "${Z}" "${G}"`,{stdio:"pipe"})}catch(V){return{error:!0,message:`Failed to backup: ${V.message}`}}if(B.includes("<!-- SUPERPOWERS_-_INSTRUCTIONS_START -->")&&B.includes("<!-- SUPERPOWERS_-_INSTRUCTIONS_END -->")){let V=new RegExp("<!-- SUPERPOWERS_-_INSTRUCTIONS_START -->[\\s\\S]*?<!-- SUPERPOWERS_-_INSTRUCTIONS_END -->","g"),I=B.replace(V,K.trim());try{return $$(Z,I,"utf8"),{updated:!0,backup:G}}catch(U){return{error:!0,message:`Failed to update: ${U.message}`}}}else{let V=B.trimEnd()+`
|
|
118
118
|
|
|
119
119
|
`+K.trim()+`
|
|
120
|
-
`;try{return $$(Z,V,"utf8"),{updated:!0,backup:G}}catch(
|
|
121
|
-
`);let $=process.cwd(),Q=
|
|
120
|
+
`;try{return $$(Z,V,"utf8"),{updated:!0,backup:G}}catch(I){return{error:!0,message:`Failed to append: ${I.message}`}}}}else try{return $$(Z,K,"utf8"),{created:!0}}catch(B){return{error:!0,message:`Failed to create: ${B.message}`}}},pQ=()=>{u(),console.log(`# Setting up Superpowers skills for this project
|
|
121
|
+
`);let $=process.cwd(),Q=v($,".agents"),X=v(Q,"skills"),Z=v($,"AGENTS.md"),Y=v(Q,"AGENTS.md"),q=A(Z)?Z:Y,z=v(H.superpowersRepo,".agents","templates","AGENTS.md.template");if(!A(z)){console.log(`✗ Error: AGENTS.md template not found
|
|
122
122
|
Expected at: ${z}
|
|
123
|
-
Please update your Superpowers installation`);return}if(!A(Q))try{R(`mkdir -p "${Q}"`,{stdio:"pipe"}),console.log("✓ Created .agents/ directory")}catch(O){console.log(`✗ Failed to create .agents/ directory: ${O.message}`);return}else console.log("✓ .agents/ directory exists");if(!A(X))try{R(`mkdir -p "${X}"`,{stdio:"pipe"}),R(`touch "${
|
|
123
|
+
Please update your Superpowers installation`);return}if(!A(Q))try{R(`mkdir -p "${Q}"`,{stdio:"pipe"}),console.log("✓ Created .agents/ directory")}catch(O){console.log(`✗ Failed to create .agents/ directory: ${O.message}`);return}else console.log("✓ .agents/ directory exists");if(!A(X))try{R(`mkdir -p "${X}"`,{stdio:"pipe"}),R(`touch "${v(X,".gitkeep")}"`,{stdio:"pipe"}),console.log("✓ Created .agents/skills/ directory")}catch(O){console.log(`✗ Failed to create skills directory: ${O.message}`);return}else console.log("✓ .agents/skills/ directory exists");let W=v(Q,"docs"),K=v(W,"SUPERPOWERS.md"),E=v(H.superpowersRepo,".agents","templates","SUPERPOWERS.md.template");if(!A(W))try{R(`mkdir -p "${W}"`,{stdio:"pipe"}),console.log("✓ Created .agents/docs/ directory")}catch(O){console.log(`⚠️ Failed to create docs directory: ${O.message}`)}else console.log("✓ .agents/docs/ directory exists");let B=A(q);if(B){let O=new Date().toISOString().split("T")[0],c=`${q}.backup-${O}`;try{R(`cp "${q}" "${c}"`,{stdio:"pipe"}),console.log(`✓ Backed up existing AGENTS.md to ${e(c).base}`)}catch(E$){console.log(`✗ Failed to backup AGENTS.md: ${E$.message}`);return}}let _;try{_=a(z,"utf8")}catch(O){console.log(`✗ Failed to read template: ${O.message}`);return}let G=P();if(_=_.replace(/\{\{VERSION\}\}/g,G),A(E))try{let O=a(E,"utf8"),c=new Date().toISOString().split("T")[0];O=O.replace(/\{\{VERSION\}\}/g,G),O=O.replace(/\{\{DATE\}\}/g,c),$$(K,O,"utf8"),console.log("✓ Created .agents/docs/SUPERPOWERS.md")}catch(O){console.log(`⚠️ Failed to create SUPERPOWERS.md: ${O.message}`)}else console.log("⚠️ SUPERPOWERS.md.template not found");let V=[],I=v($,".github","copilot-instructions.md"),U=v(H.home,".github","copilot-instructions.md");if(A(I)||A(U)||D.copilot.check())V.push("github-copilot");let M=v($,"CLAUDE.md"),C=v(Q,"CLAUDE.md");if(A(M)||A(C)||D.claude.check())V.push("claude-code");if(D.opencode.check())V.push("opencode");console.log(`
|
|
124
124
|
Detected platforms for project: ${V.join(", ")||"none"}
|
|
125
|
-
`);let f=V.filter((O)=>["github-copilot","opencode"].includes(O)),N=I$(q,
|
|
125
|
+
`);let f=V.filter((O)=>["github-copilot","opencode"].includes(O)),N=I$(q,_,f,!B);if(N.created)console.log(`✓ Created AGENTS.md with platform tool mappings (${q===Z?"root":".agents/"})`);else if(N.updated)console.log(`✓ Updated AGENTS.md with platform tool mappings (${q===Z?"root":".agents/"})`);else if(N.error)console.log("⚠️ Failed to update AGENTS.md");let H$=A(M)?M:C,L=I$(H$,_,["claude-code"],!1);if(L.created)console.log(`✓ Created CLAUDE.md with Claude Code tool mappings (${H$===M?"root":".agents/"})`);else if(L.updated){if(console.log(`✓ Updated CLAUDE.md with Claude Code tool mappings (${H$===M?"root":".agents/"})`),L.backup)console.log(` Backed up to ${e(L.backup).base}`)}else if(L.skipped)console.log("ℹ️ Skipped CLAUDE.md (does not exist)");else if(L.error)console.log("⚠️ Failed to update CLAUDE.md");let J=v($,".github","copilot-instructions.md"),F={skipped:!0};if(V.includes("github-copilot")){if(F=GY($),F.created)console.log("✓ Created .github/copilot-instructions.md with Superpowers instructions");else if(F.updated){if(console.log("✓ Updated .github/copilot-instructions.md with Superpowers instructions"),F.backup)console.log(` Backed up to ${e(F.backup).base}`)}else if(F.error)console.log(`⚠️ Failed to update .github/copilot-instructions.md: ${F.message||""}`)}else console.log("ℹ️ Skipped .github/copilot-instructions.md (GitHub Copilot not detected)");let S=!A(Z)&&!A(Y);if(A(J)&&S){let O=I$(J,_,["github-copilot"],!1);if(O.updated){if(console.log("✓ Updated .github/copilot-instructions.md with GitHub Copilot tool mappings"),O.backup)console.log(` Backed up to ${e(O.backup).base}`)}else if(O.error)console.log("⚠️ Failed to update .github/copilot-instructions.md with tool mappings")}else if(A(J)&&!S)console.log("ℹ️ Skipped .github/copilot-instructions.md tool mappings (AGENTS.md exists, using that instead)");else if(!A(J)&&!V.includes("github-copilot"))console.log("ℹ️ Skipped .github/copilot-instructions.md tool mappings (does not exist)");let g=`
|
|
126
126
|
# Setup complete!
|
|
127
127
|
|
|
128
128
|
Your project now has:
|
|
@@ -132,7 +132,7 @@ Your project now has:
|
|
|
132
132
|
- .github/copilot-instructions.md with Superpowers instructions`;g+=`
|
|
133
133
|
- .agents/skills/ ready for project-specific skills`,g+=`
|
|
134
134
|
- .agents/docs/SUPERPOWERS.md for detailed reference
|
|
135
|
-
`,console.log(g)},
|
|
135
|
+
`,console.log(g)},VY=()=>{let $=[...["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)=>v(H.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)=>v(H.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)=>v(H.home,".config","opencode","command",X))],Q=0;for(let X of $)if(A(X))try{mQ(X),Q++}catch(Z){console.log(` ⚠️ Could not remove ${X}: ${Z.message}`)}if(Q>0)console.log(`✓ Removed ${Q} legacy prompt/command file${Q!==1?"s":""}`);else console.log("✓ No legacy prompt/command files found")},LY=()=>{let $=0;for(let Q of U$){let X=Q.skillsDir(),Z=v(X,"superpowers");try{if(EY(Z).isSymbolicLink())mQ(Z),console.log(`✓ Removed legacy superpowers symlink from ${X.replace(H.home,"~")}`),$++}catch{}}if($===0)console.log("✓ No legacy superpowers directory symlinks found")},cQ=async()=>{u(),console.log(`# Superpowers Bootstrap for Agents
|
|
136
136
|
# ==================================
|
|
137
137
|
`);let $=process.argv.includes("--no-update"),X=new Set(["copilot","claude","opencode"].filter((z)=>process.argv.includes(`--force-${z}`))),Z=X.size>0;if(!$){let z=Z$(),W=await V$();if(W.error)console.log(`## Update Check
|
|
138
138
|
|
|
@@ -145,10 +145,10 @@ Your project now has:
|
|
|
145
145
|
---
|
|
146
146
|
`)}if(!Z)u$(),console.log(`---
|
|
147
147
|
`);if(!Z)console.log(`## Cleaning Up Legacy Files
|
|
148
|
-
`),
|
|
148
|
+
`),VY(),console.log(`
|
|
149
149
|
---
|
|
150
150
|
`);if(!Z||X.has("copilot")){if(console.log(`## GitHub Copilot Integration
|
|
151
|
-
`),console.log("✓ Skill symlinks handled in sync step below"),q$("copilot")||A(
|
|
151
|
+
`),console.log("✓ Skill symlinks handled in sync step below"),q$("copilot")||A(v(H.home,".copilot"))||X.has("copilot")){let W=jQ();if(W.created)console.log(`✓ Installed Copilot sessionStart hook -> ${W.path.replace(H.home,"~")}`);else if(W.updated)console.log(`✓ Updated Copilot sessionStart hook -> ${W.path.replace(H.home,"~")}`);else if(W.existed)console.log("✓ Copilot sessionStart hook already up to date");else if(W.error)console.log(`⚠️ Failed to install Copilot sessionStart hook: ${W.message}`)}else console.log("ℹ️ Skipped Copilot sessionStart hook (Copilot CLI not detected; run with --force-copilot to install anyway)");console.log(`
|
|
152
152
|
---
|
|
153
153
|
`)}if(!Z||X.has("claude")){if(console.log(`## Claude Code Integration
|
|
154
154
|
`),!D.claude.check()&&!X.has("claude"))console.log(`⚠️ Skipped (${D.claude.name} CLI not detected)
|
|
@@ -164,11 +164,11 @@ Your project now has:
|
|
|
164
164
|
---
|
|
165
165
|
`)}if(!Z){console.log(`## Generating Platform-Specific Files
|
|
166
166
|
`);let z=vQ();console.log(`Detected platforms: ${z.join(", ")||"none"}
|
|
167
|
-
`);let W=
|
|
168
|
-
`)}if(K){let E=P();K=K.replace(/\{\{VERSION\}\}/g,E);let
|
|
167
|
+
`);let W=v(H.superpowersRepo,".agents","templates","AGENTS.md.template"),K="";try{K=a(W,"utf8")}catch(E){console.log(`⚠️ Could not read AGENTS.md template: ${E.message}
|
|
168
|
+
`)}if(K){let E=P();K=K.replace(/\{\{VERSION\}\}/g,E);let B=v(H.home,".agents","AGENTS.md"),_=I$(B,K,z,!0);if(_.created)console.log(`✓ Created ${B}`);else if(_.updated)console.log(`✓ Updated ${B}`)}console.log(`
|
|
169
169
|
---
|
|
170
170
|
`)}console.log(`## Cleaning Up Legacy Superpowers Dir Symlinks
|
|
171
|
-
`),
|
|
171
|
+
`),LY(),console.log(`
|
|
172
172
|
---
|
|
173
173
|
`),console.log(`## Syncing Repo Skills -> ~/.agents/skills/
|
|
174
174
|
`);let Y=PQ();if(Y.created>0||Y.updated>0)console.log(` ✓ ${Y.created} created, ${Y.updated} updated, ${Y.existed} already current`);else if(Y.errors.length>0)for(let z of Y.errors)console.log(` ⚠️ ${z}`);else console.log(` ✓ ${Y.existed} skill symlinks already up to date`);console.log(`
|
|
@@ -178,12 +178,12 @@ Your project now has:
|
|
|
178
178
|
---
|
|
179
179
|
`),console.log(`# Bootstrap Complete!
|
|
180
180
|
`),console.log("✓ All integrations installed"),console.log("✓ Skills system ready"),console.log(`✓ Skill symlinks synced
|
|
181
|
-
`),console.log("Next steps:"),console.log(" - Run `superpowers-agent find-skills` to see available skills"),console.log(" - Run `superpowers-agent setup-skills` in your project directory")};import{existsSync as b,readFileSync as O$,mkdirSync as
|
|
182
|
-
⚠ Could not parse agents.json: ${V.message}`);return}let Y=
|
|
181
|
+
`),console.log("Next steps:"),console.log(" - Run `superpowers-agent find-skills` to see available skills"),console.log(" - Run `superpowers-agent setup-skills` in your project directory")};import{existsSync as b,readFileSync as O$,mkdirSync as vY,rmSync as n$,cpSync as NY,lstatSync as bY}from"fs";import{join as T,dirname as w$,parse as z$,sep as CY}from"path";import{execSync as j}from"child_process";import{homedir as p}from"os";import{createInterface as FY}from"readline";import{readFileSync as UY,existsSync as h$,unlinkSync as IY,lstatSync as JY,mkdirSync as OY}from"fs";import{join as wY,dirname as MY}from"path";import{join as W$}from"path";import{homedir as nQ}from"os";var d$={github:{name:"github",sourceDir:".github/agents",sourceExt:".agent.md",getDestDir:()=>W$(H.vscodeUserDir,"prompts"),destExt:".agent.md"},opencode:{name:"opencode",sourceDir:".opencode/agents",sourceExt:".md",getDestDir:()=>W$(nQ(),".config","opencode","agents"),destExt:".md"},claude:{name:"claude",sourceDir:".claude/agents",sourceExt:".md",getDestDir:()=>W$(nQ(),".claude","agents"),destExt:".md"}};function oQ($,Q,X){let Z=d$[Q];if(!Z)return null;return W$($,Z.sourceDir,`${X}${Z.sourceExt}`)}function iQ($,Q){let X=d$[$];if(!X)return null;return W$(X.getDestDir(),`${Q}${X.destExt}`)}function m$(){return Object.keys(d$)}function AY($){if(!$||typeof $!=="object")return{valid:!1,error:"agents.json must be a JSON object"};if(!$.version||typeof $.version!=="string")return{valid:!1,error:'agents.json must have a "version" string field'};if(!$.agents||typeof $.agents!=="object")return{valid:!1,error:'agents.json must have an "agents" object field'};let Q=m$(),X=[];for(let[Z,Y]of Object.entries($.agents)){if(!Q.includes(Z)){X.push(Z);continue}if(!Array.isArray(Y))return{valid:!1,error:`agents.${Z} must be an array of agent names`};for(let q of Y)if(typeof q!=="string")return{valid:!1,error:`agents.${Z} must contain only string agent names`}}return{valid:!0,data:$,skippedPlatforms:X}}function TY($,Q){if(!h$($))return{installed:!1,error:`Source file not found: ${$}`};if(h$(Q))try{if(!JY(Q).isSymbolicLink())IY(Q)}catch(Z){}OY(MY(Q),{recursive:!0});let X=fQ($,Q);if(X.error)return{installed:!1,error:X.error};return{installed:!0}}function p$($,Q={}){let X=wY($,"agents.json");if(!h$(X))return;let Z;try{Z=JSON.parse(UY(X,"utf8"))}catch(V){console.log(`
|
|
182
|
+
⚠ Could not parse agents.json: ${V.message}`);return}let Y=AY(Z);if(!Y.valid){console.log(`
|
|
183
183
|
⚠ Invalid agents.json: ${Y.error}`);return}for(let V of Y.skippedPlatforms)console.log(` ⚠ Skipping unknown platform: ${V}`);let q=Z.repository||"unknown",z=Z.version,W=Q.isUpdate?"Updating":"Installing",K=Q.isUpdate?"Updated":"Installed";console.log(`
|
|
184
|
-
\uD83D\uDCE6 Found agents.json (${q} v${z})`);let E=m$(),
|
|
185
|
-
${W} ${V} agents:`);for(let U of
|
|
186
|
-
${K} ${
|
|
184
|
+
\uD83D\uDCE6 Found agents.json (${q} v${z})`);let E=m$(),B=0,_=0,G=[];for(let[V,I]of Object.entries(Z.agents)){if(!E.includes(V))continue;console.log(`
|
|
185
|
+
${W} ${V} agents:`);for(let U of I){let M=oQ($,V,U),C=iQ(V,U),f=TY(M,C);if(f.installed)console.log(` ✓ ${U}`),G.push({platformKey:V,agentName:U,sourcePath:M,destPath:C}),B++;else console.log(` ✗ ${U}: ${f.error}`),_++}}if(G.length>0){let V=y(!0);if(!V.installedAgents)V.installedAgents={};if(!V.installedAgents[q])V.installedAgents[q]={version:z,agents:{}};V.installedAgents[q].version=z;for(let{platformKey:I,agentName:U,sourcePath:M,destPath:C}of G){if(!V.installedAgents[q].agents[I])V.installedAgents[q].agents[I]={};V.installedAgents[q].agents[I][U]={source:M,destination:C,installedAt:new Date().toISOString()}}h(V,!0)}if(B>0)console.log(`
|
|
186
|
+
${K} ${B} agent(s)${_>0?` (${_} failed)`:""}`)}var lQ=($,Q)=>{if(Q.type==="local"){let Z=$;for(let Y=0;Y<10;Y++){if(b(T(Z,"agents.json")))return Z;let q=w$(Z);if(q===Z)break;Z=q}return $}let X=T(".agents","tmp");if($.includes(X)){let Z=$.indexOf(X),q=$.substring(Z+X.length+1).split(CY)[0];return T($.substring(0,Z),".agents","tmp",q)}return $},aQ=($,Q)=>{let X=T(p(),".agents","repos"),Z=Q.replace(/^@/,"").replace(/[^a-zA-Z0-9_-]/g,"_"),Y=T(X,Z);try{if(vY(X,{recursive:!0}),b(Y))n$(Y,{recursive:!0,force:!0});return NY($,Y,{recursive:!0}),Y}catch(q){return console.log(` Warning: Could not persist repository for agents: ${q.message}`),null}},o$=($)=>{let Q=$.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)$/);if(Q){let[,Y,q,z,W]=Q;return{type:"git-tree",repoUrl:`https://github.com/${Y}/${q}.git`,branch:z,path:W,original:$}}let X=$.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/);if(X){let[,Y,q]=X;return{type:"git-repo",repoUrl:`git@github.com:${Y}/${q}.git`,branch:null,path:null,original:$}}let Z=$.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?$/);if(Z){let[,Y,q]=Z;return{type:"git-repo",repoUrl:`https://github.com/${Y}/${q}.git`,branch:null,path:null,original:$}}if(b($))return{type:"local",path:$,original:$};return null},i$=($)=>{let Q=$.includes("--global")||$.includes("-g"),X=$.includes("--project")||$.includes("-p");if(Q)return T(p(),".agents","skills");if(X)return T(process.cwd(),".agents","skills");let Z=T(process.cwd(),".agents","config.json"),Y=T(p(),".agents","config.json");for(let q of[Z,Y])if(b(q))try{if(JSON.parse(O$(q,"utf8")).installLocation==="project")return T(process.cwd(),".agents","skills")}catch(z){}return T(p(),".agents","skills")},l$=($,Q)=>{let X=T(p(),".agents","tmp",`skill-install-${Date.now()}`);try{if(j(`mkdir -p "${X}"`,{stdio:"pipe"}),Q)j(`git clone --branch ${Q} --depth 1 "${$}" "${X}"`,{stdio:"pipe",timeout:30000});else j(`git clone --depth 1 "${$}" "${X}"`,{stdio:"pipe",timeout:30000});return X}catch(Z){try{j(`rm -rf "${X}"`,{stdio:"pipe"})}catch{}throw Error(`Failed to clone repository: ${Z.message}`)}},Q$=($)=>{let Q=T($,"skill.json");if(!b(Q))return null;try{let X=O$(Q,"utf8");return JSON.parse(X)}catch(X){throw Error(`Failed to read skill.json: ${X.message}`)}},J$=($,Q,X,Z)=>{let Y=T($,Q);if(!b(Y)){Z.errors.push(`Skill directory not found: ${Q}`);return}let q=Q$(Y);if(!q){Z.errors.push(`No skill.json found in: ${Q}`);return}let z=q.name||Q,W=z.split("/").pop()||z,K=T(X,W),E=w$(K);try{j(`mkdir -p "${E}"`,{stdio:"pipe"})}catch(B){Z.errors.push(`Failed to create directory ${E}: ${B.message}`);return}try{if(b(K))j(`rm -rf "${K}"`,{stdio:"pipe"});j(`cp -R "${Y}" "${K}"`,{stdio:"pipe"}),Z.installed.push({name:W,path:K,title:q.title||q.description||W})}catch(B){Z.errors.push(`Failed to install ${Q}: ${B.message}`)}},rQ=($,Q,X,Z,Y=null)=>{let q=y(Z);if(!q.installedSkills)q.installedSkills={};let z={source:$,installBase:Q,installedAt:new Date().toISOString(),skills:X.installed.map((W)=>({name:W.name,path:W.path}))};if(q.installedSkills[$]=z,Y&&Y!==$)q.installedSkills[Y]=z;h(q,Z)},sQ=()=>{let $=process.argv.slice(3),Q=$.find((_)=>!_.startsWith("-")),X=$.filter((_)=>_.startsWith("-"));if(!Q){console.log(`Usage: superpowers-agent add <url-or-path|@alias> [skill-path] [options]
|
|
187
187
|
|
|
188
188
|
Options:
|
|
189
189
|
--global, -g Install skills globally in ~/.agents/skills/ (default)
|
|
@@ -205,18 +205,18 @@ Description:
|
|
|
205
205
|
|
|
206
206
|
Repository aliases can be added using:
|
|
207
207
|
superpowers-agent add-repository <git-url> [--as=@alias]`);return}console.log(`Installing skill(s)...
|
|
208
|
-
`);let Z=!X.includes("--project")&&!X.includes("-p"),Y=null,q=null,z=null;if(Q.startsWith("@")){let
|
|
208
|
+
`);let Z=!X.includes("--project")&&!X.includes("-p"),Y=null,q=null,z=null;if(Q.startsWith("@")){let _=Q;z=_,q=$.find((U,M)=>M>0&&!U.startsWith("-")&&U!==_);let G=k(!1),V=k(!0);if(G[_])Y=G[_],console.log(`Using project repository alias: ${_}`);else if(V[_])Y=V[_],console.log(`Using global repository alias: ${_}`);else{console.log(`Error: Repository alias not found: ${_}`),console.log(`
|
|
209
209
|
Available aliases:`);let U={...V,...G};if(Object.keys(U).length===0)console.log(" (none)"),console.log(`
|
|
210
|
-
Add a repository using:`),console.log(" superpowers-agent add-repository <git-url>");else for(let[
|
|
210
|
+
Add a repository using:`),console.log(" superpowers-agent add-repository <git-url>");else for(let[M,C]of Object.entries(U))console.log(` ${M} -> ${C}`);return}let I=b(Y);if(q)if(I)Q=T(Y,q),console.log(`Repository path: ${Y}`),console.log(`Skill path: ${q}
|
|
211
211
|
`);else Q=Y,console.log(`Repository URL: ${Y}`),console.log(`Skill path: ${q}
|
|
212
|
-
`);else if(Q=Y,
|
|
212
|
+
`);else if(Q=Y,I)console.log(`Repository path: ${Y}
|
|
213
213
|
`);else console.log(`Repository URL: ${Y}
|
|
214
214
|
`)}let W=o$(Q);if(!W){console.log(`Error: Invalid URL or path not found: ${Q}`);return}if(q&&W.type==="git-repo"&&!W.path)W.path=q;let K=i$(X);console.log(`Install location: ${K}
|
|
215
|
-
`);let E,
|
|
216
|
-
`);for(let U of
|
|
215
|
+
`);let E,B=!1;try{if(W.type==="git-repo"||W.type==="git-tree"){if(console.log(`Cloning repository: ${W.repoUrl}`),W.branch)console.log(`Branch: ${W.branch}`);if(E=l$(W.repoUrl,W.branch),B=!0,W.path){if(E=T(E,W.path),!b(E))throw Error(`Path not found in repository: ${W.path}`)}console.log("")}else E=W.path;let _=Q$(E);if(!_)throw Error("No skill.json found in source directory");let G={installed:[],errors:[],source:W.original};if(_.skills&&Array.isArray(_.skills)){console.log(`Found ${_.skills.length} skill(s) to install
|
|
216
|
+
`);for(let U of _.skills)J$(E,U,K,G)}else{let U=_.name||z$(E).base;J$(w$(E),z$(E).base,K,G)}let V=lQ(E,W),I=T(V,"agents.json");if(b(I)){let U=V;if(B){let M;try{M=JSON.parse(O$(I,"utf8"))}catch{}let C=M?.repository||W.original,f=aQ(V,C);if(f)U=f}p$(U,{isUpdate:!1})}if(B&&E)try{let U=E.split("/.agents/tmp/")[0]+"/.agents/tmp/"+E.split("/.agents/tmp/")[1].split("/")[0];j(`rm -rf "${U}"`,{stdio:"pipe"})}catch{}if(console.log(`
|
|
217
217
|
**Successfully installed skills:**`),console.log(`- Source: ${G.source}`),G.installed.length>0)for(let U of G.installed)console.log(` - Installed: ${U.name} at ${U.path}`),console.log(` ${U.title}`);if(G.errors.length>0){console.log(`
|
|
218
|
-
**Errors:**`);for(let U of G.errors)console.log(` - ${U}`)}if(G.installed.length===0&&G.errors.length===0)console.log(" No skills were installed");if(G.installed.length>0)rQ(W.original,K,G,Z,z)}catch(
|
|
219
|
-
Error: ${
|
|
218
|
+
**Errors:**`);for(let U of G.errors)console.log(` - ${U}`)}if(G.installed.length===0&&G.errors.length===0)console.log(" No skills were installed");if(G.installed.length>0)rQ(W.original,K,G,Z,z)}catch(_){if(B&&E)try{let G=E.split("/.agents/tmp/")[0]+"/.agents/tmp/"+E.split("/.agents/tmp/")[1].split("/")[0];j(`rm -rf "${G}"`,{stdio:"pipe"})}catch{}console.log(`
|
|
219
|
+
Error: ${_.message}`)}},tQ=()=>{let $=process.argv.slice(3),Q=$.find((_)=>!_.startsWith("-")),X=$.filter((_)=>_.startsWith("-"));if(!Q){console.log(`Usage: superpowers-agent pull <url-or-path|@alias> [skill-path] [options]
|
|
220
220
|
|
|
221
221
|
Options:
|
|
222
222
|
--global, -g Update skills globally in ~/.agents/skills/ (default)
|
|
@@ -241,18 +241,18 @@ Description:
|
|
|
241
241
|
|
|
242
242
|
Repository aliases can be added using:
|
|
243
243
|
superpowers-agent add-repository <git-url> [--as=@alias]`);return}console.log(`Updating skill(s)...
|
|
244
|
-
`);let Z=!X.includes("--project")&&!X.includes("-p"),Y=null,q=null,z=null;if(Q.startsWith("@")){let
|
|
244
|
+
`);let Z=!X.includes("--project")&&!X.includes("-p"),Y=null,q=null,z=null;if(Q.startsWith("@")){let _=Q;z=_,q=$.find((U,M)=>M>0&&!U.startsWith("-")&&U!==_);let G=k(!1),V=k(!0);if(G[_])Y=G[_],console.log(`Using project repository alias: ${_}`);else if(V[_])Y=V[_],console.log(`Using global repository alias: ${_}`);else{console.log(`Error: Repository alias not found: ${_}`),console.log(`
|
|
245
245
|
Available aliases:`);let U={...V,...G};if(Object.keys(U).length===0)console.log(" (none)"),console.log(`
|
|
246
|
-
Add a repository using:`),console.log(" superpowers-agent add-repository <git-url>");else for(let[
|
|
246
|
+
Add a repository using:`),console.log(" superpowers-agent add-repository <git-url>");else for(let[M,C]of Object.entries(U))console.log(` ${M} -> ${C}`);return}let I=b(Y);if(q)if(I)Q=T(Y,q),console.log(`Repository path: ${Y}`),console.log(`Skill path: ${q}
|
|
247
247
|
`);else Q=Y,console.log(`Repository URL: ${Y}`),console.log(`Skill path: ${q}
|
|
248
|
-
`);else if(Q=Y,
|
|
248
|
+
`);else if(Q=Y,I)console.log(`Repository path: ${Y}
|
|
249
249
|
`);else console.log(`Repository URL: ${Y}
|
|
250
250
|
`)}let W=o$(Q);if(!W){console.log(`Error: Invalid URL or path not found: ${Q}`);return}if(q&&W.type==="git-repo"&&!W.path)W.path=q;let K=i$(X);console.log(`Install location: ${K}
|
|
251
|
-
`);let E,
|
|
252
|
-
`);for(let U of
|
|
251
|
+
`);let E,B=!1;try{if(W.type==="git-repo"||W.type==="git-tree"){if(console.log(`Cloning repository: ${W.repoUrl}`),W.branch)console.log(`Branch: ${W.branch}`);if(E=l$(W.repoUrl,W.branch),B=!0,W.path){if(E=T(E,W.path),!b(E))throw Error(`Path not found in repository: ${W.path}`)}console.log("")}else E=W.path;let _=Q$(E);if(!_)throw Error("No skill.json found in source directory");let G={installed:[],errors:[],source:W.original};if(_.skills&&Array.isArray(_.skills)){console.log(`Found ${_.skills.length} skill(s) to update
|
|
252
|
+
`);for(let U of _.skills)J$(E,U,K,G)}else{let U=_.name||z$(E).base;J$(w$(E),z$(E).base,K,G)}let V=lQ(E,W),I=T(V,"agents.json");if(b(I)){let U=V;if(B){let M;try{M=JSON.parse(O$(I,"utf8"))}catch{}let C=M?.repository||W.original,f=aQ(V,C);if(f)U=f}p$(U,{isUpdate:!0})}if(B&&E)try{let U=E.split("/.agents/tmp/")[0]+"/.agents/tmp/"+E.split("/.agents/tmp/")[1].split("/")[0];j(`rm -rf "${U}"`,{stdio:"pipe"})}catch{}if(console.log(`
|
|
253
253
|
**Successfully updated skills:**`),console.log(`- Source: ${G.source}`),G.installed.length>0)for(let U of G.installed)console.log(` - Updated: ${U.name} at ${U.path}`),console.log(` ${U.title}`);if(G.errors.length>0){console.log(`
|
|
254
|
-
**Errors:**`);for(let U of G.errors)console.log(` - ${U}`)}if(G.installed.length===0&&G.errors.length===0)console.log(" No skills were updated");if(G.installed.length>0)rQ(W.original,K,G,Z,z)}catch(
|
|
255
|
-
Error: ${
|
|
254
|
+
**Errors:**`);for(let U of G.errors)console.log(` - ${U}`)}if(G.installed.length===0&&G.errors.length===0)console.log(" No skills were updated");if(G.installed.length>0)rQ(W.original,K,G,Z,z)}catch(_){if(B&&E)try{let G=E.split("/.agents/tmp/")[0]+"/.agents/tmp/"+E.split("/.agents/tmp/")[1].split("/")[0];j(`rm -rf "${G}"`,{stdio:"pipe"})}catch{}console.log(`
|
|
255
|
+
Error: ${_.message}`)}},jY=($)=>new Promise((Q)=>{let X=FY({input:process.stdin,output:process.stdout});X.question($,(Z)=>{X.close(),Q(Z.trim())})}),c$=($)=>{try{return bY($).isSymbolicLink()}catch{return!1}},eQ=async()=>{let $=process.argv.slice(3),Q=$.find((L)=>!L.startsWith("-")),X=$.filter((L)=>L.startsWith("-"));if(!Q){console.log(`Usage: superpowers-agent rm <url-or-path|@alias> [options]
|
|
256
256
|
|
|
257
257
|
Options:
|
|
258
258
|
--global, -g Remove globally installed skills (default)
|
|
@@ -261,9 +261,9 @@ Options:
|
|
|
261
261
|
Examples:
|
|
262
262
|
superpowers-agent rm https://github.com/example/skills
|
|
263
263
|
superpowers-agent rm @myrepo
|
|
264
|
-
superpowers-agent rm ~/my-local-skills`);return}let Z=!X.includes("--project")&&!X.includes("-p"),Y=Q,q=null;if(Q.startsWith("@")){q=Q;let L=k(!1),
|
|
265
|
-
`);let L=o$(Y);if(!L){console.log(`Error: Invalid URL or path not found: ${Y}`);return}let
|
|
266
|
-
Proceed? [y/N] `)).toLowerCase()!=="y"){console.log("Aborted.");return}for(let L of
|
|
264
|
+
superpowers-agent rm ~/my-local-skills`);return}let Z=!X.includes("--project")&&!X.includes("-p"),Y=Q,q=null;if(Q.startsWith("@")){q=Q;let L=k(!1),J=k(!0);if(L[Q])Y=L[Q];else if(J[Q])Y=J[Q];else{console.log(`Error: Repository alias not found: ${Q}`);return}}let z=EQ(Z),W=z[Q]||z[Y],K=W?.installBase||i$(X),E=[];if(W)E=W.skills;else{console.log(`No tracking data found. Attempting to re-resolve skills from source...
|
|
265
|
+
`);let L=o$(Y);if(!L){console.log(`Error: Invalid URL or path not found: ${Y}`);return}let J,F=!1;try{if(L.type==="git-repo"||L.type==="git-tree"){if(console.log(`Cloning repository: ${L.repoUrl}`),J=l$(L.repoUrl,L.branch),F=!0,L.path){if(J=T(J,L.path),!b(J))throw Error(`Path not found in repository: ${L.path}`)}}else J=L.path;let S=Q$(J);if(!S)throw Error("No skill.json found in source");let g=S.skills&&Array.isArray(S.skills)?S.skills:[S.name||z$(J).base];for(let O of g){let c=O;if(S.skills){let E$=T(J,O);if(b(E$)){let a$=Q$(E$);if(a$?.name)c=a$.name}}E.push({name:c,path:T(K,c)})}if(F)try{let O=J.split("/.agents/tmp/")[0]+"/.agents/tmp/"+J.split("/.agents/tmp/")[1].split("/")[0];j(`rm -rf "${O}"`,{stdio:"pipe"})}catch{}}catch(S){if(F&&J)try{let g=J.split("/.agents/tmp/")[0]+"/.agents/tmp/"+J.split("/.agents/tmp/")[1].split("/")[0];j(`rm -rf "${g}"`,{stdio:"pipe"})}catch{}console.log(`Error resolving source: ${S.message}`);return}}let B=E.filter((L)=>b(L.path)||c$(L.path)),_=[];for(let L of E)for(let J of U$){let F=T(J.skillsDir(),L.name);if(b(F)||c$(F))_.push({platform:J.name,path:F})}let G=KQ(),V=q||Y,I=[];if(G[V]){for(let[,L]of Object.entries(G[V].agents||{}))for(let[,J]of Object.entries(L))if(J.destination&&(b(J.destination)||c$(J.destination)))I.push({path:J.destination})}let U=V.replace(/^@/,"").replace(/[^a-zA-Z0-9_-]/g,"_"),M=T(p(),".agents","repos",U),C=b(M),f=p(),N=(L)=>L.replace(f,"~");if(B.length===0&&_.length===0&&I.length===0&&!C){console.log("Nothing to remove.");return}if(console.log("Will remove:"),B.length>0){console.log(" Skills:");for(let L of B)console.log(` ${N(L.path)}`)}if(_.length>0){console.log(" Platform symlinks:");for(let L of _)console.log(` ${N(L.path)}`)}if(I.length>0){console.log(" Agents:");for(let L of I)console.log(` ${N(L.path)}`)}if(C)console.log(" Persisted repo:"),console.log(` ${N(M)}`);if((await jY(`
|
|
266
|
+
Proceed? [y/N] `)).toLowerCase()!=="y"){console.log("Aborted.");return}for(let L of _){let J=k$(L.path);if(J.removed)console.log(`Removed symlink: ${N(L.path)}`),yQ(L.platform,L.path,"skills");else if(J.error==="Symlink does not exist")console.log(`Already removed: ${N(L.path)}`);else console.log(`Warning: ${N(L.path)}: ${J.error}`)}for(let L of I){let J=k$(L.path);if(J.removed)console.log(`Removed agent: ${N(L.path)}`);else if(J.error==="Symlink does not exist")console.log(`Already removed: ${N(L.path)}`);else console.log(`Warning: ${N(L.path)}: ${J.error}`)}if(C)try{n$(M,{recursive:!0,force:!0}),console.log(`Removed persisted repo: ${N(M)}`)}catch(L){console.log(`Warning: Failed to remove persisted repo: ${L.message}`)}for(let L of B){if(!b(L.path)){console.log(`Already removed: ${N(L.path)}`);continue}try{n$(L.path,{recursive:!0,force:!0}),console.log(`Removed skill: ${N(L.path)}`)}catch(J){console.log(`Warning: Failed to remove ${N(L.path)}: ${J.message}`)}}if(F$(Q,Z),Y!==Q)F$(Y,Z);if(G[V]){let L=y(!0);if(L.installedAgents)delete L.installedAgents[V],h(L,!0)}console.log(`
|
|
267
267
|
Done.`)},$X=()=>{let $=process.argv.slice(3),Q=$.find((E)=>!E.startsWith("-")),X=$.filter((E)=>E.startsWith("-"));if(!Q){console.log(`Usage: superpowers-agent add-repository <git-url> [options]
|
|
268
268
|
|
|
269
269
|
Options:
|
|
@@ -282,8 +282,8 @@ Description:
|
|
|
282
282
|
The repository's skill.json will be read to determine the default alias.
|
|
283
283
|
Use --as to specify a custom alias.
|
|
284
284
|
After adding, you can install skills using: superpowers-agent add @alias path/to/skill`);return}console.log(`Adding repository...
|
|
285
|
-
`);let Z=X.some((E)=>E==="--global"||E==="-g"),Y=X.some((E)=>E==="--project"||E==="-p"),q=X.find((E)=>E.startsWith("--as=")),z=q?q.split("=")[1]:null,W=Y?!1:!0,K;try{console.log(`Cloning repository: ${Q}`),K=
|
|
286
|
-
You can now install skills using:`),console.log(` superpowers-agent add ${
|
|
285
|
+
`);let Z=X.some((E)=>E==="--global"||E==="-g"),Y=X.some((E)=>E==="--project"||E==="-p"),q=X.find((E)=>E.startsWith("--as=")),z=q?q.split("=")[1]:null,W=Y?!1:!0,K;try{console.log(`Cloning repository: ${Q}`),K=T(p(),".agents","tmp",`repo-add-${Date.now()}`),j(`mkdir -p "${K}"`,{stdio:"pipe"}),j(`git clone --depth 1 "${Q}" "${K}"`,{stdio:"pipe",timeout:30000}),console.log("");let E=Q$(K);if(!E)throw Error("No skill.json found in repository");let B;if(z)B=z;else if(E.repository)B=E.repository;else{let V=Q.match(/\/([^/]+?)(?:\.git)?$/);if(V)B="@"+V[1];else throw Error("Could not determine repository alias. Use --as=@alias to specify manually.")}HQ(B,Q,W),j(`rm -rf "${K}"`,{stdio:"pipe"});let _=W?"globally":"in project",G=W?T(p(),".agents","config.json"):T(process.cwd(),".agents","config.json");console.log(`✓ Repository added ${_}`),console.log(` Alias: ${B}`),console.log(` URL: ${Q}`),console.log(` Config: ${G}`),console.log(`
|
|
286
|
+
You can now install skills using:`),console.log(` superpowers-agent add ${B} <path-to-skill>`)}catch(E){if(K)try{j(`rm -rf "${K}"`,{stdio:"pipe"})}catch{}console.log(`
|
|
287
287
|
Error: ${E.message}`)}};import{dirname as QX}from"path";var XX=($,Q,X)=>{let{content:Z,frontmatter:Y}=M$($),q=r[Q].prefix+X,z=QX($),W=`# ${Y.name||q}`;if(Y.description)W+=`
|
|
288
288
|
# ${Y.description}`;if(Y.whenToUse)W+=`
|
|
289
289
|
# When to use: ${Y.whenToUse}`;return W+=`
|
|
@@ -313,15 +313,15 @@ Available skills:`),console.log("Run: superpowers-agent find-skills");return}let
|
|
|
313
313
|
# Supporting tools and docs are in ${K}
|
|
314
314
|
# ============================================
|
|
315
315
|
|
|
316
|
-
${q}`,console.log(E)}catch(q){console.log(q.message)}};var
|
|
316
|
+
${q}`,console.log(E)}catch(q){console.log(q.message)}};var xY=`You have superpowers.
|
|
317
317
|
|
|
318
|
-
**IMPORTANT: The using-superpowers skill content is included below. It is ALREADY LOADED - you are currently following it. Do NOT use the skill tool to load "using-superpowers" again - that would be redundant.**`,
|
|
319
|
-
${
|
|
318
|
+
**IMPORTANT: The using-superpowers skill content is included below. It is ALREADY LOADED - you are currently following it. Do NOT use the skill tool to load "using-superpowers" again - that would be redundant.**`,DY="---\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.",RY=()=>{let $=m("using-superpowers");if(!$)return null;let Q;try{Q=XX($.skillFile,$.sourceType,$.actualSkillPath)}catch{return null}return`<EXTREMELY_IMPORTANT>
|
|
319
|
+
${xY}
|
|
320
320
|
|
|
321
321
|
${Q}
|
|
322
322
|
|
|
323
|
-
${
|
|
324
|
-
</EXTREMELY_IMPORTANT>`},
|
|
323
|
+
${DY}
|
|
324
|
+
</EXTREMELY_IMPORTANT>`},fY=($="raw")=>{let Q=RY();if($==="claude")return JSON.stringify({hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:Q||""}});if($==="copilot")return JSON.stringify({additionalContext:Q||""});return Q||""},ZX=()=>{let $=process.argv.find((X)=>X.startsWith("--format=")),Q=$?$.split("=")[1]:"raw";process.stdout.write(fY(Q)+`
|
|
325
325
|
`)};var qX={bootstrap:cQ,version:TQ,"check-updates":()=>{AQ().catch(($)=>{console.error($.message),process.exit(1)})},update:()=>{let $=process.argv.includes("--no-reinstall");R$({skipReinstall:$})},"config-get":JQ,"config-set":OQ,"setup-skills":pQ,"use-skill":()=>YX(process.argv[3]),"session-context":ZX,execute:VQ,"find-skills":s,add:sQ,"add-repository":$X,"list-repositories":wQ,pull:tQ,rm:eQ,dir:UQ,path:LQ,"get-helpers":IQ,"install-aliases":u$,default:()=>{console.log(`Superpowers for Agents
|
|
326
326
|
Usage:
|
|
327
327
|
superpowers-agent bootstrap [--no-update] [--force] # Run complete bootstrap
|
|
@@ -346,4 +346,4 @@ Usage:
|
|
|
346
346
|
superpowers-agent install-aliases # Install universal aliases (superpowers, superpowers-agent)
|
|
347
347
|
|
|
348
348
|
Documentation: https://github.com/complexthings/superpowers
|
|
349
|
-
`)}},
|
|
349
|
+
`)}},yY=process.argv[2]||"default",SY=qX[yY]||qX.default;try{let $=SY();if($&&typeof $.then==="function")$.catch((Q)=>{console.error(`Error: ${Q.message}`),process.exit(1)})}catch($){console.error(`Error: ${$.message}`),process.exit(1)}
|
|
@@ -5,51 +5,24 @@ Skills extend your capabilities with proven workflows.
|
|
|
5
5
|
### Discover Skills First
|
|
6
6
|
|
|
7
7
|
**Before starting any task**, check for relevant skills:
|
|
8
|
-
1. Use your native skill tool to list available skills
|
|
9
|
-
2. Review skill frontmatter
|
|
10
|
-
3. Run `superpowers-agent find-skills [PATTERN]` for superpowers skills
|
|
8
|
+
1. Use your native skill tool to list available skills.
|
|
9
|
+
2. Review skill descriptions/frontmatter to identify relevant ones.
|
|
11
10
|
|
|
12
11
|
### Skill Loading Rules
|
|
13
12
|
|
|
14
|
-
- Load skills **JIT only** — never preload to "understand" them
|
|
15
|
-
- Follow skill instructions **exactly as written** — no skimming, no shortcuts
|
|
16
|
-
- If a skill has a checklist, create a todo for **each item** — no mental tracking
|
|
17
|
-
- Simple tasks benefit from skills as much as complex ones
|
|
13
|
+
- Load skills **JIT only** — never preload to "understand" them.
|
|
14
|
+
- Follow skill instructions **exactly as written** — no skimming, no shortcuts.
|
|
15
|
+
- If a skill has a checklist, create a todo for **each item** — no mental tracking.
|
|
16
|
+
- Simple tasks benefit from skills as much as complex ones.
|
|
18
17
|
|
|
19
|
-
**Skill priority (highest to lowest):** Project → Personal
|
|
18
|
+
**Skill priority (highest to lowest):** Project → Personal
|
|
20
19
|
|
|
21
20
|
### Using Tools with Skills
|
|
22
21
|
|
|
23
|
-
1. **Native
|
|
24
|
-
2. **Symlinked
|
|
25
|
-
3. **Fallback** —
|
|
26
|
-
4. **Tool
|
|
27
|
-
|
|
28
|
-
| Skill References | Use Your Equivalent |
|
|
29
|
-
|---|---|
|
|
30
|
-
| File operations | Read / Write / Edit tools |
|
|
31
|
-
| Terminal commands | Bash / Shell tool |
|
|
32
|
-
| Search operations | Grep / Glob / Search tools |
|
|
33
|
-
| Task management | TodoWrite / TodoRead tools |
|
|
34
|
-
| Subagent dispatch | Task / Agent tool — or execute directly |
|
|
35
|
-
| Web fetching | WebFetch / Fetch tool |
|
|
36
|
-
|
|
37
|
-
### Version Check
|
|
38
|
-
|
|
39
|
-
**Bootstrapped Version:** `^^SAV:{{VERSION}}^^`
|
|
40
|
-
|
|
41
|
-
At conversation start:
|
|
42
|
-
1. Run a superpowers-agent command and note the version string `^^SAV:X.Y.Z^^` in output
|
|
43
|
-
2. Compare against bootstrapped version `^^SAV:{{VERSION}}^^`
|
|
44
|
-
3. If they differ, notify the user:
|
|
45
|
-
Your superpowers-agent may have updates. Run:
|
|
46
|
-
```sh
|
|
47
|
-
superpowers-agent update && superpowers-agent bootstrap && superpowers-agent setup-skills
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
```sh
|
|
51
|
-
superpowers-agent update && superpowers-agent bootstrap && superpowers-agent setup-skills
|
|
52
|
-
```
|
|
22
|
+
1. **Native skill tool** — load skills via your platform's native skill tool.
|
|
23
|
+
2. **Symlinked skills** — Superpowers skills are symlinked into your platform's skills directory.
|
|
24
|
+
3. **Fallback** — if a skill isn't found via the native tool, run `superpowers-agent find-skills [PATTERN]`.
|
|
25
|
+
4. **Tool equivalence** — when a skill references a tool you don't have, substitute your equivalent.
|
|
53
26
|
|
|
54
27
|
### Why Skills Matter
|
|
55
28
|
|
|
@@ -57,4 +30,21 @@ Skills encode proven techniques that prevent mistakes. Not using them means repe
|
|
|
57
30
|
|
|
58
31
|
**If a skill exists for your task, you MUST use it.**
|
|
59
32
|
|
|
60
|
-
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Version Check
|
|
36
|
+
|
|
37
|
+
Periodically, e.g. once per day check the version of superpowers-agent:
|
|
38
|
+
1. **CURRENT_VERSION** — run a `superpowers-agent` command and extract `X.Y.Z` from the `^^SAV:X.Y.Z^^` string in its output.
|
|
39
|
+
2. **NPM_LATEST_VERSION** — run `npm view @complexthings/superpowers-agent version`.
|
|
40
|
+
3. Compare by **semver precedence, not string comparison** (e.g. `9.10.0` > `9.9.0`). If NPM_LATEST_VERSION is newer, tell the user — do not run these yourself:
|
|
41
|
+
> Your superpowers-agent has updates (`CURRENT_VERSION` → `NPM_LATEST_VERSION`). Run:
|
|
42
|
+
> ```sh
|
|
43
|
+
> npm install -g @complexthings/superpowers-agent
|
|
44
|
+
> superpowers-agent update && superpowers-agent bootstrap && superpowers-agent setup-skills
|
|
45
|
+
> ```
|
|
46
|
+
If versions match, or either lookup fails (e.g. no network), continue silently.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
*Generated by Superpowers on {{DATE}}*
|
|
@@ -1,42 +1,37 @@
|
|
|
1
1
|
# SUPERPOWERS Reference Guide
|
|
2
2
|
|
|
3
|
-
You are an autonomous agent with access to the `superpowers-agent` system.
|
|
3
|
+
You are an autonomous agent with access to the `superpowers-agent` system.
|
|
4
4
|
|
|
5
|
-
>
|
|
6
|
-
> Load this file only when you need specific information not covered in AGENTS.md.
|
|
7
|
-
|
|
8
|
-
**Bootstrapped Version:** `^^SAV:{{VERSION}}^^`
|
|
5
|
+
> Loaded at conversation start. `AGENTS.md` is the primary reference; this guide is the detailed supplement.
|
|
9
6
|
|
|
10
7
|
---
|
|
11
8
|
|
|
12
9
|
## Installation
|
|
13
10
|
|
|
14
|
-
If `superpowers-agent` is not available, install it:
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
npm install -g @complexthings/superpowers-agent
|
|
18
|
-
```
|
|
11
|
+
If `superpowers-agent` is not available, install it: `npm install -g @complexthings/superpowers-agent`
|
|
19
12
|
|
|
20
13
|
---
|
|
21
14
|
|
|
22
15
|
## Version Check
|
|
23
16
|
|
|
24
|
-
|
|
25
|
-
1.
|
|
26
|
-
2.
|
|
27
|
-
3. If
|
|
28
|
-
Your superpowers-agent
|
|
29
|
-
```sh
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
Periodically, e.g. once per day check the version of superpowers-agent:
|
|
18
|
+
1. **CURRENT_VERSION** — run a `superpowers-agent version` command and extract `X.Y.Z` from the `X.Y.Z` string in its output.
|
|
19
|
+
2. **NPM_LATEST_VERSION** — run `npm view @complexthings/superpowers-agent version`.
|
|
20
|
+
3. Compare by **semver precedence, not string comparison** (e.g. `9.10.0` > `9.9.0`). If NPM_LATEST_VERSION is newer, tell the user — do not run these yourself:
|
|
21
|
+
> Your superpowers-agent has updates (`CURRENT_VERSION` → `NPM_LATEST_VERSION`). Run:
|
|
22
|
+
> ```sh
|
|
23
|
+
> npm install -g @complexthings/superpowers-agent
|
|
24
|
+
> superpowers-agent update && superpowers-agent bootstrap && superpowers-agent setup-skills
|
|
25
|
+
> ```
|
|
26
|
+
If versions match, or either lookup fails (e.g. no network), continue silently.
|
|
32
27
|
|
|
33
28
|
---
|
|
34
29
|
|
|
35
30
|
## Skill Loading Rules
|
|
36
31
|
|
|
37
|
-
- Load skills **JIT only** — never preload to "understand" them
|
|
38
|
-
- Follow skill instructions **exactly as written** — no skimming, no shortcuts
|
|
39
|
-
- If a skill has a checklist, create a todo for **each item** — no mental tracking
|
|
40
|
-
- Simple tasks benefit from skills as much as complex ones
|
|
32
|
+
- Load skills **JIT only** — never preload to "understand" them.
|
|
33
|
+
- Follow skill instructions **exactly as written** — no skimming, no shortcuts.
|
|
34
|
+
- If a skill has a checklist, create a todo for **each item** — no mental tracking.
|
|
35
|
+
- Simple tasks benefit from skills as much as complex ones.
|
|
41
36
|
|
|
42
|
-
**Skill priority (highest to lowest):** Project → Personal → Superpowers
|
|
37
|
+
**Skill priority (highest to lowest):** Project → Personal → Superpowers
|
package/package.json
CHANGED
|
@@ -15,62 +15,51 @@ This means BEFORE writing code, BEFORE asking clarifying questions, BEFORE explo
|
|
|
15
15
|
|
|
16
16
|
Why this matters: skills encode hard-won workflows for tasks like debugging, TDD, and brainstorming. Skipping the check means you may skip a workflow that would have prevented a costly mistake.
|
|
17
17
|
|
|
18
|
-
## How to Invoke Skills
|
|
18
|
+
## How to Discover and Invoke Skills
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Skills appear in your context as an available-skills list — scan it at the start of every task. That list is the same workflow library no matter which agent platform you run on (Claude Code, Copilot, OpenCode, Pi, or anything else); only the tools around it differ.
|
|
21
21
|
|
|
22
|
-
To load a skill
|
|
22
|
+
To load a skill's full instructions:
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
skill
|
|
26
|
-
skill("systematic-debugging")
|
|
27
|
-
skill("test-driven-development")
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
When a skill is invoked, its full content is loaded into context. Follow it directly.
|
|
31
|
-
|
|
32
|
-
**Announce when using a skill:**
|
|
33
|
-
> "Using Skill: [name] to [purpose]"
|
|
34
|
-
|
|
35
|
-
This keeps the conversation clear and lets the user know which workflow you're following.
|
|
24
|
+
- **If your platform has a native skill-loading tool**, call it with the skill's name.
|
|
25
|
+
- **If it doesn't**, load the skill the way you'd open any file: read its SKILL.md directly with your file-read tool. Find the path in the skills list, or via the CLI fallback below.
|
|
36
26
|
|
|
37
|
-
|
|
27
|
+
Either path has the same result — the skill's content enters your context and you follow it directly. Don't assume a native tool exists; if you can't find one, read the file. The point is to get the skill's content in front of you, not to use any particular mechanism.
|
|
38
28
|
|
|
39
|
-
**
|
|
29
|
+
**CLI fallback** (use when the skills list isn't already in your context):
|
|
40
30
|
|
|
41
|
-
**CLI fallback:**
|
|
42
31
|
```bash
|
|
43
32
|
superpowers-agent find-skills # list all skills
|
|
44
33
|
superpowers-agent find-skills | grep test # filter by topic
|
|
45
|
-
superpowers-agent execute <skill-name> # load and follow
|
|
34
|
+
superpowers-agent execute <skill-name> # print a skill to load and follow
|
|
46
35
|
```
|
|
47
36
|
|
|
37
|
+
**Announce when using a skill:**
|
|
38
|
+
> "Using Skill: [name] to [purpose]"
|
|
39
|
+
|
|
40
|
+
This keeps the conversation clear and lets the user know which workflow you're following.
|
|
41
|
+
|
|
48
42
|
## Skill Priority
|
|
49
43
|
|
|
50
|
-
When
|
|
44
|
+
When several skills could apply, load them in order of how much each reframes the problem — broadest understanding first, narrowest execution last. Loading a skill is cheap (you are only reading); committing to the wrong workflow is expensive.
|
|
45
|
+
|
|
46
|
+
1. **Domain / context skills first.** A skill about the specific technology or domain you are working in teaches you the territory — and often tells you which approach fits, or that a generic workflow does not. Read it before you commit to a process, and before you brainstorm or plan: knowing the territory makes the brainstorm sharper and can rule a planning skill in or out. A domain skill outranks even an intent-gathering skill like brainstorming.
|
|
47
|
+
2. **Process / approach skills next.** brainstorming, planning, systematic-debugging, test-driven-development — chosen *informed by* what the domain skill told you.
|
|
48
|
+
3. **Implementation skills last.** Step-by-step execution guides, once the approach is set.
|
|
49
|
+
|
|
50
|
+
Why this order: if you lock into a planning or process workflow before reading the domain skill, you may follow steps that do not fit the problem — and by the time you read the domain skill you are already mid-workflow and cannot switch cleanly. Read first, the domain skill can still redirect you to the right process, or tell you to skip one.
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
2. **Implementation skills second** (domain-specific guides) — these guide execution
|
|
52
|
+
**Worked example** — "Let's build a subscription checkout on Stripe," with a Stripe domain skill, a payment-flow planning skill, and a Stripe-checkout implementation skill available:
|
|
54
53
|
|
|
55
|
-
|
|
56
|
-
- "Let's build X" → invoke `brainstorming` first, then domain implementation skills
|
|
57
|
-
- "Fix this bug" → invoke `systematic-debugging` first, then domain-specific skills
|
|
54
|
+
→ `stripe-payments-domain` (learn the territory; it may change how you plan) → `planning-payment-flows` (map states and failure modes) → `implementing-stripe-checkout` (execute).
|
|
58
55
|
|
|
59
|
-
|
|
56
|
+
When no domain skill applies, the leading process skill comes first: "Fix this bug" → `systematic-debugging`, then any domain or implementation skill it points you to.
|
|
60
57
|
|
|
61
|
-
|
|
58
|
+
The first skill you load may change the rest of the plan — reassess after each one rather than committing to the whole sequence up front.
|
|
62
59
|
|
|
63
|
-
|
|
64
|
-
|-------------------|---------------|
|
|
65
|
-
| `TodoWrite` / task list | Your platform's todo or task-tracking tool |
|
|
66
|
-
| `Task` / subagent dispatch | Your subagent or agent-spawning tool |
|
|
67
|
-
| `Skill` tool | Your platform's native skill-loading tool |
|
|
68
|
-
| File read/write/edit | Your file read, write, and edit tools |
|
|
69
|
-
| Terminal / shell commands | Your bash or shell execution tool |
|
|
70
|
-
| Search | Your grep, glob, or search tools |
|
|
71
|
-
| Web fetching | Your web fetch or browser tool |
|
|
60
|
+
## Mapping Skill Instructions to Your Tools
|
|
72
61
|
|
|
73
|
-
|
|
62
|
+
A skill may name a tool using one platform's vocabulary — a todo tracker, a subagent dispatcher, a file editor, a shell, a search tool, a web fetcher. Map each to the closest equivalent your environment provides and use it. If your platform has no equivalent for something a skill calls for, perform the action inline yourself. The skill's intent is what matters, not the specific tool name it happens to use.
|
|
74
63
|
|
|
75
64
|
## Red Flags — You're Rationalizing
|
|
76
65
|
|
|
@@ -107,16 +96,13 @@ Instructions say WHAT, not HOW. "Add X" or "Fix Y" doesn't mean skip workflows.
|
|
|
107
96
|
|
|
108
97
|
## Version Monitoring
|
|
109
98
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
superpowers-agent
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
- **using-a-skill** — How to load and apply a specific skill by name
|
|
121
|
-
- **brainstorming** — Required before any creative work or feature implementation
|
|
122
|
-
- **writing-skills** — How to create new skills using TDD
|
|
99
|
+
At conversation start (periodically thereafter, e.g. once per day), check your version:
|
|
100
|
+
1. **CURRENT_VERSION** — run a `superpowers-agent version` command and extract `X.Y.Z` from the `X.Y.Z` string in its output.
|
|
101
|
+
2. **NPM_LATEST_VERSION** — run `npm view @complexthings/superpowers-agent version`.
|
|
102
|
+
3. Compare by **semver precedence, not string comparison** (e.g. `9.2.0` > `9.0.1`). If NPM_LATEST_VERSION is newer, tell the user — do not run these yourself:
|
|
103
|
+
> Your superpowers-agent has updates (`CURRENT_VERSION` → `NPM_LATEST_VERSION`). Run:
|
|
104
|
+
> ```sh
|
|
105
|
+
> npm install -g @complexthings/superpowers-agent
|
|
106
|
+
> superpowers-agent update && superpowers-agent bootstrap && superpowers-agent setup-skills
|
|
107
|
+
> ```
|
|
108
|
+
If versions match, or either lookup fails (e.g. no network), continue silently.
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
### Using Tools with Skills
|
|
2
|
-
|
|
3
|
-
**1. Native Skill Tool:** Use your platform's native skill tool for loading skills.
|
|
4
|
-
|
|
5
|
-
**2. Symlinked Skills:** Superpowers skills are symlinked to your platform's skills directory.
|
|
6
|
-
|
|
7
|
-
**3. Fallback:** If a skill isn't found via native tool, use `superpowers-agent find-skills [PATTERN]`
|
|
8
|
-
|
|
9
|
-
**4. Tool Equivalence:** When skills reference tools you don't have, use your equivalent:
|
|
10
|
-
- File operations -> your Read/Write/Edit tools
|
|
11
|
-
- Terminal commands -> your Bash/Shell tool
|
|
12
|
-
- Search operations -> your Grep/Glob/Search tools
|
|
13
|
-
- Task management -> your TodoWrite/TodoRead tools
|
|
14
|
-
- Subagent dispatch -> your Task/Agent tool (or execute the work yourself)
|
|
15
|
-
- Web fetching -> your WebFetch/Fetch tool
|