mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-07 03:00:29 +00:00
parent
318fc6b17d
commit
094dc47722
5 changed files with 825 additions and 209 deletions
826
run.json
826
run.json
File diff suppressed because one or more lines are too long
173
stages/003-impl_setup@1/diff.patch
Normal file
173
stages/003-impl_setup@1/diff.patch
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
diff --git a/solitaire-app/README.md b/solitaire-app/README.md
|
||||
new file mode 100644
|
||||
index 000000000..e176b81f5
|
||||
--- /dev/null
|
||||
+++ b/solitaire-app/README.md
|
||||
@@ -0,0 +1,29 @@
|
||||
+# Terminal Klondike Solitaire
|
||||
+
|
||||
+A terminal-based Klondike Solitaire game in Python 3.11+ using the standard `curses` library.
|
||||
+
|
||||
+## Features
|
||||
+- Standard Draw-One Klondike Solitaire rules
|
||||
+- Fully keyboard-driven curses TUI
|
||||
+- Unlimited Undo functionality
|
||||
+- Auto-move to foundations
|
||||
+- Fully testable pure Python core game engine
|
||||
+
|
||||
+## Installation & Running
|
||||
+
|
||||
+To run the game, use:
|
||||
+```bash
|
||||
+python3 main.py
|
||||
+```
|
||||
+
|
||||
+To run smoke tests (non-interactive):
|
||||
+```bash
|
||||
+python3 main.py --smoke
|
||||
+```
|
||||
+
|
||||
+## Testing
|
||||
+To run the automated tests using pytest:
|
||||
+```bash
|
||||
+cd solitaire-app
|
||||
+pytest
|
||||
+```
|
||||
diff --git a/solitaire-app/main.py b/solitaire-app/main.py
|
||||
index 71febf900..9715c3a3c 100644
|
||||
--- a/solitaire-app/main.py
|
||||
+++ b/solitaire-app/main.py
|
||||
@@ -1,15 +1,24 @@
|
||||
import sys
|
||||
+import os
|
||||
import argparse
|
||||
import unittest
|
||||
|
||||
+# Ensure the "src" directory and current directory are on sys.path so imports work seamlessly
|
||||
+current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
+src_dir = os.path.join(current_dir, "src")
|
||||
+if src_dir not in sys.path:
|
||||
+ sys.path.insert(0, src_dir)
|
||||
+if current_dir not in sys.path:
|
||||
+ sys.path.insert(1, current_dir)
|
||||
+
|
||||
def run_smoke_test() -> None:
|
||||
"""Proves imports work, instantiates core classes, and runs self-tests."""
|
||||
print("Running Solitaire smoke tests...")
|
||||
|
||||
# 1. Test Imports
|
||||
try:
|
||||
- from game import Card, GameState
|
||||
- from ui import SolitaireTUI
|
||||
+ from solitaire_tui.game import Card, GameState
|
||||
+ from solitaire_tui.ui import SolitaireTUI
|
||||
print("✓ Successfully imported core modules (game, ui).")
|
||||
except Exception as e:
|
||||
print(f"✗ Failed to import core modules: {e}")
|
||||
@@ -29,9 +38,14 @@ def run_smoke_test() -> None:
|
||||
# 3. Run full unit tests to confirm rule-engine validity
|
||||
print("Running automated unit tests...")
|
||||
loader = unittest.TestLoader()
|
||||
- # Discover and run tests in the solitaire-app folder
|
||||
- from test_game import TestSolitaireGame
|
||||
- suite = loader.loadTestsFromTestCase(TestSolitaireGame)
|
||||
+ # Discover and run tests
|
||||
+ try:
|
||||
+ from tests.test_game import TestSolitaireGame
|
||||
+ suite = loader.loadTestsFromTestCase(TestSolitaireGame)
|
||||
+ except Exception as e:
|
||||
+ print(f"✗ Failed to import tests: {e}")
|
||||
+ sys.exit(1)
|
||||
+
|
||||
runner = unittest.TextTestRunner(verbosity=1)
|
||||
result = runner.run(suite)
|
||||
|
||||
@@ -58,8 +72,8 @@ def main() -> None:
|
||||
|
||||
# Normal execution starts curses-based TUI
|
||||
import curses
|
||||
- from game import GameState
|
||||
- from ui import SolitaireTUI
|
||||
+ from solitaire_tui.game import GameState
|
||||
+ from solitaire_tui.ui import SolitaireTUI
|
||||
|
||||
game = GameState()
|
||||
tui = SolitaireTUI(game)
|
||||
diff --git a/solitaire-app/pyproject.toml b/solitaire-app/pyproject.toml
|
||||
new file mode 100644
|
||||
index 000000000..1f5ee0594
|
||||
--- /dev/null
|
||||
+++ b/solitaire-app/pyproject.toml
|
||||
@@ -0,0 +1,26 @@
|
||||
+[build-system]
|
||||
+requires = ["setuptools>=61.0.0", "wheel"]
|
||||
+build-backend = "setuptools.build_meta"
|
||||
+
|
||||
+[project]
|
||||
+name = "solitaire-tui"
|
||||
+version = "0.1.0"
|
||||
+description = "A terminal-based Klondike solitaire game in Python with a curses TUI"
|
||||
+readme = "README.md"
|
||||
+requires-python = ">=3.11"
|
||||
+classifiers = [
|
||||
+ "Programming Language :: Python :: 3",
|
||||
+ "License :: OSI Approved :: MIT License",
|
||||
+ "Operating System :: OS Independent",
|
||||
+]
|
||||
+dependencies = []
|
||||
+
|
||||
+[tool.pytest.ini_options]
|
||||
+minversion = "6.0"
|
||||
+addopts = "-ra -q"
|
||||
+testpaths = [
|
||||
+ "tests",
|
||||
+]
|
||||
+pythonpath = [
|
||||
+ "src"
|
||||
+]
|
||||
diff --git a/solitaire-app/src/solitaire_tui/__init__.py b/solitaire-app/src/solitaire_tui/__init__.py
|
||||
new file mode 100644
|
||||
index 000000000..a1c1ef18a
|
||||
--- /dev/null
|
||||
+++ b/solitaire-app/src/solitaire_tui/__init__.py
|
||||
@@ -0,0 +1 @@
|
||||
+# solitaire_tui package
|
||||
diff --git a/solitaire-app/game.py b/solitaire-app/src/solitaire_tui/game.py
|
||||
similarity index 100%
|
||||
rename from solitaire-app/game.py
|
||||
rename to solitaire-app/src/solitaire_tui/game.py
|
||||
diff --git a/solitaire-app/ui.py b/solitaire-app/src/solitaire_tui/ui.py
|
||||
similarity index 99%
|
||||
rename from solitaire-app/ui.py
|
||||
rename to solitaire-app/src/solitaire_tui/ui.py
|
||||
index 9950c1459..6705819aa 100644
|
||||
--- a/solitaire-app/ui.py
|
||||
+++ b/solitaire-app/src/solitaire_tui/ui.py
|
||||
@@ -1,5 +1,5 @@
|
||||
import curses
|
||||
-from game import GameState, Card
|
||||
+from .game import GameState, Card
|
||||
from typing import Optional, Tuple
|
||||
|
||||
class SolitaireTUI:
|
||||
diff --git a/solitaire-app/tests/__init__.py b/solitaire-app/tests/__init__.py
|
||||
new file mode 100644
|
||||
index 000000000..65140f2e3
|
||||
--- /dev/null
|
||||
+++ b/solitaire-app/tests/__init__.py
|
||||
@@ -0,0 +1 @@
|
||||
+# tests package
|
||||
diff --git a/solitaire-app/test_game.py b/solitaire-app/tests/test_game.py
|
||||
similarity index 99%
|
||||
rename from solitaire-app/test_game.py
|
||||
rename to solitaire-app/tests/test_game.py
|
||||
index 4b7c2bce1..03ec90162 100644
|
||||
--- a/solitaire-app/test_game.py
|
||||
+++ b/solitaire-app/tests/test_game.py
|
||||
@@ -1,5 +1,5 @@
|
||||
import unittest
|
||||
-from game import GameState, Card
|
||||
+from solitaire_tui.game import GameState, Card
|
||||
|
||||
class TestSolitaireGame(unittest.TestCase):
|
||||
def setUp(self):
|
||||
6
stages/003-impl_setup@1/status.json
Normal file
6
stages/003-impl_setup@1/status.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"outcome": "succeeded",
|
||||
"notes": "Stage completed: impl_setup",
|
||||
"failure_reason": null,
|
||||
"timestamp": "2026-06-04T18:17:47.239773Z"
|
||||
}
|
||||
24
stages/004-verify_setup@1/prompt.md
Normal file
24
stages/004-verify_setup@1/prompt.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
Goal: Build a terminal-based Klondike solitaire game in Python with a curses TUI
|
||||
|
||||
## Completed stages
|
||||
- **expand_spec**: succeeded
|
||||
- Model: gemini-3.5-flash, 140.8k tokens in / 24.8k out
|
||||
- Files: /home/daytona/workspace/fabro/.ai/solitaire-spec.md, /home/daytona/workspace/fabro/solitaire-app/game.py, /home/daytona/workspace/fabro/solitaire-app/main.py, /home/daytona/workspace/fabro/solitaire-app/test_game.py, /home/daytona/workspace/fabro/solitaire-app/ui.py, /home/daytona/workspace/fabro/status.json
|
||||
- **impl_setup**: succeeded
|
||||
- Model: gemini-3.5-flash, 148.0k tokens in / 18.3k out
|
||||
- Files: /home/daytona/workspace/fabro/solitaire-app/README.md, /home/daytona/workspace/fabro/solitaire-app/main.py, /home/daytona/workspace/fabro/solitaire-app/pyproject.toml, /home/daytona/workspace/fabro/solitaire-app/src/solitaire_tui/__init__.py, /home/daytona/workspace/fabro/solitaire-app/src/solitaire_tui/game.py, /home/daytona/workspace/fabro/solitaire-app/src/solitaire_tui/ui.py, /home/daytona/workspace/fabro/solitaire-app/tests/__init__.py, /home/daytona/workspace/fabro/solitaire-app/tests/test_game.py, /home/daytona/workspace/fabro/status.json
|
||||
|
||||
|
||||
Verify setup for the solitaire app.
|
||||
|
||||
Check:
|
||||
1. solitaire-app/pyproject.toml exists
|
||||
2. solitaire-app/main.py exists
|
||||
3. solitaire-app/src/solitaire_tui exists
|
||||
4. Python files compile
|
||||
|
||||
Run:
|
||||
cd solitaire-app && python3 -m py_compile main.py src/solitaire_tui/*.py
|
||||
|
||||
Write findings to .ai/verify_setup.md.
|
||||
Write status.json at workspace root: outcome=succeeded if all checks pass, outcome=failed with failure_reason otherwise.
|
||||
5
stages/004-verify_setup@1/provider_used.json
Normal file
5
stages/004-verify_setup@1/provider_used.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"mode": "agent",
|
||||
"provider": "gemini",
|
||||
"model": "gemini-3.5-flash"
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue