technophyle commited on
Commit
087c947
·
verified ·
1 Parent(s): 0815510

Sync from GitHub via hub-sync

Browse files
Files changed (3) hide show
  1. evals/run_eval.py +38 -7
  2. evals/sample_eval_set.json +607 -448
  3. src/repo_fetcher.py +15 -1
evals/run_eval.py CHANGED
@@ -220,9 +220,14 @@ def compute_retrieval_metrics(expected_sources, actual_sources):
220
 
221
  def matches_expected(actual_path: str) -> bool:
222
  for expected_path in expected:
 
 
 
 
 
223
  if actual_path == expected_path:
224
  return True
225
- if "/" not in expected_path and actual_path.startswith(expected_path.rstrip("/") + "/"):
226
  return True
227
  return False
228
 
@@ -231,9 +236,14 @@ def compute_retrieval_metrics(expected_sources, actual_sources):
231
  if expected:
232
  matched_expected = set()
233
  for expected_path in expected:
 
 
 
 
 
234
  for actual_path in actual:
235
  if actual_path == expected_path or (
236
- "/" not in expected_path and actual_path.startswith(expected_path.rstrip("/") + "/")
237
  ):
238
  matched_expected.add(expected_path)
239
  break
@@ -355,6 +365,11 @@ def validate_eval_rows(rows):
355
  expected_source_counts = []
356
  keyword_counts = []
357
  conversation_cases = 0
 
 
 
 
 
358
 
359
  for index, row in enumerate(rows, start=1):
360
  row_id = row.get("id") or f"row-{index}"
@@ -407,10 +422,13 @@ def validate_eval_rows(rows):
407
 
408
  if id_prefix_counts:
409
  dominant_prefix, dominant_count = id_prefix_counts.most_common(1)[0]
410
- if dominant_count / len(rows) >= 0.8:
411
- warnings.append(
412
- f"Most cases share the same id prefix ({dominant_prefix}), which suggests a benchmark focused on one target project."
413
- )
 
 
 
414
 
