forked from Rockachopa/Timmy-time-dashboard
* polish: streamline nav, extract inline styles, improve tablet UX - Restructure desktop nav from 8+ flat links + overflow dropdown into 5 grouped dropdowns (Core, Agents, Intel, System, More) matching the mobile menu structure to reduce decision fatigue - Extract all inline styles from mission_control.html and base.html notification elements into mission-control.css with semantic classes - Replace JS-built innerHTML with secure DOM construction in notification loader and chat history - Add CONNECTING state to connection indicator (amber) instead of showing OFFLINE before WebSocket connects - Add tablet breakpoint (1024px) with larger touch targets for Apple Pencil / stylus use and safe-area padding for iPad toolbar - Add active-link highlighting in desktop dropdown menus - Rename "Mission Control" page title to "System Overview" to disambiguate from the chat home page - Add "Home — Timmy Time" page title to index.html https://claude.ai/code/session_015uPUoKyYa8M2UAcyk5Gt6h * fix(security): move auth-gate credentials to environment variables Hardcoded username, password, and HMAC secret in auth-gate.py replaced with os.environ lookups. Startup now refuses to run if any variable is unset. Added AUTH_GATE_SECRET/USER/PASS to .env.example. https://claude.ai/code/session_015uPUoKyYa8M2UAcyk5Gt6h * refactor(tooling): migrate from black+isort+bandit to ruff Replace three separate linting/formatting tools with a single ruff invocation. Updates tox.ini (lint, format, pre-push, pre-commit envs), .pre-commit-config.yaml, and CI workflow. Fixes all ruff errors including unused imports, missing raise-from, and undefined names. Ruff config maps existing bandit skips to equivalent S-rules. https://claude.ai/code/session_015uPUoKyYa8M2UAcyk5Gt6h --------- Co-authored-by: Claude <noreply@anthropic.com>
44 lines
1.8 KiB
Python
44 lines
1.8 KiB
Python
"""Tests for timmy.tools_delegation — delegate_task and list_swarm_agents."""
|
|
|
|
from timmy.tools_delegation import delegate_task, list_swarm_agents
|
|
|
|
|
|
class TestDelegateTask:
|
|
def test_unknown_agent_returns_error(self):
|
|
result = delegate_task("nonexistent", "do something")
|
|
assert result["success"] is False
|
|
assert "Unknown agent" in result["error"]
|
|
assert result["task_id"] is None
|
|
|
|
def test_valid_agent_names_normalised(self):
|
|
# Should still fail at import (no swarm module), but agent name is accepted
|
|
result = delegate_task(" Seer ", "think about it")
|
|
# The swarm import will fail, so success=False but error is about import, not agent name
|
|
assert "Unknown agent" not in result.get("error", "")
|
|
|
|
def test_invalid_priority_defaults_to_normal(self):
|
|
# Even with bad priority, delegate_task should not crash
|
|
result = delegate_task("forge", "build", priority="ultra")
|
|
assert isinstance(result, dict)
|
|
|
|
def test_all_valid_agents_accepted(self):
|
|
valid_agents = ["seer", "forge", "echo", "helm", "quill"]
|
|
for agent in valid_agents:
|
|
result = delegate_task(agent, "test task")
|
|
assert "Unknown agent" not in result.get("error", ""), f"{agent} rejected"
|
|
|
|
def test_mace_no_longer_valid(self):
|
|
result = delegate_task("mace", "run security scan")
|
|
assert result["success"] is False
|
|
assert "Unknown agent" in result["error"]
|
|
|
|
|
|
class TestListSwarmAgents:
|
|
def test_returns_agents_from_personas(self):
|
|
result = list_swarm_agents()
|
|
assert result["success"] is True
|
|
assert len(result["agents"]) > 0
|
|
agent_names = [a["name"] for a in result["agents"]]
|
|
assert "Seer" in agent_names
|
|
assert "Forge" in agent_names
|