codigest 0.8.0__tar.gz → 0.9.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.
Files changed (61) hide show
  1. {codigest-0.8.0 → codigest-0.9.0}/CITATION.cff +2 -2
  2. {codigest-0.8.0 → codigest-0.9.0}/PKG-INFO +168 -120
  3. {codigest-0.8.0 → codigest-0.9.0}/README.ko.md +162 -116
  4. {codigest-0.8.0 → codigest-0.9.0}/README.md +167 -119
  5. {codigest-0.8.0 → codigest-0.9.0}/pyproject.toml +1 -1
  6. {codigest-0.8.0 → codigest-0.9.0}/server.json +2 -2
  7. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/commands/clean.py +1 -1
  8. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/commands/diff.py +9 -23
  9. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/commands/digest.py +6 -21
  10. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/commands/init.py +2 -10
  11. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/commands/mcp.py +19 -2
  12. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/commands/pack.py +42 -42
  13. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/commands/scan.py +18 -54
  14. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/commands/semdiff.py +7 -22
  15. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/commands/status.py +0 -4
  16. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/commands/term.py +4 -3
  17. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/commands/tree.py +1 -1
  18. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/cache.py +4 -1
  19. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/common.py +5 -1
  20. codigest-0.9.0/src/codigest/core/output.py +76 -0
  21. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/prompts.py +29 -75
  22. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/redact.py +49 -7
  23. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/resolver.py +37 -4
  24. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/tags.py +3 -2
  25. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/main.py +18 -15
  26. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/options.py +6 -0
  27. codigest-0.9.0/tests/test_output.py +23 -0
  28. {codigest-0.8.0 → codigest-0.9.0}/tests/test_pack.py +55 -1
  29. codigest-0.9.0/tests/test_secrets.py +72 -0
  30. {codigest-0.8.0 → codigest-0.9.0}/tests/test_termstore.py +18 -0
  31. {codigest-0.8.0 → codigest-0.9.0}/uv.lock +1 -1
  32. codigest-0.8.0/src/codigest/core/output.py +0 -50
  33. {codigest-0.8.0 → codigest-0.9.0}/.gitattributes +0 -0
  34. {codigest-0.8.0 → codigest-0.9.0}/.github/workflows/publish.yml +0 -0
  35. {codigest-0.8.0 → codigest-0.9.0}/.github/workflows/tests.yml +0 -0
  36. {codigest-0.8.0 → codigest-0.9.0}/.gitignore +0 -0
  37. {codigest-0.8.0 → codigest-0.9.0}/.python-version +0 -0
  38. {codigest-0.8.0 → codigest-0.9.0}/LICENSE +0 -0
  39. {codigest-0.8.0 → codigest-0.9.0}/docs/demo/demo.gif +0 -0
  40. {codigest-0.8.0 → codigest-0.9.0}/docs/demo/make_gif.py +0 -0
  41. {codigest-0.8.0 → codigest-0.9.0}/docs/dogfood.md +0 -0
  42. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/__init__.py +0 -0
  43. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/__main__.py +0 -0
  44. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/commands/cap.py +0 -0
  45. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/commands/mark.py +0 -0
  46. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/config.py +0 -0
  47. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/git_ops.py +0 -0
  48. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/processor.py +0 -0
  49. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/runner.py +0 -0
  50. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/scanner.py +0 -0
  51. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/semdiff.py +0 -0
  52. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/shadow.py +0 -0
  53. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/shellhist.py +0 -0
  54. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/structure.py +0 -0
  55. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/termstore.py +0 -0
  56. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/core/tokenizer.py +0 -0
  57. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/shell/hook.ps1 +0 -0
  58. {codigest-0.8.0 → codigest-0.9.0}/src/codigest/shell/hook.sh +0 -0
  59. {codigest-0.8.0 → codigest-0.9.0}/tests/test_shadow.py +0 -0
  60. {codigest-0.8.0 → codigest-0.9.0}/tests/test_structure.py +0 -0
  61. {codigest-0.8.0 → codigest-0.9.0}/tests/test_term_install.py +0 -0
@@ -14,8 +14,8 @@ authors:
14
14
  repository-code: "https://github.com/NaNIsaac/codigest"
15
15
  url: "https://pypi.org/project/codigest/"
