⚡ 需求分析效率提升 200%!全球首个为 AI 编程时代设计的团队协作 MCP 服务器,自动分析需求自动编写前后端代码,下载切图
This report summarizes scanner evidence for dsphper/lanhu-mcp, a Python project with 2,455 GitHub stars. SynthScan examined 21,059 lines of code across 65 source files, recording 385 pattern matches distributed across 14 syntactic categories. The legacy adjusted pattern signal is 32.6 (High pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 219 finding(s).
Are imports declared and package/API names verified? 67 finding(s).
Are wrappers, guards, and repeated structures necessary? 273 finding(s).
Which changes need focused human review? 385 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 385 distinct pattern matches across 14 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH⚡ | lanhu_mcp_server.py | 1792 | let vm = null; let node = el; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 1798 | const dw = (layers[0]?.width || 750) / 2; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 1799 | const dh = (layers[0]?.height || 1334) / 2; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 1803 | for (let i = 1; i < layers.length && i < items.length; i++) { | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 1810 | results.push({ | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 1814 | textInfo: L.textInfo || null, | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 1814 | textInfo: L.textInfo || null, | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 4836 | while (current && current.nodeType === 1) { | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 4839 | style.visibility === 'collapse' || Number(style.opacity) === 0 || current.hidden) return false; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 4847 | if (rect.width < .5 || rect.height < .5) return; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 4848 | if (documentWidth > 4096 && documentHeight > 4096 && | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 4850 | rects.push({x, y, right: x + rect.width, bottom: y + rect.height}); | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 4865 | parseFloat(style.borderTopWidth) > 0 || parseFloat(style.borderRightWidth) > 0 || | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 4866 | parseFloat(style.borderBottomWidth) > 0 || parseFloat(style.borderLeftWidth) > 0; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 4873 | } : null; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5170 | blocks.push({text, bounds, color: style.color || null, fontSize: style.fontSize || null, | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5170 | blocks.push({text, bounds, color: style.color || null, fontSize: style.fontSize || null, | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5170 | blocks.push({text, bounds, color: style.color || null, fontSize: style.fontSize || null, | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5171 | fontWeight: style.fontWeight || null, elementId: parent.id || null}); | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5171 | fontWeight: style.fontWeight || null, elementId: parent.id || null}); | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5187 | const data = window.__lanhuAxurePageData || null; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5187 | const data = window.__lanhuAxurePageData || null; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5197 | while (current && current.nodeType === 1) { | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5201 | current.hidden || current.getAttribute('aria-hidden') === 'true') return false; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5205 | return rect.width >= 0.5 && rect.height >= 0.5; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5208 | if (!node) return null; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5227 | const ownerId = annotation.ownerId || null; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5227 | const ownerId = annotation.ownerId || null; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5228 | const scriptId = ownerId && objectPaths[ownerId] | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5230 | : null; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5231 | const noteHtml = annotation['注释'] || annotation.note || annotation.description || ''; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5234 | fn: annotation.fn ?? null, | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5239 | scriptId: scriptId || null | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5262 | located.push({ | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5263 | fn: record?.fn ?? null, | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5264 | ownerId: record?.ownerId ?? null, | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5340 | if (bg && bg !== 'rgba(0, 0, 0, 0)' && bg !== 'transparent') { | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5346 | if (bgImg && bgImg !== 'none') { | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5349 | images.push({ src: m[1], type: 'bg', w: Math.round(rect.width), h: Math.round(rect.heigh | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5356 | if (img.src && img.naturalWidth > 0 && !img.src.startsWith('data:')) { | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5357 | images.push({ src: img.src, type: 'img', w: img.naturalWidth, h: img.naturalHeight }); | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5389 | while (current && current.nodeType === 1) { | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5392 | style.visibility === 'collapse' || Number(style.opacity) === 0 || current.hidden) re | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5400 | if (rect.width < .5 || rect.height < .5) return; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5401 | if (documentWidth > 4096 && documentHeight > 4096 && | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5403 | rects.push({x, y, right: x + rect.width, bottom: y + rect.height}); | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5418 | parseFloat(style.borderTopWidth) > 0 || parseFloat(style.borderRightWidth) > 0 || | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5419 | parseFloat(style.borderBottomWidth) > 0 || parseFloat(style.borderLeftWidth) > 0; | CODE |
| HIGH⚡ | lanhu_mcp_server.py | 5426 | } : null; | CODE |
| HIGH | lanhu_mcp_server.py | 5140 | while (current && current.nodeType === 1) { | CODE |
| HIGH | lanhu_mcp_server.py | 5144 | current.hidden || current.getAttribute('aria-hidden') === 'true') return false; | CODE |
| HIGH | lanhu_mcp_server.py | 5159 | const rects = Array.from(range.getClientRects()).filter(r => r.width >= 0.5 && r.height >= 0.5); | CODE |
| HIGH | lanhu_mcp_server.py | 5325 | if (rect.width < 1 || rect.height < 1) return; | CODE |
| HIGH | lanhu_mcp_server.py | 5329 | n => n.nodeType === 3 && n.textContent.trim().length > 0 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | lanhu_mcp_server.py | 4878 | async def capture_axure_focus_regions_internal( | CODE |
| LOW | lanhu_mcp_server.py | 468 | def _enable_embedded_lanhu_design() -> None: | CODE |
| LOW | lanhu_mcp_server.py | 963 | def _resolve_loop_placeholder(value: str, loop_item: dict) -> str: | CODE |
| LOW | lanhu_mcp_server.py | 1145 | def _has_only_transparent_solid(fills: list) -> bool: | CODE |
| LOW | lanhu_mcp_server.py | 5560 | async def lanhu_resolve_invite_link( | CODE |
| LOW | lanhu_mcp_server.py | 5640 | def _get_analysis_mode_options_by_role(user_role: str) -> str: | CODE |
| LOW | lanhu_mcp_server.py | 7076 | async def lanhu_get_ai_analyze_design_result( | CODE |
| LOW | lanhu_mcp_server.py | 8246 | async def lanhu_get_design_overview( | CODE |
| LOW | lanhu_mcp_server.py | 8272 | async def lanhu_inspect_design_region( | CODE |
| LOW | lanhu_mcp_server.py | 8297 | async def lanhu_export_design_assets( | CODE |
| LOW⚡ | lanhu_mcp_server.py | 1823 | def _extract_full_annotations_from_sketch(sketch_data: dict, design_scale: float = 2.0) -> str: | STRING |
| LOW⚡ | lanhu_mcp_server.py | 4829 | async def _extract_axure_page_metrics(page) -> dict: | STRING |
| LOW | lanhu_mcp_server.py | 3168 | async def _find_current_axure_doc_id(self, project_id: str, team_id: str, | STRING |
| LOW | lanhu_mcp_server.py | 4219 | async def _get_version_id_by_image_id(self, project_id: str, team_id: str = None, image_id: str = None) -> str: | STRING |
| LOW | lanhu_mcp_server.py | 4330 | def _format_axure_annotations_for_text(axure_annotations: Optional[dict]) -> str: | STRING |
| LOW | lanhu_mcp_server.py | 4509 | def _select_axure_screenshot_clip(metrics: dict, margin: int = 32) -> Optional[dict]: | STRING |
| LOW | lanhu_mcp_server.py | 4610 | def _plan_axure_screenshot_tiles(metrics: dict, text_blocks: Optional[List[dict]] = None) -> List[dict]: | STRING |
| LOW | lanhu_mcp_server.py | 4730 | def _normalize_axure_anchor_text(value: str) -> str: | STRING |
| LOW | lanhu_mcp_server.py | 4744 | def _center_axure_focus_region(anchor: dict, document_size: dict, width: float, height: float) -> dict: | STRING |
| LOW | lanhu_mcp_server.py | 4788 | def _parse_axure_focus_levels(value: str) -> List[str]: | STRING |
| LOW | lanhu_mcp_server.py | 5714 | async def lanhu_list_product_documents( | STRING |
| LOW | lanhu_mcp_server.py | 6335 | def _get_analysis_mode_prompt(analysis_mode: str) -> dict: | STRING |
| LOW | lanhu_mcp_server.py | 6369 | async def lanhu_get_ai_analyze_page_result( | STRING |
| LOW | lanhu_mcp_server.py | 6715 | async def lanhu_inspect_requirement_region( | STRING |
| LOW | lanhu_mcp_server.py | 6890 | def _normalize_design_sectors(sectors: List[dict]) -> tuple[List[dict], dict[str, List[dict]]]: | STRING |
| LOW | lanhu_design/variants.py | 121 | def validate_downloaded_variant(selected: dict, decoded: dict) -> None: | CODE |
| LOW | lanhu_design/install.py | 273 | def _decode_resource_contents(contents: Any) -> bytes: | CODE |
| LOW | tests/test_design_service.py | 66 | async def test_exact_versions_and_snapshot_queries_never_switch_to_latest(tmp_path): | CODE |
| LOW | tests/test_design_service.py | 87 | async def test_region_crop_pagination_validation_and_unknown_ids(tmp_path): | CODE |
| LOW | tests/test_design_service.py | 110 | async def test_dds_failure_is_explicit_and_does_not_mix_newer_layout(tmp_path): | CODE |
| LOW | tests/test_design_service.py | 121 | async def test_mcp_image_and_bundle_can_be_installed_on_a_separate_client_path(tmp_path, monkeypatch): | CODE |
| LOW | tests/test_design_service.py | 157 | async def test_partial_exports_and_unknown_assets_are_not_false_success(tmp_path): | CODE |
| LOW | tests/test_design_service.py | 168 | def test_mixed_design_url_preserves_design_identity_and_requires_exact_version(): | CODE |
| LOW | tests/test_design_service.py | 177 | async def test_credentials_do_not_follow_cdn_redirects(tmp_path, monkeypatch): | CODE |
| LOW | tests/test_design_service.py | 197 | async def test_a_different_credential_namespace_cannot_read_cached_resources(tmp_path): | CODE |
| LOW | tests/test_design_service.py | 207 | async def test_hidden_ancestor_and_numeric_dds_ids_are_respected(tmp_path): | CODE |
| LOW | tests/test_design_service.py | 226 | async def test_unverified_nonfigma_origin_allows_read_only_overview_but_blocks_export(tmp_path): | CODE |
| LOW | tests/test_design_service.py | 248 | async def test_figma_nonzero_origin_supports_overview_inspection_and_export(tmp_path): | CODE |
| LOW | tests/test_design_service.py | 271 | async def test_changed_normalizer_output_does_not_reuse_old_derived_snapshot(tmp_path, monkeypatch): | CODE |
| LOW | tests/test_design_service.py | 287 | async def test_mcp_visual_failures_are_json_objects_and_preserve_decoder_reason(tmp_path, monkeypatch): | CODE |
| LOW | tests/test_design_service.py | 309 | async def test_large_reference_uses_bounded_overview_and_native_region(tmp_path, monkeypatch): | CODE |
| LOW | tests/test_design_service.py | 346 | async def test_region_fetch_failure_returns_labeled_lower_resolution_evidence(tmp_path): | CODE |
| LOW | tests/test_design_service.py | 362 | async def test_svg_selection_is_public_and_has_separate_verifiable_bundle(tmp_path): | CODE |
| LOW | tests/test_design_service.py | 394 | def test_font_requirements_keep_mixed_numeric_and_named_weights(): | CODE |
| LOW | tests/test_design_service.py | 405 | async def test_overview_font_inventory_is_not_limited_by_node_pagination(tmp_path, monkeypatch): | CODE |
| LOW | tests/test_design_service.py | 425 | async def test_refreshed_signed_url_updates_transport_without_changing_snapshot_identity(tmp_path): | CODE |
| LOW | tests/test_design_service.py | 444 | async def test_tiny_provider_image_is_not_reported_as_native_detail(tmp_path): | CODE |
| LOW | tests/test_design_service.py | 464 | async def test_raster_request_cannot_succeed_with_hidden_svg_and_failure_is_retryable(tmp_path): | CODE |
| LOW | tests/test_basic.py | 37 | def test_data_directory_creation(): | CODE |
| LOW | tests/test_package_runtime.py | 66 | def test_installed_launcher_configuration(installed_runtime, case, expected_cookie): | CODE |
| LOW | tests/test_package_runtime.py | 95 | def test_installed_launcher_rejects_missing_explicit_configuration(installed_runtime): | CODE |
| LOW | tests/test_package_runtime.py | 127 | async def test_notification_diagnostics_use_stderr_only(notification_server, monkeypatch, capsys, | CODE |
| LOW | tests/test_package_runtime.py | 163 | def test_single_file_upgrade_keeps_requirement_server_importable(tmp_path): | CODE |
| LOW | tests/test_package_runtime.py | 197 | def test_embedded_design_package_makes_main_server_a_full_single_file(tmp_path): | CODE |
| LOW | tests/test_package_runtime.py | 228 | def test_embedded_design_payload_matches_modular_sources(): | CODE |
| LOW | tests/test_design_media.py | 39 | def test_region_maps_design_units_to_crop_pixels_and_clamps(): | CODE |
| LOW | tests/test_design_media.py | 51 | def test_region_pixels_and_mapping_respect_nonzero_canvas_origin(): | CODE |
| LOW | tests/test_design_media.py | 66 | def test_labels_are_source_order_stable_and_measurements_are_geometry_only(): | CODE |
| LOW | tests/test_design_media.py | 77 | def test_missing_hidden_and_outside_nodes_do_not_get_invented_positions(): | CODE |
| LOW | tests/test_design_media.py | 84 | def test_degenerate_or_invalid_node_bounds_do_not_break_valid_visual_evidence(): | CODE |
| 111 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | setup-env.sh | 61 | # ============================================== | COMMENT |
| MEDIUM⚡ | setup-env.sh | 63 | # ============================================== | COMMENT |
| MEDIUM⚡ | setup-env.sh | 68 | # ============================================== | COMMENT |
| MEDIUM⚡ | setup-env.sh | 70 | # ============================================== | COMMENT |
| MEDIUM⚡ | setup-env.sh | 78 | # ============================================== | COMMENT |
| MEDIUM⚡ | setup-env.sh | 80 | # ============================================== | COMMENT |
| MEDIUM⚡ | setup-env.sh | 85 | # ============================================== | COMMENT |
| MEDIUM⚡ | setup-env.sh | 87 | # ============================================== | COMMENT |
| MEDIUM⚡ | setup-env.sh | 92 | # ============================================== | COMMENT |
| MEDIUM⚡ | setup-env.sh | 94 | # ============================================== | COMMENT |
| MEDIUM | setup-env.sh | 105 | # ============================================== | COMMENT |
| MEDIUM | setup-env.sh | 107 | # ============================================== | COMMENT |
| MEDIUM | easy-install.sh | 46 | # ============================================ | COMMENT |
| MEDIUM | easy-install.sh | 48 | # ============================================ | COMMENT |
| MEDIUM | easy-install.sh | 102 | # ============================================ | COMMENT |
| MEDIUM | easy-install.sh | 104 | # ============================================ | COMMENT |
| MEDIUM | easy-install.sh | 213 | # ============================================ | COMMENT |
| MEDIUM | easy-install.sh | 215 | # ============================================ | COMMENT |
| MEDIUM | easy-install.sh | 309 | # ============================================ | COMMENT |
| MEDIUM | easy-install.sh | 311 | # ============================================ | COMMENT |
| MEDIUM | easy-install.sh | 325 | # ============================================ | COMMENT |
| MEDIUM | easy-install.sh | 327 | # ============================================ | COMMENT |
| MEDIUM | docker-compose.yml | 25 | # ============================================ | COMMENT |
| MEDIUM | docker-compose.yml | 27 | # ============================================ | COMMENT |
| MEDIUM⚡ | lanhu_mcp_server.py | 2515 | # ============================================ | STRING |
| MEDIUM⚡ | lanhu_mcp_server.py | 2517 | # ============================================ | STRING |
| MEDIUM | lanhu_mcp_server.py | 2357 | # ============================================ | STRING |
| MEDIUM | lanhu_mcp_server.py | 2359 | # ============================================ | STRING |
| MEDIUM | lanhu_mcp_server.py | 6096 | # ============================================ | STRING |
| MEDIUM | lanhu_mcp_server.py | 6098 | # ============================================ | STRING |
| MEDIUM | tests/test_product_documents.py | 22 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_product_documents.py | 24 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_product_documents.py | 42 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/test_product_documents.py | 44 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_product_documents.py | 61 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/test_product_documents.py | 63 | # --------------------------------------------------------------------------- | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | lanhu_mcp_server.py | 514 | except ImportError: | CODE |
| HIGH | lanhu_mcp_server.py | 2853 | except Exception: | CODE |
| HIGH | lanhu_mcp_server.py | 3000 | except Exception: | CODE |
| HIGH | lanhu_mcp_server.py | 3445 | except Exception: | CODE |
| HIGH | lanhu_mcp_server.py | 3714 | except Exception: | CODE |
| HIGH | lanhu_mcp_server.py | 5553 | except Exception: | CODE |
| HIGH | lanhu_mcp_server.py | 2547 | except Exception: | CODE |
| HIGH | lanhu_mcp_server.py | 2994 | except Exception: | CODE |
| HIGH | lanhu_mcp_server.py | 7276 | except Exception: | CODE |
| HIGH | lanhu_mcp_server.py | 5042 | except Exception: | CODE |
| HIGH | lanhu_mcp_server.py | 5051 | except Exception: | CODE |
| HIGH | lanhu_mcp_server.py | 5059 | except Exception: | CODE |
| HIGH | lanhu_mcp_server.py | 5477 | except Exception: | CODE |
| HIGH | lanhu_mcp_server.py | 5495 | except Exception: | CODE |
| HIGH | lanhu_mcp_server.py | 5485 | except Exception: | CODE |
| HIGH | lanhu_design/media.py | 355 | except (OSError, ValueError, AttributeError, TypeError): | CODE |
| HIGH | lanhu_design/media.py | 264 | except ValueError: | CODE |
| HIGH | lanhu_design/media.py | 378 | except (OSError, ValueError): | CODE |
| HIGH | lanhu_design/install.py | 267 | except OSError: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | lanhu_mcp_server.py | 5033 | except Exception: | CODE |
| LOW⚡ | lanhu_mcp_server.py | 5042 | except Exception: | CODE |
| LOW⚡ | lanhu_mcp_server.py | 5051 | except Exception: | CODE |
| LOW⚡ | lanhu_mcp_server.py | 5059 | except Exception: | CODE |
| LOW⚡ | lanhu_mcp_server.py | 5477 | except Exception: | CODE |
| LOW⚡ | lanhu_mcp_server.py | 5485 | except Exception: | CODE |
| LOW⚡ | lanhu_mcp_server.py | 5495 | except Exception: | CODE |
| LOW | lanhu_mcp_server.py | 541 | except Exception: | CODE |
| LOW | lanhu_mcp_server.py | 4992 | except Exception: | CODE |
| LOW | lanhu_mcp_server.py | 5022 | except Exception: | CODE |
| LOW | lanhu_mcp_server.py | 5462 | except Exception as tile_error: | CODE |
| LOW | lanhu_mcp_server.py | 5532 | except Exception as e: | CODE |
| LOW | lanhu_mcp_server.py | 5553 | except Exception: | CODE |
| LOW | lanhu_mcp_server.py | 5620 | except Exception as e: | CODE |
| LOW | lanhu_mcp_server.py | 5631 | except Exception as e: | CODE |
| LOW | lanhu_mcp_server.py | 6982 | except Exception as e: | CODE |
| LOW | lanhu_mcp_server.py | 7193 | except Exception as e: | CODE |
| LOW | lanhu_mcp_server.py | 7230 | except Exception as e: | CODE |
| LOW | lanhu_mcp_server.py | 7276 | except Exception: | CODE |
| LOW | lanhu_mcp_server.py | 7542 | except Exception as e: | CODE |
| LOW | lanhu_mcp_server.py | 7670 | except Exception as e: | CODE |
| LOW | lanhu_mcp_server.py | 8110 | except Exception as e: | CODE |
| LOW | lanhu_mcp_server.py | 8267 | except Exception as exc: | CODE |
| LOW | lanhu_mcp_server.py | 8292 | except Exception as exc: | CODE |
| LOW | lanhu_mcp_server.py | 8314 | except Exception as exc: | CODE |
| LOW⚡ | lanhu_mcp_server.py | 2510 | except Exception as e: | STRING |
| LOW⚡ | lanhu_mcp_server.py | 4824 | except Exception: | STRING |
| LOW | lanhu_mcp_server.py | 2547 | except Exception: | STRING |
| LOW | lanhu_mcp_server.py | 2745 | except Exception: | STRING |
| LOW | lanhu_mcp_server.py | 2853 | except Exception: | STRING |
| LOW | lanhu_mcp_server.py | 2967 | except Exception: | STRING |
| LOW | lanhu_mcp_server.py | 2994 | except Exception: | STRING |
| LOW | lanhu_mcp_server.py | 3000 | except Exception: | STRING |
| LOW | lanhu_mcp_server.py | 3222 | except Exception: | STRING |
| LOW | lanhu_mcp_server.py | 3307 | except Exception: | STRING |
| LOW | lanhu_mcp_server.py | 3445 | except Exception: | STRING |
| LOW | lanhu_mcp_server.py | 3473 | except Exception: | STRING |
| LOW | lanhu_mcp_server.py | 3714 | except Exception: | STRING |
| LOW | lanhu_mcp_server.py | 4807 | except Exception as exc: | STRING |
| LOW | lanhu_mcp_server.py | 4811 | except Exception: | STRING |
| LOW | lanhu_design/service.py | 115 | except Exception as exc: | CODE |
| LOW | lanhu_design/media.py | 395 | except Exception: | CODE |
| LOW | lanhu_design/install.py | 318 | except Exception as exc: | CODE |
| LOW⚡ | tests/test_product_documents.py | 232 | except Exception as e: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | lanhu_mcp_server.py | 790 | CODE | |
| LOW | lanhu_mcp_server.py | 828 | CODE | |
| LOW | lanhu_mcp_server.py | 927 | CODE | |
| LOW | lanhu_mcp_server.py | 1085 | CODE | |
| LOW | lanhu_mcp_server.py | 1331 | CODE | |
| LOW | lanhu_mcp_server.py | 1823 | CODE | |
| LOW | lanhu_mcp_server.py | 2361 | CODE | |
| LOW | lanhu_mcp_server.py | 2894 | CODE | |
| LOW | lanhu_mcp_server.py | 4384 | CODE | |
| LOW | lanhu_mcp_server.py | 4878 | CODE | |
| LOW | lanhu_mcp_server.py | 4963 | CODE | |
| LOW | lanhu_mcp_server.py | 6369 | CODE | |
| LOW | lanhu_mcp_server.py | 6715 | CODE | |
| LOW | lanhu_mcp_server.py | 7076 | CODE | |
| LOW | lanhu_mcp_server.py | 7427 | CODE | |
| LOW | lanhu_mcp_server.py | 7700 | CODE | |
| LOW | lanhu_mcp_server.py | 1206 | CODE | |
| LOW | lanhu_mcp_server.py | 1931 | CODE | |
| LOW | lanhu_mcp_server.py | 2413 | CODE | |
| LOW | lanhu_mcp_server.py | 3168 | CODE | |
| LOW | lanhu_mcp_server.py | 3816 | CODE | |
| LOW | lanhu_mcp_server.py | 3868 | CODE | |
| LOW | lanhu_design/service.py | 98 | CODE | |
| LOW | lanhu_design/service.py | 465 | CODE | |
| LOW | lanhu_design/media.py | 94 | CODE | |
| LOW | lanhu_design/media.py | 319 | CODE | |
| LOW | lanhu_design/media.py | 359 | CODE | |
| LOW | lanhu_design/variants.py | 148 | CODE | |
| LOW | lanhu_design/normalize.py | 139 | CODE | |
| LOW | lanhu_design/text.py | 97 | CODE | |
| LOW | lanhu_design/install.py | 194 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | lanhu_mcp_server.py | 7489 | CODE | |
| LOW | lanhu_design/service.py | 3 | CODE | |
| LOW | lanhu_design/media.py | 7 | CODE | |
| LOW | lanhu_design/normalize.py | 8 | CODE | |
| LOW | lanhu_design/text.py | 8 | CODE | |
| LOW | lanhu_design/install.py | 8 | CODE | |
| LOW | tests/test_basic.py | 19 | CODE | |
| LOW | tests/test_basic.py | 20 | CODE | |
| LOW | tests/test_basic.py | 21 | CODE | |
| LOW | tests/test_basic.py | 22 | CODE | |
| LOW | tests/test_basic.py | 23 | CODE | |
| LOW | scripts/embed_lanhu_design.py | 4 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | CONTRIBUTING.md | 124 | 从蓝湖URL获取元数据 Args: url: 蓝湖文档URL use_cache: 是否使用缓存,默认为True Returns: 包含元数据的字典 R | STRING |
| HIGH | lanhu_mcp_server.py | 3170 | 文档被替换后旧 docId 失效,通过 product_documents 定位当前有效 axure 文档。 Args: project_id: 项目 ID team_id: | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | setup-env.sh | 61 | # ============================================== | COMMENT |
| LOW | docker-compose.yml | 21 | - SERVER_PORT=8000 | COMMENT |
| LOW | docker-compose.yml | 41 | # docker-compose down | COMMENT |
| LOW | docker-compose.yml | 61 | # | COMMENT |
| LOW | lanhu_mcp_server.py | 6001 | #### 正向场景(P0) | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/test_requirement_cache.py | 87 | # Keep this test focused on orchestration; FastMCP image decoding is covered elsewhere. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | lanhu_mcp_server.py | 6715 | CODE | |
| LOW | lanhu_mcp_server.py | 2614 | CODE | |
| LOW | lanhu_design/service.py | 302 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | lanhu_mcp_server.py | 2235 | # Step 1: 从 CSS 规则中收集 url -> class_name 映射 | STRING |
| LOW⚡ | lanhu_mcp_server.py | 2245 | # Step 2: 替换 <img src="...">,优先用 img 的 class 属性 | STRING |
| LOW | lanhu_mcp_server.py | 2260 | # Step 3: 替换 CSS url(...) 背景图,用 CSS 类名作文件名 | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | lanhu_mcp_server.py | 2235 | # Step 1: 从 CSS 规则中收集 url -> class_name 映射 | STRING |
| LOW⚡ | lanhu_mcp_server.py | 2245 | # Step 2: 替换 <img src="...">,优先用 img 的 class 属性 | STRING |
| LOW | lanhu_mcp_server.py | 2260 | # Step 3: 替换 CSS url(...) 背景图,用 CSS 类名作文件名 | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_package_runtime.py | 146 | monkeypatch.setattr(server, "FEISHU_USER_ID_MAP", {"FixtureUser": "fake-user-id"}) | CODE |