proof-pr 0.1.13 → 0.1.14

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 (3) hide show
  1. package/README.md +9 -2
  2. package/dist/index.js +195 -6
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -12,7 +12,7 @@ ProofPR 是给开源维护者和工程团队使用的 PR 证据门禁。它在
12
12
  npx proof-pr@latest --version
13
13
  ```
14
14
 
15
- 当前应输出 `0.1.13`。
15
+ 当前应输出 `0.1.14`。
16
16
 
17
17
  不知道用哪个功能时:
18
18
 
@@ -22,6 +22,13 @@ npx proof-pr@latest
22
22
  npx proof-pr@latest guide
23
23
  ```
24
24
 
25
+ 不接入仓库,先体验报告:
26
+
27
+ ```bash
28
+ npx proof-pr@latest demo workflow --locale zh-CN
29
+ npx proof-pr@latest demo --list
30
+ ```
31
+
25
32
  初始化配置和 GitHub Action:
26
33
 
27
34
  ```bash
@@ -65,7 +72,7 @@ npx proof-pr@latest benchmark --cases benchmarks/cases
65
72
  ## GitHub Action
66
73
 
67
74
  ```yaml
68
- - uses: linsk27/proof-pr@v0.1.13
75
+ - uses: linsk27/proof-pr@v0.1.14
69
76
  with:
70
77
  fail-on: high
71
78
  comment: "true"
