cctally 1.91.0 → 1.92.0

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/bin/_cctally_cache.py +863 -74
  3. package/bin/_cctally_config.py +57 -0
  4. package/bin/_cctally_core.py +39 -8
  5. package/bin/_cctally_dashboard.py +146 -5
  6. package/bin/_cctally_dashboard_conversation.py +164 -18
  7. package/bin/_cctally_dashboard_envelope.py +2 -0
  8. package/bin/_cctally_db.py +372 -10
  9. package/bin/_cctally_doctor.py +18 -1
  10. package/bin/_cctally_journal.py +535 -13
  11. package/bin/_cctally_journal_repair.py +6 -0
  12. package/bin/_cctally_parser.py +6 -0
  13. package/bin/_cctally_quota.py +171 -55
  14. package/bin/_cctally_record.py +13 -1
  15. package/bin/_cctally_rederive.py +4 -0
  16. package/bin/_cctally_store.py +311 -6
  17. package/bin/_cctally_transcript.py +32 -2
  18. package/bin/_lib_cache_report.py +8 -3
  19. package/bin/_lib_codex_conversation.py +851 -81
  20. package/bin/_lib_codex_conversation_query.py +2005 -95
  21. package/bin/_lib_codex_find_projection.py +370 -0
  22. package/bin/_lib_codex_harness_preamble.py +176 -0
  23. package/bin/_lib_codex_hooks.py +5 -3
  24. package/bin/_lib_codex_js_scan.py +254 -0
  25. package/bin/_lib_codex_landmarks.py +309 -0
  26. package/bin/_lib_codex_title_clean.py +116 -0
  27. package/bin/_lib_conversation_dispatch.py +153 -21
  28. package/bin/_lib_conversation_watch.py +4 -2
  29. package/bin/_lib_doctor.py +64 -0
  30. package/bin/_lib_quota_alert_axes.py +31 -34
  31. package/bin/_lib_stats_damage.py +523 -0
  32. package/bin/cctally +5 -0
  33. package/dashboard/static/assets/index-BEzzJtUd.js +97 -0
  34. package/dashboard/static/assets/{index-Dwirao3Y.css → index-DnWdv8um.css} +1 -1
  35. package/dashboard/static/dashboard.html +2 -2
  36. package/package.json +7 -1
  37. package/dashboard/static/assets/index-CILAoEja.js +0 -90
