bigpowers 2.90.0 → 2.90.1

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.90.0",
3
+ "version": "2.90.1",
4
4
  "description": "80 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.90.0",
3
+ "version": "2.90.1",
4
4
  "description": "80 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,10 @@
1
+ ## [2.90.1](https://github.com/danielvm-git/bigpowers/compare/v2.90.0...v2.90.1) (2026-11-03)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **omp:** keep the tool_call branch probe quiet outside a git repo ([#190](https://github.com/danielvm-git/bigpowers/issues/190)) ([bcacf33](https://github.com/danielvm-git/bigpowers/commit/bcacf33ec72a8705c6b0dbbcf91f2ea2bed4b406)), closes [#189](https://github.com/danielvm-git/bigpowers/issues/189)
7
+
1
8
  # [2.90.0](https://github.com/danielvm-git/bigpowers/compare/v2.89.1...v2.90.0) (2026-11-03)
2
9
 
3
10
 
@@ -205,11 +205,19 @@ function inGitRepo(cwd?: string): boolean {
205
205
  }
206
206
 
207
207
  function currentBranch(cwd: string): string {
208
+ // Probing a directory that is not a repository makes git print
209
+ // "fatal: not a git repository (or any of the parent directories): .git".
210
+ // execSync inherits fd 2 when no stdio option is given, so that message is
211
+ // painted straight over the TUI input line and vanishes on the next redraw
212
+ // (BUG-2026-11-03-omp-hooks-stderr-leak, issue #189). Ask inGitRepo() first —
213
+ // it is silent — so a non-repo target spawns no git process at all.
214
+ if (!inGitRepo(cwd)) return "unknown";
208
215
  try {
209
216
  return execSync("git rev-parse --abbrev-ref HEAD", {
210
217
  encoding: "utf-8",
211
218
  timeout: 3000,
212
219
  cwd,
220
+ stdio: ["ignore", "pipe", "ignore"],
213
221
  }).trim();
214
222
  } catch {
215
223
  return "unknown";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.90.0",
3
+ "version": "2.90.1",
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": {
@@ -10,7 +10,9 @@
10
10
  // fails here exactly as it does in real pi, instead of silently passing.
11
11
  // See pi 0.85.1 src/core/extensions/loader.ts (createExtensionRuntime).
12
12
 
13
- import { readFileSync } from "node:fs";
13
+ import { mkdtempSync, readFileSync, rmSync } from "node:fs";
14
+ import { tmpdir } from "node:os";
15
+ import { join } from "node:path";
14
16
  import bigpowers from "../extensions/omp-hooks.ts";
15
17
 
16
18
  type AnyObj = Record<string, unknown>;
@@ -118,3 +120,27 @@ console.log(JSON.stringify({
118
120
  sendCalls,
119
121
  runDetails: runResult.details,
120
122
  }));
123
+
124
+ // Silent-probe check (BUG-2026-11-03-omp-hooks-stderr-leak, issue #189).
125
+ // The tool_call handler resolves the branch of the directory the command will
126
+ // run in. When that directory is not a repository, a git probe that inherits
127
+ // fd 2 paints "fatal: not a git repository" over the TUI. The handler must be
128
+ // invisible: validate-omp-extension.sh runs this mode with stderr captured and
129
+ // fails on any leaked git noise.
130
+ if (process.env.OMP_SMOKE_SILENT_TOOL_CALL === "1") {
131
+ const toolCall = events.get("tool_call");
132
+ if (typeof toolCall !== "function") throw new Error("tool_call handler not registered");
133
+ const nonRepo = mkdtempSync(join(tmpdir(), "omp-nonrepo-"));
134
+ try {
135
+ const verdict = await toolCall({
136
+ toolName: "bash",
137
+ input: { command: `cd ${nonRepo} && ls` },
138
+ });
139
+ // Fail-closed contract: a harmless command in a non-repo dir is not blocked.
140
+ if (verdict && (verdict as { block?: boolean }).block) {
141
+ throw new Error(`harmless command in a non-repo dir was blocked: ${JSON.stringify(verdict)}`);
142
+ }
143
+ } finally {
144
+ rmSync(nonRepo, { recursive: true, force: true });
145
+ }
146
+ }
@@ -121,6 +121,28 @@ else
121
121
  rm -f "$SMOKE_ERR"
122
122
  fi
123
123
 
124
+ # ── 7. tool_call is silent outside a repo (BUG-2026-11-03, issue #189) ────────
125
+ # A guard that inspects the command must not paint git's stderr on the agent
126
+ # TTY. The probe runs the REAL tool_call handler with a command that cds into a
127
+ # directory that is not a repository; any leaked "fatal:" lands on this
128
+ # script's captured stderr because execSync inherits fd 2.
129
+ echo "--- [OMP] tool_call stays quiet outside a git repo ---"
130
+ if [[ ! -f "$SMOKE" ]] || ! command -v node >/dev/null 2>&1; then
131
+ echo "warn: node or $SMOKE unavailable — skipping the silent-probe check"
132
+ else
133
+ SILENT_ERR=$(mktemp)
134
+ if OMP_SMOKE_SILENT_TOOL_CALL=1 node "$SMOKE" >/dev/null 2>"$SILENT_ERR"; then
135
+ if grep -qi 'fatal: not a git repository' "$SILENT_ERR"; then
136
+ ta_err "tool_call leaked git stderr onto the TUI: $(grep -i -m1 'fatal: not a git repository' "$SILENT_ERR")"
137
+ else
138
+ ta_ok "tool_call writes nothing to stderr for a non-repo target"
139
+ fi
140
+ else
141
+ ta_err "silent tool_call probe failed — $(head -3 "$SILENT_ERR" 2>/dev/null | tr '\n' ' ')"
142
+ fi
143
+ rm -f "$SILENT_ERR"
144
+ fi
145
+
124
146
  # ── Summary ────────────────────────────────────────────────────────────────
125
147
  echo "---"
126
148
  if [[ "$ERRORS" -eq 0 ]]; then