16
16
  license: MIT
17
- version: 0.8.0
18
- date-released: "2026-10-17"
17
+ version: 0.9.0
18
+ date-released: "2026-10-18"
19
19
  keywords:
20
20
  - LLM
21
21
  - developer tools
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: codigest
3
- Version: 0.8.0
3
+ Version: 0.9.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,30 +30,32 @@ Description-Content-Type: text/markdown
30
30
 
31
31
  <!-- mcp-name: io.github.NaNIsaac/codigest -->
32
32
 
33
- **Collects what an AI model needs to help with your code, from your terminal and your project.**
33
+ **Share the code context you choose with an AI: your project, a few files, what changed, or the command that failed.**
34
34
 
35
35
  [한국어](README.ko.md)
36
36
 
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.
37
+ Codigest is a command-line tool for the moment you ask ChatGPT, Claude or a coding agent about
38
+ your code. It turns the part of your project you pick into one block of text you can paste into
39
+ any chat.
39
40
 
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.
43
-
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.
41
+ A model only knows what you show it. Copying files by hand is slow, it is easy to miss the one
42
+ file that matters, and it is just as easy to paste far more than the question needs. Codigest
43
+ lets you decide what to share and then collects it for you: the whole project, a file and the
44
+ files it imports, what changed since a point you marked, or a failing test with the code it points
45
+ at.
47
46
 
48
47
  ## What it does
49
48
 
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.
49
+ - **Bundles code you pick.** The whole project, chosen files and folders, or the local files they
50
+ import (Python, JS/TS), as one block with the file tree.
51
+ - **Shows what changed.** Text or function-level diffs since a baseline you set, without touching
52
+ your Git history.
53
+ - **Brings in terminal output.** It records commands you run and can hand over a failing one
54
+ together with the files its error points at.
55
+ - **Says what it included.** Every bundle reports its size, and `pack` gives the reason for each
56
+ file and names the ones it left out.
57
+ - **Keeps secrets out.** `.env` files and keys are never included, and tokens in code or output
58
+ are masked.
57
59
  - **Works with agents.** Claude Code, Cursor and other MCP clients can request the same output.
58
60
 
59
61
  Codigest does not call any AI model; it only prepares what you send to one. Everything runs on
@@ -62,7 +64,7 @@ your machine, and your source files and Git history are only read.
62
64
  <p align="center">
63
65
  <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
66
  <br>
65
- <sub>A test fails; one command collects what the model needs.</sub>
67
+ <sub>One of the workflows below: a test fails, and one command collects what the model needs.</sub>
66
68
  </p>
67
69
 
68
70
  ## Install
@@ -78,21 +80,91 @@ uv tool install codigest
78
80
  uv tool update-shell # then restart your terminal
79
81
  ```
80
82
 
81
- The command is `codigest`, or `cdg` for short.
83
+ The command is `codigest`, or `cdg` for short. No setup is needed in your projects.
82
84
  If the install fails with a syntax error on `lazy import`, run `uv self update` and try again.
83
85
 
84
- ## Getting started
86
+ Every command below copies its result to the clipboard. Add `-s` to also print it (for pipes and
87
+ redirects), `-o FILE` to also write it to a file, `--no-copy` to leave the clipboard alone, and
88
+ `-m "..."` to put your question or instruction in it.
85
89
 
86
- Try it in any project with a failing test. No setup is needed.
90
+ ## 1. Share your project with an AI chat
87
91
 
88
- **1. Run the test through `cdg cap`.** Put `--` before your command. The output looks exactly as
89
- it would without `cdg cap`; Codigest just keeps a copy.
92
+ Run `scan` in your project and paste:
90
93
 
91
94
  ```bash
