cursorflow 2.4.3__py3-none-any.whl → 2.5.0__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.
- cursorflow/cli.py +11 -19
- cursorflow/core/cursorflow.py +3 -13
- cursorflow/core/json_utils.py +53 -0
- cursorflow/core/mockup_comparator.py +29 -58
- cursorflow/rules/cursorflow-usage.mdc +25 -0
- {cursorflow-2.4.3.dist-info → cursorflow-2.5.0.dist-info}/METADATA +8 -6
- {cursorflow-2.4.3.dist-info → cursorflow-2.5.0.dist-info}/RECORD +11 -10
- {cursorflow-2.4.3.dist-info → cursorflow-2.5.0.dist-info}/WHEEL +0 -0
- {cursorflow-2.4.3.dist-info → cursorflow-2.5.0.dist-info}/entry_points.txt +0 -0
- {cursorflow-2.4.3.dist-info → cursorflow-2.5.0.dist-info}/licenses/LICENSE +0 -0
- {cursorflow-2.4.3.dist-info → cursorflow-2.5.0.dist-info}/top_level.txt +0 -0
cursorflow/cli.py
CHANGED
@@ -428,29 +428,20 @@ def compare_mockup(mockup_url, base_url, mockup_actions, implementation_actions,
|
|
428
428
|
console.print(f"[red]❌ Comparison failed: {results['error']}[/red]")
|
429
429
|
return
|
430
430
|
|
431
|
-
# Display results summary
|
431
|
+
# Display results summary (pure metrics only)
|
432
432
|
summary = results.get('summary', {})
|
433
433
|
console.print(f"✅ Comparison completed: {results.get('comparison_id', 'unknown')}")
|
434
434
|
console.print(f"📊 Average similarity: [bold]{summary.get('average_similarity', 0)}%[/bold]")
|
435
435
|
console.print(f"📱 Viewports tested: {summary.get('viewports_tested', 0)}")
|
436
436
|
|
437
|
-
# Show
|
438
|
-
|
439
|
-
if
|
440
|
-
console.print(f"
|
441
|
-
for i, rec in enumerate(recommendations[:3]): # Show first 3
|
442
|
-
console.print(f" {i+1}. {rec.get('description', 'No description')}")
|
437
|
+
# Show similarity range
|
438
|
+
similarity_range = summary.get('similarity_range', {})
|
439
|
+
if similarity_range:
|
440
|
+
console.print(f"📈 Similarity range: {similarity_range.get('min', 0)}% - {similarity_range.get('max', 0)}%")
|
443
441
|
|
444
|
-
# Save results with
|
445
|
-
|
446
|
-
|
447
|
-
# Handle numpy types
|
448
|
-
if hasattr(obj, 'item'): # numpy scalars (bool_, int_, float_)
|
449
|
-
return obj.item()
|
450
|
-
if hasattr(obj, 'tolist'): # numpy arrays
|
451
|
-
return obj.tolist()
|
452
|
-
return str(obj)
|
453
|
-
json.dump(results, f, indent=2, default=json_serializer)
|
442
|
+
# Save results with safe serialization
|
443
|
+
from .core.json_utils import safe_json_dump
|
444
|
+
safe_json_dump(results, output)
|
454
445
|
|
455
446
|
console.print(f"💾 Full results saved to: [cyan]{output}[/cyan]")
|
456
447
|
console.print(f"📁 Visual diffs stored in: [cyan].cursorflow/artifacts/[/cyan]")
|
@@ -551,9 +542,10 @@ def iterate_mockup(mockup_url, base_url, css_improvements, base_actions, diff_th
|
|
551
542
|
for i, rec in enumerate(recommendations[:3]):
|
552
543
|
console.print(f" {i+1}. {rec.get('description', 'No description')}")
|
553
544
|
|
554
|
-
# Save results
|
545
|
+
# Save results with numpy type handling
|
546
|
+
from cursorflow.core.json_utils import safe_json_serialize
|
555
547
|
with open(output, 'w') as f:
|
556
|
-
json.dump(results, f, indent=2, default=
|
548
|
+
json.dump(results, f, indent=2, default=safe_json_serialize)
|
557
549
|
|
558
550
|
console.print(f"💾 Full results saved to: [cyan]{output}[/cyan]")
|
559
551
|
console.print(f"📁 Iteration progress stored in: [cyan].cursorflow/artifacts/[/cyan]")
|
cursorflow/core/cursorflow.py
CHANGED
@@ -575,19 +575,9 @@ class CursorFlow:
|
|
575
575
|
if "error" in raw_results:
|
576
576
|
return raw_results
|
577
577
|
|
578
|
-
#
|
579
|
-
|
580
|
-
|
581
|
-
raw_results=raw_results,
|
582
|
-
session_id=session_id,
|
583
|
-
project_context={
|
584
|
-
"framework": "auto-detected",
|
585
|
-
"base_url": self.base_url,
|
586
|
-
"test_type": "mockup_comparison"
|
587
|
-
}
|
588
|
-
)
|
589
|
-
|
590
|
-
return cursor_results
|
578
|
+
# Return raw measurement data directly (pure observation)
|
579
|
+
# No interpretation, no analysis - Cursor makes decisions based on data
|
580
|
+
return raw_results
|
591
581
|
|
592
582
|
except Exception as e:
|
593
583
|
self.logger.error(f"Mockup comparison failed: {e}")
|
@@ -0,0 +1,53 @@
|
|
1
|
+
"""
|
2
|
+
JSON Serialization Utilities
|
3
|
+
|
4
|
+
Handles conversion of numpy and other non-standard types to JSON-safe Python types.
|
5
|
+
Essential for mockup comparison and any feature using PIL/numpy for image analysis.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import json
|
9
|
+
from typing import Any
|
10
|
+
from pathlib import Path
|
11
|
+
|
12
|
+
|
13
|
+
def safe_json_serialize(obj: Any) -> Any:
|
14
|
+
"""
|
15
|
+
Convert any Python/numpy type to JSON-safe type
|
16
|
+
|
17
|
+
Handles:
|
18
|
+
- numpy scalars (bool_, int_, float_)
|
19
|
+
- numpy arrays (ndarray)
|
20
|
+
- Other non-serializable types (converts to string)
|
21
|
+
|
22
|
+
Args:
|
23
|
+
obj: Any object that might not be JSON serializable
|
24
|
+
|
25
|
+
Returns:
|
26
|
+
JSON-safe Python type
|
27
|
+
"""
|
28
|
+
# numpy scalars (bool_, int64, float64, etc.)
|
29
|
+
if hasattr(obj, 'item'):
|
30
|
+
return obj.item()
|
31
|
+
|
32
|
+
# numpy arrays
|
33
|
+
if hasattr(obj, 'tolist'):
|
34
|
+
return obj.tolist()
|
35
|
+
|
36
|
+
# Fallback for anything else
|
37
|
+
return str(obj)
|
38
|
+
|
39
|
+
|
40
|
+
def safe_json_dump(data: Any, file_path: str, indent: int = 2) -> None:
|
41
|
+
"""
|
42
|
+
Safely dump data to JSON file with numpy type handling
|
43
|
+
|
44
|
+
Args:
|
45
|
+
data: Data to serialize
|
46
|
+
file_path: Path to output file
|
47
|
+
indent: JSON indentation level
|
48
|
+
"""
|
49
|
+
file_path = Path(file_path)
|
50
|
+
file_path.parent.mkdir(parents=True, exist_ok=True)
|
51
|
+
|
52
|
+
with open(file_path, 'w') as f:
|
53
|
+
json.dump(data, f, indent=indent, default=safe_json_serialize)
|
@@ -11,6 +11,8 @@ import json
|
|
11
11
|
from typing import Dict, List, Optional, Any, Tuple
|
12
12
|
from pathlib import Path
|
13
13
|
import logging
|
14
|
+
|
15
|
+
from .json_utils import safe_json_dump, safe_json_serialize
|
14
16
|
try:
|
15
17
|
from PIL import Image, ImageDraw, ImageChops
|
16
18
|
import numpy as np
|
@@ -107,9 +109,14 @@ class MockupComparator:
|
|
107
109
|
await mockup_browser.set_viewport(viewport["width"], viewport["height"])
|
108
110
|
await implementation_browser.set_viewport(viewport["width"], viewport["height"])
|
109
111
|
|
110
|
-
# Navigate to initial pages
|
112
|
+
# Navigate to initial pages with stabilization
|
111
113
|
await mockup_browser.navigate("/")
|
114
|
+
await asyncio.sleep(1)
|
115
|
+
await mockup_browser.page.wait_for_load_state("domcontentloaded")
|
116
|
+
|
112
117
|
await implementation_browser.navigate("/")
|
118
|
+
await asyncio.sleep(1)
|
119
|
+
await implementation_browser.page.wait_for_load_state("domcontentloaded")
|
113
120
|
|
114
121
|
# Execute any required actions on mockup
|
115
122
|
if mockup_actions:
|
@@ -119,6 +126,9 @@ class MockupComparator:
|
|
119
126
|
if implementation_actions:
|
120
127
|
await self._execute_actions_on_browser(implementation_browser, implementation_actions)
|
121
128
|
|
129
|
+
# Final stabilization before capturing
|
130
|
+
await asyncio.sleep(0.5)
|
131
|
+
|
122
132
|
# Capture screenshots
|
123
133
|
mockup_screenshot = await self._capture_comparison_screenshot(
|
124
134
|
mockup_browser, f"{comparison_name}_mockup_{viewport_name}"
|
@@ -163,19 +173,12 @@ class MockupComparator:
|
|
163
173
|
"implementation_url": implementation_url,
|
164
174
|
"viewports_tested": len(viewports),
|
165
175
|
"results": comparison_results,
|
166
|
-
"summary": self._create_comparison_summary(comparison_results)
|
167
|
-
"recommendations": self._generate_improvement_recommendations(comparison_results)
|
176
|
+
"summary": self._create_comparison_summary(comparison_results)
|
168
177
|
}
|
169
178
|
|
170
|
-
# Save comparison report
|
179
|
+
# Save comparison report with safe serialization
|
171
180
|
report_path = self.artifacts_base / "mockup_comparisons" / f"{comparison_name}.json"
|
172
|
-
|
173
|
-
# Custom JSON encoder to handle numpy booleans/integers
|
174
|
-
def json_serializer(obj):
|
175
|
-
if hasattr(obj, 'item'): # numpy types
|
176
|
-
return obj.item()
|
177
|
-
return str(obj)
|
178
|
-
json.dump(comparison_report, f, indent=2, default=json_serializer)
|
181
|
+
safe_json_dump(comparison_report, str(report_path))
|
179
182
|
|
180
183
|
self.logger.info(f"Mockup comparison completed: {comparison_name}")
|
181
184
|
return comparison_report
|
@@ -293,10 +296,9 @@ class MockupComparator:
|
|
293
296
|
"final_recommendations": self._generate_final_recommendations(iteration_results)
|
294
297
|
}
|
295
298
|
|
296
|
-
# Save iteration report
|
299
|
+
# Save iteration report with safe JSON serialization
|
297
300
|
report_path = self.artifacts_base / "iteration_progress" / f"{iteration_session_id}.json"
|
298
|
-
|
299
|
-
json.dump(iteration_report, f, indent=2, default=str)
|
301
|
+
safe_json_dump(iteration_report, str(report_path))
|
300
302
|
|
301
303
|
self.logger.info(f"UI matching iteration completed: {iteration_session_id}")
|
302
304
|
return iteration_report
|
@@ -314,11 +316,15 @@ class MockupComparator:
|
|
314
316
|
if "navigate" in action:
|
315
317
|
path = action["navigate"]
|
316
318
|
await browser.navigate(path)
|
319
|
+
# Wait for page to stabilize after navigation
|
320
|
+
await asyncio.sleep(1) # Brief pause for dynamic content rendering
|
321
|
+
await browser.page.wait_for_load_state("domcontentloaded")
|
317
322
|
elif "click" in action:
|
318
323
|
selector = action["click"]
|
319
324
|
if isinstance(selector, dict):
|
320
325
|
selector = selector["selector"]
|
321
326
|
await browser.click(selector)
|
327
|
+
await asyncio.sleep(0.5) # Brief pause for UI response
|
322
328
|
elif "wait_for" in action:
|
323
329
|
selector = action["wait_for"]
|
324
330
|
if isinstance(selector, dict):
|
@@ -329,6 +335,7 @@ class MockupComparator:
|
|
329
335
|
elif "scroll" in action:
|
330
336
|
scroll_config = action["scroll"]
|
331
337
|
await browser.page.evaluate(f"window.scrollTo({scroll_config.get('x', 0)}, {scroll_config.get('y', 0)})")
|
338
|
+
await asyncio.sleep(0.3) # Brief pause for scroll rendering
|
332
339
|
|
333
340
|
async def _capture_comparison_screenshot(self, browser: BrowserController, name: str) -> str:
|
334
341
|
"""Capture screenshot for comparison"""
|
@@ -1223,55 +1230,19 @@ class MockupComparator:
|
|
1223
1230
|
|
1224
1231
|
avg_similarity = sum(similarities) / len(similarities) if similarities else 0
|
1225
1232
|
|
1233
|
+
# Pure data summary - no interpretation
|
1226
1234
|
return {
|
1227
1235
|
"average_similarity": round(float(avg_similarity), 2),
|
1228
1236
|
"viewports_tested": len(comparison_results),
|
1229
|
-
"
|
1230
|
-
|
1237
|
+
"similarity_by_viewport": [
|
1238
|
+
{
|
1239
|
+
"viewport": result.get("viewport", {}).get("name", "unknown"),
|
1240
|
+
"similarity": float(result.get("visual_diff", {}).get("similarity_score", 0))
|
1241
|
+
}
|
1242
|
+
for result in comparison_results
|
1243
|
+
]
|
1231
1244
|
}
|
1232
1245
|
|
1233
|
-
def _generate_improvement_recommendations(self, comparison_results: List[Dict]) -> List[Dict]:
|
1234
|
-
"""Generate recommendations for improving implementation to match mockup"""
|
1235
|
-
recommendations = []
|
1236
|
-
|
1237
|
-
for result in comparison_results:
|
1238
|
-
viewport = result.get("viewport", {})
|
1239
|
-
layout_analysis = result.get("layout_analysis", {})
|
1240
|
-
visual_diff = result.get("visual_diff", {})
|
1241
|
-
|
1242
|
-
# Analyze layout differences for recommendations
|
1243
|
-
differences = layout_analysis.get("differences", [])
|
1244
|
-
|
1245
|
-
for diff in differences:
|
1246
|
-
if diff["type"] == "missing_in_implementation":
|
1247
|
-
recommendations.append({
|
1248
|
-
"type": "add_element",
|
1249
|
-
"priority": "high",
|
1250
|
-
"description": f"Add missing element: {diff['selector']}",
|
1251
|
-
"viewport": viewport.get("name", "unknown")
|
1252
|
-
})
|
1253
|
-
elif diff["type"] == "property_differences":
|
1254
|
-
for prop, prop_diff in diff.get("differences", {}).items():
|
1255
|
-
recommendations.append({
|
1256
|
-
"type": "adjust_property",
|
1257
|
-
"priority": "medium",
|
1258
|
-
"description": f"Adjust {prop} for {diff['selector']}",
|
1259
|
-
"current_value": prop_diff.get("implementation"),
|
1260
|
-
"target_value": prop_diff.get("mockup"),
|
1261
|
-
"viewport": viewport.get("name", "unknown")
|
1262
|
-
})
|
1263
|
-
|
1264
|
-
# Add visual similarity recommendations
|
1265
|
-
similarity = visual_diff.get("similarity_score", 0)
|
1266
|
-
if similarity < 70:
|
1267
|
-
recommendations.append({
|
1268
|
-
"type": "major_visual_changes",
|
1269
|
-
"priority": "high",
|
1270
|
-
"description": f"Significant visual differences detected (similarity: {similarity}%)",
|
1271
|
-
"viewport": viewport.get("name", "unknown")
|
1272
|
-
})
|
1273
|
-
|
1274
|
-
return recommendations
|
1275
1246
|
|
1276
1247
|
def _create_iteration_summary(self, baseline_comparison: Dict, iteration_results: List[Dict]) -> Dict[str, Any]:
|
1277
1248
|
"""Create summary of iteration session"""
|
@@ -425,6 +425,31 @@ cursorflow measure -u http://localhost:3000 -s "#panel"
|
|
425
425
|
# Output: 532w × 900h ✅
|
426
426
|
```
|
427
427
|
|
428
|
+
### Visual Comparison & Iteration
|
429
|
+
```bash
|
430
|
+
# Compare mockup to implementation (pure measurement)
|
431
|
+
cursorflow compare-mockup MOCKUP_URL -u BASE_URL -ia '[{"navigate": "/page"}]'
|
432
|
+
# Output: Similarity percentage, diff images, element data
|
433
|
+
|
434
|
+
# Test CSS variations (observe real rendering)
|
435
|
+
cursorflow iterate-mockup MOCKUP_URL -u BASE_URL --css-improvements '[
|
436
|
+
{"name": "test1", "css": ".header { padding: 2rem; }"},
|
437
|
+
{"name": "test2", "css": ".header { padding: 1rem; }"}
|
438
|
+
]'
|
439
|
+
# Output: Similarity for each variation - Cursor decides which to apply
|
440
|
+
```
|
441
|
+
|
442
|
+
**Philosophy**:
|
443
|
+
- CursorFlow observes mockup and implementation (both are reality)
|
444
|
+
- Provides quantified measurements (similarity %, diff images, element data)
|
445
|
+
- Temporarily injects CSS to observe what reality WOULD look like
|
446
|
+
- Cursor analyzes the data and makes decisions
|
447
|
+
|
448
|
+
**When to use**:
|
449
|
+
- User has design mockup and needs to match it
|
450
|
+
- Testing multiple CSS approaches before applying
|
451
|
+
- Measuring progress toward design specifications
|
452
|
+
|
428
453
|
## Analyzing Results
|
429
454
|
|
430
455
|
### **Hot Reload CSS Iteration Results**
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: cursorflow
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.5.0
|
4
4
|
Summary: 🔥 Complete page intelligence for AI-driven development with Hot Reload Intelligence - captures DOM, network, console, performance, HMR events, and comprehensive page analysis
|
5
5
|
Author-email: GeekWarrior Development <rbush@cooltheory.com>
|
6
6
|
License-Expression: MIT
|
@@ -370,20 +370,22 @@ cursorflow test --base-url http://localhost:3000 --responsive --actions '[
|
|
370
370
|
cursorflow test --base-url http://localhost:3000 --path "/api" --output "api-test-results.json"
|
371
371
|
```
|
372
372
|
|
373
|
-
### **Design Comparison**
|
373
|
+
### **Design Comparison** (Pure Measurement)
|
374
374
|
```bash
|
375
|
-
# Compare mockup to implementation
|
375
|
+
# Compare mockup to implementation - get similarity metrics
|
376
376
|
cursorflow compare-mockup https://mockup.com/design \
|
377
377
|
--base-url http://localhost:3000 \
|
378
|
-
--mockup-actions '[{"navigate": "/"}]' \
|
379
378
|
--implementation-actions '[{"navigate": "/dashboard"}]'
|
379
|
+
# Output: 87.3% similarity, diff images, element measurements
|
380
380
|
|
381
|
-
# CSS
|
381
|
+
# Test CSS variations - observe real rendering
|
382
382
|
cursorflow iterate-mockup https://mockup.com/design \
|
383
383
|
--base-url http://localhost:5173 \
|
384
384
|
--css-improvements '[
|
385
|
-
{"name": "fix
|
385
|
+
{"name": "spacing-fix", "css": ".container { gap: 2rem; }"},
|
386
|
+
{"name": "tighter-spacing", "css": ".container { gap: 1rem; }"}
|
386
387
|
]'
|
388
|
+
# Output: Similarity data for each variation (Cursor decides which to apply)
|
387
389
|
```
|
388
390
|
|
389
391
|
### **Element Analysis & CSS Debugging**
|
@@ -1,7 +1,7 @@
|
|
1
1
|
cursorflow/__init__.py,sha256=2V9xzG2tYxVWOTmSw2v9Jdbr7lSrMi_y2SMUMuNZdvw,2990
|
2
2
|
cursorflow/auto_init.py,sha256=dXQaXXiXe4wkUP-jd8fcJ5fYVt7ASdTb47b7SzXymOM,6122
|
3
3
|
cursorflow/auto_updater.py,sha256=oQ12TIMZ6Cm3HF-x9iRWFtvOLkRh-JWPqitS69-4roE,7851
|
4
|
-
cursorflow/cli.py,sha256=
|
4
|
+
cursorflow/cli.py,sha256=Wj4i60rYGZlGaejES7msuEFWODlu_f0DMlVnHzEFSaU,64742
|
5
5
|
cursorflow/install_cursorflow_rules.py,sha256=DsZ0680y9JMuTKFXjdgYtOKIEAjBMsdwL8LmA9WEb5A,11864
|
6
6
|
cursorflow/post_install.py,sha256=WieBiKWG0qBAQpF8iMVWUyb9Fr2Xky9qECTMPrlAbpE,2678
|
7
7
|
cursorflow/updater.py,sha256=SroSQHQi5cYyzcOK_bf-WzmQmE7yeOs8qo3r__j-Z6E,19583
|
@@ -13,15 +13,16 @@ cursorflow/core/browser_engine.py,sha256=7N9hPOyDrEhLWYgZW2981N9gKlHF6Lbp7D7h0zB
|
|
13
13
|
cursorflow/core/config_validator.py,sha256=HRtONSOmM0Xxt3-ok3xwnBADRiNnI0nNOMaS2OqOkDk,7286
|
14
14
|
cursorflow/core/css_iterator.py,sha256=whLCIwbHZEWaH1HCbmqhNX5zrh_fL-r3hsxKjYsukcE,16478
|
15
15
|
cursorflow/core/cursor_integration.py,sha256=MAeHjXYeqzaXnhskqkTDB-n5ixIHqapGe93X0lLKhws,67501
|
16
|
-
cursorflow/core/cursorflow.py,sha256=
|
16
|
+
cursorflow/core/cursorflow.py,sha256=j1LRNiRpUl3gZlB3r-yQ_h0HISNwnhi8-iZa_E0h86o,46111
|
17
17
|
cursorflow/core/error_context_collector.py,sha256=so-aveqwb6_vRDbtKR2ln8_F84aaVIceNi1UHsaVPgc,26196
|
18
18
|
cursorflow/core/error_correlator.py,sha256=g6YaIF2yFXUDrTuWHCyuES6K0696H8LDWmXH1qI8ddA,13367
|
19
19
|
cursorflow/core/event_correlator.py,sha256=lCzXFnii17AQt3rOVOclez_AnjvBCF_2ZlnFG0mIN6c,7808
|
20
20
|
cursorflow/core/file_change_monitor.py,sha256=tl_ZdsGW8LZBTImniD-lqaGgNb9dYjlDsP2XmevE0xk,21258
|
21
21
|
cursorflow/core/hmr_detector.py,sha256=IrGYhXIeTBukffRXF74SW45cB_Im0cmq8RxxjtSz-2w,17431
|
22
|
+
cursorflow/core/json_utils.py,sha256=ofqRP1twDSHQx-SERgLTO5y2ZXkoirsEw8OOiJkGh2w,1370
|
22
23
|
cursorflow/core/log_collector.py,sha256=CYh41SLDI_t-hgzJqG3fTrSTDhEPFDktjO_mOQwucnE,15198
|
23
24
|
cursorflow/core/log_monitor.py,sha256=pONMu_JHEnT0T62OA5KRZ4nClzKgNpifPyrfN5w_RM8,6704
|
24
|
-
cursorflow/core/mockup_comparator.py,sha256=
|
25
|
+
cursorflow/core/mockup_comparator.py,sha256=ttcXdueZz9dwcUGBQ2sft4i66zRdkZkFPu41s6JlEwU,63472
|
25
26
|
cursorflow/core/persistent_session.py,sha256=FsEHj4wKkycmdp6PFRHv3g333Y74yqra0x_qhUTQpik,36075
|
26
27
|
cursorflow/core/report_generator.py,sha256=-vosfyrnfVyWDbAIMlMurl90xOXqBae8d6aLd9sEqiY,10113
|
27
28
|
cursorflow/core/trace_manager.py,sha256=Jj9ultZrL1atiZXfcRVI6ynCnnfqZM-X0_taxt-llJ0,7189
|
@@ -29,10 +30,10 @@ cursorflow/log_sources/local_file.py,sha256=GVnhsaifIdc41twXwbxRM9-fBeRDsknDpk5I
|
|
29
30
|
cursorflow/log_sources/ssh_remote.py,sha256=_Kwh0bhRpKgq-0c98oaX2hN6h9cT-wCHlqY5NiWVCoY,8388
|
30
31
|
cursorflow/rules/__init__.py,sha256=gPcA-IkhXj03sl7cvZV0wwo7CtEkcyuKs4y0F5oQbqE,458
|
31
32
|
cursorflow/rules/cursorflow-installation.mdc,sha256=D55pzzDPAVVbE3gAtKPUGoT-2fvB-FI2l6yrTdzUIEo,10208
|
32
|
-
cursorflow/rules/cursorflow-usage.mdc,sha256=
|
33
|
-
cursorflow-2.
|
34
|
-
cursorflow-2.
|
35
|
-
cursorflow-2.
|
36
|
-
cursorflow-2.
|
37
|
-
cursorflow-2.
|
38
|
-
cursorflow-2.
|
33
|
+
cursorflow/rules/cursorflow-usage.mdc,sha256=W56Qydfb4jqSBTrki7cNyFPfOe_b89mzniRtKSrMlz4,24138
|
34
|
+
cursorflow-2.5.0.dist-info/licenses/LICENSE,sha256=e4QbjAsj3bW-xgQOvQelr8sGLYDoqc48k6cKgCr_pBU,1080
|
35
|
+
cursorflow-2.5.0.dist-info/METADATA,sha256=vr-9bDM-frTvKKRDVPCdekst6mD8oNtxObWj9Y9VaUY,15011
|
36
|
+
cursorflow-2.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
37
|
+
cursorflow-2.5.0.dist-info/entry_points.txt,sha256=-Ed_n4Uff7wClEtWS-Py6xmQabecB9f0QAOjX0w7ljA,51
|
38
|
+
cursorflow-2.5.0.dist-info/top_level.txt,sha256=t1UZwRyZP4u-ng2CEcNHmk_ZT4ibQxoihB2IjTF7ovc,11
|
39
|
+
cursorflow-2.5.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|