cctally 1.80.3 → 1.80.4
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/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,11 @@ based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [1.80.4] - 2026-07-23
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- Codex Recent Sessions now keeps MCP-invoked sessions in true last-activity order and derives each Started time and duration from retained accounting events, so a cache rebuild no longer gives historical conversations one shared date or `0m` durations.
|
|
12
|
+
|
|
8
13
|
## [1.80.3] - 2026-07-23
|
|
9
14
|
|
|
10
15
|
### Fixed
|
|
@@ -757,12 +757,19 @@ def _codex_conversation_metadata(
|
|
|
757
757
|
metadata: dict[tuple[str, str], dict[str, object]] = {}
|
|
758
758
|
try:
|
|
759
759
|
core_rows = tuple(cache_conn.execute(
|
|
760
|
+
"WITH accounting AS ("
|
|
761
|
+
" SELECT source_root_key, source_path, MIN(id) AS first_id,"
|
|
762
|
+
" MIN(timestamp_utc) AS started_at"
|
|
763
|
+
" FROM codex_session_entries"
|
|
764
|
+
" GROUP BY source_root_key, source_path"
|
|
765
|
+
") "
|
|
760
766
|
"SELECT t.source_root_key, t.source_path, t.native_thread_id, "
|
|
761
|
-
"
|
|
762
|
-
"
|
|
763
|
-
" ORDER BY e.id LIMIT 1) AS accounting_session_id, "
|
|
764
|
-
"t.cwd, t.git_json, t.first_seen_utc, t.last_seen_utc "
|
|
767
|
+
"e.session_id AS accounting_session_id, "
|
|
768
|
+
"t.cwd, t.git_json, a.started_at, t.last_seen_utc "
|
|
765
769
|
"FROM codex_conversation_threads AS t "
|
|
770
|
+
"LEFT JOIN accounting AS a "
|
|
771
|
+
"ON a.source_root_key=t.source_root_key AND a.source_path=t.source_path "
|
|
772
|
+
"LEFT JOIN codex_session_entries AS e ON e.id=a.first_id "
|
|
766
773
|
"ORDER BY t.last_seen_utc DESC, t.conversation_key DESC"
|
|
767
774
|
))
|
|
768
775
|
from _cctally_cache import _codex_conversation_project_attribution
|
|
@@ -778,16 +785,20 @@ def _codex_conversation_metadata(
|
|
|
778
785
|
) in core_rows
|
|
779
786
|
)
|
|
780
787
|
file_aliases = tuple(cache_conn.execute(
|
|
781
|
-
"SELECT source_root_key, path, last_native_thread_id,
|
|
782
|
-
"
|
|
783
|
-
"
|
|
784
|
-
"
|
|
788
|
+
"SELECT f.source_root_key, f.path, f.last_native_thread_id, "
|
|
789
|
+
"f.last_session_id, MIN(e.timestamp_utc) "
|
|
790
|
+
"FROM codex_session_files AS f "
|
|
791
|
+
"LEFT JOIN codex_session_entries AS e "
|
|
792
|
+
"ON e.source_root_key=f.source_root_key AND e.source_path=f.path "
|
|
793
|
+
"WHERE f.last_native_thread_id IS NOT NULL AND f.last_native_thread_id != '' "
|
|
794
|
+
"GROUP BY f.source_root_key, f.path, f.last_native_thread_id, f.last_session_id "
|
|
795
|
+
"ORDER BY f.last_ingested_at DESC, f.path DESC"
|
|
785
796
|
))
|
|
786
797
|
native_ids = tuple(sorted({
|
|
787
798
|
str(native_thread_id) for _, _, native_thread_id, *_ in rows
|
|
788
799
|
if isinstance(native_thread_id, str) and native_thread_id
|
|
789
800
|
} | {
|
|
790
|
-
str(native_thread_id) for _, _, native_thread_id, _ in file_aliases
|
|
801
|
+
str(native_thread_id) for _, _, native_thread_id, *_ in file_aliases
|
|
791
802
|
if isinstance(native_thread_id, str) and native_thread_id
|
|
792
803
|
}))
|
|
793
804
|
provider_roots = {
|
|
@@ -858,7 +869,10 @@ def _codex_conversation_metadata(
|
|
|
858
869
|
# persists the rooted native thread id. Inherit only presentation
|
|
859
870
|
# metadata from that rooted task; the child's accounting path and
|
|
860
871
|
# session id remain its own identity and totals are never merged.
|
|
861
|
-
for
|
|
872
|
+
for (
|
|
873
|
+
root_key, source_path, native_thread_id, accounting_session_id,
|
|
874
|
+
started_at,
|
|
875
|
+
) in file_aliases:
|
|
862
876
|
identity = (str(root_key or ""), str(source_path or ""))
|
|
863
877
|
if not all(identity) or identity in metadata:
|
|
864
878
|
continue
|
|
@@ -871,7 +885,7 @@ def _codex_conversation_metadata(
|
|
|
871
885
|
"root_path": str(provider_roots.get(identity[0]) or ""),
|
|
872
886
|
"project_key": (inherited or {}).get("project_key"),
|
|
873
887
|
"project_label": (inherited or {}).get("project_label"),
|
|
874
|
-
"started_at": (inherited or {}).get("started_at"),
|
|
888
|
+
"started_at": started_at or (inherited or {}).get("started_at"),
|
|
875
889
|
}
|
|
876
890
|
except sqlite3.Error:
|
|
877
891
|
return {}
|