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 = "code-context-engine"
version = "0.4.23"
version = "0.4.24"
description = "Save 94% on AI coding tokens. Index your codebase, agents search instead of reading files. Works with Claude Code, Cursor, Codex, Copilot, Gemini CLI. Local MCP server, free, open source."
readme = {file = "README.md", content-type = "text/markdown"}
license = "MIT"
Expand Down
4 changes: 2 additions & 2 deletions server.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
"url": "https://github.com/elara-labs/code-context-engine",
"source": "github"
},
"version": "0.4.23",
"version": "0.4.24",
"packages": [
{
"registryType": "pypi",
"registryBaseUrl": "https://pypi.org",
"identifier": "code-context-engine",
"version": "0.4.23",
"version": "0.4.24",
"runtimeHint": "uvx",
"transport": {
"type": "stdio"
Expand Down
7 changes: 4 additions & 3 deletions src/context_engine/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1525,12 +1525,13 @@ def _fmt_cost(c: float) -> str:
return

# Shields.io badge URL: /badge/LABEL-MESSAGE-COLOR
# In the message: spaces%20, %%25, $ stays as-is in URL encoding
# shields.io path-segment rules: ---, ___, spaces → %20, $ is safe
badge_color = "brightgreen" if pct >= 80 else "green" if pct >= 50 else "yellowgreen"
cost_str = _fmt_cost(cost_saved)
badge_msg = f"{cost_str} saved | {pct}% tokens saved"
# shields.io requires: dashes as --, underscores as __, spaces as _ or %20
badge_msg_enc = quote(badge_msg, safe="")
# Escape shields.io special chars before URL encoding
badge_msg_shields = badge_msg.replace("-", "--").replace("_", "__")
badge_msg_enc = quote(badge_msg_shields, safe="$")
badge_url = (
f"https://img.shields.io/badge/"
f"CCE-{badge_msg_enc}-{badge_color}"
Expand Down
54 changes: 54 additions & 0 deletions tests/test_cli_savings.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,57 @@ def test_savings_all_projects_empty(runner, tmp_path):
result = runner.invoke(main, ["savings", "--all"])
assert result.exit_code == 0
assert "No usage recorded" in result.output


def test_savings_badge_with_data(runner, stats_dir):
"""--badge outputs Markdown badge and shields.io URL."""
storage_path, project_name = stats_dir
result = _invoke_savings(runner, storage_path, project_name, "--badge")
assert result.exit_code == 0
assert "shields.io" in result.output
assert "![" in result.output # Markdown badge syntax
assert "CCE" in result.output


def test_savings_badge_no_data(runner, tmp_path):
"""--badge with no data prints a helpful message instead of a badge."""
config = Config(storage_path=str(tmp_path))
from unittest.mock import patch
with runner.isolated_filesystem():
cwd = Path.cwd() / "empty-project"
cwd.mkdir()
with patch("context_engine.cli.load_config", return_value=config), \
patch("context_engine.cli.Path.cwd", return_value=cwd):
result = runner.invoke(main, ["savings", "--badge"])
assert result.exit_code == 0
assert "No savings data" in result.output


def test_savings_shortcut_badge(runner, stats_dir):
"""cce-savings --badge shortcut also outputs a shields.io badge."""
from unittest.mock import patch

storage_path, project_name = stats_dir
config = Config(storage_path=str(storage_path))

import click
with runner.isolated_filesystem():
cwd_path = Path.cwd() / project_name
cwd_path.mkdir(parents=True, exist_ok=True)

@click.command()
@click.option("--json", "as_json", is_flag=True)
@click.option("--all", "all_projects", is_flag=True)
@click.option("--badge", "show_badge", is_flag=True)
def _cmd(as_json, all_projects, show_badge):
from context_engine.cli import _print_savings_badge, _run_savings_report
if show_badge:
_print_savings_badge(config)
return
_run_savings_report(config, as_json=as_json, all_projects=all_projects)

with patch("context_engine.cli.Path.cwd", return_value=cwd_path):
result = runner.invoke(_cmd, ["--badge"])

assert result.exit_code == 0
assert "shields.io" in result.output
Loading