adversarial-workflow 0.6.0__py3-none-any.whl → 0.6.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- adversarial_workflow/__init__.py +1 -1
- adversarial_workflow/cli.py +29 -10
- {adversarial_workflow-0.6.0.dist-info → adversarial_workflow-0.6.1.dist-info}/METADATA +34 -4
- {adversarial_workflow-0.6.0.dist-info → adversarial_workflow-0.6.1.dist-info}/RECORD +8 -8
- {adversarial_workflow-0.6.0.dist-info → adversarial_workflow-0.6.1.dist-info}/WHEEL +0 -0
- {adversarial_workflow-0.6.0.dist-info → adversarial_workflow-0.6.1.dist-info}/entry_points.txt +0 -0
- {adversarial_workflow-0.6.0.dist-info → adversarial_workflow-0.6.1.dist-info}/licenses/LICENSE +0 -0
- {adversarial_workflow-0.6.0.dist-info → adversarial_workflow-0.6.1.dist-info}/top_level.txt +0 -0
adversarial_workflow/__init__.py
CHANGED
adversarial_workflow/cli.py
CHANGED
|
@@ -27,9 +27,9 @@ from pathlib import Path
|
|
|
27
27
|
from typing import Dict, List, Optional, Tuple
|
|
28
28
|
|
|
29
29
|
import yaml
|
|
30
|
-
from dotenv import load_dotenv
|
|
30
|
+
from dotenv import load_dotenv, dotenv_values
|
|
31
31
|
|
|
32
|
-
__version__ = "0.6.
|
|
32
|
+
__version__ = "0.6.1"
|
|
33
33
|
|
|
34
34
|
# ANSI color codes for better output
|
|
35
35
|
RESET = "\033[0m"
|
|
@@ -800,26 +800,37 @@ def check() -> int:
|
|
|
800
800
|
issues: List[Dict] = []
|
|
801
801
|
good_checks: List[str] = []
|
|
802
802
|
|
|
803
|
-
# Check for .env file
|
|
803
|
+
# Check for .env file (note: already loaded by main() at startup)
|
|
804
804
|
env_file = Path(".env")
|
|
805
805
|
env_loaded = False
|
|
806
|
-
env_keys_before = set(os.environ.keys())
|
|
807
806
|
|
|
808
807
|
if env_file.exists():
|
|
809
808
|
try:
|
|
809
|
+
# Load .env into environment (idempotent - safe to call again after main())
|
|
810
810
|
load_dotenv(env_file)
|
|
811
|
-
|
|
812
|
-
|
|
811
|
+
# Use dotenv_values() to count variables directly from file
|
|
812
|
+
# This gives accurate count regardless of what was already in environment
|
|
813
|
+
env_vars = dotenv_values(env_file)
|
|
813
814
|
env_loaded = True
|
|
814
815
|
good_checks.append(
|
|
815
|
-
f".env file found
|
|
816
|
+
f".env file found ({len(env_vars)} variables configured)"
|
|
816
817
|
)
|
|
817
|
-
except
|
|
818
|
+
except (FileNotFoundError, PermissionError) as e:
|
|
819
|
+
# File access errors
|
|
818
820
|
issues.append(
|
|
819
821
|
{
|
|
820
822
|
"severity": "WARNING",
|
|
821
|
-
"message": f".env file found but could not be
|
|
822
|
-
"fix": "Check .env file
|
|
823
|
+
"message": f".env file found but could not be read: {e}",
|
|
824
|
+
"fix": "Check .env file permissions",
|
|
825
|
+
}
|
|
826
|
+
)
|
|
827
|
+
except (OSError, ValueError) as e:
|
|
828
|
+
# Covers UnicodeDecodeError (ValueError subclass) and other OS errors
|
|
829
|
+
issues.append(
|
|
830
|
+
{
|
|
831
|
+
"severity": "WARNING",
|
|
832
|
+
"message": f".env file found but could not be parsed: {e}",
|
|
833
|
+
"fix": "Check .env file encoding (should be UTF-8)",
|
|
823
834
|
}
|
|
824
835
|
)
|
|
825
836
|
else:
|
|
@@ -2868,6 +2879,14 @@ def list_evaluators() -> int:
|
|
|
2868
2879
|
def main():
|
|
2869
2880
|
"""Main CLI entry point."""
|
|
2870
2881
|
import logging
|
|
2882
|
+
import sys
|
|
2883
|
+
|
|
2884
|
+
# Load .env file before any commands run
|
|
2885
|
+
# Wrapped in try/except so CLI remains usable even with malformed .env
|
|
2886
|
+
try:
|
|
2887
|
+
load_dotenv()
|
|
2888
|
+
except Exception as e:
|
|
2889
|
+
print(f"Warning: Could not load .env file: {e}", file=sys.stderr)
|
|
2871
2890
|
|
|
2872
2891
|
from adversarial_workflow.evaluators import (
|
|
2873
2892
|
get_all_evaluators,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: adversarial-workflow
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.1
|
|
4
4
|
Summary: Multi-stage AI code review system preventing phantom work - Author/Evaluator pattern
|
|
5
5
|
Author: Fredrik Matheson
|
|
6
6
|
License: MIT
|
|
@@ -35,6 +35,10 @@ Dynamic: license-file
|
|
|
35
35
|
|
|
36
36
|
# Adversarial Workflow
|
|
37
37
|
|
|
38
|
+
[](https://pypi.org/project/adversarial-workflow/)
|
|
39
|
+
[](https://www.python.org/downloads/)
|
|
40
|
+
[](https://opensource.org/licenses/MIT)
|
|
41
|
+
|
|
38
42
|
**A multi-stage AI code review system that makes your code better**
|
|
39
43
|
|
|
40
44
|
Evaluate proposals, sort out ideas, and prevent "phantom work" (AI claiming to implement but not delivering) through adversarial verification using independent review stages. A battle-tested workflow from the [thematic-cuts](https://github.com/movito/thematic-cuts) project that achieved 96.9% test pass rate improvement.
|
|
@@ -51,6 +55,31 @@ Evaluate proposals, sort out ideas, and prevent "phantom work" (AI claiming to i
|
|
|
51
55
|
- 🎯 **Tool-agnostic**: Use with Claude Code, Cursor, Aider, manual coding, or any workflow
|
|
52
56
|
- ✨ **Interactive onboarding**: Guided setup wizard gets you started in <5 minutes
|
|
53
57
|
|
|
58
|
+
## What's New in v0.6.0
|
|
59
|
+
|
|
60
|
+
🔌 **Plugin Architecture** - Define custom evaluators without modifying the package:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Create a custom evaluator
|
|
64
|
+
mkdir -p .adversarial/evaluators
|
|
65
|
+
cat > .adversarial/evaluators/athena.yml << 'EOF'
|
|
66
|
+
name: athena
|
|
67
|
+
description: Knowledge evaluation using Gemini 2.5 Pro
|
|
68
|
+
model: gemini-2.5-pro
|
|
69
|
+
api_key_env: GEMINI_API_KEY
|
|
70
|
+
prompt: |
|
|
71
|
+
You are Athena, a knowledge evaluation specialist...
|
|
72
|
+
EOF
|
|
73
|
+
|
|
74
|
+
# Use it immediately
|
|
75
|
+
adversarial athena docs/research-plan.md
|
|
76
|
+
|
|
77
|
+
# List all available evaluators
|
|
78
|
+
adversarial list-evaluators
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
See [Custom Evaluators](#custom-evaluators) for full documentation, or check the [CHANGELOG](CHANGELOG.md) for complete release history.
|
|
82
|
+
|
|
54
83
|
## Prerequisites
|
|
55
84
|
|
|
56
85
|
Before installing, ensure you have:
|
|
@@ -856,12 +885,13 @@ From the [thematic-cuts](https://github.com/movito/thematic-cuts) project:
|
|
|
856
885
|
|
|
857
886
|
## Documentation
|
|
858
887
|
|
|
859
|
-
- **
|
|
888
|
+
- **[Custom Evaluators Guide](docs/CUSTOM_EVALUATORS.md)**: Create project-specific evaluators
|
|
889
|
+
- **[Integration Guide](docs/INTEGRATION-GUIDE.md)**: Detailed integration strategies
|
|
890
|
+
- **[CHANGELOG](CHANGELOG.md)**: Release history and version notes
|
|
891
|
+
- **Interaction Patterns**: How Author-Evaluator collaboration works
|
|
860
892
|
- **Token Optimization**: Detailed Aider configuration guide
|
|
861
893
|
- **Workflow Phases**: Step-by-step guide for each phase
|
|
862
894
|
- **Troubleshooting**: Common issues and solutions
|
|
863
|
-
- **Examples**: Real integration scenarios
|
|
864
|
-
- **Terminology**: Official standards for Author/Reviewer concepts
|
|
865
895
|
|
|
866
896
|
See `docs/` directory for comprehensive guides.
|
|
867
897
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
adversarial_workflow/__init__.py,sha256=
|
|
1
|
+
adversarial_workflow/__init__.py,sha256=0AhyTbjRHXfTskqMpd272ayiGdU4rfQqAcf9_oJScnA,596
|
|
2
2
|
adversarial_workflow/__main__.py,sha256=Ibb0CngDCh4mpCe8Zxnf3kyKnMddBxQy2JAk_kfTUMQ,119
|
|
3
|
-
adversarial_workflow/cli.py,sha256=
|
|
3
|
+
adversarial_workflow/cli.py,sha256=ckrJNqJiX6Okg5f7UcahaB2-qx8PrnQg5MA6OymKrpY,110065
|
|
4
4
|
adversarial_workflow/evaluators/__init__.py,sha256=vB4gGaoP46a-ZLOeoVKjR6WohAsgeif4JMhaak9AIPo,1266
|
|
5
5
|
adversarial_workflow/evaluators/builtins.py,sha256=u5LokYLe8ruEW2tunhOQaNSkpcZ9Ee2IeTkaC0dZDSY,1102
|
|
6
6
|
adversarial_workflow/evaluators/config.py,sha256=05qYPIiIpCxXBVJzs70WQQLxi8I7MedfhE_oydXEcq0,1520
|
|
@@ -25,9 +25,9 @@ adversarial_workflow/utils/colors.py,sha256=uRrG6KfIDBLo0F5_vPwms9NCm9-x8YXBiyZ4
|
|
|
25
25
|
adversarial_workflow/utils/config.py,sha256=NBoC_-YYukEVo6BgpX2cDyeqV-3tnn_sHNU9L1AuSLQ,1341
|
|
26
26
|
adversarial_workflow/utils/file_splitter.py,sha256=rVRMHJgzJ7uNiytimqbBY8PAr-SevXdRqUpr4xf6LdM,12061
|
|
27
27
|
adversarial_workflow/utils/validation.py,sha256=0QfuRd-kurcadUCd9XQvO-N8RsmLp6ONQnc0vaQTUBA,2188
|
|
28
|
-
adversarial_workflow-0.6.
|
|
29
|
-
adversarial_workflow-0.6.
|
|
30
|
-
adversarial_workflow-0.6.
|
|
31
|
-
adversarial_workflow-0.6.
|
|
32
|
-
adversarial_workflow-0.6.
|
|
33
|
-
adversarial_workflow-0.6.
|
|
28
|
+
adversarial_workflow-0.6.1.dist-info/licenses/LICENSE,sha256=M-dOQlre-NmicyPa55hYOJUW8roGpCKEgtq-z0z1KCA,1073
|
|
29
|
+
adversarial_workflow-0.6.1.dist-info/METADATA,sha256=ItR4yn7PWdP_AsFqDLMQhAkwuxhit76LxkQYHsVDXlo,29955
|
|
30
|
+
adversarial_workflow-0.6.1.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
31
|
+
adversarial_workflow-0.6.1.dist-info/entry_points.txt,sha256=9H-iZ-yF1uKZ8P0G1suc6kWR0NvK7uPZJbhN7nvt1sE,62
|
|
32
|
+
adversarial_workflow-0.6.1.dist-info/top_level.txt,sha256=8irutNxLRjUbTlzfAibIpz7_ovkkF2h8ES69NQpv24c,21
|
|
33
|
+
adversarial_workflow-0.6.1.dist-info/RECORD,,
|
|
File without changes
|
{adversarial_workflow-0.6.0.dist-info → adversarial_workflow-0.6.1.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{adversarial_workflow-0.6.0.dist-info → adversarial_workflow-0.6.1.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|