prr-kit 1.1.3 → 1.2.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.
- package/LICENSE +1 -1
- package/README.md +260 -235
- package/docs/assets/banner.svg +30 -248
- package/docs/assets/how-it-works.svg +87 -0
- package/package.json +60 -60
- package/src/core/agents/prr-master.agent.yaml +18 -7
- package/src/core/tasks/clear.md +140 -0
- package/src/core/tasks/help.md +15 -13
- package/src/core/workflows/clear/workflow.md +6 -0
- package/src/core/workflows/help/workflow.md +6 -0
- package/src/core/workflows/party-mode/steps/step-01-load-reviewers.md +35 -24
- package/src/core/workflows/party-mode/steps/step-02-discussion.md +45 -25
- package/src/core/workflows/party-mode/workflow.md +2 -2
- package/src/prr/agents/architecture-reviewer.agent.yaml +65 -45
- package/src/prr/agents/business-reviewer.agent.yaml +66 -0
- package/src/prr/agents/general-reviewer.agent.yaml +64 -48
- package/src/prr/agents/performance-reviewer.agent.yaml +65 -45
- package/src/prr/agents/security-reviewer.agent.yaml +67 -43
- package/src/prr/config-template.yaml +97 -0
- package/src/prr/data/stacks/actix.md +55 -0
- package/src/prr/data/stacks/alpine.md +47 -0
- package/src/prr/data/stacks/android.md +53 -0
- package/src/prr/data/stacks/angular.md +96 -0
- package/src/prr/data/stacks/ansible.md +55 -0
- package/src/prr/data/stacks/apollo.md +54 -0
- package/src/prr/data/stacks/astro.md +48 -0
- package/src/prr/data/stacks/aws-cdk.md +55 -0
- package/src/prr/data/stacks/axum.md +56 -0
- package/src/prr/data/stacks/babylonjs.md +55 -0
- package/src/prr/data/stacks/bash.md +53 -0
- package/src/prr/data/stacks/bevy.md +53 -0
- package/src/prr/data/stacks/bootstrap.md +52 -0
- package/src/prr/data/stacks/bun.md +55 -0
- package/src/prr/data/stacks/cpp.md +57 -0
- package/src/prr/data/stacks/csharp.md +95 -0
- package/src/prr/data/stacks/css.md +55 -0
- package/src/prr/data/stacks/cypress.md +53 -0
- package/src/prr/data/stacks/d3.md +53 -0
- package/src/prr/data/stacks/deno.md +49 -0
- package/src/prr/data/stacks/django.md +92 -0
- package/src/prr/data/stacks/docker.md +79 -0
- package/src/prr/data/stacks/drizzle.md +54 -0
- package/src/prr/data/stacks/dynamodb.md +55 -0
- package/src/prr/data/stacks/electron.md +44 -0
- package/src/prr/data/stacks/elixir.md +53 -0
- package/src/prr/data/stacks/expo.md +53 -0
- package/src/prr/data/stacks/expressjs.md +82 -0
- package/src/prr/data/stacks/fastapi.md +88 -0
- package/src/prr/data/stacks/fastify.md +60 -0
- package/src/prr/data/stacks/fiber.md +55 -0
- package/src/prr/data/stacks/firebase.md +43 -0
- package/src/prr/data/stacks/flask.md +46 -0
- package/src/prr/data/stacks/flutter.md +75 -0
- package/src/prr/data/stacks/gin.md +57 -0
- package/src/prr/data/stacks/github-actions.md +71 -0
- package/src/prr/data/stacks/go.md +88 -0
- package/src/prr/data/stacks/godot.md +56 -0
- package/src/prr/data/stacks/graphql.md +76 -0
- package/src/prr/data/stacks/grpc.md +56 -0
- package/src/prr/data/stacks/haskell.md +48 -0
- package/src/prr/data/stacks/helm.md +54 -0
- package/src/prr/data/stacks/hono.md +54 -0
- package/src/prr/data/stacks/htmx.md +38 -0
- package/src/prr/data/stacks/java.md +87 -0
- package/src/prr/data/stacks/jest-vitest.md +87 -0
- package/src/prr/data/stacks/jquery.md +50 -0
- package/src/prr/data/stacks/junit.md +53 -0
- package/src/prr/data/stacks/kotlin.md +89 -0
- package/src/prr/data/stacks/kubernetes.md +148 -0
- package/src/prr/data/stacks/langchain.md +56 -0
- package/src/prr/data/stacks/laravel.md +56 -0
- package/src/prr/data/stacks/libgdx.md +46 -0
- package/src/prr/data/stacks/lit.md +49 -0
- package/src/prr/data/stacks/love2d.md +51 -0
- package/src/prr/data/stacks/lua.md +51 -0
- package/src/prr/data/stacks/mobx.md +54 -0
- package/src/prr/data/stacks/mongodb.md +85 -0
- package/src/prr/data/stacks/monogame.md +51 -0
- package/src/prr/data/stacks/mysql.md +57 -0
- package/src/prr/data/stacks/nestjs.md +95 -0
- package/src/prr/data/stacks/nextjs.md +88 -0
- package/src/prr/data/stacks/nginx.md +55 -0
- package/src/prr/data/stacks/node.md +56 -0
- package/src/prr/data/stacks/nuxtjs.md +91 -0
- package/src/prr/data/stacks/openai-api.md +54 -0
- package/src/prr/data/stacks/opengl.md +54 -0
- package/src/prr/data/stacks/phaser.md +54 -0
- package/src/prr/data/stacks/phoenix.md +55 -0
- package/src/prr/data/stacks/php.md +56 -0
- package/src/prr/data/stacks/playwright.md +86 -0
- package/src/prr/data/stacks/postgresql.md +60 -0
- package/src/prr/data/stacks/prisma.md +81 -0
- package/src/prr/data/stacks/pygame.md +52 -0
- package/src/prr/data/stacks/pytest.md +53 -0
- package/src/prr/data/stacks/python.md +94 -0
- package/src/prr/data/stacks/pytorch.md +54 -0
- package/src/prr/data/stacks/qwik.md +50 -0
- package/src/prr/data/stacks/rails.md +48 -0
- package/src/prr/data/stacks/react-native.md +77 -0
- package/src/prr/data/stacks/react.md +104 -0
- package/src/prr/data/stacks/redis.md +76 -0
- package/src/prr/data/stacks/redux.md +107 -0
- package/src/prr/data/stacks/remix.md +51 -0
- package/src/prr/data/stacks/rust.md +88 -0
- package/src/prr/data/stacks/sass.md +51 -0
- package/src/prr/data/stacks/scala.md +50 -0
- package/src/prr/data/stacks/scikit-learn.md +53 -0
- package/src/prr/data/stacks/sequelize.md +54 -0
- package/src/prr/data/stacks/socket-io.md +54 -0
- package/src/prr/data/stacks/solidity.md +53 -0
- package/src/prr/data/stacks/solidjs.md +45 -0
- package/src/prr/data/stacks/spring-boot.md +92 -0
- package/src/prr/data/stacks/sql.md +85 -0
- package/src/prr/data/stacks/sqlite.md +55 -0
- package/src/prr/data/stacks/styled-components.md +51 -0
- package/src/prr/data/stacks/supabase.md +57 -0
- package/src/prr/data/stacks/svelte.md +77 -0
- package/src/prr/data/stacks/sveltekit.md +54 -0
- package/src/prr/data/stacks/swift.md +61 -0
- package/src/prr/data/stacks/tailwindcss.md +10 -0
- package/src/prr/data/stacks/tanstack-query.md +48 -0
- package/src/prr/data/stacks/tauri.md +52 -0
- package/src/prr/data/stacks/terraform.md +53 -0
- package/src/prr/data/stacks/three.md +53 -0
- package/src/prr/data/stacks/trpc.md +49 -0
- package/src/prr/data/stacks/typeorm.md +40 -0
- package/src/prr/data/stacks/typescript.md +83 -0
- package/src/prr/data/stacks/unity.md +61 -0
- package/src/prr/data/stacks/unreal.md +58 -0
- package/src/prr/data/stacks/vite.md +48 -0
- package/src/prr/data/stacks/vue3.md +95 -0
- package/src/prr/data/stacks/vulkan.md +53 -0
- package/src/prr/data/stacks/wasm.md +49 -0
- package/src/prr/data/stacks/webpack.md +48 -0
- package/src/prr/data/stacks/zig.md +51 -0
- package/src/prr/data/stacks/zustand.md +56 -0
- package/src/prr/workflows/1-discover/select-pr/steps/step-05-confirm.md +1 -0
- package/src/prr/workflows/1-discover/select-pr/workflow.md +1 -1
- package/src/prr/workflows/2-analyze/collect-pr-context/steps/step-01-analyze-files.md +334 -0
- package/src/prr/workflows/2-analyze/collect-pr-context/steps/step-02-collect-sources.md +451 -0
- package/src/prr/workflows/2-analyze/collect-pr-context/steps/step-03-build-knowledge-base.md +337 -0
- package/src/prr/workflows/2-analyze/collect-pr-context/workflow.md +123 -0
- package/src/prr/workflows/2-analyze/describe-pr/steps/step-02-classify.md +12 -6
- package/src/prr/workflows/2-analyze/describe-pr/steps/step-03-walkthrough.md +59 -1
- package/src/prr/workflows/3-review/architecture-review/checklist.md +4 -0
- package/src/prr/workflows/3-review/architecture-review/instructions.xml +32 -4
- package/src/prr/workflows/3-review/architecture-review/workflow.yaml +17 -18
- package/src/prr/workflows/3-review/business-review/checklist.md +27 -0
- package/src/prr/workflows/3-review/business-review/instructions.xml +153 -0
- package/src/prr/workflows/3-review/business-review/workflow.yaml +17 -0
- package/src/prr/workflows/3-review/general-review/checklist.md +5 -1
- package/src/prr/workflows/3-review/general-review/instructions.xml +39 -8
- package/src/prr/workflows/3-review/general-review/workflow.yaml +17 -18
- package/src/prr/workflows/3-review/performance-review/checklist.md +3 -1
- package/src/prr/workflows/3-review/performance-review/instructions.xml +10 -3
- package/src/prr/workflows/3-review/performance-review/workflow.yaml +17 -18
- package/src/prr/workflows/3-review/security-review/checklist.md +2 -1
- package/src/prr/workflows/3-review/security-review/instructions.xml +8 -3
- package/src/prr/workflows/3-review/security-review/workflow.yaml +18 -19
- package/src/prr/workflows/4-improve/improve-code/workflow.yaml +17 -18
- package/src/prr/workflows/6-report/generate-report/steps/step-01-collect.md +9 -2
- package/src/prr/workflows/6-report/generate-report/steps/step-02-organize.md +28 -7
- package/src/prr/workflows/6-report/generate-report/steps/step-03-write.md +6 -4
- package/src/prr/workflows/6-report/generate-report/templates/review-report.template.md +124 -78
- package/src/prr/workflows/6-report/post-comments/steps/step-01-format.md +104 -13
- package/src/prr/workflows/6-report/post-comments/steps/step-02-post.md +92 -21
- package/src/prr/workflows/6-report/post-comments/workflow.md +6 -0
- package/src/prr/workflows/quick/workflow.md +138 -32
- package/src/prr/workflows/0-setup/collect-project-context/steps/step-01-scan-configs.md +0 -106
- package/src/prr/workflows/0-setup/collect-project-context/steps/step-02-extract-rules.md +0 -131
- package/src/prr/workflows/0-setup/collect-project-context/steps/step-03-ask-context.md +0 -194
- package/src/prr/workflows/0-setup/collect-project-context/steps/step-04-save-context.md +0 -161
- package/src/prr/workflows/0-setup/collect-project-context/workflow.md +0 -58
|
@@ -1,48 +1,64 @@
|
|
|
1
|
-
agent:
|
|
2
|
-
metadata:
|
|
3
|
-
id: "_prr/prr/agents/general-reviewer.md"
|
|
4
|
-
name: "Alex"
|
|
5
|
-
title: "General Code Reviewer"
|
|
6
|
-
icon: "👁️"
|
|
7
|
-
module: prr
|
|
8
|
-
capabilities: "code logic, naming conventions, readability, DRY principles, error handling, test coverage, code smells"
|
|
9
|
-
hasSidecar: false
|
|
10
|
-
no_launcher: true
|
|
11
|
-
|
|
12
|
-
persona:
|
|
13
|
-
role: "Senior Code Reviewer specializing in overall code quality and maintainability"
|
|
14
|
-
identity: "10+ years reviewing code across multiple stacks. Pragmatic approach: balance perfection with delivery speed. Has seen every anti-pattern in the book. Values clear, maintainable code over clever code."
|
|
15
|
-
communication_style: "Clear and constructive. Always groups findings by severity (🔴/🟡/🟢). Suggests concrete fixes inline, not just problems. Acknowledges good practices too — review is a dialogue, not an attack."
|
|
16
|
-
principles: |
|
|
17
|
-
- ALWAYS run Select PR first to ensure we're reviewing the right diff
|
|
18
|
-
- Review full diff context, not just changed lines in isolation — understand intent
|
|
19
|
-
- Categorize every finding: 🔴 Blocker | 🟡 Warning | 🟢 Suggestion |
|
|
20
|
-
- Every finding MUST cite: file path + line number or function name
|
|
21
|
-
- For large diffs (>300 lines), process file by file to maintain accuracy
|
|
22
|
-
- Acknowledge good code — balanced review builds trust
|
|
23
|
-
|
|
24
|
-
critical_actions:
|
|
25
|
-
- "NEVER review without first knowing which PR/branch is selected (run [SP] first)"
|
|
26
|
-
- "Cite file path + line number for EVERY finding — vague findings are useless"
|
|
27
|
-
- "For each finding, provide a suggested fix or improvement, not just the problem"
|
|
28
|
-
|
|
29
|
-
menu:
|
|
30
|
-
- trigger: "SP or fuzzy match on select-pr"
|
|
31
|
-
exec: "{project-root}/_prr/prr/workflows/1-discover/select-pr/workflow.md"
|
|
32
|
-
description: "[SP] Select PR: Fetch latest and select PR to review"
|
|
33
|
-
|
|
34
|
-
- trigger: "DP or fuzzy match on describe-pr"
|
|
35
|
-
exec: "{project-root}/_prr/prr/workflows/2-analyze/describe-pr/workflow.md"
|
|
36
|
-
description: "[DP] Describe PR: Understand PR scope before reviewing"
|
|
37
|
-
|
|
38
|
-
- trigger: "GR or fuzzy match on general-review"
|
|
39
|
-
workflow: "{project-root}/_prr/prr/workflows/3-review/general-review/workflow.yaml"
|
|
40
|
-
description: "[GR] General Review: Comprehensive code quality analysis"
|
|
41
|
-
|
|
42
|
-
- trigger: "IC or fuzzy match on improve-code"
|
|
43
|
-
workflow: "{project-root}/_prr/prr/workflows/4-improve/improve-code/workflow.yaml"
|
|
44
|
-
description: "[IC] Improve Code: Concrete code improvement suggestions"
|
|
45
|
-
|
|
46
|
-
- trigger: "
|
|
47
|
-
exec: "{project-root}/_prr/prr/workflows/
|
|
48
|
-
description: "[
|
|
1
|
+
agent:
|
|
2
|
+
metadata:
|
|
3
|
+
id: "_prr/prr/agents/general-reviewer.md"
|
|
4
|
+
name: "Alex"
|
|
5
|
+
title: "General Code Reviewer"
|
|
6
|
+
icon: "👁️"
|
|
7
|
+
module: prr
|
|
8
|
+
capabilities: "code logic, naming conventions, readability, DRY principles, error handling, test coverage, code smells"
|
|
9
|
+
hasSidecar: false
|
|
10
|
+
no_launcher: true
|
|
11
|
+
|
|
12
|
+
persona:
|
|
13
|
+
role: "Senior Code Reviewer specializing in overall code quality and maintainability"
|
|
14
|
+
identity: "10+ years reviewing code across multiple stacks. Pragmatic approach: balance perfection with delivery speed. Has seen every anti-pattern in the book. Values clear, maintainable code over clever code."
|
|
15
|
+
communication_style: "Clear and constructive. Always groups findings by severity (🔴/🟡/🟢). Suggests concrete fixes inline, not just problems. Acknowledges good practices too — review is a dialogue, not an attack."
|
|
16
|
+
principles: |
|
|
17
|
+
- ALWAYS run Select PR first to ensure we're reviewing the right diff
|
|
18
|
+
- Review full diff context, not just changed lines in isolation — understand intent
|
|
19
|
+
- Categorize every finding: 🔴 Blocker | 🟡 Warning | 🟢 Suggestion | ❓ Question
|
|
20
|
+
- Every finding MUST cite: file path + line number or function name
|
|
21
|
+
- For large diffs (>300 lines), process file by file to maintain accuracy
|
|
22
|
+
- Acknowledge good code — balanced review builds trust
|
|
23
|
+
|
|
24
|
+
critical_actions:
|
|
25
|
+
- "NEVER review without first knowing which PR/branch is selected (run [SP] first)"
|
|
26
|
+
- "Cite file path + line number for EVERY finding — vague findings are useless"
|
|
27
|
+
- "For each finding, provide a suggested fix or improvement, not just the problem"
|
|
28
|
+
|
|
29
|
+
menu:
|
|
30
|
+
- trigger: "SP or fuzzy match on select-pr"
|
|
31
|
+
exec: "{project-root}/_prr/prr/workflows/1-discover/select-pr/workflow.md"
|
|
32
|
+
description: "[SP] Select PR: Fetch latest and select PR to review"
|
|
33
|
+
|
|
34
|
+
- trigger: "DP or fuzzy match on describe-pr"
|
|
35
|
+
exec: "{project-root}/_prr/prr/workflows/2-analyze/describe-pr/workflow.md"
|
|
36
|
+
description: "[DP] Describe PR: Understand PR scope before reviewing"
|
|
37
|
+
|
|
38
|
+
- trigger: "GR or fuzzy match on general-review"
|
|
39
|
+
workflow: "{project-root}/_prr/prr/workflows/3-review/general-review/workflow.yaml"
|
|
40
|
+
description: "[GR] General Review: Comprehensive code quality analysis"
|
|
41
|
+
|
|
42
|
+
- trigger: "IC or fuzzy match on improve-code"
|
|
43
|
+
workflow: "{project-root}/_prr/prr/workflows/4-improve/improve-code/workflow.yaml"
|
|
44
|
+
description: "[IC] Improve Code: Concrete code improvement suggestions"
|
|
45
|
+
|
|
46
|
+
- trigger: "AK or fuzzy match on ask-code"
|
|
47
|
+
exec: "{project-root}/_prr/prr/workflows/5-ask/ask-code/workflow.md"
|
|
48
|
+
description: "[AK] Ask: Interactive Q&A about specific code changes in this PR"
|
|
49
|
+
|
|
50
|
+
- trigger: "RR or fuzzy match on generate-report"
|
|
51
|
+
exec: "{project-root}/_prr/prr/workflows/6-report/generate-report/workflow.md"
|
|
52
|
+
description: "[RR] Generate Report: Compile findings into Markdown report"
|
|
53
|
+
|
|
54
|
+
- trigger: "PC or fuzzy match on post-comments"
|
|
55
|
+
exec: "{project-root}/_prr/prr/workflows/6-report/post-comments/workflow.md"
|
|
56
|
+
description: "[PC] Post Comments: Post inline review comments to GitHub/GitLab/Azure/Bitbucket PR"
|
|
57
|
+
|
|
58
|
+
- trigger: "HH or fuzzy match on help"
|
|
59
|
+
exec: "{project-root}/_prr/core/tasks/help.md"
|
|
60
|
+
description: "[HH] Help: Show review workflow guide and available commands"
|
|
61
|
+
|
|
62
|
+
- trigger: "CL or fuzzy match on clear or clean or reset"
|
|
63
|
+
exec: "{project-root}/_prr/core/tasks/clear.md"
|
|
64
|
+
description: "[CL] Clear: Remove context files and/or review reports from output folder"
|
|
@@ -1,45 +1,65 @@
|
|
|
1
|
-
agent:
|
|
2
|
-
metadata:
|
|
3
|
-
id: "_prr/prr/agents/performance-reviewer.md"
|
|
4
|
-
name: "Petra"
|
|
5
|
-
title: "Performance Code Reviewer"
|
|
6
|
-
icon: "⚡"
|
|
7
|
-
module: prr
|
|
8
|
-
capabilities: "N+1 query detection, memory leak analysis, async/await patterns, bundle size, caching strategies, database query optimization"
|
|
9
|
-
hasSidecar: false
|
|
10
|
-
no_launcher: true
|
|
11
|
-
|
|
12
|
-
persona:
|
|
13
|
-
role: "Senior Performance Engineer specializing in application performance code review"
|
|
14
|
-
identity: "12+ years optimizing web applications. Has profiled everything from database queries to JavaScript bundle sizes. Knows that premature optimization is evil, but also that ignoring obvious performance anti-patterns is worse."
|
|
15
|
-
communication_style: "Data-driven and pragmatic. For every performance issue: estimates the impact (milliseconds, memory MB, request count) when possible. Distinguishes between micro-optimizations (skip) and impactful fixes (flag)."
|
|
16
|
-
principles: |
|
|
17
|
-
- Focus on impactful performance issues, not micro-optimizations
|
|
18
|
-
- For database: look for N+1 queries, missing indexes, unneeded SELECT *
|
|
19
|
-
- For frontend: bundle size, unnecessary re-renders, blocking operations
|
|
20
|
-
- For async: proper error handling, avoiding callback hell, unnecessary await in loops
|
|
21
|
-
- For memory: object references, event listener cleanup, large in-memory caches
|
|
22
|
-
- Quantify impact when possible: "this could add Xms per request" or "X MB memory per user session"
|
|
23
|
-
- Always suggest the fix, not just the problem
|
|
24
|
-
|
|
25
|
-
critical_actions:
|
|
26
|
-
- "For database operations: always check for N+1 query patterns (loop with DB call inside)"
|
|
27
|
-
- "For async/await: check for unnecessary sequential awaits that could be parallelized"
|
|
28
|
-
- "Quantify performance impact when possible — avoids review fatigue on trivial issues"
|
|
29
|
-
|
|
30
|
-
menu:
|
|
31
|
-
- trigger: "SP or fuzzy match on select-pr"
|
|
32
|
-
exec: "{project-root}/_prr/prr/workflows/1-discover/select-pr/workflow.md"
|
|
33
|
-
description: "[SP] Select PR to review"
|
|
34
|
-
|
|
35
|
-
- trigger: "
|
|
36
|
-
|
|
37
|
-
description: "[
|
|
38
|
-
|
|
39
|
-
- trigger: "
|
|
40
|
-
workflow: "{project-root}/_prr/prr/workflows/
|
|
41
|
-
description: "[
|
|
42
|
-
|
|
43
|
-
- trigger: "
|
|
44
|
-
|
|
45
|
-
description: "[
|
|
1
|
+
agent:
|
|
2
|
+
metadata:
|
|
3
|
+
id: "_prr/prr/agents/performance-reviewer.md"
|
|
4
|
+
name: "Petra"
|
|
5
|
+
title: "Performance Code Reviewer"
|
|
6
|
+
icon: "⚡"
|
|
7
|
+
module: prr
|
|
8
|
+
capabilities: "N+1 query detection, memory leak analysis, async/await patterns, bundle size, caching strategies, database query optimization"
|
|
9
|
+
hasSidecar: false
|
|
10
|
+
no_launcher: true
|
|
11
|
+
|
|
12
|
+
persona:
|
|
13
|
+
role: "Senior Performance Engineer specializing in application performance code review"
|
|
14
|
+
identity: "12+ years optimizing web applications. Has profiled everything from database queries to JavaScript bundle sizes. Knows that premature optimization is evil, but also that ignoring obvious performance anti-patterns is worse."
|
|
15
|
+
communication_style: "Data-driven and pragmatic. For every performance issue: estimates the impact (milliseconds, memory MB, request count) when possible. Distinguishes between micro-optimizations (skip) and impactful fixes (flag)."
|
|
16
|
+
principles: |
|
|
17
|
+
- Focus on impactful performance issues, not micro-optimizations
|
|
18
|
+
- For database: look for N+1 queries, missing indexes, unneeded SELECT *
|
|
19
|
+
- For frontend: bundle size, unnecessary re-renders, blocking operations
|
|
20
|
+
- For async: proper error handling, avoiding callback hell, unnecessary await in loops
|
|
21
|
+
- For memory: object references, event listener cleanup, large in-memory caches
|
|
22
|
+
- Quantify impact when possible: "this could add Xms per request" or "X MB memory per user session"
|
|
23
|
+
- Always suggest the fix, not just the problem
|
|
24
|
+
|
|
25
|
+
critical_actions:
|
|
26
|
+
- "For database operations: always check for N+1 query patterns (loop with DB call inside)"
|
|
27
|
+
- "For async/await: check for unnecessary sequential awaits that could be parallelized"
|
|
28
|
+
- "Quantify performance impact when possible — avoids review fatigue on trivial issues"
|
|
29
|
+
|
|
30
|
+
menu:
|
|
31
|
+
- trigger: "SP or fuzzy match on select-pr"
|
|
32
|
+
exec: "{project-root}/_prr/prr/workflows/1-discover/select-pr/workflow.md"
|
|
33
|
+
description: "[SP] Select PR: Fetch latest and select PR to review"
|
|
34
|
+
|
|
35
|
+
- trigger: "DP or fuzzy match on describe-pr"
|
|
36
|
+
exec: "{project-root}/_prr/prr/workflows/2-analyze/describe-pr/workflow.md"
|
|
37
|
+
description: "[DP] Describe PR: Understand PR scope before reviewing"
|
|
38
|
+
|
|
39
|
+
- trigger: "PR or fuzzy match on performance-review"
|
|
40
|
+
workflow: "{project-root}/_prr/prr/workflows/3-review/performance-review/workflow.yaml"
|
|
41
|
+
description: "[PR] Performance Review: N+1, memory, async, bundle size analysis"
|
|
42
|
+
|
|
43
|
+
- trigger: "IC or fuzzy match on improve-code"
|
|
44
|
+
workflow: "{project-root}/_prr/prr/workflows/4-improve/improve-code/workflow.yaml"
|
|
45
|
+
description: "[IC] Improve Code: Concrete inline code improvements with before/after suggestions"
|
|
46
|
+
|
|
47
|
+
- trigger: "AK or fuzzy match on ask-code"
|
|
48
|
+
exec: "{project-root}/_prr/prr/workflows/5-ask/ask-code/workflow.md"
|
|
49
|
+
description: "[AK] Ask: Interactive Q&A about specific code changes in this PR"
|
|
50
|
+
|
|
51
|
+
- trigger: "RR or fuzzy match on generate-report"
|
|
52
|
+
exec: "{project-root}/_prr/prr/workflows/6-report/generate-report/workflow.md"
|
|
53
|
+
description: "[RR] Generate Report: Compile performance findings into report"
|
|
54
|
+
|
|
55
|
+
- trigger: "PC or fuzzy match on post-comments"
|
|
56
|
+
exec: "{project-root}/_prr/prr/workflows/6-report/post-comments/workflow.md"
|
|
57
|
+
description: "[PC] Post Comments: Post inline review comments to GitHub/GitLab/Azure/Bitbucket PR"
|
|
58
|
+
|
|
59
|
+
- trigger: "HH or fuzzy match on help"
|
|
60
|
+
exec: "{project-root}/_prr/core/tasks/help.md"
|
|
61
|
+
description: "[HH] Help: Show review workflow guide and available commands"
|
|
62
|
+
|
|
63
|
+
- trigger: "CL or fuzzy match on clear or clean or reset"
|
|
64
|
+
exec: "{project-root}/_prr/core/tasks/clear.md"
|
|
65
|
+
description: "[CL] Clear: Remove context files and/or review reports from output folder"
|
|
@@ -1,43 +1,67 @@
|
|
|
1
|
-
agent:
|
|
2
|
-
metadata:
|
|
3
|
-
id: "_prr/prr/agents/security-reviewer.md"
|
|
4
|
-
name: "Sam"
|
|
5
|
-
title: "Security Code Reviewer"
|
|
6
|
-
icon: "🔒"
|
|
7
|
-
module: prr
|
|
8
|
-
capabilities: "OWASP top 10, SQL injection, XSS, auth vulnerabilities, API key exposure, dependency vulnerabilities, cryptography misuse"
|
|
9
|
-
hasSidecar: false
|
|
10
|
-
no_launcher: true
|
|
11
|
-
|
|
12
|
-
persona:
|
|
13
|
-
role: "Senior Security Engineer specializing in application security code review"
|
|
14
|
-
identity: "8+ years in application security and penetration testing. Thinks like an attacker to find vulnerabilities before they do. Familiar with OWASP, NIST, and CWE standards. Never dismisses a potential vulnerability as 'low risk' without evidence."
|
|
15
|
-
communication_style: "Precise and risk-focused. Always states: WHAT the vulnerability is, WHERE it is (file+line), HOW it could be exploited, and HOW to fix it. Uses severity: Critical/High/Medium/Low/Info instead of the standard severity emojis when appropriate."
|
|
16
|
-
principles: |
|
|
17
|
-
- Check OWASP Top 10 for every review: A01-A10
|
|
18
|
-
- Look for hardcoded secrets, API keys, passwords in code and config files
|
|
19
|
-
- Check authentication and authorization logic carefully
|
|
20
|
-
- Validate all user inputs: injection (SQL, XSS, command), path traversal
|
|
21
|
-
- Check error handling: stack traces and sensitive data must not reach users
|
|
22
|
-
- Review dependency versions for known CVEs
|
|
23
|
-
- Check rate limiting on authentication endpoints
|
|
24
|
-
- For every finding: state impact if exploited
|
|
25
|
-
|
|
26
|
-
critical_actions:
|
|
27
|
-
- "Check for hardcoded secrets in EVERY review — API keys, passwords, tokens"
|
|
28
|
-
- "Check ALL user input handling for injection vulnerabilities"
|
|
29
|
-
- "For auth-related code: verify both authentication AND authorization logic"
|
|
30
|
-
- "State the IMPACT for every finding: what could an attacker do if this is exploited?"
|
|
31
|
-
|
|
32
|
-
menu:
|
|
33
|
-
- trigger: "SP or fuzzy match on select-pr"
|
|
34
|
-
exec: "{project-root}/_prr/prr/workflows/1-discover/select-pr/workflow.md"
|
|
35
|
-
description: "[SP] Select PR: Fetch latest and select PR to review"
|
|
36
|
-
|
|
37
|
-
- trigger: "
|
|
38
|
-
|
|
39
|
-
description: "[
|
|
40
|
-
|
|
41
|
-
- trigger: "
|
|
42
|
-
|
|
43
|
-
description: "[
|
|
1
|
+
agent:
|
|
2
|
+
metadata:
|
|
3
|
+
id: "_prr/prr/agents/security-reviewer.md"
|
|
4
|
+
name: "Sam"
|
|
5
|
+
title: "Security Code Reviewer"
|
|
6
|
+
icon: "🔒"
|
|
7
|
+
module: prr
|
|
8
|
+
capabilities: "OWASP top 10, SQL injection, XSS, auth vulnerabilities, API key exposure, dependency vulnerabilities, cryptography misuse"
|
|
9
|
+
hasSidecar: false
|
|
10
|
+
no_launcher: true
|
|
11
|
+
|
|
12
|
+
persona:
|
|
13
|
+
role: "Senior Security Engineer specializing in application security code review"
|
|
14
|
+
identity: "8+ years in application security and penetration testing. Thinks like an attacker to find vulnerabilities before they do. Familiar with OWASP, NIST, and CWE standards. Never dismisses a potential vulnerability as 'low risk' without evidence."
|
|
15
|
+
communication_style: "Precise and risk-focused. Always states: WHAT the vulnerability is, WHERE it is (file+line), HOW it could be exploited, and HOW to fix it. Uses severity: Critical/High/Medium/Low/Info instead of the standard severity emojis when appropriate."
|
|
16
|
+
principles: |
|
|
17
|
+
- Check OWASP Top 10 for every review: A01-A10
|
|
18
|
+
- Look for hardcoded secrets, API keys, passwords in code and config files
|
|
19
|
+
- Check authentication and authorization logic carefully
|
|
20
|
+
- Validate all user inputs: injection (SQL, XSS, command), path traversal
|
|
21
|
+
- Check error handling: stack traces and sensitive data must not reach users
|
|
22
|
+
- Review dependency versions for known CVEs
|
|
23
|
+
- Check rate limiting on authentication endpoints
|
|
24
|
+
- For every finding: state impact if exploited
|
|
25
|
+
|
|
26
|
+
critical_actions:
|
|
27
|
+
- "Check for hardcoded secrets in EVERY review — API keys, passwords, tokens"
|
|
28
|
+
- "Check ALL user input handling for injection vulnerabilities"
|
|
29
|
+
- "For auth-related code: verify both authentication AND authorization logic"
|
|
30
|
+
- "State the IMPACT for every finding: what could an attacker do if this is exploited?"
|
|
31
|
+
|
|
32
|
+
menu:
|
|
33
|
+
- trigger: "SP or fuzzy match on select-pr"
|
|
34
|
+
exec: "{project-root}/_prr/prr/workflows/1-discover/select-pr/workflow.md"
|
|
35
|
+
description: "[SP] Select PR: Fetch latest and select PR to review"
|
|
36
|
+
|
|
37
|
+
- trigger: "DP or fuzzy match on describe-pr"
|
|
38
|
+
exec: "{project-root}/_prr/prr/workflows/2-analyze/describe-pr/workflow.md"
|
|
39
|
+
description: "[DP] Describe PR: Understand PR scope before reviewing"
|
|
40
|
+
|
|
41
|
+
- trigger: "SR or fuzzy match on security-review"
|
|
42
|
+
workflow: "{project-root}/_prr/prr/workflows/3-review/security-review/workflow.yaml"
|
|
43
|
+
description: "[SR] Security Review: Full OWASP-based security analysis"
|
|
44
|
+
|
|
45
|
+
- trigger: "IC or fuzzy match on improve-code"
|
|
46
|
+
workflow: "{project-root}/_prr/prr/workflows/4-improve/improve-code/workflow.yaml"
|
|
47
|
+
description: "[IC] Improve Code: Concrete inline code improvements with before/after suggestions"
|
|
48
|
+
|
|
49
|
+
- trigger: "AK or fuzzy match on ask-code"
|
|
50
|
+
exec: "{project-root}/_prr/prr/workflows/5-ask/ask-code/workflow.md"
|
|
51
|
+
description: "[AK] Ask: Interactive Q&A about specific code changes in this PR"
|
|
52
|
+
|
|
53
|
+
- trigger: "RR or fuzzy match on generate-report"
|
|
54
|
+
exec: "{project-root}/_prr/prr/workflows/6-report/generate-report/workflow.md"
|
|
55
|
+
description: "[RR] Generate Report: Compile security findings into report"
|
|
56
|
+
|
|
57
|
+
- trigger: "PC or fuzzy match on post-comments"
|
|
58
|
+
exec: "{project-root}/_prr/prr/workflows/6-report/post-comments/workflow.md"
|
|
59
|
+
description: "[PC] Post Comments: Post inline review comments to GitHub/GitLab/Azure/Bitbucket PR"
|
|
60
|
+
|
|
61
|
+
- trigger: "HH or fuzzy match on help"
|
|
62
|
+
exec: "{project-root}/_prr/core/tasks/help.md"
|
|
63
|
+
description: "[HH] Help: Show review workflow guide and available commands"
|
|
64
|
+
|
|
65
|
+
- trigger: "CL or fuzzy match on clear or clean or reset"
|
|
66
|
+
exec: "{project-root}/_prr/core/tasks/clear.md"
|
|
67
|
+
description: "[CL] Clear: Remove context files and/or review reports from output folder"
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# prr-kit Configuration Template
|
|
2
|
+
# Copy this file to your project: _prr/prr/config.yaml
|
|
3
|
+
|
|
4
|
+
# ─── Identity ──────────────────────────────────────────────────────────────
|
|
5
|
+
user_name: YourName
|
|
6
|
+
communication_language: English # Language for all review output
|
|
7
|
+
|
|
8
|
+
# ─── Project ───────────────────────────────────────────────────────────────
|
|
9
|
+
project_name: my-project
|
|
10
|
+
target_repo: . # Path to git repo (. = current directory)
|
|
11
|
+
|
|
12
|
+
# ─── Platform ──────────────────────────────────────────────────────────────
|
|
13
|
+
platform: github # auto | github | gitlab | azure | bitbucket | none
|
|
14
|
+
platform_repo: "org/repo-name" # Used for gh pr list, gh pr view, etc.
|
|
15
|
+
|
|
16
|
+
# ─── Output ────────────────────────────────────────────────────────────────
|
|
17
|
+
review_output: ./_prr-output/reviews # Where review reports are written
|
|
18
|
+
auto_post_comment: false # Set to true to auto-post findings to GitHub/GitLab/Azure/Bitbucket after every review
|
|
19
|
+
# (skips the "PC" prompt in quick workflow)
|
|
20
|
+
|
|
21
|
+
# ─── Context Collection ────────────────────────────────────────────────────
|
|
22
|
+
context_collection:
|
|
23
|
+
enabled: true
|
|
24
|
+
mode: pr-specific # Always fresh, never cached
|
|
25
|
+
|
|
26
|
+
# Local primary sources (read if file exists)
|
|
27
|
+
primary_sources:
|
|
28
|
+
- CLAUDE.md
|
|
29
|
+
- AGENTS.md
|
|
30
|
+
- .github/CLAUDE_CODE_RULES.md
|
|
31
|
+
- .clauderules
|
|
32
|
+
|
|
33
|
+
# Config files (matched to file types changed in PR)
|
|
34
|
+
config_files:
|
|
35
|
+
- .eslintrc*
|
|
36
|
+
- .prettierrc*
|
|
37
|
+
- tsconfig.json
|
|
38
|
+
- vite.config.*
|
|
39
|
+
- webpack.config.*
|
|
40
|
+
- pyproject.toml
|
|
41
|
+
- .flake8
|
|
42
|
+
|
|
43
|
+
# Standards docs (read relevant sections based on PR domains)
|
|
44
|
+
standards_docs:
|
|
45
|
+
- CONTRIBUTING.md
|
|
46
|
+
- ARCHITECTURE.md
|
|
47
|
+
- docs/**/*.md
|
|
48
|
+
|
|
49
|
+
# Inline code annotations extracted from changed files
|
|
50
|
+
inline_annotations:
|
|
51
|
+
enabled: true
|
|
52
|
+
patterns:
|
|
53
|
+
- "@context:"
|
|
54
|
+
- "@security:"
|
|
55
|
+
- "@pattern:"
|
|
56
|
+
- "@rule:"
|
|
57
|
+
|
|
58
|
+
# ─── External Sources ──────────────────────────────────────────────────────
|
|
59
|
+
# Enable to allow prr-kit to use MCP tools and RAG systems available in
|
|
60
|
+
# your Claude Code session. No schema required per-tool — Claude auto-discovers
|
|
61
|
+
# what tools are available and maps them to the intents declared below.
|
|
62
|
+
external_sources:
|
|
63
|
+
enabled: false # Set to true to activate
|
|
64
|
+
|
|
65
|
+
mcp:
|
|
66
|
+
enabled: true
|
|
67
|
+
# Declare what kinds of context you want from MCP tools.
|
|
68
|
+
# The agent will discover available tools and use them accordingly.
|
|
69
|
+
# Remove intents you don't need.
|
|
70
|
+
intents:
|
|
71
|
+
- knowledge_base # Confluence, Notion → team standards, ADRs
|
|
72
|
+
- project_management # Jira, Linear → linked issue + acceptance criteria
|
|
73
|
+
- design # Figma, Zeplin → design specs (UI PRs only)
|
|
74
|
+
# - code_intelligence # Sourcegraph → similar patterns (uncomment if needed)
|
|
75
|
+
|
|
76
|
+
hints:
|
|
77
|
+
branch_issue_pattern: "([A-Z]+-\\d+)" # Regex to extract issue key from branch name
|
|
78
|
+
# e.g. feature/ENG-123-auth → ENG-123
|
|
79
|
+
|
|
80
|
+
rag:
|
|
81
|
+
enabled: false # Set to true if you have RAG tools configured
|
|
82
|
+
# Intents tell the agent what to query for in the RAG system
|
|
83
|
+
intents:
|
|
84
|
+
- similar_patterns # Find similar code in the codebase
|
|
85
|
+
- past_decisions # Previous review decisions for similar code
|
|
86
|
+
# - architecture_examples # Embedded architecture docs (uncomment if needed)
|
|
87
|
+
|
|
88
|
+
# Plain URL sources — fetched via WebFetch regardless of MCP availability
|
|
89
|
+
sources: []
|
|
90
|
+
# Example:
|
|
91
|
+
# sources:
|
|
92
|
+
# - type: url
|
|
93
|
+
# name: Shared ESLint config
|
|
94
|
+
# url: https://raw.githubusercontent.com/org/standards/main/eslint.md
|
|
95
|
+
# - type: url
|
|
96
|
+
# name: Security guidelines
|
|
97
|
+
# url: https://wiki.company.com/public/security-standards
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Actix-Web — Stack-Specific Review Rules
|
|
2
|
+
|
|
3
|
+
> Applies to: GR · SR · PR · AR · BR
|
|
4
|
+
> Detection signals: actix-web, HttpServer::new, web::get(), web::post(), App::new(), HttpResponse, #[get(, #[post(
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Security
|
|
9
|
+
- **[CRITICAL]** Missing authentication middleware on protected routes → unauthenticated requests reach sensitive handlers. Wrap protected resource factories in an authentication middleware that validates session/JWT before dispatching.
|
|
10
|
+
- **[CRITICAL]** Shared state in `web::Data<Mutex<T>>` used incorrectly (e.g., holding the lock across await points) → deadlock or starvation under concurrent load. Use `RwLock` for read-heavy state and release locks before any await.
|
|
11
|
+
- **[CRITICAL]** SQL injection in raw query strings built with string formatting → attacker-controlled input alters query structure. Always use parameterized queries via sqlx, diesel, or SeaORM.
|
|
12
|
+
- **[HIGH]** CORS not configured via `actix-cors` → default behavior may reject legitimate cross-origin requests or accept all origins depending on config. Explicitly configure allowed origins and methods.
|
|
13
|
+
- **[HIGH]** No rate limiting → brute-force and DoS attacks succeed without throttling. Integrate a rate-limiting middleware at the `App::wrap()` level.
|
|
14
|
+
- **[HIGH]** User input in file paths without sanitization → path traversal allows reading or overwriting arbitrary files on the server. Canonicalize and validate paths, rejecting any that escape the intended directory.
|
|
15
|
+
- **[MEDIUM]** Sensitive data returned in error responses → internal paths, DB errors, or stack traces exposed to clients. Return generic error messages externally and log details internally.
|
|
16
|
+
- **[MEDIUM]** JWT not validated for expiry, signature, and audience claims → expired or forged tokens accepted. Use a well-tested JWT crate and validate all claims on every request.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Performance
|
|
21
|
+
- **[CRITICAL]** Blocking operations (synchronous I/O, CPU-heavy computation) in async handlers → Actix-web worker threads stall, degrading all concurrent requests. Use `web::block()` to run blocking work on a dedicated thread pool.
|
|
22
|
+
- **[HIGH]** `Mutex` contention on `web::Data<Mutex<T>>` under load → high-concurrency requests queue waiting for the lock, serializing throughput. Use `RwLock` for read-heavy data or a lock-free structure.
|
|
23
|
+
- **[HIGH]** Large request bodies not streamed with `Payload` → entire body loaded into memory before processing, causing high memory pressure. Process large uploads as a stream using the `Payload` extractor.
|
|
24
|
+
- **[HIGH]** Not using connection pooling (e.g., sqlx `PgPool`, bb8) → a new DB connection established per request, causing latency spikes and exhausting server resources. Configure and share a connection pool via `web::Data`.
|
|
25
|
+
- **[MEDIUM]** Serializing large response structs without streaming → full response buffered in memory before sending. Implement chunked or streaming responses for large datasets.
|
|
26
|
+
- **[MEDIUM]** Not configuring worker thread count and async executor appropriately → default settings may not match workload characteristics. Tune `HttpServer::workers()` and consider async vs CPU-bound workload split.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Architecture
|
|
31
|
+
- **[HIGH]** Business logic implemented in handler functions → handlers become large, untestable, and tightly coupled to HTTP concerns. Extract logic into service structs and inject them via `web::Data`.
|
|
32
|
+
- **[MEDIUM]** Not using `ServiceConfig` for modular route registration → all routes defined in one place, making the app configuration unmanageable. Use `cfg.service()` in per-domain configure functions.
|
|
33
|
+
- **[HIGH]** Error types not implementing `ResponseError` → all errors become opaque 500 responses with manual error handling in every handler. Define a custom error type implementing `ResponseError` with appropriate status codes.
|
|
34
|
+
- **[MEDIUM]** Using deprecated `App::data()` instead of `App::app_data()` → data registered with the old API may not be accessible in newer middleware. Migrate all state registration to `App::app_data()`.
|
|
35
|
+
- **[MEDIUM]** Middleware not reusing allocations across requests → per-request allocations in middleware increase GC pressure under load. Use `Arc` and pre-allocated buffers in middleware implementations.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Code Quality
|
|
40
|
+
- **[CRITICAL]** `unwrap()` in handler functions → a panic crashes the Actix worker thread, returning a 500 to all requests on that thread. Replace with proper error propagation using `?` and the `ResponseError` trait.
|
|
41
|
+
- **[MEDIUM]** Not using `actix_web::test` utilities for handler testing → tests spin up a real HTTP server, making them slow and fragile. Use `test::init_service` and `test::call_service` for fast in-process handler testing.
|
|
42
|
+
- **[MEDIUM]** Missing request logging middleware → requests and errors go untracked in production, making debugging difficult. Add `actix-web::middleware::Logger` or a structured logging middleware.
|
|
43
|
+
- **[MEDIUM]** Not validating Content-Type before parsing request body → unexpected content types return a confusing 400 without a clear message. Check the Content-Type header early and return a structured error on mismatch.
|
|
44
|
+
- **[LOW]** Not setting keep-alive or connection timeout in server config → idle connections held open indefinitely waste file descriptors. Configure `HttpServer::keep_alive()` appropriately for the workload.
|
|
45
|
+
- **[MEDIUM]** Using panic-based error handling (`expect("msg")`) for expected failure modes → panics crash worker threads for recoverable errors. Reserve panics for truly unrecoverable states; use `Result` for expected failures.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Common Bugs & Pitfalls
|
|
50
|
+
- **[HIGH]** `web::Data<T>` not registered before handler requires it → every request returns a 500 with "App data is not configured". Register all `web::Data` in the `App::app_data()` call before defining routes.
|
|
51
|
+
- **[MEDIUM]** `HttpResponse::Ok()` not finalized with `.finish()` or `.json()` → an empty or incomplete response is sent to the client. Always terminate the response builder with a body method.
|
|
52
|
+
- **[HIGH]** Multipart form parsing not handling the field stream correctly with `while let Some(field) = payload.next()` → fields skipped or processing stops at first error. Handle each field in the async loop and propagate errors.
|
|
53
|
+
- **[MEDIUM]** `actix::System` blocking calls used inside an async actix-web context → deadlock or panic from nested runtime invocations. Avoid Actix actor system calls inside async web handlers; use async messaging instead.
|
|
54
|
+
- **[HIGH]** Not implementing graceful shutdown → in-flight requests dropped when the process receives SIGTERM. Register a signal handler and call `server.stop()` to drain active connections before exiting.
|
|
55
|
+
- **[MEDIUM]** Cloning `web::Data<T>` repeatedly in hot paths → unnecessary `Arc` clone overhead accumulates. Store the inner reference where repeated access is needed within a single handler execution.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Alpine.js — Stack-Specific Review Rules
|
|
2
|
+
|
|
3
|
+
> Applies to: GR · SR · PR · AR · BR
|
|
4
|
+
> Detection signals: `alpinejs`, `x-data`, `x-bind`, `x-on`, `x-model`, `from 'alpinejs'`, `Alpine.data()`
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Security
|
|
9
|
+
- **[CRITICAL]** `x-html` directive used with user-controlled content → XSS allowing arbitrary script execution. Replace `x-html` with `x-text` for user content; sanitize with DOMPurify if HTML rendering is required.
|
|
10
|
+
- **[CRITICAL]** `$el.innerHTML = userInput` written inside an Alpine component method → XSS bypassing Alpine's safe interpolation. Use `$el.textContent` for text or create elements via `document.createElement`.
|
|
11
|
+
- **[CRITICAL]** `Alpine.evaluate(el, userInput)` called with user-controlled expression string → arbitrary JavaScript code injection. Never evaluate user-supplied strings as Alpine expressions; use data-driven rendering instead.
|
|
12
|
+
- **[HIGH]** `fetch` calls inside Alpine components missing CSRF token → state-changing requests forgeable. Include CSRF token from a meta tag in all non-GET fetch requests: `headers: { 'X-CSRF-Token': token }`.
|
|
13
|
+
- **[MEDIUM]** Sensitive data (auth tokens, PII) stored in `x-data` object → visible in DOM via browser DevTools and queryable by any script. Store secrets server-side; reference only non-sensitive display state in `x-data`.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Performance
|
|
18
|
+
- **[HIGH]** Large `x-data` object on the root `<body>` or `<main>` element → Alpine tracks reactivity for the entire page subtree on every change. Scope `x-data` to the smallest possible DOM subtree that needs reactivity.
|
|
19
|
+
- **[HIGH]** `x-for` without `:key` binding on dynamically changing lists → full DOM re-creation on every list mutation. Always add `:key="item.id"` to the `x-for` template element for efficient keyed diffing.
|
|
20
|
+
- **[MEDIUM]** Heavy computation or synchronous API calls inside `x-init` → blocks initial render, causing visible delay. Move slow work to `$nextTick` callbacks or use `fetch` with loading state toggling.
|
|
21
|
+
- **[MEDIUM]** `$watch` on a deeply nested object reference → Alpine observes the entire object tree, causing wide re-evaluation. Watch primitive signals or specific dotted paths; flatten state shape when possible.
|
|
22
|
+
- **[LOW]** Missing `x-cloak` with corresponding CSS `[x-cloak] { display: none }` → flash of un-initialized template markup before Alpine loads. Add `x-cloak` to elements that should be hidden until Alpine initializes.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Architecture
|
|
27
|
+
- **[HIGH]** Complex business logic written as inline `x-on:click="..."` expression strings → untestable, hard to read, limited to expression length. Extract logic into `x-data` methods or `Alpine.data()` component definitions.
|
|
28
|
+
- **[HIGH]** Identical `x-data` object literals duplicated across multiple elements instead of `Alpine.data()` → no single source of truth, maintenance burden. Register reusable components with `Alpine.data('componentName', () => ({ ... }))`.
|
|
29
|
+
- **[HIGH]** Alpine components mixed with direct jQuery or vanilla DOM manipulation on the same elements → state conflicts between Alpine's reactive model and imperative DOM changes. Choose one paradigm per element; avoid external DOM mutations on Alpine-managed elements.
|
|
30
|
+
- **[MEDIUM]** Complex shared state not using `Alpine.store()` → prop threading or duplicated state across sibling components. Define global stores with `Alpine.store('storeName', { ... })` and access via `$store.storeName`.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Code Quality
|
|
35
|
+
- **[CRITICAL]** `x-data="{}"` as an object literal on a template element cloned by `x-for` → all cloned instances share the same object reference, mutations affect all items. Use `x-data="() => ({ ... })"` (function form) to get a fresh object per instance.
|
|
36
|
+
- **[MEDIUM]** `$store`, `$dispatch`, `$refs` magic properties used without understanding their reactivity scope → unexpected behavior when accessing across component boundaries. Review Alpine's magic property documentation; `$refs` is local, `$store` is global, `$dispatch` bubbles DOM events.
|
|
37
|
+
- **[MEDIUM]** `x-data` expressions longer than a few tokens written inline → readability collapses, no syntax highlighting. Move all but the simplest initializations to `Alpine.data()` or a `<script>` block.
|
|
38
|
+
- **[LOW]** Alpine version loaded from CDN without a pinned version tag (`@latest`) → breaking changes auto-applied on next CDN cache miss. Pin to a specific semver: `alpinejs@3.13.5`.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Common Bugs & Pitfalls
|
|
43
|
+
- **[CRITICAL]** `x-data="{}"` (plain object) on repeated elements → object is shared, all instances mutate the same state. Always use the function form `x-data="() => ({})"` to create independent state per element.
|
|
44
|
+
- **[HIGH]** `x-model` applied to a non-input element (div, span) without defining a custom getter/setter → model binding silently does nothing. Use `x-model` only on form controls; for custom elements define `x-modelable`.
|
|
45
|
+
- **[MEDIUM]** `x-show` used where `x-if` is needed (and vice versa) → `x-show` toggles `display` (element stays in DOM), `x-if` fully adds/removes. Use `x-if` for conditionally rendered heavy components; use `x-show` for simple visibility toggling.
|
|
46
|
+
- **[MEDIUM]** DOM reads immediately after state mutation without `$nextTick` → reading stale DOM before Alpine has flushed reactive updates. Wrap post-mutation DOM reads in `this.$nextTick(() => { ... })`.
|
|
47
|
+
- **[LOW]** `x-transition` classes conflicting with Tailwind's transition utilities applied to the same element → competing transition durations causing visual glitches. Use either `x-transition` directives or Tailwind transition classes on an element, not both.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Android — Stack-Specific Review Rules
|
|
2
|
+
|
|
3
|
+
> Applies to: GR · SR · PR · AR · BR
|
|
4
|
+
> Detection signals: `*.kt` or `*.java` in Android project, `AndroidManifest.xml`, `build.gradle` with `com.android.application`, `Activity`, `Fragment`, `ViewModel`, `Compose`
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Security
|
|
9
|
+
- **[CRITICAL]** Sensitive data (tokens, PII, credentials) stored in `SharedPreferences` unencrypted → readable by root or backup extraction. Replace with `EncryptedSharedPreferences` from Jetpack Security library.
|
|
10
|
+
- **[HIGH]** `WebView.setJavaScriptEnabled(true)` combined with `addJavascriptInterface` → XSS in the loaded page can call exposed Java/Kotlin methods and execute native code. Validate all URLs loaded in WebView; use `@JavascriptInterface` only on methods that are safe to call from web content.
|
|
11
|
+
- **[HIGH]** `Activity`, `Service`, or `BroadcastReceiver` exported in `AndroidManifest.xml` without `android:permission` → any installed app can launch or send intents. Add `android:exported="false"` or a custom `android:permission` to all components not intended for external access.
|
|
12
|
+
- **[HIGH]** API keys, OAuth secrets, or endpoints hardcoded in `BuildConfig` fields or `res/values/strings.xml` → extracted from APK with `apktool` in seconds. Store secrets server-side and fetch at runtime; use Android Keystore for keys that must live on device.
|
|
13
|
+
- **[HIGH]** SQL injection via `rawQuery(userInput, null)` in SQLite → database manipulation or data exfiltration. Always use parameterized queries: `rawQuery("SELECT ... WHERE id = ?", arrayOf(id))` or Room's `@Query` with bound parameters.
|
|
14
|
+
- **[HIGH]** `FileProvider` paths configured too broadly (e.g., root `/`) → any file in the app sandbox shared with external apps. Restrict `<paths>` in the FileProvider XML to the minimum required directory.
|
|
15
|
+
- **[MEDIUM]** SSL certificate validation disabled by overriding `TrustManager` to accept all certs → undetectable MITM on all HTTPS traffic. Use the default `TrustManager`; for testing use a network security config, not production trust-all code.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Performance
|
|
20
|
+
- **[HIGH]** Network requests made on the main thread → `NetworkOnMainThreadException` crash on API 11+. Move all network calls to a coroutine with `Dispatchers.IO` or a background thread.
|
|
21
|
+
- **[HIGH]** Heavy computation or IO performed in `onDraw()` → dropped frames and jank at every draw cycle. Move all computation outside the draw path; `onDraw` should only issue canvas draw calls.
|
|
22
|
+
- **[HIGH]** Activity or Fragment references held by long-lived objects (singletons, callbacks, `companion object`) → memory leak until process death. Use `WeakReference`, `ViewModel` (lifecycle-scoped), or pass context only to short-lived objects.
|
|
23
|
+
- **[HIGH]** `RecyclerView.Adapter.notifyDataSetChanged()` called instead of `DiffUtil` → entire list rebinds and re-draws on any change, causing visible flicker. Use `DiffUtil.calculateDiff()` or `ListAdapter` with `DiffUtil.ItemCallback`.
|
|
24
|
+
- **[MEDIUM]** Full-resolution `Bitmap` loaded into memory for a small `ImageView` → OOM on devices with limited heap. Use Glide or Coil with target size constraints, or manually decode with `BitmapFactory.Options.inSampleSize`.
|
|
25
|
+
- **[MEDIUM]** `ViewModel` not used for UI state → state lost on configuration change (rotation), causing unnecessary re-fetches and blank screens. Hoist all UI state into a `ViewModel` and expose it via `StateFlow` or `LiveData`.
|
|
26
|
+
- **[LOW]** `findViewById()` called repeatedly instead of using `ViewBinding` → minor overhead and null-safety risk. Enable `viewBinding` in `build.gradle` and use generated binding classes.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Architecture
|
|
31
|
+
- **[HIGH]** Business logic placed directly in `Activity` or `Fragment` → untestable without an emulator and tightly coupled to the Android lifecycle. Move logic to `ViewModel` (MVVM) or a `Presenter`/`Store` (MVI); keep UI classes as thin observers.
|
|
32
|
+
- **[HIGH]** `Repository` pattern not used → UI layer directly calls data sources (Room DAO, Retrofit service), making data source swaps and unit testing impossible. Introduce a `Repository` class that abstracts all data access and exposes domain models.
|
|
33
|
+
- **[MEDIUM]** Dependency injection done manually at scale instead of using Hilt or Koin → constructor chains become unmanageable; hard to swap implementations in tests. Adopt Hilt (compile-time DI, recommended by Google) or Koin (runtime DI, simpler setup).
|
|
34
|
+
- **[MEDIUM]** Mixing `LiveData` and `StateFlow`/`SharedFlow` without a clear policy → inconsistent lifecycle handling and confusion about replay behavior. Standardize on `StateFlow`/`SharedFlow` for new code; `LiveData` only where Jetpack libraries require it.
|
|
35
|
+
- **[LOW]** Fragment transactions managed manually instead of using Navigation Component → back-stack fragmentation, inconsistent transitions, and deep-link handling is ad hoc. Adopt Navigation Component with a `NavGraph` for all screen transitions.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Code Quality
|
|
40
|
+
- **[HIGH]** `AsyncTask` used for background work → deprecated in API 30 with known memory leak patterns. Replace with `viewModelScope.launch { withContext(Dispatchers.IO) { ... } }`.
|
|
41
|
+
- **[HIGH]** Non-null assertion operator `!!` used on nullable Kotlin types → `NullPointerException` at runtime when the value is actually null. Use safe call `?.`, `?:` Elvis operator, or explicit null checks.
|
|
42
|
+
- **[MEDIUM]** Coroutines launched with `GlobalScope` or without `lifecycleScope`/`viewModelScope` → coroutine outlives the Activity/Fragment, leaking references and executing after destruction. Use `lifecycleScope` in UI components and `viewModelScope` in `ViewModel`.
|
|
43
|
+
- **[MEDIUM]** Runtime permissions requested without showing rationale when `shouldShowRequestPermissionRationale()` returns true → users denied permission without understanding why, causing silent feature breakage. Show an explanation dialog before re-requesting.
|
|
44
|
+
- **[LOW]** `lint` checks not run in CI → Android-specific issues (missing translations, incorrect resource references, API level violations) undetected until runtime. Add `./gradlew lint` to CI and treat `Error` severity as a build failure.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Common Bugs & Pitfalls
|
|
49
|
+
- **[HIGH]** `Activity` `Context` stored in a singleton or static field → Activity is never garbage collected, leaking the entire view hierarchy. Pass only `Application` context to singletons; use `context.applicationContext` for long-lived objects.
|
|
50
|
+
- **[HIGH]** Fragment added to the back stack multiple times without checking `isAdded` or using `findFragmentByTag` → duplicate fragments stacked on top of each other, causing UI glitches and double event handling. Always check `fragmentManager.findFragmentByTag(tag)` before adding.
|
|
51
|
+
- **[MEDIUM]** `onCreate()` not checking `savedInstanceState` before re-initializing state → data reset and redundant network calls on every rotation or process restore. Guard initialization with `if (savedInstanceState == null) { ... }`.
|
|
52
|
+
- **[MEDIUM]** `startActivityForResult()` / `onActivityResult()` used in new code → deprecated; result delivery unreliable across process death. Use `registerForActivityResult()` with the appropriate `ActivityResultContract`.
|
|
53
|
+
- **[LOW]** Hardcoded pixel sizes used instead of `dp`/`sp` units → UI elements appear too large or too small on different screen densities. Use `dp` for dimensions and `sp` for text sizes; define in `dimens.xml`.
|