cctally 1.99.0 → 1.100.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.
- package/CHANGELOG.md +52 -0
- package/bin/_cctally_dashboard.py +1370 -190
- package/bin/_cctally_dashboard_envelope.py +98 -4
- package/bin/_cctally_dashboard_perf.py +433 -0
- package/bin/_cctally_dashboard_sources.py +450 -56
- package/bin/_cctally_db.py +30 -14
- package/bin/_cctally_doctor.py +1331 -1148
- package/bin/_cctally_parser.py +86 -1
- package/bin/_cctally_quota.py +40 -21
- package/bin/_cctally_record.py +37 -2
- package/bin/_cctally_refresh.py +60 -10
- package/bin/_cctally_statusline.py +53 -7
- package/bin/_cctally_tui.py +335 -30
- package/bin/_cctally_update.py +28 -22
- package/bin/_lib_dashboard_sources.py +26 -7
- package/bin/_lib_doctor.py +37 -0
- package/bin/_lib_jsonl.py +4 -2
- package/bin/_lib_perf.py +132 -3
- package/bin/_lib_source_analytics.py +2 -2
- package/bin/_lib_tick_stats.py +538 -0
- package/bin/cctally +19 -7
- package/dashboard/static/assets/index-B5YfQEtn.css +1 -0
- package/dashboard/static/assets/index-Bt59nMMO.js +97 -0
- package/dashboard/static/dashboard.html +2 -2
- package/package.json +3 -1
- package/dashboard/static/assets/index-Bcbm-DNP.js +0 -97
- package/dashboard/static/assets/index-hJP4wlIO.css +0 -1
package/bin/_cctally_db.py
CHANGED
|
@@ -11084,7 +11084,7 @@ def cmd_db_backup(args: argparse.Namespace) -> int:
|
|
|
11084
11084
|
|
|
11085
11085
|
|
|
11086
11086
|
def cmd_db_checkpoint(args: argparse.Namespace) -> int:
|
|
11087
|
-
"""Fast, non-destructive WAL drain (TRUNCATE checkpoint) for
|
|
11087
|
+
"""Fast, non-destructive WAL drain (TRUNCATE checkpoint) for a WAL store.
|
|
11088
11088
|
|
|
11089
11089
|
Opens a RAW existing-file-only connection — NOT open_cache_db()/open_db(),
|
|
11090
11090
|
which apply schema, run the migration dispatcher, can DELETE Codex rows on a
|
|
@@ -11095,14 +11095,16 @@ def cmd_db_checkpoint(args: argparse.Namespace) -> int:
|
|
|
11095
11095
|
|
|
11096
11096
|
A cache checkpoint takes the same global writer flock as both provider
|
|
11097
11097
|
syncs, using the command's timeout as one bounded wait, so it cannot overlap
|
|
11098
|
-
a cache write or another cache checkpoint.
|
|
11099
|
-
|
|
11100
|
-
|
|
11101
|
-
|
|
11098
|
+
a cache write or another cache checkpoint. A conversations checkpoint takes
|
|
11099
|
+
a THREE-lock plan instead, because that store has two independently writable
|
|
11100
|
+
provider domains rather than cache.db's single global writer flock (#583
|
|
11101
|
+
S4). Exit 0 when drained / already-small / the DB is absent; 3 (staged) if
|
|
11102
|
+
the target stayed busy or was not fully truncated through the timeout — an
|
|
11103
|
+
actionable "something is still holding it" signal.
|
|
11102
11104
|
"""
|
|
11103
11105
|
from _lib_json_envelope import stamp_schema_version
|
|
11104
11106
|
|
|
11105
|
-
which = args.db # "cache" | "stats"
|
|
11107
|
+
which = args.db # "cache" | "conversations" | "stats"
|
|
11106
11108
|
as_json = bool(getattr(args, "json", False))
|
|
11107
11109
|
if which == "stats":
|
|
11108
11110
|
reason = (
|
|
@@ -11120,7 +11122,26 @@ def cmd_db_checkpoint(args: argparse.Namespace) -> int:
|
|
|
11120
11122
|
|
|
11121
11123
|
import _cctally_cache
|
|
11122
11124
|
|
|
11123
|
-
|
|
11125
|
+
if which == "conversations":
|
|
11126
|
+
path, label = _cctally_core.CONVERSATIONS_DB_PATH, "conversations.db"
|
|
11127
|
+
# conversations.db has TWO independently writable provider domains,
|
|
11128
|
+
# unlike cache.db's single global writer flock, so a checkpoint must
|
|
11129
|
+
# exclude both. The order is the documented lock-order law: maintenance
|
|
11130
|
+
# flocks before the conversation provider flocks (Claude, then Codex),
|
|
11131
|
+
# and checkpoint work takes maintenance SHARED — only mutating
|
|
11132
|
+
# maintenance takes it exclusive, and retention's exclusive hold is an
|
|
11133
|
+
# admission gate it downgrades to shared for the mutating pass itself.
|
|
11134
|
+
lock_plan = [
|
|
11135
|
+
(_cctally_core.CONVERSATIONS_LOCK_MAINTENANCE_PATH, fcntl.LOCK_SH),
|
|
11136
|
+
(_cctally_core.CONVERSATIONS_LOCK_PATH, fcntl.LOCK_EX),
|
|
11137
|
+
(_cctally_core.CONVERSATIONS_LOCK_CODEX_PATH, fcntl.LOCK_EX),
|
|
11138
|
+
]
|
|
11139
|
+
else:
|
|
11140
|
+
path, label = _cctally_core.CACHE_DB_PATH, "cache.db"
|
|
11141
|
+
lock_plan = [
|
|
11142
|
+
(_cctally_core.CACHE_LOCK_MAINTENANCE_PATH, fcntl.LOCK_SH),
|
|
11143
|
+
(_cctally_core.CACHE_LOCK_PATH, fcntl.LOCK_EX),
|
|
11144
|
+
]
|
|
11124
11145
|
timeout = int(getattr(args, "busy_timeout_ms", None)
|
|
11125
11146
|
or _cctally_cache.CHECKPOINT_CMD_BUSY_TIMEOUT_MS)
|
|
11126
11147
|
|
|
@@ -11137,16 +11158,11 @@ def cmd_db_checkpoint(args: argparse.Namespace) -> int:
|
|
|
11137
11158
|
print(f"cctally: no {label} database file present; nothing to drain.")
|
|
11138
11159
|
return 0
|
|
11139
11160
|
|
|
11140
|
-
|
|
11141
|
-
|
|
11142
|
-
lock_plan = [
|
|
11143
|
-
(_cctally_core.CACHE_LOCK_MAINTENANCE_PATH, fcntl.LOCK_SH),
|
|
11144
|
-
(_cctally_core.CACHE_LOCK_PATH, fcntl.LOCK_EX),
|
|
11145
|
-
]
|
|
11161
|
+
import _lib_cache_writer_lock
|
|
11146
11162
|
|
|
11147
11163
|
held: list[int] = []
|
|
11148
11164
|
try:
|
|
11149
|
-
acquired = acquire_ordered_flocks(
|
|
11165
|
+
acquired = _lib_cache_writer_lock.acquire_ordered_flocks(
|
|
11150
11166
|
lock_plan, timeout=max(timeout, 0) / 1000
|
|
11151
11167
|
)
|
|
11152
11168
|
if acquired is None:
|