package/dist/index.js CHANGED
@@ -25728,7 +25728,131 @@ function dedupeFindings(findings) {
25728
25728
 
25729
25729
 
25730
25730
  const execFileAsync = (0,external_node_util_namespaceObject.promisify)(external_node_child_process_.execFile);
25731
- const CLI_VERSION = "0.1.13";
25731
+ const CLI_VERSION = "0.1.14";
25732
+ const DEMO_CASES = [
25733
+ {
25734
+ id: "workflow",
25735
+ title: "高权限 workflow 运行不可信 PR 代码",
25736
+ description: "演示 pull_request_target 与 PR head checkout 组合风险。",
25737
+ diffText: `diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
25738
+ index 1111111..2222222 100644
25739
+ --- a/.github/workflows/pr.yml
25740
+ +++ b/.github/workflows/pr.yml
25741
+ @@ -1,7 +1,17 @@
25742
+ name: PR automation
25743
+ on:
25744
+ + pull_request_target:
25745
+ + types: [opened, synchronize]
25746
+ +
25747
+ jobs:
25748
+ test:
25749
+ runs-on: ubuntu-latest
25750
+ steps:
25751
+ - - uses: actions/checkout@v4
25752
+ + - uses: actions/checkout@v4
25753
+ + with:
25754
+ + repository: \${{ github.event.pull_request.head.repo.full_name }}
25755
+ + ref: \${{ github.event.pull_request.head.sha }}
25756
+ + - run: pnpm install
25757
+ + - run: pnpm test
25758
+ `
25759
+ },
25760
+ {
25761
+ id: "secret",
25762
+ title: "疑似 secret 被提交",
25763
+ description: "演示 .env、OpenAI key、数据库连接串等敏感内容会被拦截。",
25764
+ diffText: `diff --git a/.env b/.env
25765
+ new file mode 100644
25766
+ index 0000000..1111111
25767
+ --- /dev/null
25768
+ +++ b/.env
25769
+ @@ -0,0 +1,2 @@
25770
+ +OPENAI_API_KEY=sk-proj-examplevalueexamplevalue1234567890
25771
+ +DATABASE_URL=postgres://demo:super-secret-password@example.com:5432/app
25772
+ `
25773
+ },
25774
+ {
25775
+ id: "dependency",
25776
+ title: "依赖大版本升级",
25777
+ description: "演示依赖 major upgrade 需要 changelog、迁移说明和验证证据。",
25778
+ diffText: `diff --git a/package.json b/package.json
25779
+ index 1111111..2222222 100644
25780
+ --- a/package.json
25781
+ +++ b/package.json
25782
+ @@ -1,8 +1,8 @@
25783
+ {
25784
+ "dependencies": {
25785
+ - "react": "^18.2.0",
25786
+ + "react": "^19.0.0",
25787
+ "zod": "^3.25.1"
25788
+ },
25789
+ "devDependencies": {
25790
+ "typescript": "^5.9.3"
25791
+ }
25792
+ }
25793
+ `
25794
+ },
25795
+ {
25796
+ id: "mcp",
25797
+ title: "MCP 本地命令和凭据面",
25798
+ description: "演示 MCP / agent 配置中的 command、args、env 风险。",
25799
+ diffText: `diff --git a/.cursor/mcp.json b/.cursor/mcp.json
25800
+ new file mode 100644
25801
+ index 0000000..1111111
25802
+ --- /dev/null
25803
+ +++ b/.cursor/mcp.json
25804
+ @@ -0,0 +1,11 @@
25805
+ +{
25806
+ + "mcpServers": {
25807
+ + "local-admin": {
25808
+ + "command": "node",
25809
+ + "args": ["scripts/admin-server.js"],
25810
+ + "env": {
25811
+ + "API_TOKEN": "\${LOCAL_API_TOKEN}"
25812
+ + }
25813
+ + }
25814
+ + }
25815
+ +}
25816
+ `,
25817
+ config: { preset: "mcp-security" }
25818
+ },
25819
+ {
25820
+ id: "ui-evidence",
25821
+ title: "UI 改动缺少截图证据",
25822
+ description: "演示 Evidence Contract:组件改动必须提供截图和验证说明。",
25823
+ diffText: `diff --git a/src/components/Button.tsx b/src/components/Button.tsx
25824
+ index 1111111..2222222 100644
25825
+ --- a/src/components/Button.tsx
25826
+ +++ b/src/components/Button.tsx
25827
+ @@ -1,3 +1,7 @@
25828
+ export function Button() {
25829
+ - return <button>Save</button>;
25830
+ + return (
25831
+ + <button className="primary">
25832
+ + Save
25833
+ + </button>
25834
+ + );
25835
+ }
25836
+ `,
25837
+ config: {
25838
+ evidence: {
25839
+ contracts: [
25840
+ {
25841
+ id: "ui-screenshot",
25842
+ title: "UI changes need screenshots",
25843
+ paths: ["src/components/**"],
25844
+ requires: ["screenshot", "verification"],
25845
+ severity: "medium"
25846
+ }
25847
+ ]
25848
+ }
25849
+ },
25850
+ pullRequest: {
25851
+ title: "Update button styling",
25852
+ body: "This updates the primary button style and spacing so the layout is easier to scan."
25853
+ }
25854
+ }
25855
+ ];
25732
25856
  const build_program = new Command();
25733
25857
  build_program
25734
25858
  .name("proof-pr")
@@ -25754,6 +25878,37 @@ build_program
25754
25878
  process.exitCode = 1;
25755
25879
  }
25756
25880
  });
25881
+ build_program
25882
+ .command("demo")
25883
+ .description("Run a built-in ProofPR demo case without cloning this repository.")
25884
+ .argument("[case]", "Demo case id. Use --list to see available cases.", "workflow")
25885
+ .option("--list", "List built-in demo cases.", false)
25886
+ .option("--format <format>", "Output format: markdown, json, sarif, or html.", parseFormat, "markdown")
25887
+ .option("--output <path>", "Write demo report output to a file instead of stdout.")
25888
+ .option("--locale <locale>", "Report language: en or zh-CN.", "zh-CN")
25889
+ .action(async (caseId, options) => {
25890
+ if (options.list) {
25891
+ process.stdout.write(renderDemoList());
25892
+ return;
25893
+ }
25894
+ const demoCase = DEMO_CASES.find((item) => item.id === caseId);
25895
+ if (!demoCase) {
25896
+ throw new Error(`Unknown demo case "${caseId}". Run "proof-pr demo --list" to see available cases.`);
25897
+ }
25898
+ const result = scanDiff(demoCase.diffText, {
25899
+ config: demoCase.config,
25900
+ pullRequest: demoCase.pullRequest
25901
+ });
25902
+ const locale = parseLocale(options.locale, "zh-CN");
25903
+ const output = renderDemoOutput(demoCase, result, options.format, locale);
25904
+ if (options.output) {
25905
+ await writeOutput(options.output, `${output}\n`);
25906
+ process.stdout.write(`ProofPR demo ${options.format} report written to ${options.output}\n`);
25907
+ }
25908
+ else {
25909
+ process.stdout.write(`${output}\n`);
25910
+ }
25911
+ });
25757
25912
  build_program
