@ascenda-one/history-import 0.1.24 → 0.1.26
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.
- package/README.md +107 -3
- package/dist/cli.js +497 -161
- package/dist/daySlice.js +15 -2
- package/dist/daySlice.js.map +1 -1
- package/dist/extractors/claudeCode.js +149 -29
- package/dist/extractors/claudeCode.js.map +1 -1
- package/dist/interruptedRuns.js +23 -0
- package/dist/interruptedRuns.js.map +1 -1
- package/dist/localHandoff.js +9 -3
- package/dist/localHandoff.js.map +1 -1
- package/dist/promptLedger.js +513 -0
- package/dist/promptLedger.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -152,6 +152,47 @@ line that closes the turn. The rule is in
|
|
|
152
152
|
[`src/interruptedRuns.ts`](./src/interruptedRuns.ts), and the desktop app's
|
|
153
153
|
importer counts by the same one.
|
|
154
154
|
|
|
155
|
+
A cut counts in the session you pressed Escape in, and in no other. Resuming
|
|
156
|
+
a session copies the history it inherits, markers included, so before this
|
|
157
|
+
rule every resume in a lineage reported its ancestors' interruptions as
|
|
158
|
+
well — a fifth of the counted total on the store this was measured against.
|
|
159
|
+
The same ownership rule as the minutes (`minutesBasis: owned_lines`).
|
|
160
|
+
|
|
161
|
+
### When two files both say a line is theirs
|
|
162
|
+
|
|
163
|
+
Most copies keep the session id the line was written with, which is how the
|
|
164
|
+
import tells a copy from the real thing. Some rewrite it to the file the copy
|
|
165
|
+
now sits in, keeping the line's own id and its original timestamp — so the
|
|
166
|
+
test that settles every other copy answers "written here" in both places, and
|
|
167
|
+
both sessions counted the line. Nothing on the line says which of the two
|
|
168
|
+
wrote it: the two records are identical apart from the fields the copy
|
|
169
|
+
rewrote.
|
|
170
|
+
|
|
171
|
+
Where the line sits is what settles it. A line two files claim is contested.
|
|
172
|
+
Inside a file, the run of contested lines at the top is the history it
|
|
173
|
+
inherited, and it ends at the first line that file claims and nobody else
|
|
174
|
+
does — from there on, what it holds it wrote. So a contested line belongs to
|
|
175
|
+
the file still holding it after its own history has started.
|
|
176
|
+
|
|
177
|
+
Not simply the first file the import reaches, which would be the easy rule and
|
|
178
|
+
the wrong one: on the store this was measured against it would hand two fifths
|
|
179
|
+
of these lines to the copy instead, which is the error this whole rule exists
|
|
180
|
+
to remove.
|
|
181
|
+
|
|
182
|
+
**What that leaves.** A lineage whose earliest file the 30-day cleanup has
|
|
183
|
+
already taken has no file that wrote those lines — every one still holding
|
|
184
|
+
them holds them in its inherited head, and nothing left on disk says which
|
|
185
|
+
session did the work. The line is still counted once, by the first file the
|
|
186
|
+
import reaches, the same answer any orphaned line gets. The total is right and
|
|
187
|
+
the session it lands on is a guess. That was 16.1% of contested lines here.
|
|
188
|
+
|
|
189
|
+
Sizes, on the same store: 3.7% of the lines claiming their own file were
|
|
190
|
+
claimed by two of them, and counting each once takes 3.9% off the summed
|
|
191
|
+
active minutes. **Your week doesn't move** — the union of your active time
|
|
192
|
+
holds to a minute, because a line counted twice was one minute counted twice.
|
|
193
|
+
Hands-on shifts a little more than that: a span changes sides when the lines
|
|
194
|
+
around it move, so the unioned hands-on figure moved by 19 minutes in 6,734.
|
|
195
|
+
|
|
155
196
|
### What counts as a prompt
|
|
156
197
|
|
|
157
198
|
`promptCount` on a Claude Code session counts the prompts you typed. Claude
|
|
@@ -170,9 +211,6 @@ Code also writes `user` lines on your behalf, and none of these count:
|
|
|
170
211
|
variant.
|
|
171
212
|
|
|
172
213
|
Each session carries `syntheticPromptLines`, the number of lines it left out.
|
|
173
|
-
The handoff stamps `promptBasis: "typed"`. A handoff without the stamp counted
|
|
174
|
-
every `user` line that wasn't a tool result, so its prompt counts run higher for
|
|
175
|
-
the same week. The schema number doesn't move.
|
|
176
214
|
|
|
177
215
|
These lines aren't you, and they aren't the agent, so they don't start or end a
|
|
178
216
|
hands-on span. Prompt events, after-hours prompts and quick re-prompts all
|
|
@@ -180,6 +218,72 @@ follow the same count. The desktop app's importer declines the same lines; the
|
|
|
180
218
|
test is `isTypedPromptLine` in
|
|
181
219
|
[`src/interruptedRuns.ts`](./src/interruptedRuns.ts).
|
|
182
220
|
|
|
221
|
+
Two more rules need the whole store, so the extractor reads every transcript
|
|
222
|
+
once before it folds any session ([`src/promptLedger.ts`](./src/promptLedger.ts)):
|
|
223
|
+
|
|
224
|
+
- **Each line belongs to one session.** Resuming or forking a session writes a
|
|
225
|
+
new transcript that copies the history it inherited, line ids and timestamps
|
|
226
|
+
included. Each copy has one owner: the transcript the line's `sessionId`
|
|
227
|
+
names, or, where the purge took that file, the first in the walk's sorted
|
|
228
|
+
order. The owner counts the prompt, and the owner's timeline carries the
|
|
229
|
+
instant — so `activeMinutes`, the hands-on split, the day slices and
|
|
230
|
+
`startedAt` describe the session you resumed rather than everything behind
|
|
231
|
+
it. Two files can both name themselves on one line, which "When two files
|
|
232
|
+
both say a line is theirs" above settles. A line with no id is counted
|
|
233
|
+
wherever it appears; on the reference store that's `queue-operation` lines
|
|
234
|
+
and nothing else.
|
|
235
|
+
- **A chip's prompt isn't typed.** A session launched from a `spawn_task` chip
|
|
236
|
+
opens on the chip's prompt. When a line's text, wrappers stripped, matches a
|
|
237
|
+
chip that some session in the store offered, it counts in
|
|
238
|
+
`dispatchedPromptLines`, not `promptCount`. The agent still runs on it, so an
|
|
239
|
+
interrupt during that first turn is still a cut-short run. Only hashes of
|
|
240
|
+
chip prompts are kept, and only for the run. If the store's cleanup has
|
|
241
|
+
already removed the session that offered the chip, there's nothing to match
|
|
242
|
+
and the opener counts as typed.
|
|
243
|
+
|
|
244
|
+
The handoff stamps `promptBasis: "typed_once"`. `"typed"` means the rules above
|
|
245
|
+
the list, with every resumed copy counted again and chip prompts counted as
|
|
246
|
+
typed. A handoff without the stamp counted every `user` line that wasn't a tool
|
|
247
|
+
result. Prompt counts for the same week run highest under that rule and lowest
|
|
248
|
+
under `typed_once`. The schema number doesn't move.
|
|
249
|
+
|
|
250
|
+
Beside it, `minutesBasis: "owned_lines"` says the minutes were cut the same
|
|
251
|
+
way. `"every_line"` — and an absent stamp — means a transcript's whole
|
|
252
|
+
contents counted there, inherited history included. Gate on this before
|
|
253
|
+
comparing minutes across two handoffs: a store's figures drop when it changes,
|
|
254
|
+
and nothing else in the file says so.
|
|
255
|
+
|
|
256
|
+
### How much history a resume carries
|
|
257
|
+
|
|
258
|
+
Enough to matter, which is why the rule above covers the minutes and not only
|
|
259
|
+
the counts. On one real store of 984 transcripts, 151 carried inherited lines:
|
|
260
|
+
275,801 of them, 29% of every dated line in the store. They held the whole of
|
|
261
|
+
the gap between what the sessions claimed and what the clock allowed. Both
|
|
262
|
+
columns are the same 983 sessions, read from one snapshot:
|
|
263
|
+
|
|
264
|
+
| | Every line | Owned lines |
|
|
265
|
+
|---|---|---|
|
|
266
|
+
| Summed active minutes | 70,212 | 53,600 |
|
|
267
|
+
| Summed hands-on minutes | 12,238 | 8,006 |
|
|
268
|
+
| Union of every active interval | 25,078 | 25,077 |
|
|
269
|
+
| Exact-duplicate spans | 262,500 of 873,599 | 21,982 of 635,126 |
|
|
270
|
+
| Sessions apparently spanning over a day | 158 | 154 |
|
|
271
|
+
|
|
272
|
+
The union is the control. It holds to the minute, so no work anyone did was
|
|
273
|
+
dropped: what went was the copy of it. Duplicate spans fell from 30% of the
|
|
274
|
+
store to 3.5%, which matters to any count of how many agents were running at
|
|
275
|
+
once, since a duplicate reads as a second agent. 127 sessions now start when
|
|
276
|
+
they were resumed, 13 of them more than an hour later than they used to.
|
|
277
|
+
|
|
278
|
+
That 3.5% was not the floor, and it was not coincidence: four fifths of it was
|
|
279
|
+
the copy path settled above. On a later and slightly larger snapshot of the
|
|
280
|
+
same store, the duplicate spans go from 21,982 to 4,087 once contested lines
|
|
281
|
+
are settled.
|
|
282
|
+
|
|
283
|
+
An earlier reading of this exposure put it at 0.72% of sessions. It counted
|
|
284
|
+
repeated `sessionRef`s, and a resumed transcript carries a fresh one, so it saw
|
|
285
|
+
three sessions where 151 transcripts were affected.
|
|
286
|
+
|
|
183
287
|
### Autonomy bands
|
|
184
288
|
|
|
185
289
|
`permissionMode` is on the transcript's human-prompt lines and nowhere else —
|