bigpowers 2.88.6 → 2.88.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.88.6",
3
+ "version": "2.88.8",
4
4
  "description": "81 skills — 73 agent skills synthesizing 17 years of software engineering discipline into a prescriptive methodology for solo developers",
5
5
  "keywords": [
6
6
  "gemini-extension"
package/.pi/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.88.6",
3
+ "version": "2.88.8",
4
4
  "description": "81 skills — 73 agent skills synthesizing 17 years of software engineering discipline into a prescriptive methodology for solo developers",
5
5
  "keywords": [
6
6
  "pi-package"
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [2.88.8](https://github.com/danielvm-git/bigpowers/compare/v2.88.7...v2.88.8) (2026-09-21)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **mcp:** switch stdio transport to newline-delimited JSON per MCP spec ([#132](https://github.com/danielvm-git/bigpowers/issues/132)) ([2e07b81](https://github.com/danielvm-git/bigpowers/commit/2e07b81e6a19ee8cad12001114193e22cf224511)), closes [#131](https://github.com/danielvm-git/bigpowers/issues/131)
7
+
8
+ ## [2.88.7](https://github.com/danielvm-git/bigpowers/compare/v2.88.6...v2.88.7) (2026-09-17)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **scripts:** resolve repo root in projects without skills/ ([093fef7](https://github.com/danielvm-git/bigpowers/commit/093fef72eb9f3be4c8cc61431df421752ed1ed44)), closes [#130](https://github.com/danielvm-git/bigpowers/issues/130)
14
+
1
15
  ## [2.88.6](https://github.com/danielvm-git/bigpowers/compare/v2.88.5...v2.88.6) (2026-09-13)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.88.6",
3
+ "version": "2.88.8",
4
4
  "description": "73 agent skills synthesizing 17 years of software engineering discipline into a prescriptive methodology for solo developers",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -16,7 +16,9 @@ resolve_repo_root() {
16
16
  # Library is at REPO/scripts/lib/skill-common.sh → two levels up
17
17
  local repo_candidate
18
18
  repo_candidate="$(cd "$lib_dir/../.." 2>/dev/null && pwd)"
19
- if [ -n "$repo_candidate" ] && [ -d "$repo_candidate/skills" ]; then
19
+ if [ -n "$repo_candidate" ] && {
20
+ [ -d "$repo_candidate/scripts/lib" ] || [ -d "$repo_candidate/skills" ]
21
+ }; then
20
22
  REPO_ROOT="$repo_candidate"
21
23
  else
22
24
  repo_candidate="$(cd "$lib_dir/.." 2>/dev/null && pwd)"
@@ -31,7 +31,9 @@ def resolve_repo_root():
31
31
  lib_dir = os.path.dirname(os.path.abspath(__file__))
32
32
  # scripts/lib/srp-engine.py -> two levels up is REPO_ROOT
33
33
  repo_candidate = os.path.dirname(os.path.dirname(lib_dir))
34
- if os.path.isdir(os.path.join(repo_candidate, "skills")):
34
+ if os.path.isdir(os.path.join(repo_candidate, "scripts", "lib")) or os.path.isdir(
35
+ os.path.join(repo_candidate, "skills")
36
+ ):
35
37
  return repo_candidate
36
38
  return os.path.dirname(lib_dir)
37
39
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  // bigpowers MCP server — exposes 68 skills as MCP tools via stdio transport
3
- // Zero dependencies — raw JSON-RPC over stdio with Content-Length framing
3
+ // Zero dependencies — raw JSON-RPC over stdio (newline-delimited, per MCP spec)
4
4
 
5
5
  'use strict';
6
6
 
@@ -154,6 +154,7 @@ const TOOLS = {
154
154
  // ─── MCP stdio transport ──────────────────────────────────────────────────────
155
155
 
156
156
  let inputBuffer = Buffer.alloc(0);
157
+ let useLspFraming = false;
157
158
 
158
159
  process.stdin.on('data', chunk => {
159
160
  inputBuffer = Buffer.concat([inputBuffer, chunk]);
@@ -163,28 +164,47 @@ process.stdin.on('data', chunk => {
163
164
  process.stdin.on('end', () => process.exit(0));
164
165
 
165
166
  function processBuffer() {
166
- while (true) {
167
- const headerEnd = inputBuffer.indexOf('\r\n\r\n');
168
- if (headerEnd === -1) break;
167
+ while (inputBuffer.length) {
168
+ // Legacy: LSP-style Content-Length framing (kept for backwards compatibility)
169
+ if (/^\s*Content-Length:/i.test(inputBuffer.toString('utf8', 0, Math.min(inputBuffer.length, 20)))) {
170
+ const headerEnd = inputBuffer.indexOf('\r\n\r\n');
171
+ if (headerEnd === -1) break;
169
172
 
170
- const header = inputBuffer.slice(0, headerEnd).toString();
171
- const match = header.match(/Content-Length:\s*(\d+)/i);
172
- if (!match) { inputBuffer = inputBuffer.slice(headerEnd + 4); continue; }
173
+ const header = inputBuffer.slice(0, headerEnd).toString();
174
+ const match = header.match(/Content-Length:\s*(\d+)/i);
175
+ if (!match) { inputBuffer = inputBuffer.slice(headerEnd + 4); continue; }
173
176
 
174
- const contentLength = parseInt(match[1], 10);
175
- const bodyStart = headerEnd + 4;
176
- if (inputBuffer.length < bodyStart + contentLength) break;
177
+ const contentLength = parseInt(match[1], 10);
178
+ const bodyStart = headerEnd + 4;
179
+ if (inputBuffer.length < bodyStart + contentLength) break;
177
180
 
178
- const body = inputBuffer.slice(bodyStart, bodyStart + contentLength).toString();
179
- inputBuffer = inputBuffer.slice(bodyStart + contentLength);
181
+ const body = inputBuffer.slice(bodyStart, bodyStart + contentLength).toString();
182
+ inputBuffer = inputBuffer.slice(bodyStart + contentLength);
180
183
 
181
- try { handleMessage(JSON.parse(body)); } catch (_) {}
184
+ useLspFraming = true;
185
+ try { handleMessage(JSON.parse(body)); } catch (_) {}
186
+ continue;
187
+ }
188
+
189
+ // MCP stdio standard: newline-delimited JSON
190
+ const nl = inputBuffer.indexOf('\n');
191
+ if (nl === -1) break;
192
+
193
+ const line = inputBuffer.slice(0, nl).toString().trim();
194
+ inputBuffer = inputBuffer.slice(nl + 1);
195
+
196
+ useLspFraming = false;
197
+ if (line) try { handleMessage(JSON.parse(line)); } catch (_) {}
182
198
  }
183
199
  }
184
200
 
185
201
  function send(msg) {
186
202
  const body = JSON.stringify(msg);
187
- process.stdout.write(`Content-Length: ${Buffer.byteLength(body, 'utf8')}\r\n\r\n${body}`);
203
+ if (useLspFraming) {
204
+ process.stdout.write(`Content-Length: ${Buffer.byteLength(body, 'utf8')}\r\n\r\n${body}`);
205
+ } else {
206
+ process.stdout.write(body + '\n');
207
+ }
188
208
  }
189
209
 
190
210
  function handleInitialize(id) {
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env bash
2
+ # Regression test for resolve_repo_root() in consumer layouts without skills/.
3
+ # See: https://github.com/danielvm-git/bigpowers/issues/130
4
+ set -euo pipefail
5
+
6
+ TA_PASS=0
7
+ TA_FAIL=0
8
+ TA_TMPDIR=""
9
+
10
+ source "$(dirname "${BASH_SOURCE[0]}")/lib/test-assertions.sh"
11
+ trap ta_cleanup EXIT
12
+
13
+ echo "=== test-resolve-repo-root.sh ==="
14
+
15
+ # Consumer project: scripts/lib present, no local skills/ directory.
16
+ TA_TMPDIR="$(mktemp -d)"
17
+ mkdir -p "$TA_TMPDIR/scripts/lib"
18
+ cp "$(dirname "${BASH_SOURCE[0]}")/lib/skill-common.sh" "$TA_TMPDIR/scripts/lib/"
19
+
20
+ set +e
21
+ out=$(bash -c "source '$TA_TMPDIR/scripts/lib/skill-common.sh' && resolve_repo_root && printf '%s|%s' \"\$REPO_ROOT\" \"\$SKILLS_ROOT\"")
22
+ rc=$?
23
+ set -e
24
+
25
+ if [[ $rc -ne 0 ]]; then
26
+ ta_fail "consumer layout: resolve_repo_root exited $rc"
27
+ elif [[ "$out" == "$TA_TMPDIR|$TA_TMPDIR" ]]; then
28
+ ta_pass "consumer layout without skills/ resolves repo root (not scripts/)"
29
+ else
30
+ ta_fail "consumer layout: expected REPO_ROOT=$TA_TMPDIR, got: $out"
31
+ fi
32
+
33
+ # bigpowers repo: skills/ and scripts/lib both present.
34
+ source "$(dirname "${BASH_SOURCE[0]}")/lib/skill-common.sh"
35
+ resolve_repo_root
36
+ expected_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
37
+ if [[ "$REPO_ROOT" == "$expected_root" && -d "$REPO_ROOT/skills" ]]; then
38
+ ta_pass "bigpowers repo resolves REPO_ROOT with skills/"
39
+ else
40
+ ta_fail "bigpowers repo: REPO_ROOT=$REPO_ROOT expected=$expected_root"
41
+ fi
42
+
43
+ echo "=== $TA_PASS passed, $TA_FAIL failed ==="
44
+ [[ "$TA_FAIL" -eq 0 ]]