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.
- package/.gemini/extensions/bigpowers/gemini-extension.json +2 -2
- package/.pi/package.json +2 -2
- package/CHANGELOG.md +18 -0
- package/CLAUDE.md +1 -1
- package/CONVENTIONS.md +0 -1
- package/README.md +1 -1
- package/SKILL-INDEX.md +43 -44
- package/bigpowers-mcp/build/lib/git-context.js +52 -36
- package/bigpowers-mcp/build/lib/git-context.js.map +1 -1
- package/bigpowers-mcp/src/lib/git-context.ts +9 -5
- package/dashboard/src/web/client.html +15 -8
- package/dashboard/src/web/server.js +2 -1
- package/package.json +1 -1
- package/scripts/bp-read-agents.sh +7 -5
- package/scripts/generate-skill-index.sh +1 -1
- package/scripts/lib/__pycache__/link_utils.cpython-310.pyc +0 -0
- package/scripts/lib/__pycache__/srp_engine_links.cpython-310.pyc +0 -0
- package/scripts/lib/__pycache__/srp_engine_okf.cpython-310.pyc +0 -0
- package/scripts/lib/doc-fetch-cache.sh +1 -1
- package/scripts/lib/golden-suite-gates.sh +6 -0
- package/scripts/lib/migrate-version-common.sh +15 -5
- package/scripts/lib/migrate-version-plan.sh +7 -7
- package/scripts/lib/migrate-version-run.sh +3 -0
- package/scripts/lib/sync-post.sh +1 -1
- package/scripts/validate-skill-catalog.sh +1 -1
- package/skills-lock.json +0 -5
- package/tests/security/agents-import.cjs +36 -0
- package/tests/security/dashboard-bind.cjs +31 -0
- package/tests/security/dashboard-render.cjs +60 -0
- package/tests/security/git-context.cjs +44 -0
- package/tests/security/migration.cjs +76 -0
- package/.agents/skills/context7-mcp/SKILL.md +0 -55
- package/.cline/skills/context7-mcp/SKILL.md +0 -55
- package/.codebuddy/skills/context7-mcp/SKILL.md +0 -55
- package/.codex/skills/context7-mcp/SKILL.md +0 -55
- package/.continue/rules/context7-mcp.md +0 -0
- package/.copilot/skills/context7-mcp/SKILL.md +0 -55
- package/.cursor/rules/context7-mcp.mdc +0 -54
- package/.gemini/extensions/bigpowers/commands/prompts/context7-mcp.md +0 -54
- package/.gemini/extensions/bigpowers/skills/context7-mcp/SKILL.md +0 -56
- package/.hermes/skills/context7-mcp/SKILL.md +0 -55
- package/.kilocode/rules/context7-mcp.md +0 -55
- package/.mimocode/skills/context7-mcp/SKILL.md +0 -55
- package/.opencode/skills/context7-mcp/SKILL.md +0 -55
- package/.pi/prompts/context7-mcp.md +0 -54
- package/.pi/skills/context7-mcp/SKILL.md +0 -55
- package/.qwen/skills/context7-mcp/SKILL.md +0 -55
- package/.trae/skills/context7-mcp/SKILL.md +0 -55
- package/.windsurf/rules/context7-mcp.md +0 -55
- package/.zcode/skills/context7-mcp/SKILL.md +0 -55
- package/skills/context7-mcp/SKILL.md +0 -57
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bigpowers",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "
|
|
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.
|
|
4
|
-
"description": "
|
|
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
|
|
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
|

|
|
4
4
|

|
|
5
|
-

|
|
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:**
|
|
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 |
|
|
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** | **
|
|
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 | `
|
|
72
|
-
| 44 | Verify | `diagnose-
|
|
73
|
-
| 45 | Verify | `
|
|
74
|
-
| 46 | Verify | `
|
|
75
|
-
| 47 | Verify | `
|
|
76
|
-
| 48 | Verify | `
|
|
77
|
-
| 49 | Verify | `
|
|
78
|
-
| 50 | Verify | `
|
|
79
|
-
| 51 | Verify | `
|
|
80
|
-
| 52 | Verify | `
|
|
81
|
-
| 53 | Verify | `
|
|
82
|
-
| 54 | Verify | `
|
|
83
|
-
| 55 | Verify | `
|
|
84
|
-
| 56 | Verify | `
|
|
85
|
-
| 57 | Verify | `
|
|
86
|
-
| 58 | Verify | `
|
|
87
|
-
| 59 | Verify | `validate-
|
|
88
|
-
| 60 | Verify | `
|
|
89
|
-
| 61 |
|
|
90
|
-
| 62 | Release | `
|
|
91
|
-
| 63 |
|
|
92
|
-
| 64 | Sustain | `
|
|
93
|
-
| 65 | Sustain | `
|
|
94
|
-
| 66 | Sustain | `
|
|
95
|
-
| 67 | Sustain | `
|
|
96
|
-
| 68 | Sustain | `
|
|
97
|
-
| 69 | Sustain | `
|
|
98
|
-
| 70 | Sustain | `
|
|
99
|
-
| 71 | Sustain | `
|
|
100
|
-
| 72 | Sustain | `
|
|
101
|
-
| 73 | Sustain | `
|
|
102
|
-
| 74 | Sustain | `
|
|
103
|
-
| 75 | Sustain | `
|
|
104
|
-
| 76 | Sustain | `
|
|
105
|
-
| 77 | Sustain | `
|
|
106
|
-
| 78 | Sustain | `
|
|
107
|
-
| 79 | Sustain | `
|
|
108
|
-
| 80 | Sustain | `
|
|
109
|
-
|
|
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
|
-
|
|
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, [
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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 = {
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
65
|
-
|
|
65
|
+
if (current) commits.push(current);
|
|
66
|
+
return {
|
|
67
|
+
action,
|
|
68
|
+
changed_files: {},
|
|
69
|
+
commits
|
|
70
|
+
};
|
|
66
71
|
}
|
|
67
|
-
const diffOut = git(repoRoot, [
|
|
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
|
-
|
|
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
|
-
|
|
74
|
-
diffs[currentFile] = buf.join("\n");
|
|
87
|
+
flushDiff();
|
|
75
88
|
const match = / b\/(.+)$/.exec(line);
|
|
76
89
|
currentFile = match?.[1] ?? "";
|
|
77
|
-
buf = [
|
|
78
|
-
|
|
79
|
-
|
|
90
|
+
buf = [
|
|
91
|
+
line
|
|
92
|
+
];
|
|
93
|
+
} else {
|
|
80
94
|
buf.push(line);
|
|
81
95
|
}
|
|
82
96
|
}
|
|
83
|
-
|
|
84
|
-
diffs[currentFile] = buf.join("\n");
|
|
85
|
-
}
|
|
97
|
+
flushDiff();
|
|
86
98
|
const changed = Object.keys(diffs);
|
|
87
|
-
return {
|
|
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,"
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' };
|
|
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
|
@@ -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
|
-
|
|
57
|
-
if [ -n "$
|
|
58
|
-
if [ -n "$
|
|
59
|
-
if [ -n "$
|
|
60
|
-
if [ -n "$
|
|
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|
|
|
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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# story: e45s20
|
|
3
|
-
# doc-fetch-cache.sh — ETag-revalidated fetch cache for
|
|
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
|
+
|