transcripto 0.1.5__tar.gz → 0.2.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.
@@ -0,0 +1,222 @@
1
+ Metadata-Version: 2.4
2
+ Name: transcripto
3
+ Version: 0.2.0
4
+ Summary: Instant replay for coding agents. Inspect requests, tool calls, and recorded results across Claude Code, Codex, and Cursor. Local, stdlib-only.
5
+ Author: Oscar Morke
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Morkeeth/transcripto
8
+ Project-URL: Source, https://github.com/Morkeeth/transcripto
9
+ Keywords: claude-code,coding-agents,transcripts,local-first,analytics
10
+ Classifier: Environment :: Console
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Topic :: Utilities
14
+ Requires-Python: >=3.9
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Dynamic: license-file
18
+
19
+ # Transcripto
20
+
21
+ **Your agent said “done.” Replay what happened.**
22
+
23
+ Transcripto reads the transcripts already on your machine and puts your request,
24
+ the tool calls, and their recorded results in order. Failed edits stay failed.
25
+ Missing results stay unknown. A confident closing message changes neither.
26
+
27
+ Claude Code · Codex · Cursor. Local. No accounts. No runtime dependencies.
28
+
29
+ ```sh
30
+ uvx --from transcripto==0.2.0 transcripto
31
+
32
+ # Try a synthetic session without opening your own history:
33
+ uvx --from transcripto==0.2.0 transcripto replay --demo
34
+ ```
35
+
36
+ Or install with `python3 -m pip install transcripto==0.2.0`, then run
37
+ `transcripto`. Requires Python 3.9 or newer.
38
+
39
+ Version **0.2.0** adds replay. The default command opens your latest human
40
+ session. Pinning the version makes the reviewed build and the build you run
41
+ the same object.
42
+
43
+ ## The replay
44
+
45
+ This is output from `replay --demo`. **All prompts and results in this example
46
+ are invented.** The demo goes through the same parser as a real transcript.
47
+
48
+ ```text
49
+ THE COMEBACK · claude · request 1
50
+ You asked: "Fix the login redirect and run its tests."
51
+
52
+ 1 FAIL edit src/login.py
53
+ Tool error: Error: text not found [call L2 → result L3]
54
+ 2 OK edit src/login.py
55
+ Tool reported success. [call L4 → result L5]
56
+ 3 FAIL check pytest tests/test_login.py
57
+ Tool error: Process exited with code 1 [call L6 → result L7]
58
+ 4 OK edit src/login.py
59
+ Tool reported success. [call L8 → result L9]
60
+ 5 OK check pytest tests/test_login.py
61
+ Tool reported success. [call L10 → result L11]
62
+
63
+ Agent said: "The redirect is fixed and the tests pass."
64
+
65
+ Recorded: 3 succeeded · 2 failed · 0 unknown
66
+ Status describes a tool result, not task correctness. Missing results stay unknown.
67
+ ```
68
+
69
+ The headings have rules. **The comeback** means a recorded failure was followed
70
+ by success for the same operation and target, without a later failed or unknown
71
+ attempt on that target. **The snag** means a failure is
72
+ present. **The missing receipt** means a result is unknown. **The answer** means
73
+ there were no recorded tool calls; an explanation may have been the whole task.
74
+ These are descriptions of the sequence, not grades for you or your agent.
75
+
76
+ On your own history, each replay names its source file and line numbers, plus a
77
+ command that reopens that exact request. Long sequences open around the first
78
+ failure or change and tell you what was omitted. `--all` shows the full sequence.
79
+
80
+ ```sh
81
+ transcripto # latest session you submitted a request in
82
+ transcripto replay --failures # most recent request with a recorded failure
83
+ transcripto replay "login redirect" # find requests containing these words
84
+ transcripto replay path/to/session.jsonl # inspect one transcript
85
+ transcripto replay --session 3f9c1a2b # explicitly select a session prefix
86
+ transcripto replay path/to/session.jsonl --episode 3 --all
87
+ transcripto replay latest --json # structured events, evidence, source lines
88
+ transcripto replay latest --share # counts + caveat; no prompts or paths
89
+ ```
90
+
91
+ `--share` is intentionally small. Full replay output and JSON contain your own
92
+ words and local paths. The tool does not upload either.
93
+
94
+ ## Find the thing you remember
95
+
96
+ Search automatically refreshes a local index. No setup command is required.
97
+
98
+ ```sh
99
+ transcripto ask "retry" # your submitted words
100
+ transcripto search "retry" # prompts, replies, and tool text
101
+ transcripto find parser.py # recorded file operations and attempts
102
+ transcripto trace "retry" # an alias into result-aware replay
103
+ transcripto sessions # sessions with submitted prompts
104
+ transcripto stats # activity counts
105
+ ```
106
+
107
+ A failed or unconfirmed file change is labelled an **attempt**, never `WROTE`.
108
+ Queries with `--harness` or `--root` are scoped to that selection even if the
109
+ index already contains another corpus. `index` and `watch` remain available for
110
+ explicit refresh and background polling.
111
+
112
+ ## What each harness supports
113
+
114
+ | Feature | Claude Code | Codex | Cursor |
115
+ |---|---|---|---|
116
+ | Replay, search, ask, find, trace, sessions, stats | Yes | Yes | Yes |
117
+ | Tool attempts | Native tool calls | Direct calls and supported static wrappers | `StrReplace`, `Shell`, `Write`, and other calls |
118
+ | Execution status | Matched results | Matched results; ambiguous wrappers stay unknown | Unknown when the export omits results or call IDs |
119
+ | Authorship | `promptSource` typed/queued, excluding injected/tool records | User messages with known injected context excluded | `<user_query>` wrapper; a weaker signal |
120
+ | Coach, export-run | Yes | Yes | Yes, with missing evidence preserved |
121
+ | API-equivalent cost | Yes | Not supported | Not supported |
122
+
123
+ ```sh
124
+ transcripto replay --harness claude
125
+ transcripto replay --harness codex
126
+ transcripto replay --harness cursor
127
+ transcripto search "retry" --harness codex
128
+ transcripto replay --root /path/to/transcripts
129
+ ```
130
+
131
+ Default roots are `~/.claude/projects`, `~/.codex`, and `~/.cursor`.
132
+ Codex reads sessions and archived sessions. Cursor reads the per-session files
133
+ under `projects/*/agent-transcripts/*/`. Latest-session replay skips subagents
134
+ and files without a submitted human request.
135
+
136
+ Cursor exports often contain calls without results. That is useful evidence
137
+ of an attempt, but not enough to claim success. Transcripto does not substitute
138
+ an assistant's closing message or a `turn_ended` record for the missing result.
139
+
140
+ ## The evidence contract
141
+
142
+ 1. A tool call is an **attempt**.
143
+ 2. A matching result may establish **succeeded** or **failed** execution.
144
+ 3. A missing result, a running command, or an ambiguous result is **unknown**.
145
+ 4. An exit code of zero is not proof that the requested task is correct.
146
+ 5. A later human request opens a new episode. Its work is never absorbed into
147
+ the previous request because the words happen to overlap.
148
+ 6. A command mentioning `git commit` is not necessarily a commit. Quoted text,
149
+ dry runs, and compound shell commands are not promoted to commit evidence.
150
+
151
+ The tool never executes transcript commands. It parses a limited set of static
152
+ Codex wrapper forms; arbitrary JavaScript and multiple nested child calls are
153
+ not reconstructed. A long-running call can remain unknown when completion is
154
+ only present in a later polling call. Cross-session durability, semantic task
155
+ completion, and live repository state are not inferred from transcript text.
156
+
157
+ ## Coach without invented grades
158
+
159
+ `transcripto coach` shows descriptive request history. It no longer recommends
160
+ prompt habits, labels a no-edit answer a bad prompt, or applies one person's
161
+ correction-rate calibration to someone else's data.
162
+
163
+ Habit proportions include **change attempts with known outcomes**. Unknown
164
+ outcomes and read-only tasks are excluded. The groups overlap and the requests
165
+ can be correlated, so these proportions are not significance tests or causal
166
+ advice. No best/worst ranking is printed. Correction markers are a lexical
167
+ estimate with false positives and misses, not a guaranteed lower bound.
168
+
169
+ Coach JSON is marked `transcripto.coach/2`. Legacy `durable`/`survived` fields
170
+ refer only to observed successful change results, not lasting work. Unknown
171
+ request outcomes have `survived: null`. `durable_rate` uses only known change
172
+ requests as its denominator and is null when there are none. `best_prompt` and `worst_prompt` are
173
+ retained as null compatibility fields. Use `successful_request`,
174
+ `failed_request`, and replay's event status to inspect evidence.
175
+
176
+ `export-run latest` always prints JSON. Its
177
+ existing `transcripto.export-run/1` keys remain available. `records` counts
178
+ normalized message records. `files_touched` lists attempted file targets,
179
+ including reads; it is not a successful-change count. Reflog commits are local
180
+ working-tree events inside the available timestamp window, not proof that this
181
+ agent caused them. Without a usable window, the commit fields are null.
182
+
183
+ ## Privacy and limits
184
+
185
+ The three runtime modules contain no network client, telemetry, account flow,
186
+ or process execution. Package installation (`pip` or `uvx`) is a separate
187
+ operation that may contact a package registry and write a package cache.
188
+
189
+ Replay and coach read transcripts without making an index. Search writes text
190
+ and file metadata to `~/.trace/trace.db`. A new index directory is private;
191
+ database and WAL files use mode `0600`. The index stays after the command exits.
192
+ Schema upgrades rebuild it locally. `replay --demo` briefly writes an invented
193
+ transcript to a temporary directory and removes it afterward.
194
+
195
+ Malformed records and unreadable files produce diagnostics. Search indexes the
196
+ valid records of partially malformed files and repeats the warning on later
197
+ queries until the source is repaired. A wholly unreadable file keeps any prior
198
+ indexed copy, with an explicit warning; replay always reads the source. Files larger than
199
+ 128 MiB are skipped before parsing; lines larger than 8 MiB are discarded as
200
+ whole records. Split larger files into smaller JSONL files to inspect them.
201
+ Individual displayed text fields are bounded at 16,000 characters. Replay's
202
+ source references let you inspect the original. Terminal control sequences are
203
+ removed from rendered transcript content.
204
+
205
+ ## Development
206
+
207
+ Python 3.9+, standard library only. The CLI remains in `transcripto.py`;
208
+ `transcripto_core.py` owns normalization and evidence; `transcripto_replay.py`
209
+ owns replay selection and presentation. All fixtures committed here are synthetic.
210
+
211
+ ```sh
212
+ python3 -m unittest discover -s tests -v
213
+ for test in test_*.sh; do bash "$test" || exit; done
214
+ ```
215
+
216
+ The regression cases include failed edits and commits, missing/mismatched
217
+ results, Cursor call shapes, Codex wrappers, result attribution across prompts,
218
+ rollback order, malformed JSON, a sparse 2 GiB file, terminal controls, private
219
+ index permissions, incremental search, and cross-harness retrieval.
220
+
221
+ MIT. Open an issue with the **record shape** that fails, or a synthetic
222
+ reproduction. Your real prompt text is not needed.
@@ -0,0 +1,204 @@
1
+ # Transcripto
2
+
3
+ **Your agent said “done.” Replay what happened.**
4
+
5
+ Transcripto reads the transcripts already on your machine and puts your request,
6
+ the tool calls, and their recorded results in order. Failed edits stay failed.
7
+ Missing results stay unknown. A confident closing message changes neither.
8
+
9
+ Claude Code · Codex · Cursor. Local. No accounts. No runtime dependencies.
10
+
11
+ ```sh
12
+ uvx --from transcripto==0.2.0 transcripto
13
+
14
+ # Try a synthetic session without opening your own history:
15
+ uvx --from transcripto==0.2.0 transcripto replay --demo
16
+ ```
17
+
18
+ Or install with `python3 -m pip install transcripto==0.2.0`, then run
19
+ `transcripto`. Requires Python 3.9 or newer.
20
+
21
+ Version **0.2.0** adds replay. The default command opens your latest human
22
+ session. Pinning the version makes the reviewed build and the build you run
23
+ the same object.
24
+
25
+ ## The replay
26
+
27
+ This is output from `replay --demo`. **All prompts and results in this example
28
+ are invented.** The demo goes through the same parser as a real transcript.
29
+
30
+ ```text
31
+ THE COMEBACK · claude · request 1
32
+ You asked: "Fix the login redirect and run its tests."
33
+
34
+ 1 FAIL edit src/login.py
35
+ Tool error: Error: text not found [call L2 → result L3]
36
+ 2 OK edit src/login.py
37
+ Tool reported success. [call L4 → result L5]
38
+ 3 FAIL check pytest tests/test_login.py
39
+ Tool error: Process exited with code 1 [call L6 → result L7]
40
+ 4 OK edit src/login.py
41
+ Tool reported success. [call L8 → result L9]
42
+ 5 OK check pytest tests/test_login.py
43
+ Tool reported success. [call L10 → result L11]
44
+
45
+ Agent said: "The redirect is fixed and the tests pass."
46
+
47
+ Recorded: 3 succeeded · 2 failed · 0 unknown
48
+ Status describes a tool result, not task correctness. Missing results stay unknown.
49
+ ```
50
+
51
+ The headings have rules. **The comeback** means a recorded failure was followed
52
+ by success for the same operation and target, without a later failed or unknown
53
+ attempt on that target. **The snag** means a failure is
54
+ present. **The missing receipt** means a result is unknown. **The answer** means
55
+ there were no recorded tool calls; an explanation may have been the whole task.
56
+ These are descriptions of the sequence, not grades for you or your agent.
57
+
58
+ On your own history, each replay names its source file and line numbers, plus a
59
+ command that reopens that exact request. Long sequences open around the first
60
+ failure or change and tell you what was omitted. `--all` shows the full sequence.
61
+
62
+ ```sh
63
+ transcripto # latest session you submitted a request in
64
+ transcripto replay --failures # most recent request with a recorded failure
65
+ transcripto replay "login redirect" # find requests containing these words
66
+ transcripto replay path/to/session.jsonl # inspect one transcript
67
+ transcripto replay --session 3f9c1a2b # explicitly select a session prefix
68
+ transcripto replay path/to/session.jsonl --episode 3 --all
69
+ transcripto replay latest --json # structured events, evidence, source lines
70
+ transcripto replay latest --share # counts + caveat; no prompts or paths
71
+ ```
72
+
73
+ `--share` is intentionally small. Full replay output and JSON contain your own
74
+ words and local paths. The tool does not upload either.
75
+
76
+ ## Find the thing you remember
77
+
78
+ Search automatically refreshes a local index. No setup command is required.
79
+
80
+ ```sh
81
+ transcripto ask "retry" # your submitted words
82
+ transcripto search "retry" # prompts, replies, and tool text
83
+ transcripto find parser.py # recorded file operations and attempts
84
+ transcripto trace "retry" # an alias into result-aware replay
85
+ transcripto sessions # sessions with submitted prompts
86
+ transcripto stats # activity counts
87
+ ```
88
+
89
+ A failed or unconfirmed file change is labelled an **attempt**, never `WROTE`.
90
+ Queries with `--harness` or `--root` are scoped to that selection even if the
91
+ index already contains another corpus. `index` and `watch` remain available for
92
+ explicit refresh and background polling.
93
+
94
+ ## What each harness supports
95
+
96
+ | Feature | Claude Code | Codex | Cursor |
97
+ |---|---|---|---|
98
+ | Replay, search, ask, find, trace, sessions, stats | Yes | Yes | Yes |
99
+ | Tool attempts | Native tool calls | Direct calls and supported static wrappers | `StrReplace`, `Shell`, `Write`, and other calls |
100
+ | Execution status | Matched results | Matched results; ambiguous wrappers stay unknown | Unknown when the export omits results or call IDs |
101
+ | Authorship | `promptSource` typed/queued, excluding injected/tool records | User messages with known injected context excluded | `<user_query>` wrapper; a weaker signal |
102
+ | Coach, export-run | Yes | Yes | Yes, with missing evidence preserved |
103
+ | API-equivalent cost | Yes | Not supported | Not supported |
104
+
105
+ ```sh
106
+ transcripto replay --harness claude
107
+ transcripto replay --harness codex
108
+ transcripto replay --harness cursor
109
+ transcripto search "retry" --harness codex
110
+ transcripto replay --root /path/to/transcripts
111
+ ```
112
+
113
+ Default roots are `~/.claude/projects`, `~/.codex`, and `~/.cursor`.
114
+ Codex reads sessions and archived sessions. Cursor reads the per-session files
115
+ under `projects/*/agent-transcripts/*/`. Latest-session replay skips subagents
116
+ and files without a submitted human request.
117
+
118
+ Cursor exports often contain calls without results. That is useful evidence
119
+ of an attempt, but not enough to claim success. Transcripto does not substitute
120
+ an assistant's closing message or a `turn_ended` record for the missing result.
121
+
122
+ ## The evidence contract
123
+
124
+ 1. A tool call is an **attempt**.
125
+ 2. A matching result may establish **succeeded** or **failed** execution.
126
+ 3. A missing result, a running command, or an ambiguous result is **unknown**.
127
+ 4. An exit code of zero is not proof that the requested task is correct.
128
+ 5. A later human request opens a new episode. Its work is never absorbed into
129
+ the previous request because the words happen to overlap.
130
+ 6. A command mentioning `git commit` is not necessarily a commit. Quoted text,
131
+ dry runs, and compound shell commands are not promoted to commit evidence.
132
+
133
+ The tool never executes transcript commands. It parses a limited set of static
134
+ Codex wrapper forms; arbitrary JavaScript and multiple nested child calls are
135
+ not reconstructed. A long-running call can remain unknown when completion is
136
+ only present in a later polling call. Cross-session durability, semantic task
137
+ completion, and live repository state are not inferred from transcript text.
138
+
139
+ ## Coach without invented grades
140
+
141
+ `transcripto coach` shows descriptive request history. It no longer recommends
142
+ prompt habits, labels a no-edit answer a bad prompt, or applies one person's
143
+ correction-rate calibration to someone else's data.
144
+
145
+ Habit proportions include **change attempts with known outcomes**. Unknown
146
+ outcomes and read-only tasks are excluded. The groups overlap and the requests
147
+ can be correlated, so these proportions are not significance tests or causal
148
+ advice. No best/worst ranking is printed. Correction markers are a lexical
149
+ estimate with false positives and misses, not a guaranteed lower bound.
150
+
151
+ Coach JSON is marked `transcripto.coach/2`. Legacy `durable`/`survived` fields
152
+ refer only to observed successful change results, not lasting work. Unknown
153
+ request outcomes have `survived: null`. `durable_rate` uses only known change
154
+ requests as its denominator and is null when there are none. `best_prompt` and `worst_prompt` are
155
+ retained as null compatibility fields. Use `successful_request`,
156
+ `failed_request`, and replay's event status to inspect evidence.
157
+
158
+ `export-run latest` always prints JSON. Its
159
+ existing `transcripto.export-run/1` keys remain available. `records` counts
160
+ normalized message records. `files_touched` lists attempted file targets,
161
+ including reads; it is not a successful-change count. Reflog commits are local
162
+ working-tree events inside the available timestamp window, not proof that this
163
+ agent caused them. Without a usable window, the commit fields are null.
164
+
165
+ ## Privacy and limits
166
+
167
+ The three runtime modules contain no network client, telemetry, account flow,
168
+ or process execution. Package installation (`pip` or `uvx`) is a separate
169
+ operation that may contact a package registry and write a package cache.
170
+
171
+ Replay and coach read transcripts without making an index. Search writes text
172
+ and file metadata to `~/.trace/trace.db`. A new index directory is private;
173
+ database and WAL files use mode `0600`. The index stays after the command exits.
174
+ Schema upgrades rebuild it locally. `replay --demo` briefly writes an invented
175
+ transcript to a temporary directory and removes it afterward.
176
+
177
+ Malformed records and unreadable files produce diagnostics. Search indexes the
178
+ valid records of partially malformed files and repeats the warning on later
179
+ queries until the source is repaired. A wholly unreadable file keeps any prior
180
+ indexed copy, with an explicit warning; replay always reads the source. Files larger than
181
+ 128 MiB are skipped before parsing; lines larger than 8 MiB are discarded as
182
+ whole records. Split larger files into smaller JSONL files to inspect them.
183
+ Individual displayed text fields are bounded at 16,000 characters. Replay's
184
+ source references let you inspect the original. Terminal control sequences are
185
+ removed from rendered transcript content.
186
+
187
+ ## Development
188
+
189
+ Python 3.9+, standard library only. The CLI remains in `transcripto.py`;
190
+ `transcripto_core.py` owns normalization and evidence; `transcripto_replay.py`
191
+ owns replay selection and presentation. All fixtures committed here are synthetic.
192
+
193
+ ```sh
194
+ python3 -m unittest discover -s tests -v
195
+ for test in test_*.sh; do bash "$test" || exit; done
196
+ ```
197
+
198
+ The regression cases include failed edits and commits, missing/mismatched
199
+ results, Cursor call shapes, Codex wrappers, result attribution across prompts,
200
+ rollback order, malformed JSON, a sparse 2 GiB file, terminal controls, private
201
+ index permissions, incremental search, and cross-harness retrieval.
202
+
203
+ MIT. Open an issue with the **record shape** that fails, or a synthetic
204
+ reproduction. Your real prompt text is not needed.
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "transcripto"
7
- version = "0.1.5"
8
- description = "Search everything your coding agents ever did, grade your own prompts, and price your decisions. Local, stdlib-only, your data never leaves the machine."
7
+ version = "0.2.0"
8
+ description = "Instant replay for coding agents. Inspect requests, tool calls, and recorded results across Claude Code, Codex, and Cursor. Local, stdlib-only."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
11
11
  license = { text = "MIT" }
@@ -28,4 +28,4 @@ Source = "https://github.com/Morkeeth/transcripto"
28
28
  transcripto = "transcripto:main"
29
29
 
30
30
  [tool.setuptools]
31
- py-modules = ["transcripto"]
31
+ py-modules = ["transcripto", "transcripto_core", "transcripto_replay"]