CtrlK
BlogDocsLog inGet started
Tessl Logo

jbaruch/coding-policy

General-purpose coding policy for Baruch's AI agents

76

Quality

95%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Low

Low-risk findings worth noting

Overview
Quality
Evals
Security
Files

test_config.pyskills/herdr-teamlead/tests/

"""Tests for teamlead.config."""

import os as _os
import sys as _sys

# Run as a script (`python3 tests/test_x.py`), Python puts tests/ on sys.path
# rather than the repo root, so neither `teamlead` nor `tests.fakes` would
# resolve. Under `-m unittest` from the root this is already true and the
# insert is a no-op. The consuming repo's runner executes files as scripts.
_ROOT = _os.path.dirname(_os.path.dirname(_os.path.abspath(__file__)))
if _ROOT not in _sys.path:
    _sys.path.insert(0, _ROOT)

import json
import os
import shutil
import tempfile
import unittest
from pathlib import Path

from teamlead.config import (
    Agent,
    default_config_path,
    load_config,
    load_role_costs,
    parse_config,
    parse_role_costs,
    select_agents,
)
from teamlead.errors import ConfigError

REPO_ROOT = Path(__file__).resolve().parent.parent

VALID = {
    "schema_version": 1,
    "agents": [
        {
            "name": "claude",
            "kind": "claude",
            "usage_prompt": "/usage",
            "usage_marker": "Current week",
            "usage_read_source": "visible",
            "close_keys": ["esc"],
            "clear_prompt": "/clear",
            "idle_markers": ["? for shortcuts"],
            "working_markers": ["Churned for"],
        },
        {
            "name": "codex",
            "kind": "codex",
            "usage_prompt": "/status",
            "usage_marker": "Weekly limit",
            "usage_read_source": "recent-unwrapped",
            "clear_prompt": "/new",
        },
    ],
}