415
  return {
416
  "case_count": len(rows),
@@ -418,6 +436,7 @@ def validate_eval_rows(rows):
418
  "conversation_case_count": conversation_cases,
419
  "average_expected_sources": round(mean(expected_source_counts), 2) if expected_source_counts else 0.0,
420
  "average_keywords_per_case": round(mean(keyword_counts), 2) if keyword_counts else 0.0,
 
421
  "errors": errors,
422
  "warnings": warnings,
423
  "is_valid": not errors,
@@ -582,6 +601,13 @@ def build_resume_summary(custom_metrics, audit, ragas_report, ragas_error):
582
  else:
583
  lines.append("LLM-judge metrics were skipped or unstable, so headline metrics rely on deterministic checks.")
584
 
 
 
 
 
 
 
 
585
  if audit["warnings"]:
586
  lines.append(
587
  "Benchmark caveat: "
@@ -600,7 +626,7 @@ def benchmark_readiness(audit, ragas_error):
600
  if audit["conversation_case_count"] < 2:
601
  reasons.append("limited_multi_turn_coverage")
602
  if audit["warnings"]:
603
- reasons.append("dataset_scope_warnings")
604
  if ragas_error not in {None, "disabled"}:
605
  reasons.append("ragas_instability")
606
 
@@ -609,6 +635,11 @@ def benchmark_readiness(audit, ragas_error):
609
  "status": "internal_or_demo_benchmark",
610
  "reasons": reasons,
611
  }
 
 
 
 
 
612
  return {
613
  "status": "presentation_ready",
614
  "reasons": [],
 
220
 
221
  def matches_expected(actual_path: str) -> bool:
222
  for expected_path in expected:
223
+ expected_is_directory = (
224
+ expected_path.endswith("/")
225
+ or "." not in expected_path.rsplit("/", 1)[-1]
226
+ )
227
+ normalized_expected = expected_path.rstrip("/")
228
  if actual_path == expected_path:
229
  return True
230
+ if expected_is_directory and actual_path.startswith(normalized_expected + "/"):
231
  return True
232
  return False
233
 
 
236
  if expected:
237
  matched_expected = set()
238
  for expected_path in expected:
239
+ expected_is_directory = (
240
+ expected_path.endswith("/")
241
+ or "." not in expected_path.rsplit("/", 1)[-1]
242
+ )
243
+ normalized_expected = expected_path.rstrip("/")
244
  for actual_path in actual:
245
  if actual_path == expected_path or (
246
+ expected_is_directory and actual_path.startswith(normalized_expected + "/")
247
  ):
248
  matched_expected.add(expected_path)
249
  break
 
365
  expected_source_counts = []
366
  keyword_counts = []
367
  conversation_cases = 0
368
+ benchmark_scope = {
369
+ "type": "mixed_or_unknown",
370
+ "dominant_prefix": None,
371
+ "dominant_prefix_fraction": 0.0,
372
+ }
373
 
374
  for index, row in enumerate(rows, start=1):
375
  row_id = row.get("id") or f"row-{index}"
 
422
 
423
  if id_prefix_counts:
424
  dominant_prefix, dominant_count = id_prefix_counts.most_common(1)[0]
425
+ dominant_prefix_fraction = dominant_count / len(rows)
426
+ if dominant_prefix_fraction >= 0.8:
427
+ benchmark_scope = {
428
+ "type": "single_repository",
429
+ "dominant_prefix": dominant_prefix,
430
+ "dominant_prefix_fraction": round(dominant_prefix_fraction, 4),
431
+ }
432
 
433
  return {
434
  "case_count": len(rows),
 
436
  "conversation_case_count": conversation_cases,
437
  "average_expected_sources": round(mean(expected_source_counts), 2) if expected_source_counts else 0.0,
438
  "average_keywords_per_case": round(mean(keyword_counts), 2) if keyword_counts else 0.0,
439
+ "benchmark_scope": benchmark_scope,
440
  "errors": errors,
441
  "warnings": warnings,
442
  "is_valid": not errors,
 
601
  else:
602
  lines.append("LLM-judge metrics were skipped or unstable, so headline metrics rely on deterministic checks.")
603
 
604
+ scope = audit.get("benchmark_scope", {})
605
+ if scope.get("type") == "single_repository":
606
+ lines.append(
607
+ "Benchmark scope: single-repository benchmark "
608
+ f"({scope.get('dominant_prefix')}); use it to judge this target repo, not cross-repo generalization."
609
+ )
610
+
611
  if audit["warnings"]:
612
  lines.append(
613
  "Benchmark caveat: "
 
626
  if audit["conversation_case_count"] < 2:
627
  reasons.append("limited_multi_turn_coverage")
628
  if audit["warnings"]:
629
+ reasons.append("eval_set_warnings")
630
  if ragas_error not in {None, "disabled"}:
631
  reasons.append("ragas_instability")
632
 
 
635
  "status": "internal_or_demo_benchmark",
636
  "reasons": reasons,
637
  }
638
+ if audit.get("benchmark_scope", {}).get("type") == "single_repository":
639
+ return {
640
+ "status": "single_repo_benchmark_ready",
641
+ "reasons": [],
642
+ }
643
  return {
644
  "status": "presentation_ready",
645
  "reasons": [],
evals/sample_eval_set.json CHANGED
@@ -1,729 +1,888 @@
1
  [
2
  {
3
- "id": "sqlmodel-purpose",
4
  "category": "architecture",
5
- "question": "What is SQLModel and how is it positioned relative to Pydantic and SQLAlchemy?",
6
- "ground_truth": "SQLModel is a thin layer designed to combine Pydantic-style data modeling with SQLAlchemy ORM and SQL expression features. The project presents itself as a library for SQL databases in Python that emphasizes simplicity, compatibility, and robustness while being built on top of Pydantic and SQLAlchemy.",
7
  "expected_sources": [
8
  "README.md",
9
- "sqlmodel/__init__.py",
10
- "sqlmodel/main.py"
11
  ],
12
  "must_include_any": [
13
- "Pydantic",
14
- "SQLAlchemy",
15
- "thin layer"
 
16
  ],
17
  "min_keyword_matches": 2
18
  },
19
  {
20
- "id": "sqlmodel-core-model-class",
21
  "category": "architecture",
22
- "question": "Where is the core SQLModel base class defined and what is its role?",
23
- "ground_truth": "The SQLModel base class is defined in sqlmodel/main.py. It acts as the main model base that bridges typed field definitions, Pydantic-compatible validation behavior, and SQLAlchemy table or ORM metadata.",
24
  "expected_sources": [
25
- "sqlmodel/main.py"
 
 
 
 
26
  ],
27
  "must_include_any": [
28
- "SQLModel",
29
- "base class",
30
- "Pydantic",
31
- "SQLAlchemy"
32
  ],
33
- "min_keyword_matches": 2
34
  },
35
  {
36
- "id": "sqlmodel-field-helper",
37
  "category": "architecture",
38
- "question": "How does SQLModel expose field declarations for model attributes?",
39
- "ground_truth": "SQLModel exposes a Field helper in sqlmodel/main.py and re-exports it at the package level. Field collects model metadata such as defaults, primary key flags, indexes, foreign keys, nullability, and other column-related settings used when building SQL-backed models.",
40
  "expected_sources": [
41
- "sqlmodel/main.py",
42
- "sqlmodel/__init__.py"
 
 
43
  ],
44
  "must_include_any": [
45
- "Field",
46
- "primary key",
47
- "foreign key",
48
- "re-export"
49
  ],
50
  "min_keyword_matches": 2
51
  },
52
  {
53
- "id": "sqlmodel-relationship-helper",
54
  "category": "architecture",
55
- "question": "How are relationships modeled in SQLModel?",
56
- "ground_truth": "Relationships are declared through the Relationship helper and associated metadata in sqlmodel/main.py. SQLModel captures relationship configuration separately from normal field definitions so relationship behavior can be translated into SQLAlchemy ORM relationship setup.",
57
  "expected_sources": [
58
- "sqlmodel/main.py",
59
- "sqlmodel/__init__.py"
 
 
 
 
 
 
60
  ],
61
  "must_include_any": [
62
- "Relationship",
63
- "SQLAlchemy",
64
- "metadata"
 
 
65
  ],
66
- "min_keyword_matches": 2
67
  },
68
  {
69
- "id": "sqlmodel-field-function",
70
- "category": "specific-function",
71
- "question": "What does the Field() function do in SQLModel?",
72
- "ground_truth": "Field defines metadata for a model attribute, including validation defaults and SQL column configuration such as primary_key, foreign_key, index, nullable, sa_type, or sa_column options. SQLModel uses that metadata when constructing models that can also map to tables.",
73
  "expected_sources": [
74
- "sqlmodel/main.py"
 
 
 
75
  ],
76
  "must_include_any": [
77
- "Field",
78
- "primary_key",
79
- "nullable",
80
- "column"
 
81
  ],
82
- "min_keyword_matches": 2
83
  },
84
  {
85
- "id": "sqlmodel-relationship-function",
86
- "category": "specific-function",
87
- "question": "What does Relationship() do in SQLModel?",
88
- "ground_truth": "Relationship captures relationship-specific configuration for ORM links between models, such as back_populates and SQLAlchemy relationship arguments. It provides structured metadata that SQLModel can later translate into SQLAlchemy relationship objects.",
89
  "expected_sources": [
90
- "sqlmodel/main.py"
91
  ],
92
  "must_include_any": [
93
- "Relationship",
94
- "back_populates",
95
- "metadata"
 
96
  ],
97
  "min_keyword_matches": 2
98
  },
99
  {
100
- "id": "sqlmodel-session-exec",
101
- "category": "specific-function",
102
- "question": "What is special about Session.exec() in SQLModel?",
103
- "ground_truth": "SQLModel provides a Session class with an exec helper that offers a friendlier typed wrapper around SQLAlchemy execution patterns, especially for SQLModel select statements. It is intended to make common query execution more ergonomic than raw SQLAlchemy session.execute calls.",
104
  "expected_sources": [
105
- "sqlmodel/orm/session.py",
106
- "sqlmodel/__init__.py"
 
107
  ],
108
  "must_include_any": [
109
- "Session",
110
- "exec",
111
- "execute",
112
- "typed"
 
113
  ],
114
- "min_keyword_matches": 2
115
  },
116
  {
117
- "id": "sqlmodel-async-session-exec",
118
- "category": "specific-function",
119
- "question": "How does async query execution work in SQLModel?",
120
- "ground_truth": "SQLModel provides async session support under sqlmodel.ext.asyncio.session, including an async session wrapper that supports exec-style query execution for SQLModel statements in asynchronous applications.",
121
  "expected_sources": [
122
- "sqlmodel/ext/asyncio/session.py"
 
 
 
123
  ],
124
  "must_include_any": [
125
- "async",
126
- "AsyncSession",
127
- "exec",
128
- "greenlet"
 
129
  ],
130
- "min_keyword_matches": 2
131
  },
132
  {
133
- "id": "sqlmodel-select-export",
134
- "category": "specific-function",
135
- "question": "How is select exposed to users in SQLModel?",
136
- "ground_truth": "SQLModel re-exports a select helper from its SQL expression layer so users can write typed select statements directly from the sqlmodel package instead of importing SQLAlchemy primitives manually.",
137
  "expected_sources": [
138
- "sqlmodel/__init__.py",
139
- "sqlmodel/sql/expression.py"
 
 
140
  ],
141
  "must_include_any": [
142
- "select",
143
- "re-export",
144
- "expression",
145
- "sqlmodel"
 
146
  ],
147
- "min_keyword_matches": 2
148
  },
149
  {
150
- "id": "sqlmodel-create-engine-export",
151
- "category": "specific-function",
152
- "question": "How does SQLModel expose create_engine to application code?",
153
- "ground_truth": "SQLModel re-exports create_engine from SQLAlchemy at the package level so users can import it directly from sqlmodel while using SQLModel models and sessions together.",
154
  "expected_sources": [
155
- "sqlmodel/__init__.py"
 
 
 
 
 
156
  ],
157
  "must_include_any": [
158
- "create_engine",
159
- "re-export",
160
- "SQLAlchemy",
161
- "sqlmodel"
162
  ],
163
  "min_keyword_matches": 2
164
  },
165
  {
166
- "id": "sqlmodel-metadata-create-all",
167
  "category": "config-setup",
168
- "question": "How are database tables created when using SQLModel?",
169
- "ground_truth": "Table creation typically happens by calling SQLModel.metadata.create_all(engine). SQLModel models register table metadata in a way that allows SQLAlchemy metadata creation workflows to build the underlying database tables.",
170
  "expected_sources": [
171
  "README.md",
172
- "sqlmodel/main.py",
173
- "docs_src"
174
  ],
175
  "must_include_any": [
176
- "metadata",
177
- "create_all",
178
- "engine",
179
- "table"
 
180
  ],
181
- "min_keyword_matches": 2
182
  },
183
  {
184
- "id": "sqlmodel-package-exports",
185
  "category": "config-setup",
186
- "question": "What does sqlmodel.__init__ export for end users?",
187
- "ground_truth": "The package initializer re-exports core user-facing APIs from SQLAlchemy and SQLModel, including create_engine, Session, SQLModel, Field, Relationship, and select-related helpers so application code can import most common primitives directly from sqlmodel.",
188
  "expected_sources": [
189
- "sqlmodel/__init__.py"
 
 
 
 
190
  ],
191
  "must_include_any": [
192
- "Session",
193
- "SQLModel",
194
- "Field",
195
- "create_engine"
 
196
  ],
197
  "min_keyword_matches": 3
198
  },
199
  {
200
- "id": "sqlmodel-readme-basic-flow",
201
  "category": "config-setup",
202
- "question": "What basic database workflow does the README show for SQLModel?",
203
- "ground_truth": "The README demonstrates defining a SQLModel table model, creating an engine, creating tables with metadata.create_all, opening a Session, inserting rows, committing, and then selecting rows with select and session.exec.",
204
  "expected_sources": [
205
- "README.md"
 
 
 
206
  ],
207
  "must_include_any": [
208
- "create_engine",
209
- "Session",
210
- "create_all",
211
- "select"
 
212
  ],
213
  "min_keyword_matches": 3
214
  },
215
  {
216
- "id": "sqlmodel-column-options-errors",
217
- "category": "error-handling",
218
- "question": "How does SQLModel guard against conflicting or invalid Field configuration?",
219
- "ground_truth": "SQLModel performs validation around Field configuration in its core model code and raises errors when incompatible options are combined or when SQLAlchemy-specific arguments conflict with other field settings.",
220
  "expected_sources": [
221
- "sqlmodel/main.py"
 
 
222
  ],
223
  "must_include_any": [
224
- "raise",
225
- "Field",
226
- "conflict",
227
- "sa_column"
228
  ],
229
- "min_keyword_matches": 2
230
  },
231
  {
232
- "id": "sqlmodel-relationship-errors",
233
- "category": "error-handling",
234
- "question": "Where would SQLModel enforce invalid relationship configuration?",
235
- "ground_truth": "Relationship configuration is handled in the core SQLModel model layer, where relationship metadata is collected and incompatible combinations are guarded before being translated to SQLAlchemy ORM behavior.",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  "expected_sources": [
237
- "sqlmodel/main.py"
 
 
 
238
  ],
239
  "must_include_any": [
240
- "Relationship",
241
- "metadata",
242
- "SQLAlchemy",
243
- "raise"
244
  ],
245
  "min_keyword_matches": 2
246
  },
247
  {
248
- "id": "sqlmodel-session-cross-file",
249
- "category": "cross-file",
250
- "question": "How do SQLModel models flow into query execution with Session.exec()?",
251
- "ground_truth": "Models are defined in the core SQLModel layer, queries are built through the SQL expression helpers such as select, and then those statements are executed through the SQLModel Session.exec wrapper, which ties model definitions and typed query execution together.",
252
  "expected_sources": [
253
- "sqlmodel/main.py",
254
- "sqlmodel/sql/expression.py",
255
- "sqlmodel/orm/session.py"
 
 
256
  ],
257
  "must_include_any": [
258
- "select",
259
- "Session",
260
- "exec",
261
- "model"
262
  ],
263
  "min_keyword_matches": 3
264
  },
265
  {
266
- "id": "sqlmodel-sync-async-cross-file",
267
- "category": "cross-file",
268
- "question": "How does SQLModel support both sync and async session patterns across files?",
269
- "ground_truth": "SQLModel exposes synchronous session helpers in its ORM session module and asynchronous support in the ext.asyncio package, giving similar exec-oriented ergonomics across both sync and async query paths.",
270
  "expected_sources": [
271
- "sqlmodel/orm/session.py",
272
- "sqlmodel/ext/asyncio/session.py",
273
- "sqlmodel/__init__.py"
 
274
  ],
275
  "must_include_any": [
276
- "sync",
277
- "async",
278
- "Session",
279
- "exec"
280
  ],
281
  "min_keyword_matches": 3
282
  },
283
  {
284
- "id": "sqlmodel-field-to-table-flow",
285
- "category": "cross-file",
286
- "question": "How do typed Field declarations become SQL table columns in SQLModel?",
287
- "ground_truth": "Typed model attributes and Field metadata are collected in the SQLModel core model layer, where SQLModel builds SQLAlchemy-compatible field and table metadata so the resulting class can participate in SQLAlchemy table creation and ORM mapping.",
288
  "expected_sources": [
289
- "sqlmodel/main.py",
290
- "sqlmodel/_compat.py"
 
 
 
291
  ],
292
  "must_include_any": [
293
- "Field",
294
- "column",
295
- "table",
296
- "metadata"
297
  ],
298
  "min_keyword_matches": 3
299
  },
300
  {
301
- "id": "sqlmodel-docs-fastapi-positioning",
302
- "category": "docs",
303
- "question": "How does the project describe SQLModel's relationship to FastAPI in its docs or README?",
304
- "ground_truth": "The project describes SQLModel as being designed to simplify SQL database work in FastAPI applications and emphasizes that it is created by the same author, with strong compatibility between FastAPI, Pydantic, and SQLAlchemy.",
305
  "expected_sources": [
306
- "README.md",
307
- "docs"
 
 
 
308
  ],
309
  "must_include_any": [
310
- "FastAPI",
311
- "same author",
312
- "compatibility"
 
313
  ],
314
- "min_keyword_matches": 2
315
  },
316
  {
317
- "id": "sqlmodel-followup-show-session-code",
318
- "category": "conversation",
319
- "turns": [
320
- {
321
- "role": "user",
322
- "content": "How does SQLModel make query execution easier than raw SQLAlchemy?"
323
- },
324
- {
325
- "role": "assistant",
326
- "content": "It provides a Session.exec helper and package-level exports to simplify common query patterns."
327
- }
328
  ],
329
- "question": "show me the code path for that",
330
- "ground_truth": "The follow-up should stay anchored to Session.exec and SQLModel query ergonomics, retrieving code from the session wrapper and related SQLModel exports instead of drifting to README-only results.",
 
 
 
 
 
 
 
 
 
 
 
331
  "expected_sources": [
332
- "sqlmodel/orm/session.py",
333
- "sqlmodel/__init__.py",
334
- "sqlmodel/sql/expression.py"
 
 
335
  ],
336
  "must_include_any": [
337
- "Session",
338
- "exec",
339
- "select"
 
 
340
  ],
341
- "min_keyword_matches": 2
342
  },
343
  {
344
- "id": "sqlmodel-select-implementation-layer",
345
  "category": "specific-function",
346
- "question": "Where is select implemented under the hood and how is that different from how it is exposed publicly?",
347
- "ground_truth": "SQLModel exposes select through package-level imports such as sqlmodel.__init__ and sqlmodel.sql.expression, while the implementation details and overload-heavy generation live in lower-level SQL expression modules like _expression_select_gen.py and related select classes.",
348
  "expected_sources": [
349
- "sqlmodel/__init__.py",
350
- "sqlmodel/sql/expression.py",
351
- "sqlmodel/sql/_expression_select_gen.py",
352
- "sqlmodel/sql/_expression_select_cls.py"
353
  ],
354
  "must_include_any": [
355
- "select",
356
- "public",
357
- "implementation",
358
- "re-export"
 
359
  ],
360
- "min_keyword_matches": 2
361
  },
362
  {
363
- "id": "sqlmodel-async-session-delegation",
364
  "category": "cross-file",
365
- "question": "How does AsyncSession.exec reuse the synchronous Session.exec path?",
366
- "ground_truth": "The async session layer delegates execution to the synchronous Session.exec logic rather than duplicating it. AsyncSession uses greenlet-based bridging so async callers can reuse the sync execution wrapper and still get SQLModel-style exec ergonomics.",
367
  "expected_sources": [
368
- "sqlmodel/ext/asyncio/session.py",
369
- "sqlmodel/orm/session.py"
 
 
 
 
370
  ],
371
  "must_include_any": [
372
- "AsyncSession",
373
- "Session",
374
- "greenlet",
375
- "exec"
 
376
  ],
377
  "min_keyword_matches": 3
378
  },
379
  {
380
- "id": "sqlmodel-select-tutorial-usage",
381
- "category": "docs",
382
- "question": "How do the docs teach people to use select together with Session.exec?",
383
- "ground_truth": "The tutorials show users building a statement with select(...) and then executing it through Session.exec(...), positioning exec as the ergonomic query entry point for SQLModel statements.",
384
  "expected_sources": [
385
- "docs/tutorial/select.md",
386
- "README.md"
 
 
 
 
 
387
  ],
388
  "must_include_any": [
389
- "select",
390
- "Session",
391
- "exec",
392
- "statement"
 
393
  ],
394
  "min_keyword_matches": 3
395
  },
396
  {
397
- "id": "sqlmodel-fastapi-response-model-docs",
398
- "category": "docs",
399
- "question": "How do the FastAPI docs describe using SQLModel models as response models?",
400
- "ground_truth": "The FastAPI-focused docs explain that SQLModel classes can participate in API request and response modeling because they build on Pydantic, letting applications reuse models or related model variants in response_model patterns.",
401
  "expected_sources": [
402
- "docs/tutorial/fastapi/response-model.md",
403
- "README.md"
 
 
404
  ],
405
  "must_include_any": [
406
- "FastAPI",
407
- "response_model",
408
- "Pydantic",
409
- "model"
410
  ],
411
- "min_keyword_matches": 2
412
  },
413
  {
414
- "id": "sqlmodel-independent-library-positioning",
415
- "category": "docs",
416
- "question": "Does the project describe SQLModel as FastAPI-only or as a standalone library too?",
417
- "ground_truth": "The docs position SQLModel as especially strong with FastAPI, but still as an independent library that can be used outside FastAPI. It is not described as FastAPI-only.",
418
  "expected_sources": [
419
- "README.md",
420
- "docs/features.md",
421
- "docs/index.md"
 
 
 
422
  ],
423
  "must_include_any": [
424
- "FastAPI",
425
- "independent",
426
- "library",
427
- "not"
 
428
  ],
429
- "min_keyword_matches": 2
430
  },
431
  {
432
- "id": "sqlmodel-sa-relationship-test-guard",
433
- "category": "tests",
434
- "question": "What invalid Relationship combinations are guarded by tests?",
435
- "ground_truth": "The relationship tests cover invalid combinations where a pre-built sa_relationship is mixed with sa_relationship_args or sa_relationship_kwargs, confirming that SQLModel raises when overlapping relationship configuration styles are combined.",
436
  "expected_sources": [
437
- "tests/test_field_sa_relationship.py",
438
- "sqlmodel/main.py"
 
 
 
439
  ],
440
  "must_include_any": [
441
- "sa_relationship",
442
- "args",
443
- "kwargs",
444
- "raise"
 
445
  ],
446
  "min_keyword_matches": 3
447
  },
448
  {
449
- "id": "sqlmodel-ondelete-nullable-test",
450
- "category": "tests",
451
- "question": "What does the project test about ondelete and nullable relationship fields?",
452
- "ground_truth": "The test suite checks that using ondelete='SET NULL' on a non-nullable relationship field is invalid. The model layer should raise because SET NULL requires the underlying foreign key column to be nullable.",
453
  "expected_sources": [
454
- "tests/test_ondelete_raises.py",
455
- "sqlmodel/main.py"
 
 
 
456
  ],
457
  "must_include_any": [
458
- "ondelete",
459
- "SET NULL",
460
- "nullable",
461
- "raise"
462
  ],
463
  "min_keyword_matches": 3
464
  },
465
  {
466
- "id": "sqlmodel-type-validation-test",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
  "category": "tests",
468
- "question": "What do the tests suggest about invalid SQLAlchemy or field type combinations in SQLModel?",
469
- "ground_truth": "The tests indicate that SQLModel raises when unsupported or ambiguous field type combinations are mapped into SQLAlchemy columns, reinforcing that not every Python type annotation can become a database column shape automatically.",
470
  "expected_sources": [
471
- "tests/test_sqlalchemy_type_errors.py",
472
- "sqlmodel/main.py"
 
473
  ],
474
  "must_include_any": [
475
- "type",
476
- "SQLAlchemy",
477
- "raise",
478
- "column"
479
  ],
480
  "min_keyword_matches": 2
481
  },
482
  {
483
- "id": "sqlmodel-readme-engine-session-imports",
484
- "category": "config-setup",
485
- "question": "What top-level imports does the README encourage for getting started with SQLModel?",
486
- "ground_truth": "The README encourages importing SQLModel, Field, Session, create_engine, and select from the top-level sqlmodel package so users can define models, create tables, and run queries with a unified import style.",
487
  "expected_sources": [
488
- "README.md",
489
- "sqlmodel/__init__.py"
 
490
  ],
491
  "must_include_any": [
492
- "SQLModel",
493
- "Field",
494
- "Session",
495
- "create_engine",
496
- "select"
497
  ],
498
- "min_keyword_matches": 4
499
  },
500
  {
501
- "id": "sqlmodel-many-to-many-link-model-docs",
502
- "category": "docs",
503
- "question": "How do the relationship docs explain link_model for many-to-many mappings?",
504
- "ground_truth": "The relationship docs explain that link_model is used as an association or link table model for many-to-many relationships, letting SQLModel connect two models through an explicit intermediary model.",
505
  "expected_sources": [
506
- "docs/tutorial/many-to-many/create-models-with-link.md",
507
- "sqlmodel/main.py"
 
 
508
  ],
509
  "must_include_any": [
510
- "link_model",
511
- "many-to-many",
512
- "association",
513
- "relationship"
 
514
  ],
515
  "min_keyword_matches": 3
516
  },
517
  {
518
- "id": "sqlmodel-followup-async-code-path",
519
  "category": "conversation",
520
  "turns": [
521
  {
522
  "role": "user",
523
- "content": "How does async query execution work in SQLModel?"
524
  },
525
  {
526
  "role": "assistant",
527
- "content": "It uses AsyncSession and bridges into the sync session execution path."
528
  }
529
  ],
530
- "question": "show me where that bridge happens",
531
- "ground_truth": "The follow-up should stay on the async execution path and retrieve the async session module together with the sync session module it delegates to, rather than drifting to docs-only summaries.",
532
  "expected_sources": [
533
- "sqlmodel/ext/asyncio/session.py",
534
- "sqlmodel/orm/session.py"
 
 
535
  ],
536
  "must_include_any": [
537
- "AsyncSession",
538
- "greenlet",
539
- "Session",
540
- "exec"
541
  ],
542
  "min_keyword_matches": 3
543
  },
544
  {
545
- "id": "sqlmodel-followup-field-column-path",
546
  "category": "conversation",
547
  "turns": [
548
  {
549
  "role": "user",
550
- "content": "How do typed Field declarations become SQL table columns in SQLModel?"
551
  },
552
  {
553
  "role": "assistant",
554
- "content": "The metaclass and field helpers translate Field metadata into SQLAlchemy Column objects."
555
  }
556
  ],
557
- "question": "show me the main code path for that conversion",
558
- "ground_truth": "The follow-up should stay anchored to the field-to-column conversion path in the core model implementation instead of drifting to tutorial prose alone.",
559
  "expected_sources": [
560
- "sqlmodel/main.py",
561
- "sqlmodel/_compat.py"
 
 
 
562
  ],
563
  "must_include_any": [
564
- "Field",
565
- "Column",
566
- "metaclass",
567
- "conversion"
568
  ],
569
  "min_keyword_matches": 3
570
  },
571
  {
572
- "id": "sqlmodel-followup-select-public-path",
573
  "category": "conversation",
574
  "turns": [
575
  {
576
  "role": "user",
577
- "content": "How is select exposed to users in SQLModel?"
578
  },
579
  {
580
  "role": "assistant",
581
- "content": "It is re-exported for public use from the SQLModel package and expression layer."
582
  }
583
  ],
584
- "question": "and where is the lower-level implementation behind that?",
585
- "ground_truth": "The follow-up should connect the public export path to the lower-level select generator and select class implementation files instead of repeating only the package-level export story.",
586
- "expected_sources": [
587
- "sqlmodel/sql/expression.py",
588
- "sqlmodel/sql/_expression_select_gen.py",
589
- "sqlmodel/sql/_expression_select_cls.py"
590
- ],
591
- "must_include_any": [
592
- "select",
593
- "implementation",
594
- "expression",
595
- "class"
596
- ],
597
- "min_keyword_matches": 2
598
- },
599
- {
600
- "id": "sqlmodel-test-vs-core-evidence-balance",
601
- "category": "cross-file",
602
- "question": "When explaining configuration errors in SQLModel, how should core implementation and tests complement each other?",
603
- "ground_truth": "The core implementation in sqlmodel/main.py is the canonical source for behavior, while tests such as relationship and ondelete checks provide evidence that those guards are enforced in concrete scenarios. A good answer should balance both without treating tests as the primary implementation source.",
604
- "expected_sources": [
605
- "sqlmodel/main.py",
606
- "tests/test_field_sa_relationship.py",
607
- "tests/test_ondelete_raises.py"
608
- ],
609
- "must_include_any": [
610
- "main.py",
611
- "tests",
612
- "canonical",
613
- "guard"
614
- ],
615
- "min_keyword_matches": 2
616
- },
617
- {
618
- "id": "sqlmodel-docs-vs-core-select-balance",
619
- "category": "cross-file",
620
- "question": "For explaining select in SQLModel, which files are canonical implementation sources and which are usage-oriented docs?",
621
- "ground_truth": "The canonical implementation path is in sqlmodel.__init__, sqlmodel.sql.expression, and the lower-level select generator or select class modules, while files like README and docs/tutorial/select.md are usage-oriented documentation rather than the implementation itself.",
622
- "expected_sources": [
623
- "sqlmodel/__init__.py",
624
- "sqlmodel/sql/expression.py",
625
- "sqlmodel/sql/_expression_select_gen.py",
626
- "sqlmodel/sql/_expression_select_cls.py",
627
- "docs/tutorial/select.md",
628
- "README.md"
629
- ],
630
- "must_include_any": [
631
- "canonical",
632
- "implementation",
633
- "docs",
634
- "usage"
635
- ],
636
- "min_keyword_matches": 2
637
- },
638
- {
639
- "id": "sqlmodel-features-doc-positioning",
640
- "category": "docs",
641
- "question": "What themes does the features documentation emphasize about SQLModel's value proposition?",
642
- "ground_truth": "The features docs emphasize reduced duplication, editor friendliness, compatibility across Pydantic and SQLAlchemy, and an ergonomic way to work with SQL databases using standard Python type hints and models.",
643
  "expected_sources": [
644
- "docs/features.md",
645
- "README.md"
 
 
 
646
  ],
647
  "must_include_any": [
648
- "duplication",
649
- "editor",
650
- "compatibility",
651
- "Python"
652
  ],
653
- "min_keyword_matches": 2
654
  },
655
  {
656
- "id": "sqlmodel-docs-index-overview",
657
- "category": "docs",
658
- "question": "What kind of project overview should a user get from the docs index for SQLModel?",
659
- "ground_truth": "The docs index should frame SQLModel as a Python SQL library that combines data modeling and database access patterns, point users toward tutorials or feature explanations, and reinforce its relationship to Pydantic, SQLAlchemy, and FastAPI.",
660
- "expected_sources": [
661
- "docs/index.md",
662
- "README.md"
663
- ],
664
- "must_include_any": [
665
- "overview",
666
- "Pydantic",
667
- "SQLAlchemy",
668
- "FastAPI"
669
  ],
670
- "min_keyword_matches": 2
671
- },
672
- {
673
- "id": "sqlmodel-sa-column-conflict-error",
674
- "category": "error-handling",
675
- "question": "What happens if you pass both sa_column and other Field options like primary_key or index in SQLModel?",
676
- "ground_truth": "SQLModel raises a RuntimeError when sa_column is combined with other field-level options like primary_key, index, or foreign_key because sa_column is meant to be a fully self-contained SQLAlchemy column definition and mixing it with SQLModel field shortcuts creates an ambiguous configuration.",
677
  "expected_sources": [
678
- "sqlmodel/main.py"
 
 
 
 
679
  ],
680
  "must_include_any": [
681
- "sa_column",
682
- "primary_key",
683
- "raise",
684
- "conflict"
685
  ],
686
  "min_keyword_matches": 3
687
  },
688
  {
689
- "id": "sqlmodel-codegen-basic-model",
690
  "category": "code-generation",
691
- "question": "Write a SQLModel table model for a User with an integer primary key, a required name string, and an optional email string",
692
- "ground_truth": "A correct answer defines a class inheriting from SQLModel with table=True, uses Field(primary_key=True) on an integer id, declares name as a required str, and declares email as Optional[str] with a default of None.",
693
  "expected_sources": [
694
- "sqlmodel/main.py",
695
- "README.md",
696
- "docs_src"
 
 
697
  ],
698
  "must_include_any": [
699
- "SQLModel",
700
- "Field",
701
- "table=True",
702
- "primary_key",
703
- "Optional"
704
  ],
705
  "min_keyword_matches": 3
706
  },
707
  {
708
- "id": "sqlmodel-codegen-session-query",
709
  "category": "code-generation",
710
- "question": "Write a SQLModel example that creates an engine, opens a session, inserts a User row, and queries all users",
711
- "ground_truth": "A correct answer uses create_engine to set up the database, SQLModel.metadata.create_all to create tables, opens a Session using a context manager, adds and commits a User instance, then uses select(User) with session.exec to retrieve all rows.",
712
  "expected_sources": [
713
- "README.md",
714
- "sqlmodel/__init__.py",
715
- "sqlmodel/orm/session.py",
716
- "docs/tutorial/create-db-and-table.md",
717
- "docs/tutorial/insert.md",
718
- "docs/tutorial/select.md"
719
  ],
720
  "must_include_any": [
721
- "create_engine",
722
- "Session",
723
- "select",
724
- "exec",
725
- "commit"
726
  ],
727
- "min_keyword_matches": 4
728
  }
729
  ]
 
1
  [
2
  {
3
+ "id": "documenso-purpose",
4
  "category": "architecture",
5
+ "question": "What is Documenso and what product problem is it trying to solve?",
6
+ "ground_truth": "Documenso is an open-source document signing platform and DocuSign alternative. It lets users create, send, and sign documents electronically while emphasizing self-hosting, trust, and the ability to inspect how the signing system works under the hood.",
7
  "expected_sources": [
8
  "README.md",
9
+ "ARCHITECTURE.md"
 
10
  ],
11
  "must_include_any": [
12
+ "document signing",
13
+ "self-host",
14
+ "DocuSign",
15
+ "open trust"
16
  ],
17
  "min_keyword_matches": 2
18
  },
19
  {
20
+ "id": "documenso-monorepo-shape",
21
  "category": "architecture",
22
+ "question": "How is the Documenso monorepo organized at a high level?",
23
+ "ground_truth": "The repo is organized as a Turborepo/npm-workspaces monorepo. Applications live under apps, including the main Remix/React Router application, documentation site, and openpage-api public analytics API, while shared domain and infrastructure packages live under packages, including lib, trpc, api, prisma, ui, email, auth, and signing.",
24
  "expected_sources": [
25
+ "ARCHITECTURE.md",
26
+ "package.json",
27
+ "turbo.json",
28
+ "apps",
29
+ "packages"
30
  ],
31
  "must_include_any": [
32
+ "monorepo",
33
+ "Turborepo",
34
+ "apps",
35
+ "packages"
36
  ],
37
+ "min_keyword_matches": 3
38
  },
39
  {
40
+ "id": "documenso-remix-hono-app",
41
  "category": "architecture",
42
+ "question": "What role does apps/remix play in Documenso?",
43
+ "ground_truth": "apps/remix is the main application. The architecture describes it as a React Router/Remix app served by a Hono server, exposing UI routes alongside API mounts such as /api/v1, /api/v2, /api/trpc, and /api/jobs.",
44
  "expected_sources": [
45
+ "ARCHITECTURE.md",
46
+ "apps/remix",
47
+ "apps/remix/server",
48
+ "apps/remix/app"
49
  ],
50
  "must_include_any": [
51
+ "React Router",
52
+ "Remix",
53
+ "Hono",
54
+ "apps/remix"
55
  ],
56
  "min_keyword_matches": 2
57
  },
58
  {
59
+ "id": "documenso-package-responsibilities",
60
  "category": "architecture",
61
+ "question": "What are the main responsibilities of the core packages in Documenso?",
62
+ "ground_truth": "The core packages split responsibilities by layer: @documenso/lib holds server-only, client-only, and universal business logic; @documenso/trpc provides the current API V2 layer; @documenso/api maintains the older REST API V1; @documenso/prisma owns database access; @documenso/email owns React Email templates and mail delivery; @documenso/auth handles authentication; and @documenso/signing handles PDF signing.",
63
  "expected_sources": [
64
+ "ARCHITECTURE.md",
65
+ "packages/lib",
66
+ "packages/trpc",
67
+ "packages/api",
68
+ "packages/prisma",
69
+ "packages/email",
70
+ "packages/auth",
71
+ "packages/signing"
72
  ],
73
  "must_include_any": [
74
+ "lib",
75
+ "trpc",
76
+ "prisma",
77
+ "email",
78
+ "signing"
79
  ],
80
+ "min_keyword_matches": 3
81
  },
82
  {
83
+ "id": "documenso-api-architecture-overview",
84
+ "category": "architecture",
85
+ "question": "How does Documenso separate API V1, API V2, and internal tRPC APIs?",
86
+ "ground_truth": "Documenso keeps API V1 in packages/api/v1 using ts-rest, marks it as deprecated but maintained, and mounts it under /api/v1. API V2 lives under packages/trpc/server, uses tRPC plus trpc-to-openapi, and is mounted under /api/v2 and /api/v2-beta. Internal frontend-to-backend tRPC is mounted under /api/trpc and uses session-based auth.",
87
  "expected_sources": [
88
+ "ARCHITECTURE.md",
89
+ "packages/api",
90
+ "packages/trpc/server",
91
+ "apps/remix/server"
92
  ],
93
  "must_include_any": [
94
+ "API V1",
95
+ "API V2",
96
+ "tRPC",
97
+ "ts-rest",
98
+ "OpenAPI"
99
  ],
100
+ "min_keyword_matches": 3
101
  },
102
  {
103
+ "id": "documenso-readme-positioning",
104
+ "category": "docs",
105
+ "question": "How does the README position Documenso to someone evaluating the project?",
106
+ "ground_truth": "The README presents Documenso as the open-source DocuSign alternative and frames its mission around making digital document signing fast, easy, trustworthy, self-hostable, and inspectable under the hood.",
107
  "expected_sources": [
108
+ "README.md"
109
  ],
110
  "must_include_any": [
111
+ "DocuSign",
112
+ "open-source",
113
+ "self-host",
114
+ "trust"
115
  ],
116
  "min_keyword_matches": 2
117
  },
118
  {
119
+ "id": "documenso-readme-tech-stack",
120
+ "category": "docs",
121
+ "question": "What technology stack does the README advertise for Documenso?",
122
+ "ground_truth": "The README lists a TypeScript application using React Router, Prisma, Tailwind, shadcn/ui, React Email, tRPC, PDF signing tooling, React-PDF, PDF-Lib, and Stripe.",
123
  "expected_sources": [
124
+ "README.md",
125
+ "ARCHITECTURE.md",
126
+ "package.json"
127
  ],
128
  "must_include_any": [
129
+ "TypeScript",
130
+ "Prisma",
131
+ "tRPC",
132
+ "React Email",
133
+ "Stripe"
134
  ],
135
+ "min_keyword_matches": 3
136
  },
137
  {
138
+ "id": "documenso-local-dev-quickstart",
139
+ "category": "docs",
140
+ "question": "What local development workflow does the README recommend for getting Documenso running quickly?",
141
+ "ground_truth": "The README and developer docs recommend using Node.js, Postgres, and optionally Docker. The quickstart has users copy or create an env file, run npm run dx to start supporting services such as Postgres and Inbucket, then run npm run dev for the app.",
142
  "expected_sources": [
143
+ "README.md",
144
+ ".env.example",
145
+ "apps/docs/content/docs/developers/local-development/quickstart.mdx",
146
+ "docker"
147
  ],
148
  "must_include_any": [
149
+ "Node.js",
150
+ "Postgres",
151
+ "Docker",
152
+ "npm run dx",
153
+ "npm run dev"
154
  ],
155
+ "min_keyword_matches": 3
156
  },
157
  {
158
+ "id": "documenso-self-hosting-docs",
159
+ "category": "docs",
160
+ "question": "What does the project documentation say about self-hosting Documenso?",
161
+ "ground_truth": "The README and docs describe self-hosting by cloning the repository, copying .env.example to .env, setting required web, database, encryption, signing, and SMTP-related variables, then deploying with Docker, Docker Compose, or a manual flow. The docs also cover configuration and maintenance topics.",
162
  "expected_sources": [
163
+ "README.md",
164
+ ".env.example",
165
+ "docker",
166
+ "apps/docs/content/docs/self-hosting"
167
  ],
168
  "must_include_any": [
169
+ "self-host",
170
+ ".env.example",
171
+ "database",
172
+ "SMTP",
173
+ "Docker"
174
  ],
175
+ "min_keyword_matches": 3
176
  },
177
  {
178
+ "id": "documenso-docs-app-purpose",
179
+ "category": "docs",
180
+ "question": "What is the purpose of the apps/docs application in the repository?",
181
+ "ground_truth": "apps/docs is the documentation site application. ARCHITECTURE.md identifies it as the docs site, while the app's own README, package.json, and source config show the current implementation as a Next.js/Fumadocs MDX app with content loading, docs layout, and a search route.",
182
  "expected_sources": [
183
+ "ARCHITECTURE.md",
184
+ "apps/docs/README.md",
185
+ "apps/docs/package.json",
186
+ "apps/docs/source.config.ts",
187
+ "apps/docs/src/lib/source.ts",
188
+ "apps/docs/src/app/api/search/route.ts"
189
  ],
190
  "must_include_any": [
191
+ "documentation",
192
+ "Next.js",
193
+ "Fumadocs",
194
+ "search"
195
  ],
196
  "min_keyword_matches": 2
197
  },
198
  {
199
+ "id": "documenso-required-env",
200
  "category": "config-setup",
201
+ "question": "Which environment variables are central to running a self-hosted Documenso instance?",
202
+ "ground_truth": "The setup expects values such as NEXTAUTH_SECRET, NEXT_PRIVATE_ENCRYPTION_KEY, NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY, NEXT_PUBLIC_WEBAPP_URL, NEXT_PRIVATE_DATABASE_URL, NEXT_PRIVATE_DIRECT_DATABASE_URL, NEXT_PRIVATE_SMTP_FROM_NAME, and NEXT_PRIVATE_SMTP_FROM_ADDRESS. The env example and self-hosting docs also cover internal URLs, signing transport, storage transport, and optional OAuth and webhook configuration.",
203
  "expected_sources": [
204
  "README.md",
205
+ ".env.example",
206
+ "apps/docs/content/docs/self-hosting/configuration/environment.mdx"
207
  ],
208
  "must_include_any": [
209
+ "NEXTAUTH_SECRET",
210
+ "NEXT_PUBLIC_WEBAPP_URL",
211
+ "DATABASE_URL",
212
+ "SMTP",
213
+ "encryption"
214
  ],
215
+ "min_keyword_matches": 3
216
  },
217
  {
218
+ "id": "documenso-database-setup",
219
  "category": "config-setup",
220
+ "question": "How is the database layer configured and managed in Documenso?",
221
+ "ground_truth": "Documenso uses PostgreSQL with Prisma and Kysely. Database connection URLs are configured through NEXT_PRIVATE_DATABASE_URL and NEXT_PRIVATE_DIRECT_DATABASE_URL, the self-hosting docs describe database setup, and schema or migration work is handled from the packages/prisma package with commands such as prisma migrations.",
222
  "expected_sources": [
223
+ "ARCHITECTURE.md",
224
+ ".env.example",
225
+ "apps/docs/content/docs/self-hosting/configuration/database.mdx",
226
+ "packages/prisma",
227
+ "packages/prisma/schema.prisma"
228
  ],
229
  "must_include_any": [
230
+ "PostgreSQL",
231
+ "Prisma",
232
+ "Kysely",
233
+ "DATABASE_URL",
234
+ "migration"
235
  ],
236
  "min_keyword_matches": 3
237
  },
238
  {
239
+ "id": "documenso-signing-config",
240
  "category": "config-setup",
241
+ "question": "How is document signing configured for local and cloud-backed signing?",
242
+ "ground_truth": "Signing is configured with NEXT_PRIVATE_SIGNING_TRANSPORT. The env example and self-hosting docs document local signing as the default and also support gcloud-hsm with related key, certificate, credential, certificate chain, and timestamp authority configuration.",
243
  "expected_sources": [
244
+ ".env.example",
245
+ "apps/docs/content/docs/self-hosting/configuration/signing-certificate",
246
+ "packages/signing",
247
+ "packages/signing/transports"
248
  ],
249
  "must_include_any": [
250
+ "NEXT_PRIVATE_SIGNING_TRANSPORT",
251
+ "local",
252
+ "gcloud-hsm",
253
+ "certificate",
254
+ "timestamp"
255
  ],
256
  "min_keyword_matches": 3
257
  },
258
  {
259
+ "id": "documenso-workspace-build-config",
260
+ "category": "config-setup",
261
+ "question": "Where should you look to understand package workspaces and build orchestration in Documenso?",
262
+ "ground_truth": "The root package.json defines npm workspaces and scripts, while turbo.json defines Turborepo task orchestration. ARCHITECTURE.md explains the monorepo layout and how apps and packages fit together.",
263
  "expected_sources": [
264
+ "package.json",
265
+ "turbo.json",
266
+ "ARCHITECTURE.md"
267
  ],
268
  "must_include_any": [
269
+ "package.json",
270
+ "workspaces",
271
+ "turbo",
272
+ "Turborepo"
273
  ],
274
+ "min_keyword_matches": 3
275
  },
276
  {
277
+ "id": "documenso-api-v2-document-router",
278
+ "category": "api",
279
+ "question": "Where is the current document API implemented and how is it exposed?",
280
+ "ground_truth": "The current API V2 is implemented under packages/trpc/server, with document operations organized under a document router. It is exposed through /api/v2 and /api/v2-beta with tRPC and OpenAPI support, and it accepts API-token or session-cookie authentication depending on the route.",
281
+ "expected_sources": [
282
+ "ARCHITECTURE.md",
283
+ "packages/trpc/server",
284
+ "packages/trpc/server/document-router",
285
+ "apps/remix/server"
286
+ ],
287
+ "must_include_any": [
288
+ "packages/trpc/server",
289
+ "document-router",
290
+ "API V2",
291
+ "OpenAPI",
292
+ "tRPC"
293
+ ],
294
+ "min_keyword_matches": 3
295
+ },
296
+ {
297
+ "id": "documenso-api-v1-deprecated",
298
+ "category": "api",
299
+ "question": "What is the older API V1 layer in Documenso and what is its status?",
300
+ "ground_truth": "API V1 lives under packages/api/v1, uses ts-rest for contract-based REST, is mounted under /api/v1, and is described as deprecated but maintained.",
301
+ "expected_sources": [
302
+ "ARCHITECTURE.md",
303
+ "packages/api",
304
+ "packages/api/v1"
305
+ ],
306
+ "must_include_any": [
307
+ "API V1",
308
+ "packages/api/v1",
309
+ "ts-rest",
310
+ "deprecated"
311
+ ],
312
+ "min_keyword_matches": 3
313
+ },
314
+ {
315
+ "id": "documenso-internal-trpc",
316
+ "category": "api",
317
+ "question": "How does the frontend talk to the backend internally in Documenso?",
318
+ "ground_truth": "The frontend uses an internal tRPC API mounted under /api/trpc for frontend-to-backend communication. This internal API is separate from the public API V1 and V2 routes and uses session-based authentication.",
319
+ "expected_sources": [
320
+ "ARCHITECTURE.md",
321
+ "apps/remix/server/trpc",
322
+ "apps/remix/server/router.ts",
323
+ "packages/trpc"
324
+ ],
325
+ "must_include_any": [
326
+ "/api/trpc",
327
+ "tRPC",
328
+ "frontend",
329
+ "session"
330
+ ],
331
+ "min_keyword_matches": 3
332
+ },
333
+ {
334
+ "id": "documenso-public-api-auth",
335
+ "category": "api",
336
+ "question": "How are public API requests authenticated in Documenso?",
337
+ "ground_truth": "Public API routes use API-token style authentication, typically through bearer or API-key headers. API V2 can also use session cookies where appropriate, while internal tRPC uses session-based auth.",
338
  "expected_sources": [
339
+ "ARCHITECTURE.md",
340
+ "packages/lib/server-only/public-api",
341
+ "packages/trpc/server",
342
+ "packages/api"
343
  ],
344
  "must_include_any": [
345
+ "API Token",
346
+ "Bearer",
347
+ "session",
348
+ "public API"
349
  ],
350
  "min_keyword_matches": 2
351
  },
352
  {
353
+ "id": "documenso-openapi-support",
354
+ "category": "api",
355
+ "question": "Where does OpenAPI support fit into Documenso's API architecture?",
356
+ "ground_truth": "OpenAPI support appears in both API layers. API V2 generates an OpenAPI document from the tRPC app router in packages/trpc/server/open-api.ts and mounts it from the Remix/Hono server. API V1 is the older ts-rest layer under packages/api/v1 and also exposes an OpenAPI document through packages/api/hono.ts.",
357
  "expected_sources": [
358
+ "ARCHITECTURE.md",
359
+ "apps/remix/server/router.ts",
360
+ "packages/trpc/server/open-api.ts",
361
+ "packages/api/hono.ts",
362
+ "packages/api/v1/openapi.ts"
363
  ],
364
  "must_include_any": [
365
+ "OpenAPI",
366
+ "trpc-to-openapi",
367
+ "tRPC",
368
+ "API V2"
369
  ],
370
  "min_keyword_matches": 3
371
  },
372
  {
373
+ "id": "documenso-document-business-logic",
374
+ "category": "specific-function",
375
+ "question": "Where is document business logic likely implemented in Documenso?",
376
+ "ground_truth": "Document business logic belongs primarily in packages/lib/server-only/document, with API-facing operations routed through packages/trpc/server/document-router or the legacy packages/api layer. Database persistence is supported by packages/prisma.",
377
  "expected_sources": [
378
+ "ARCHITECTURE.md",
379
+ "packages/lib/server-only/document",
380
+ "packages/trpc/server/document-router",
381
+ "packages/prisma"
382
  ],
383
  "must_include_any": [
384
+ "server-only",
385
+ "document",
386
+ "document-router",
387
+ "prisma"
388
  ],
389
  "min_keyword_matches": 3
390
  },
391
  {
392
+ "id": "documenso-recipient-field-logic",
393
+ "category": "specific-function",
394
+ "question": "Where should you look for recipient and field behavior in Documenso?",
395
+ "ground_truth": "Recipient and field behavior is split between packages/lib/server-only/recipient and packages/lib/server-only/field for core logic, with packages/trpc/server/recipient-router and packages/trpc/server/field-router exposing API operations.",
396
  "expected_sources": [
397
+ "packages/lib/server-only/recipient",
398
+ "packages/lib/server-only/field",
399
+ "packages/trpc/server/recipient-router",
400
+ "packages/trpc/server/field-router",
401
+ "ARCHITECTURE.md"
402
  ],
403
  "must_include_any": [
404
+ "recipient",
405
+ "field",
406
+ "server-only",
407
+ "router"
408
  ],
409
  "min_keyword_matches": 3
410
  },
411
  {
412
+ "id": "documenso-template-envelope-logic",
413
+ "category": "specific-function",
414
+ "question": "How are templates and envelopes represented in the codebase?",
415
+ "ground_truth": "Templates and envelopes have their own server-only domain areas under packages/lib/server-only/template and packages/lib/server-only/envelope. API V2 also organizes routes into template-router and envelope-router directories under packages/trpc/server.",
416
  "expected_sources": [
417
+ "ARCHITECTURE.md",
418
+ "packages/lib/server-only/template",
419
+ "packages/lib/server-only/envelope",
420
+ "packages/trpc/server/template-router",
421
+ "packages/trpc/server/envelope-router"
422
  ],
423
  "must_include_any": [
424
+ "template",
425
+ "envelope",
426
+ "server-only",
427
+ "router"
428
  ],
429
+ "min_keyword_matches": 3
430
  },
431
  {
432
+ "id": "documenso-email-templates",
433
+ "category": "specific-function",
434
+ "question": "How are lifecycle emails represented in Documenso?",
435
+ "ground_truth": "Lifecycle emails live in the @documenso/email package, with React Email templates under packages/email/templates. The package also includes mailer, transports, providers, render helpers, and reusable template components.",
436
+ "expected_sources": [
437
+ "ARCHITECTURE.md",
438
+ "packages/email",
439
+ "packages/email/templates",
440
+ "packages/email/mailer.ts",
441
+ "packages/email/render.tsx"
 
442
  ],
443
+ "must_include_any": [
444
+ "React Email",
445
+ "templates",
446
+ "mailer",
447
+ "transports"
448
+ ],
449
+ "min_keyword_matches": 3
450
+ },
451
+ {
452
+ "id": "documenso-signing-package",
453
+ "category": "specific-function",
454
+ "question": "What does the signing package do in Documenso?",
455
+ "ground_truth": "The @documenso/signing package owns PDF signing behavior. Its signPdf entry point selects a signing transport, applies timestamp authority settings when configured, and supports local P12 signing and Google Cloud KMS/HSM-backed signing through transport implementations.",
456
  "expected_sources": [
457
+ "ARCHITECTURE.md",
458
+ "packages/signing/index.ts",
459
+ "packages/signing/helpers",
460
+ "packages/signing/transports",
461
+ ".env.example"
462
  ],
463
  "must_include_any": [
464
+ "PDF signing",
465
+ "transports",
466
+ "local",
467
+ "Google",
468
+ "KMS"
469
  ],
470
+ "min_keyword_matches": 3
471
  },
472
  {
473
+ "id": "documenso-job-system",
474
  "category": "specific-function",
475
+ "question": "What role do jobs play in Documenso?",
476
+ "ground_truth": "Jobs handle asynchronous operations such as email sending, document sealing, reminders, and webhooks. The architecture describes Inngest or local providers, with job definitions and clients under packages/lib/jobs.",
477
  "expected_sources": [
478
+ "ARCHITECTURE.md",
479
+ "packages/lib/jobs",
480
+ "packages/lib/server-only/email",
481
+ "packages/lib/server-only/webhooks"
482
  ],
483
  "must_include_any": [
484
+ "jobs",
485
+ "Inngest",
486
+ "local",
487
+ "email",
488
+ "webhooks"
489
  ],
490
+ "min_keyword_matches": 3
491
  },
492
  {
493
+ "id": "documenso-document-send-flow",
494
  "category": "cross-file",
495
+ "question": "How does a document send operation flow across the Documenso codebase?",
496
+ "ground_truth": "A document send operation starts at an API or UI route, goes through the API layer such as packages/trpc/server/document-router, delegates core behavior to packages/lib/server-only/document and related recipient or field logic, persists through packages/prisma, and can trigger emails or jobs through packages/email and packages/lib/jobs.",
497
  "expected_sources": [
498
+ "packages/trpc/server/document-router",
499
+ "packages/lib/server-only/document",
500
+ "packages/lib/server-only/recipient",
501
+ "packages/prisma",
502
+ "packages/email",
503
+ "packages/lib/jobs"
504
  ],
505
  "must_include_any": [
506
+ "document-router",
507
+ "server-only/document",
508
+ "prisma",
509
+ "email",
510
+ "jobs"
511
  ],
512
  "min_keyword_matches": 3
513
  },
514
  {
515
+ "id": "documenso-signing-completion-flow",
516
+ "category": "cross-file",
517
+ "question": "How do recipient fields, PDF handling, signing, and completion emails connect?",
518
+ "ground_truth": "Signing completion crosses several packages: recipient and field logic model who signs and which fields are completed, the seal-document job prepares the completed PDF, server-only PDF helpers insert fields/certificates/audit logs, @documenso/signing applies cryptographic signing, Prisma persists state, and document-completed email templates notify participants.",
519
  "expected_sources": [
520
+ "packages/lib/server-only/recipient",
521
+ "packages/lib/server-only/field",
522
+ "packages/lib/server-only/pdf",
523
+ "packages/lib/jobs/definitions/internal/seal-document.handler.ts",
524
+ "packages/signing",
525
+ "packages/prisma",
526
+ "packages/email/templates/document-completed.tsx"
527
  ],
528
  "must_include_any": [
529
+ "recipient",
530
+ "field",
531
+ "PDF",
532
+ "signing",
533
+ "document-completed"
534
  ],
535
  "min_keyword_matches": 3
536
  },
537
  {
538
+ "id": "documenso-webhook-job-flow",
539
+ "category": "cross-file",
540
+ "question": "How do background jobs and webhooks complement each other in Documenso?",
541
+ "ground_truth": "Background jobs handle asynchronous work, and webhook logic lives under packages/lib/server-only/webhooks. Together they allow document lifecycle events to be processed outside the immediate request path and delivered to external integrations.",
542
  "expected_sources": [
543
+ "ARCHITECTURE.md",
544
+ "packages/lib/jobs",
545
+ "packages/lib/server-only/webhooks",
546
+ ".env.example"
547
  ],
548
  "must_include_any": [
549
+ "jobs",
550
+ "webhooks",
551
+ "asynchronous",
552
+ "events"
553
  ],
554
+ "min_keyword_matches": 3
555
  },
556
  {
557
+ "id": "documenso-ui-to-api-flow",
558
+ "category": "cross-file",
559
+ "question": "How does the Remix UI connect to server routes and shared API packages?",
560
+ "ground_truth": "The Remix UI is under apps/remix/app with route definitions and root app wiring. The server side under apps/remix/server wires routers and context, then connects to the shared packages/trpc APIs and packages/lib business logic.",
561
  "expected_sources": [
562
+ "apps/remix/app/routes.ts",
563
+ "apps/remix/app/root.tsx",
564
+ "apps/remix/server/router.ts",
565
+ "apps/remix/server/context.ts",
566
+ "packages/trpc",
567
+ "packages/lib"
568
  ],
569
  "must_include_any": [
570
+ "apps/remix/app",
571
+ "apps/remix/server",
572
+ "router",
573
+ "context",
574
+ "tRPC"
575
  ],
576
+ "min_keyword_matches": 3
577
  },
578
  {
579
+ "id": "documenso-storage-pdf-flow",
580
+ "category": "cross-file",
581
+ "question": "How do storage, PDF processing, and database state fit together?",
582
+ "ground_truth": "The architecture separates storage provider concerns, PDF handling, and database state. Server-side PDF behavior lives under packages/lib/server-only/pdf, upload and download storage logic lives under packages/lib/universal/upload, document data records are created through packages/lib/server-only/document-data, and packages/prisma persists metadata and workflow state.",
583
  "expected_sources": [
584
+ "ARCHITECTURE.md",
585
+ "packages/lib/server-only/pdf",
586
+ "packages/lib/server-only/document-data",
587
+ "packages/prisma",
588
+ "packages/lib/universal/upload"
589
  ],
590
  "must_include_any": [
591
+ "storage",
592
+ "PDF",
593
+ "database",
594
+ "prisma",
595
+ "metadata"
596
  ],
597
  "min_keyword_matches": 3
598
  },
599
  {
600
+ "id": "documenso-auth-session-flow",
601
+ "category": "cross-file",
602
+ "question": "How does authentication show up across Documenso's app and packages?",
603
+ "ground_truth": "Authentication spans the @documenso/auth package, server-only auth logic under packages/lib/server-only/auth, app server context in apps/remix/server/context.ts, and API layers that choose between session cookies and API tokens.",
604
  "expected_sources": [
605
+ "ARCHITECTURE.md",
606
+ "packages/auth",
607
+ "packages/lib/server-only/auth",
608
+ "apps/remix/server/context.ts",
609
+ "packages/trpc/server"
610
  ],
611
  "must_include_any": [
612
+ "auth",
613
+ "session",
614
+ "API token",
615
+ "context"
616
  ],
617
  "min_keyword_matches": 3
618
  },
619
  {
620
+ "id": "documenso-public-api-errors",
621
+ "category": "error-handling",
622
+ "question": "Where would Documenso validate or reject bad public API requests?",
623
+ "ground_truth": "Bad public API requests are validated in the API layer and supporting server-only public API logic. The relevant code is under packages/trpc/server for API V2, packages/api for API V1, and packages/lib/server-only/public-api for shared public API behavior such as authentication, permissions, and validation.",
624
+ "expected_sources": [
625
+ "packages/trpc/server",
626
+ "packages/api",
627
+ "packages/lib/server-only/public-api"
628
+ ],
629
+ "must_include_any": [
630
+ "validation",
631
+ "API",
632
+ "auth",
633
+ "public-api"
634
+ ],
635
+ "min_keyword_matches": 2
636
+ },
637
+ {
638
+ "id": "documenso-webhook-security-errors",
639
+ "category": "error-handling",
640
+ "question": "Where should you look for webhook security or SSRF-related safeguards?",
641
+ "ground_truth": "Webhook safeguards belong in packages/lib/server-only/webhooks, with related configuration documented in .env.example such as NEXT_PRIVATE_WEBHOOK_SSRF_BYPASS_HOSTS. These sources explain where outbound webhook behavior and security exceptions are controlled.",
642
+ "expected_sources": [
643
+ ".env.example",
644
+ "packages/lib/server-only/webhooks"
645
+ ],
646
+ "must_include_any": [
647
+ "webhook",
648
+ "SSRF",
649
+ "bypass",
650
+ "hosts"
651
+ ],
652
+ "min_keyword_matches": 2
653
+ },
654
+ {
655
+ "id": "documenso-signing-config-errors",
656
+ "category": "error-handling",
657
+ "question": "Where would invalid signing configuration most likely be enforced?",
658
+ "ground_truth": "Invalid signing configuration is handled by the signing package and the code that reads signing environment variables. The key sources are .env.example for supported values, packages/signing/index.ts for transport selection and unsupported transport errors, and packages/signing/transports for local or gcloud-hsm certificate/key validation.",
659
+ "expected_sources": [
660
+ ".env.example",
661
+ "packages/signing/index.ts",
662
+ "packages/signing/transports",
663
+ "packages/signing/helpers"
664
+ ],
665
+ "must_include_any": [
666
+ "signing",
667
+ "transport",
668
+ "local",
669
+ "gcloud-hsm"
670
+ ],
671
+ "min_keyword_matches": 3
672
+ },
673
+ {
674
+ "id": "documenso-playwright-tests",
675
  "category": "tests",
676
+ "question": "Where does Documenso keep end-to-end app tests?",
677
+ "ground_truth": "The architecture identifies @documenso/app-tests as the E2E test package, and the packages/app-tests directory is intended for Playwright coverage of app behavior.",
678
  "expected_sources": [
679
+ "ARCHITECTURE.md",
680
+ "packages/app-tests",
681
+ "packages/app-tests/package.json"
682
  ],
683
  "must_include_any": [
684
+ "app-tests",
685
+ "E2E",
686
+ "Playwright"
 
687
  ],
688
  "min_keyword_matches": 2
689
  },
690
  {
691
+ "id": "documenso-package-test-config",
692
+ "category": "tests",
693
+ "question": "How can you find package-level test configuration for shared logic?",
694
+ "ground_truth": "Package-level tests and configuration can be found near the package they cover, such as packages/lib/vitest.config.ts for shared library tests and package.json scripts in the relevant package directories.",
695
  "expected_sources": [
696
+ "packages/lib/vitest.config.ts",
697
+ "packages/lib/package.json",
698
+ "packages"
699
  ],
700
  "must_include_any": [
701
+ "vitest",
702
+ "package.json",
703
+ "packages/lib"
 
 
704
  ],
705
+ "min_keyword_matches": 2
706
  },
707
  {
708
+ "id": "documenso-email-template-tests",
709
+ "category": "tests",
710
+ "question": "What should be tested when changing document lifecycle email behavior?",
711
+ "ground_truth": "A good answer should point to packages/email templates and rendering/mailer code, and should mention checking template output, variables, delivery behavior, and any app or E2E tests that cover document lifecycle notifications.",
712
  "expected_sources": [
713
+ "packages/email/templates",
714
+ "packages/email/render.tsx",
715
+ "packages/email/mailer.ts",
716
+ "packages/app-tests"
717
  ],
718
  "must_include_any": [
719
+ "email",
720
+ "templates",
721
+ "render",
722
+ "mailer",
723
+ "tests"
724
  ],
725
  "min_keyword_matches": 3
726
  },
727
  {
728
+ "id": "documenso-followup-api-v2-code-path",
729
  "category": "conversation",
730
  "turns": [
731
  {
732
  "role": "user",
733
+ "content": "How does Documenso expose document operations in the current public API?"
734
  },
735
  {
736
  "role": "assistant",
737
+ "content": "The current public API is API V2, implemented through the tRPC server package and document router, with OpenAPI support."
738
  }
739
  ],
740
+ "question": "show me the code path for that",
741
+ "ground_truth": "The follow-up should stay anchored to packages/trpc/server/document-router and the apps/remix server routing that mounts API V2. It should avoid drifting to README-only setup material.",
742
  "expected_sources": [
743
+ "packages/trpc/server/document-router",
744
+ "packages/trpc/server",
745
+ "apps/remix/server/router.ts",
746
+ "ARCHITECTURE.md"
747
  ],
748
  "must_include_any": [
749
+ "document-router",
750
+ "packages/trpc/server",
751
+ "API V2",
752
+ "router"
753
  ],
754
  "min_keyword_matches": 3
755
  },
756
  {
757
+ "id": "documenso-followup-email-flow",
758
  "category": "conversation",
759
  "turns": [
760
  {
761
  "role": "user",
762
+ "content": "What happens after a document is sent for signing?"
763
  },
764
  {
765
  "role": "assistant",
766
+ "content": "The send flow updates document state, recipient state, jobs, and lifecycle emails."
767
  }
768
  ],
769
+ "question": "where does the email part live?",
770
+ "ground_truth": "The follow-up should retrieve packages/email templates, mailer/render code, and any server-only email or job code that triggers those templates.",
771
  "expected_sources": [
772
+ "packages/email/templates",
773
+ "packages/email/mailer.ts",
774
+ "packages/email/render.tsx",
775
+ "packages/lib/server-only/email",
776
+ "packages/lib/jobs"
777
  ],
778
  "must_include_any": [
779
+ "packages/email",
780
+ "templates",
781
+ "mailer",
782
+ "jobs"
783
  ],
784
  "min_keyword_matches": 3
785
  },
786
  {
787
+ "id": "documenso-followup-self-hosting-config",
788
  "category": "conversation",
789
  "turns": [
790
  {
791
  "role": "user",
792
+ "content": "How do I run Documenso myself?"
793
  },
794
  {
795
  "role": "assistant",
796
+ "content": "Self-hosting uses the README flow: copy .env.example, set required URLs, database, SMTP, and secrets, run migrations, then start apps/remix."
797
  }
798
  ],
799
+ "question": "which config files should I inspect?",
800
+ "ground_truth": "The follow-up should point to .env.example, README self-hosting instructions, package.json or turbo config for scripts, and apps/remix for where the app starts.",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
801
  "expected_sources": [
802
+ ".env.example",
803
+ "README.md",
804
+ "package.json",
805
+ "turbo.json",
806
+ "apps/remix"
807
  ],
808
  "must_include_any": [
809
+ ".env.example",
810
+ "README",
811
+ "package.json",
812
+ "apps/remix"
813
  ],
814
+ "min_keyword_matches": 3
815
  },
816
  {
817
+ "id": "documenso-followup-signing-bridge",
818
+ "category": "conversation",
819
+ "turns": [
820
+ {
821
+ "role": "user",
822
+ "content": "How does Documenso seal or sign completed documents?"
823
+ },
824
+ {
825
+ "role": "assistant",
826
+ "content": "PDF completion crosses server-only PDF/document logic and the @documenso/signing package, which supports local and Google-backed signing transports."
827
+ }
 
 
828
  ],
829
+ "question": "show me where signing plugs in",
830
+ "ground_truth": "The follow-up should retrieve packages/signing, especially the signPdf entry point, transports, and helpers, plus the seal-document job where completed PDFs are decorated and passed into signing, and signing-related env configuration.",
 
 
 
 
 
831
  "expected_sources": [
832
+ "packages/signing/index.ts",
833
+ "packages/signing/transports",
834
+ "packages/signing/helpers",
835
+ "packages/lib/jobs/definitions/internal/seal-document.handler.ts",
836
+ ".env.example"
837
  ],
838
  "must_include_any": [
839
+ "packages/signing",
840
+ "transports",
841
+ "PDF",
842
+ "signing"
843
  ],
844
  "min_keyword_matches": 3
845
  },
846
  {
847
+ "id": "documenso-codegen-email-template-checklist",
848
  "category": "code-generation",
849
+ "question": "Write a short implementation checklist for adding a new document lifecycle email template in Documenso",
850
+ "ground_truth": "A good checklist should mention adding a React Email template under packages/email/templates, wiring rendering or mailer usage if needed, passing required variables from server-side document or job logic, and covering the change with focused tests or previews.",
851
  "expected_sources": [
852
+ "packages/email/templates",
853
+ "packages/email/mailer.ts",
854
+ "packages/email/render.tsx",
855
+ "packages/lib/jobs",
856
+ "packages/lib/server-only/document"
857
  ],
858
  "must_include_any": [
859
+ "packages/email/templates",
860
+ "React Email",
861
+ "mailer",
862
+ "jobs",
863
+ "tests"
864
  ],
865
  "min_keyword_matches": 3
866
  },
867
  {
868
+ "id": "documenso-codegen-api-route-checklist",
869
  "category": "code-generation",
870
+ "question": "Write a short implementation checklist for adding a new API V2 document operation in Documenso",
871
+ "ground_truth": "A good checklist should point to packages/trpc/server and the document-router, define request and response types or schemas, delegate business logic to packages/lib/server-only/document, update OpenAPI exposure if applicable, persist with Prisma when needed, and add tests.",
872
  "expected_sources": [
873
+ "packages/trpc/server/document-router",
874
+ "packages/trpc/server",
875
+ "packages/lib/server-only/document",
876
+ "packages/prisma",
877
+ "ARCHITECTURE.md"
 
878
  ],
879
  "must_include_any": [
880
+ "document-router",
881
+ "tRPC",
882
+ "OpenAPI",
883
+ "server-only/document",
884
+ "Prisma"
885
  ],
886
+ "min_keyword_matches": 3
887
  }
888
  ]
src/repo_fetcher.py CHANGED
@@ -11,12 +11,17 @@ SUPPORTED_EXTENSIONS = {
11
  ".py",
12
  ".js",
13
  ".jsx",
 
 
14
  ".ts",
15
  ".tsx",
 
 
16
  ".java",
17
  ".go",
18
  ".rs",
19
  ".md",
 
20
  ".json",
21
  ".yml",
22
  ".yaml",
@@ -24,6 +29,12 @@ SUPPORTED_EXTENSIONS = {
24
  ".sh",
25
  ".css",
26
  ".html",
 
 
 
 
 
 
27
  }
28
 
29
  IGNORED_FILENAMES = {
@@ -157,7 +168,10 @@ class RepoFetcher:
157
  continue
158
  if file_path.name in IGNORED_FILENAMES:
159
  continue
160
- if file_path.suffix.lower() not in SUPPORTED_EXTENSIONS:
 
 
 
161
  continue
162
  if file_path.stat().st_size > MAX_FILE_SIZE_BYTES:
163
  continue
 
11
  ".py",
12
  ".js",
13
  ".jsx",
14
+ ".mjs",
15
+ ".cjs",
16
  ".ts",
17
  ".tsx",
18
+ ".mts",
19
+ ".cts",
20
  ".java",
21
  ".go",
22
  ".rs",
23
  ".md",
24
+ ".mdx",
25
  ".json",
26
  ".yml",
27
  ".yaml",
 
29
  ".sh",
30
  ".css",
31
  ".html",
32
+ ".prisma",
33
+ }
34
+
35
+ SUPPORTED_FILENAMES = {
36
+ ".env.example",
37
+ "Dockerfile",
38
  }
39
 
40
  IGNORED_FILENAMES = {
 
168
  continue
169
  if file_path.name in IGNORED_FILENAMES:
170
  continue
171
+ if (
172
+ file_path.suffix.lower() not in SUPPORTED_EXTENSIONS
173
+ and file_path.name not in SUPPORTED_FILENAMES
174
+ ):
175
  continue
176
  if file_path.stat().st_size > MAX_FILE_SIZE_BYTES:
177
  continue