claude-self-reflect 5.0.2 → 5.0.4

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.
@@ -647,6 +647,8 @@ if __name__ == "__main__":
647
647
  parser.add_argument('--project-name', help='Name of the project for cache file')
648
648
  parser.add_argument('--use-tracker', action='store_true',
649
649
  help='Use session edit tracker for analysis')
650
+ parser.add_argument('--update-cache-only', action='store_true',
651
+ help='Only update cache without printing report')
650
652
  args = parser.parse_args()
651
653
 
652
654
  # If external project specified, change to that directory
@@ -658,4 +660,12 @@ if __name__ == "__main__":
658
660
  # This will be used in the main() function for cache naming
659
661
  os.environ['QUALITY_PROJECT_NAME'] = args.project_name
660
662
 
663
+ # For cache-only mode, suppress output
664
+ if args.update_cache_only:
665
+ # Redirect logger to null
666
+ import os
667
+ import sys
668
+ sys.stdout = open(os.devnull, 'w')
669
+ sys.stderr = open(os.devnull, 'w')
670
+
661
671
  main(use_tracker=args.use_tracker)
@@ -21,7 +21,7 @@ import logging
21
21
  import sys
22
22
  from pathlib import Path
23
23
  from datetime import datetime, timedelta, timezone
24
- from typing import Dict, Any, Optional, List, Set
24
+ from typing import Dict, Any, Optional, List, Set, Union
25
25
  from contextlib import contextmanager
26
26
 
27
27
  # Try to import filelock, fall back to platform-specific implementation
@@ -62,14 +62,17 @@ class UnifiedStateManager:
62
62
  LOCK_TIMEOUT = 5.0
63
63
  LOCK_EXPIRY = timedelta(seconds=30)
64
64
 
65
- def __init__(self, state_file: Optional[Path] = None):
65
+ def __init__(self, state_file: Optional[Union[Path, str]] = None):
66
66
  """
67
67
  Initialize the unified state manager.
68
68
 
69
69
  Args:
70
70
  state_file: Path to the state file (defaults to ~/.claude-self-reflect/config/unified-state.json)
71
71
  """
72
- self.state_file = state_file or Path.home() / ".claude-self-reflect" / "config" / "unified-state.json"
72
+ if state_file:
73
+ self.state_file = Path(state_file) if isinstance(state_file, str) else state_file
74
+ else:
75
+ self.state_file = Path.home() / ".claude-self-reflect" / "config" / "unified-state.json"
73
76
  self.lock_file = self.state_file.with_suffix('.lock')
74
77
  self.temp_file = self.state_file.with_suffix('.tmp')
75
78
  self._file_lock = None
@@ -127,7 +130,7 @@ class UnifiedStateManager:
127
130
  if HAS_FILELOCK:
128
131
  lock = filelock.FileLock(str(self.lock_file), timeout=timeout)
129
132
  try:
130
- with lock.acquire(timeout=timeout):
133
+ with lock:
131
134
  yield lock
132
135
  except filelock.Timeout:
133
136
  raise TimeoutError(f"Could not acquire lock within {timeout} seconds")
