@groupby/ai-dev 0.5.0 → 0.5.3

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.
@@ -0,0 +1,99 @@
1
+ # Reviewer Prompt Template
2
+
3
+ You are one member of a 3-model code review council. Your job is to independently
4
+ review the code changes below and produce high-signal findings. Another process
5
+ will compare your review against two other models' reviews to find consensus.
6
+
7
+ ## Your Review Constraints
8
+
9
+ - **Only flag things that genuinely matter.** Bugs, security issues, logic errors,
10
+ performance problems, missing error handling, test gaps for changed code.
11
+ - **Never comment on style, formatting, naming preferences, or trivial matters**
12
+ unless they cause a real problem (e.g., a misleading variable name that could
13
+ cause a bug).
14
+ - **Be specific.** Always include the file path, approximate line range, and a
15
+ concrete description of the problem.
16
+ - **Suggest a fix** when possible. Don't just say "this is wrong" — say what to do.
17
+ - **Don't be redundant.** If two issues share the same root cause, report it once.
18
+ - **Respect repo-specific rules.** The project context below includes this repo's
19
+ own conventions, technology profile, and CI expectations. Review against THOSE
20
+ rules, not generic best practices. Do not assume patterns from other repos.
21
+
22
+ ## Project Context
23
+
24
+ {PROJECT_CONTEXT}
25
+
26
+ This context was discovered from the repo's own guidance files, CI workflows,
27
+ build configuration, and technology markers. If the context mentions specific
28
+ patterns (e.g., Micronaut DI, tenant isolation, cache key format), verify the
29
+ diff follows them. If the context is silent on something, don't invent rules.
30
+
31
+ ## Technology Profile
32
+
33
+ {TECHNOLOGY_PROFILE}
34
+
35
+ ## Change Classification
36
+
37
+ {CHANGE_CLASSIFICATION}
38
+
39
+ ## Review Focus Areas (from repo's CI/review config)
40
+
41
+ Review against these standard areas, but weight them based on the change
42
+ classification above:
43
+
44
+ 1. **Code quality:** single responsibility, clarity, maintainability, unnecessary
45
+ complexity/nesting, redundant abstractions, local style conventions.
46
+ 2. **Security:** auth, authorization, tenant isolation, input validation, secrets,
47
+ sensitive data exposure.
48
+ 3. **Performance:** database/query shape, cache behavior, external calls,
49
+ async/blocking boundaries, memory/resource lifecycle.
50
+ 4. **Testing:** adequate coverage for changed code, edge cases, missing scenarios.
51
+ 5. **Documentation:** README/docs/OpenAPI/API docs accuracy when behavior changes.
52
+
53
+ ## Changed Files Summary
54
+
55
+ {DIFF_STAT}
56
+
57
+ ## Full Diff
58
+
59
+ {DIFF}
60
+
61
+ ## Output Format
62
+
63
+ Return your findings as a structured list. Each finding must follow this exact format:
64
+
65
+ ```
66
+ ### Finding <N>
67
+ - **File:** <path/to/file>
68
+ - **Lines:** <start>-<end> (approximate)
69
+ - **Severity:** P1 | P2 | P3
70
+ - **Category:** bug | security | performance | design | test-gap | error-handling | concurrency | data-integrity
71
+ - **Summary:** <one-line summary>
72
+ - **Details:** <1-3 sentences explaining the issue>
73
+ - **Suggestion:** <concrete fix or action>
74
+ ```
75
+
76
+ ### Severity Guide
77
+
78
+ - **P1 — Critical:** Likely bug, security vulnerability, data loss, crash, race condition,
79
+ or production incident. Must fix before merge.
80
+ - **P2 — Important:** Behavior regression, missing important test, incorrect error handling,
81
+ performance issue under realistic load. Should fix before merge.
82
+ - **P3 — Minor:** Low-risk test gap, minor inefficiency, documentation inaccuracy.
83
+ Nice to fix but not blocking.
84
+
85
+ ### What NOT to Report
86
+
87
+ - Style or formatting preferences
88
+ - "Consider renaming X" suggestions
89
+ - "Add a comment explaining Y" suggestions
90
+ - Import ordering
91
+ - Trailing whitespace
92
+ - Suggestions that don't prevent a real problem
93
+
94
+ If you find zero genuine issues, return:
95
+
96
+ ```
97
+ ### No Issues Found
98
+ The changes look correct. No bugs, security issues, or significant concerns identified.
99
+ ```
@@ -0,0 +1,54 @@
1
+ # Technology Profiles
2
+
3
+ Apply a profile **only** when discovered in the current repo's files.
4
+ Do not carry assumptions from one repo to another.
5
+
6
+ ## Java / Micronaut
7
+
8
+ - Check the Java version from workflow and Gradle config (do not assume 21 — some repos use 17).
9
+ - Use Micronaut compile-time DI patterns; avoid Spring Boot assumptions unless the repo is Spring-based.
10
+ - Prefer constructor injection and the Lombok annotations already used locally.
11
+ - Follow the repo's `var` rule (many Rezolve Java repos use `var` for new variables created with `new`).
12
+ - Check `@Singleton` vs `@Context` scope, `@Named` qualifiers, `@ExecuteOn` boundaries.
13
+ - Verify blocking operations are not on the event loop thread.
14
+
15
+ ## JOOQ / Flyway / Database
16
+
17
+ - Migration names and generated classes matter — check naming conventions.
18
+ - Check tenant isolation on queries and mutation side effects (events, audit logs).
19
+ - Verify transaction boundaries and connection management.
20
+
21
+ ## Search Services
22
+
23
+ - Check strategy and engine selection order.
24
+ - Ensure request builders, filters, refinements, biasing, pagination, and response builders preserve behavior.
25
+ - For Google Retail: check proto conversion, request fields, fallback behavior.
26
+ - For Mongo Atlas Search: check aggregation stages, index assumptions, field paths, unsupported Google-only features.
27
+ - For Redis caches: check key composition, tenant/collection/area isolation, TTLs, skip-cache paths.
28
+
29
+ ## Mongo Data / Indexing
30
+
31
+ - Check collection and tenant scoping.
32
+ - Check aggregation pipeline correctness, projections, variant/inventory handling.
33
+ - Check index definition generation, conditional indexing, feature flags.
34
+
35
+ ## Authentication / Security
36
+
37
+ - Check token validation, claims, expiration, signature algorithms, public endpoint boundaries.
38
+ - Check Redis key storage, key rotation, secret handling.
39
+ - Check Pub/Sub credential update idempotency.
40
+
41
+ ## Go / Python / Node
42
+
43
+ - Prefer repo-provided commands from Makefile, package files, workflow files, or docs.
44
+ - Keep tests close to the changed package/module.
45
+ - Check schema/serialization compatibility and environment variable handling.
46
+ - Do not import Java/Micronaut assumptions into these repos.
47
+
48
+ ## General (all profiles)
49
+
50
+ - **Code quality:** Single responsibility, clarity, maintainability, unnecessary complexity.
51
+ - **Security:** Auth, authorization, tenant isolation, input validation, secrets.
52
+ - **Performance:** Database/query shape, cache behavior, external calls, async/blocking.
53
+ - **Testing:** Adequate coverage for changed code, edge cases, no superfluous tests.
54
+ - **Documentation:** README/docs/OpenAPI accuracy when behavior changes.
@@ -0,0 +1,226 @@
1
+ #!/usr/bin/env python3
2
+ """Summarize PR review and CI configuration for a repository.
3
+
4
+ Repo-agnostic: takes the repository root as its argument (defaults to the current
5
+ directory) and works on any project. Uses only the Python standard library so it
6
+ can run in sandboxes without installing PyYAML or other dependencies.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+ import re
13
+ from pathlib import Path
14
+
15
+
16
+ GUIDANCE_FILES = [
17
+ ".github/copilot-instructions.md",
18
+ "CLAUDE.md",
19
+ "AGENTS.md",
20
+ "README.md",
21
+ "docs/conventions.md",
22
+ "docs/project-rule.md",
23
+ "docs/source-control.md",
24
+ ]
25
+
26
+ REVIEW_FILES = [
27
+ ".github/workflows/claude-pr-review.yml",
28
+ ".github/workflows/claude.yml",
29
+ ".github/workflows/build-pr.yaml",
30
+ ".github/PULL_REQUEST_TEMPLATE.md",
31
+ ".github/CODEOWNERS",
32
+ ]
33
+
34
+ BUILD_FILES = [
35
+ "build.gradle",
36
+ "build.gradle.kts",
37
+ "settings.gradle",
38
+ "gradle.properties",
39
+ "pom.xml",
40
+ "go.mod",
41
+ "Makefile",
42
+ "pyproject.toml",
43
+ "requirements.txt",
44
+ "package.json",
45
+ ]
46
+
47
+ KEYWORDS = [
48
+ "Micronaut",
49
+ "Java 21",
50
+ "Java 17",
51
+ "Spring",
52
+ "Lombok",
53
+ "Spock",
54
+ "JUnit",
55
+ "Mockito",
56
+ "Testcontainers",
57
+ "JOOQ",
58
+ "jOOQ",
59
+ "Flyway",
60
+ "PostgreSQL",
61
+ "Mongo",
62
+ "Redis",
63
+ "Google Retail",
64
+ "Command Center",
65
+ "Pub/Sub",
66
+ "BigQuery",
67
+ "LaunchDarkly",
68
+ "ANTLR",
69
+ "Kafka",
70
+ "JWT",
71
+ "Docker",
72
+ "Jib",
73
+ ]
74
+
75
+
76
+ def read(path: Path) -> str:
77
+ try:
78
+ return path.read_text(errors="replace")
79
+ except FileNotFoundError:
80
+ return ""
81
+
82
+
83
+ def existing(root: Path, paths: list[str]) -> list[Path]:
84
+ return [root / path for path in paths if (root / path).exists()]
85
+
86
+
87
+ def first_match(pattern: str, text: str) -> str | None:
88
+ match = re.search(pattern, text, re.MULTILINE)
89
+ return match.group(1).strip() if match else None
90
+
91
+
92
+ def command_lines(text: str) -> list[str]:
93
+ commands: list[str] = []
94
+ for line in text.splitlines():
95
+ stripped = line.strip()
96
+ candidate = stripped
97
+ if stripped.startswith("run:"):
98
+ candidate = stripped.removeprefix("run:").strip()
99
+ if re.match(r"^(\.?/gradlew|gradle|mvn|make|go\s+test|pytest|npm|pnpm|yarn|docker)\b", candidate):
100
+ commands.append(candidate)
101
+ return commands
102
+
103
+
104
+ def pr_checkboxes(text: str) -> list[str]:
105
+ checks = []
106
+ for line in text.splitlines():
107
+ if re.match(r"\s*-\s+\[[ xX]\]", line):
108
+ checks.append(line.strip())
109
+ return checks
110
+
111
+
112
+ def collect_keywords(text: str) -> list[str]:
113
+ found = []
114
+ lower_text = text.lower()
115
+ for keyword in KEYWORDS:
116
+ if keyword.lower() in lower_text:
117
+ found.append(keyword)
118
+ normalized = []
119
+ seen = set()
120
+ for keyword in found:
121
+ key = keyword.lower()
122
+ if key not in seen:
123
+ seen.add(key)
124
+ normalized.append(keyword)
125
+ return sorted(normalized, key=str.lower)
126
+
127
+
128
+ def main() -> int:
129
+ parser = argparse.ArgumentParser(description=__doc__)
130
+ parser.add_argument("repo", nargs="?", default=".", help="Repository root")
131
+ args = parser.parse_args()
132
+
133
+ root = Path(args.repo).resolve()
134
+ print(f"# PR Review Configuration Summary\n")
135
+ print(f"Repository: `{root}`\n")
136
+
137
+ review_files = existing(root, REVIEW_FILES)
138
+ guidance_files = existing(root, GUIDANCE_FILES)
139
+ build_files = existing(root, BUILD_FILES)
140
+
141
+ print("## Files Found\n")
142
+ for title, files in [
143
+ ("Review/CI", review_files),
144
+ ("Guidance", guidance_files),
145
+ ("Build", build_files),
146
+ ]:
147
+ print(f"### {title}")
148
+ if files:
149
+ for path in files:
150
+ print(f"- `{path.relative_to(root)}`")
151
+ else:
152
+ print("- none")
153
+ print()
154
+
155
+ claude_text = read(root / ".github/workflows/claude-pr-review.yml")
156
+ if not claude_text:
157
+ claude_text = read(root / ".github/workflows/claude.yml")
158
+ build_text = read(root / ".github/workflows/build-pr.yaml")
159
+ pr_template = read(root / ".github/PULL_REQUEST_TEMPLATE.md")
160
+ codeowners = read(root / ".github/CODEOWNERS")
161
+ guidance_text = "\n\n".join(read(path) for path in guidance_files)
162
+ build_texts = "\n\n".join(read(path) for path in build_files)
163
+
164
+ print("## Claude Review\n")
165
+ if claude_text:
166
+ triggers = re.findall(r"types:\s*\[([^\]]+)\]", claude_text)
167
+ model = first_match(r"--model\s+([^\s]+)", claude_text)
168
+ print(f"- Workflow present: yes")
169
+ print(f"- Trigger type lists: {', '.join(triggers) if triggers else 'not parsed'}")
170
+ print(f"- Model: {model or 'not parsed'}")
171
+ print("- Standard focus areas present:")
172
+ for area in ["Code Quality", "Security", "Performance", "Testing", "Documentation"]:
173
+ print(f" - {area}: {'yes' if area in claude_text else 'not found'}")
174
+ else:
175
+ print("- Workflow present: no")
176
+ print()
177
+
178
+ print("## PR CI Commands\n")
179
+ commands = command_lines(build_text)
180
+ if commands:
181
+ for command in commands:
182
+ print(f"- `{command}`")
183
+ else:
184
+ print("- none parsed")
185
+ print()
186
+
187
+ java_version = first_match(r"java-version:\s*['\"]?([^'\"\n]+)", build_text)
188
+ if java_version:
189
+ print(f"Java version from PR workflow: `{java_version}`\n")
190
+
191
+ print("## PR Template Checks\n")
192
+ checks = pr_checkboxes(pr_template)
193
+ if checks:
194
+ for check in checks:
195
+ print(f"- {check}")
196
+ else:
197
+ print("- none")
198
+ print()
199
+
200
+ print("## CODEOWNERS\n")
201
+ owners = [line.strip() for line in codeowners.splitlines() if line.strip() and not line.strip().startswith("#")]
202
+ if owners:
203
+ for owner in owners:
204
+ print(f"- `{owner}`")
205
+ else:
206
+ print("- none")
207
+ print()
208
+
209
+ print("## Detected Keywords\n")
210
+ keywords = collect_keywords("\n\n".join([guidance_text, build_texts, claude_text, build_text]))
211
+ if keywords:
212
+ for keyword in keywords:
213
+ print(f"- {keyword}")
214
+ else:
215
+ print("- none")
216
+ print()
217
+
218
+ print("## Suggested Next Steps\n")
219
+ print("- Review changed files against the discovered keywords and guidance files.")
220
+ print("- Run targeted tests first, then the PR build command if feasible.")
221
+ print("- Run `git diff --check` before final output.")
222
+ return 0
223
+
224
+
225
+ if __name__ == "__main__":
226
+ raise SystemExit(main())