class ParseConfigTest(unittest.TestCase):
    def test_parses_a_valid_config(self):
        agents = parse_config(VALID)
        self.assertEqual([agent.name for agent in agents], ["claude", "codex"])
        self.assertEqual(agents[0].close_keys, ("esc",))
        self.assertEqual(agents[1].close_keys, ())

    def test_probe_markers_are_read_into_the_agent(self):
        agents = parse_config(VALID)
        self.assertEqual(agents[0].idle_markers, ("? for shortcuts",))
        self.assertEqual(agents[0].working_markers, ("Churned for",))

    def test_probe_markers_default_to_empty(self):
        # An agent with no markers is simply never probed; herdr's state stands.
        agents = parse_config(VALID)
        self.assertEqual(agents[1].idle_markers, ())
        self.assertEqual(agents[1].working_markers, ())

    def test_slash_delivery_defaults_to_paste(self):
        # The older path, and the one claude and codex need.
        self.assertEqual(parse_config(VALID)[0].slash_delivery, "paste")

    def test_slash_delivery_is_read_when_given(self):
        entry = json.loads(json.dumps(VALID))
        entry["agents"][0]["slash_delivery"] = "type"
        self.assertEqual(parse_config(entry)[0].slash_delivery, "type")

    def test_an_unknown_slash_delivery_is_a_config_error(self):
        broken = json.loads(json.dumps(VALID))
        broken["agents"][0]["slash_delivery"] = "sendkeys"
        with self.assertRaises(ConfigError) as caught:
            parse_config(broken)
        message = str(caught.exception)
        self.assertIn("slash_delivery", message)
        self.assertIn("'paste'", message)
        self.assertIn("'type'", message)

    def test_dialog_next_tab_keys_default_to_empty(self):
        self.assertEqual(parse_config(VALID)[0].dialog_next_tab_keys, ())

    def test_dialog_next_tab_keys_are_read_when_given(self):
        entry = json.loads(json.dumps(VALID))
        entry["agents"][0]["dialog_next_tab_keys"] = ["tab"]
        self.assertEqual(parse_config(entry)[0].dialog_next_tab_keys, ("tab",))

    def test_dialog_next_tab_keys_must_be_an_array_of_strings(self):
        broken = json.loads(json.dumps(VALID))
        broken["agents"][0]["dialog_next_tab_keys"] = "tab"
        with self.assertRaises(ConfigError) as caught:
            parse_config(broken)
        self.assertIn("dialog_next_tab_keys", str(caught.exception))

    def test_idle_markers_must_be_an_array_of_strings(self):
        broken = json.loads(json.dumps(VALID))
        broken["agents"][0]["idle_markers"] = "? for shortcuts"
        with self.assertRaises(ConfigError) as caught:
            parse_config(broken)
        self.assertIn("idle_markers", str(caught.exception))

    def test_working_markers_reject_non_string_items(self):
        broken = json.loads(json.dumps(VALID))
        broken["agents"][0]["working_markers"] = [42]
        with self.assertRaises(ConfigError) as caught:
            parse_config(broken)
        self.assertIn("working_markers", str(caught.exception))

    def test_shipped_example_config_is_valid(self):
        payload = json.loads((REPO_ROOT / "config.example.json").read_text(encoding="utf-8"))
        agents = parse_config(payload, source="config.example.json")
        self.assertEqual([agent.name for agent in agents], ["claude", "codex", "grok"])
        self.assertEqual([agent.kind for agent in agents], ["claude", "codex", "grok"])
        by_name = {agent.name: agent for agent in agents}
        # Grok renders /usage as a modal after a restart, so it reads the
        # viewport and dismisses the dialog just like claude does.
        self.assertEqual(by_name["grok"].usage_read_source, "visible")
        self.assertEqual(by_name["grok"].close_keys, ("esc",))
        # Every shipped agent carries an idle signature for the probe.
        self.assertTrue(all(agent.idle_markers for agent in agents))
        # Delivery is per-agent because the TUIs disagree: grok reads a pasted
        # slash command as a chat message, codex swallows a typed one in its
        # autocomplete popup.
        self.assertEqual(
            {agent.name: agent.slash_delivery for agent in agents},
            {"claude": "paste", "codex": "type", "grok": "type"},
        )
        # Every agent can be checked for a stuck composer.
        self.assertTrue(all(agent.composer_glyph for agent in agents))
        self.assertEqual(by_name["codex"].composer_glyph, "\u203a ")
        # Codex ships with NO recovery keys: the key that clears its composer
        # is ctrl+c, and ctrl+c on an idle Codex exits the process. That is
        # how a live agent was killed.
        self.assertEqual(by_name["codex"].recover_keys, ())
        # And its empty-composer placeholder is declared, so the hint text is
        # never read as somebody's typing.
        self.assertEqual(
            by_name["codex"].composer_placeholders, ("Ask Codex to do anything",)
        )
        # Dim composer text is never typing, on every kind.
        self.assertTrue(all(agent.composer_ignore_dim for agent in agents))
        self.assertEqual(by_name["grok"].dialog_next_tab_keys, ("tab",))

    def test_wrong_schema_version_is_rejected(self):
        payload = dict(VALID, schema_version=2)
        with self.assertRaises(ConfigError) as caught:
            parse_config(payload)
        self.assertIn("schema_version", str(caught.exception))

    def test_missing_agents_array_is_rejected(self):
        with self.assertRaises(ConfigError):
            parse_config({"schema_version": 1})

    def test_empty_agents_array_is_rejected(self):
        with self.assertRaises(ConfigError):
            parse_config({"schema_version": 1, "agents": []})

    def test_missing_field_names_the_field(self):
        broken = json.loads(json.dumps(VALID))
        del broken["agents"][0]["clear_prompt"]
        with self.assertRaises(ConfigError) as caught:
            parse_config(broken)
        self.assertIn("clear_prompt", str(caught.exception))

    def test_bad_read_source_is_rejected(self):
        broken = json.loads(json.dumps(VALID))
        broken["agents"][0]["usage_read_source"] = "screenshot"
        with self.assertRaises(ConfigError) as caught:
            parse_config(broken)
        self.assertIn("recent-unwrapped", str(caught.exception))

    def test_duplicate_names_are_rejected(self):
        broken = json.loads(json.dumps(VALID))
        broken["agents"][1]["name"] = "claude"
        with self.assertRaises(ConfigError):
            parse_config(broken)

    def test_close_keys_must_be_an_array(self):
        broken = json.loads(json.dumps(VALID))
        broken["agents"][0]["close_keys"] = "esc"
        with self.assertRaises(ConfigError):
            parse_config(broken)

    def test_non_object_payload_is_rejected(self):
        with self.assertRaises(ConfigError):
            parse_config([VALID])


