cctally 1.71.0 → 1.73.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 +20 -0
- package/bin/_cctally_cache.py +501 -49
- package/bin/_cctally_core.py +20 -40
- package/bin/_cctally_dashboard_conversation.py +731 -94
- package/bin/_cctally_db.py +286 -1
- package/bin/_cctally_doctor.py +59 -0
- package/bin/_cctally_parser.py +17 -4
- package/bin/_cctally_record.py +162 -33
- package/bin/_cctally_refresh.py +58 -36
- package/bin/_cctally_statusline.py +811 -82
- package/bin/_cctally_transcript.py +223 -7
- package/bin/_lib_codex_conversation.py +509 -0
- package/bin/_lib_codex_conversation_export.py +124 -0
- package/bin/_lib_codex_conversation_query.py +1422 -0
- package/bin/_lib_codex_conversation_watch.py +323 -0
- package/bin/_lib_conversation_dispatch.py +809 -0
- package/bin/_lib_conversation_query.py +88 -0
- package/bin/_lib_conversation_retention.py +344 -0
- package/bin/_lib_doctor.py +62 -0
- package/bin/_lib_statusline_candidates.py +734 -0
- package/bin/cctally +31 -2
- package/package.json +8 -1
package/bin/_cctally_core.py
CHANGED
|
@@ -67,6 +67,9 @@ def _init_paths_from_env() -> None:
|
|
|
67
67
|
global HOOK_TICK_LOG_DIR, HOOK_TICK_LOG_PATH, HOOK_TICK_LOG_ROTATED_PATH
|
|
68
68
|
global HOOK_TICK_THROTTLE_PATH, HOOK_TICK_THROTTLE_LOCK_PATH
|
|
69
69
|
global STATUSLINE_OBSERVE_MARKER_PATH, STATUSLINE_PERSIST_LOCK_PATH
|
|
70
|
+
global STATUSLINE_CANDIDATE_DIR, STATUSLINE_SELECTED_PATH
|
|
71
|
+
global STATUSLINE_TRANSPORT_MARKER_PATH
|
|
72
|
+
global STATUSLINE_AUTHORITATIVE_7D_PATH, STATUSLINE_AUTHORITATIVE_5H_PATH
|
|
70
73
|
global OAUTH_BACKOFF_MARKER_PATH, OAUTH_BACKOFF_COUNT_PATH
|
|
71
74
|
global UPDATE_STATE_PATH, UPDATE_SUPPRESS_PATH
|
|
72
75
|
global UPDATE_LOCK_PATH, UPDATE_LOG_PATH, UPDATE_LOG_ROTATED_PATH
|
|
@@ -126,25 +129,17 @@ def _init_paths_from_env() -> None:
|
|
|
126
129
|
HOOK_TICK_THROTTLE_PATH = APP_DIR / "hook-tick.last-fetch"
|
|
127
130
|
HOOK_TICK_THROTTLE_LOCK_PATH = APP_DIR / "hook-tick.last-fetch.lock"
|
|
128
131
|
|
|
129
|
-
# Statusline
|
|
130
|
-
#
|
|
131
|
-
#
|
|
132
|
-
#
|
|
133
|
-
# like HOOK_TICK_THROTTLE_PATH) — touched after every statusline
|
|
134
|
-
# persist that fed valid 7d input through cmd_record_usage, INCLUDING
|
|
135
|
-
# a dedup no-op. Represents "the statusline is alive and feeding".
|
|
136
|
-
# The statusline persist throttle AND the OAuth backfill gate both
|
|
137
|
-
# key off this, NOT snapshot age (cmd_record_usage dedups unchanged
|
|
138
|
-
# percentages without refreshing captured_at, so snapshot age keeps
|
|
139
|
-
# growing while the statusline is actively feeding).
|
|
140
|
-
# - STATUSLINE_PERSIST_LOCK_PATH: cross-process flock serializing the
|
|
141
|
-
# detached persist feeder so a multi-session render herd yields at
|
|
142
|
-
# most one snapshot per throttle window.
|
|
143
|
-
# - OAUTH_BACKOFF_MARKER_PATH: shared 429 cooldown. Stores an ABSOLUTE
|
|
144
|
-
# epoch deadline in the file CONTENT (never the mtime — future-dating
|
|
145
|
-
# an mtime would corrupt HOOK_TICK_THROTTLE_PATH's age reading).
|
|
132
|
+
# Statusline candidate arbitration (#318). The spool and derived selected
|
|
133
|
+
# state are entirely APP_DIR-derived so dev/data-dir redirection remains
|
|
134
|
+
# complete. The observation marker now means selected/authoritative
|
|
135
|
+
# freshness; transport liveness has its own marker.
|
|
146
136
|
STATUSLINE_OBSERVE_MARKER_PATH = APP_DIR / "statusline-observe.last"
|
|
147
137
|
STATUSLINE_PERSIST_LOCK_PATH = APP_DIR / "statusline-persist.lock"
|
|
138
|
+
STATUSLINE_CANDIDATE_DIR = APP_DIR / "statusline-candidates"
|
|
139
|
+
STATUSLINE_SELECTED_PATH = APP_DIR / "statusline-selected.json"
|
|
140
|
+
STATUSLINE_TRANSPORT_MARKER_PATH = APP_DIR / "statusline-transport.last"
|
|
141
|
+
STATUSLINE_AUTHORITATIVE_7D_PATH = APP_DIR / "statusline-authoritative-7d.json"
|
|
142
|
+
STATUSLINE_AUTHORITATIVE_5H_PATH = APP_DIR / "statusline-authoritative-5h.json"
|
|
148
143
|
OAUTH_BACKOFF_MARKER_PATH = APP_DIR / "oauth-backoff.until"
|
|
149
144
|
# Consecutive-429 counter (text int) driving the headerless exponential
|
|
150
145
|
# backoff (base * 2**count). Separate from the deadline marker so the
|
|
@@ -246,38 +241,23 @@ def _real_prod_data_dir() -> pathlib.Path:
|
|
|
246
241
|
# Internal (no config UI — YAGNI, spec §Out of scope); test injection only.
|
|
247
242
|
# Spec 2026-07-17-usage-statusline-fallback-design.
|
|
248
243
|
#
|
|
249
|
-
# STATUSLINE_PERSIST_THROTTLE_SECONDS: min seconds between statusline
|
|
250
|
-
# persist attempts (keyed off STATUSLINE_OBSERVE_MARKER_PATH liveness).
|
|
251
|
-
# Retuned 60.0 -> 25.0 for #311: the setup-managed statusLine.refreshInterval
|
|
252
|
-
# timer fires the statusline on a 30s cadence, and the throttle MUST be
|
|
253
|
-
# strictly LESS than that interval. When interval <= throttle, phase jitter
|
|
254
|
-
# produces beat-frequency skips (a tick at 59.9s of marker age is throttled;
|
|
255
|
-
# the next persist waits ~120s), so a 60/60 pairing oscillates 60<->120s.
|
|
256
|
-
# With interval 30 > throttle 25, every tick whose predecessor's record
|
|
257
|
-
# completed promptly (within interval - throttle = 5s) passes the gate.
|
|
258
|
-
# CADENCE QUALIFIER: the marker is touched at persist COMPLETION, so a tick
|
|
259
|
-
# observes marker age = 30 - d where d is the previous record's duration;
|
|
260
|
-
# if d > 5s (the record kernel can run cmd_sync_week JSONL scans) that tick
|
|
261
|
-
# throttles and the cycle degrades to skip-one-tick (~60s), self-correcting
|
|
262
|
-
# on the next tick. Exact-30s is NOT an invariant (no attempt-start marker
|
|
263
|
-
# exists — one would let a hung/failed record claim liveness and suppress
|
|
264
|
-
# the OAuth backfill). Still strictly better than the 60/60 beat's 60-120s.
|
|
265
244
|
# OAUTH_BACKFILL_STALE_SECONDS: the OAuth poll only backfills once the
|
|
266
|
-
#
|
|
267
|
-
#
|
|
268
|
-
# statusline is the primary writer and OAuth only covers its absence
|
|
269
|
-
# (300 > 25 still holds).
|
|
245
|
+
# selected-freshness marker is at least this stale. The 30-second statusline
|
|
246
|
+
# transport tick does not run OAuth.
|
|
270
247
|
# OAUTH_BACKOFF_BASE_SECONDS / OAUTH_BACKOFF_CAP_SECONDS: the headerless
|
|
271
248
|
# exponential 429 backoff (base * 2**consecutive_429, capped).
|
|
272
|
-
|
|
249
|
+
STATUSLINE_CANDIDATE_TTL_SECONDS = 90
|
|
250
|
+
STATUSLINE_CANDIDATE_FUTURE_SKEW_SECONDS = 5
|
|
251
|
+
STATUSLINE_CANDIDATE_DOCUMENT_MAX_BYTES = 4 * 1024
|
|
252
|
+
STATUSLINE_SELECTED_DOCUMENT_MAX_BYTES = 1024 * 1024
|
|
253
|
+
STATUSLINE_TOMBSTONE_DOCUMENT_MAX_BYTES = 1024
|
|
273
254
|
# STATUSLINE_REFRESH_INTERVAL_DEFAULT (#311): the value `cctally setup`
|
|
274
255
|
# writes into Claude Code's settings.json `statusLine.refreshInterval` when a
|
|
275
256
|
# recognized cctally statusLine block lacks one. Claude Code re-runs the
|
|
276
257
|
# statusline command on this fixed timer "in addition to the event-driven
|
|
277
258
|
# updates", which keeps the usage-persistence feeder ticking while a parent
|
|
278
259
|
# session waits on a long subagent (event-driven updates go quiet then). MUST
|
|
279
|
-
#
|
|
280
|
-
# above. Add-when-absent only; a user-set value is never mutated.
|
|
260
|
+
# Add-when-absent only; a user-set value is never mutated.
|
|
281
261
|
STATUSLINE_REFRESH_INTERVAL_DEFAULT = 30
|
|
282
262
|
OAUTH_BACKFILL_STALE_SECONDS = 300.0
|
|
283
263
|
OAUTH_BACKOFF_BASE_SECONDS = 60.0
|