92
- cdg cap -- pytest -q # or npm test, cargo test, go test ./..., make
95
+ cdg scan
96
+ ```
97
+
98
+ ```console
99
+ $ cdg scan
100
+ Copied snapshot to clipboard
101
+ Snapshot 3 files, ~121 tokens
102
+ ```
103
+
104
+ The clipboard now holds the file tree and every file, honoring `.gitignore`:
105
+
106
+ ```xml
107
+ <project_snapshot project="project">
108
+ <project_structure>
109
+ ├── .gitignore
110
+ ├── prices.py
111
+ └── test_prices.py
112
+ </project_structure>
113
+ <source_code>
114
+ <file path=".gitignore">
115
+ .venv/
116
+ __pycache__/
117
+ .pytest_cache/
118
+ </file>
119
+
120
+ <file path="prices.py">
121
+ def apply_discount(price, percent):
122
+ return price * (1 - percent)
123
+ </file>
124
+
125
+ <file path="test_prices.py">
126
+ from prices import apply_discount
127
+
128
+
129
+ def test_ten_percent():
130
+ assert apply_discount(200, 10) == 180
131
+ </file>
132
+ </source_code>
133
+ </project_snapshot>
134
+ ```
135
+
136
+ Large projects ask before copying (above 30k tokens or 100 files). For those, share less, as in
137
+ the next section.
138
+
139
+ ## 2. Share only part of it, or what changed
140
+
141
+ ```bash
142
+ cdg scan src/app.py -r # one file and the local files it imports, recursively
143
+ cdg scan src/billing/ # one folder
144
+ cdg digest # Python signatures and docstrings only, much smaller
145
+ cdg tree # just the file tree
146
+ ```
147
+
148
+ To share what changed while you work, set a baseline first:
149
+
150
+ ```bash
151
+ cdg mark # e.g. before a refactor
152
+ # ... work ...
153
+ cdg diff # text diff since the mark
154
+ cdg semdiff # Python: which functions and classes changed
93
155
  ```
94
156
 
95
- **2. Run `cdg pack`.** It tells you what it picked and why:
157
+ A baseline is a private copy kept in `.codigest/`; your Git history is not touched.
158
+
159
+ ## 3. Hand over a failing command
160
+
161
+ Run the command through `cdg cap`. The output looks exactly as it would without it; Codigest
162
+ keeps a copy. Then ask for a pack:
163
+
164
+ ```bash
165
+ cdg cap -- pytest -q # or npm test, cargo test, go test ./..., make
166
+ cdg pack
167
+ ```
96
168
 
97
169
  ```console
98
170
  $ cdg pack
@@ -107,15 +179,9 @@ Copied pack to clipboard
107
179
  Read it as: the failing command, your uncommitted Git changes, `test_prices.py` because the error
108
180
  points at its line 5, and `prices.py` because you edited it.
109
181
 
110
- **3. Paste into the chat** and say what you want. You can also put the request in the pack:
111
- `cdg pack -m "fix the discount calculation"`.
112
-
113
182
  <details>
114
183
  <summary>What exactly was copied</summary>
115
184
 
116
- One XML block: the command with its output, the diff, and each file with line numbers and the
117
- reason it was included. This is the pack above, unedited apart from the working directory:
118
-
119
185
  ```xml
120
186
  <context_pack project="project">
121
187
  <terminal_history>
@@ -166,87 +232,48 @@ what it is not seeing.
166
232
 
167
233
  </details>
168
234
 
169
- ## Making it smoother
170
-
171
- Once the basic loop works, each of these removes one manual step.
172
-
173
- **Stop typing `cdg cap`.** Hook your shell once and every command is captured automatically:
174
-
175
- ```bash
176
- cdg term install # cdg term uninstall to undo
177
- ```
178
-
179
- **Stop pasting.** Connect your coding agent over MCP and it fetches the pack itself:
180
-
181
- ```bash
182
- claude mcp add --scope user codigest -- cdg mcp # Claude Code
183
- ```
184
-
185
- Other clients (Cursor, VS Code, Claude Desktop): add a stdio server with command `cdg` and args
186
- `["mcp"]`. Details for both are in the [reference](#automatic-capture).
235
+ ### How `pack` decides
187
236
 
188
- ## How `pack` decides
237
+ Plain `cdg pack` fills its token budget (default 30,000) in this order:
189
238
 
190
- When a file you expected is missing, or one you didn't expect is there, this is the order `pack`
191
- fills its token budget (default 30,000):
192
-
193
- 1. Files you name: `cdg pack src/prices.py`.
194
- 2. Files named in the output of the last failed command run in this project in the past hour:
239
+ 1. Files named in the output of the last failed command run in this project in the past hour:
195
240
  `File "x.py", line 7` (Python), `x.py:7` (pytest, ruff, gcc, rustc, eslint), `x.ts(7,3)` (tsc).
196
241
  Once the same command passes again, that failure is no longer used. A file that is only named
197
242
  in the output, not changed by you, comes as an excerpt: ten lines around each place the output
198
243
  points at, marked with a `lines="40-60"` attribute. Short files come whole.
199
- 3. Files you changed: uncommitted and untracked files in Git, or changes since `cdg mark` if you
200
- set a baseline (see [below](#see-what-changed-since-a-point)).
201
- 4. Tests that import a changed file (`test_*.py`, `*_test.py`, `*.test.ts`, `*.spec.js`, ...).
202
- 5. Project files imported by the files from steps 1, 3 and 4: Python imports, and relative imports in
203
- JS/TS (`./x`, `./x.js` for `x.ts`, `./dir` for `dir/index.ts`).
244
+ 2. Files you changed: uncommitted and untracked files in Git, or changes since `cdg mark`.
245
+ 3. Tests that import those files (`test_*.py`, `*_test.py`, `*.test.ts`, `*.spec.js`, ...).
246
+ 4. Project files they import: Python imports, and relative imports in JS/TS (`./x`, `./x.js` for
247
+ `x.ts`, `./dir` for `dir/index.ts`).
204
248
 
205
- The failed command and the diff are always included. `.env`, `*.pem`, `*.key` and SSH keys never
206
- are. Tokens are estimated at four characters each, so the budget is approximate.
249
+ When you name files, you get only those files. `--with` adds automatic sources back:
207
250
 
208
251
  ```bash