25758
25913
  .command("scan", { isDefault: true })
25759
25914
  .description("Scan a git diff and print a ProofPR report.")
@@ -25867,15 +26022,18 @@ function renderGuide() {
25867
26022
  npx proof-pr@latest scan --base origin/main --head HEAD --format sarif --output proofpr.sarif
25868
26023
  适合在 CI 里配合 github/codeql-action/upload-sarif 使用。
25869
26024
 
25870
- 6. 试跑内置风险案例
25871
- npx proof-pr@latest scan --diff-file examples/cases/workflow-untrusted-checkout.diff --locale zh-CN
25872
- 不需要改项目代码,也能快速看到 ProofPR 会抓什么风险。
26025
+ 6. 不接入仓库,先试跑内置案例
26026
+ npx proof-pr@latest demo workflow --locale zh-CN
26027
+ 不需要 clone 仓库或寻找 examples 文件,也能快速看到 ProofPR 会抓什么风险。
25873
26028
 
25874
- 7. 验证规则样本是否仍然命中
26029
+ 7. 查看所有内置案例
26030
+ npx proof-pr@latest demo --list
26031
+
26032
+ 8. 验证规则样本是否仍然命中
25875
26033
  npx proof-pr@latest benchmark --cases benchmarks/cases
25876
26034
  适合维护 ProofPR 规则或发版前回归。
25877
26035
 
25878
- 8. 调整审查强度
26036
+ 9. 调整审查强度
25879
26037
  打开 .proofpr.yml,把 preset 改成 security-strict、dependency-careful 或 mcp-security。
25880
26038
 
25881
26039
  结果在哪里看:
@@ -25883,6 +26041,37 @@ function renderGuide() {
25883
26041
  - 本地 CLI:终端输出;如果用了 --output,就看写出的 HTML / JSON / SARIF / Markdown 文件。
25884
26042
  `;
25885
26043
  }
26044
+ function renderDemoList() {
26045
+ const rows = DEMO_CASES.map((item) => `- ${item.id}: ${item.title}\n ${item.description}`).join("\n");
26046
+ return `ProofPR 内置案例
26047
+
26048
+ 用法:
26049
+ npx proof-pr@latest demo <case> --locale zh-CN
26050
+
26051
+ 可用案例:
26052
+ ${rows}
26053
+ `;
26054
+ }
26055
+ function renderDemoOutput(demoCase, result, format, locale) {
26056
+ if (format === "json") {
26057
+ return JSON.stringify({
26058
+ demo: {
26059
+ id: demoCase.id,
26060
+ title: demoCase.title,
26061
+ description: demoCase.description
26062
+ },
26063
+ result
26064
+ }, null, 2);
26065
+ }
26066
+ if (format === "markdown") {
26067
+ return `# ProofPR demo: ${demoCase.title}
26068
+
26069
+ ${demoCase.description}
26070
+
26071
+ ${renderMarkdownReport(result, locale)}`;
26072
+ }
26073
+ return renderOutput(result, format, locale);
26074
+ }
25886
26075
  async function runDoctor(options) {
25887
26076
  const checks = [];
25888
26077
  const nextSteps = new Set();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "proof-pr",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "description": "CLI for ProofPR, a maintainer-focused pull request evidence scanner.",
5
5
  "license": "MIT",
6
6
  "type": "module",