pr-context-engine 0.1.3__tar.gz → 0.1.4__tar.gz
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.
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/CHANGELOG.md +12 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/PKG-INFO +1 -1
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/pyproject.toml +1 -1
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/analyzers/risk_scorer.py +47 -1
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/briefing/prompt_templates.py +6 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/unit/test_risk_scorer.py +103 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/.claude/commands/publish-pypi.md +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/.env.example +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/.github/pull_request_template.md +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/.github/workflows/pr-review.yml +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/.github/workflows/release.yml +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/.gitignore +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/.python-version +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/CODE_OF_CONDUCT.md +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/CONFIG.md +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/CONTRIBUTING.md +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/LICENSE +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/README.md +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/action.yml +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/docs/architecture.md +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/docs/design-decisions.md +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/__init__.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/analyzers/__init__.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/analyzers/ast_walker.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/analyzers/diff_parser.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/briefing/__init__.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/briefing/generator.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/cli.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/config.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/context/__init__.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/context/codebase_index.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/context/git_history.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/fixes/__init__.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/fixes/confidence.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/fixes/fix_generator.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/github_api/__init__.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/github_api/comment_poster.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/llm/__init__.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/llm/anthropic_provider.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/llm/base.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/llm/gemini_provider.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/llm/groq_provider.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/src/llm/ollama_provider.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/__init__.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/__init__.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/01-simple-refactor.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/02-auth-middleware.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/03-db-migration.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/04-config-update.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/05-public-api-deleted.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/06-hardcoded-api-key.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/07-token-in-url.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/08-retry-no-limit.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/09-missing-null-check.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/10-trivial-docfix.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/11-multi-flag.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/12-new-endpoint.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/13-auth-bypass.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/14-env-file-update.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/15-dependency-update.json +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/rubric.md +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/test_briefings.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/unit/__init__.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/unit/test_anthropic_provider.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/unit/test_ast_walker.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/unit/test_briefing_generator.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/unit/test_codebase_index.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/unit/test_config.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/unit/test_diff_parser.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/unit/test_failover_provider.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/unit/test_fix_generator.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/unit/test_gemini_provider.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/unit/test_git_history.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/unit/test_groq_provider.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/unit/test_ollama_provider.py +0 -0
- {pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/uv.lock +0 -0
|
@@ -6,6 +6,18 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Thi
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## 0.1.4 — 2026-05-23
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **Risk scorer false positives** — Comment lines (including `#no-space` Python comments) and bare type/struct/class declarations are now skipped before the auth-keyword check, eliminating spurious `modifies_auth` flags on struct definitions and comment blocks.
|
|
14
|
+
- **Auth flag noise** — `modifies_auth` is now deduplicated to one hit per file; large new store files no longer flood the briefing with dozens of identical flags.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`large_new_file` flag** — New files with 300+ added lines are flagged for explicit review.
|
|
19
|
+
- **Briefing prompt improvements** — LLM is instructed to cover all change threads (not just the largest file), name changed type signatures explicitly, and avoid asking questions whose answers are already visible in the diff.
|
|
20
|
+
|
|
9
21
|
## 0.1.3 — 2026-05-23
|
|
10
22
|
|
|
11
23
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pr-context-engine
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: An AI tool that reads every PR and posts a senior-engineer-style briefing.
|
|
5
5
|
Project-URL: Homepage, https://github.com/paramahastha/pr-context-engine
|
|
6
6
|
Project-URL: Repository, https://github.com/paramahastha/pr-context-engine
|
|
@@ -27,6 +27,18 @@ _FUNC_DEF_RE = re.compile(
|
|
|
27
27
|
|
|
28
28
|
_MIGRATION_MARKERS = ("migrations/", "alembic/", "alembic_migrations/")
|
|
29
29
|
|
|
30
|
+
# Lines that look auth-related by keyword but carry no real risk:
|
|
31
|
+
# - comment lines (// # /* * <!--)
|
|
32
|
+
# - bare type/struct/class/interface declarations
|
|
33
|
+
_COMMENT_LINE_RE = re.compile(r"^\s*(?://|/\*|\*+/?\s|#|<!--)")
|
|
34
|
+
_TYPE_DECL_RE = re.compile(
|
|
35
|
+
r"^\s*type\s+\w+\s+(?:struct|interface)\b" # Go struct/interface
|
|
36
|
+
r"|^\s*type\s+\w+\s*(?:=|\b(?:int|string|float|bool)\b)" # Go type alias/definition
|
|
37
|
+
r"|^\s*(?:class|interface)\s+\w+" # Python / JS / TS
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
_LARGE_NEW_FILE_THRESHOLD = 300 # added lines; new files above this warrant explicit review
|
|
41
|
+
|
|
30
42
|
|
|
31
43
|
@dataclass
|
|
32
44
|
class RiskFlag:
|
|
@@ -64,6 +76,26 @@ def _is_config(path: str) -> bool:
|
|
|
64
76
|
return False
|
|
65
77
|
|
|
66
78
|
|
|
79
|
+
def _dedup_flags(flags: list[RiskFlag]) -> list[RiskFlag]:
|
|
80
|
+
"""Deduplicate flags where one occurrence per file is enough.
|
|
81
|
+
|
|
82
|
+
modifies_auth fires once per matching line and can produce dozens of hits
|
|
83
|
+
in a large file (e.g. a new store implementation). Keeping only the first
|
|
84
|
+
match per file preserves the signal while eliminating fix-suggestion spam.
|
|
85
|
+
Other flag types are kept as-is because each occurrence is independently
|
|
86
|
+
meaningful (e.g. multiple deletes_public_api deletions).
|
|
87
|
+
"""
|
|
88
|
+
seen_auth_files: set[str] = set()
|
|
89
|
+
result: list[RiskFlag] = []
|
|
90
|
+
for flag in flags:
|
|
91
|
+
if flag.flag == "modifies_auth":
|
|
92
|
+
if flag.file in seen_auth_files:
|
|
93
|
+
continue
|
|
94
|
+
seen_auth_files.add(flag.file)
|
|
95
|
+
result.append(flag)
|
|
96
|
+
return result
|
|
97
|
+
|
|
98
|
+
|
|
67
99
|
def score(changes: list[FileChange]) -> list[RiskFlag]:
|
|
68
100
|
"""Return all risk flags detected across the list of file changes."""
|
|
69
101
|
flags: list[RiskFlag] = []
|
|
@@ -79,6 +111,16 @@ def score(changes: list[FileChange]) -> list[RiskFlag]:
|
|
|
79
111
|
RiskFlag(flag="changes_config", file=change.path, line=None, snippet=change.path)
|
|
80
112
|
)
|
|
81
113
|
|
|
114
|
+
if change.is_new_file and len(change.added_lines) >= _LARGE_NEW_FILE_THRESHOLD:
|
|
115
|
+
flags.append(
|
|
116
|
+
RiskFlag(
|
|
117
|
+
flag="large_new_file",
|
|
118
|
+
file=change.path,
|
|
119
|
+
line=None,
|
|
120
|
+
snippet=f"{len(change.added_lines)} lines added — review for correctness and completeness",
|
|
121
|
+
)
|
|
122
|
+
)
|
|
123
|
+
|
|
82
124
|
for hunk in change.hunks:
|
|
83
125
|
new_lineno = hunk.new_start
|
|
84
126
|
old_lineno = hunk.old_start
|
|
@@ -86,6 +128,10 @@ def score(changes: list[FileChange]) -> list[RiskFlag]:
|
|
|
86
128
|
for raw in hunk.lines:
|
|
87
129
|
if raw.startswith("+") and not raw.startswith("+++"):
|
|
88
130
|
content = raw[1:]
|
|
131
|
+
stripped = content.strip()
|
|
132
|
+
if _COMMENT_LINE_RE.match(stripped) or _TYPE_DECL_RE.match(stripped):
|
|
133
|
+
new_lineno += 1
|
|
134
|
+
continue
|
|
89
135
|
if _AUTH_RE.search(content):
|
|
90
136
|
flags.append(
|
|
91
137
|
RiskFlag(
|
|
@@ -118,4 +164,4 @@ def score(changes: list[FileChange]) -> list[RiskFlag]:
|
|
|
118
164
|
new_lineno += 1
|
|
119
165
|
old_lineno += 1
|
|
120
166
|
|
|
121
|
-
return flags
|
|
167
|
+
return _dedup_flags(flags)
|
|
@@ -18,9 +18,13 @@ Produce a briefing with exactly four sections:
|
|
|
18
18
|
|
|
19
19
|
1. WHAT CHANGED — 2-3 sentences. Describe the *intent* of the change, not the
|
|
20
20
|
lines. Do not list files. If you can't tell the intent, say so.
|
|
21
|
+
If the PR has multiple distinct threads (e.g. both new infrastructure and
|
|
22
|
+
model/API changes), cover all threads — do not describe only the largest file.
|
|
21
23
|
|
|
22
24
|
2. BLAST RADIUS — Which callers, services, contracts, or data could break?
|
|
23
25
|
Be specific. If the change is internal and self-contained, write "Self-contained."
|
|
26
|
+
If any public-facing struct field or type signature changed, name it explicitly
|
|
27
|
+
(e.g. "Snapshot.Configs changed from map[string]Config to map[string]ConfigEntry").
|
|
24
28
|
|
|
25
29
|
3. RISK FLAGS — Bullet list. Only include flags that are actually present.
|
|
26
30
|
If none, write "None."
|
|
@@ -29,6 +33,8 @@ Produce a briefing with exactly four sections:
|
|
|
29
33
|
approving. Questions must be answerable and specific. Bad question:
|
|
30
34
|
"Did you test this?" Good question: "The new retry loop in fetch_user
|
|
31
35
|
has no backoff — is that intentional given this is called per-request?"
|
|
36
|
+
Do NOT ask questions whose answer is already visible in the diff (e.g. do
|
|
37
|
+
not ask about WAL mode if the schema already sets PRAGMA journal_mode=WAL).
|
|
32
38
|
|
|
33
39
|
Rules:
|
|
34
40
|
- Be terse. Aim for under 200 words total.
|
|
@@ -4,6 +4,20 @@ from src.analyzers.diff_parser import FileChange, Hunk
|
|
|
4
4
|
from src.analyzers.risk_scorer import score
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
def _new_file_change(path: str, num_lines: int) -> FileChange:
|
|
8
|
+
lines = [f"+ x_{i} = {i}" for i in range(num_lines)]
|
|
9
|
+
h = Hunk(old_start=0, old_count=0, new_start=1, new_count=num_lines, lines=lines)
|
|
10
|
+
added = [ln[1:] for ln in lines]
|
|
11
|
+
return FileChange(
|
|
12
|
+
path=path,
|
|
13
|
+
language="python",
|
|
14
|
+
added_lines=added,
|
|
15
|
+
removed_lines=[],
|
|
16
|
+
hunks=[h],
|
|
17
|
+
is_new_file=True,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
7
21
|
def _hunk(old_start: int, new_start: int, lines: list[str]) -> Hunk:
|
|
8
22
|
added = sum(1 for ln in lines if ln.startswith("+") and not ln.startswith("+++"))
|
|
9
23
|
removed = sum(1 for ln in lines if ln.startswith("-") and not ln.startswith("---"))
|
|
@@ -176,3 +190,92 @@ def test_no_flags_for_plain_change():
|
|
|
176
190
|
c = _change("src/constants.py", [h])
|
|
177
191
|
flags = score([c])
|
|
178
192
|
assert flags == []
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
# ── comment and type-decl false-positive suppression ─────────────────────────
|
|
196
|
+
|
|
197
|
+
def test_python_comment_without_space_not_flagged():
|
|
198
|
+
# Previously `#\s` required a space, so `#token` slipped through.
|
|
199
|
+
h = _hunk(1, 1, ['+#auth_token = request.headers.get("X-Token")'])
|
|
200
|
+
c = _change("src/auth.py", [h])
|
|
201
|
+
assert not any(f.flag == "modifies_auth" for f in score([c]))
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def test_python_comment_with_space_not_flagged():
|
|
205
|
+
h = _hunk(1, 1, ['+# store the auth token here'])
|
|
206
|
+
c = _change("src/auth.py", [h])
|
|
207
|
+
assert not any(f.flag == "modifies_auth" for f in score([c]))
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def test_go_line_comment_not_flagged():
|
|
211
|
+
h = _hunk(1, 1, ['+// token is validated upstream'])
|
|
212
|
+
c = _change("pkg/handler.go", [h], language="go")
|
|
213
|
+
assert not any(f.flag == "modifies_auth" for f in score([c]))
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def test_go_struct_decl_not_flagged():
|
|
217
|
+
h = _hunk(1, 1, ['+type AuthStore struct {'])
|
|
218
|
+
c = _change("pkg/store.go", [h], language="go")
|
|
219
|
+
assert not any(f.flag == "modifies_auth" for f in score([c]))
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def test_python_class_decl_not_flagged():
|
|
223
|
+
h = _hunk(1, 1, ['+class AuthManager:'])
|
|
224
|
+
c = _change("src/auth.py", [h])
|
|
225
|
+
assert not any(f.flag == "modifies_auth" for f in score([c]))
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def test_python_class_with_base_not_flagged():
|
|
229
|
+
h = _hunk(1, 1, ['+class AuthManager(BaseManager):'])
|
|
230
|
+
c = _change("src/auth.py", [h])
|
|
231
|
+
assert not any(f.flag == "modifies_auth" for f in score([c]))
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
# ── modifies_auth deduplication ───────────────────────────────────────────────
|
|
235
|
+
|
|
236
|
+
def test_auth_deduped_within_file():
|
|
237
|
+
lines = ['+ token_a = get_token()', '+ token_b = get_token()', '+ password = "secret"']
|
|
238
|
+
h = _hunk(1, 1, lines)
|
|
239
|
+
c = _change("src/auth.py", [h])
|
|
240
|
+
auth_flags = [f for f in score([c]) if f.flag == "modifies_auth"]
|
|
241
|
+
assert len(auth_flags) == 1
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def test_auth_not_deduped_across_files():
|
|
245
|
+
h = _hunk(1, 1, ['+ token = get_token()'])
|
|
246
|
+
c1 = _change("src/auth.py", [h])
|
|
247
|
+
c2 = _change("src/user.py", [h])
|
|
248
|
+
auth_flags = [f for f in score([c1, c2]) if f.flag == "modifies_auth"]
|
|
249
|
+
assert len(auth_flags) == 2
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def test_auth_dedup_preserves_first_match_line():
|
|
253
|
+
lines = ['+ password_a = "x"', '+ password_b = "y"']
|
|
254
|
+
h = _hunk(10, 10, lines)
|
|
255
|
+
c = _change("src/auth.py", [h])
|
|
256
|
+
auth_flags = [f for f in score([c]) if f.flag == "modifies_auth"]
|
|
257
|
+
assert auth_flags[0].line == 10
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
# ── large_new_file ────────────────────────────────────────────────────────────
|
|
261
|
+
|
|
262
|
+
def test_large_new_file_flagged():
|
|
263
|
+
c = _new_file_change("src/new_store.py", 300)
|
|
264
|
+
assert any(f.flag == "large_new_file" for f in score([c]))
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def test_boundary_new_file_flagged():
|
|
268
|
+
c = _new_file_change("src/new_store.py", 301)
|
|
269
|
+
assert any(f.flag == "large_new_file" for f in score([c]))
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def test_small_new_file_not_flagged():
|
|
273
|
+
c = _new_file_change("src/tiny.py", 50)
|
|
274
|
+
assert not any(f.flag == "large_new_file" for f in score([c]))
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def test_large_existing_file_not_flagged():
|
|
278
|
+
lines = [f"+ x_{i} = {i}" for i in range(300)]
|
|
279
|
+
h = _hunk(1, 1, lines)
|
|
280
|
+
c = _change("src/existing.py", [h])
|
|
281
|
+
assert not any(f.flag == "large_new_file" for f in score([c]))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/.github/ISSUE_TEMPLATE/feature_request.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/01-simple-refactor.json
RENAMED
|
File without changes
|
{pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/02-auth-middleware.json
RENAMED
|
File without changes
|
{pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/03-db-migration.json
RENAMED
|
File without changes
|
{pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/04-config-update.json
RENAMED
|
File without changes
|
{pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/05-public-api-deleted.json
RENAMED
|
File without changes
|
{pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/06-hardcoded-api-key.json
RENAMED
|
File without changes
|
{pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/07-token-in-url.json
RENAMED
|
File without changes
|
{pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/08-retry-no-limit.json
RENAMED
|
File without changes
|
{pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/09-missing-null-check.json
RENAMED
|
File without changes
|
{pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/10-trivial-docfix.json
RENAMED
|
File without changes
|
|
File without changes
|
{pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/12-new-endpoint.json
RENAMED
|
File without changes
|
|
File without changes
|
{pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/14-env-file-update.json
RENAMED
|
File without changes
|
{pr_context_engine-0.1.3 → pr_context_engine-0.1.4}/tests/eval/fixtures/15-dependency-update.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|