209
- cdg pack -b 8000 # smaller budget
210
- cdg pack -s > context.xml # print instead of copying
252
+ cdg pack src/prices.py # just this file
253
+ cdg pack src/prices.py --with tests # this file and its tests
254
+ cdg pack --with changes # only your changes, no failure
255
+ cdg pack --with failure,changes,tests,imports # the same as plain `cdg pack`
211
256
  ```
212
257
 
213
- ## Other things you can hand an LLM
258
+ The failed command and the diff are always included when their source is on. Tokens are estimated
259
+ at four characters each, so the budget is approximate.
214
260
 
215
- `pack` covers the failing-test case. These cover the rest, grouped by what you want to do.
261
+ ### Making it smoother
216
262
 
217
- ### Recall an earlier command
263
+ `cdg term install` hooks your shell so every command is captured without typing `cdg cap`
264
+ (`cdg term uninstall` removes it). `cdg term` shows what was captured; see
265
+ [Terminal capture](#terminal-capture).
218
266
 
219
- Every captured command stays available, not only the last failure:
267
+ ## 4. Let an agent fetch it
220
268
 
221
- ```bash
222
- cdg term # last command and its output
223
- cdg term -n 3 # last 3
224
- cdg term -f # last failed one
225
- cdg term --here -n 3 # last 3 run in this project
226
- ```
227
-
228
- ### See what changed since a point
229
-
230
- Set a baseline before you start, then ask for everything since:
269
+ Connect your coding agent over MCP and it requests context itself instead of asking you to paste:
231
270
 
232
271
  ```bash
