codigest 0.7.0__tar.gz → 0.8.0__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.
- {codigest-0.7.0 → codigest-0.8.0}/CITATION.cff +1 -1
- {codigest-0.7.0 → codigest-0.8.0}/PKG-INFO +34 -23
- codigest-0.8.0/README.ko.md +371 -0
- {codigest-0.7.0 → codigest-0.8.0}/README.md +33 -22
- codigest-0.8.0/docs/demo/demo.gif +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/pyproject.toml +1 -1
- {codigest-0.7.0 → codigest-0.8.0}/server.json +2 -2
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/commands/cap.py +2 -2
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/commands/clean.py +3 -3
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/commands/diff.py +4 -5
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/commands/digest.py +4 -4
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/commands/init.py +13 -24
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/commands/mark.py +2 -2
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/commands/mcp.py +1 -1
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/commands/pack.py +10 -8
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/commands/scan.py +2 -3
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/commands/semdiff.py +7 -8
- codigest-0.8.0/src/codigest/commands/status.py +61 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/commands/term.py +7 -5
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/commands/tree.py +2 -2
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/output.py +2 -2
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/semdiff.py +2 -8
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/main.py +1 -1
- {codigest-0.7.0 → codigest-0.8.0}/uv.lock +1 -1
- codigest-0.7.0/README.ko.md +0 -357
- codigest-0.7.0/docs/demo/demo.gif +0 -0
- codigest-0.7.0/src/codigest/commands/status.py +0 -149
- {codigest-0.7.0 → codigest-0.8.0}/.gitattributes +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/.github/workflows/publish.yml +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/.github/workflows/tests.yml +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/.gitignore +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/.python-version +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/LICENSE +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/docs/demo/make_gif.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/docs/dogfood.md +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/__init__.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/__main__.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/config.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/cache.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/common.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/git_ops.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/processor.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/prompts.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/redact.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/resolver.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/runner.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/scanner.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/shadow.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/shellhist.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/structure.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/tags.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/termstore.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/core/tokenizer.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/options.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/shell/hook.ps1 +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/src/codigest/shell/hook.sh +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/tests/test_pack.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/tests/test_shadow.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/tests/test_structure.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/tests/test_term_install.py +0 -0
- {codigest-0.7.0 → codigest-0.8.0}/tests/test_termstore.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: codigest
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: Human-Centered Codebase Context Manager for LLMs
|
|
5
5
|
Project-URL: Homepage, https://github.com/NaNIsaac/codigest
|
|
6
6
|
Project-URL: Repository, https://github.com/NaNIsaac/codigest
|
|
@@ -30,34 +30,45 @@ Description-Content-Type: text/markdown
|
|
|
30
30
|
|
|
31
31
|
<!-- mcp-name: io.github.NaNIsaac/codigest -->
|
|
32
32
|
|
|
33
|
-
**
|
|
33
|
+
**Collects what an AI model needs to help with your code, from your terminal and your project.**
|
|
34
34
|
|
|
35
35
|
[한국어](README.ko.md)
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
</p>
|
|
37
|
+
Codigest is a command-line tool. When you ask ChatGPT, Claude or a coding agent about a failing
|
|
38
|
+
test or code you are working on, it gathers the material the model needs to answer.
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
A model only knows what you show it. To help, it needs the error, the code involved, and what you
|
|
41
|
+
changed. Collecting that by hand is slow, and it is easy to leave out the one file that matters,
|
|
42
|
+
or to paste far more than the question needs.
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
Codigest remembers the commands you run and their output, finds the files an error points at and
|
|
45
|
+
the changes Git knows about, and puts them together as one block of text. You paste it into a
|
|
46
|
+
chat, or let an agent fetch it directly.
|
|
45
47
|
|
|
46
|
-
|
|
48
|
+
## What it does
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
- **Remembers terminal output.** Commands are stored with their output and exit code. Values that
|
|
51
|
+
look like tokens or passwords are masked before anything is written.
|
|
52
|
+
- **Picks the relevant code.** It finds the files and lines an error names and the files you
|
|
53
|
+
changed, then follows the tests and imports connected to them.
|
|
54
|
+
- **Says why.** Each file carries the reason it was included, and files left out for size are
|
|
55
|
+
still listed by name.
|
|
56
|
+
- **Fits a budget.** Large files come as excerpts around the lines that matter.
|
|
57
|
+
- **Works with agents.** Claude Code, Cursor and other MCP clients can request the same output.
|
|
53
58
|
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
Codigest does not call any AI model; it only prepares what you send to one. Everything runs on
|
|
60
|
+
your machine, and your source files and Git history are only read.
|
|
61
|
+
|
|
62
|
+
<p align="center">
|
|
63
|
+
<img src="docs/demo/demo.gif" alt="cdg cap runs a failing pytest, then cdg pack bundles the failure, the test file it names and the changed file" width="760">
|
|
64
|
+
<br>
|
|
65
|
+
<sub>A test fails; one command collects what the model needs.</sub>
|
|
66
|
+
</p>
|
|
56
67
|
|
|
57
68
|
## Install
|
|
58
69
|
|
|
59
|
-
|
|
60
|
-
|
|
70
|
+
Install it with [uv](https://docs.astral.sh/uv/), which also fetches the Python version Codigest
|
|
71
|
+
needs (3.15) and keeps it apart from your projects:
|
|
61
72
|
|
|
62
73
|
```bash
|
|
63
74
|
winget install --id astral-sh.uv # Windows (skip if you have uv)
|
|
@@ -70,9 +81,9 @@ uv tool update-shell # then restart your terminal
|
|
|
70
81
|
The command is `codigest`, or `cdg` for short.
|
|
71
82
|
If the install fails with a syntax error on `lazy import`, run `uv self update` and try again.
|
|
72
83
|
|
|
73
|
-
##
|
|
84
|
+
## Getting started
|
|
74
85
|
|
|
75
|
-
|
|
86
|
+
Try it in any project with a failing test. No setup is needed.
|
|
76
87
|
|
|
77
88
|
**1. Run the test through `cdg cap`.** Put `--` before your command. The output looks exactly as
|
|
78
89
|
it would without `cdg cap`; Codigest just keeps a copy.
|
|
@@ -90,7 +101,7 @@ Packed ~370 / 30,000 tokens
|
|
|
90
101
|
changes uncommitted changes (git)
|
|
91
102
|
+ test_prices.py line 5 in failing output
|
|
92
103
|
+ prices.py changed
|
|
93
|
-
|
|
104
|
+
Copied pack to clipboard
|
|
94
105
|
```
|
|
95
106
|
|
|
96
107
|
Read it as: the failing command, your uncommitted Git changes, `test_prices.py` because the error
|
|
@@ -155,7 +166,7 @@ what it is not seeing.
|
|
|
155
166
|
|
|
156
167
|
</details>
|
|
157
168
|
|
|
158
|
-
##
|
|
169
|
+
## Making it smoother
|
|
159
170
|
|
|
160
171
|
Once the basic loop works, each of these removes one manual step.
|
|
161
172
|
|
|
@@ -263,7 +274,7 @@ instead, `--no-copy` skips the clipboard, and `-m` / `--message` adds an instruc
|
|
|
263
274
|
| `scan` | The whole project, or chosen paths, as one block | `.codigest/snapshot.txt` |
|
|
264
275
|
| `digest` | Signatures and docstrings, no bodies (Python) | `.codigest/digest.txt` |
|
|
265
276
|
| `tree` | Project tree | nothing |
|
|
266
|
-
| `status` |
|
|
277
|
+
| `status` | What `pack` would use here: last failure, changes, baseline | nothing |
|
|
267
278
|
| `init` | Config file and baseline; only needed to change [file filters](#configuration) | `.codigest/`, `.gitignore` |
|
|
268
279
|
| `clean` | Deletes `.codigest/` (asks first, `-y` to skip) | removes `.codigest/` |
|
|
269
280
|
| `mcp` | MCP server for agents | nothing |
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
# Codigest
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/codigest/) [](https://github.com/NaNIsaac/codigest/actions/workflows/tests.yml) [](LICENSE)
|
|
4
|
+
|
|
5
|
+
**AI에게 코드 질문을 할 때 함께 보낼 자료를 터미널과 프로젝트에서 골라 주는 도구**
|
|
6
|
+
|
|
7
|
+
[English](README.md)
|
|
8
|
+
|
|
9
|
+
Codigest는 명령줄 도구입니다. ChatGPT나 Claude, 코딩 에이전트에게 실패한 테스트나 작업 중인
|
|
10
|
+
코드를 물어볼 때, 모델이 알아야 할 내용을 대신 모아 줍니다.
|
|
11
|
+
|
|
12
|
+
모델은 내가 보여 준 만큼만 압니다. 제대로 답하려면 오류 메시지와 관련 코드, 내가 고친 부분이
|
|
13
|
+
있어야 합니다. 그런데 이걸 손으로 모으다 보면 정작 중요한 파일 하나를 빼먹거나, 반대로 상관없는
|
|
14
|
+
코드까지 잔뜩 붙여 넣게 됩니다.
|
|
15
|
+
|
|
16
|
+
Codigest는 내가 실행한 명령과 그 출력을 기억해 두었다가, 오류가 가리키는 파일과 Git에서 바뀐
|
|
17
|
+
부분을 찾아 하나의 텍스트로 묶어 줍니다. 채팅창에 붙여 넣어도 되고, 에이전트가 직접 가져가게 할
|
|
18
|
+
수도 있습니다.
|
|
19
|
+
|
|
20
|
+
## 하는 일
|
|
21
|
+
|
|
22
|
+
- **터미널 출력을 기억합니다.** 명령과 출력, 종료 코드를 저장합니다. 토큰이나 비밀번호처럼 보이는
|
|
23
|
+
값은 가린 뒤에 저장합니다.
|
|
24
|
+
- **관련 있는 코드를 고릅니다.** 오류에 나온 파일과 줄, Git에서 바뀐 파일을 찾고, 그 파일을 쓰는
|
|
25
|
+
테스트와 import까지 따라갑니다.
|
|
26
|
+
- **고른 이유를 밝힙니다.** 파일마다 왜 넣었는지 적혀 있고, 분량 때문에 뺀 파일도 이름은 남깁니다.
|
|
27
|
+
- **분량을 맞춥니다.** 큰 파일은 오류 근처만 잘라 넣어 토큰 예산에 맞춥니다.
|
|
28
|
+
- **에이전트와 연결됩니다.** Claude Code, Cursor 같은 MCP 클라이언트가 같은 결과를 직접 받아 갑니다.
|
|
29
|
+
|
|
30
|
+
Codigest는 AI 모델을 호출하지 않습니다. 모델에게 보낼 자료를 준비할 뿐입니다. 모든 작업은 내
|
|
31
|
+
컴퓨터 안에서 이루어지고, 소스 파일과 Git 기록은 읽기만 합니다.
|
|
32
|
+
|
|
33
|
+
<p align="center">
|
|
34
|
+
<img src="docs/demo/demo.gif" alt="cdg cap으로 실패하는 pytest를 실행한 뒤, cdg pack이 실패 출력과 오류가 가리키는 테스트 파일, 바뀐 파일을 묶는 화면" width="760">
|
|
35
|
+
<br>
|
|
36
|
+
<sub>테스트가 실패한 뒤, 명령 하나로 모델에게 보낼 자료를 모으는 모습</sub>
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
## 설치
|
|
40
|
+
|
|
41
|
+
[uv](https://docs.astral.sh/uv/)로 설치합니다. uv가 필요한 Python(3.15)까지 알아서 받아 두므로,
|
|
42
|
+
내 프로젝트의 Python 환경과 섞이지 않습니다.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
winget install --id astral-sh.uv # Windows (uv가 이미 있으면 건너뛰기)
|
|
46
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS/Linux
|
|
47
|
+
|
|
48
|
+
uv tool install codigest
|
|
49
|
+
uv tool update-shell # 끝나면 터미널을 다시 열기
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
명령 이름은 `codigest`이고, 줄여서 `cdg`로도 쓸 수 있습니다.
|
|
53
|
+
설치할 때 `lazy import` 부분에서 문법 오류가 나면 `uv self update`를 한 뒤 다시 설치하세요.
|
|
54
|
+
|
|
55
|
+
## 처음 써 보기
|
|
56
|
+
|
|
57
|
+
테스트가 실패하는 프로젝트에서 바로 해 볼 수 있습니다. 미리 설정할 것은 없습니다.
|
|
58
|
+
|
|
59
|
+
**1. 테스트를 `cdg cap`으로 실행합니다.** 실행할 명령 앞에 `--`를 붙입니다. 화면에는 평소와 똑같이
|
|
60
|
+
출력되고, Codigest는 그 내용을 따로 저장해 둡니다.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
cdg cap -- pytest -q # npm test, cargo test, go test ./..., make 무엇이든 됩니다
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**2. `cdg pack`을 실행합니다.** 무엇을 왜 골랐는지 보여 주고, 결과를 클립보드에 복사합니다.
|
|
67
|
+
|
|
68
|
+
```console
|
|
69
|
+
$ cdg pack
|
|
70
|
+
Packed ~370 / 30,000 tokens
|
|
71
|
+
failed pytest -q (exit 1, just now)
|
|
72
|
+
changes uncommitted changes (git)
|
|
73
|
+
+ test_prices.py line 5 in failing output
|
|
74
|
+
+ prices.py changed
|
|
75
|
+
Copied pack to clipboard
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
위에서부터 실패한 명령, Git에서 아직 커밋하지 않은 변경, 오류가 5번째 줄을 가리킨
|
|
79
|
+
`test_prices.py`, 내가 고친 `prices.py`를 담았다는 뜻입니다.
|
|
80
|
+
|
|
81
|
+
**3. 채팅창에 붙여 넣고** 원하는 것을 적습니다. 요청을 미리 넣어 둘 수도 있습니다:
|
|
82
|
+
`cdg pack -m "할인 계산이 틀린 이유를 찾아서 고쳐 줘"`.
|
|
83
|
+
|
|
84
|
+
<details>
|
|
85
|
+
<summary>클립보드에 실제로 들어간 내용</summary>
|
|
86
|
+
|
|
87
|
+
XML 블록 하나입니다. 명령과 출력, diff, 그리고 줄 번호와 포함한 이유가 붙은 파일이 들어 있습니다.
|
|
88
|
+
위 예시 그대로이고 작업 경로만 줄였습니다.
|
|
89
|
+
|
|
90
|
+
```xml
|
|
91
|
+
<context_pack project="project">
|
|
92
|
+
<terminal_history>
|
|
93
|
+
<command index="1" command="pytest -q" exit_code="1" cwd="~/project" duration="1.5s" at="2026-10-17T01:58:14+09:00">
|
|
94
|
+
<output>
|
|
95
|
+
F [100%]
|
|
96
|
+
================================= FAILURES ==================================
|
|
97
|
+
_____________________________ test_ten_percent ______________________________
|
|
98
|
+
|
|
99
|
+
def test_ten_percent():
|
|
100
|
+
> assert apply_discount(200, 10) == 180
|
|
101
|
+
E assert -1800 == 180
|
|
102
|
+
E + where -1800 = apply_discount(200, 10)
|
|
103
|
+
|
|
104
|
+
test_prices.py:5: AssertionError
|
|
105
|
+
========================== short test summary info ==========================
|
|
106
|
+
FAILED test_prices.py::test_ten_percent - assert -1800 == 180
|
|
107
|
+
1 failed in 0.11s
|
|
108
|
+
</output>
|
|
109
|
+
</command>
|
|
110
|
+
</terminal_history>
|
|
111
|
+
<changes source="uncommitted changes (git)">
|
|
112
|
+
diff --git a/prices.py b/prices.py
|
|
113
|
+
index 3d691df..428752a 100644
|
|
114
|
+
--- a/prices.py
|
|
115
|
+
+++ b/prices.py
|
|
116
|
+
@@ -1,2 +1,2 @@
|
|
117
|
+
def apply_discount(price, percent):
|
|
118
|
+
- return price * (1 - percent / 100)
|
|
119
|
+
+ return price * (1 - percent)
|
|
120
|
+
</changes>
|
|
121
|
+
<file path="test_prices.py" reason="line 5 in failing output">
|
|
122
|
+
1: from prices import apply_discount
|
|
123
|
+
2:
|
|
124
|
+
3:
|
|
125
|
+
4: def test_ten_percent():
|
|
126
|
+
5: assert apply_discount(200, 10) == 180
|
|
127
|
+
</file>
|
|
128
|
+
<file path="prices.py" reason="changed">
|
|
129
|
+
1: def apply_discount(price, percent):
|
|
130
|
+
2: return price * (1 - percent)
|
|
131
|
+
</file>
|
|
132
|
+
</context_pack>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
분량이 넘쳐 뺀 파일은 `<omitted>` 블록에 이름이 남기 때문에, 모델도 무엇이 빠졌는지 알 수 있습니다.
|
|
136
|
+
|
|
137
|
+
</details>
|
|
138
|
+
|
|
139
|
+
## 더 편하게 쓰기
|
|
140
|
+
|
|
141
|
+
기본 흐름에 익숙해졌다면, 아래 두 가지로 손이 한 번씩 덜 갑니다.
|
|
142
|
+
|
|
143
|
+
**`cdg cap`을 매번 붙이지 않기.** 셸에 한 번 훅을 설치하면 모든 명령이 자동으로 기록됩니다.
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
cdg term install # 되돌릴 때는 cdg term uninstall
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**붙여 넣지 않기.** 코딩 에이전트를 MCP로 연결하면 에이전트가 직접 가져갑니다.
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
claude mcp add --scope user codigest -- cdg mcp # Claude Code
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Cursor, VS Code, Claude Desktop 같은 다른 클라이언트에서는 명령 `cdg`, 인자 `["mcp"]`로 stdio
|
|
156
|
+
서버를 추가하면 됩니다. 자세한 내용은 [참고 자료](#자동-기록)에 있습니다.
|
|
157
|
+
|
|
158
|
+
## `pack`이 파일을 고르는 기준
|
|
159
|
+
|
|
160
|
+
넣을 줄 알았던 파일이 빠졌거나 뜻밖의 파일이 들어왔을 때 확인하세요. `pack`은 아래 순서대로
|
|
161
|
+
토큰 예산(기본 30,000)을 채웁니다.
|
|
162
|
+
|
|
163
|
+
1. 직접 지정한 파일: `cdg pack src/prices.py`
|
|
164
|
+
2. 이 프로젝트에서 최근 한 시간 안에 실패한 마지막 명령의 출력에 나온 파일.
|
|
165
|
+
`File "x.py", line 7`(Python), `x.py:7`(pytest, ruff, gcc, rustc, eslint), `x.ts(7,3)`(tsc)
|
|
166
|
+
같은 형식을 알아봅니다. 같은 명령이 나중에 성공하면 그 실패는 더 이상 쓰지 않습니다.
|
|
167
|
+
내가 고치지 않았는데 출력에만 나온 파일은, 오류가 가리킨 곳마다 앞뒤 열 줄씩만 잘라서 넣고
|
|
168
|
+
`lines="40-60"`처럼 표시합니다. 짧은 파일은 전체를 넣습니다.
|
|
169
|
+
3. 내가 바꾼 파일: Git에서 아직 커밋하지 않은 파일과 새로 만든 파일. `cdg mark`로 기준점을
|
|
170
|
+
잡아 두었다면 그 뒤로 바뀐 파일([아래](#특정-시점-이후의-변경-사항-보기) 참고).
|
|
171
|
+
4. 바뀐 파일을 import하는 테스트(`test_*.py`, `*_test.py`, `*.test.ts`, `*.spec.js` 등).
|
|
172
|
+
5. 1·3·4번 파일이 import하는 프로젝트 안의 파일. Python import와 JS/TS 상대 경로 import를
|
|
173
|
+
따라갑니다(`./x`, `x.ts`를 가리키는 `./x.js`, `dir/index.ts`를 가리키는 `./dir`).
|
|
174
|
+
|
|
175
|
+
실패한 명령과 diff는 항상 넣고, `.env`, `*.pem`, `*.key`, SSH 키는 절대 넣지 않습니다. 토큰 수는
|
|
176
|
+
네 글자를 한 토큰으로 계산한 어림값이라 실제와 조금 다를 수 있습니다.
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
cdg pack -b 8000 # 예산을 줄이기
|
|
180
|
+
cdg pack -s > context.xml # 클립보드 대신 화면에 출력
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## 다른 상황에서 쓰기
|
|
184
|
+
|
|
185
|
+
`pack`은 테스트가 실패했을 때를 위한 명령입니다. 다른 상황에서는 아래 명령을 씁니다.
|
|
186
|
+
|
|
187
|
+
### 이전에 실행한 명령 꺼내기
|
|
188
|
+
|
|
189
|
+
마지막 실패뿐 아니라 기록해 둔 명령은 모두 다시 꺼낼 수 있습니다.
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
cdg term # 마지막 명령과 출력
|
|
193
|
+
cdg term -n 3 # 최근 3개
|
|
194
|
+
cdg term -f # 마지막으로 실패한 명령
|
|
195
|
+
cdg term --here -n 3 # 이 프로젝트에서 실행한 최근 3개
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### 특정 시점 이후의 변경 사항 보기
|
|
199
|
+
|
|
200
|
+
작업을 시작하기 전에 기준점을 잡아 두면, 나중에 그 뒤로 바뀐 내용을 한꺼번에 받을 수 있습니다.
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
cdg mark # 예: 리팩터링을 시작하기 전에
|
|
204
|
+
# ... 작업 ...
|
|
205
|
+
cdg diff # 기준점 이후의 diff
|
|
206
|
+
cdg semdiff # Python 전용: 어떤 함수와 클래스가 바뀌었는지
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
기준점은 `.codigest/` 폴더에 따로 저장하는 복사본이라 Git 기록에는 영향이 없습니다. 기준점을 잡아
|
|
210
|
+
두면 `pack`도 `git diff` 대신 이것과 비교합니다.
|
|
211
|
+
|
|
212
|
+
### 프로젝트 전체나 구조만 넘기기
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
cdg scan # 모든 파일을 하나로 묶기 (3만 토큰이 넘으면 먼저 확인)
|
|
216
|
+
cdg scan src/app.py -r # 파일 하나와, 그 파일이 import하는 프로젝트 파일
|
|
217
|
+
cdg digest # Python 함수 선언과 docstring만, 훨씬 짧음
|
|
218
|
+
cdg tree # 파일 트리만
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## 참고 자료
|
|
222
|
+
|
|
223
|
+
- [전체 명령](#전체-명령)
|
|
224
|
+
- [터미널 기록](#터미널-기록)
|
|
225
|
+
- [MCP 도구](#mcp-도구)
|
|
226
|
+
- [설정](#설정)
|
|
227
|
+
- [개인정보와 안전](#개인정보와-안전)
|
|
228
|
+
- [동작 방식](#동작-방식)
|
|
229
|
+
- [개발](#개발)
|
|
230
|
+
|
|
231
|
+
### 전체 명령
|
|
232
|
+
|
|
233
|
+
결과를 만드는 명령은 모두 클립보드에 복사합니다. `-s` / `--stdout`을 붙이면 화면에 출력하고,
|
|
234
|
+
`--no-copy`를 붙이면 복사하지 않으며, `-m` / `--message`로 요청 문구를 덧붙일 수 있습니다.
|
|
235
|
+
|
|
236
|
+
| 명령 | 하는 일 | 프로젝트에 만드는 파일 |
|
|
237
|
+
| --- | --- | --- |
|
|
238
|
+
| `pack` | 마지막 실패와 관련 파일, 변경 사항 묶기 | 없음 |
|
|
239
|
+
| `cap` | 명령을 실행하고 출력 기록 | 없음 |
|
|
240
|
+
| `term` | 최근 기록한 명령과 출력 보기 | 없음 |
|
|
241
|
+
| `mark` | 기준점 잡기 | `.codigest/` |
|
|
242
|
+
| `diff` | 기준점 이후의 diff | `.codigest/changes.diff` |
|
|
243
|
+
| `semdiff` | 기준점 이후 함수·클래스 단위 변경 (Python) | `.codigest/semdiff.txt` |
|
|
244
|
+
| `scan` | 프로젝트 전체나 지정한 경로를 하나로 묶기 | `.codigest/snapshot.txt` |
|
|
245
|
+
| `digest` | 함수 본문을 뺀 선언과 docstring (Python) | `.codigest/digest.txt` |
|
|
246
|
+
| `tree` | 프로젝트 파일 트리 | 없음 |
|
|
247
|
+
| `status` | 지금 `pack`이 쓸 내용 확인: 마지막 실패, 변경 사항, 기준점 | 없음 |
|
|
248
|
+
| `init` | 설정 파일 만들기와 기준점 잡기. [파일 필터](#설정)를 바꿀 때만 필요 | `.codigest/`, `.gitignore` |
|
|
249
|
+
| `clean` | `.codigest/` 지우기 (먼저 물어보며, `-y`면 묻지 않음) | `.codigest/` 삭제 |
|
|
250
|
+
| `mcp` | 에이전트용 MCP 서버 실행 | 없음 |
|
|
251
|
+
|
|
252
|
+
그 밖의 옵션: `scan -l`은 줄 번호를 붙이고, `scan -a`는 설정 필터를 무시하며, `scan -y`는 확인 없이
|
|
253
|
+
진행합니다(CI용). `scan`, `diff`, `semdiff`, `digest`에 `-r` / `--resolve`를 붙이면 대상 파일이
|
|
254
|
+
import하는 프로젝트 파일도 함께 넣습니다. `cdg <명령> --help`로 모든 옵션을 볼 수 있습니다.
|
|
255
|
+
|
|
256
|
+
### 터미널 기록
|
|
257
|
+
|
|
258
|
+
`cdg cap`은 명령의 출력을 그대로 보여 주면서 명령어, 출력(stdout과 stderr), 종료 코드, 실행한
|
|
259
|
+
폴더를 기록합니다. 기록은 프로젝트마다 따로가 아니라 컴퓨터 한 곳에 모이므로, `cap`과 `term`은
|
|
260
|
+
어느 폴더에서나 쓸 수 있습니다.
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
cdg cap "npm run build | tail -20" # 파이프가 있으면 따옴표로 감싸기
|
|
264
|
+
cdg term -i 2 # 두 번 전에 실행한 명령 하나만
|
|
265
|
+
cdg term path # 기록 파일 위치 (CODIGEST_HOME으로 바꿀 수 있음)
|
|
266
|
+
cdg term clear # 기록 모두 지우기
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
`cap` 없이 실행한 명령은 셸의 히스토리(PowerShell, bash, zsh, fish)에서 읽어 오며, 이때는 출력이
|
|
270
|
+
없습니다.
|
|
271
|
+
|
|
272
|
+
#### 자동 기록
|
|
273
|
+
|
|
274
|
+
`cdg term install`은 설치되어 있는 셸에 맞춰 PowerShell 프로필, `~/.bashrc`, `~/.zshrc`에 훅을
|
|
275
|
+
추가합니다. `--shell powershell|bash|zsh|all`로 고를 수 있고, Windows의 Git Bash는 bash로 칩니다.
|
|
276
|
+
명령은 원래 세션에서 그대로 실행되므로 `cd`, 변수, 함수가 모두 평소처럼 동작하고, 히스토리에도
|
|
277
|
+
입력한 그대로 남습니다. 편집기, 페이저, REPL, `ssh`는 기록하지 않습니다.
|
|
278
|
+
|
|
279
|
+
- 명령 하나만 기록하지 않으려면 맨 앞에 공백을 넣습니다.
|
|
280
|
+
- 기록하지 않을 프로그램을 더 지정하려면: `$env:CODIGEST_CAP_SKIP = '^\s*(myrepl|mytui)\b'`
|
|
281
|
+
(bash/zsh에서는 `export CODIGEST_CAP_SKIP='^(myrepl|mytui)( |$)'`, 확장 정규식).
|
|
282
|
+
- 지금 세션에서만 끄려면: `$env:CODIGEST_NOCAP = 1` (bash/zsh: `export CODIGEST_NOCAP=1`).
|
|
283
|
+
- 훅을 없애려면: `cdg term uninstall`.
|
|
284
|
+
|
|
285
|
+
알아 둘 점:
|
|
286
|
+
|
|
287
|
+
- 기록되는 프로그램은 터미널이 아니라 파이프로 출력하게 되므로, 색이나 진행 막대가 사라지는
|
|
288
|
+
프로그램이 있습니다.
|
|
289
|
+
- bash(4 이상)와 zsh에서는 여러 줄에 걸친 명령(여러 줄로 입력한 반복문, heredoc), 백그라운드
|
|
290
|
+
작업(`cmd &`), `!` 히스토리 확장을 쓴 줄은 기록하지 않고 그냥 실행합니다. bash에서는 서브셸
|
|
291
|
+
`( ... )`로 시작하는 줄도 마찬가지입니다.
|
|
292
|
+
- bash 훅은 DEBUG 트랩을 씁니다. 첫 프롬프트 전에 설정된 트랩(starship, bash-preexec)은 그대로
|
|
293
|
+
두지만, 그 뒤에 새로 설정한 DEBUG 트랩은 훅을 덮어씁니다.
|
|
294
|
+
|
|
295
|
+
### MCP 도구
|
|
296
|
+
|
|
297
|
+
| 도구 | 돌려주는 내용 |
|
|
298
|
+
| --- | --- |
|
|
299
|
+
| `pack` | 마지막 실패와 관련 파일, 변경 사항, import를 예산에 맞춰 (`targets`, `budget`, `message`) |
|
|
300
|
+
| `terminal_history` | 최근 명령과 출력, 종료 코드 (`count`, `failed`, `here`: 이 프로젝트만, 기본값 켜짐) |
|
|
301
|
+
| `scan` | 프로젝트 전체 묶음 (`targets`, `resolve`, `message`) |
|
|
302
|
+
| `diff` / `semdiff` | 기준점 이후의 diff / 구조 변경 |
|
|
303
|
+
| `digest` | 선언과 docstring만 |
|
|
304
|
+
| `tree` | 파일 트리 |
|
|
305
|
+
|
|
306
|
+
각 도구는 CLI가 출력하는 것과 똑같은 내용을 돌려줍니다. 기준점을 옮기는 도구는 없고, 서버를 실행한
|
|
307
|
+
프로젝트 밖의 경로는 거부합니다.
|
|
308
|
+
|
|
309
|
+
### 설정
|
|
310
|
+
|
|
311
|
+
`cdg init`을 실행하면 `.codigest/config.toml`이 생깁니다. `[filter]` 항목에서 모든 명령이 다룰
|
|
312
|
+
파일을 정합니다.
|
|
313
|
+
|
|
314
|
+
```toml
|
|
315
|
+
[filter]
|
|
316
|
+
# 이 확장자만 다룹니다 (지우면 무시 목록에 없는 모든 파일)
|
|
317
|
+
extensions = [".py", ".ts", ".rs", ".md", ".json"]
|
|
318
|
+
|
|
319
|
+
# 추가로 뺄 파일, .gitignore 문법 (.gitignore는 항상 따릅니다)
|
|
320
|
+
exclude_patterns = [
|
|
321
|
+
"*.lock",
|
|
322
|
+
"tests/data/",
|
|
323
|
+
"legacy_code/"
|
|
324
|
+
]
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
`.git/`, `.codigest/`, 가상환경, `node_modules/`, `__pycache__/`는 설정과 상관없이 항상 뺍니다.
|
|
328
|
+
|
|
329
|
+
### 개인정보와 안전
|
|
330
|
+
|
|
331
|
+
- **기록 속 비밀정보.** API 키, 토큰, `password=...`, 개인 키, URL에 들어 있는 인증 정보처럼 흔한
|
|
332
|
+
형태는 디스크에 저장하기 전에 가립니다. `env`, `printenv`, `gh auth token`, `aws configure`처럼
|
|
333
|
+
인증 정보를 출력하는 명령은 출력을 아예 저장하지 않습니다. 다만 모든 형태의 비밀정보를 잡아낼
|
|
334
|
+
수는 없습니다.
|
|
335
|
+
- **비밀정보 파일.** `pack`은 `.env*`, `*.pem`, `*.key`, `*.p12`, `*.pfx`, SSH 개인 키를 넣지 않고,
|
|
336
|
+
뺐다는 사실만 목록에 남깁니다.
|
|
337
|
+
- **내 프로젝트.** 어떤 명령도 소스 파일을 수정하지 않습니다. 저장하는 결과와 기준점은 모두
|
|
338
|
+
`.codigest/` 폴더 안에만 두며, `init`이 이 폴더를 `.gitignore`에 추가합니다. 기준점을 잡지 않았다면
|
|
339
|
+
`pack`은 파일을 하나도 만들지 않습니다.
|
|
340
|
+
- **기록 파일 위치.** `cdg term path`로 확인할 수 있습니다. macOS와 Linux에서는 본인만 읽을 수 있게
|
|
341
|
+
저장하고, `cdg term clear`로 지울 수 있습니다.
|
|
342
|
+
- **외부로 보내지 않습니다.** Codigest는 네트워크를 쓰지 않습니다. 결과는 내가 붙여 넣은 곳이나
|
|
343
|
+
내가 연결한 MCP 클라이언트로만 갑니다.
|
|
344
|
+
|
|
345
|
+
### 동작 방식
|
|
346
|
+
|
|
347
|
+
- **기준점.** `.codigest/anchor/.shadow_git`에 있는 별도의 Git 저장소입니다. 편집기가 프로젝트
|
|
348
|
+
저장소로 착각하지 않도록 이름을 `.git`으로 짓지 않았습니다. `mark`와 `init`이 현재 상태를 여기에
|
|
349
|
+
커밋하고, `diff`, `semdiff`, `status`, `pack`이 지금 파일과 비교합니다.
|
|
350
|
+
- **터미널 기록.** 한 줄에 하나씩 JSON으로 적는 파일 하나에 최근 명령 200개를 보관합니다. 출력은
|
|
351
|
+
명령 하나당 64 KB까지 저장하고, 넘치면 앞부분과 뒷부분만 남깁니다.
|
|
352
|
+
- **출력 형식.** 파일 내용은 `<file>` 블록 안에 XML 이스케이프해서 넣고, 블록을 들여쓰지 않아
|
|
353
|
+
프롬프트에 불필요한 공백이 섞이지 않게 합니다.
|
|
354
|
+
- **MCP.** stdio로 JSON-RPC를 주고받는 작은 서버입니다. 각 도구는 일반 CLI를 `-s --no-copy`로
|
|
355
|
+
실행하므로, 에이전트는 내가 붙여 넣을 내용과 똑같은 것을 받습니다.
|
|
356
|
+
|
|
357
|
+
### 개발
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
git clone https://github.com/NaNIsaac/codigest
|
|
361
|
+
cd codigest
|
|
362
|
+
uv run cdg --help # 내려받은 소스에서 바로 실행
|
|
363
|
+
uv run --with pytest pytest -q # 테스트
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
데모 GIF는 실제로 기록한 출력을 [`docs/demo/make_gif.py`](docs/demo/make_gif.py)가 그려서 만듭니다.
|
|
367
|
+
다시 녹화하는 방법은 그 파일 맨 위의 설명에 있습니다.
|
|
368
|
+
|
|
369
|
+
## 라이선스
|
|
370
|
+
|
|
371
|
+
MIT. [LICENSE](LICENSE)를 참고하세요.
|
|
@@ -4,34 +4,45 @@
|
|
|
4
4
|
|
|
5
5
|
<!-- mcp-name: io.github.NaNIsaac/codigest -->
|
|
6
6
|
|
|
7
|
-
**
|
|
7
|
+
**Collects what an AI model needs to help with your code, from your terminal and your project.**
|
|
8
8
|
|
|
9
9
|
[한국어](README.ko.md)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
</p>
|
|
11
|
+
Codigest is a command-line tool. When you ask ChatGPT, Claude or a coding agent about a failing
|
|
12
|
+
test or code you are working on, it gathers the material the model needs to answer.
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
A model only knows what you show it. To help, it needs the error, the code involved, and what you
|
|
15
|
+
changed. Collecting that by hand is slow, and it is easy to leave out the one file that matters,
|
|
16
|
+
or to paste far more than the question needs.
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
Codigest remembers the commands you run and their output, finds the files an error points at and
|
|
19
|
+
the changes Git knows about, and puts them together as one block of text. You paste it into a
|
|
20
|
+
chat, or let an agent fetch it directly.
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
## What it does
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
- **Remembers terminal output.** Commands are stored with their output and exit code. Values that
|
|
25
|
+
look like tokens or passwords are masked before anything is written.
|
|
26
|
+
- **Picks the relevant code.** It finds the files and lines an error names and the files you
|
|
27
|
+
changed, then follows the tests and imports connected to them.
|
|
28
|
+
- **Says why.** Each file carries the reason it was included, and files left out for size are
|
|
29
|
+
still listed by name.
|
|
30
|
+
- **Fits a budget.** Large files come as excerpts around the lines that matter.
|
|
31
|
+
- **Works with agents.** Claude Code, Cursor and other MCP clients can request the same output.
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
Codigest does not call any AI model; it only prepares what you send to one. Everything runs on
|
|
34
|
+
your machine, and your source files and Git history are only read.
|
|
35
|
+
|
|
36
|
+
<p align="center">
|
|
37
|
+
<img src="docs/demo/demo.gif" alt="cdg cap runs a failing pytest, then cdg pack bundles the failure, the test file it names and the changed file" width="760">
|
|
38
|
+
<br>
|
|
39
|
+
<sub>A test fails; one command collects what the model needs.</sub>
|
|
40
|
+
</p>
|
|
30
41
|
|
|
31
42
|
## Install
|
|
32
43
|
|
|
33
|
-
|
|
34
|
-
|
|
44
|
+
Install it with [uv](https://docs.astral.sh/uv/), which also fetches the Python version Codigest
|
|
45
|
+
needs (3.15) and keeps it apart from your projects:
|
|
35
46
|
|
|
36
47
|
```bash
|
|
37
48
|
winget install --id astral-sh.uv # Windows (skip if you have uv)
|
|
@@ -44,9 +55,9 @@ uv tool update-shell # then restart your terminal
|
|
|
44
55
|
The command is `codigest`, or `cdg` for short.
|
|
45
56
|
If the install fails with a syntax error on `lazy import`, run `uv self update` and try again.
|
|
46
57
|
|
|
47
|
-
##
|
|
58
|
+
## Getting started
|
|
48
59
|
|
|
49
|
-
|
|
60
|
+
Try it in any project with a failing test. No setup is needed.
|
|
50
61
|
|
|
51
62
|
**1. Run the test through `cdg cap`.** Put `--` before your command. The output looks exactly as
|
|
52
63
|
it would without `cdg cap`; Codigest just keeps a copy.
|
|
@@ -64,7 +75,7 @@ Packed ~370 / 30,000 tokens
|
|
|
64
75
|
changes uncommitted changes (git)
|
|
65
76
|
+ test_prices.py line 5 in failing output
|
|
66
77
|
+ prices.py changed
|
|
67
|
-
|
|
78
|
+
Copied pack to clipboard
|
|
68
79
|
```
|
|
69
80
|
|
|
70
81
|
Read it as: the failing command, your uncommitted Git changes, `test_prices.py` because the error
|
|
@@ -129,7 +140,7 @@ what it is not seeing.
|
|
|
129
140
|
|
|
130
141
|
</details>
|
|
131
142
|
|
|
132
|
-
##
|
|
143
|
+
## Making it smoother
|
|
133
144
|
|
|
134
145
|
Once the basic loop works, each of these removes one manual step.
|
|
135
146
|
|
|
@@ -237,7 +248,7 @@ instead, `--no-copy` skips the clipboard, and `-m` / `--message` adds an instruc
|
|
|
237
248
|
| `scan` | The whole project, or chosen paths, as one block | `.codigest/snapshot.txt` |
|
|
238
249
|
| `digest` | Signatures and docstrings, no bodies (Python) | `.codigest/digest.txt` |
|
|
239
250
|
| `tree` | Project tree | nothing |
|
|
240
|
-
| `status` |
|
|
251
|
+
| `status` | What `pack` would use here: last failure, changes, baseline | nothing |
|
|
241
252
|
| `init` | Config file and baseline; only needed to change [file filters](#configuration) | `.codigest/`, `.gitignore` |
|
|
242
253
|
| `clean` | Deletes `.codigest/` (asks first, `-y` to skip) | removes `.codigest/` |
|
|
243
254
|
| `mcp` | MCP server for agents | nothing |
|
|
Binary file
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"url": "https://github.com/NaNIsaac/codigest",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.8.0",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "pypi",
|
|
14
14
|
"identifier": "codigest",
|
|
15
|
-
"version": "0.
|
|
15
|
+
"version": "0.8.0",
|
|
16
16
|
"runtimeHint": "uvx",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
@@ -32,7 +32,7 @@ CommandArgument = Annotated[
|
|
|
32
32
|
|
|
33
33
|
def handle(ctx: typer.Context, command: CommandArgument = None) -> None:
|
|
34
34
|
"""
|
|
35
|
-
|
|
35
|
+
Run a command as usual and keep its output for `pack` and `term`.
|
|
36
36
|
|
|
37
37
|
Examples:
|
|
38
38
|
|
|
@@ -73,6 +73,6 @@ def handle(ctx: typer.Context, command: CommandArgument = None) -> None:
|
|
|
73
73
|
try:
|
|
74
74
|
termstore.append_entry(entry)
|
|
75
75
|
except OSError as e:
|
|
76
|
-
err_console.print(f"[dim]
|
|
76
|
+
err_console.print(f"[dim]Capture not stored: {e}[/dim]")
|
|
77
77
|
|
|
78
78
|
raise typer.Exit(code=exit_code)
|