class LoadConfigTest(unittest.TestCase):
    def setUp(self):
        self.tmp = tempfile.mkdtemp(prefix="teamlead-config-test-")
        self.addCleanup(shutil.rmtree, self.tmp)

    def test_loads_from_disk(self):
        path = Path(self.tmp) / "config.json"
        path.write_text(json.dumps(VALID), encoding="utf-8")
        self.assertEqual([agent.name for agent in load_config(path)], ["claude", "codex"])

    def test_missing_file_error_tells_the_operator_what_to_run(self):
        path = Path(self.tmp) / "nope" / "config.json"
        with self.assertRaises(ConfigError) as caught:
            load_config(path)
        message = str(caught.exception)
        self.assertIn("config.example.json", message)
        self.assertIn(str(path), message)

    def test_malformed_json_error_names_the_validator(self):
        path = Path(self.tmp) / "config.json"
        path.write_text("{not json", encoding="utf-8")
        with self.assertRaises(ConfigError) as caught:
            load_config(path)
        self.assertIn("json.tool", str(caught.exception))

    def test_directory_instead_of_file_is_rejected(self):
        path = Path(self.tmp) / "adir"
        path.mkdir()
        with self.assertRaises(ConfigError):
            load_config(path)


class DefaultPathTest(unittest.TestCase):
    def setUp(self):
        self.original = os.environ.get("XDG_CONFIG_HOME")
        self.addCleanup(self._restore)

    def _restore(self):
        if self.original is None:
            os.environ.pop("XDG_CONFIG_HOME", None)
        else:
            os.environ["XDG_CONFIG_HOME"] = self.original

    def test_honours_xdg_config_home(self):
        os.environ["XDG_CONFIG_HOME"] = "/somewhere/cfg"
        self.assertEqual(default_config_path(), Path("/somewhere/cfg/teamlead/config.json"))

    def test_falls_back_to_dot_config(self):
        os.environ.pop("XDG_CONFIG_HOME", None)
        self.assertEqual(
            default_config_path(), Path.home() / ".config" / "teamlead" / "config.json"
        )


class SelectAgentsTest(unittest.TestCase):
    def setUp(self):
        self.agents = parse_config(VALID)

    def test_no_names_selects_everything_in_config_order(self):
        self.assertEqual([a.name for a in select_agents(self.agents, None)], ["claude", "codex"])
        self.assertEqual([a.name for a in select_agents(self.agents, [])], ["claude", "codex"])

    def test_named_subset_keeps_config_order(self):
        self.assertEqual([a.name for a in select_agents(self.agents, ["codex"])], ["codex"])
        selected = select_agents(self.agents, ["codex", "claude"])
        self.assertEqual([a.name for a in selected], ["claude", "codex"])

    def test_unknown_name_is_an_error_not_a_silent_skip(self):
        with self.assertRaises(ConfigError) as caught:
            select_agents(self.agents, ["grok"])
        self.assertIn("grok", str(caught.exception))