233
- cdg mark # e.g. before a refactor
234
- # ... work ...
235
- cdg diff # text diff since the mark
236
- cdg semdiff # Python only: which functions and classes changed
272
+ claude mcp add --scope user codigest -- cdg mcp # Claude Code
237
273
  ```
238
274
 
239
- A baseline is a private copy kept in `.codigest/`; your Git history is not touched. Once you set
240
- one, `pack` also uses it instead of `git diff`.
241
-
242
- ### Give the whole project, or its shape
243
-
244
- ```bash
245
- cdg scan # every file, as one block (asks first above 30k tokens)
246
- cdg scan src/app.py -r # one file plus the local files it imports
247
- cdg digest # Python signatures and docstrings only, much smaller
248
- cdg tree # just the file tree
249
- ```
275
+ Other clients (Cursor, VS Code, Claude Desktop): add a stdio server with command `cdg` and args
276
+ `["mcp"]`. The tools are listed under [MCP tools](#mcp-tools).
250
277
 
251
278
  ## Reference
252
279
 
@@ -255,32 +282,35 @@ cdg tree # just the file tree
255
282
  - [MCP tools](#mcp-tools)
256
283
  - [Configuration](#configuration)
257
284
  - [Privacy and safety](#privacy-and-safety)
285
+ - [Upgrading from 0.8](#upgrading-from-08)
258
286
  - [How it works](#how-it-works)
259
287
  - [Development](#development)
260
288
 
261
289
  ### All commands
262
290
 
263
- Every command that produces context copies it to the clipboard. `-s` / `--stdout` prints it
264
- instead, `--no-copy` skips the clipboard, and `-m` / `--message` adds an instruction.
291
+ `cdg --help` lists them in the same groups.
265
292
 
266
293
  | Command | What it gives you | Writes to your project |
267
294
  | --- | --- | --- |
268
- | `pack` | Last failure, the files it names, your changes | nothing |
295
+ | `scan` | The whole project, or chosen paths, as one block | nothing |
296
+ | `digest` | Signatures and docstrings, no bodies (Python) | nothing |
297
+ | `tree` | Project tree | nothing |
298
+ | `mark` | Sets the baseline | `.codigest/` |
299
+ | `diff` | Text diff since the baseline | nothing |
300
+ | `semdiff` | Function and class level changes since the baseline (Python) | nothing |
269
301
  | `cap` | Runs a command and keeps its output | nothing |
270
302
  | `term` | Recent captured commands with output | nothing |
271
- | `mark` | Sets the baseline | `.codigest/` |
272
- | `diff` | Text diff since the baseline | `.codigest/changes.diff` |
273
- | `semdiff` | Function and class level changes since the baseline (Python) | `.codigest/semdiff.txt` |
274
- | `scan` | The whole project, or chosen paths, as one block | `.codigest/snapshot.txt` |
275
- | `digest` | Signatures and docstrings, no bodies (Python) | `.codigest/digest.txt` |
276
- | `tree` | Project tree | nothing |
303
+ | `pack` | Last failure, the files it names, your changes | nothing |
304
+ | `mcp` | MCP server for agents | nothing |
277
305
  | `status` | What `pack` would use here: last failure, changes, baseline | nothing |
278
- | `init` | Config file and baseline; only needed to change [file filters](#configuration) | `.codigest/`, `.gitignore` |
306
+ | `init` | `.codigest/config.toml` for [file filters](#configuration) | `.codigest/`, `.gitignore` |
279
307
  | `clean` | Deletes `.codigest/` (asks first, `-y` to skip) | removes `.codigest/` |
280
- | `mcp` | MCP server for agents | nothing |
281
308
 
282
- More options: `scan -l` adds line numbers, `scan -a` ignores the config filters, `scan -y` skips
283
- the confirmation (CI). `-r` / `--resolve` on `scan`, `diff`, `semdiff` and `digest` also pulls in
309
+ Shared options: `-s` / `--stdout` also prints the result (status messages go to stderr),
310
+ `--no-copy` skips the clipboard, `-o FILE` also writes it to a file, `-m` / `--message` adds an
311
+ instruction.
312
+ `scan -l` adds line numbers, `scan -a` ignores the config filters, `scan -y` skips the
313
+ confirmation (CI). `-r` / `--resolve` on `scan`, `diff`, `semdiff` and `digest` also pulls in
284
314
  local files imported by the targets. `cdg <command> --help` lists everything.
285
315
 
286
316
  ### Terminal capture
@@ -291,6 +321,10 @@ your machine, so `cap` and `term` work in any directory.
291
321
 
292
322
  ```bash
293
323
  cdg cap "npm run build | tail -20" # quote pipelines
324
+ cdg term # last command and its output
325
+ cdg term -n 3 # last 3
326
+ cdg term -f # last failed one
327
+ cdg term --here -n 3 # last 3 run in this project
294
328
  cdg term -i 2 # only the command from 2 runs ago
295
329
  cdg term path # where captures are stored (override with CODIGEST_HOME)
296
330
  cdg term clear # delete all captures
@@ -325,7 +359,7 @@ Limitations:
325
359
 
326
360
  | Tool | Returns |
327
361
  | --- | --- |