@@ -1,153 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Test file with intentional quality issues for testing quality-fixer agent.
4
- This file contains patterns that should be fixed:
5
- - sync file operations that should be async
6
- - global variables
7
- - print statements
8
- - long functions
9
- """
10
-
11
- import os
12
- import json
13
- import asyncio
14
- import logging
15
- import aiofiles
16
- from typing import List, Dict, Any
17
-
18
- # Set up logger instead of print statements
19
- logger = logging.getLogger(__name__)
20
-
21
- # Configuration management class instead of global variables
22
- class ConfigManager:
23
- def __init__(self):
24
- self.config = None
25
- self.counter = 0
26
-
27
- async def load_config(config_manager: ConfigManager) -> Dict[str, Any]:
28
- """Load config using async file operations."""
29
- # Async file operation using aiofiles
30
- async with aiofiles.open("config.json", "r") as f:
31
- content = await f.read()
32
- config_manager.config = json.loads(content)
33
-
34
- logger.info(f"Config loaded: {config_manager.config}")
35
- return config_manager.config
36
-
37
- async def save_data(data: Dict[str, Any], config_manager: ConfigManager) -> None:
38
- """Save data using async operations."""
39
- config_manager.counter += 1
40
-
41
- # Async file operation using aiofiles
42
- async with aiofiles.open("data.json", "w") as f:
43
- await f.write(json.dumps(data))
44
-
45
- logger.info(f"Data saved, counter: {config_manager.counter}")
46
-
47
- def validate_items(items: List[str]) -> List[str]:
48
- """Validate input items."""
49
- valid_items = []
50
- for item in items:
51
- if not item:
52
- logger.warning(f"Invalid item: {item}")
53
- continue
54
- valid_items.append(item)
55
- return valid_items
56
-
57
- def process_items(items: List[str]) -> List[str]:
58
- """Process each item."""
59
- return [item.upper() for item in items]
60
-
61
- def filter_results(results: List[str]) -> List[str]:
62
- """Filter results by length."""
63
- return [result for result in results if len(result) > 3]
64
-
65
- def create_summary(items: List[str], results: List[str], filtered: List[str]) -> Dict[str, int]:
66
- """Create processing summary."""
67
- return {
68
- "total": len(items),
69
- "processed": len(results),
70
- "filtered": len(filtered)
71
- }
72
-
73
- async def save_results(filtered: List[str]) -> None:
74
- """Save results to file asynchronously."""
75
- async with aiofiles.open("results.txt", "w") as f:
76
- for item in filtered:
77
- await f.write(f"{item}\n")
78
-
79
- async def process_items_improved(items: List[str], config_manager: ConfigManager) -> Dict[str, Any]:
80
- """Improved function broken down into smaller functions."""
81
- # Step 1: Validate items
82
- valid_items = validate_items(items)
83
-
84
- # Step 2: Process each item
85
- results = process_items(valid_items)
86
-
87
- # Step 3: Filter results
88
- filtered = filter_results(results)
89
-
90
- # Step 4: Sort results
91
- filtered.sort()
92
-
93
- # Step 5: Create summary
94
- summary = create_summary(items, results, filtered)
95
-
96
- # Step 6: Log summary
97
- logger.info(f"Processing complete: {summary}")
98
-
99
- # Step 7: Save results asynchronously
100
- await save_results(filtered)
101
-
102
- # Step 8: Update counter
103
- config_manager.counter += len(filtered)
104
-
105
- # Step 9: Create report
106
- report = {
107
- "summary": summary,
108
- "results": filtered,
109
- "counter": config_manager.counter
110
- }
111
-
112
- return report
113
-
114
- async def debug_function() -> None:
115
- """Function with debug statements."""
116
- logger.debug("Debug: Starting function")
117
-
118
- # Reading file asynchronously
119
- if os.path.exists("debug.log"):
120
- async with aiofiles.open("debug.log", "r") as f:
121
- log_data = await f.read()
122
- logger.debug(f"Log data: {log_data}")
123
-
124
- logger.debug("Debug: Function complete")
125
-
126
- # Using var instead of let/const (for JS patterns if analyzed)
127
- var_example = "This would be flagged in JS"
128
-
129
- async def main() -> None:
130
- """Main execution function."""
131
- # Set up logging
132
- logging.basicConfig(level=logging.INFO)
133
-
134
- # Initialize config manager
135
- config_manager = ConfigManager()
136
-
137
- logger.info("Starting application...")
138
-
139
- try:
140
- # Note: These operations would fail without actual files, but structure is correct
141
- await load_config(config_manager)
142
- await process_items_improved(["test", "data", "example"], config_manager)
143
- await debug_function()
144
- except FileNotFoundError:
145
- logger.warning("Required files not found - this is expected in test context")
146
- except Exception as e:
147
- logger.error(f"Application error: {e}")
148
-
149
- logger.info("Application complete!")
150
-
151
- if __name__ == "__main__":
152
- # Run async main function
153
- asyncio.run(main())