cctally 1.68.0 → 1.69.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 +56 -0
- package/bin/_cctally_alerts.py +54 -2
- package/bin/_cctally_cache.py +644 -107
- package/bin/_cctally_cache_report.py +41 -17
- package/bin/_cctally_codex.py +109 -4
- package/bin/_cctally_config.py +368 -2
- package/bin/_cctally_core.py +168 -5
- package/bin/_cctally_dashboard.py +679 -5
- package/bin/_cctally_dashboard_conversation.py +9 -4
- package/bin/_cctally_dashboard_envelope.py +110 -1
- package/bin/_cctally_dashboard_share.py +557 -79
- package/bin/_cctally_db.py +303 -17
- package/bin/_cctally_diff.py +49 -16
- package/bin/_cctally_doctor.py +118 -0
- package/bin/_cctally_forecast.py +12 -4
- package/bin/_cctally_parser.py +298 -92
- package/bin/_cctally_project.py +24 -8
- package/bin/_cctally_quota.py +1381 -0
- package/bin/_cctally_record.py +319 -14
- package/bin/_cctally_refresh.py +105 -3
- package/bin/_cctally_reporting.py +7 -1
- package/bin/_cctally_setup.py +343 -113
- package/bin/_cctally_statusline.py +228 -0
- package/bin/_cctally_tui.py +787 -7
- package/bin/_lib_alert_axes.py +11 -0
- package/bin/_lib_codex_hooks.py +367 -0
- package/bin/_lib_conversation_query.py +156 -67
- package/bin/_lib_doctor.py +202 -0
- package/bin/_lib_jsonl.py +529 -162
- package/bin/_lib_quota.py +566 -0
- package/bin/_lib_share.py +152 -34
- package/bin/_lib_snapshot_cache.py +26 -0
- package/bin/_lib_source_identity.py +74 -0
- package/bin/cctally +324 -10
- package/dashboard/static/assets/index-CBbErI-P.js +80 -0
- package/dashboard/static/assets/index-kDDVOLa_.css +1 -0
- package/dashboard/static/dashboard.html +2 -2
- package/package.json +5 -1
- package/dashboard/static/assets/index-BybNp_Di.js +0 -80
- package/dashboard/static/assets/index-DgAmLK65.css +0 -1
package/bin/_cctally_project.py
CHANGED
|
@@ -239,7 +239,7 @@ def _accumulate_entry_into_bucket(
|
|
|
239
239
|
mb["cache_read"] += entry.cache_read_tokens
|
|
240
240
|
|
|
241
241
|
|
|
242
|
-
def
|
|
242
|
+
def _project_json_payload(
|
|
243
243
|
*,
|
|
244
244
|
since: dt.datetime,
|
|
245
245
|
until: dt.datetime,
|
|
@@ -250,8 +250,8 @@ def _project_json_output(
|
|
|
250
250
|
warnings: list[str],
|
|
251
251
|
include_breakdown: bool,
|
|
252
252
|
week_snapshots: dict[dt.datetime, float],
|
|
253
|
-
) ->
|
|
254
|
-
"""
|
|
253
|
+
) -> dict:
|
|
254
|
+
"""Build the project subcommand's --json payload per spec §4.
|
|
255
255
|
|
|
256
256
|
Accepts rows already sorted by the caller (so ordering flags apply
|
|
257
257
|
uniformly to both terminal and JSON modes). Aggregates `totals.costUsd`
|
|
@@ -325,7 +325,12 @@ def _project_json_output(
|
|
|
325
325
|
"projects": projects_json,
|
|
326
326
|
"warnings": warnings,
|
|
327
327
|
}
|
|
328
|
-
return
|
|
328
|
+
return _cctally().stamp_schema_version(payload)
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def _project_json_output(**kwargs) -> str:
|
|
332
|
+
"""Serialize :func:`_project_json_payload` without changing CLI bytes."""
|
|
333
|
+
return json.dumps(_project_json_payload(**kwargs), indent=2)
|
|
329
334
|
|
|
330
335
|
|
|
331
336
|
def _project_sort_key(row: dict, sort_by: str, order: str):
|
|
@@ -393,8 +398,14 @@ def cmd_project(args: argparse.Namespace) -> int:
|
|
|
393
398
|
now = _command_as_of()
|
|
394
399
|
conn = open_db()
|
|
395
400
|
|
|
396
|
-
# Resolve [since_dt, until_dt] in UTC.
|
|
397
|
-
|
|
401
|
+
# Resolve [since_dt, until_dt] in UTC. All-provider project dispatch
|
|
402
|
+
# resolves its calendar range once, then injects it here so Claude and
|
|
403
|
+
# Codex describe precisely the same interval. The normal Claude parser
|
|
404
|
+
# remains unchanged for every user-facing legacy invocation.
|
|
405
|
+
source_range = getattr(args, "_source_analytics_range", None)
|
|
406
|
+
if source_range is not None:
|
|
407
|
+
since_dt, until_dt = source_range
|
|
408
|
+
elif args.since or args.until:
|
|
398
409
|
parsed = c._parse_cli_date_range(args, now_utc=now)
|
|
399
410
|
if isinstance(parsed, int):
|
|
400
411
|
# Translate the ccusage-parity helper's exit 1 into project's own
|
|
@@ -766,7 +777,7 @@ def cmd_project(args: argparse.Namespace) -> int:
|
|
|
766
777
|
return 0
|
|
767
778
|
|
|
768
779
|
if args.json:
|
|
769
|
-
|
|
780
|
+
payload = _project_json_payload(
|
|
770
781
|
since=since_dt,
|
|
771
782
|
until=until_dt,
|
|
772
783
|
weeks_in_range=len(weeks_in_range),
|
|
@@ -776,7 +787,12 @@ def cmd_project(args: argparse.Namespace) -> int:
|
|
|
776
787
|
warnings=warnings,
|
|
777
788
|
include_breakdown=args.breakdown,
|
|
778
789
|
week_snapshots=week_snapshots,
|
|
779
|
-
)
|
|
790
|
+
)
|
|
791
|
+
sink = getattr(args, "_source_result_sink", None)
|
|
792
|
+
if sink is not None:
|
|
793
|
+
sink(payload)
|
|
794
|
+
else:
|
|
795
|
+
print(json.dumps(payload, indent=2))
|
|
780
796
|
return 0
|
|
781
797
|
|
|
782
798
|
# Terminal path
|