bigpowers 2.88.17 → 2.89.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.
Files changed (51) hide show
  1. package/.gemini/extensions/bigpowers/gemini-extension.json +2 -2
  2. package/.pi/package.json +2 -2
  3. package/CHANGELOG.md +18 -0
  4. package/CLAUDE.md +1 -1
  5. package/CONVENTIONS.md +0 -1
  6. package/README.md +1 -1
  7. package/SKILL-INDEX.md +43 -44
  8. package/bigpowers-mcp/build/lib/git-context.js +52 -36
  9. package/bigpowers-mcp/build/lib/git-context.js.map +1 -1
  10. package/bigpowers-mcp/src/lib/git-context.ts +9 -5
  11. package/dashboard/src/web/client.html +15 -8
  12. package/dashboard/src/web/server.js +2 -1
  13. package/package.json +1 -1
  14. package/scripts/bp-read-agents.sh +7 -5
  15. package/scripts/generate-skill-index.sh +1 -1
  16. package/scripts/lib/__pycache__/link_utils.cpython-310.pyc +0 -0
  17. package/scripts/lib/__pycache__/srp_engine_links.cpython-310.pyc +0 -0
  18. package/scripts/lib/__pycache__/srp_engine_okf.cpython-310.pyc +0 -0
  19. package/scripts/lib/doc-fetch-cache.sh +1 -1
  20. package/scripts/lib/golden-suite-gates.sh +6 -0
  21. package/scripts/lib/migrate-version-common.sh +15 -5
  22. package/scripts/lib/migrate-version-plan.sh +7 -7
  23. package/scripts/lib/migrate-version-run.sh +3 -0
  24. package/scripts/lib/sync-post.sh +1 -1
  25. package/scripts/validate-skill-catalog.sh +1 -1
  26. package/skills-lock.json +0 -5
  27. package/tests/security/agents-import.cjs +36 -0
  28. package/tests/security/dashboard-bind.cjs +31 -0
  29. package/tests/security/dashboard-render.cjs +60 -0
  30. package/tests/security/git-context.cjs +44 -0
  31. package/tests/security/migration.cjs +76 -0
  32. package/.agents/skills/context7-mcp/SKILL.md +0 -55
  33. package/.cline/skills/context7-mcp/SKILL.md +0 -55
  34. package/.codebuddy/skills/context7-mcp/SKILL.md +0 -55
  35. package/.codex/skills/context7-mcp/SKILL.md +0 -55
  36. package/.continue/rules/context7-mcp.md +0 -0
  37. package/.copilot/skills/context7-mcp/SKILL.md +0 -55
  38. package/.cursor/rules/context7-mcp.mdc +0 -54
  39. package/.gemini/extensions/bigpowers/commands/prompts/context7-mcp.md +0 -54
  40. package/.gemini/extensions/bigpowers/skills/context7-mcp/SKILL.md +0 -56
  41. package/.hermes/skills/context7-mcp/SKILL.md +0 -55
  42. package/.kilocode/rules/context7-mcp.md +0 -55
  43. package/.mimocode/skills/context7-mcp/SKILL.md +0 -55
  44. package/.opencode/skills/context7-mcp/SKILL.md +0 -55
  45. package/.pi/prompts/context7-mcp.md +0 -54
  46. package/.pi/skills/context7-mcp/SKILL.md +0 -55
  47. package/.qwen/skills/context7-mcp/SKILL.md +0 -55
  48. package/.trae/skills/context7-mcp/SKILL.md +0 -55
  49. package/.windsurf/rules/context7-mcp.md +0 -55
  50. package/.zcode/skills/context7-mcp/SKILL.md +0 -55
  51. package/skills/context7-mcp/SKILL.md +0 -57
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.88.17",
4
- "description": "81 skills — 73 agent skills synthesizing 17 years of software engineering discipline into a prescriptive methodology for solo developers",
3
+ "version": "2.89.0",
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"
7
7
  ],
package/.pi/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.88.17",
4
- "description": "81 skills — 73 agent skills synthesizing 17 years of software engineering discipline into a prescriptive methodology for solo developers",
3
+ "version": "2.89.0",
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"
7
7
  ],