package/CHANGELOG.md CHANGED
@@ -5,6 +5,45 @@ based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [1.92.0] - 2026-08-05
9
+
10
+ ### Added
11
+ - Add per-run bearer authentication for non-loopback dashboards, with fragment-to-HttpOnly-cookie browser bootstrap and a restart-only Settings/CLI opt-out (#282).
12
+ - Add account-scoped conversation browsing, search, reading, export, and permalinks to the dashboard and `cctally transcript`, while preserving the existing all-account and single-account output shapes (#347).
13
+
14
+ ### Changed
15
+ - Long Codex conversations now open with two concurrent data requests instead of issuing a third detail request just to repeat totals already available from the outline. On the same 3,733-row conversation, the first painted row improved from 784 ms to 421–429 ms while live-tail streaming remained connected (#477).
16
+ - A Codex tool result in the conversation reader no longer opens with the harness's own `Script completed` / `Wall time` / `Output:` boilerplate, and a call that failed is now identified as failed rather than shown with no outcome at all. Roughly 50,000 results in a real store lose three to five lines of boilerplate, and 82.4% now resolve to a real completed, failed or still-running state. Every Codex tool call now ends with an explicit **ok**, **error**, **running** or **outcome unknown**, and a failing call finally matches the reader's Errors filter, which previously matched no Codex call at all. Four more tool families became legible instead of raw: an `exec` call whose body is a JavaScript program, and every `js` call, show the invocations the reader could decode — and say so when the body also contains statements it could not read, so the list is never presented as the whole program; `write_stdin` and `wait` show which shell session they wrote to or which sandbox cell they polled; and `tool_search_call` shows its query. A patch event now shows a per-file diff, including for added and deleted files, which the provider retains as content but never transmits as a diff — those are labelled as rendered from retained content rather than passed off as provider-supplied, and a file whose diff was clipped to nothing says a diff exists and none of it fit rather than claiming none was retained. A conversation's shell sessions are numbered and grouped: each call shows which session it belongs to, a run that stays in one session names it, and the call that opened a session is marked as the one that started it, identified from that call's own output. Where the retained data does not identify an opener the reader says so, and where the session list itself was capped it says that instead, so nothing is reported as absent when it was merely not loaded. Session numbers are conversation-local and the provider's own session identifier is never shown. Finally, an assistant message carrying a serialized external-agent marker renders as a labelled disclosure naming the tool with its input behind it, instead of printing the raw marker mid-prose. An `apply_patch` call now shows the diff it is holding: the card decodes the patch text it already carries into a per-file diff, so a call no longer reports "no diffs" and "no diff retained" over a patch it is holding, and it no longer contradicts the matching patch-applied event elsewhere in the same conversation. A change that genuinely carries no line-level diff now says only that, rather than making a claim about what the provider retained. The exit code and running time behind an outcome are now shown in the expanded card as well as its tooltip, on every card family that shows an outcome, so they are reachable on a phone. A `write_stdin` row and a terminal row with collapsed output both keep a readable command preview at phone width instead of being squeezed to a couple of characters. Exported transcripts are unchanged (#463).
17
+ - The Codex conversation outline now offers landmarks proportional to the work a conversation did, so a real failure is reachable from the navigation chrome without a text search. Alongside the existing per-turn spine, the outline lists each authored reasoning heading, each failing tool call and each plan call as its own row, indented under the turn it belongs to; clicking one loads the part of the turn that holds it rather than the top of a turn that may run to 142 calls. On the heaviest conversation in a real store that is 424 landmarks where there were none. The outline's stats card starts reporting Codex's real models, tools, duration and errors instead of leaving four rows blank, and where the conversation's retained evidence cannot say whether anything failed it now says "not reported" rather than showing a confident zero — the comparison strip does the same. The Files tab lists each file a patch touched with its per-file `+N −M`, and a file row now jumps to the change that touched it; a count that cannot be determined is left blank rather than understated. Conversation titles stop showing the harness's own markup — a skill invocation's private filesystem path, a slash-command wrapper — on every surface that renders one, including `cctally transcript search --source codex --kind title`. A tool call that reported an error status is now treated as failed by the reader's Errors filter and badge, matching what the server reports. Clicking a landmark scrolls to the individual call or heading it names rather than to the segment containing it, which on a real conversation moved the failing call from as much as 6,574 pixels below the fold to the top of the window. The stats card's error line now reads "11 errors in 2 turns" for Codex as it already did for Claude, instead of reporting the same number twice; the jump chip beside it counts error turns, not failing calls; and repeated plan rows are numbered so four of them are told apart. A conversation title whose prompt text was written straight against the end of a skill link is cleaned too, which it was not before (#463).
18
+
19
+ ### Fixed
20
+ - Conversation Viewer outline pins now stay truthful after restoring a saved position inside a tall turn and after jumping to a cache rebuild on a sidechain member: an unaligned inner failure is no longer marked, and an available enclosing prompt or subagent row remains current instead (#492).
21
+ - Codex spend and quota ingest no longer freeze after the first append to a tracked rollout when a large history begins with legacy record envelopes (#502).
22
+ - Stats damage characterization now detects a table or index whose root page holds the wrong kind of b-tree page. The previous check accepted any valid page type, so the damage shape that actually occurs — a table rooted at an index leaf — was reported as healthy (#496).
23
+ - A detached Codex quota verification can no longer make the following hook tick acknowledge success without evaluating its budget alerts. If the verifier still owns the stats ingest lock, the tick remains due and retries as soon as that lock is released (#461).
24
+ - Cache Report no longer warns that net cache spend is negative when savings and write costs cancel to an effectively zero floating-point residue (#471).
25
+ - Fix `cctally setup` npm installs repeatedly adding duplicate Codex Stop/SubagentStop hooks instead of reconciling them (#458).
26
+ - Cache Report charts now announce one consistent window size to screen readers and identify unobserved days as a measured subset (#469).
27
+ - Codex quota rows restored from the journal or repaired during migration now invalidate cached dashboard and projection state immediately, instead of waiting for an unrelated later Codex mutation (#457).
28
+ - Codex file-path search now indexes the dict-shaped patch events the provider actually records, and upgrades backfill retained history so existing conversations become searchable by touched file (#489).
29
+ - A stats index rebuild that publishes a damaged index now reports failure instead of printing a success line, and the next command refuses that index rather than silently accepting it. A corruption incident now retains substantially more evidence about itself — why the rebuild ran, the write-ahead log bytes present when the damage was found, a structured description of what was damaged, and whether the published replacement passed validation — so a recurring fault can be told apart from a one-off. Internal (maintainer-only): a correlator classifies the existing incident corpus as far as retained evidence allows and reports the remainder as unknown (#496).
30
+ - A conversation's injected-context rows are readable on a phone. Labels such as "SESSION CONTEXT" and "AGENT MODE", and the section list beside them, were being broken apart mid-word — one or two characters per line — and they now wrap at spaces like ordinary text. The whole summary row is protected rather than one kind of row, so a row type added later cannot come back broken (#463, #493).
31
+ - A file path, a relative path or a custom link target in conversation text is no longer rendered as a working link or image. Those targets could not lead anywhere useful, and the browser was quietly requesting some of them from the dashboard; they now appear as plain text with no destination stored anywhere in the page. Web and email links are unaffected. This applies to both Claude and Codex conversations (#463, #484).
32
+ - Codex and Claude each have one colour across the whole app. The same blue previously meant Claude on the dashboard's source chips and Codex in the conversation viewer, so the colour could not be used to tell them apart. Codex now uses its own brand green and Claude uses purple everywhere, including the provider pills in the Forecast, Trend and Source Detail views. Colours that indicate a state rather than a provider are unchanged (#463).
33
+ - Opening a conversation link now selects the matching source tab and highlights the conversation's row in the list, including when a search or filter was left active that would otherwise have hidden it, and the browser's Back button returns to where you were instead of to an intermediate list view. Going Back or Forward keeps the search and filters you had set, rather than clearing them as following a fresh link does. Opening one side of a comparison in the reader moves the list to that side's source the same way. Opening a parent or child thread, or a subagent's child conversation, now stays within the account you were viewing (#463).
34
+ - The Conversation Viewer now preserves Claude tool names and request/result details on qualified links, keeps terminal copy controls clear of long working directories at phone width, and uses the same **ok**, **error**, **running**, and **outcome unknown** wording across Codex web, MCP, and subagent cards (#488).
35
+ - Qualified Claude conversation links now retain error, subagent, plan, compaction, file, and cache-rebuild navigation, while one-segment Codex links open under the Codex source instead of Claude (#491).
36
+ - MCP tools that report a protocol-level error inside a successful Codex transport response now appear as failed in conversation cards, the Errors filter and count, and outline landmarks instead of being shown as successful (#494).
37
+ - Stepping through Codex landmarks in the conversation viewer now moves. After a jump to a failing call or a plan call, pressing `e`/`E` or shift-clicking the jump chip re-found the first landmark forever going forward and reported no landmark at all going backward, because the position the jump left behind was not one the stepping cursor could read. The keyboard now also lands on the individual call or heading a landmark names, as clicking the same landmark in the rail already did, and the rail's highlight follows whichever of the three — rail row, chip, keyboard — issued the jump. A failing tool result that the reader shows on its own can now be jumped to at all: it carried no address in the page, so a jump aimed at it landed at the top of the surrounding block. That same result is now also shown as failed instead of as though it had succeeded, and one whose output was clipped says so. A patch the provider reported as errored counts as a failure too — only the word "failed" did before, so a patch reporting "error" was counted by the Errors badge and then hidden by the Errors filter. An MCP tool call and a subagent now decide what a failure is the same way the rest of the reader does. For MCP that closes a hole nobody could have reached, because a Codex MCP call has only ever reported "ok" or "error" and the card already recognised "error". For subagents it is a real if uncommon fix: a subagent run reporting "failed" was shown with the neutral marker rather than the error marker, so those runs now read as errors and reach the Errors filter and badge. Clicking a cache-rebuild row clears a focus filter that would hide the turn it lands on, in the session detail modal as well as in the outline; only the outline copy did that before. The stats card says "3 errors in 1 turn" rather than "in 1 turns". The Errors filter's own count badge now agrees with the jump chip beside it: on a Codex conversation whose failures cluster in a few turns it read the number of failing calls — 27 next to a chip reading 14 — and it now reads the number of error turns at every width (#463).
38
+ - Dashboard conversation source controls and provider context now render their intended borders and active surface, stale source status keeps its outline, and Codex reasoning uses the dashboard prose typeface instead of falling back to the browser default (#481).
39
+ - Codex conversation search now shows readable retained tool output instead of serialized `[{"text": ...}]` content wrappers, including a safe best-effort excerpt when a retained array was clipped mid-value. Opening the Codex conversation list and its filter facets now reads materialized conversation rollups in set-based pages rather than rebuilding and pricing every conversation one at a time; on a production-shaped 1,668-conversation store the warm 50-row browse fell from 6,694 SQL reads / 1.334 seconds to 8 reads / 0.162 seconds with a byte-identical response (#438).
40
+ - Find in a Codex conversation now counts and reaches every visible match instead of counting only the messages or reading units that contain one. Repeated matches inside the same formatted message, command, output, reasoning disclosure, or folded patch/web/MCP result each get their own navigation stop; next and previous cross the complete result set without skipping the short first page. Regex and case-sensitive modes keep their existing meaning, live updates preserve the selected match when it still exists, and a removed match is announced explicitly. Claude find behavior is unchanged (#482).
41
+ - Conversation deep links now finish only after the requested message is mounted and stably aligned at its start. Deferred virtualizer height corrections no longer leave a tall target thousands of pixels above the viewport, and a target that cannot be retained in view now produces a visible failure instead of silently clearing the jump (#479).
42
+ - Pressing `h` or `H` in a long Codex conversation now reliably reaches the adjacent reasoning heading even when that heading's row is unmounted behind a very large turn. A failed hop keeps the existing heading marked instead of clearing it, and headings on collapsed subagent bucket roots now open and land like other subagent headings (#486).
43
+ - A failed Conversation Viewer page request during a deep-link or find jump now retries with bounded backoff and then shows a connection error, instead of spinning forever until the tab or test worker runs out of memory. A transient failure still recovers and continues the jump (#480).
44
+ - A missing, empty, unrecognized, or temporarily unmounted `$CODEX_HOME` no longer causes an ordinary sync or rebuild to erase retained Codex accounting and conversation history. Orphan pruning now requires positive evidence from each configured root, still removes genuinely deleted rollout files and deliberately deconfigured roots, and reports every safety refusal through `cctally doctor` (#485).
45
+ - Codex quota alerts no longer leave a future-clocked capture unevaluated forever when its window goes quiet. The scheduled boundary now remembers which Codex root owns it, so the first hook tick after it matures re-evaluates only that root, retires the boundary, and keeps the next quiet tick fast without scanning unrelated quota history (#460).
46
+
8
47
  ## [1.91.0] - 2026-08-03
9
48
 
10
49
  ### Added