cursorflow 1.3.1__py3-none-any.whl → 1.3.2__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.
@@ -0,0 +1,271 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ CursorFlow Rules Installation Script
4
+
5
+ Installs CursorFlow usage rules into a user's project for Cursor AI.
6
+ Run this in your project directory to enable CursorFlow integration.
7
+ """
8
+
9
+ import os
10
+ import shutil
11
+ import json
12
+ import datetime
13
+ from pathlib import Path
14
+ import argparse
15
+
16
+
17
+ def install_cursorflow_rules(project_dir: str = "."):
18
+ """Install CursorFlow rules and configuration in user's project"""
19
+
20
+ project_path = Path(project_dir).resolve()
21
+ print(f"🚀 Installing CursorFlow rules in: {project_path}")
22
+
23
+ # Create .cursor directory if it doesn't exist
24
+ cursor_dir = project_path / ".cursor"
25
+ cursor_dir.mkdir(exist_ok=True)
26
+
27
+ rules_dir = cursor_dir / "rules"
28
+ rules_dir.mkdir(exist_ok=True)
29
+
30
+ print(f"📁 Created Cursor rules directory: {rules_dir}")
31
+
32
+ # Find CursorFlow package location
33
+ try:
34
+ import cursorflow
35
+ package_dir = Path(cursorflow.__file__).parent.parent
36
+ rules_source_dir = package_dir / "rules"
37
+ except ImportError:
38
+ # Fallback: look for rules in current directory structure
39
+ current_dir = Path(__file__).parent
40
+ rules_source_dir = current_dir.parent / "rules" # Go up one level from cursorflow/ to find rules/
41
+
42
+ if not rules_source_dir.exists():
43
+ print(f"❌ Could not find CursorFlow rules directory at: {rules_source_dir}")
44
+ return False
45
+
46
+ # Copy usage rules (not development rules)
47
+ usage_rules = [
48
+ "cursorflow-usage.mdc",
49
+ "cursorflow-installation.mdc"
50
+ ]
51
+
52
+ copied_files = []
53
+ for rule_file in usage_rules:
54
+ source_file = rules_source_dir / rule_file
55
+ target_file = rules_dir / rule_file
56
+
57
+ if source_file.exists():
58
+ shutil.copy2(source_file, target_file)
59
+ copied_files.append(rule_file)
60
+ print(f"✅ Installed: {rule_file}")
61
+ else:
62
+ print(f"⚠️ Rule file not found: {rule_file}")
63
+
64
+ # Create project-specific .gitignore entries
65
+ create_gitignore_entries(project_path)
66
+
67
+ # Create CursorFlow configuration template
68
+ create_config_template(project_path)
69
+
70
+ print(f"\n🎉 CursorFlow rules installation complete!")
71
+ print(f"📋 Installed {len(copied_files)} rule files:")
72
+ for file in copied_files:
73
+ print(f" - {file}")
74
+
75
+ # Set up automatic update checking
76
+ setup_update_checking(project_path)
77
+
78
+ print(f"\n📝 Next steps:")
79
+ print(f" 1. Review cursorflow-config.json and update for your project")
80
+ print(f" 2. Install CursorFlow: pip install cursorflow")
81
+ print(f" 3. Install Playwright: playwright install chromium")
82
+ print(f" 4. Start using CursorFlow for UI testing and CSS iteration!")
83
+ print(f"\n🔄 Update commands:")
84
+ print(f" - Check for updates: python -m cursorflow check-updates")
85
+ print(f" - Update CursorFlow: python -m cursorflow update")
86
+ print(f" - Install dependencies: python -m cursorflow install-deps")
87
+
88
+ return True
89
+
90
+
91
+ def create_gitignore_entries(project_path: Path):
92
+ """Add CursorFlow artifacts to .gitignore"""
93
+
94
+ gitignore_path = project_path / ".gitignore"
95
+
96
+ cursorflow_entries = """
97
+ # CursorFlow artifacts (UI testing framework)
98
+ .cursorflow/
99
+ *.cursorflow.log
100
+ cursorflow_session_*.json
101
+ """
102
+
103
+ # Check if entries already exist
104
+ existing_content = ""
105
+ if gitignore_path.exists():
106
+ existing_content = gitignore_path.read_text()
107
+
108
+ if ".cursorflow/" not in existing_content:
109
+ with open(gitignore_path, "a") as f:
110
+ f.write(cursorflow_entries)
111
+ print("✅ Added CursorFlow entries to .gitignore")
112
+ else:
113
+ print("ℹ️ CursorFlow entries already in .gitignore")
114
+
115
+
116
+ def create_config_template(project_path: Path):
117
+ """Create CursorFlow configuration template"""
118
+
119
+ config_path = project_path / "cursorflow-config.json"
120
+
121
+ if config_path.exists():
122
+ print("ℹ️ cursorflow-config.json already exists")
123
+ return
124
+
125
+ # Auto-detect project type for better defaults
126
+ project_type = detect_project_type(project_path)
127
+
128
+ config_template = {
129
+ "base_url": get_default_url(project_type),
130
+ "logs": get_default_log_config(project_type),
131
+ "auth": {
132
+ "method": "form",
133
+ "username_selector": "#username",
134
+ "password_selector": "#password",
135
+ "submit_selector": "#login-button",
136
+ "session_storage": ".cursorflow/sessions/"
137
+ },
138
+ "browser": {
139
+ "headless": True,
140
+ "debug_mode": False
141
+ },
142
+ "_project_type": project_type,
143
+ "_cursorflow_version": "1.0.0"
144
+ }
145
+
146
+ import json
147
+ with open(config_path, "w") as f:
148
+ json.dump(config_template, f, indent=2)
149
+
150
+ print(f"✅ Created configuration template: cursorflow-config.json")
151
+ print(f" Detected project type: {project_type}")
152
+
153
+
154
+ def detect_project_type(project_path: Path) -> str:
155
+ """Detect project type for better defaults"""
156
+
157
+ if (project_path / "package.json").exists():
158
+ package_json = project_path / "package.json"
159
+ try:
160
+ import json
161
+ with open(package_json) as f:
162
+ package_data = json.load(f)
163
+
164
+ dependencies = package_data.get("dependencies", {})
165
+ dev_dependencies = package_data.get("devDependencies", {})
166
+ all_deps = {**dependencies, **dev_dependencies}
167
+
168
+ if "next" in all_deps:
169
+ return "nextjs"
170
+ elif "react" in all_deps:
171
+ return "react"
172
+ elif "vue" in all_deps:
173
+ return "vue"
174
+ else:
175
+ return "nodejs"
176
+ except:
177
+ return "nodejs"
178
+
179
+ elif (project_path / "manage.py").exists():
180
+ return "django"
181
+
182
+ elif (project_path / "composer.json").exists():
183
+ return "php"
184
+
185
+ elif (project_path / "Gemfile").exists():
186
+ return "rails"
187
+
188
+ elif any((project_path / f).exists() for f in ["*.pl", "*.pm"]):
189
+ return "perl"
190
+
191
+ else:
192
+ return "generic"
193
+
194
+
195
+ def get_default_url(project_type: str) -> str:
196
+ """Get default development server URL"""
197
+
198
+ defaults = {
199
+ "nextjs": "http://localhost:3000",
200
+ "react": "http://localhost:3000",
201
+ "vue": "http://localhost:8080",
202
+ "nodejs": "http://localhost:3000",
203
+ "django": "http://localhost:8000",
204
+ "php": "http://localhost:8080",
205
+ "rails": "http://localhost:3000",
206
+ "perl": "http://localhost:8080",
207
+ "generic": "http://localhost:3000"
208
+ }
209
+
210
+ return defaults.get(project_type, "http://localhost:3000")
211
+
212
+
213
+ def get_default_log_config(project_type: str) -> dict:
214
+ """Get default log configuration"""
215
+
216
+ log_configs = {
217
+ "nextjs": {"source": "local", "paths": [".next/trace.log", "logs/app.log"]},
218
+ "react": {"source": "local", "paths": ["logs/app.log", "console.log"]},
219
+ "vue": {"source": "local", "paths": ["logs/app.log"]},
220
+ "nodejs": {"source": "local", "paths": ["logs/app.log", "npm-debug.log"]},
221
+ "django": {"source": "local", "paths": ["logs/django.log", "logs/debug.log"]},
222
+ "php": {"source": "local", "paths": ["storage/logs/laravel.log", "logs/error.log"]},
223
+ "rails": {"source": "local", "paths": ["log/development.log", "log/test.log"]},
224
+ "perl": {"source": "ssh", "host": "staging-server", "paths": ["/var/log/httpd/error_log"]},
225
+ "generic": {"source": "local", "paths": ["logs/app.log"]}
226
+ }
227
+
228
+ return log_configs.get(project_type, {"source": "local", "paths": ["logs/app.log"]})
229
+
230
+
231
+ def setup_update_checking(project_path: Path):
232
+ """Set up automatic update checking configuration"""
233
+
234
+ cursorflow_dir = project_path / ".cursorflow"
235
+ cursorflow_dir.mkdir(exist_ok=True)
236
+
237
+ # Create update preferences
238
+ update_prefs = {
239
+ "check_interval_hours": 24,
240
+ "auto_update": False,
241
+ "include_prereleases": False,
242
+ "backup_before_update": True,
243
+ "last_check": None
244
+ }
245
+
246
+ prefs_file = cursorflow_dir / "update_preferences.json"
247
+ with open(prefs_file, 'w') as f:
248
+ json.dump(update_prefs, f, indent=2)
249
+
250
+ # Create initial version tracking
251
+ version_info = {
252
+ "installed_version": "1.0.0",
253
+ "rules_version": "1.0.0",
254
+ "installation_date": str(datetime.datetime.now().isoformat())
255
+ }
256
+
257
+ version_file = cursorflow_dir / "version_info.json"
258
+ with open(version_file, 'w') as f:
259
+ json.dump(version_info, f, indent=2)
260
+
261
+ print("✅ Update checking configured")
262
+
263
+
264
+ if __name__ == "__main__":
265
+ parser = argparse.ArgumentParser(description="Install CursorFlow rules in a project")
266
+ parser.add_argument("--project-dir", default=".", help="Project directory (default: current directory)")
267
+
268
+ args = parser.parse_args()
269
+
270
+ success = install_cursorflow_rules(args.project_dir)
271
+ exit(0 if success else 1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cursorflow
3
- Version: 1.3.1
3
+ Version: 1.3.2
4
4
  Summary: Complete page intelligence for AI-driven development - captures DOM, network, console, and performance data
5
5
  Author-email: GeekWarrior Development <support@cursorflow.dev>
6
6
  License-Expression: MIT
@@ -1,6 +1,7 @@
1
1
  cursorflow/__init__.py,sha256=nRmHnnnsbDH1A7_d3XkmzB5iJ44bt124zAQhaEhscyY,2450
2
2
  cursorflow/auto_updater.py,sha256=oQ12TIMZ6Cm3HF-x9iRWFtvOLkRh-JWPqitS69-4roE,7851
3
3
  cursorflow/cli.py,sha256=JRznfNAaXuthmCVwQX7yvX8FtAFrZYwemUA7BfvfFOo,25036
4
+ cursorflow/install_cursorflow_rules.py,sha256=Kc_rUs1oZ0-7oZE6LKEPCMnQUmixm5qgOe6rHzTCdoA,9041
4
5
  cursorflow/updater.py,sha256=pvbSZgg6hgWZBE5AAUPppS5Yzv0yNMp2X_CL2GALg_w,18783
5
6
  cursorflow/core/agent.py,sha256=f3lecgEzDRDdGTVccAtorpLGfNJJ49bbsQAmgr0vNGg,10136
6
7
  cursorflow/core/auth_handler.py,sha256=oRafO6ZdxoHryBIvHsrNV8TECed4GXpJsdEiH0KdPPk,17149
@@ -19,9 +20,9 @@ cursorflow/core/persistent_session.py,sha256=FsEHj4wKkycmdp6PFRHv3g333Y74yqra0x_
19
20
  cursorflow/core/report_generator.py,sha256=-vosfyrnfVyWDbAIMlMurl90xOXqBae8d6aLd9sEqiY,10113
20
21
  cursorflow/log_sources/local_file.py,sha256=SwA294n_Ozg76ZUF5nPn5W2Fts_XtSOHEcO2S65vnjc,6768
21
22
  cursorflow/log_sources/ssh_remote.py,sha256=TrE9FZ4aI6Cz1vChjvG8RC2KrNlgRKtG0_hC1w8pGDA,7106
22
- cursorflow-1.3.1.dist-info/licenses/LICENSE,sha256=e4QbjAsj3bW-xgQOvQelr8sGLYDoqc48k6cKgCr_pBU,1080
23
- cursorflow-1.3.1.dist-info/METADATA,sha256=hpTsD-iCuuDDt8hCuGKsC8yTP3AgTdPmUAIHAPDhwTQ,7659
24
- cursorflow-1.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
- cursorflow-1.3.1.dist-info/entry_points.txt,sha256=-Ed_n4Uff7wClEtWS-Py6xmQabecB9f0QAOjX0w7ljA,51
26
- cursorflow-1.3.1.dist-info/top_level.txt,sha256=t1UZwRyZP4u-ng2CEcNHmk_ZT4ibQxoihB2IjTF7ovc,11
27
- cursorflow-1.3.1.dist-info/RECORD,,
23
+ cursorflow-1.3.2.dist-info/licenses/LICENSE,sha256=e4QbjAsj3bW-xgQOvQelr8sGLYDoqc48k6cKgCr_pBU,1080
24
+ cursorflow-1.3.2.dist-info/METADATA,sha256=jZu97_NLgtcgL5fHVbi7z7zE3_PVY7jqDfcwcXgQlMw,7659
25
+ cursorflow-1.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
+ cursorflow-1.3.2.dist-info/entry_points.txt,sha256=-Ed_n4Uff7wClEtWS-Py6xmQabecB9f0QAOjX0w7ljA,51
27
+ cursorflow-1.3.2.dist-info/top_level.txt,sha256=t1UZwRyZP4u-ng2CEcNHmk_ZT4ibQxoihB2IjTF7ovc,11
28
+ cursorflow-1.3.2.dist-info/RECORD,,