package/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ # [2.89.0](https://github.com/danielvm-git/bigpowers/compare/v2.88.18...v2.89.0) (2026-11-02)
2
+
3
+
4
+ ### Features
5
+
6
+ * **skills:** remove context7-mcp skill for provider-agnostic catalog ([#180](https://github.com/danielvm-git/bigpowers/issues/180)) ([514826b](https://github.com/danielvm-git/bigpowers/commit/514826b9c5c003aad45349e9cf54b2f09976a7ce))
7
+
8
+ ## [2.88.18](https://github.com/danielvm-git/bigpowers/compare/v2.88.17...v2.88.18) (2026-11-02)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **dashboard:** bind the project dashboard to loopback ([#175](https://github.com/danielvm-git/bigpowers/issues/175)) ([b796b17](https://github.com/danielvm-git/bigpowers/commit/b796b17f3b077a36d725018d3ad6f2fb5cc0426f))
14
+ * **dashboard:** escape project metadata before rendering HTML ([#178](https://github.com/danielvm-git/bigpowers/issues/178)) ([f905d5b](https://github.com/danielvm-git/bigpowers/commit/f905d5b30753e715d8675401aeceefa98d850476))
15
+ * **mcp:** filter every diff before returning its contents ([#174](https://github.com/danielvm-git/bigpowers/issues/174)) ([d0b9f70](https://github.com/danielvm-git/bigpowers/commit/d0b9f70a7319d396858890e2abfa1253b68837ff))
16
+ * **migrate:** treat version metadata and preview paths as data ([#177](https://github.com/danielvm-git/bigpowers/issues/177)) ([2b0649c](https://github.com/danielvm-git/bigpowers/commit/2b0649c0a8723695e2c1f078112bca3993b8b383))
17
+ * **scripts:** escape AGENTS commands when emitting Bash exports ([#176](https://github.com/danielvm-git/bigpowers/issues/176)) ([1800dd5](https://github.com/danielvm-git/bigpowers/commit/1800dd5f682cb98afdbbdce06cbcc8cae2a6eb9f))
18
+
1
19
  ## [2.88.17](https://github.com/danielvm-git/bigpowers/compare/v2.88.16...v2.88.17) (2026-10-30)
2
20
 
3
21
 
package/CLAUDE.md CHANGED
@@ -173,7 +173,7 @@ Before any task, run this sequence — not optional:
173
173
  - Search with `bts find` before opening files to locate a symbol or pattern.
174
174
  - Pipe anything > 200 lines through `bts compress` before adding to context.
175
175
  - Run `bts map` when asked for a repo overview.
176
- - Use `bts docs <lib>` before answering questions about library APIs. Doc fetches use `scripts/lib/doc-fetch-cache.sh` (ETag-revalidated, 300s TTL — see `context7-mcp` skill, e45s20).
176
+ - Use `bts docs <lib>` before answering questions about library APIs. Doc fetches use `scripts/lib/doc-fetch-cache.sh` (ETag-revalidated, 300s TTL).
177
177
  - If a tool is missing, say so and run `bts doctor` — do not silently substitute.
178
178
 
179
179
  <!-- BEGIN rtk-pretooluse-hook (e45s16 — mechanical PreToolUse backstop; remove block to disable) -->
package/CONVENTIONS.md CHANGED
@@ -380,7 +380,6 @@ name must return < 5 results across the repo.
380
380
  | `visual-dashboard` | adjective-noun | `view-dashboard` implies read-only; `show-dashboard` collides with `show` verbs |
381
381
  | `deploy` | single verb | Well-known DevOps single-word concept; renames like `deploy-app` or `deploy-service` are redundant since deploy always targets an application |
382
382
  | `grill-with-docs` | three-word verb-prep-noun | Variant of `grill-me`; the `-with-docs` suffix is the distinguishing feature — collapsing it would hide the doc-grounded contract |
383
- | `context7-mcp` | noun-noun (product + protocol) | Names the external service and protocol it fronts; a verb-noun rename (`fetch-docs`) would collide with generic doc-fetch skills and hide which provider is used |
384
383
  | `generate-allure-report` | three-word verb-noun-noun | `generate-report` is ambiguous across report types; `allure` names the specific output format consumers integrate with |
385
384
  | `simple-english` | adjective-noun | Names the recognizable STE brand users search for (`simplify-english` / `write-plain` hide intent and break searchability for users coming from the upstream skill) |
386
385
 
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
4
4
  ![npm version](https://img.shields.io/npm/v/bigpowers.svg)
5
- ![Skills](https://img.shields.io/badge/skills-81-brightgreen.svg)
5
+ ![Skills](https://img.shields.io/badge/skills-80-brightgreen.svg)
6
6
 
7
7
  **Agent skills synthesizing 17 years of software engineering discipline — from Clean Code to AI-native architecture — into a single, prescriptive methodology for solo developers.**
8
8
 
package/SKILL-INDEX.md CHANGED
@@ -3,7 +3,7 @@
3
3
  > **DO NOT EDIT** — This file is auto-generated by `scripts/generate-skill-index.sh`.
4
4
  > Edit `SKILL.md` source files or `skills-lock.json` instead. Run `bash scripts/sync-skills.sh` to regenerate.
5
5
 
6
- **Skills:** 81
6
+ **Skills:** 80
7
7
 
8
8
  ---
9
9
 
@@ -15,10 +15,10 @@
15
15
  | Design | 7 | `deepen-architecture, define-language, define-success, design-interface, grill-me, grill-with-docs, model-domain` |
16
16
  | Plan | 9 | `assess-impact, change-request, plan-refactor, plan-release, plan-work, run-planning, scope-work, seed-conventions, slice-tasks` |
17
17
  | Build | 17 | `align-grid, build-epic, craft-skill, deploy, develop-tdd, execute-plan, extract-design, guard-git, hook-commits, kickoff-branch, orchestrate-project, publish-package, quick-fix, setup-environment, spike-prototype, wire-ci, wire-observability` |
18
- | Verify | 20 | `audit-code, context7-mcp, diagnose-root, diagnose-stall, enforce-first, fix-bug, gate-trace, generate-allure-report, inspect-quality, investigate-bug, plan-tests, request-review, respond-review, run-evals, security-review, smoke-test, trace-requirement, validate-contracts, validate-fix, verify-work` |
18
+ | Verify | 19 | `audit-code, diagnose-root, diagnose-stall, enforce-first, fix-bug, gate-trace, generate-allure-report, inspect-quality, investigate-bug, plan-tests, request-review, respond-review, run-evals, security-review, smoke-test, trace-requirement, validate-contracts, validate-fix, verify-work` |
19
19
  | Release | 2 | `commit-message, release-branch` |
20
20
  | Sustain | 18 | `compose-workflow, delegate-task, dispatch-agents, edit-document, evolve-skill, harden-vps, maintain-wiki, migrate-spec, organize-workspace, reset-baseline, run-benchmark, session-state, simple-english, simulate-agents, stocktake-skills, terse-mode, visual-dashboard, write-document` |
21
- | **TOTAL** | **81** | |
21
+ | **TOTAL** | **80** | |
22
22
 
23
23
  ---
24
24
 
@@ -68,47 +68,46 @@
68
68
  | 40 | Build | `wire-ci` | "CI pipeline setup with bundled, forge-neutral templates and local validation. D | ✅ Active |
69
69
  | 41 | Build | `wire-observability` | Add structured JSON logging, observability commands, and idempotent setup script | ✅ Active |
70
70
  | 42 | Verify | `audit-code` | Self-review checklist for the coding agent to run before dispatching a reviewer. | ✅ Active |
71
- | 43 | Verify | `context7-mcp` | Fetch current library docs via Context7 MCP instead of training data. Use when u | ✅ Active |
72
- | 44 | Verify | `diagnose-root` | Run 4-phase root cause analysis — reproduce, isolate, hypothesize, verify. Use | ✅ Active |
73
- | 45 | Verify | `diagnose-stall` | Diagnose why agent orchestration stopped producing progress — silent stalls in | ✅ Active |
74
- | 46 | Verify | `enforce-first` | Apply the F.I.R.S.T test quality rubric (per CONVENTIONS.md §Tests) to a test s | ✅ Active |
75
- | 47 | Verify | `fix-bug` | Bug fix orchestrator — active_flow fix_bug; reads specs/bugs/BUG-*.md; chains | ✅ Active |
76
- | 48 | Verify | `gate-trace` | "Deterministic traceability quality gate — reads coverage matrix + blind-spot | ✅ Active |
77
- | 49 | Verify | `generate-allure-report` | "Generate Allure-ready reports from bigpowers YAML metadata. Reads execution-sta | ✅ Active |
78
- | 50 | Verify | `inspect-quality` | Interactive QA session where user reports bugs or issues conversationally, and t | ✅ Active |
79
- | 51 | Verify | `investigate-bug` | Investigate a bug or issue by exploring the codebase to find root cause, then wr | ✅ Active |
80
- | 52 | Verify | `plan-tests` | "Design a risk-scaled test architecture for an epic before implementation begins | ✅ Active |
81
- | 53 | Verify | `request-review` | Dispatch a fresh reviewer agent with a clean context to critique the code after | ✅ Active |
82
- | 54 | Verify | `respond-review` | Act on a reviewer agent's feedback systematically — categorize findings, apply | ✅ Active |
83
- | 55 | Verify | `run-evals` | Eval-Driven Development — define capability and regression evals before buildi | ✅ Active |
84
- | 56 | Verify | `security-review` | > | ✅ Active |
85
- | 57 | Verify | `smoke-test` | "Post-deploy health-check against a live URL. Validates HTTP status, response co | ✅ Active |
86
- | 58 | Verify | `trace-requirement` | Link story IDs from specs/release-plan.yaml + epic capsule directories to the im | ✅ Active |
87
- | 59 | Verify | `validate-contracts` | "Assert data shape consistency across system boundaries — live API responses a | ✅ Active |
88
- | 60 | Verify | `validate-fix` | Prove a fix works before declaring done — re-run the failing test, run the ful | ✅ Active |
89
- | 61 | Verify | `verify-work` | Multi-phase UAT gate — cold-start smoke, build, typecheck, lint, tests, step-b | ✅ Active |
90
- | 62 | Release | `commit-message` | Reviews working-tree changes, then drafts a Conventional Commits title/body and | ✅ Active |
91
- | 63 | Release | `release-branch` | Make the merge/PR/keep/discard decision for a feature branch, verify coverage ga | ✅ Active |
92
- | 64 | Sustain | `compose-workflow` | Chain multiple bigpowers skills into a custom workflow recipe saved in specs/. U | ✅ Active |
93
- | 65 | Sustain | `delegate-task` | Delegate one complex task to a single subagent, review its work in two stages be | ✅ Active |
94
- | 66 | Sustain | `dispatch-agents` | Dispatch multiple subagents in parallel on independent tasks. No waiting between | ✅ Active |
95
- | 67 | Sustain | `edit-document` | Edit and improve documents by restructuring sections, improving clarity, and tig | ✅ Active |
96
- | 68 | Sustain | `evolve-skill` | Benchmark-gated skill evolution — consume bigpowers-benchmark report, propose | ✅ Active |
97
- | 69 | Sustain | `harden-vps` | "Harden a production Linux VPS for your application across three layers — appl | ✅ Active |
98
- | 70 | Sustain | `maintain-wiki` | "Agent-maintained OKF wiki — INGEST source docs, LINT for issues, QUERY across | ✅ Active |
99
- | 71 | Sustain | `migrate-spec` | Detect GSD, spec-kit, or BMAD spec artifacts and transform them into bigpowers Y | ✅ Active |
100
- | 72 | Sustain | `organize-workspace` | Scans the active workspace for disposable artifacts—logs, caches, stale build | ✅ Active |
101
- | 73 | Sustain | `reset-baseline` | Restore the project to a known clean state between agent runs or experiments. Us | ✅ Active |
102
- | 74 | Sustain | `run-benchmark` | Run skill quality benchmarks from specs/benchmarks/ definitions — N-run with/w | ✅ Active |
103
- | 75 | Sustain | `session-state` | Track implementation decisions and progress in specs/state.yaml to prevent conte | ✅ Active |
104
- | 76 | Sustain | `simple-english` | Write or rewrite technical text with the rules of ASD-STE100 Simplified Technica | ✅ Active |
105
- | 77 | Sustain | `simulate-agents` | Run Mock User and Auditor agents against a feature in fresh contexts before huma | ✅ Active |
106
- | 78 | Sustain | `stocktake-skills` | Sequential subagent batch audit of the bigpowers skill catalog — Quick Scan (c | ✅ Active |
107
- | 79 | Sustain | `terse-mode` | Fallback ultra-compressed communication mode. Cuts token usage ~75% by dropping | ✅ Active |
108
- | 80 | Sustain | `visual-dashboard` | Start a browser-based dashboard that visualizes architecture, implementation pla | ✅ Active |
109
- | 81 | Sustain | `write-document` | Write, organize, and sync high-integrity technical documents using the BMAD meth | ✅ Active |
110
-
111
- **Total: 81 active skills.**
71
+ | 43 | Verify | `diagnose-root` | Run 4-phase root cause analysis — reproduce, isolate, hypothesize, verify. Use | ✅ Active |
72
+ | 44 | Verify | `diagnose-stall` | Diagnose why agent orchestration stopped producing progress — silent stalls in | ✅ Active |
73
+ | 45 | Verify | `enforce-first` | Apply the F.I.R.S.T test quality rubric (per CONVENTIONS.md §Tests) to a test s | ✅ Active |
74
+ | 46 | Verify | `fix-bug` | Bug fix orchestrator — active_flow fix_bug; reads specs/bugs/BUG-*.md; chains | ✅ Active |
75
+ | 47 | Verify | `gate-trace` | "Deterministic traceability quality gate — reads coverage matrix + blind-spot | ✅ Active |
76
+ | 48 | Verify | `generate-allure-report` | "Generate Allure-ready reports from bigpowers YAML metadata. Reads execution-sta | ✅ Active |
77
+ | 49 | Verify | `inspect-quality` | Interactive QA session where user reports bugs or issues conversationally, and t | ✅ Active |
78
+ | 50 | Verify | `investigate-bug` | Investigate a bug or issue by exploring the codebase to find root cause, then wr | ✅ Active |
79
+ | 51 | Verify | `plan-tests` | "Design a risk-scaled test architecture for an epic before implementation begins | ✅ Active |
80
+ | 52 | Verify | `request-review` | Dispatch a fresh reviewer agent with a clean context to critique the code after | ✅ Active |
81
+ | 53 | Verify | `respond-review` | Act on a reviewer agent's feedback systematically — categorize findings, apply | ✅ Active |
82
+ | 54 | Verify | `run-evals` | Eval-Driven Development — define capability and regression evals before buildi | ✅ Active |
83
+ | 55 | Verify | `security-review` | > | ✅ Active |
84
+ | 56 | Verify | `smoke-test` | "Post-deploy health-check against a live URL. Validates HTTP status, response co | ✅ Active |
85
+ | 57 | Verify | `trace-requirement` | Link story IDs from specs/release-plan.yaml + epic capsule directories to the im | ✅ Active |
86
+ | 58 | Verify | `validate-contracts` | "Assert data shape consistency across system boundaries — live API responses a | ✅ Active |
87
+ | 59 | Verify | `validate-fix` | Prove a fix works before declaring done — re-run the failing test, run the ful | ✅ Active |
88
+ | 60 | Verify | `verify-work` | Multi-phase UAT gate — cold-start smoke, build, typecheck, lint, tests, step-b | ✅ Active |
89
+ | 61 | Release | `commit-message` | Reviews working-tree changes, then drafts a Conventional Commits title/body and | ✅ Active |
90
+ | 62 | Release | `release-branch` | Make the merge/PR/keep/discard decision for a feature branch, verify coverage ga | ✅ Active |
91
+ | 63 | Sustain | `compose-workflow` | Chain multiple bigpowers skills into a custom workflow recipe saved in specs/. U | ✅ Active |
92
+ | 64 | Sustain | `delegate-task` | Delegate one complex task to a single subagent, review its work in two stages be | ✅ Active |
93
+ | 65 | Sustain | `dispatch-agents` | Dispatch multiple subagents in parallel on independent tasks. No waiting between | ✅ Active |
94
+ | 66 | Sustain | `edit-document` | Edit and improve documents by restructuring sections, improving clarity, and tig | ✅ Active |
95
+ | 67 | Sustain | `evolve-skill` | Benchmark-gated skill evolution — consume bigpowers-benchmark report, propose | ✅ Active |
96
+ | 68 | Sustain | `harden-vps` | "Harden a production Linux VPS for your application across three layers — appl | ✅ Active |
97
+ | 69 | Sustain | `maintain-wiki` | "Agent-maintained OKF wiki — INGEST source docs, LINT for issues, QUERY across | ✅ Active |
98
+ | 70 | Sustain | `migrate-spec` | Detect GSD, spec-kit, or BMAD spec artifacts and transform them into bigpowers Y | ✅ Active |
99
+ | 71 | Sustain | `organize-workspace` | Scans the active workspace for disposable artifacts—logs, caches, stale build | ✅ Active |
100
+ | 72 | Sustain | `reset-baseline` | Restore the project to a known clean state between agent runs or experiments. Us | ✅ Active |
101
+ | 73 | Sustain | `run-benchmark` | Run skill quality benchmarks from specs/benchmarks/ definitions — N-run with/w | ✅ Active |
102
+ | 74 | Sustain | `session-state` | Track implementation decisions and progress in specs/state.yaml to prevent conte | ✅ Active |
103
+ | 75 | Sustain | `simple-english` | Write or rewrite technical text with the rules of ASD-STE100 Simplified Technica | ✅ Active |
104
+ | 76 | Sustain | `simulate-agents` | Run Mock User and Auditor agents against a feature in fresh contexts before huma | ✅ Active |
105
+ | 77 | Sustain | `stocktake-skills` | Sequential subagent batch audit of the bigpowers skill catalog — Quick Scan (c | ✅ Active |
106
+ | 78 | Sustain | `terse-mode` | Fallback ultra-compressed communication mode. Cuts token usage ~75% by dropping | ✅ Active |
107
+ | 79 | Sustain | `visual-dashboard` | Start a browser-based dashboard that visualizes architecture, implementation pla | ✅ Active |
108
+ | 80 | Sustain | `write-document` | Write, organize, and sync high-integrity technical documents using the BMAD meth | ✅ Active |
109
+
110
+ **Total: 80 active skills.**
112
111
 
113
112
  ---
114
113
 
@@ -6,17 +6,15 @@ import { GIT_SCOPE_DIRS } from "../config.js";
6
6
  import { isSecretPath } from "./paths.js";
7
7
  function inScope(filePath) {
8
8
  const norm = filePath.replace(/\\/g, "/");
9
- if (isSecretPath(norm))
10
- return false;
11
- return GIT_SCOPE_DIRS.some((d) => norm === d || norm.startsWith(`${d}/`));
9
+ if (isSecretPath(norm)) return false;
10
+ return GIT_SCOPE_DIRS.some((d)=>norm === d || norm.startsWith(`${d}/`));
12
11
  }
13
12
  function groupByDir(files) {
14
13
  const grouped = {};
15
- for (const f of files) {
14
+ for (const f of files){
16
15
  const parts = f.split("/");
17
16
  const dir = parts.length > 1 ? parts[0] : ".";
18
- if (!grouped[dir])
19
- grouped[dir] = [];
17
+ if (!grouped[dir]) grouped[dir] = [];
20
18
  grouped[dir].push(f);
21
19
  }
22
20
  return grouped;
@@ -25,18 +23,20 @@ function git(repoRoot, args) {
25
23
  return execFileSync("git", args, {
26
24
  cwd: repoRoot,
27
25
  encoding: "utf8",
28
- maxBuffer: 10 * 1024 * 1024,
26
+ maxBuffer: 10 * 1024 * 1024
29
27
  }).trim();
30
28
  }
31
29
  export function getGitContext(repoRoot, action) {
32
30
  if (action === "status") {
33
- const out = git(repoRoot, ["status", "--porcelain"]);
34
- const files = out
35
- .split("\n")
36
- .filter(Boolean)
37
- .map((line) => line.slice(3).trim())
38
- .filter(inScope);
39
- return { action, changed_files: groupByDir(files) };
31
+ const out = git(repoRoot, [
32
+ "status",
33
+ "--porcelain"
34
+ ]);
35
+ const files = out.split("\n").filter(Boolean).map((line)=>line.slice(3).trim()).filter(inScope);
36
+ return {
37
+ action,
38
+ changed_files: groupByDir(files)
39
+ };
40
40
  }
41
41
  if (action === "log") {
42
42
  const out = git(repoRoot, [
@@ -45,48 +45,64 @@ export function getGitContext(repoRoot, action) {
45
45
  "--pretty=format:%H|%s",
46
46
  "--name-only",
47
47
  "--",
48
- ...GIT_SCOPE_DIRS,
48
+ ...GIT_SCOPE_DIRS
49
49
  ]);
50
50
  const commits = [];
51
51
  let current = null;
52
- for (const line of out.split("\n")) {
52
+ for (const line of out.split("\n")){
53
53
  if (line.includes("|")) {
54
- if (current)
55
- commits.push(current);
54
+ if (current) commits.push(current);
56
55
  const [hash, subject] = line.split("|");
57
- current = { hash, subject, files: [] };
58
- }
59
- else if (line.trim() && current && inScope(line.trim())) {
56
+ current = {
57
+ hash,
58
+ subject,
59
+ files: []
60
+ };
61
+ } else if (line.trim() && current && inScope(line.trim())) {
60
62
  current.files.push(line.trim());
61
63
  }
62
64
  }
63
- if (current)
64
- commits.push(current);
65
- return { action, changed_files: {}, commits };
65
+ if (current) commits.push(current);
66
+ return {
67
+ action,
68
+ changed_files: {},
69
+ commits
70
+ };
66
71
  }
67
- const diffOut = git(repoRoot, ["diff", "--", ...GIT_SCOPE_DIRS]);
72
+ const diffOut = git(repoRoot, [
73
+ "diff",
74
+ "--",
75
+ ...GIT_SCOPE_DIRS
76
+ ]);
68
77
  const diffs = {};
69
78
  let currentFile = "";
70
79
  let buf = [];
71
- for (const line of diffOut.split("\n")) {
80
+ const flushDiff = ()=>{
81
+ if (currentFile && buf.length && inScope(currentFile)) {
82
+ diffs[currentFile] = buf.join("\n");
83
+ }
84
+ };
85
+ for (const line of diffOut.split("\n")){
72
86
  if (line.startsWith("diff --git")) {
73
- if (currentFile && buf.length)
74
- diffs[currentFile] = buf.join("\n");
87
+ flushDiff();
75
88
  const match = / b\/(.+)$/.exec(line);
76
89
  currentFile = match?.[1] ?? "";
77
- buf = [line];
78
- }
79
- else {
90
+ buf = [
91
+ line
92
+ ];
93
+ } else {
80
94
  buf.push(line);
81
95
  }
82
96
  }
83
- if (currentFile && buf.length && inScope(currentFile) && !isSecretPath(currentFile)) {
84
- diffs[currentFile] = buf.join("\n");
85
- }
97
+ flushDiff();
86
98
  const changed = Object.keys(diffs);
87
- return { action, changed_files: groupByDir(changed), diffs };
99
+ return {
100
+ action,
101
+ changed_files: groupByDir(changed),
102
+ diffs
103
+ };
88
104
  }
89
105
  export function isGitRepo(repoRoot) {
90
106
  return fs.existsSync(path.join(repoRoot, ".git"));
91
107
  }
92
- //# sourceMappingURL=git-context.js.map
108
+ //# sourceMappingURL=git-context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"git-context.js","sourceRoot":"","sources":["../../src/lib/git-context.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAmB,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAS1C,SAAS,OAAO,CAAC,QAAgB;IAC/B,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC1C,IAAI,YAAY,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,UAAU,CAAC,KAAe;IACjC,MAAM,OAAO,GAA6B,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,GAAG,CAAC,QAAgB,EAAE,IAAc;IAC3C,OAAO,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE;QAC/B,GAAG,EAAE,QAAQ;QACb,QAAQ,EAAE,MAAM;QAChB,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;KAC5B,CAAC,CAAC,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,MAAiC;IAC/E,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,GAAG;aACd,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACnC,MAAM,CAAC,OAAO,CAAC,CAAC;QACnB,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;IACtD,CAAC;IAED,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,EAAE;YACxB,KAAK;YACL,KAAK;YACL,uBAAuB;YACvB,aAAa;YACb,IAAI;YACJ,GAAG,cAAc;SAClB,CAAC,CAAC;QACH,MAAM,OAAO,GAAgC,EAAE,CAAC;QAChD,IAAI,OAAO,GAA8D,IAAI,CAAC;QAC9E,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,IAAI,OAAO;oBAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACnC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACxC,OAAO,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;YACzC,CAAC;iBAAM,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;gBAC1D,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QACD,IAAI,OAAO;YAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;IAChD,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC;IACjE,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,IAAI,GAAG,GAAa,EAAE,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAClC,IAAI,WAAW,IAAI,GAAG,CAAC,MAAM;gBAAE,KAAK,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnE,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrC,WAAW,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/B,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QACf,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,IAAI,WAAW,IAAI,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC;QACpF,KAAK,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AACpD,CAAC"}
1
+ {"version":3,"sources":["../../src/lib/git-context.ts"],"names":[],"mappings":"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","file":"git-context.js","sourceRoot":""}
@@ -2,7 +2,7 @@
2
2
  import { execFileSync } from "node:child_process";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
- import { GIT_SCOPE_DIRS, SECRET_DENYLIST } from "../config.js";
5
+ import { GIT_SCOPE_DIRS } from "../config.js";
6
6
  import { isSecretPath } from "./paths.js";
7
7
 
8
8
  export interface GitContextResult {
@@ -76,9 +76,14 @@ export function getGitContext(repoRoot: string, action: "status" | "log" | "diff
76
76
  const diffs: Record<string, string> = {};
77
77
  let currentFile = "";
78
78
  let buf: string[] = [];
79
+ const flushDiff = () => {
80
+ if (currentFile && buf.length && inScope(currentFile)) {
81
+ diffs[currentFile] = buf.join("\n");
82
+ }
83
+ };
79
84
  for (const line of diffOut.split("\n")) {
80
85
  if (line.startsWith("diff --git")) {
81
- if (currentFile && buf.length) diffs[currentFile] = buf.join("\n");
86
+ flushDiff();
82
87
  const match = / b\/(.+)$/.exec(line);
83
88
  currentFile = match?.[1] ?? "";
84
89
  buf = [line];
@@ -86,9 +91,7 @@ export function getGitContext(repoRoot: string, action: "status" | "log" | "diff
86
91
  buf.push(line);
87
92
  }
88
93
  }
89
- if (currentFile && buf.length && inScope(currentFile) && !isSecretPath(currentFile)) {
90
- diffs[currentFile] = buf.join("\n");
91
- }
94
+ flushDiff();
92
95
 
93
96
  const changed = Object.keys(diffs);
94
97
  return { action, changed_files: groupByDir(changed), diffs };
@@ -97,3 +100,4 @@ export function getGitContext(repoRoot: string, action: "status" | "log" | "diff
97
100
  export function isGitRepo(repoRoot: string): boolean {
98
101
  return fs.existsSync(path.join(repoRoot, ".git"));
99
102
  }
103
+
@@ -218,6 +218,12 @@
218
218
  let eventSource = null;
219
219
  let pollInterval = null;
220
220
 
221
+ // Project metadata belongs in HTML text content, never in markup.
222
+ function escapeHtml(value) {
223
+ const entities = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };
224
+ return String(value).replace(/[&<>"']/g, char => entities[char]);
225
+ }
226
+
221
227
  function render(data) {
222
228
  if (!data) return;
223
229
  renderPipeline(data);
@@ -246,14 +252,14 @@
246
252
 
247
253
  let html = '';
248
254
  if (metrics) {
249
- html += `<div class="metric-row"><span class="metric-label">Total BCPs</span><span class="metric-value">${metrics.totalBcps}</span></div>`;
255
+ html += `<div class="metric-row"><span class="metric-label">Total BCPs</span><span class="metric-value">${escapeHtml(metrics.totalBcps)}</span></div>`;
250
256
  html += `<div class="metric-row"><span class="metric-label">Avg BCP/Hour</span><span class="metric-value">${metrics.avgBcpPerHour.toFixed(2)}</span></div>`;
251
257
  }
252
258
  if (velocity) {
253
259
  html += `<div class="metric-row"><span class="metric-label">Current Velocity</span><span class="metric-value">${velocity.avgBcpPerHour.toFixed(2)} BCP/h</span></div>`;
254
260
  }
255
261
  if (data.state?.release?.version) {
256
- html += `<div class="metric-row"><span class="metric-label">Version</span><span class="metric-value">${data.state.release.version}</span></div>`;
262
+ html += `<div class="metric-row"><span class="metric-label">Version</span><span class="metric-value">${escapeHtml(data.state.release.version)}</span></div>`;
257
263
  }
258
264
  if (timestamp) {
259
265
  html += `<div class="metric-row"><span class="metric-label">Updated</span><span class="metric-value" style="font-size: 10px;">${new Date(timestamp).toLocaleTimeString()}</span></div>`;
@@ -271,7 +277,7 @@
271
277
  { key: 'Git Branch', value: state.gitBranch }
272
278
  ];
273
279
  container.innerHTML = pairs.map(pair => {
274
- const val = pair.value || '(none)';
280
+ const val = escapeHtml(pair.value || '(none)');
275
281
  return `<div class="state-pair"><span class="state-key">${pair.key}</span><span class="state-value">${val}</span></div>`;
276
282
  }).join('');
277
283
  }
@@ -288,8 +294,8 @@
288
294
  const storyCount = stories.length;
289
295
  return `
290
296
  <div class="epic-item">
291
- <div class="epic-title">${epic.id || 'Unknown'}</div>
292
- <div style="color: var(--ink-soft); font-size: 11px; margin-bottom: 0;">${epic.title || 'Untitled'}</div>
297
+ <div class="epic-title">${escapeHtml(epic.id || 'Unknown')}</div>
298
+ <div style="color: var(--ink-soft); font-size: 11px; margin-bottom: 0;">${escapeHtml(epic.title || 'Untitled')}</div>
293
299
  <div class="epic-stories">${storyCount} stories</div>
294
300
  </div>
295
301
  `;
@@ -308,10 +314,10 @@
308
314
  const end = row.end ? new Date(row.end).toLocaleDateString() : '(active)';
309
315
  return `
310
316
  <div class="ledger-row">
311
- <div class="ledger-id">${row.id}</div>
317
+ <div class="ledger-id">${escapeHtml(row.id)}</div>
312
318
  <div style="text-align: right;">
313
- <div class="ledger-value">${row.bcps} BCP</div>
314
- <div class="ledger-meta">${row.cycleMin}min | ${row.bcpPerHour.toFixed(2)}/h</div>
319
+ <div class="ledger-value">${escapeHtml(row.bcps)} BCP</div>
320
+ <div class="ledger-meta">${escapeHtml(row.cycleMin)}min | ${row.bcpPerHour.toFixed(2)}/h</div>
315
321
  </div>
316
322
  </div>
317
323
  `;
@@ -417,3 +423,4 @@
417
423
  </script>
418
424
  </body>
419
425
  </html>
426
+
@@ -104,9 +104,10 @@ function createServer(projectRoot, port = 7742) {
104
104
 
105
105
  return {
106
106
  listen(portNum = port, cb) {
107
- return app.listen(portNum, cb);
107
+ return app.listen(portNum, '127.0.0.1', cb);
108
108
  }
109
109
  };
110
110
  }
111
111
 
112
112
  module.exports = { createServer };
113
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigpowers",
3
- "version": "2.88.17",
3
+ "version": "2.89.0",
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": {
@@ -53,9 +53,11 @@ if $PRINT_MODE; then
53
53
  if [ -n "$BP_LINT" ]; then echo "Lint: $BP_LINT"; fi
54
54
  if [ -n "$BP_DEPLOY" ]; then echo "Deploy: $BP_DEPLOY"; fi
55
55
  else
56
- if [ -n "$BP_PREFLIGHT" ]; then echo "export BP_PREFLIGHT='$BP_PREFLIGHT'"; fi
57
- if [ -n "$BP_TEST" ]; then echo "export BP_TEST='$BP_TEST'"; fi
58
- if [ -n "$BP_BUILD" ]; then echo "export BP_BUILD='$BP_BUILD'"; fi
59
- if [ -n "$BP_LINT" ]; then echo "export BP_LINT='$BP_LINT'"; fi
60
- if [ -n "$BP_DEPLOY" ]; then echo "export BP_DEPLOY='$BP_DEPLOY'"; fi
56
+ # Bash %q preserves the command as data when the caller evaluates exports.
57
+ if [ -n "$BP_PREFLIGHT" ]; then printf 'export BP_PREFLIGHT=%q\n' "$BP_PREFLIGHT"; fi
58
+ if [ -n "$BP_TEST" ]; then printf 'export BP_TEST=%q\n' "$BP_TEST"; fi
59
+ if [ -n "$BP_BUILD" ]; then printf 'export BP_BUILD=%q\n' "$BP_BUILD"; fi
60
+ if [ -n "$BP_LINT" ]; then printf 'export BP_LINT=%q\n' "$BP_LINT"; fi
61
+ if [ -n "$BP_DEPLOY" ]; then printf 'export BP_DEPLOY=%q\n' "$BP_DEPLOY"; fi
61
62
  fi
63
+
@@ -44,7 +44,7 @@ phase_of() {
44
44
  # Build
45
45
  develop-tdd|kickoff-branch|execute-plan|build-epic|spike-prototype|craft-skill|quick-fix|setup-environment|wire-observability|wire-ci|publish-package|align-grid|orchestrate-project|guard-git|hook-commits|deploy|smoke-test|validate-contracts|extract-design) echo "Build" ;;
46
46
  # Verify
47
- verify-work|validate-fix|audit-code|enforce-first|run-evals|investigate-bug|diagnose-root|fix-bug|inspect-quality|request-review|respond-review|trace-requirement|security-review|context7-mcp|diagnose-stall|gate-trace|generate-allure-report|plan-tests) echo "Verify" ;;
47
+ verify-work|validate-fix|audit-code|enforce-first|run-evals|investigate-bug|diagnose-root|fix-bug|inspect-quality|request-review|respond-review|trace-requirement|security-review|diagnose-stall|gate-trace|generate-allure-report|plan-tests) echo "Verify" ;;
48
48
  # Release
49
49
  release-branch|commit-message) echo "Release" ;;
50
50
  # Sustain
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bash
2
2
  # story: e45s20
3
- # doc-fetch-cache.sh — ETag-revalidated fetch cache for Context7 / bts docs queries.
3
+ # doc-fetch-cache.sh — ETag-revalidated fetch cache for bts docs queries.
4
4
  # Usage:
5
5
  # bash scripts/lib/doc-fetch-cache.sh get <cache-key> # print cached body or empty
6
6
  # bash scripts/lib/doc-fetch-cache.sh put <key> <etag> <body-file>
@@ -9,6 +9,7 @@ GOLDEN_GATES=(
9
9
  "compliance:npm run compliance:false"
10
10
  "g04-selftest:bash scripts/golden-g04-selftest.sh:true"
11
11
  "g06-migrate-version:bash tests/run-golden-migrate-version.sh:true"
12
+ "security-migration:node tests/security/migration.cjs:false"
12
13
  "g07-negative-path:bash scripts/golden-g07-negative-path.sh:false"
13
14
  "g08-anti-vacuity:bash scripts/golden-g08-anti-vacuity.sh:false"
14
15
  "g09-yaml-roundtrip:bash scripts/golden-g09-yaml-roundtrip.sh:false"
@@ -66,10 +67,14 @@ GOLDEN_GATES=(
66
67
  "golden-g11-worktree-venv:bash scripts/test-golden-g11-worktree-venv.sh:false"
67
68
  "install-helpers:bash scripts/test-install-helpers.sh:false"
68
69
  "project-runtime:bash scripts/test-project-runtime.sh:false"
70
+ "security-agents-import:node tests/security/agents-import.cjs:false"
69
71
  "omp-extension:bash scripts/validate-omp-extension.sh:false"
70
72
  "mcp-package:bash scripts/validate-mcp-package.sh:false"
73
+ "security-git-context:node tests/security/git-context.cjs:false"
71
74
  "docs-base-path:bash scripts/validate-docs-base-path.sh:false"
75
+ "security-dashboard-bind:node tests/security/dashboard-bind.cjs:false"
72
76
  "import-boundaries:bash scripts/check-import-boundaries.sh:false"
77
+ "security-dashboard-render:node tests/security/dashboard-render.cjs:false"
73
78
  "skill-catalog:bash scripts/validate-skill-catalog.sh:false"
74
79
  "specs-parse:bash scripts/validate-specs-yaml.sh:false"
75
80
  # The runner itself: failing output is shown, skips are named and reasoned.
@@ -204,3 +209,4 @@ golden_run_deterministic_gates() {
204
209
  fi
205
210
  done
206
211
  }
212
+