Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "goodeye"
version = "0.18.0"
version = "0.18.1"
description = "Goodeye CLI: share and run outcome-aligned AI workflows from the terminal."
readme = "README.md"
license = { file = "LICENSE" }
Expand Down
13 changes: 9 additions & 4 deletions src/goodeye_cli/commands/usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,26 @@ def _coerce_usage(body: UsageResponse | dict[str, Any]) -> UsageResponse:
def format_usage_summary(body: UsageResponse | dict[str, Any]) -> str:
"""Render the usage payload as a human-readable multi-line string.

The purchased-credits and unpaid-balance lines only render when their
values are positive.
The purchased-credits, referral-credits, and unpaid-balance lines only
render when their values are positive.
"""
usage = _coerce_usage(body)
refill_at = usage.monthly_refill_at.strftime("%m/%d/%Y")
has_purchased = float(usage.purchased_remaining_usd) > 0
has_referral = float(usage.referral_remaining_usd) > 0
lines = [
f"Tier: {usage.tier}",
f"Available: ${usage.available_usd}",
]
if has_purchased:
if has_purchased or has_referral:
lines.append(
f" ${usage.monthly_remaining_usd} monthly "
f"(refills to ${usage.monthly_refill_usd} on {refill_at})"
)
lines.append(f" ${usage.purchased_remaining_usd} one-off credits")
if has_purchased:
lines.append(f" ${usage.purchased_remaining_usd} one-off credits")
if has_referral:
lines.append(f" ${usage.referral_remaining_usd} referral credits")
else:
lines.append(f" refills to ${usage.monthly_refill_usd} on {refill_at}")
if float(usage.unpaid_balance_usd) > 0:
Expand Down Expand Up @@ -75,6 +79,7 @@ def usage(
"monthly_refill_usd": result.monthly_refill_usd,
"monthly_refill_at": result.monthly_refill_at.isoformat(),
"purchased_remaining_usd": result.purchased_remaining_usd,
"referral_remaining_usd": result.referral_remaining_usd,
"unpaid_balance_usd": result.unpaid_balance_usd,
}
typer.echo(_json.dumps(payload))
Expand Down
5 changes: 4 additions & 1 deletion src/goodeye_cli/wire.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ class UsageResponse(_WireBase):
Money-shaped fields are strings to preserve exact decimal values across
the wire (callers parse them with ``Decimal`` or ``float`` as needed).
``available_usd`` is what the caller can spend right now: monthly grant
plus any one-off purchased credits, minus carried-over unpaid balance.
plus any one-off purchased credits and referral bonus credits, minus
carried-over unpaid balance. ``referral_remaining_usd`` defaults to 0.00
so responses from servers that predate the field still parse.
"""

tier: str
Expand All @@ -47,6 +49,7 @@ class UsageResponse(_WireBase):
monthly_refill_usd: str
monthly_refill_at: datetime
purchased_remaining_usd: str
referral_remaining_usd: str = "0.00"
unpaid_balance_usd: str


Expand Down
35 changes: 35 additions & 0 deletions tests/test_commands_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,40 @@ def test_format_usage_summary_with_purchased() -> None:
assert "$50.00 one-off credits" in out


def test_format_usage_summary_with_referral() -> None:
out = format_usage_summary(
_body(
available_usd="9.17",
monthly_remaining_usd="4.17",
referral_remaining_usd="5.00",
)
)
assert "Available: $9.17" in out
assert "$4.17 monthly (refills to $5.00 on 05/14/2026)" in out
assert "$5.00 referral credits" in out


def test_format_usage_summary_with_purchased_and_referral() -> None:
out = format_usage_summary(
_body(
available_usd="59.17",
monthly_remaining_usd="4.17",
purchased_remaining_usd="50.00",
referral_remaining_usd="5.00",
)
)
assert "Available: $59.17" in out
assert "$50.00 one-off credits" in out
assert "$5.00 referral credits" in out


def test_format_usage_summary_no_referral_line_when_absent() -> None:
# Older servers omit the field entirely; the wire default keeps it at 0.00
# and the line is suppressed.
out = format_usage_summary(_body())
assert "referral" not in out


def test_format_usage_summary_with_unpaid() -> None:
out = format_usage_summary(
_body(
Expand Down Expand Up @@ -128,6 +162,7 @@ def test_usage_command_json(tmp_config_paths: ConfigPaths, monkeypatch) -> None:
assert data["tier"] == "pro"
assert data["available_usd"] == "15.00"
assert data["monthly_refill_usd"] == "20.00"
assert data["referral_remaining_usd"] == "0.00"


def test_usage_command_without_credentials_errors(
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.