cctally 1.63.0 → 1.65.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 +22 -0
- package/README.md +7 -0
- package/bin/_cctally_cache.py +60 -19
- package/bin/_cctally_config.py +68 -0
- package/bin/_cctally_core.py +29 -0
- package/bin/_cctally_dashboard.py +364 -38
- package/bin/_cctally_doctor.py +24 -0
- package/bin/_cctally_parser.py +61 -0
- package/bin/_cctally_setup.py +22 -0
- package/bin/_cctally_telemetry.py +362 -0
- package/bin/_cctally_tui.py +445 -236
- package/bin/_cctally_update.py +53 -9
- package/bin/_lib_conversation_query.py +349 -36
- package/bin/_lib_doctor.py +32 -0
- package/bin/_lib_perf.py +180 -0
- package/bin/_lib_transcript_access.py +23 -0
- package/bin/cctally +98 -0
- package/bin/cctally-npm-postinstall.js +4 -0
- package/dashboard/static/assets/index-CJTUCpKt.js +80 -0
- package/dashboard/static/assets/index-DQWNrIqu.css +1 -0
- package/dashboard/static/dashboard.html +2 -2
- package/package.json +3 -1
- package/dashboard/static/assets/index-0jzYm75p.css +0 -1
- package/dashboard/static/assets/index-D_Ylyqsf.js +0 -80
package/bin/_cctally_update.py
CHANGED
|
@@ -1118,18 +1118,21 @@ def _do_update_check() -> None:
|
|
|
1118
1118
|
c._save_update_state(state)
|
|
1119
1119
|
|
|
1120
1120
|
|
|
1121
|
-
def
|
|
1122
|
-
"""Fire-and-forget
|
|
1123
|
-
|
|
1124
|
-
Detached `subprocess.Popen` with `start_new_session=True` so a
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1121
|
+
def _spawn_detached(command: str) -> None:
|
|
1122
|
+
"""Fire-and-forget a hidden self-subcommand as a detached worker.
|
|
1123
|
+
|
|
1124
|
+
Detached `subprocess.Popen` with `start_new_session=True` so a parent
|
|
1125
|
+
exit (the user closes the shell) doesn't propagate SIGHUP to the child;
|
|
1126
|
+
stdin/stdout/stderr all `/dev/null` so the child can't pollute the
|
|
1127
|
+
parent's terminal; exceptions swallowed so a failed spawn can't break
|
|
1128
|
+
the parent command. Shared launch boilerplate for both dedicated
|
|
1129
|
+
background workers below — `_update-check` and `_telemetry-beat` stay
|
|
1130
|
+
deliberately separate spawns (spec review finding #1) and share only
|
|
1131
|
+
this Popen shape.
|
|
1129
1132
|
"""
|
|
1130
1133
|
try:
|
|
1131
1134
|
subprocess.Popen(
|
|
1132
|
-
[sys.executable, os.path.realpath(sys.argv[0]),
|
|
1135
|
+
[sys.executable, os.path.realpath(sys.argv[0]), command],
|
|
1133
1136
|
stdin=subprocess.DEVNULL,
|
|
1134
1137
|
stdout=subprocess.DEVNULL,
|
|
1135
1138
|
stderr=subprocess.DEVNULL,
|
|
@@ -1141,6 +1144,11 @@ def _spawn_background_update_check() -> None:
|
|
|
1141
1144
|
pass
|
|
1142
1145
|
|
|
1143
1146
|
|
|
1147
|
+
def _spawn_background_update_check() -> None:
|
|
1148
|
+
"""Fire-and-forget the hidden ``_update-check`` worker (spec §3.6)."""
|
|
1149
|
+
_spawn_detached("_update-check")
|
|
1150
|
+
|
|
1151
|
+
|
|
1144
1152
|
def cmd_update_check_internal(args) -> int:
|
|
1145
1153
|
"""Hidden ``_update-check`` subcommand handler (spec §3.6).
|
|
1146
1154
|
|
|
@@ -1167,6 +1175,37 @@ def cmd_update_check_internal(args) -> int:
|
|
|
1167
1175
|
return 0
|
|
1168
1176
|
|
|
1169
1177
|
|
|
1178
|
+
def _spawn_background_telemetry_beat() -> None:
|
|
1179
|
+
"""Fire-and-forget the hidden ``_telemetry-beat`` worker.
|
|
1180
|
+
|
|
1181
|
+
A DEDICATED detached worker, deliberately separate from
|
|
1182
|
+
``_update-check`` (spec review finding #1): the anonymous install-count
|
|
1183
|
+
beat must never share a process, throttle marker, or failure mode with
|
|
1184
|
+
the update check. Only the launch boilerplate is shared, via
|
|
1185
|
+
``_spawn_detached``."""
|
|
1186
|
+
_spawn_detached("_telemetry-beat")
|
|
1187
|
+
|
|
1188
|
+
|
|
1189
|
+
def cmd_telemetry_beat_internal(args) -> int:
|
|
1190
|
+
"""Hidden ``_telemetry-beat`` subcommand handler.
|
|
1191
|
+
|
|
1192
|
+
The detached anonymous-install-count worker. It does the beat and
|
|
1193
|
+
NOTHING else — critically it must NOT read or write any update-check
|
|
1194
|
+
state (spec review finding #1: a dedicated worker fully decoupled
|
|
1195
|
+
from ``_update-check``). Always returns 0 so the parent's
|
|
1196
|
+
spawn-and-forget contract holds. The try/except wraps both the
|
|
1197
|
+
``load_config`` read and ``do_telemetry_beat`` (which only guarantees
|
|
1198
|
+
the network POST is swallowed, not that pure helper defects can't
|
|
1199
|
+
raise), and its return value is unused."""
|
|
1200
|
+
c = _cctally()
|
|
1201
|
+
try:
|
|
1202
|
+
config = c.load_config()
|
|
1203
|
+
c.do_telemetry_beat(config)
|
|
1204
|
+
except Exception:
|
|
1205
|
+
pass
|
|
1206
|
+
return 0
|
|
1207
|
+
|
|
1208
|
+
|
|
1170
1209
|
# === User-facing `cctally update` (spec §4) ===
|
|
1171
1210
|
# `cmd_update` routes by mode flag. Mode flags are mutually exclusive
|
|
1172
1211
|
# (argparse enforces it; the dispatcher's redundant check is defense in
|
|
@@ -1976,6 +2015,11 @@ class _DashboardUpdateCheckThread(threading.Thread):
|
|
|
1976
2015
|
envelope_precompute=(
|
|
1977
2016
|
c._cctally_tui._tui_precompute_envelope_config(load_config())
|
|
1978
2017
|
),
|
|
2018
|
+
# #278 §1.4.1: a version-banner refresh republishes complete data;
|
|
2019
|
+
# force the hydration latch clear so a republish that happens to
|
|
2020
|
+
# carry a prior hydrating seed/partial doesn't freeze the client's
|
|
2021
|
+
# loading skeletons.
|
|
2022
|
+
hydrating=False,
|
|
1979
2023
|
)
|
|
1980
2024
|
self._ref.set(fresh)
|
|
1981
2025
|
self._hub.publish(fresh)
|