From 68f97fcc59b8d07312737ab56fa1172e15d946ea Mon Sep 17 00:00:00 2001 From: Kydoimos97 Date: Tue, 26 May 2026 12:27:47 -0600 Subject: [PATCH 1/3] fix: replace non-ASCII symbols with ASCII in console output Checkmark and cross characters (U+2713, U+2717) crash on Windows terminals using cp1252 encoding. Replaced with OK/FAIL plain text so output works on all platforms without requiring UTF-8 console setup. --- puppy_kit/commands/config.py | 6 +++--- puppy_kit/commands/event.py | 2 +- puppy_kit/commands/monitor.py | 14 +++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/puppy_kit/commands/config.py b/puppy_kit/commands/config.py index 794449d..081cf34 100644 --- a/puppy_kit/commands/config.py +++ b/puppy_kit/commands/config.py @@ -285,11 +285,11 @@ def test_credentials(): # Check if it's an auth error error_msg = str(e).lower() if "401" in error_msg or "403" in error_msg or "authentication" in error_msg: - console.print("[red]✗ Auth FAILED[/red] — check DD_API_KEY and DD_APP_KEY") + console.print("[red]FAIL Auth FAILED[/red] — check DD_API_KEY and DD_APP_KEY") sys.exit(2) else: # Other API errors - console.print(f"[red]✗ API Error[/red] — {e}") + console.print(f"[red]FAIL API Error[/red] — {e}") sys.exit(1) # Success @@ -299,7 +299,7 @@ def test_credentials(): except Exception: site = "unknown" - console.print("[green]✓ Auth OK[/green] — credentials are valid") + console.print("[green]OK Auth OK[/green] — credentials are valid") console.print(f" Site: {site}") # Try to get the API key from environment or config diff --git a/puppy_kit/commands/event.py b/puppy_kit/commands/event.py index 47f66b6..63c54cd 100644 --- a/puppy_kit/commands/event.py +++ b/puppy_kit/commands/event.py @@ -132,7 +132,7 @@ def post_event(title, text, tags, priority): with console.status("[cyan]Posting event...[/cyan]"): result = client.events.create_event(body=event_req) - console.print(f"[green]✓ Event posted: {result.event.id}[/green]") + console.print(f"[green]OK Event posted: {result.event.id}[/green]") console.print(f"[bold]Title:[/bold] {result.event.title}") if result.event.url: console.print(f"[bold]URL:[/bold] {result.event.url}") diff --git a/puppy_kit/commands/monitor.py b/puppy_kit/commands/monitor.py index 9c713ba..c96bac0 100644 --- a/puppy_kit/commands/monitor.py +++ b/puppy_kit/commands/monitor.py @@ -264,7 +264,7 @@ def unmute_monitor(monitor_id, scope): client.monitors.update_monitor(monitor_id, body=MonitorUpdateRequest(**unmute_options)) - console.print(f"[green]✓ Monitor {monitor_id} unmuted[/green]") + console.print(f"[green]OK Monitor {monitor_id} unmuted[/green]") @monitor.command(name="validate") @@ -283,12 +283,12 @@ def validate_monitor(monitor_type, query): # Check if result has errors if hasattr(result, "errors") and result.errors: - console.print("[red]✗ Monitor definition is invalid[/red]") + console.print("[red]FAIL Monitor definition is invalid[/red]") for error in result.errors: # ty:ignore[not-iterable] console.print(f" • {error}") sys.exit(1) else: - console.print("[green]✓ Monitor definition is valid[/green]") + console.print("[green]OK Monitor definition is valid[/green]") @monitor.command(name="create") @@ -360,7 +360,7 @@ def create_monitor_cmd( if fmt == "json": click.echo(json.dumps(json_list_response(result.to_dict()), default=json_default)) else: - console.print(f"[green]✓ Monitor {result.id} created[/green]") + console.print(f"[green]OK Monitor {result.id} created[/green]") console.print(f"[bold]Name:[/bold] {result.name}") @@ -431,7 +431,7 @@ def update_monitor_cmd( if fmt == "json": click.echo(json.dumps(json_list_response(result.to_dict()), default=json_default)) else: - console.print(f"[green]✓ Monitor {monitor_id} updated[/green]") + console.print(f"[green]OK Monitor {monitor_id} updated[/green]") console.print(f"[bold]Name:[/bold] {result.name}") @@ -453,7 +453,7 @@ def mute_all_monitors(message): with console.status("[cyan]Muting all monitors...[/cyan]"): result = client.downtimes.create_downtime(body=downtime_body) - console.print("[green]✓ All monitors muted[/green]") + console.print("[green]OK All monitors muted[/green]") console.print(f"[dim]Downtime ID: {result.id}[/dim]") @@ -478,5 +478,5 @@ def unmute_all_monitors(): client.downtimes.cancel_downtime(dt.id) console.print( - f"[green]✓ All monitors unmuted ({len(global_downtimes)} downtime(s) cancelled)[/green]" + f"[green]OK All monitors unmuted ({len(global_downtimes)} downtime(s) cancelled)[/green]" ) From 6ee807c0b67a95c27cf2fd9a521d9d8cfb2c5cf0 Mon Sep 17 00:00:00 2001 From: Kydoimos97 Date: Tue, 26 May 2026 13:55:35 -0600 Subject: [PATCH 2/3] feat: add puppy-mcp console script entry point Adds a dedicated puppy-mcp script so the MCP server can be invoked directly without running as a module. Claude Code MCP config becomes: {"command": "uvx", "args": ["--from", "puppy-kit[mcp]", "puppy-mcp"]} Previously the only option was python -m puppy_kit.mcp.server, which caused users to accidentally pick up the unrelated puppy-mcp-server package on PyPI. --- puppy_kit/mcp/server.py | 7 ++++++- pyproject.toml | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/puppy_kit/mcp/server.py b/puppy_kit/mcp/server.py index db6c0ef..a601aca 100644 --- a/puppy_kit/mcp/server.py +++ b/puppy_kit/mcp/server.py @@ -558,5 +558,10 @@ def dd_dashboards_get(dashboard_id: str) -> str: # Entry point # --------------------------------------------------------------------------- -if __name__ == "__main__": +def main() -> None: + """Entry point for the puppy-mcp console script.""" mcp.run() + + +if __name__ == "__main__": + main() diff --git a/pyproject.toml b/pyproject.toml index 8b08420..5990b3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,6 +50,7 @@ dev = [ [project.scripts] puppy = "puppy_kit.cli:run" puppy-kit = "puppy_kit.cli:run" +puppy-mcp = "puppy_kit.mcp.server:main" [project.urls] Homepage = "https://github.com/WrenchAI/puppy-kit" From fdb23097ea1f622decebc1f459772a4a05d4ef9d Mon Sep 17 00:00:00 2001 From: Kydoimos97 Date: Tue, 26 May 2026 13:56:31 -0600 Subject: [PATCH 3/3] chore: apply ruff format to server.py --- puppy_kit/mcp/server.py | 1 + 1 file changed, 1 insertion(+) diff --git a/puppy_kit/mcp/server.py b/puppy_kit/mcp/server.py index a601aca..1507b40 100644 --- a/puppy_kit/mcp/server.py +++ b/puppy_kit/mcp/server.py @@ -558,6 +558,7 @@ def dd_dashboards_get(dashboard_id: str) -> str: # Entry point # --------------------------------------------------------------------------- + def main() -> None: """Entry point for the puppy-mcp console script.""" mcp.run()