@complexthings/superpowers-agent 8.2.1 → 8.2.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.
@@ -0,0 +1,62 @@
1
+ # Post-Migration Fixes — Round Three
2
+
3
+ You are working in an agentic coding environment with access to file system tools, web fetching, subagents, and skills.
4
+
5
+ ## Objective
6
+
7
+ Fix the double `.git` suffix bug in the `add` command's repository cloning logic.
8
+
9
+ **TARGET_VERSION: 8.2.2**
10
+
11
+ ## Problem
12
+
13
+ When a repository URL already ends in `.git`, the clone step appends `.git` again, producing an invalid URL:
14
+ ```
15
+ Input: https://github.com/BlueAcornInc/skills.git
16
+ Cloned: https://github.com/BlueAcornInc/skills.git.git ← broken
17
+ ```
18
+
19
+ This breaks `superpowers-agent add @baici` after `superpowers-agent add-repository` registers a `.git`-suffixed URL.
20
+
21
+ ## Phase 1 — Discover
22
+
23
+ Before writing or modifying anything:
24
+
25
+ 1. Read `~/.agents/config.json` — understand how repository URLs and aliases are stored. Note if a previously registered repo with the bad URL is already present (this will interfere with testing).
26
+ 2. Read the `add-repository` command implementation — understand how it stores the repository URL.
27
+ 3. Read the `add` command implementation — trace the full path from alias resolution → URL construction → `git clone` invocation. Identify exactly where `.git` is appended.
28
+ 4. Check for any other commands that construct Git clone URLs — the same bug may exist elsewhere.
29
+
30
+ ## Phase 2 — Fix
31
+
32
+ 1. Fix the URL construction so it does not append `.git` if the URL already ends with `.git`.
33
+ 2. Apply the same fix to any other code paths identified in Phase 1 that construct clone URLs.
34
+ 3. Ensure URLs without `.git` suffix still work correctly (both forms are valid Git URLs).
35
+
36
+ ## Phase 3 — Verify
37
+
38
+ 1. Before testing, check `~/.agents/config.json` for any stale or malformed repository entries from previous failed attempts. Remove them if present so they don't interfere with validation.
39
+ 2. Confirm the clone URL is correct for inputs both with and without `.git` suffix.
40
+ 3. Search the codebase for any other instances of `.git` suffix appending that could produce the same bug.
41
+ 4. Set version to `8.2.2` in both `./package.json` and `.agents/package.json`.
42
+
43
+ ## Known Testing Gotcha
44
+
45
+ `~/.agents/config.json` persists previously registered repositories. If a repo was added before this fix, the stored URL may already contain the double `.git`. Clear the relevant entry from `~/.agents/config.json` before re-testing `add-repository` and `add` commands.
46
+
47
+ ## Completion Criteria
48
+
49
+ - Repository URLs ending in `.git` are not double-suffixed during clone
50
+ - Repository URLs without `.git` continue to work correctly
51
+ - No other code paths in the codebase have the same double-suffix bug
52
+ - Both `./package.json` and `.agents/package.json` set to version `8.2.2`
53
+ - No regressions in existing CLI functionality
54
+
55
+ ## Agent Instructions
56
+
57
+ - Spawn parallel subagents where tasks are independent; each subagent owns a single concern
58
+ - Use Claude Sonnet 4.6 model for subagents
59
+ - USE `leveraging-cli-tools` skill — use `rg`, `fd`, `jq`, `bat`, `ast-grep` over standard tools
60
+ - Reason from facts only — read actual files before writing or modifying anything
61
+ - Do not guess file contents, dependency structures, or platform behaviors — verify first
62
+ - Concise output only; no padding
@@ -4,77 +4,24 @@ You are working in an agentic coding environment with access to file system tool
4
4
 
5
5
  ## Objective
6
6
 
7
- Fix two issues introduced during the shell-to-npm migration, add a Husky pre-commit hook to keep versions synchronized, and update documentation to reflect today's changes. Target version: **8.2.0**.
7
+ TARGET_VERSION: **8.2.1**.
8
8
 
