transcripto 0.1.2__tar.gz → 0.1.4__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.
- {transcripto-0.1.2/transcripto.egg-info → transcripto-0.1.4}/PKG-INFO +113 -42
- {transcripto-0.1.2 → transcripto-0.1.4}/README.md +112 -41
- {transcripto-0.1.2 → transcripto-0.1.4}/pyproject.toml +1 -1
- {transcripto-0.1.2 → transcripto-0.1.4/transcripto.egg-info}/PKG-INFO +113 -42
- {transcripto-0.1.2 → transcripto-0.1.4}/transcripto.py +476 -43
- {transcripto-0.1.2 → transcripto-0.1.4}/LICENSE +0 -0
- {transcripto-0.1.2 → transcripto-0.1.4}/setup.cfg +0 -0
- {transcripto-0.1.2 → transcripto-0.1.4}/transcripto.egg-info/SOURCES.txt +0 -0
- {transcripto-0.1.2 → transcripto-0.1.4}/transcripto.egg-info/dependency_links.txt +0 -0
- {transcripto-0.1.2 → transcripto-0.1.4}/transcripto.egg-info/entry_points.txt +0 -0
- {transcripto-0.1.2 → transcripto-0.1.4}/transcripto.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: transcripto
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Search everything your coding agents ever did, grade your own prompts, and price your decisions. Local, stdlib-only, your data never leaves the machine.
|
|
5
5
|
Author: Oscar Morke
|
|
6
6
|
License: MIT
|
|
@@ -29,19 +29,11 @@ your disk and never opens a socket.
|
|
|
29
29
|
uvx transcripto coach
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
> **
|
|
33
|
-
>
|
|
34
|
-
>
|
|
35
|
-
> traceback instead of an instruction. One line settles which one you are holding:
|
|
32
|
+
> **which build you got.** `uvx transcripto --version` should print **0.1.3**. If `--version`
|
|
33
|
+
> is not a recognised flag at all you are on 0.1.1, which predates `trace`, Cursor support and
|
|
34
|
+
> this README. `uvx --refresh transcripto` forces a fresh resolve past uv's cache.
|
|
36
35
|
>
|
|
37
|
-
>
|
|
38
|
-
> uvx transcripto --version # 0.1.2 or newer = this README is accurate
|
|
39
|
-
> ```
|
|
40
|
-
>
|
|
41
|
-
> *Read 2026-08-31: PyPI was serving 0.1.1 while this README described 0.1.2, so
|
|
42
|
-
> `uvx transcripto` gave the older build. If `--version` is not even a recognised
|
|
43
|
-
> flag, you have 0.1.1 — it was added in 0.1.2 precisely because there was no way
|
|
44
|
-
> to tell.* The repo always matches this README and needs nothing installed:
|
|
36
|
+
> The repo always matches this README and needs nothing installed:
|
|
45
37
|
>
|
|
46
38
|
> ```
|
|
47
39
|
> git clone https://github.com/Morkeeth/transcripto && cd transcripto
|
|
@@ -81,41 +73,48 @@ the same way.
|
|
|
81
73
|
|
|
82
74
|
## what you get back
|
|
83
75
|
|
|
84
|
-
this is a real run on one machine,
|
|
76
|
+
this is a real run on one machine, 2026-08-31. The numbers are unedited; the two quoted prompts are synthetic stand-ins of the same shape, because your prompts never leave your machine and neither do mine:
|
|
85
77
|
|
|
86
78
|
```
|
|
87
79
|
|
|
88
80
|
YOUR PROMPT HABITS, GRADED (offline, your machine only)
|
|
89
81
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
82
|
+
- your worst looped prompt, with its witness:
|
|
83
|
+
"hmm ok lets just try again and see if it works this time, same thing as before but…"
|
|
84
|
+
NO-DURABLE-RECORD: read-only Bash only, no file change · corrections: 15 · assistant turns: 221
|
|
85
|
+
|
|
86
|
+
+ your best landed prompt, with its witness:
|
|
87
|
+
"TERMINAL 3 — parser · ~/CODE/demo Read hack.md. Fix the counter, run the suite, commit if green…"
|
|
88
|
+
COMMIT-WITNESSED: git commit · corrections: 0
|
|
95
89
|
|
|
96
90
|
SURVIVAL IS A PROXY: survival = a durable Write/Edit or an un-reverted git commit in-episode. A PROXY, not proof the work was correct or shipped.
|
|
97
91
|
|
|
98
92
|
SURVIVES MOST do more of these:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
57% (
|
|
93
|
+
65% (71/110) states-a-check-or-done-condition
|
|
94
|
+
64% (178/276) detailed (>40 words)
|
|
95
|
+
59% (22/37) no-object (pronoun/vague)
|
|
96
|
+
59% (451/763) intent:CHANGE
|
|
97
|
+
57% (106/187) cites-a-file-or-path
|
|
104
98
|
|
|
105
99
|
SURVIVES LEAST these tend to loop:
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
42% (
|
|
110
|
-
45% (
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
100
|
+
31% (4/13) intent:REVERT
|
|
101
|
+
40% (451/1129) intent:none
|
|
102
|
+
42% (320/765) terse (<8 words)
|
|
103
|
+
42% (81/192) intent:DESCRIBE
|
|
104
|
+
45% (5/11) intent:TEST
|
|
105
|
+
|
|
106
|
+
harness claude · 2957 transcript(s), 431,085 records · 3969 typed by you (0.92%)
|
|
107
|
+
episodes: 2108 ranked, 992 survived (47%)
|
|
108
|
+
commit 454 · write/edit 538 · reverted 2 · nothing durable 1114
|
|
109
|
+
|
|
110
|
+
─────────────────────────────────────────────────────────
|
|
111
|
+
compare yours. numbers only, nothing from your prompts:
|
|
112
|
+
|
|
113
|
+
transcripto coach · claude · 2108 episodes · 47% survived
|
|
114
|
+
states-a-check-or-done-condition 65% (71/110)
|
|
115
|
+
intent:none 40% (451/1129)
|
|
116
|
+
gap 1.6x
|
|
117
|
+
─────────────────────────────────────────────────────────
|
|
119
118
|
```
|
|
120
119
|
|
|
121
120
|
those are my numbers on that date, and they move every session i run, so treat
|
|
@@ -143,6 +142,74 @@ signal, not a verdict. if it ever prints something that flatters you, distrust i
|
|
|
143
142
|
|
|
144
143
|
the caveat is printed in the output itself, every run, on purpose.
|
|
145
144
|
|
|
145
|
+
## correction rate
|
|
146
|
+
|
|
147
|
+
> in the repo since 2026-09-02, not yet on PyPI. `python3 transcripto.py coach` prints it.
|
|
148
|
+
|
|
149
|
+
one more line under the coach footer:
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
correction rate: 6% measured (227 of 4061 typed turns) · v1 catches ~1 in 6, so the real rate is ~26-37%
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**correction rate = typed turns that correct the agent ÷ typed turns.** the denominator
|
|
156
|
+
is the same authorship gate as every other number here (`typed` or `queued`, never
|
|
157
|
+
`isMeta`, `isSidechain` or a tool result), so a tool result that happens to say "wrong"
|
|
158
|
+
cannot move it. a typed turn counts as a correction when a **marker** fires in its head:
|
|
159
|
+
the first 80 words after URLs and file paths are stripped, case-insensitive, whole-word:
|
|
160
|
+
a leading or bare `no`, `again`, `wrong`, `not that`, `I meant`, `revert`, `undo`, `stop`,
|
|
161
|
+
`instead`, plus a few measured additions. whole-word, so "against" is not "again" and
|
|
162
|
+
"now" is not "no". the v0 "nudge" rule (a short turn naming the agent's last file) is gone:
|
|
163
|
+
measured over 100 flagged rows it fired alone five times and was wrong five times.
|
|
164
|
+
`TRANSCRIPTO_CORRECTION=v0` brings the old classifier back for comparison.
|
|
165
|
+
|
|
166
|
+
it is one pure function, `is_correction(text)`, and it is a **floor**, now measured rather
|
|
167
|
+
than asserted: on a 200-row labelled sample the v1 classifier has precision 0.81 and recall
|
|
168
|
+
0.16 (`docs/CORRECTION-PRECISION-2026-09-03.md`), which is why the printed line carries the
|
|
169
|
+
"~1 in 6" correction and a range. read it as a trend on your own history.
|
|
170
|
+
`test_correction.sh` pins the rule and the gate on `fixtures-correction/`.
|
|
171
|
+
|
|
172
|
+
## export-run
|
|
173
|
+
|
|
174
|
+
> in the repo since 2026-09-02, not yet on PyPI.
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
transcripto export-run latest # the newest session on this machine
|
|
178
|
+
transcripto export-run 3f9c1a2b # a session id, or a prefix of one
|
|
179
|
+
transcripto export-run path/to/session.jsonl # a transcript file
|
|
180
|
+
transcripto export-run latest --harness codex # --root / --harness as for coach
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
one run's numbers as JSON, read straight from the transcript file (no index needed).
|
|
184
|
+
this is the contract other tools read (Agent Grinder's card, ZUP's board); the keys are
|
|
185
|
+
frozen under `schema`, and a new key is an addition, never a rename.
|
|
186
|
+
|
|
187
|
+
| key | meaning |
|
|
188
|
+
|---|---|
|
|
189
|
+
| `schema` | `transcripto.export-run/1` |
|
|
190
|
+
| `session_id` | the harness's session id (Claude Code: the file name; Codex: `session_meta.id`; Cursor: the file name) |
|
|
191
|
+
| `project` | the run's `cwd` |
|
|
192
|
+
| `harness` | `claude` · `codex` · `cursor` |
|
|
193
|
+
| `transcript` | absolute path of the file read |
|
|
194
|
+
| `started` · `ended` | first and last record timestamp, UTC, `…Z`; `null` if the file carries none |
|
|
195
|
+
| `duration_s` | `ended − started`, whole seconds |
|
|
196
|
+
| `records` | every record in the file, before any gate |
|
|
197
|
+
| `typed_turns` | records that pass the authorship gate: `promptSource` typed or queued, never meta, sidechain or tool result. the same count coach prints as "typed by you" |
|
|
198
|
+
| `corrections` | typed turns `is_correction()` flags (see above) |
|
|
199
|
+
| `correction_rate` | `corrections / typed_turns`, 3 decimals; `null` when nothing was typed |
|
|
200
|
+
| `tool_calls` | every `tool_use` block the agent emitted |
|
|
201
|
+
| `files_touched` | sorted set of `file_path` (or `notebook_path`) from Edit / Write / Read / MultiEdit / NotebookEdit calls |
|
|
202
|
+
| `commits_in_window` | commits stamped inside `[started, ended]` in the project's git reflog; `null` when `project` is not inside a git repo |
|
|
203
|
+
| `commits` | those commits as `{sha, ts, subject}`, oldest first; `null` when not a repo |
|
|
204
|
+
| `proxy` | the caveat, in the JSON so it travels with the numbers |
|
|
205
|
+
|
|
206
|
+
`commits_in_window` reads `.git/logs/HEAD` directly, not `git log`, because this file
|
|
207
|
+
does not shell out (see privacy). the reflog is the record of what **that working tree**
|
|
208
|
+
did: a commit made there in the window is in it, a commit pulled in from elsewhere is not.
|
|
209
|
+
git expires the reflog after 90 days by default, so a run older than that can read 0 here
|
|
210
|
+
while `git log` would still show its commits. `commit (amend)` counts; a rebase's `pick`
|
|
211
|
+
lines do not. a `.git` file (a worktree) is followed to its gitdir.
|
|
212
|
+
|
|
146
213
|
## why your own gate matters here
|
|
147
214
|
|
|
148
215
|
at fleet scale roughly 95% of the `type: user` records in a transcript are not
|
|
@@ -200,15 +267,15 @@ claim, so here is the grep that settles it against the single file it ships as:
|
|
|
200
267
|
$ grep -nE '^[[:space:]]*(import|from) ' transcripto.py
|
|
201
268
|
8:import sys, os, json, glob, re, sqlite3, argparse
|
|
202
269
|
9:from datetime import datetime, timezone
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
270
|
+
261: import time
|
|
271
|
+
1160: import datetime
|
|
272
|
+
1170: from the separator), so the result is checked on disk and dropped if it is
|
|
206
273
|
```
|
|
207
274
|
|
|
208
275
|
five lines, four of which are imports and all four are stdlib. `time` and
|
|
209
276
|
`datetime` sit inside functions, which is why the pattern allows for indentation —
|
|
210
277
|
anchor it at `^import` and you would miss two, so do not take my word for the
|
|
211
|
-
anchor either. line
|
|
278
|
+
anchor either. line 1170 is the pattern catching a docstring that happens to begin
|
|
212
279
|
with the word `from`; it is prose, not an import, and it is left in rather than
|
|
213
280
|
tuned out, because a grep you tuned until it agreed with you proves nothing.
|
|
214
281
|
|
|
@@ -247,6 +314,7 @@ transcripto sessions recent sessions + the first prompt YOU typed in each
|
|
|
247
314
|
transcripto stats what you actually work on
|
|
248
315
|
transcripto cost what ONE of your decisions costs
|
|
249
316
|
transcripto coach which of YOUR prompt habits survive (a proxy)
|
|
317
|
+
transcripto export-run one run's numbers as JSON (typed turns, correction rate, commits)
|
|
250
318
|
```
|
|
251
319
|
|
|
252
320
|
`ask` is the one that kills "wait, did i lose something?". it answers "what was i
|
|
@@ -307,9 +375,12 @@ just gives the file a name on your PATH.
|
|
|
307
375
|
./test_cost.sh 12 assertions
|
|
308
376
|
./test_small_n.sh 7 assertions
|
|
309
377
|
./test_label_bands.sh 13 assertions
|
|
378
|
+
./test_correction.sh 32 assertions (correction rate + export-run, 2026-09-02)
|
|
379
|
+
./test_cursor_partial.sh 7 assertions
|
|
380
|
+
./test_version.sh 1 assertion (VERSION matches in transcripto.py and pyproject.toml)
|
|
310
381
|
```
|
|
311
382
|
|
|
312
|
-
|
|
383
|
+
91 assertions, all green, re-run 2026-09-02.
|
|
313
384
|
|
|
314
385
|
offline, no keys, on fixtures that inherit the real transcript shape including
|
|
315
386
|
all four ways a non-human record disguises itself as `type: user`.
|
|
@@ -11,19 +11,11 @@ your disk and never opens a socket.
|
|
|
11
11
|
uvx transcripto coach
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
> **
|
|
15
|
-
>
|
|
16
|
-
>
|
|
17
|
-
> traceback instead of an instruction. One line settles which one you are holding:
|
|
14
|
+
> **which build you got.** `uvx transcripto --version` should print **0.1.3**. If `--version`
|
|
15
|
+
> is not a recognised flag at all you are on 0.1.1, which predates `trace`, Cursor support and
|
|
16
|
+
> this README. `uvx --refresh transcripto` forces a fresh resolve past uv's cache.
|
|
18
17
|
>
|
|
19
|
-
>
|
|
20
|
-
> uvx transcripto --version # 0.1.2 or newer = this README is accurate
|
|
21
|
-
> ```
|
|
22
|
-
>
|
|
23
|
-
> *Read 2026-08-31: PyPI was serving 0.1.1 while this README described 0.1.2, so
|
|
24
|
-
> `uvx transcripto` gave the older build. If `--version` is not even a recognised
|
|
25
|
-
> flag, you have 0.1.1 — it was added in 0.1.2 precisely because there was no way
|
|
26
|
-
> to tell.* The repo always matches this README and needs nothing installed:
|
|
18
|
+
> The repo always matches this README and needs nothing installed:
|
|
27
19
|
>
|
|
28
20
|
> ```
|
|
29
21
|
> git clone https://github.com/Morkeeth/transcripto && cd transcripto
|
|
@@ -63,41 +55,48 @@ the same way.
|
|
|
63
55
|
|
|
64
56
|
## what you get back
|
|
65
57
|
|
|
66
|
-
this is a real run on one machine,
|
|
58
|
+
this is a real run on one machine, 2026-08-31. The numbers are unedited; the two quoted prompts are synthetic stand-ins of the same shape, because your prompts never leave your machine and neither do mine:
|
|
67
59
|
|
|
68
60
|
```
|
|
69
61
|
|
|
70
62
|
YOUR PROMPT HABITS, GRADED (offline, your machine only)
|
|
71
63
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
64
|
+
- your worst looped prompt, with its witness:
|
|
65
|
+
"hmm ok lets just try again and see if it works this time, same thing as before but…"
|
|
66
|
+
NO-DURABLE-RECORD: read-only Bash only, no file change · corrections: 15 · assistant turns: 221
|
|
67
|
+
|
|
68
|
+
+ your best landed prompt, with its witness:
|
|
69
|
+
"TERMINAL 3 — parser · ~/CODE/demo Read hack.md. Fix the counter, run the suite, commit if green…"
|
|
70
|
+
COMMIT-WITNESSED: git commit · corrections: 0
|
|
77
71
|
|
|
78
72
|
SURVIVAL IS A PROXY: survival = a durable Write/Edit or an un-reverted git commit in-episode. A PROXY, not proof the work was correct or shipped.
|
|
79
73
|
|
|
80
74
|
SURVIVES MOST do more of these:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
57% (
|
|
75
|
+
65% (71/110) states-a-check-or-done-condition
|
|
76
|
+
64% (178/276) detailed (>40 words)
|
|
77
|
+
59% (22/37) no-object (pronoun/vague)
|
|
78
|
+
59% (451/763) intent:CHANGE
|
|
79
|
+
57% (106/187) cites-a-file-or-path
|
|
86
80
|
|
|
87
81
|
SURVIVES LEAST these tend to loop:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
42% (
|
|
92
|
-
45% (
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
82
|
+
31% (4/13) intent:REVERT
|
|
83
|
+
40% (451/1129) intent:none
|
|
84
|
+
42% (320/765) terse (<8 words)
|
|
85
|
+
42% (81/192) intent:DESCRIBE
|
|
86
|
+
45% (5/11) intent:TEST
|
|
87
|
+
|
|
88
|
+
harness claude · 2957 transcript(s), 431,085 records · 3969 typed by you (0.92%)
|
|
89
|
+
episodes: 2108 ranked, 992 survived (47%)
|
|
90
|
+
commit 454 · write/edit 538 · reverted 2 · nothing durable 1114
|
|
91
|
+
|
|
92
|
+
─────────────────────────────────────────────────────────
|
|
93
|
+
compare yours. numbers only, nothing from your prompts:
|
|
94
|
+
|
|
95
|
+
transcripto coach · claude · 2108 episodes · 47% survived
|
|
96
|
+
states-a-check-or-done-condition 65% (71/110)
|
|
97
|
+
intent:none 40% (451/1129)
|
|
98
|
+
gap 1.6x
|
|
99
|
+
─────────────────────────────────────────────────────────
|
|
101
100
|
```
|
|
102
101
|
|
|
103
102
|
those are my numbers on that date, and they move every session i run, so treat
|
|
@@ -125,6 +124,74 @@ signal, not a verdict. if it ever prints something that flatters you, distrust i
|
|
|
125
124
|
|
|
126
125
|
the caveat is printed in the output itself, every run, on purpose.
|
|
127
126
|
|
|
127
|
+
## correction rate
|
|
128
|
+
|
|
129
|
+
> in the repo since 2026-09-02, not yet on PyPI. `python3 transcripto.py coach` prints it.
|
|
130
|
+
|
|
131
|
+
one more line under the coach footer:
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
correction rate: 6% measured (227 of 4061 typed turns) · v1 catches ~1 in 6, so the real rate is ~26-37%
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**correction rate = typed turns that correct the agent ÷ typed turns.** the denominator
|
|
138
|
+
is the same authorship gate as every other number here (`typed` or `queued`, never
|
|
139
|
+
`isMeta`, `isSidechain` or a tool result), so a tool result that happens to say "wrong"
|
|
140
|
+
cannot move it. a typed turn counts as a correction when a **marker** fires in its head:
|
|
141
|
+
the first 80 words after URLs and file paths are stripped, case-insensitive, whole-word:
|
|
142
|
+
a leading or bare `no`, `again`, `wrong`, `not that`, `I meant`, `revert`, `undo`, `stop`,
|
|
143
|
+
`instead`, plus a few measured additions. whole-word, so "against" is not "again" and
|
|
144
|
+
"now" is not "no". the v0 "nudge" rule (a short turn naming the agent's last file) is gone:
|
|
145
|
+
measured over 100 flagged rows it fired alone five times and was wrong five times.
|
|
146
|
+
`TRANSCRIPTO_CORRECTION=v0` brings the old classifier back for comparison.
|
|
147
|
+
|
|
148
|
+
it is one pure function, `is_correction(text)`, and it is a **floor**, now measured rather
|
|
149
|
+
than asserted: on a 200-row labelled sample the v1 classifier has precision 0.81 and recall
|
|
150
|
+
0.16 (`docs/CORRECTION-PRECISION-2026-09-03.md`), which is why the printed line carries the
|
|
151
|
+
"~1 in 6" correction and a range. read it as a trend on your own history.
|
|
152
|
+
`test_correction.sh` pins the rule and the gate on `fixtures-correction/`.
|
|
153
|
+
|
|
154
|
+
## export-run
|
|
155
|
+
|
|
156
|
+
> in the repo since 2026-09-02, not yet on PyPI.
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
transcripto export-run latest # the newest session on this machine
|
|
160
|
+
transcripto export-run 3f9c1a2b # a session id, or a prefix of one
|
|
161
|
+
transcripto export-run path/to/session.jsonl # a transcript file
|
|
162
|
+
transcripto export-run latest --harness codex # --root / --harness as for coach
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
one run's numbers as JSON, read straight from the transcript file (no index needed).
|
|
166
|
+
this is the contract other tools read (Agent Grinder's card, ZUP's board); the keys are
|
|
167
|
+
frozen under `schema`, and a new key is an addition, never a rename.
|
|
168
|
+
|
|
169
|
+
| key | meaning |
|
|
170
|
+
|---|---|
|
|
171
|
+
| `schema` | `transcripto.export-run/1` |
|
|
172
|
+
| `session_id` | the harness's session id (Claude Code: the file name; Codex: `session_meta.id`; Cursor: the file name) |
|
|
173
|
+
| `project` | the run's `cwd` |
|
|
174
|
+
| `harness` | `claude` · `codex` · `cursor` |
|
|
175
|
+
| `transcript` | absolute path of the file read |
|
|
176
|
+
| `started` · `ended` | first and last record timestamp, UTC, `…Z`; `null` if the file carries none |
|
|
177
|
+
| `duration_s` | `ended − started`, whole seconds |
|
|
178
|
+
| `records` | every record in the file, before any gate |
|
|
179
|
+
| `typed_turns` | records that pass the authorship gate: `promptSource` typed or queued, never meta, sidechain or tool result. the same count coach prints as "typed by you" |
|
|
180
|
+
| `corrections` | typed turns `is_correction()` flags (see above) |
|
|
181
|
+
| `correction_rate` | `corrections / typed_turns`, 3 decimals; `null` when nothing was typed |
|
|
182
|
+
| `tool_calls` | every `tool_use` block the agent emitted |
|
|
183
|
+
| `files_touched` | sorted set of `file_path` (or `notebook_path`) from Edit / Write / Read / MultiEdit / NotebookEdit calls |
|
|
184
|
+
| `commits_in_window` | commits stamped inside `[started, ended]` in the project's git reflog; `null` when `project` is not inside a git repo |
|
|
185
|
+
| `commits` | those commits as `{sha, ts, subject}`, oldest first; `null` when not a repo |
|
|
186
|
+
| `proxy` | the caveat, in the JSON so it travels with the numbers |
|
|
187
|
+
|
|
188
|
+
`commits_in_window` reads `.git/logs/HEAD` directly, not `git log`, because this file
|
|
189
|
+
does not shell out (see privacy). the reflog is the record of what **that working tree**
|
|
190
|
+
did: a commit made there in the window is in it, a commit pulled in from elsewhere is not.
|
|
191
|
+
git expires the reflog after 90 days by default, so a run older than that can read 0 here
|
|
192
|
+
while `git log` would still show its commits. `commit (amend)` counts; a rebase's `pick`
|
|
193
|
+
lines do not. a `.git` file (a worktree) is followed to its gitdir.
|
|
194
|
+
|
|
128
195
|
## why your own gate matters here
|
|
129
196
|
|
|
130
197
|
at fleet scale roughly 95% of the `type: user` records in a transcript are not
|
|
@@ -182,15 +249,15 @@ claim, so here is the grep that settles it against the single file it ships as:
|
|
|
182
249
|
$ grep -nE '^[[:space:]]*(import|from) ' transcripto.py
|
|
183
250
|
8:import sys, os, json, glob, re, sqlite3, argparse
|
|
184
251
|
9:from datetime import datetime, timezone
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
252
|
+
261: import time
|
|
253
|
+
1160: import datetime
|
|
254
|
+
1170: from the separator), so the result is checked on disk and dropped if it is
|
|
188
255
|
```
|
|
189
256
|
|
|
190
257
|
five lines, four of which are imports and all four are stdlib. `time` and
|
|
191
258
|
`datetime` sit inside functions, which is why the pattern allows for indentation —
|
|
192
259
|
anchor it at `^import` and you would miss two, so do not take my word for the
|
|
193
|
-
anchor either. line
|
|
260
|
+
anchor either. line 1170 is the pattern catching a docstring that happens to begin
|
|
194
261
|
with the word `from`; it is prose, not an import, and it is left in rather than
|
|
195
262
|
tuned out, because a grep you tuned until it agreed with you proves nothing.
|
|
196
263
|
|
|
@@ -229,6 +296,7 @@ transcripto sessions recent sessions + the first prompt YOU typed in each
|
|
|
229
296
|
transcripto stats what you actually work on
|
|
230
297
|
transcripto cost what ONE of your decisions costs
|
|
231
298
|
transcripto coach which of YOUR prompt habits survive (a proxy)
|
|
299
|
+
transcripto export-run one run's numbers as JSON (typed turns, correction rate, commits)
|
|
232
300
|
```
|
|
233
301
|
|
|
234
302
|
`ask` is the one that kills "wait, did i lose something?". it answers "what was i
|
|
@@ -289,9 +357,12 @@ just gives the file a name on your PATH.
|
|
|
289
357
|
./test_cost.sh 12 assertions
|
|
290
358
|
./test_small_n.sh 7 assertions
|
|
291
359
|
./test_label_bands.sh 13 assertions
|
|
360
|
+
./test_correction.sh 32 assertions (correction rate + export-run, 2026-09-02)
|
|
361
|
+
./test_cursor_partial.sh 7 assertions
|
|
362
|
+
./test_version.sh 1 assertion (VERSION matches in transcripto.py and pyproject.toml)
|
|
292
363
|
```
|
|
293
364
|
|
|
294
|
-
|
|
365
|
+
91 assertions, all green, re-run 2026-09-02.
|
|
295
366
|
|
|
296
367
|
offline, no keys, on fixtures that inherit the real transcript shape including
|
|
297
368
|
all four ways a non-human record disguises itself as `type: user`.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "transcripto"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.4"
|
|
8
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."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|