File size: 4,207 Bytes
036a2db
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# DiffContext β€” Day-to-Day Usage

This captures the actual workflow that works, based on real use against a
1000+ symbol production repo (not just toy examples).

## Setup (once per shell session, or add to ~/.bashrc / ~/.zshrc)

```bash
alias dcb='diffcontext blast --changed'
alias dcc='diffcontext compile --changed'
alias dci='diffcontext index'
alias dcs='diffcontext sync'
```

To make these permanent, append the three lines above to `~/.bashrc` (or
`~/.zshrc` if you use zsh), then `source ~/.bashrc`.

## The core workflow

### 1. While actively editing β€” don't rely on git diff detection

Git-diff-based commands (`diffcontext diff`, `diffcontext blast` with no
`--changed`) only see **tracked** changes that are committed or staged.
An edit to an **untracked** (brand new) file is invisible to them β€” not a
bug, that's just what `git diff` means.

For active editing, skip git entirely and name the symbol directly:

```bash
dcb ./path/to/file.py:function_name
```

This works immediately, no commit, no `git add`, no staging.

### 2. Symbol IDs β€” exact format

```
./relative/path.py:function_name
./relative/path.py:ClassName.method_name
```

Rules:
- Path is relative to the repo root you indexed, always starts with `./`
- **No parentheses, no arguments, no type hints** β€” `update_run`, never
  `update_run(run_id: int, **kwargs)`. Bash will choke on unquoted `()`
  with a `syntax error near unexpected token` β€” that's bash, not
  diffcontext, complaining.
- Find real names fast:
  ```bash
  grep -n "^def \|^    def " path/to/file.py
  ```

### 3. Before trusting "no callers found" β€” spot-check with grep

This caught 3 real bugs during testing. Make it a habit, not a one-off:

```bash
grep -rn "function_name(" --include="*.py" .
```

If grep finds callers diffcontext's blast radius missed, that's a real
gap worth knowing about (and worth reporting) β€” don't assume the blast
radius is complete just because it ran without error.

### 4. Getting LLM-ready context

```bash
dcc ./path/to/file.py:function_name --max-tokens 4000
```

Paste the output into Claude/ChatGPT **with a specific question**, not
just the raw context:

- Bad: "review this"
- Good: "I'm about to add a new field to `update_run` β€” given these 5
  callers, what do I need to check?"
- Good: "Is the dynamic SQL construction in `update_run` safe given how
  `kwargs` is validated against `_UPDATABLE_RUN_COLUMNS`?"

### 5. Tuning context size

- `--depth N` (default 2-3): how many hops of callers/callees to pull in.
  Use `--depth 1` for a tight, single-function check. Use `--depth 4+`
  for "how does this fit into the bigger picture."
- `--max-tokens N`: hard cap. Lower it to force tighter selection (only
  the highest-scored symbols survive); raise it if you have a
  large-context model and want more surrounding code.

### 6. Checking what changed (only works for committed/staged files)

```bash
diffcontext diff                    # working tree vs HEAD~1, tracked files only
diffcontext diff --committed-only   # two commits only, ignores uncommitted edits
```

If a file shows as broken (`Skipping X due to SyntaxError`), diffcontext
will still report a best-effort diff using the prior committed version β€”
look for the `⚠ N file(s) failed to parse` block in the output.

## Known limitations (don't trust blast radius blindly here)

- **Dynamic dispatch / `getattr()`-based routing**: common in CLI
  argument dispatch and plugin systems β€” invisible to static analysis.
- **Cross-file changes related by theme, not by function calls**: e.g.
  "remove a dependency" touching 3 unrelated-by-call-graph files for one
  conceptual reason. Blast radius won't connect these.
- **User-defined higher-order functions**: only the common stdlib cases
  (`map`, `filter`, `sorted`/`max`/`min` with `key=`) are recognized.
  A custom `def apply_twice(fn, value)` is not tracked.

When in doubt: grep first, trust second.

## Cloud sync (CtxSync)

Push your blast radius to the cloud in one command:

```bash
diffcontext sync
```

Reads credentials from `~/.ctxsync` (or `--url`/`--key` flags, or env vars).
The system prompt URL can be pasted into any AI tool for live context awareness.