9
- ## Phase 1 — Discover
9
+ FIX the following issues:
10
10
 
11
- Before writing or modifying anything:
11
+ I installed the new version and noticed some issues that need to be fixed:
12
12
 
13
- 1. Read `git.js` locate the `checkForUpdates` function and understand its current Git-based logic.
14
- 2. Read `output.js` locate the `getLocalVersion` function and understand how it currently resolves the version.
15
- 3. Read `./package.json` and `.agents/package.json` note current version values and any relevant fields.
16
- 4. Check if `husky` is already a dependency or if any `.husky/` directory exists.
17
- 5. Identify how the CLI is built (confirm `bun i && bun run build` in `.agents/`).
18
- 6. Read `README.md` and `CHANGELOG.md` to understand their current structure and formatting conventions.
19
-
20
- ## Phase 2 Fix: Update Checking
21
-
22
- The `checkForUpdates` function in `git.js` currently checks the Git repo, which is unreliable post-migration.
23
-
24
- 1. Create a new function that fetches the latest published version from the npm registry for the package (e.g., `https://registry.npmjs.org/@complexthings/superpowers-agent/latest`).
25
- 2. Refactor `checkForUpdates` to use the npm registry function instead of the Git repo check.
26
- 3. Compare the registry version against the locally installed version to determine if an update is available.
27
-
28
- ## Phase 3 — Fix: Local Version Source
29
-
30
- The `getLocalVersion` function in `output.js` should read the version from `.agents/package.json` (the Bun-built CLI tool's package manifest).
31
-
32
- 1. Update `getLocalVersion` to read and parse `.agents/package.json` for its `version` field.
33
- 2. Remove or replace any previous version resolution logic that no longer applies.
34
-
35
- ## Phase 4 — Add: Husky Pre-Commit Hook
36
-
37
- Add a `husky` pre-commit hook that enforces version parity between `./package.json` and `.agents/package.json`.
38
-
39
- 1. Install `husky` as a dev dependency in the root. Initialize it (`npx husky init` or equivalent).
40
- 2. Create a pre-commit hook script that does the following:
41
- - Read `version` from `./package.json` and `.agents/package.json`.
42
- - If versions match → proceed, no action needed.
43
- - If versions differ:
44
- 1. Determine the HIGHEST version (semver comparison).
45
- 2. Update both `package.json` files to the highest version.
46
- 3. Run `npm i --package-lock-only` in the repo root to sync `package-lock.json`.
47
- 4. Run `bun i && bun run build` in `.agents/` to rebuild the CLI with the correct version.
48
- 5. Stage the changed files (`package.json`, `package-lock.json`, `.agents/package.json`, and build output) into the current commit.
49
- - Allow the commit to proceed.
50
-
51
- ## Phase 5 — Update Documentation
52
-
53
- 1. Update `CHANGELOG.md` for version **8.2.0** dated **2026-03-16**, following the existing format. Document today's changes:
54
- - Update checking now uses npm registry instead of Git repo
55
- - `getLocalVersion` now reads from `.agents/package.json`
56
- - Added Husky pre-commit hook to enforce version parity between root and `.agents/` package manifests
57
- 2. Update `README.md` to reflect any install, usage, or behavior changes introduced by these fixes. Preserve existing structure — only modify or add sections relevant to today's changes.
58
- 3. Ensure both `./package.json` and `.agents/package.json` have version set to `8.2.0`.
59
-
60
- ## Phase 6 — Verify
61
-
62
- 1. Confirm `checkForUpdates` no longer references Git-based version checking.
63
- 2. Confirm `getLocalVersion` reads from `.agents/package.json`.
64
- 3. Simulate a version mismatch between `./package.json` and `.agents/package.json` — run the pre-commit hook manually and verify it syncs versions, updates lockfiles, rebuilds, and stages changes.
65
- 4. Confirm a matching-version scenario passes the hook with no modifications.
66
- 5. Confirm both `package.json` files show version `8.2.0`.
67
- 6. Confirm `CHANGELOG.md` has a `8.2.0` entry and `README.md` reflects current behavior.
13
+ 1. Version Checking is broken:
14
+ - `superpowers-agent version` returns `0.0.0`
15
+ 2. `superpowers-agent bootstrap` command is broken:
16
+ - Running `superpowers-agent bootstrap` is broken because most things look for `~/.agents/superpowers` directory which doesn't exist anymore since it's now installed as an npm package and not as a shell script that puts it in `~/.agents/superpowers`
17
+ 3. `superpowers-agent update` command is broken:
18
+ - Running `superpowers-agent update` is also broken for the same reason as above, it looks for the old directory structure that doesn't exist anymore. It should run the new update process `npm install -g @complexthings/superpowers-agent` instead to update the global npm package, after checking the npm registry for the latest version and comparing it to the current version to see if an update is actually needed before running the install command.
19
+ 4. `superpowers-agent check-updates` command is broken:
20
+ - It returns `0.0.0` for current version
68
21
 
69
22
  ## Completion Criteria
70
23
 
71
- - `checkForUpdates` fetches latest version from npm registry, not Git
72
- - `getLocalVersion` reads version from `.agents/package.json`
73
- - Husky pre-commit hook installed and enforces version parity (highest wins)
74
- - Hook runs lockfile update and Bun rebuild when versions diverge, then stages all changes
75
- - Both `package.json` files set to version `8.2.0`
76
- - `CHANGELOG.md` updated with `8.2.0` entry for 2026-03-16
77
- - `README.md` updated to reflect current install/usage behavior
24
+ - Both `package.json` (`./package.json` & `.agents/package.json`) files set to version `<TARGET_VERSION>`
78
25
  - No regressions in existing CLI functionality
79
26
 
80
27
  ## Agent Instructions
@@ -196,7 +196,7 @@ Your project now has:
196
196
  ⚠ Invalid agents.json: ${Z.error}`);return}for(let B of Z.skippedPlatforms)console.log(` ⚠ Skipping unknown platform: ${B}`);let Y=X.repository||"unknown",H=X.version,W=q.isUpdate?"Updating":"Installing",K=q.isUpdate?"Updated":"Installed";console.log(`
197
197
  \uD83D\uDCE6 Found agents.json (${Y} v${H})`);let z=m$(),G=0,_=0,V=[];for(let[B,U]of Object.entries(X.agents)){if(!z.includes(B))continue;console.log(`
198
198
  ${W} ${B} agents:`);for(let w of U){let M=Sq($,B,w),d=gq(B,w),P=aQ(M,d);if(P.installed)console.log(` ✓ ${w}`),V.push({platformKey:B,agentName:w,sourcePath:M,destPath:d}),G++;else console.log(` ✗ ${w}: ${P.error}`),_++}}if(V.length>0){let B=p(!0);if(!B.installedAgents)B.installedAgents={};if(!B.installedAgents[Y])B.installedAgents[Y]={version:H,agents:{}};B.installedAgents[Y].version=H;for(let{platformKey:U,agentName:w,sourcePath:M,destPath:d}of V){if(!B.installedAgents[Y].agents[U])B.installedAgents[Y].agents[U]={};B.installedAgents[Y].agents[U][w]={source:M,destination:d,installedAt:new Date().toISOString()}}a(B,!0)}if(G>0)console.log(`
199
- ${K} ${G} agent(s)${_>0?` (${_} failed)`:""}`)}var kq=($,q)=>{if(q.type==="local"){let X=$;for(let Z=0;Z<10;Z++){if(x(b(X,"agents.json")))return X;let Y=w$(X);if(Y===X)break;X=Y}return $}let Q=b(".agents","tmp");if($.includes(Q)){let X=$.indexOf(Q),Y=$.substring(X+Q.length+1).split(rQ)[0];return b($.substring(0,X),".agents","tmp",Y)}return $},uq=($,q)=>{let Q=b(c(),".agents","repos"),X=q.replace(/^@/,"").replace(/[^a-zA-Z0-9_-]/g,"_"),Z=b(Q,X);try{if(lQ(Q,{recursive:!0}),x(Z))iQ(Z,{recursive:!0,force:!0});return oQ($,Z,{recursive:!0}),Z}catch(Y){return console.log(` Warning: Could not persist repository for agents: ${Y.message}`),null}},dq=($)=>{let q=$.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)$/);if(q){let[,Z,Y,H,W]=q;return{type:"git-tree",repoUrl:`https://github.com/${Z}/${Y}.git`,branch:H,path:W,original:$}}let Q=$.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/);if(Q){let[,Z,Y]=Q;return{type:"git-repo",repoUrl:`git@github.com:${Z}/${Y}.git`,branch:null,path:null,original:$}}let X=$.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)(?:\.git)?$/);if(X){let[,Z,Y]=X;return{type:"git-repo",repoUrl:`https://github.com/${Z}/${Y}.git`,branch:null,path:null,original:$}}if(x($))return{type:"local",path:$,original:$};return null},mq=($)=>{let q=$.includes("--global")||$.includes("-g"),Q=$.includes("--project")||$.includes("-p");if(q)return b(c(),".agents","skills");if(Q)return b(process.cwd(),".agents","skills");let X=b(process.cwd(),".agents","config.json"),Z=b(c(),".agents","config.json");for(let Y of[X,Z])if(x(Y))try{if(JSON.parse(v$(Y,"utf8")).installLocation==="project")return b(process.cwd(),".agents","skills")}catch(H){}return b(c(),".agents","skills")},hq=($,q)=>{let Q=b(c(),".agents","tmp",`skill-install-${Date.now()}`);try{if(N(`mkdir -p "${Q}"`,{stdio:"pipe"}),q)N(`git clone --branch ${q} --depth 1 "${$}" "${Q}"`,{stdio:"pipe",timeout:30000});else N(`git clone --depth 1 "${$}" "${Q}"`,{stdio:"pipe",timeout:30000});return Q}catch(X){try{N(`rm -rf "${Q}"`,{stdio:"pipe"})}catch{}throw Error(`Failed to clone repository: ${X.message}`)}},T$=($)=>{let q=b($,"skill.json");if(!x(q))return null;try{let Q=v$(q,"utf8");return JSON.parse(Q)}catch(Q){throw Error(`Failed to read skill.json: ${Q.message}`)}},J$=($,q,Q,X)=>{let Z=b($,q);if(!x(Z)){X.errors.push(`Skill directory not found: ${q}`);return}let Y=T$(Z);if(!Y){X.errors.push(`No skill.json found in: ${q}`);return}let H=Y.name||q,W=b(Q,H),K=w$(W);try{N(`mkdir -p "${K}"`,{stdio:"pipe"})}catch(z){X.errors.push(`Failed to create directory ${K}: ${z.message}`);return}try{if(x(W))N(`rm -rf "${W}"`,{stdio:"pipe"});N(`cp -R "${Z}" "${W}"`,{stdio:"pipe"}),X.installed.push({name:H,path:W,title:Y.title||Y.description||H})}catch(z){X.errors.push(`Failed to install ${q}: ${z.message}`)}},pq=()=>{let $=process.argv.slice(3),q=$.find((z)=>!z.startsWith("-")),Q=$.filter((z)=>z.startsWith("-"));if(!q){console.log(`Usage: superpowers-agent add <url-or-path|@alias> [skill-path] [options]
199
+ ${K} ${G} agent(s)${_>0?` (${_} failed)`:""}`)}var kq=($,q)=>{if(q.type==="local"){let X=$;for(let Z=0;Z<10;Z++){if(x(b(X,"agents.json")))return X;let Y=w$(X);if(Y===X)break;X=Y}return $}let Q=b(".agents","tmp");if($.includes(Q)){let X=$.indexOf(Q),Y=$.substring(X+Q.length+1).split(rQ)[0];return b($.substring(0,X),".agents","tmp",Y)}return $},uq=($,q)=>{let Q=b(c(),".agents","repos"),X=q.replace(/^@/,"").replace(/[^a-zA-Z0-9_-]/g,"_"),Z=b(Q,X);try{if(lQ(Q,{recursive:!0}),x(Z))iQ(Z,{recursive:!0,force:!0});return oQ($,Z,{recursive:!0}),Z}catch(Y){return console.log(` Warning: Could not persist repository for agents: ${Y.message}`),null}},dq=($)=>{let q=$.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)$/);if(q){let[,Z,Y,H,W]=q;return{type:"git-tree",repoUrl:`https://github.com/${Z}/${Y}.git`,branch:H,path:W,original:$}}let Q=$.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/);if(Q){let[,Z,Y]=Q;return{type:"git-repo",repoUrl:`git@github.com:${Z}/${Y}.git`,branch:null,path:null,original:$}}let X=$.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?$/);if(X){let[,Z,Y]=X;return{type:"git-repo",repoUrl:`https://github.com/${Z}/${Y}.git`,branch:null,path:null,original:$}}if(x($))return{type:"local",path:$,original:$};return null},mq=($)=>{let q=$.includes("--global")||$.includes("-g"),Q=$.includes("--project")||$.includes("-p");if(q)return b(c(),".agents","skills");if(Q)return b(process.cwd(),".agents","skills");let X=b(process.cwd(),".agents","config.json"),Z=b(c(),".agents","config.json");for(let Y of[X,Z])if(x(Y))try{if(JSON.parse(v$(Y,"utf8")).installLocation==="project")return b(process.cwd(),".agents","skills")}catch(H){}return b(c(),".agents","skills")},hq=($,q)=>{let Q=b(c(),".agents","tmp",`skill-install-${Date.now()}`);try{if(N(`mkdir -p "${Q}"`,{stdio:"pipe"}),q)N(`git clone --branch ${q} --depth 1 "${$}" "${Q}"`,{stdio:"pipe",timeout:30000});else N(`git clone --depth 1 "${$}" "${Q}"`,{stdio:"pipe",timeout:30000});return Q}catch(X){try{N(`rm -rf "${Q}"`,{stdio:"pipe"})}catch{}throw Error(`Failed to clone repository: ${X.message}`)}},T$=($)=>{let q=b($,"skill.json");if(!x(q))return null;try{let Q=v$(q,"utf8");return JSON.parse(Q)}catch(Q){throw Error(`Failed to read skill.json: ${Q.message}`)}},J$=($,q,Q,X)=>{let Z=b($,q);if(!x(Z)){X.errors.push(`Skill directory not found: ${q}`);return}let Y=T$(Z);if(!Y){X.errors.push(`No skill.json found in: ${q}`);return}let H=Y.name||q,W=b(Q,H),K=w$(W);try{N(`mkdir -p "${K}"`,{stdio:"pipe"})}catch(z){X.errors.push(`Failed to create directory ${K}: ${z.message}`);return}try{if(x(W))N(`rm -rf "${W}"`,{stdio:"pipe"});N(`cp -R "${Z}" "${W}"`,{stdio:"pipe"}),X.installed.push({name:H,path:W,title:Y.title||Y.description||H})}catch(z){X.errors.push(`Failed to install ${q}: ${z.message}`)}},pq=()=>{let $=process.argv.slice(3),q=$.find((z)=>!z.startsWith("-")),Q=$.filter((z)=>z.startsWith("-"));if(!q){console.log(`Usage: superpowers-agent add <url-or-path|@alias> [skill-path] [options]
200
200
 
201
201
  Options:
202
202
  --global, -g Install skills globally in ~/.agents/skills/ (default)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@complexthings/superpowers-agent",
3
- "version": "8.2.1",
3
+ "version": "8.2.2",
4
4
  "description": "Superpowers agent CLI — skills system for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {