cctally 1.7.0 → 1.7.2
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 +27 -0
- package/bin/_cctally_alerts.py +231 -0
- package/bin/_cctally_cache.py +1432 -0
- package/bin/_cctally_config.py +560 -0
- package/bin/_cctally_dashboard.py +5403 -0
- package/bin/_cctally_db.py +1837 -0
- package/bin/_cctally_record.py +2305 -0
- package/bin/_cctally_refresh.py +812 -0
- package/bin/_cctally_release.py +751 -0
- package/bin/_cctally_setup.py +1571 -0
- package/bin/_cctally_sync_week.py +110 -0
- package/bin/_cctally_tui.py +4487 -0
- package/bin/_cctally_update.py +2132 -0
- package/bin/_lib_aggregators.py +712 -0
- package/bin/_lib_alerts_payload.py +194 -0
- package/bin/_lib_blocks.py +441 -0
- package/bin/_lib_diff_kernel.py +1618 -0
- package/bin/_lib_display_tz.py +361 -0
- package/bin/_lib_doctor.py +137 -0
- package/bin/_lib_five_hour.py +82 -0
- package/bin/_lib_jsonl.py +403 -0
- package/bin/_lib_pricing.py +520 -0
- package/bin/_lib_render.py +2785 -0
- package/bin/_lib_semver.py +105 -0
- package/bin/_lib_subscription_weeks.py +492 -0
- package/bin/cctally +11694 -35448
- package/package.json +24 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""`cctally sync-week` subcommand entry point.
|
|
2
|
+
|
|
3
|
+
Lazy I/O sibling: holds the single entry-point function `cmd_sync_week`,
|
|
4
|
+
which loads config + selects the target subscription week +
|
|
5
|
+
JSONL-aggregates the week's cost + inserts a `weekly_cost_snapshots`
|
|
6
|
+
row + emits the success line (or `--json` envelope).
|
|
7
|
+
|
|
8
|
+
Every helper this command calls — `load_config`, `get_week_start_name`,
|
|
9
|
+
`open_db`, `pick_week_selection`, `compute_week_cost`,
|
|
10
|
+
`format_local_iso`, `insert_cost_snapshot`, `make_week_ref`,
|
|
11
|
+
`get_latest_usage_for_week` — stays in `bin/cctally` (they're shared
|
|
12
|
+
with the rest of the subcommand surface), reached via the `_cctally()`
|
|
13
|
+
call-time accessor (spec §5.2 / §5.5 pattern).
|
|
14
|
+
|
|
15
|
+
bin/cctally re-exports `cmd_sync_week` so the two non-extracted internal
|
|
16
|
+
callers (`cmd_record_usage`'s milestone-cost-sync path and the
|
|
17
|
+
`cmd_report` lazy-sync path) resolve via bare name unchanged.
|
|
18
|
+
|
|
19
|
+
Spec: docs/superpowers/specs/2026-05-13-bin-cctally-split-design.md
|
|
20
|
+
"""
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import argparse
|
|
24
|
+
import json
|
|
25
|
+
import sys
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _cctally():
|
|
29
|
+
"""Resolve the current `cctally` module at call-time (spec §5.5)."""
|
|
30
|
+
return sys.modules["cctally"]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def cmd_sync_week(args: argparse.Namespace) -> int:
|
|
34
|
+
c = _cctally()
|
|
35
|
+
config = c.load_config()
|
|
36
|
+
week_start_name = c.get_week_start_name(config, args.week_start_name)
|
|
37
|
+
|
|
38
|
+
conn = c.open_db()
|
|
39
|
+
try:
|
|
40
|
+
selection = c.pick_week_selection(
|
|
41
|
+
conn,
|
|
42
|
+
args.week_start,
|
|
43
|
+
args.week_end,
|
|
44
|
+
week_start_name,
|
|
45
|
+
)
|
|
46
|
+
week_start = selection.week_start
|
|
47
|
+
week_end = selection.week_end
|
|
48
|
+
result = c.compute_week_cost(
|
|
49
|
+
week_start=week_start,
|
|
50
|
+
week_end=week_end,
|
|
51
|
+
mode=args.mode,
|
|
52
|
+
offline=args.offline,
|
|
53
|
+
project=args.project,
|
|
54
|
+
start_iso_override=selection.start_iso_override,
|
|
55
|
+
end_iso_override=selection.end_iso_override,
|
|
56
|
+
)
|
|
57
|
+
week_start_at = selection.start_iso_override or c.format_local_iso(week_start, end_of_day=False)
|
|
58
|
+
week_end_at = selection.end_iso_override or c.format_local_iso(week_end, end_of_day=True)
|
|
59
|
+
insert_id = c.insert_cost_snapshot(
|
|
60
|
+
conn,
|
|
61
|
+
week_start=week_start,
|
|
62
|
+
week_end=week_end,
|
|
63
|
+
week_start_at=week_start_at,
|
|
64
|
+
week_end_at=week_end_at,
|
|
65
|
+
range_start_iso=result.start_iso,
|
|
66
|
+
range_end_iso=result.end_iso,
|
|
67
|
+
cost_usd=result.cost_usd,
|
|
68
|
+
mode=args.mode,
|
|
69
|
+
project=args.project,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
week_ref = c.make_week_ref(
|
|
73
|
+
week_start_date=week_start.isoformat(),
|
|
74
|
+
week_end_date=week_end.isoformat(),
|
|
75
|
+
week_start_at=week_start_at,
|
|
76
|
+
week_end_at=week_end_at,
|
|
77
|
+
)
|
|
78
|
+
usage_row = c.get_latest_usage_for_week(conn, week_ref)
|
|
79
|
+
weekly_percent = float(usage_row["weekly_percent"]) if usage_row else None
|
|
80
|
+
dollars_per_percent = (
|
|
81
|
+
result.cost_usd / weekly_percent if weekly_percent and weekly_percent > 0 else None
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
payload = {
|
|
85
|
+
"id": insert_id,
|
|
86
|
+
"weekStartDate": week_start.isoformat(),
|
|
87
|
+
"weekEndDate": week_end.isoformat(),
|
|
88
|
+
"weekStartAt": week_start_at,
|
|
89
|
+
"weekEndAt": week_end_at,
|
|
90
|
+
"rangeStartIso": result.start_iso,
|
|
91
|
+
"rangeEndIso": result.end_iso,
|
|
92
|
+
"costUSD": round(result.cost_usd, 9),
|
|
93
|
+
"weeklyPercent": weekly_percent,
|
|
94
|
+
"dollarsPerPercent": round(dollars_per_percent, 9) if dollars_per_percent is not None else None,
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if args.json:
|
|
98
|
+
print(json.dumps(payload, indent=2))
|
|
99
|
+
elif not args.quiet:
|
|
100
|
+
print(
|
|
101
|
+
f"Synced week {payload['weekStartDate']}..{payload['weekEndDate']} "
|
|
102
|
+
f"=> ${payload['costUSD']:.6f}"
|
|
103
|
+
)
|
|
104
|
+
if weekly_percent is not None:
|
|
105
|
+
print(f"Latest weekly usage: {weekly_percent:.2f}%")
|
|
106
|
+
if dollars_per_percent is not None:
|
|
107
|
+
print(f"$ per 1% usage: ${dollars_per_percent:.6f}")
|
|
108
|
+
return 0
|
|
109
|
+
finally:
|
|
110
|
+
conn.close()
|