class RoleCostsTest(unittest.TestCase):
    """The optional `role_costs` override the planner merges over its defaults."""

    def _with(self, costs):
        payload = dict(VALID)
        payload["role_costs"] = costs
        return payload

    def test_a_config_without_role_costs_has_no_overrides(self):
        self.assertEqual(parse_role_costs(VALID), {})

    def test_values_come_back_as_floats(self):
        self.assertEqual(
            parse_role_costs(self._with({"developer": 12, "reviewer": 5.5})),
            {"developer": 12.0, "reviewer": 5.5},
        )

    def test_zero_is_a_legal_weight(self):
        self.assertEqual(parse_role_costs(self._with({"reviewer": 0})), {"reviewer": 0.0})

    def test_a_non_object_role_costs_is_an_error_naming_the_file(self):
        with self.assertRaises(ConfigError) as caught:
            parse_role_costs(self._with([12, 10, 5]), source="/tmp/config.json")
        self.assertIn("/tmp/config.json", str(caught.exception))
        self.assertIn("role_costs", str(caught.exception))

    def test_a_negative_weight_is_an_error(self):
        with self.assertRaises(ConfigError) as caught:
            parse_role_costs(self._with({"developer": -1}))
        self.assertIn("developer", str(caught.exception))

    def test_a_non_numeric_weight_is_an_error(self):
        with self.assertRaises(ConfigError) as caught:
            parse_role_costs(self._with({"developer": "heavy"}))
        self.assertIn("heavy", str(caught.exception))

    def test_a_boolean_weight_is_an_error_not_one_point(self):
        with self.assertRaises(ConfigError) as caught:
            parse_role_costs(self._with({"developer": True}))
        self.assertIn("developer", str(caught.exception))

    def test_an_unorderable_weight_is_an_error(self):
        with self.assertRaises(ConfigError) as caught:
            parse_role_costs(self._with({"developer": float("inf")}))
        self.assertIn("developer", str(caught.exception))


class LoadRoleCostsTest(unittest.TestCase):
    def setUp(self):
        self.tmp = Path(tempfile.mkdtemp(prefix="teamlead-costs-test-"))
        self.addCleanup(shutil.rmtree, self.tmp)
        self.path = self.tmp / "config.json"

    def test_no_config_file_means_no_overrides(self):
        # `plan` contacts no agent, so it runs on a machine never set up.
        self.assertEqual(load_role_costs(self.path), {})

    def test_reads_the_map_from_the_file(self):
        payload = dict(VALID)
        payload["role_costs"] = {"tester": 20}
        self.path.write_text(json.dumps(payload), encoding="utf-8")
        self.assertEqual(load_role_costs(self.path), {"tester": 20.0})

    def test_a_config_that_exists_and_is_broken_still_fails_loudly(self):
        self.path.write_text("{not json", encoding="utf-8")
        with self.assertRaises(ConfigError) as caught:
            load_role_costs(self.path)
        self.assertIn(str(self.path), str(caught.exception))

    def test_the_shipped_example_parses(self):
        example = json.loads(
            (REPO_ROOT / "config.example.json").read_text(encoding="utf-8")
        )
        self.assertEqual(
            parse_role_costs(example),
            {"developer": 12.0, "tester": 10.0, "reviewer": 5.0},
        )


class AgentValueObjectTest(unittest.TestCase):
    def test_as_dict_round_trips_through_parse_config(self):
        agent = parse_config(VALID)[0]
        rebuilt = parse_config({"schema_version": 1, "agents": [agent.as_dict()]})[0]
        self.assertEqual(agent, rebuilt)

    def test_equality_is_by_value(self):
        self.assertNotEqual(parse_config(VALID)[0], parse_config(VALID)[1])
        self.assertEqual(
            Agent("a", "claude", "/usage", "m", "visible", "/clear"),
            Agent("a", "claude", "/usage", "m", "visible", "/clear"),
        )


if __name__ == "__main__":
    unittest.main()

skills

README.md

tile.json