codebase-brief 0.1.2__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.
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/CHANGELOG.md +10 -0
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/PKG-INFO +10 -6
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/README.md +8 -4
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/codebase_brief.egg-info/PKG-INFO +10 -6
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/context_inject/cli.py +104 -5
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/pyproject.toml +2 -2
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/tests/test_cli.py +17 -2
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/CONTRIBUTING.md +0 -0
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/LICENSE +0 -0
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/MANIFEST.in +0 -0
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/codebase_brief.egg-info/SOURCES.txt +0 -0
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/codebase_brief.egg-info/dependency_links.txt +0 -0
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/codebase_brief.egg-info/entry_points.txt +0 -0
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/codebase_brief.egg-info/top_level.txt +0 -0
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/context_inject/__init__.py +0 -0
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/context_inject/__main__.py +0 -0
- {codebase_brief-0.1.2 → codebase_brief-0.1.4}/setup.cfg +0 -0
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.4
|
|
4
|
+
|
|
5
|
+
- Refresh the package listing with the current first-run instructions, product fit, limitations, and importer-aware `--base` behavior.
|
|
6
|
+
- Link package metadata to the project site and keep source-code and issue links explicit.
|
|
7
|
+
|
|
8
|
+
## 0.1.3
|
|
9
|
+
|
|
10
|
+
- Find task-matching snippets deeper inside selected source files and show their line ranges instead of always starting at the file's beginning.
|
|
11
|
+
- Keep excerpt reads bounded and apply the existing secret redaction before including source snippets.
|
|
12
|
+
|
|
3
13
|
## 0.1.2
|
|
4
14
|
|
|
5
15
|
- Add `brief --demo`, which generates a real example brief from temporary sample files without reading or modifying the user's project.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codebase-brief
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Local-first CLI that builds task-focused context briefs from code repositories
|
|
5
5
|
Author: Mohamed Maggy
|
|
6
6
|
License-Expression: MIT
|
|
7
|
-
Project-URL: Homepage, https://github.
|
|
7
|
+
Project-URL: Homepage, https://mohamed1111111m.github.io/codebase-brief/
|
|
8
8
|
Project-URL: Repository, https://github.com/mohamed1111111m/codebase-brief
|
|
9
9
|
Project-URL: Issues, https://github.com/mohamed1111111m/codebase-brief/issues
|
|
10
10
|
Keywords: developer-tools,codebase,context,cli
|
|
@@ -33,11 +33,13 @@ Dynamic: license-file
|
|
|
33
33
|
[](https://www.python.org/)
|
|
34
34
|
[](LICENSE)
|
|
35
35
|
|
|
36
|
-
**
|
|
36
|
+
**Need a reviewed, task-specific handoff for a coding chat?** Codebase Brief turns one coding task into a short file shortlist—with excerpts, reasons, and source paths—when your assistant cannot access the project directly or you want to choose exactly what context to share.
|
|
37
37
|
|
|
38
|
-
It works locally, without an AI service or account. Review the brief, save it, or paste it into
|
|
38
|
+
It works locally, without an AI service or account. Review the brief, save it, or paste it into the assistant you want to use.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
## When Codebase Brief fits
|
|
41
|
+
|
|
42
|
+
It is most useful when your chat cannot access the current local project, or when you want a small, reviewable handoff instead of giving an assistant broad repo access. Some tools now offer local-folder or GitHub-repository access—for example, [ChatGPT Work and Codex](https://help.openai.com/en/articles/20001275), [Claude's local and GitHub connections](https://support.anthropic.com/en/articles/11725091-when-to-use-desktop-and-web-connectors), and [Gemini's GitHub import](https://support.google.com/gemini/answer/16176929). Availability depends on the tool, plan, and setup. If your assistant can already read the current working tree and do the task safely, its built-in repo access may be simpler; you may not need Codebase Brief.
|
|
41
43
|
|
|
42
44
|
## See it in action
|
|
43
45
|
|
|
@@ -53,7 +55,7 @@ The first image is a terminal-style rendering of the app's actual numbered menu.
|
|
|
53
55
|
|
|
54
56
|
You need Python 3.10 or newer. Git is optional, but required for recent-history and base-diff details.
|
|
55
57
|
|
|
56
|
-
The current PyPI
|
|
58
|
+
The current PyPI package includes the review-feedback summary, importer-aware `--base` selection, and a sample demo. Install it with `pipx`:
|
|
57
59
|
|
|
58
60
|
```powershell
|
|
59
61
|
pipx install codebase-brief
|
|
@@ -90,6 +92,8 @@ When the menu opens, it uses the folder you launched it from as the starting pro
|
|
|
90
92
|
|
|
91
93
|
In plain terms, Codebase Brief makes a small guide to a project so an AI coding assistant can get oriented before helping with a task. It does not write or fix code. It reads project information locally and prepares a guide for you to review and share.
|
|
92
94
|
|
|
95
|
+
For selected source files, it looks for code near words in your task and labels each excerpt with its source line range. This is a bounded, best-effort search: if it finds no clear match, it falls back to a general excerpt. Check the cited lines in your editor before relying on them.
|
|
96
|
+
|
|
93
97
|
Before generating the brief, the tool shows suggested files and why they were selected. Press Enter to keep the checked files, type file numbers to toggle selections, or use `add path/to/file.py` to include another safe text file from the repository. Type `none` for an overview without source excerpts. After the brief is shown, saved, or copied, Codebase Brief prints a copyable summary of files kept, removed, added from suggestions, and manually added. To help improve file selection, paste that summary into the [tester feedback form](https://github.com/mohamed1111111m/codebase-brief/issues/new?template=tester-feedback.yml) along with your task and whether the brief helped. Do not include private source code or secrets. The menu's save-here choice writes `context.md` in the folder where you launched the menu; if that is the target repository, the file will be created there. Choose the show or copy option to avoid writing a file into that folder.
|
|
94
98
|
|
|
95
99
|
For your first try, choose a project you know and a task you understand. Check whether the suggested files are the ones you would have shown a coding assistant yourself.
|
|
@@ -8,11 +8,13 @@
|
|
|
8
8
|
[](https://www.python.org/)
|
|
9
9
|
[](LICENSE)
|
|
10
10
|
|
|
11
|
-
**
|
|
11
|
+
**Need a reviewed, task-specific handoff for a coding chat?** Codebase Brief turns one coding task into a short file shortlist—with excerpts, reasons, and source paths—when your assistant cannot access the project directly or you want to choose exactly what context to share.
|
|
12
12
|
|
|
13
|
-
It works locally, without an AI service or account. Review the brief, save it, or paste it into
|
|
13
|
+
It works locally, without an AI service or account. Review the brief, save it, or paste it into the assistant you want to use.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
## When Codebase Brief fits
|
|
16
|
+
|
|
17
|
+
It is most useful when your chat cannot access the current local project, or when you want a small, reviewable handoff instead of giving an assistant broad repo access. Some tools now offer local-folder or GitHub-repository access—for example, [ChatGPT Work and Codex](https://help.openai.com/en/articles/20001275), [Claude's local and GitHub connections](https://support.anthropic.com/en/articles/11725091-when-to-use-desktop-and-web-connectors), and [Gemini's GitHub import](https://support.google.com/gemini/answer/16176929). Availability depends on the tool, plan, and setup. If your assistant can already read the current working tree and do the task safely, its built-in repo access may be simpler; you may not need Codebase Brief.
|
|
16
18
|
|
|
17
19
|
## See it in action
|
|
18
20
|
|
|
@@ -28,7 +30,7 @@ The first image is a terminal-style rendering of the app's actual numbered menu.
|
|
|
28
30
|
|
|
29
31
|
You need Python 3.10 or newer. Git is optional, but required for recent-history and base-diff details.
|
|
30
32
|
|
|
31
|
-
The current PyPI
|
|
33
|
+
The current PyPI package includes the review-feedback summary, importer-aware `--base` selection, and a sample demo. Install it with `pipx`:
|
|
32
34
|
|
|
33
35
|
```powershell
|
|
34
36
|
pipx install codebase-brief
|
|
@@ -65,6 +67,8 @@ When the menu opens, it uses the folder you launched it from as the starting pro
|
|
|
65
67
|
|
|
66
68
|
In plain terms, Codebase Brief makes a small guide to a project so an AI coding assistant can get oriented before helping with a task. It does not write or fix code. It reads project information locally and prepares a guide for you to review and share.
|
|
67
69
|
|
|
70
|
+
For selected source files, it looks for code near words in your task and labels each excerpt with its source line range. This is a bounded, best-effort search: if it finds no clear match, it falls back to a general excerpt. Check the cited lines in your editor before relying on them.
|
|
71
|
+
|
|
68
72
|
Before generating the brief, the tool shows suggested files and why they were selected. Press Enter to keep the checked files, type file numbers to toggle selections, or use `add path/to/file.py` to include another safe text file from the repository. Type `none` for an overview without source excerpts. After the brief is shown, saved, or copied, Codebase Brief prints a copyable summary of files kept, removed, added from suggestions, and manually added. To help improve file selection, paste that summary into the [tester feedback form](https://github.com/mohamed1111111m/codebase-brief/issues/new?template=tester-feedback.yml) along with your task and whether the brief helped. Do not include private source code or secrets. The menu's save-here choice writes `context.md` in the folder where you launched the menu; if that is the target repository, the file will be created there. Choose the show or copy option to avoid writing a file into that folder.
|
|
69
73
|
|
|
70
74
|
For your first try, choose a project you know and a task you understand. Check whether the suggested files are the ones you would have shown a coding assistant yourself.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codebase-brief
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Local-first CLI that builds task-focused context briefs from code repositories
|
|
5
5
|
Author: Mohamed Maggy
|
|
6
6
|
License-Expression: MIT
|
|
7
|
-
Project-URL: Homepage, https://github.
|
|
7
|
+
Project-URL: Homepage, https://mohamed1111111m.github.io/codebase-brief/
|
|
8
8
|
Project-URL: Repository, https://github.com/mohamed1111111m/codebase-brief
|
|
9
9
|
Project-URL: Issues, https://github.com/mohamed1111111m/codebase-brief/issues
|
|
10
10
|
Keywords: developer-tools,codebase,context,cli
|
|
@@ -33,11 +33,13 @@ Dynamic: license-file
|
|
|
33
33
|
[](https://www.python.org/)
|
|
34
34
|
[](LICENSE)
|
|
35
35
|
|
|
36
|
-
**
|
|
36
|
+
**Need a reviewed, task-specific handoff for a coding chat?** Codebase Brief turns one coding task into a short file shortlist—with excerpts, reasons, and source paths—when your assistant cannot access the project directly or you want to choose exactly what context to share.
|
|
37
37
|
|
|
38
|
-
It works locally, without an AI service or account. Review the brief, save it, or paste it into
|
|
38
|
+
It works locally, without an AI service or account. Review the brief, save it, or paste it into the assistant you want to use.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
## When Codebase Brief fits
|
|
41
|
+
|
|
42
|
+
It is most useful when your chat cannot access the current local project, or when you want a small, reviewable handoff instead of giving an assistant broad repo access. Some tools now offer local-folder or GitHub-repository access—for example, [ChatGPT Work and Codex](https://help.openai.com/en/articles/20001275), [Claude's local and GitHub connections](https://support.anthropic.com/en/articles/11725091-when-to-use-desktop-and-web-connectors), and [Gemini's GitHub import](https://support.google.com/gemini/answer/16176929). Availability depends on the tool, plan, and setup. If your assistant can already read the current working tree and do the task safely, its built-in repo access may be simpler; you may not need Codebase Brief.
|
|
41
43
|
|
|
42
44
|
## See it in action
|
|
43
45
|
|
|
@@ -53,7 +55,7 @@ The first image is a terminal-style rendering of the app's actual numbered menu.
|
|
|
53
55
|
|
|
54
56
|
You need Python 3.10 or newer. Git is optional, but required for recent-history and base-diff details.
|
|
55
57
|
|
|
56
|
-
The current PyPI
|
|
58
|
+
The current PyPI package includes the review-feedback summary, importer-aware `--base` selection, and a sample demo. Install it with `pipx`:
|
|
57
59
|
|
|
58
60
|
```powershell
|
|
59
61
|
pipx install codebase-brief
|
|
@@ -90,6 +92,8 @@ When the menu opens, it uses the folder you launched it from as the starting pro
|
|
|
90
92
|
|
|
91
93
|
In plain terms, Codebase Brief makes a small guide to a project so an AI coding assistant can get oriented before helping with a task. It does not write or fix code. It reads project information locally and prepares a guide for you to review and share.
|
|
92
94
|
|
|
95
|
+
For selected source files, it looks for code near words in your task and labels each excerpt with its source line range. This is a bounded, best-effort search: if it finds no clear match, it falls back to a general excerpt. Check the cited lines in your editor before relying on them.
|
|
96
|
+
|
|
93
97
|
Before generating the brief, the tool shows suggested files and why they were selected. Press Enter to keep the checked files, type file numbers to toggle selections, or use `add path/to/file.py` to include another safe text file from the repository. Type `none` for an overview without source excerpts. After the brief is shown, saved, or copied, Codebase Brief prints a copyable summary of files kept, removed, added from suggestions, and manually added. To help improve file selection, paste that summary into the [tester feedback form](https://github.com/mohamed1111111m/codebase-brief/issues/new?template=tester-feedback.yml) along with your task and whether the brief helped. Do not include private source code or secrets. The menu's save-here choice writes `context.md` in the folder where you launched the menu; if that is the target repository, the file will be created there. Choose the show or copy option to avoid writing a file into that folder.
|
|
94
98
|
|
|
95
99
|
For your first try, choose a project you know and a task you understand. Check whether the suggested files are the ones you would have shown a coding assistant yourself.
|
|
@@ -24,7 +24,7 @@ MAX_KEY_FILES = 12
|
|
|
24
24
|
MAX_SELECTION_CHOICES = 30
|
|
25
25
|
MAX_DISCOVERED_FILES = 20_000
|
|
26
26
|
IMPORT_SUFFIXES = {".py", ".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".mts", ".cts"}
|
|
27
|
-
VERSION = "0.1.
|
|
27
|
+
VERSION = "0.1.4"
|
|
28
28
|
MANIFESTS = (
|
|
29
29
|
"package.json", "pyproject.toml", "requirements.txt", "Cargo.toml",
|
|
30
30
|
"go.mod", "Gemfile", "composer.json", "pom.xml",
|
|
@@ -203,6 +203,103 @@ def task_words(task: str) -> set[str]:
|
|
|
203
203
|
return {word.lower() for word in re.findall(r"[A-Za-z][A-Za-z0-9_-]{2,}", task)}
|
|
204
204
|
|
|
205
205
|
|
|
206
|
+
_TASK_STOP_WORDS = {
|
|
207
|
+
"about", "after", "also", "and", "are", "does", "from", "give", "help",
|
|
208
|
+
"how", "into", "its", "make", "show", "that", "the", "this", "what", "with",
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def read_task_excerpt(
|
|
213
|
+
root: Path, relative: str, task: str, limit: int = 1050,
|
|
214
|
+
max_bytes: int = 96_000,
|
|
215
|
+
) -> str | None:
|
|
216
|
+
"""Find compact, task-related source windows, including later definitions.
|
|
217
|
+
|
|
218
|
+
File ranking alone is not enough: returning only the first lines of a large
|
|
219
|
+
file can omit the function that made it relevant. Reads remain bounded and
|
|
220
|
+
pass through the same path and secret safeguards as ordinary excerpts.
|
|
221
|
+
"""
|
|
222
|
+
path = safe_path(root, relative)
|
|
223
|
+
if path is None:
|
|
224
|
+
return None
|
|
225
|
+
try:
|
|
226
|
+
with path.open("rb") as source:
|
|
227
|
+
raw = source.read(max_bytes + 1)
|
|
228
|
+
except OSError:
|
|
229
|
+
return None
|
|
230
|
+
if b"\0" in raw[:4096]:
|
|
231
|
+
return None
|
|
232
|
+
|
|
233
|
+
truncated = len(raw) > max_bytes
|
|
234
|
+
text = raw[:max_bytes].decode("utf-8", errors="replace")
|
|
235
|
+
all_lines = text.splitlines()
|
|
236
|
+
if not all_lines:
|
|
237
|
+
return None
|
|
238
|
+
lines = [line[:500] for line in all_lines[:1500]]
|
|
239
|
+
truncated = truncated or len(all_lines) > len(lines) or any(len(line) > 500 for line in all_lines[:1500])
|
|
240
|
+
terms = {term for term in task_words(task) if term not in _TASK_STOP_WORDS}
|
|
241
|
+
# Split snake_case and hyphenated identifiers so "demo" can match
|
|
242
|
+
# generate_demo_brief without requiring an exact function-name query.
|
|
243
|
+
tokenized_lines = [
|
|
244
|
+
{part.lower() for part in re.findall(r"[A-Za-z][A-Za-z0-9]*", line)}
|
|
245
|
+
for line in lines
|
|
246
|
+
]
|
|
247
|
+
frequencies = {
|
|
248
|
+
term: sum(term in line_terms for line_terms in tokenized_lines)
|
|
249
|
+
for term in terms
|
|
250
|
+
}
|
|
251
|
+
scores: list[float] = []
|
|
252
|
+
for line_terms in tokenized_lines:
|
|
253
|
+
scores.append(sum(
|
|
254
|
+
1 + math.log((len(lines) + 1) / (frequencies[term] + 1))
|
|
255
|
+
for term in terms if term in line_terms
|
|
256
|
+
))
|
|
257
|
+
for index, line in enumerate(lines):
|
|
258
|
+
if scores[index] and re.match(r"\s*(?:async\s+)?(?:def|class)\s+", line):
|
|
259
|
+
# In source files, a matching function/class declaration is a
|
|
260
|
+
# stronger anchor than a help string that merely mentions the task.
|
|
261
|
+
scores[index] += 8
|
|
262
|
+
|
|
263
|
+
if not any(scores):
|
|
264
|
+
return compact(redact("\n".join(lines)), limit)
|
|
265
|
+
|
|
266
|
+
# Make short windows around the strongest matching lines. Merge overlaps,
|
|
267
|
+
# then take the best windows until the excerpt budget is used.
|
|
268
|
+
candidates = sorted(range(len(lines)), key=lambda index: (-scores[index], index))
|
|
269
|
+
windows: list[tuple[int, int]] = []
|
|
270
|
+
for index in candidates:
|
|
271
|
+
if scores[index] == 0:
|
|
272
|
+
break
|
|
273
|
+
start, end = max(0, index - 4), min(len(lines), index + 11)
|
|
274
|
+
if any(start <= old_end and end >= old_start for old_start, old_end in windows):
|
|
275
|
+
continue
|
|
276
|
+
windows.append((start, end))
|
|
277
|
+
selected: list[tuple[int, int, str]] = []
|
|
278
|
+
used = 0
|
|
279
|
+
for start, end in windows:
|
|
280
|
+
body = "\n".join(lines[start:end]).strip()
|
|
281
|
+
snippet = f"Lines {start + 1}–{end}:\n{body}"
|
|
282
|
+
if not body:
|
|
283
|
+
continue
|
|
284
|
+
remaining = limit - used
|
|
285
|
+
if remaining <= 0:
|
|
286
|
+
break
|
|
287
|
+
if len(snippet) > remaining:
|
|
288
|
+
break
|
|
289
|
+
selected.append((start, end, snippet))
|
|
290
|
+
used += len(snippet) + 2
|
|
291
|
+
if not selected:
|
|
292
|
+
return compact("\n".join(lines), limit)
|
|
293
|
+
|
|
294
|
+
selected.sort(key=lambda item: item[0])
|
|
295
|
+
result = "\n…\n".join(snippet for _start, _end, snippet in selected)
|
|
296
|
+
if truncated:
|
|
297
|
+
result += "\nMore of this file was left out to keep the brief short."
|
|
298
|
+
elif len(selected) < len(windows):
|
|
299
|
+
result += "\nOther matching sections were left out to keep the brief short."
|
|
300
|
+
return redact(result)
|
|
301
|
+
|
|
302
|
+
|
|
206
303
|
def discover_files(root: Path) -> list[str]:
|
|
207
304
|
found: list[str] = []
|
|
208
305
|
visited_dirs = 0
|
|
@@ -816,12 +913,14 @@ def gather(
|
|
|
816
913
|
if label and label != "additional project file":
|
|
817
914
|
key.append(f"{relative} is already included above; it was also {label}.")
|
|
818
915
|
continue
|
|
819
|
-
excerpt =
|
|
916
|
+
excerpt = read_task_excerpt(root, relative, task)
|
|
917
|
+
if excerpt is None:
|
|
918
|
+
fallback = read_excerpt(root, relative)
|
|
919
|
+
excerpt = fallback[0] if fallback else None
|
|
820
920
|
if excerpt:
|
|
821
|
-
content
|
|
822
|
-
content = compact(content, 1050)
|
|
921
|
+
content = compact(excerpt, 1050)
|
|
823
922
|
label = reasons.get(relative, "selected by project signals")
|
|
824
|
-
shortened_note = "" if "Some lines were left out" in content
|
|
923
|
+
shortened_note = "" if "Some lines were left out" in content or "More of this file was left out" in content else ""
|
|
825
924
|
key.append(f"{relative} — {label}\n{excerpt_for_brief(relative, content)}" + shortened_note)
|
|
826
925
|
if not key:
|
|
827
926
|
if selected_files is not None and not key_files:
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "codebase-brief"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.4"
|
|
8
8
|
description = "Local-first CLI that builds task-focused context briefs from code repositories"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -27,7 +27,7 @@ classifiers = [
|
|
|
27
27
|
]
|
|
28
28
|
|
|
29
29
|
[project.urls]
|
|
30
|
-
Homepage = "https://github.
|
|
30
|
+
Homepage = "https://mohamed1111111m.github.io/codebase-brief/"
|
|
31
31
|
Repository = "https://github.com/mohamed1111111m/codebase-brief"
|
|
32
32
|
Issues = "https://github.com/mohamed1111111m/codebase-brief/issues"
|
|
33
33
|
|
|
@@ -6,7 +6,7 @@ import unittest
|
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from unittest.mock import patch
|
|
8
8
|
|
|
9
|
-
from context_inject.cli import DEFAULT_BUDGET_TOKENS, MAX_CHARS, MAX_FILE_BYTES, MAX_KEY_FILES, choose_files, compact, copy_to_clipboard, gather, interactive, local_imports, main, read_excerpt, redact, review_feedback, safe_path, suggest_file_details, suggest_files
|
|
9
|
+
from context_inject.cli import DEFAULT_BUDGET_TOKENS, MAX_CHARS, MAX_FILE_BYTES, MAX_KEY_FILES, VERSION, choose_files, compact, copy_to_clipboard, gather, interactive, local_imports, main, read_excerpt, read_task_excerpt, redact, review_feedback, safe_path, suggest_file_details, suggest_files
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class ContextInjectTests(unittest.TestCase):
|
|
@@ -75,6 +75,21 @@ class ContextInjectTests(unittest.TestCase):
|
|
|
75
75
|
self.assertLess(output.index("Files that may help"), output.index("Technology and commands"))
|
|
76
76
|
self.assertLessEqual(len(output), 1000 * 4)
|
|
77
77
|
|
|
78
|
+
def test_task_excerpt_finds_relevant_function_beyond_file_prefix(self):
|
|
79
|
+
filler = "\n".join(f"def unrelated_{index}(): return {index}" for index in range(180))
|
|
80
|
+
source = filler + "\n\ndef build_demo_brief():\n return gather(sample_files, task)\n"
|
|
81
|
+
self.put("src/app.py", source)
|
|
82
|
+
|
|
83
|
+
excerpt = read_task_excerpt(
|
|
84
|
+
self.root, "src/app.py",
|
|
85
|
+
"Explain how the built-in demo creates a sample context brief",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
self.assertIsNotNone(excerpt)
|
|
89
|
+
self.assertIn("def build_demo_brief", excerpt)
|
|
90
|
+
self.assertIn("return gather(sample_files, task)", excerpt)
|
|
91
|
+
self.assertNotIn("def unrelated_0", excerpt)
|
|
92
|
+
|
|
78
93
|
def test_excerpt_shortening_stops_on_a_word_boundary(self):
|
|
79
94
|
excerpt = compact("This is a long sentence that should end on a complete word. " * 3, 90)
|
|
80
95
|
self.assertTrue(excerpt.startswith("This is a long sentence that should\nSome lines were left out"))
|
|
@@ -486,7 +501,7 @@ class ContextInjectTests(unittest.TestCase):
|
|
|
486
501
|
plain = __import__("re").sub(r"\x1b\[[0-9;]*m", "", output.getvalue())
|
|
487
502
|
self.assertIn("CODEBASE", plain)
|
|
488
503
|
self.assertIn("BRIEF", plain)
|
|
489
|
-
self.assertIn("
|
|
504
|
+
self.assertIn(f"v{VERSION}", plain)
|
|
490
505
|
self.assertIn("Meet Briefy - your repo guide", plain)
|
|
491
506
|
self.assertIn("WHAT THIS DOES", plain)
|
|
492
507
|
self.assertIn("Makes a short guide to your project for an AI coding assistant", plain)
|
|
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
|