causetrace 0.1.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.
- causetrace-0.1.0/LICENSE +21 -0
- causetrace-0.1.0/PKG-INFO +274 -0
- causetrace-0.1.0/README.md +249 -0
- causetrace-0.1.0/causetrace/__init__.py +9 -0
- causetrace-0.1.0/causetrace/__main__.py +3 -0
- causetrace-0.1.0/causetrace/causality.py +169 -0
- causetrace-0.1.0/causetrace/cli.py +245 -0
- causetrace-0.1.0/causetrace/core.py +556 -0
- causetrace-0.1.0/causetrace/hooks/__init__.py +0 -0
- causetrace-0.1.0/causetrace/hooks/aider_bridge.py +205 -0
- causetrace-0.1.0/causetrace/hooks/claude_code.py +121 -0
- causetrace-0.1.0/causetrace/hooks/codex_tailer.py +238 -0
- causetrace-0.1.0/causetrace/hooks/continue_tailer.py +219 -0
- causetrace-0.1.0/causetrace/hooks/copilot_tailer.py +240 -0
- causetrace-0.1.0/causetrace/hooks/opencode_tailer.py +169 -0
- causetrace-0.1.0/causetrace.egg-info/PKG-INFO +274 -0
- causetrace-0.1.0/causetrace.egg-info/SOURCES.txt +21 -0
- causetrace-0.1.0/causetrace.egg-info/dependency_links.txt +1 -0
- causetrace-0.1.0/causetrace.egg-info/entry_points.txt +2 -0
- causetrace-0.1.0/causetrace.egg-info/top_level.txt +1 -0
- causetrace-0.1.0/pyproject.toml +48 -0
- causetrace-0.1.0/setup.cfg +4 -0
- causetrace-0.1.0/tests/test_invariants.py +214 -0
causetrace-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 milkoor
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: causetrace
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Causal traceability SDK for AI agent runtimes — observe, replay, understand agent behavior
|
|
5
|
+
Author: milkoor
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/milkoor/causetrace
|
|
8
|
+
Project-URL: Repository, https://github.com/milkoor/causetrace
|
|
9
|
+
Project-URL: BugTracker, https://github.com/milkoor/causetrace/issues
|
|
10
|
+
Keywords: agent,trace,observability,causality,llm,claude,opencode,runtime,monitoring,debugging
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Classifier: Topic :: System :: Monitoring
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
|
|
26
|
+
# causetrace
|
|
27
|
+
|
|
28
|
+
> [中文](README.zh-CN.md) • [CI](https://github.com/milkoor/causetrace/actions) • [PyPI](https://pypi.org/project/causetrace/)
|
|
29
|
+
|
|
30
|
+
**causetrace** captures tool calls from coding agents (Claude Code, OpenCode, Aider, Continue.dev, Codex CLI, GitHub Copilot) and links them into causal trees and DAGs — **not flat timelines**. Every event records *why* it happened, enabling replay, root-cause analysis, and behavior explanation.
|
|
31
|
+
|
|
32
|
+
> **Data sources**: Claude Code (hooks), OpenCode / Continue.dev / Codex CLI / GitHub Copilot (log tailing), Aider (process wrapper)
|
|
33
|
+
> **Storage**: `~/.causetrace/data/<session_id>.jsonl` — append-only JSONL, zero external dependencies
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Showcase
|
|
38
|
+
|
|
39
|
+
The same session viewed four ways — flat vs. causal.
|
|
40
|
+
|
|
41
|
+
### Timeline (flat)
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
$ causetrace timeline ses_10d2f16e
|
|
45
|
+
[03:13:37] Read(file_path=src/main.py)
|
|
46
|
+
[03:13:37] Grep(pattern=FIXME)
|
|
47
|
+
[03:13:37] Read(file_path=src/utils.py)
|
|
48
|
+
[03:13:37] Read(file_path=src/utils.py)
|
|
49
|
+
[03:13:38] Edit(file_path=src/utils.py)
|
|
50
|
+
[03:13:38] Bash(command=python -m pytest tests/ -x)
|
|
51
|
+
[03:13:38] Grep(pattern=counter)
|
|
52
|
+
[03:13:38] Edit(file_path=docs/api.md)
|
|
53
|
+
[03:13:38] Bash(command=python -m pytest tests/)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Chronological order, but no insight into *why* each event happened.
|
|
57
|
+
|
|
58
|
+
### Causal Tree
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
$ causetrace tree ses_10d2f16e
|
|
62
|
+
[03:13:37] Read(file_path=src/main.py)
|
|
63
|
+
└─ [03:13:37] Grep(pattern=FIXME)
|
|
64
|
+
└─ [03:13:37] Read(file_path=src/utils.py)
|
|
65
|
+
[03:13:37] Read(file_path=src/utils.py) [caused by: need_context]
|
|
66
|
+
└─ [03:13:38] Edit(file_path=src/utils.py)
|
|
67
|
+
└─ [03:13:38] Bash(command=python -m pytest tests/ -x)
|
|
68
|
+
[03:13:38] Grep(pattern=counter)
|
|
69
|
+
└─ [03:13:38] Edit(file_path=docs/api.md)
|
|
70
|
+
└─ [03:13:38] Bash(command=python -m pytest tests/)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Parent→child chains reveal the causal structure: each tool call is a direct response to its parent.
|
|
74
|
+
|
|
75
|
+
### Why (causal chain trace)
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
$ causetrace why ses_10d2f16e <event_id>
|
|
79
|
+
[03:13:38] Grep(pattern=counter) ──→
|
|
80
|
+
[03:13:38] Edit(file_path=docs/api.md) ──→
|
|
81
|
+
[03:13:38] Bash(command=python -m pytest tests/) ◀── TARGET
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Trace *why a specific event happened* — follow the causal chain backward from any event to its root.
|
|
85
|
+
|
|
86
|
+
### Multi-parent DAG
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
$ causetrace graph ses_3e23bcc8
|
|
90
|
+
[02:42:40] Bash(command=python -m pytest tests/) ← Edit(file_path=docs/api.md)
|
|
91
|
+
[02:42:41] Read(file_path=src/main.py)
|
|
92
|
+
[02:42:41] Grep(pattern=FIXME) ← Read(file_path=src/main.py)
|
|
93
|
+
[02:42:41] Read(file_path=src/utils.py) ← Grep(pattern=FIXME)
|
|
94
|
+
[02:42:41] Read(file_path=src/utils.py)
|
|
95
|
+
[02:42:41] Edit(file_path=src/utils.py) ← Read(file_path=src/utils.py)
|
|
96
|
+
[02:42:41] Bash(command=python -m pytest tests/ -x) ← Edit(file_path=src/utils.py)
|
|
97
|
+
[02:42:42] Grep(pattern=counter)
|
|
98
|
+
[02:42:42] Edit(file_path=docs/api.md) ← Grep(pattern=counter)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Fan-in DAGs visualize convergent causation — one tool consuming multiple prior results. Support for multi-parent causal links via comma-separated `parent_event_id`.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Supported Agents
|
|
106
|
+
|
|
107
|
+
| Agent | Method | How it works |
|
|
108
|
+
|-------|--------|-------------|
|
|
109
|
+
| **Claude Code** | Hook bridge | PreToolUse / PostToolUse hooks via `~/.claude/settings.json` |
|
|
110
|
+
| **OpenCode** | Log tailing | Parses `~/.local/share/opencode/log/*.log` for tool.registry entries |
|
|
111
|
+
| **Aider** | Process wrapper | Runs `aider` as subprocess, parses stdout for tool calls |
|
|
112
|
+
| **Continue.dev** | Log tailing | Parses `~/.continue/logs/core.log` for JSON tool call entries |
|
|
113
|
+
| **Codex CLI** | Log tailing | Parses `~/.codex/sessions/.../rollout-*.jsonl` for actions/observations |
|
|
114
|
+
| **GitHub Copilot** | Log tailing | Parses `~/.config/Code/logs/` extension host logs for Copilot tool calls |
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Claude Code — automatic via hooks
|
|
118
|
+
causetrace tale <session_id>
|
|
119
|
+
|
|
120
|
+
# Log-based agents — scan and save
|
|
121
|
+
causetrace opencode --save
|
|
122
|
+
causetrace continue --save
|
|
123
|
+
causetrace codex --save
|
|
124
|
+
causetrace copilot --save
|
|
125
|
+
|
|
126
|
+
# Aider — run with tracing
|
|
127
|
+
causetrace aider -- --model gpt-4 --yes "fix the bug"
|
|
128
|
+
```
|
|
129
|
+
Usage notes:
|
|
130
|
+
|
|
131
|
+
- **Claude Code** — most precise, captures full causality via Pre/Post hooks
|
|
132
|
+
- **Aider** — `causetrace aider --save -- [aider args]` wraps the CLI; best-effort parsing from output
|
|
133
|
+
- **Continue.dev**, **Codex CLI**, **Copilot** — post-hoc log scanning; causality inferred from temporal proximity via `infer_relations()`
|
|
134
|
+
- All log-based agents infer causality heuristically — timestamps between events determine parent→child chains
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Quick Start
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
pip install causetrace
|
|
142
|
+
|
|
143
|
+
# Run a demo with sample data
|
|
144
|
+
causetrace timeline ses_10d2f16e
|
|
145
|
+
causetrace tree ses_10d2f16e
|
|
146
|
+
causetrace replay ses_10d2f16e --summary
|
|
147
|
+
causetrace why ses_10d2f16e <event_id>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Hook up Claude Code
|
|
151
|
+
|
|
152
|
+
Add to `~/.claude/settings.json` to start recording every Claude Code session automatically.
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"hooks": {
|
|
157
|
+
"PreToolUse": [{ "matcher": "*", "hooks": [{
|
|
158
|
+
"type": "command",
|
|
159
|
+
"command": "python3 /path/to/causetrace/hooks/claude_code.py",
|
|
160
|
+
"timeout": 5
|
|
161
|
+
}]}],
|
|
162
|
+
"PostToolUse": [{ "matcher": "*", "hooks": [{
|
|
163
|
+
"type": "command",
|
|
164
|
+
"command": "python3 /path/to/causetrace/hooks/claude_code.py",
|
|
165
|
+
"timeout": 5
|
|
166
|
+
}]}]
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Scan OpenCode logs
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
causetrace opencode --save
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Parses OpenCode log files, infers causal relations from temporal proximity, and saves as a causetrace session.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Data Model
|
|
182
|
+
|
|
183
|
+
Every event is a `ToolEvent`. The four causal fields (`parent_event_id`, `session_id`, `event_type`, `caused_by`) distinguish causetrace from flat logging systems.
|
|
184
|
+
|
|
185
|
+
| Field | Description |
|
|
186
|
+
|-------|-------------|
|
|
187
|
+
| `event_id` | UUID |
|
|
188
|
+
| `parent_event_id` | Causal parent (comma-separated for fan-in) |
|
|
189
|
+
| `session_id` | Owning session |
|
|
190
|
+
| `tool_name` | e.g. `Bash`, `Read`, `Write` |
|
|
191
|
+
| `tool_input` | Serialized input arguments |
|
|
192
|
+
| `tool_output` | Serialized output |
|
|
193
|
+
| `timestamp` | ISO 8601 |
|
|
194
|
+
| `duration_ms` | Execution time |
|
|
195
|
+
| `event_type` | `tool_call` / `reasoning` / `context_update` / `user_input` |
|
|
196
|
+
| `caused_by` | `user` / `reasoning` / event_id / semantic tag |
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## CLI Reference
|
|
201
|
+
|
|
202
|
+
| Command | Description |
|
|
203
|
+
|---------|-------------|
|
|
204
|
+
| `causetrace timeline <id>` | Flat chronological view |
|
|
205
|
+
| `causetrace tree <id>` | Causal parent→child tree |
|
|
206
|
+
| `causetrace graph <id>` | Multi-parent DAG (fan-in) |
|
|
207
|
+
| `causetrace sessions` | List recorded sessions |
|
|
208
|
+
| `causetrace export <id>` | Export as JSON |
|
|
209
|
+
| `causetrace replay <id>` | Replay with provenance |
|
|
210
|
+
| `causetrace why <id> <eid>` | Trace causal chain from event |
|
|
211
|
+
| `causetrace opencode [--save]` | Scan OpenCode logs |
|
|
212
|
+
| `causetrace aider [--save] -- [args]` | Run aider with tracing |
|
|
213
|
+
| `causetrace continue [--save]` | Scan Continue.dev logs |
|
|
214
|
+
| `causetrace codex [--save]` | Scan OpenAI Codex CLI logs |
|
|
215
|
+
| `causetrace copilot [--save]` | Scan GitHub Copilot agent logs |
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Architecture
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
223
|
+
│ Claude Code │ │ OpenCode │ │ Aider │ │ Continue.dev │ │ Codex CLI │ │ Copilot │
|
|
224
|
+
│ (hooks) │ │ (log tail) │ │ (subprocess) │ │ (log tail) │ │ (log tail) │ │ (log tail) │
|
|
225
|
+
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘
|
|
226
|
+
│ │ │ │ │ │
|
|
227
|
+
▼ ▼ ▼ ▼ ▼ ▼
|
|
228
|
+
┌────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
229
|
+
│ TraceRecorder │
|
|
230
|
+
│ (causal linking, storage) │
|
|
231
|
+
└────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
232
|
+
│
|
|
233
|
+
▼
|
|
234
|
+
┌────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
235
|
+
│ JSONStore │
|
|
236
|
+
│ (append-only JSONL, no DB) │
|
|
237
|
+
└────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
238
|
+
│
|
|
239
|
+
▼
|
|
240
|
+
┌────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
241
|
+
│ Tree / DAG Builders │
|
|
242
|
+
│ Renderers / ReplayEngine │
|
|
243
|
+
└────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
| Module | Responsibility |
|
|
247
|
+
|--------|---------------|
|
|
248
|
+
| `causetrace/core.py` | Data model, `TraceRecorder`, `JSONStore`, tree/DAG builders, renderers, `ReplayEngine` |
|
|
249
|
+
| `causetrace/causality.py` | Temporal causal inference for unstructured logs |
|
|
250
|
+
| `causetrace/cli.py` | argparse CLI dispatching to 12 subcommands |
|
|
251
|
+
| `causetrace/hooks/` | Agent-specific bridges and tailers |
|
|
252
|
+
| `causetrace/hooks/claude_code.py` | Claude Code hook bridge |
|
|
253
|
+
| `causetrace/hooks/opencode_tailer.py` | OpenCode log tailer |
|
|
254
|
+
| `causetrace/hooks/aider_bridge.py` | Aider subprocess wrapper |
|
|
255
|
+
| `causetrace/hooks/continue_tailer.py` | Continue.dev log tailer |
|
|
256
|
+
| `causetrace/hooks/codex_tailer.py` | Codex CLI log tailer |
|
|
257
|
+
| `causetrace/hooks/copilot_tailer.py` | GitHub Copilot log tailer |
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Development
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
git clone https://github.com/milkoor/causetrace.git
|
|
265
|
+
cd causetrace
|
|
266
|
+
pip install -e .
|
|
267
|
+
python -m pytest tests/ -v
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## License
|
|
273
|
+
|
|
274
|
+
MIT
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# causetrace
|
|
2
|
+
|
|
3
|
+
> [中文](README.zh-CN.md) • [CI](https://github.com/milkoor/causetrace/actions) • [PyPI](https://pypi.org/project/causetrace/)
|
|
4
|
+
|
|
5
|
+
**causetrace** captures tool calls from coding agents (Claude Code, OpenCode, Aider, Continue.dev, Codex CLI, GitHub Copilot) and links them into causal trees and DAGs — **not flat timelines**. Every event records *why* it happened, enabling replay, root-cause analysis, and behavior explanation.
|
|
6
|
+
|
|
7
|
+
> **Data sources**: Claude Code (hooks), OpenCode / Continue.dev / Codex CLI / GitHub Copilot (log tailing), Aider (process wrapper)
|
|
8
|
+
> **Storage**: `~/.causetrace/data/<session_id>.jsonl` — append-only JSONL, zero external dependencies
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Showcase
|
|
13
|
+
|
|
14
|
+
The same session viewed four ways — flat vs. causal.
|
|
15
|
+
|
|
16
|
+
### Timeline (flat)
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
$ causetrace timeline ses_10d2f16e
|
|
20
|
+
[03:13:37] Read(file_path=src/main.py)
|
|
21
|
+
[03:13:37] Grep(pattern=FIXME)
|
|
22
|
+
[03:13:37] Read(file_path=src/utils.py)
|
|
23
|
+
[03:13:37] Read(file_path=src/utils.py)
|
|
24
|
+
[03:13:38] Edit(file_path=src/utils.py)
|
|
25
|
+
[03:13:38] Bash(command=python -m pytest tests/ -x)
|
|
26
|
+
[03:13:38] Grep(pattern=counter)
|
|
27
|
+
[03:13:38] Edit(file_path=docs/api.md)
|
|
28
|
+
[03:13:38] Bash(command=python -m pytest tests/)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Chronological order, but no insight into *why* each event happened.
|
|
32
|
+
|
|
33
|
+
### Causal Tree
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
$ causetrace tree ses_10d2f16e
|
|
37
|
+
[03:13:37] Read(file_path=src/main.py)
|
|
38
|
+
└─ [03:13:37] Grep(pattern=FIXME)
|
|
39
|
+
└─ [03:13:37] Read(file_path=src/utils.py)
|
|
40
|
+
[03:13:37] Read(file_path=src/utils.py) [caused by: need_context]
|
|
41
|
+
└─ [03:13:38] Edit(file_path=src/utils.py)
|
|
42
|
+
└─ [03:13:38] Bash(command=python -m pytest tests/ -x)
|
|
43
|
+
[03:13:38] Grep(pattern=counter)
|
|
44
|
+
└─ [03:13:38] Edit(file_path=docs/api.md)
|
|
45
|
+
└─ [03:13:38] Bash(command=python -m pytest tests/)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Parent→child chains reveal the causal structure: each tool call is a direct response to its parent.
|
|
49
|
+
|
|
50
|
+
### Why (causal chain trace)
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
$ causetrace why ses_10d2f16e <event_id>
|
|
54
|
+
[03:13:38] Grep(pattern=counter) ──→
|
|
55
|
+
[03:13:38] Edit(file_path=docs/api.md) ──→
|
|
56
|
+
[03:13:38] Bash(command=python -m pytest tests/) ◀── TARGET
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Trace *why a specific event happened* — follow the causal chain backward from any event to its root.
|
|
60
|
+
|
|
61
|
+
### Multi-parent DAG
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
$ causetrace graph ses_3e23bcc8
|
|
65
|
+
[02:42:40] Bash(command=python -m pytest tests/) ← Edit(file_path=docs/api.md)
|
|
66
|
+
[02:42:41] Read(file_path=src/main.py)
|
|
67
|
+
[02:42:41] Grep(pattern=FIXME) ← Read(file_path=src/main.py)
|
|
68
|
+
[02:42:41] Read(file_path=src/utils.py) ← Grep(pattern=FIXME)
|
|
69
|
+
[02:42:41] Read(file_path=src/utils.py)
|
|
70
|
+
[02:42:41] Edit(file_path=src/utils.py) ← Read(file_path=src/utils.py)
|
|
71
|
+
[02:42:41] Bash(command=python -m pytest tests/ -x) ← Edit(file_path=src/utils.py)
|
|
72
|
+
[02:42:42] Grep(pattern=counter)
|
|
73
|
+
[02:42:42] Edit(file_path=docs/api.md) ← Grep(pattern=counter)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Fan-in DAGs visualize convergent causation — one tool consuming multiple prior results. Support for multi-parent causal links via comma-separated `parent_event_id`.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Supported Agents
|
|
81
|
+
|
|
82
|
+
| Agent | Method | How it works |
|
|
83
|
+
|-------|--------|-------------|
|
|
84
|
+
| **Claude Code** | Hook bridge | PreToolUse / PostToolUse hooks via `~/.claude/settings.json` |
|
|
85
|
+
| **OpenCode** | Log tailing | Parses `~/.local/share/opencode/log/*.log` for tool.registry entries |
|
|
86
|
+
| **Aider** | Process wrapper | Runs `aider` as subprocess, parses stdout for tool calls |
|
|
87
|
+
| **Continue.dev** | Log tailing | Parses `~/.continue/logs/core.log` for JSON tool call entries |
|
|
88
|
+
| **Codex CLI** | Log tailing | Parses `~/.codex/sessions/.../rollout-*.jsonl` for actions/observations |
|
|
89
|
+
| **GitHub Copilot** | Log tailing | Parses `~/.config/Code/logs/` extension host logs for Copilot tool calls |
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Claude Code — automatic via hooks
|
|
93
|
+
causetrace tale <session_id>
|
|
94
|
+
|
|
95
|
+
# Log-based agents — scan and save
|
|
96
|
+
causetrace opencode --save
|
|
97
|
+
causetrace continue --save
|
|
98
|
+
causetrace codex --save
|
|
99
|
+
causetrace copilot --save
|
|
100
|
+
|
|
101
|
+
# Aider — run with tracing
|
|
102
|
+
causetrace aider -- --model gpt-4 --yes "fix the bug"
|
|
103
|
+
```
|
|
104
|
+
Usage notes:
|
|
105
|
+
|
|
106
|
+
- **Claude Code** — most precise, captures full causality via Pre/Post hooks
|
|
107
|
+
- **Aider** — `causetrace aider --save -- [aider args]` wraps the CLI; best-effort parsing from output
|
|
108
|
+
- **Continue.dev**, **Codex CLI**, **Copilot** — post-hoc log scanning; causality inferred from temporal proximity via `infer_relations()`
|
|
109
|
+
- All log-based agents infer causality heuristically — timestamps between events determine parent→child chains
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Quick Start
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
pip install causetrace
|
|
117
|
+
|
|
118
|
+
# Run a demo with sample data
|
|
119
|
+
causetrace timeline ses_10d2f16e
|
|
120
|
+
causetrace tree ses_10d2f16e
|
|
121
|
+
causetrace replay ses_10d2f16e --summary
|
|
122
|
+
causetrace why ses_10d2f16e <event_id>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Hook up Claude Code
|
|
126
|
+
|
|
127
|
+
Add to `~/.claude/settings.json` to start recording every Claude Code session automatically.
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"hooks": {
|
|
132
|
+
"PreToolUse": [{ "matcher": "*", "hooks": [{
|
|
133
|
+
"type": "command",
|
|
134
|
+
"command": "python3 /path/to/causetrace/hooks/claude_code.py",
|
|
135
|
+
"timeout": 5
|
|
136
|
+
}]}],
|
|
137
|
+
"PostToolUse": [{ "matcher": "*", "hooks": [{
|
|
138
|
+
"type": "command",
|
|
139
|
+
"command": "python3 /path/to/causetrace/hooks/claude_code.py",
|
|
140
|
+
"timeout": 5
|
|
141
|
+
}]}]
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Scan OpenCode logs
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
causetrace opencode --save
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Parses OpenCode log files, infers causal relations from temporal proximity, and saves as a causetrace session.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Data Model
|
|
157
|
+
|
|
158
|
+
Every event is a `ToolEvent`. The four causal fields (`parent_event_id`, `session_id`, `event_type`, `caused_by`) distinguish causetrace from flat logging systems.
|
|
159
|
+
|
|
160
|
+
| Field | Description |
|
|
161
|
+
|-------|-------------|
|
|
162
|
+
| `event_id` | UUID |
|
|
163
|
+
| `parent_event_id` | Causal parent (comma-separated for fan-in) |
|
|
164
|
+
| `session_id` | Owning session |
|
|
165
|
+
| `tool_name` | e.g. `Bash`, `Read`, `Write` |
|
|
166
|
+
| `tool_input` | Serialized input arguments |
|
|
167
|
+
| `tool_output` | Serialized output |
|
|
168
|
+
| `timestamp` | ISO 8601 |
|
|
169
|
+
| `duration_ms` | Execution time |
|
|
170
|
+
| `event_type` | `tool_call` / `reasoning` / `context_update` / `user_input` |
|
|
171
|
+
| `caused_by` | `user` / `reasoning` / event_id / semantic tag |
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## CLI Reference
|
|
176
|
+
|
|
177
|
+
| Command | Description |
|
|
178
|
+
|---------|-------------|
|
|
179
|
+
| `causetrace timeline <id>` | Flat chronological view |
|
|
180
|
+
| `causetrace tree <id>` | Causal parent→child tree |
|
|
181
|
+
| `causetrace graph <id>` | Multi-parent DAG (fan-in) |
|
|
182
|
+
| `causetrace sessions` | List recorded sessions |
|
|
183
|
+
| `causetrace export <id>` | Export as JSON |
|
|
184
|
+
| `causetrace replay <id>` | Replay with provenance |
|
|
185
|
+
| `causetrace why <id> <eid>` | Trace causal chain from event |
|
|
186
|
+
| `causetrace opencode [--save]` | Scan OpenCode logs |
|
|
187
|
+
| `causetrace aider [--save] -- [args]` | Run aider with tracing |
|
|
188
|
+
| `causetrace continue [--save]` | Scan Continue.dev logs |
|
|
189
|
+
| `causetrace codex [--save]` | Scan OpenAI Codex CLI logs |
|
|
190
|
+
| `causetrace copilot [--save]` | Scan GitHub Copilot agent logs |
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Architecture
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
198
|
+
│ Claude Code │ │ OpenCode │ │ Aider │ │ Continue.dev │ │ Codex CLI │ │ Copilot │
|
|
199
|
+
│ (hooks) │ │ (log tail) │ │ (subprocess) │ │ (log tail) │ │ (log tail) │ │ (log tail) │
|
|
200
|
+
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘
|
|
201
|
+
│ │ │ │ │ │
|
|
202
|
+
▼ ▼ ▼ ▼ ▼ ▼
|
|
203
|
+
┌────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
204
|
+
│ TraceRecorder │
|
|
205
|
+
│ (causal linking, storage) │
|
|
206
|
+
└────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
207
|
+
│
|
|
208
|
+
▼
|
|
209
|
+
┌────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
210
|
+
│ JSONStore │
|
|
211
|
+
│ (append-only JSONL, no DB) │
|
|
212
|
+
└────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
213
|
+
│
|
|
214
|
+
▼
|
|
215
|
+
┌────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
216
|
+
│ Tree / DAG Builders │
|
|
217
|
+
│ Renderers / ReplayEngine │
|
|
218
|
+
└────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
| Module | Responsibility |
|
|
222
|
+
|--------|---------------|
|
|
223
|
+
| `causetrace/core.py` | Data model, `TraceRecorder`, `JSONStore`, tree/DAG builders, renderers, `ReplayEngine` |
|
|
224
|
+
| `causetrace/causality.py` | Temporal causal inference for unstructured logs |
|
|
225
|
+
| `causetrace/cli.py` | argparse CLI dispatching to 12 subcommands |
|
|
226
|
+
| `causetrace/hooks/` | Agent-specific bridges and tailers |
|
|
227
|
+
| `causetrace/hooks/claude_code.py` | Claude Code hook bridge |
|
|
228
|
+
| `causetrace/hooks/opencode_tailer.py` | OpenCode log tailer |
|
|
229
|
+
| `causetrace/hooks/aider_bridge.py` | Aider subprocess wrapper |
|
|
230
|
+
| `causetrace/hooks/continue_tailer.py` | Continue.dev log tailer |
|
|
231
|
+
| `causetrace/hooks/codex_tailer.py` | Codex CLI log tailer |
|
|
232
|
+
| `causetrace/hooks/copilot_tailer.py` | GitHub Copilot log tailer |
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Development
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
git clone https://github.com/milkoor/causetrace.git
|
|
240
|
+
cd causetrace
|
|
241
|
+
pip install -e .
|
|
242
|
+
python -m pytest tests/ -v
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## License
|
|
248
|
+
|
|
249
|
+
MIT
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from .core import ToolEvent, TraceRecorder, JSONStore, TimelineRenderer, ReplayEngine, build_tree, trace_causal_chain
|
|
2
|
+
from .causality import infer_relations, build_causal_graph
|
|
3
|
+
from .cli import cli
|
|
4
|
+
|
|
5
|
+
__version__ = "0.1.0"
|
|
6
|
+
__all__ = [
|
|
7
|
+
"ToolEvent", "TraceRecorder", "JSONStore", "TimelineRenderer",
|
|
8
|
+
"ReplayEngine", "build_tree", "infer_relations", "build_causal_graph", "cli",
|
|
9
|
+
]
|