328
- | `pack` | Last failure, the files it names, changes and their imports, cut to a budget (`targets`, `budget`, `message`) |
362
+ | `pack` | Last failure, the files it names, changes and their imports, cut to a budget (`targets`, `with`, `budget`, `message`) |
329
363
  | `terminal_history` | Recent commands with output and exit code (`count`, `failed`, `here`: only this project, default on) |
330
364
  | `scan` | Project snapshot (`targets`, `resolve`, `message`) |
331
365
  | `diff` / `semdiff` | Text / structural changes since the baseline |
@@ -358,26 +392,40 @@ skipped.
358
392
 
359
393
  ### Privacy and safety
360
394
 
361
- - **Secrets in captures.** Known secret shapes (API keys, tokens, `password=...`, private keys,
362
- URL credentials) are masked before a capture is written to disk. Output of credential commands
363
- (`env`, `printenv`, `gh auth token`, `aws configure`, ...) is never stored. This catches common
364
- formats, not every possible secret.
365
- - **Secret files.** `pack` never includes `.env*`, `*.pem`, `*.key`, `*.p12`, `*.pfx` or SSH
366
- private keys, and lists them as omitted instead.
367
- - **Your project.** No command changes your source files. Commands that save output, and the
368
- baseline, live only inside `.codigest/`, which `init` adds to `.gitignore`. `pack` without a
369
- baseline creates nothing at all.
395
+ - **Credential files.** `.env*` (except `.env.example` and similar templates), `*.pem`, `*.key`,
396
+ `*.p12`, `*.pfx`, keystores, `.netrc`, `.pgpass` and SSH private keys are never included by any
397
+ command. `scan` says which it withheld, `pack` lists them as omitted, and their hunks in a diff
398
+ are replaced with a notice.
399
+ - **Tokens in code and diffs.** Private keys, JWTs, vendor tokens (OpenAI, GitHub, AWS, Google,
400
+ Slack, GitLab, npm) and passwords in URLs are masked in everything Codigest outputs. Ordinary
401
+ code such as `token = get_token()` is left alone.
402
+ - **Secrets in captures.** On top of that, terminal output is checked for `password=...` style
403
+ values and `Authorization` headers before it is written to disk, and the output of credential
404
+ commands (`env`, `printenv`, `gh auth token`, `aws configure`, ...) is never stored.
405
+ - These rules catch common formats, not every possible secret.
406
+ - **Your project.** No command changes your source files. Only `mark` and `init` create
407
+ `.codigest/`, which `init` adds to `.gitignore`.
370
408
  - **Where captures live.** `cdg term path` shows the file. On macOS and Linux it is readable only
371
409
  by you. `cdg term clear` deletes it.
372
410
  - **Nothing leaves your machine.** Codigest makes no network requests. Context goes where you
373
411
  paste it, or to the MCP client you connected.
374
412
 
413
+ ### Upgrading from 0.8
414
+
415
+ - `scan`, `diff`, `semdiff` and `digest` no longer save into `.codigest/*.txt`; use `-o FILE`.
416
+ `diff --no-save` and the like are gone.
417
+ - `cdg init` no longer sets a baseline; run `cdg mark`.
418
+ - `cdg pack FILES` packs only those files; add `--with failure,changes,tests,imports` for the
419
+ previous behavior.
420
+ - Outputs no longer start with built-in instructions to the model ("You are an expert..."). Put
421
+ your own with `-m`, or a template in `.codigest/prompts.toml`.
422
+
375
423
  ### How it works
376
424
 
377
425
  - **Baseline.** A Git repository at `.codigest/anchor/.shadow_git`, separate from your project's
378
- repository. The directory is not named `.git` so editors don't mistake it for yours. `mark` and
379
- `init` commit the current state to it; `diff`, `semdiff`, `status` and `pack` compare the
380
- working tree against it.
426
+ repository. The directory is not named `.git` so editors don't mistake it for yours. `mark`
427
+ commits the current state to it; `diff`, `semdiff`, `status` and `pack` compare the working tree
428
+ against it.
381
429
  - **Captures.** One newline-delimited JSON file holds the last 200 commands; each output is capped
382
430
  at 64 KB, keeping the head and tail.
383
431
  - **Output.** File contents are XML-escaped inside `<file>` blocks, written flush-left so no stray