From 94b7579b8d1319f0041a61322e8bd31f9951a46b Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 20 Sep 2026 14:09:44 +0000 Subject: [PATCH 1/2] Make CI pass: fix .flake8 and the 99 hard lint errors it was hiding The root .flake8 put inline comments inside multi-line option values, which flake8 >= 5 rejects, so the workflow's first lint step has crashed on every run since it was added. With the config fixed, the strict step (E9,F63,F7,F82) reported 99 pre-existing errors in 24 files. This commit fixes the config and all of them: - .flake8: comments moved out of option values; import-order-style dropped (plugin not installed). - Two syntax errors: an unterminated string in autopy.py and an empty `if __name__ == '__main__':` block in zhive-mind.py. - Missing imports (os, re, sys, shutil, subprocess, requests, anthropic, tkinter) in 19 files. - Real bugs: nomic.py used `response.content` for a variable named `response_content`; inn_mono_gui.py referenced its nested QuestionDialog class without `self.`; both harmonized_api_wrappers.py called an undefined `MonsterAPI` instead of the imported `client`; 4x/colony_management.py subclassed four never-defined base classes and read a free variable `threats` (now a parameter with an empty default); 4x/tech_tree.py's demo code used an undefined `game_state`. - shared_utils.setup_logging: basicConfig is a no-op once the root logger has handlers (as under pytest), leaving the named logger at WARNING and the file handler silent; set the logger level explicitly. This fixes the one failing root test. Locally: `flake8 . --select=E9,F63,F7,F82` -> 0; root `pytest` -> 19 passed; `pytest langtons_highway/tests` -> 8 passed. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01DVvB1dWEhjyBKh95Zojt3F --- .flake8 | 21 +++---------- 4x/colony_management.py | 31 +++++++++++++++++++- 4x/tech_tree.py | 1 + MDtoHTML/formatter.py | 1 + MakeMarkdown/txttomd.py | 1 + ant/ant.py | 1 + bookmaker/bookmaker.py | 1 + bookmaker/harmonized_api_wrappers.py | 2 +- brainstorm/brainstorm.py | 1 + brainstorm/harmonized_api_wrappers.py | 2 +- chatter/chatter-user.py | 1 + hive-mind/Z/zhive-mind.py | 1 + hive-mind/hive-mind-2/hivemind2.py | 1 + hive-mind/hive-mind/hive-mind.py | 2 ++ iPhone toss to Mac/WatchCharm.py | 1 + iPhone toss to Mac/autopy.py | 3 +- iPhone toss to Mac/mover.py | 1 + iPhone toss to Mac/old/inefficientwatcher.py | 1 + iPhone toss to Mac/scriptrunner.py | 1 + inner_monologue/inn_mono_gui.py | 3 +- llmchatroom/llmchatroom.py | 1 + movelog/movelog.py | 1 + mover/mover.py | 1 + noder/noder.py | 1 + nomic/nomic.py | 4 ++- shared_utils.py | 1 + 26 files changed, 63 insertions(+), 23 deletions(-) diff --git a/.flake8 b/.flake8 index 37b63d6..3a04f8f 100644 --- a/.flake8 +++ b/.flake8 @@ -1,26 +1,13 @@ [flake8] max-line-length = 88 -extend-ignore = - E203, # whitespace before ':' - E501, # line too long (handled by black) - W503, # line break before binary operator - E402, # module level import not at top of file (common in scripts) -exclude = - .git, - __pycache__, - .venv, - venv, - .pytest_cache, - *.egg-info, - build, - dist +# E203 whitespace before ':', E501 line too long (black), W503 line break before +# binary operator, E402 module level import not at top (common in scripts) +extend-ignore = E203,E501,W503,E402 +exclude = .git,__pycache__,.venv,venv,.pytest_cache,*.egg-info,build,dist per-file-ignores = - # Allow longer lines in certain files */4x/*.py:E501 */hive-mind/*.py:E501 - # Allow print statements in CLI scripts */ant/*.py:T201 */allseeingeye/*.py:T201 */mover/*.py:T201 max-complexity = 15 -import-order-style = google \ No newline at end of file diff --git a/4x/colony_management.py b/4x/colony_management.py index c553dda..0b1412a 100644 --- a/4x/colony_management.py +++ b/4x/colony_management.py @@ -1,6 +1,35 @@ import random import heapq + +class Infrastructure: + """Base class for colony buildings.""" + + def __init__(self): + self.cost = {} + self.maintenance = 0 + + +class Colonist: + """Base class for colonist specialisations.""" + + def __init__(self): + self.skills = {} + + +class EnvironmentalHazard: + """Base class for environmental hazards a colony can suffer.""" + + def __init__(self): + self.severity = 0 + + +class DefensePlatform: + """A defensive installation.""" + + def __init__(self): + self.strength = 1 + # Colony management class Colony: def __init__(self, name, location, resources, population=100, infrastructure=0): @@ -54,7 +83,7 @@ def __init__(self, colony): self.defense_platforms = [] self.shields = 0 - def update(self, time_step): + def update(self, time_step, threats=()): # Defend against threats for threat in threats: if self.engage(threat): diff --git a/4x/tech_tree.py b/4x/tech_tree.py index 6770a6f..d248ceb 100644 --- a/4x/tech_tree.py +++ b/4x/tech_tree.py @@ -126,6 +126,7 @@ def apply_technology_effects(tech_id: str, game_state: dict): allocated_resources = optimize_research(tech_tree, resources, strategic_goals) # Apply technology effects +game_state = {} for tech_id, cost in allocated_resources.items(): tech_tree.unlock_technology(tech_id) apply_technology_effects(tech_id, game_state) diff --git a/MDtoHTML/formatter.py b/MDtoHTML/formatter.py index 4bd055c..bf6ee6d 100644 --- a/MDtoHTML/formatter.py +++ b/MDtoHTML/formatter.py @@ -1,4 +1,5 @@ # formatter.py +import tkinter as tk from tkinter import simpledialog import webbrowser import markdown2 diff --git a/MakeMarkdown/txttomd.py b/MakeMarkdown/txttomd.py index 1230388..9e1b74f 100644 --- a/MakeMarkdown/txttomd.py +++ b/MakeMarkdown/txttomd.py @@ -1,4 +1,5 @@ # txttomd.py +import os import shutil diff --git a/ant/ant.py b/ant/ant.py index 2a82ab7..bfe7adb 100644 --- a/ant/ant.py +++ b/ant/ant.py @@ -1,3 +1,4 @@ +import os from rich import print from rich.panel import Panel import anthropic diff --git a/bookmaker/bookmaker.py b/bookmaker/bookmaker.py index 6f2d676..7f09bb8 100644 --- a/bookmaker/bookmaker.py +++ b/bookmaker/bookmaker.py @@ -1,4 +1,5 @@ # bookmaker.py +import os import time from harmonized_api_wrappers import APIWrapper diff --git a/bookmaker/harmonized_api_wrappers.py b/bookmaker/harmonized_api_wrappers.py index 60c043d..ae1a94e 100644 --- a/bookmaker/harmonized_api_wrappers.py +++ b/bookmaker/harmonized_api_wrappers.py @@ -53,7 +53,7 @@ def process_claude_model(self, model_info, temperature, system_prompt, refined_i def process_monster_model(self, model_info, prompt, parameters): api_key = os.environ.get("MONSTER_API_KEY") - client_instance = MonsterAPI(api_key) + client_instance = client(api_key) response = client_instance.get_response(model=model_info["name"], data={ "prompt": prompt, **parameters diff --git a/brainstorm/brainstorm.py b/brainstorm/brainstorm.py index fb3b4a1..489ec0e 100644 --- a/brainstorm/brainstorm.py +++ b/brainstorm/brainstorm.py @@ -1,4 +1,5 @@ # brainstorm.py +import os from harmonized_api_wrappers import APIWrapper def create_new_story(): diff --git a/brainstorm/harmonized_api_wrappers.py b/brainstorm/harmonized_api_wrappers.py index 60c043d..ae1a94e 100644 --- a/brainstorm/harmonized_api_wrappers.py +++ b/brainstorm/harmonized_api_wrappers.py @@ -53,7 +53,7 @@ def process_claude_model(self, model_info, temperature, system_prompt, refined_i def process_monster_model(self, model_info, prompt, parameters): api_key = os.environ.get("MONSTER_API_KEY") - client_instance = MonsterAPI(api_key) + client_instance = client(api_key) response = client_instance.get_response(model=model_info["name"], data={ "prompt": prompt, **parameters diff --git a/chatter/chatter-user.py b/chatter/chatter-user.py index 7da9383..4996ef0 100644 --- a/chatter/chatter-user.py +++ b/chatter/chatter-user.py @@ -1,4 +1,5 @@ # chatter-user.py +import requests import json from datetime import datetime # Configuration for LLMs, with API key for the third model. diff --git a/hive-mind/Z/zhive-mind.py b/hive-mind/Z/zhive-mind.py index 6cf80b3..3a08055 100644 --- a/hive-mind/Z/zhive-mind.py +++ b/hive-mind/Z/zhive-mind.py @@ -337,3 +337,4 @@ def main(): sys.exit(app.exec_()) if __name__ == '__main__': + main() diff --git a/hive-mind/hive-mind-2/hivemind2.py b/hive-mind/hive-mind-2/hivemind2.py index 458385e..ba2184a 100644 --- a/hive-mind/hive-mind-2/hivemind2.py +++ b/hive-mind/hive-mind-2/hivemind2.py @@ -1,3 +1,4 @@ +import os import logging import re import sys diff --git a/hive-mind/hive-mind/hive-mind.py b/hive-mind/hive-mind/hive-mind.py index c701f6d..9a6708b 100644 --- a/hive-mind/hive-mind/hive-mind.py +++ b/hive-mind/hive-mind/hive-mind.py @@ -1,4 +1,6 @@ # hive-mind.py +import os +import re import sys import logging import xml.etree.ElementTree as ET diff --git a/iPhone toss to Mac/WatchCharm.py b/iPhone toss to Mac/WatchCharm.py index 9d58744..54bcf1e 100644 --- a/iPhone toss to Mac/WatchCharm.py +++ b/iPhone toss to Mac/WatchCharm.py @@ -1,4 +1,5 @@ # WatchCharm.py +import os import shutil from watchdog.events import FileSystemEventHandler diff --git a/iPhone toss to Mac/autopy.py b/iPhone toss to Mac/autopy.py index 0cdd30b..7473da5 100644 --- a/iPhone toss to Mac/autopy.py +++ b/iPhone toss to Mac/autopy.py @@ -1,4 +1,5 @@ # autopy.py +import os import subprocess import time @@ -41,7 +42,7 @@ def on_created(self, event): if __name__ == "__main__": - path = '/PATH/charm + path = '/PATH/charm' event_handler = NewFileHandler() observer = Observer() observer.schedule(event_handler, path, recursive=False) diff --git a/iPhone toss to Mac/mover.py b/iPhone toss to Mac/mover.py index 7929d81..68d9899 100644 --- a/iPhone toss to Mac/mover.py +++ b/iPhone toss to Mac/mover.py @@ -1,4 +1,5 @@ # mover.py +import shutil from pathlib import Path # Source directory to monitor diff --git a/iPhone toss to Mac/old/inefficientwatcher.py b/iPhone toss to Mac/old/inefficientwatcher.py index ac0f111..31304d5 100644 --- a/iPhone toss to Mac/old/inefficientwatcher.py +++ b/iPhone toss to Mac/old/inefficientwatcher.py @@ -1,4 +1,5 @@ # inefficientwatcher.py +import os import time diff --git a/iPhone toss to Mac/scriptrunner.py b/iPhone toss to Mac/scriptrunner.py index 93b0c0a..3c97bbf 100644 --- a/iPhone toss to Mac/scriptrunner.py +++ b/iPhone toss to Mac/scriptrunner.py @@ -1,3 +1,4 @@ +import subprocess # _scriptrunner.py diff --git a/inner_monologue/inn_mono_gui.py b/inner_monologue/inn_mono_gui.py index 7925bb6..820d495 100644 --- a/inner_monologue/inn_mono_gui.py +++ b/inner_monologue/inn_mono_gui.py @@ -1,3 +1,4 @@ +import sys from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QTextEdit, QSpinBox, QDoubleSpinBox, QDialog from inner_monologue import InnerMonologue @@ -95,7 +96,7 @@ def get_response(self): return self.text_edit.toPlainText() def ask_user_question(self, question): - dialog = QuestionDialog(question) + dialog = self.QuestionDialog(question) if dialog.exec_() == QDialog.Accepted: return dialog.get_response() return "" diff --git a/llmchatroom/llmchatroom.py b/llmchatroom/llmchatroom.py index 3ab3f17..644a46f 100644 --- a/llmchatroom/llmchatroom.py +++ b/llmchatroom/llmchatroom.py @@ -1,4 +1,5 @@ # llmchatroom.py +import requests import json from datetime import datetime from queue import Queue diff --git a/movelog/movelog.py b/movelog/movelog.py index 819cc6a..e659122 100644 --- a/movelog/movelog.py +++ b/movelog/movelog.py @@ -1,4 +1,5 @@ # movelog.py +import os import shutil # Set the directory where you want to search for log files diff --git a/mover/mover.py b/mover/mover.py index 34a3e67..4a4f175 100644 --- a/mover/mover.py +++ b/mover/mover.py @@ -1,4 +1,5 @@ # mover.py +import shutil from pathlib import Path # Source directory to monitor diff --git a/noder/noder.py b/noder/noder.py index 0cf601d..531c747 100644 --- a/noder/noder.py +++ b/noder/noder.py @@ -1,4 +1,5 @@ # Noder.py +import anthropic import xml.etree.ElementTree as ET from termcolor import colored from pyfiglet import figlet_format diff --git a/nomic/nomic.py b/nomic/nomic.py index af3e40e..6546409 100644 --- a/nomic/nomic.py +++ b/nomic/nomic.py @@ -1,4 +1,6 @@ # nomic.py +import re +import anthropic import time import json import random @@ -271,7 +273,7 @@ def play_game(): response_content = make_api_call(llm_id, game_state, history) history += response_content - game_state = update_game_state(game_state, response.content) # Use the response content + game_state = update_game_state(game_state, response_content) # Use the response content for player in game_state["players"]: if player["points"] >= 150: diff --git a/shared_utils.py b/shared_utils.py index 7da88b5..46c46e0 100644 --- a/shared_utils.py +++ b/shared_utils.py @@ -89,6 +89,7 @@ def setup_logging( ) logger = logging.getLogger(__name__.split('.')[0]) + logger.setLevel(getattr(logging, level.upper())) # Console handler console_handler = logging.StreamHandler() From 3c2dcfa321c942371e756b7b749cb2db2fa30072 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 20 Sep 2026 14:39:55 +0000 Subject: [PATCH 2/2] nomic: extract text from Anthropic content blocks in make_api_call make_api_call returned response.content, which the Anthropic Messages API delivers as a list of content blocks rather than a string. Both consumers then failed on the first turn: `history += response_content` raised TypeError (str + list), and update_game_state's re.findall could not parse a list. Return response.content[0].text instead, matching the six other Anthropic call sites in this repository. Reported by the Codex review bot on #18. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01DVvB1dWEhjyBKh95Zojt3F --- nomic/nomic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nomic/nomic.py b/nomic/nomic.py index 6546409..7d81d7c 100644 --- a/nomic/nomic.py +++ b/nomic/nomic.py @@ -217,8 +217,8 @@ def make_api_call(llm_id, game_state, history): messages=[{"role": "user", "content": prompt}], ) - # Access the content directly from the Message object - response_content = response.content + # Extract the text from the Message object's content blocks + response_content = response.content[0].text return response_content def extract_proposed_rules(response):