@mison/ag-kit-cn 2.0.1
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.
- package/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
- package/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
- package/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
- package/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
- package/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
- package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
- package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
- package/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
- package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/search.py +106 -0
- package/.agent/ARCHITECTURE.md +285 -0
- package/.agent/agents/backend-specialist.md +268 -0
- package/.agent/agents/code-archaeologist.md +106 -0
- package/.agent/agents/database-architect.md +225 -0
- package/.agent/agents/debugger.md +225 -0
- package/.agent/agents/devops-engineer.md +242 -0
- package/.agent/agents/documentation-writer.md +104 -0
- package/.agent/agents/explorer-agent.md +73 -0
- package/.agent/agents/frontend-specialist.md +618 -0
- package/.agent/agents/game-developer.md +162 -0
- package/.agent/agents/mobile-developer.md +382 -0
- package/.agent/agents/orchestrator.md +438 -0
- package/.agent/agents/penetration-tester.md +188 -0
- package/.agent/agents/performance-optimizer.md +187 -0
- package/.agent/agents/product-manager.md +112 -0
- package/.agent/agents/product-owner.md +95 -0
- package/.agent/agents/project-planner.md +405 -0
- package/.agent/agents/qa-automation-engineer.md +103 -0
- package/.agent/agents/security-auditor.md +170 -0
- package/.agent/agents/seo-specialist.md +111 -0
- package/.agent/agents/test-engineer.md +158 -0
- package/.agent/mcp_config.json +12 -0
- package/.agent/rules/GEMINI.md +273 -0
- package/.agent/scripts/auto_preview.py +148 -0
- package/.agent/scripts/checklist.py +217 -0
- package/.agent/scripts/session_manager.py +120 -0
- package/.agent/scripts/verify_all.py +327 -0
- package/.agent/skills/api-patterns/SKILL.md +84 -0
- package/.agent/skills/api-patterns/api-style.md +42 -0
- package/.agent/skills/api-patterns/auth.md +24 -0
- package/.agent/skills/api-patterns/documentation.md +26 -0
- package/.agent/skills/api-patterns/graphql.md +41 -0
- package/.agent/skills/api-patterns/rate-limiting.md +31 -0
- package/.agent/skills/api-patterns/response.md +37 -0
- package/.agent/skills/api-patterns/rest.md +40 -0
- package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
- package/.agent/skills/api-patterns/security-testing.md +122 -0
- package/.agent/skills/api-patterns/trpc.md +41 -0
- package/.agent/skills/api-patterns/versioning.md +22 -0
- package/.agent/skills/app-builder/SKILL.md +75 -0
- package/.agent/skills/app-builder/agent-coordination.md +74 -0
- package/.agent/skills/app-builder/feature-building.md +53 -0
- package/.agent/skills/app-builder/project-detection.md +34 -0
- package/.agent/skills/app-builder/scaffolding.md +118 -0
- package/.agent/skills/app-builder/tech-stack.md +40 -0
- package/.agent/skills/app-builder/templates/SKILL.md +39 -0
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
- package/.agent/skills/architecture/SKILL.md +57 -0
- package/.agent/skills/architecture/context-discovery.md +43 -0
- package/.agent/skills/architecture/examples.md +94 -0
- package/.agent/skills/architecture/pattern-selection.md +68 -0
- package/.agent/skills/architecture/patterns-reference.md +50 -0
- package/.agent/skills/architecture/trade-off-analysis.md +77 -0
- package/.agent/skills/bash-linux/SKILL.md +201 -0
- package/.agent/skills/behavioral-modes/SKILL.md +264 -0
- package/.agent/skills/brainstorming/SKILL.md +164 -0
- package/.agent/skills/brainstorming/dynamic-questioning.md +359 -0
- package/.agent/skills/clean-code/SKILL.md +200 -0
- package/.agent/skills/code-review-checklist/SKILL.md +125 -0
- package/.agent/skills/database-design/SKILL.md +54 -0
- package/.agent/skills/database-design/database-selection.md +43 -0
- package/.agent/skills/database-design/indexing.md +39 -0
- package/.agent/skills/database-design/migrations.md +50 -0
- package/.agent/skills/database-design/optimization.md +36 -0
- package/.agent/skills/database-design/orm-selection.md +30 -0
- package/.agent/skills/database-design/schema-design.md +56 -0
- package/.agent/skills/database-design/scripts/schema_validator.py +172 -0
- package/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/.agent/skills/doc.md +177 -0
- package/.agent/skills/documentation-templates/SKILL.md +194 -0
- package/.agent/skills/frontend-design/SKILL.md +418 -0
- package/.agent/skills/frontend-design/animation-guide.md +331 -0
- package/.agent/skills/frontend-design/color-system.md +307 -0
- package/.agent/skills/frontend-design/decision-trees.md +418 -0
- package/.agent/skills/frontend-design/motion-graphics.md +306 -0
- package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
- package/.agent/skills/frontend-design/scripts/ux_audit.py +727 -0
- package/.agent/skills/frontend-design/typography-system.md +345 -0
- package/.agent/skills/frontend-design/ux-psychology.md +1118 -0
- package/.agent/skills/frontend-design/visual-effects.md +383 -0
- package/.agent/skills/game-development/2d-games/SKILL.md +119 -0
- package/.agent/skills/game-development/3d-games/SKILL.md +135 -0
- package/.agent/skills/game-development/SKILL.md +167 -0
- package/.agent/skills/game-development/game-art/SKILL.md +185 -0
- package/.agent/skills/game-development/game-audio/SKILL.md +190 -0
- package/.agent/skills/game-development/game-design/SKILL.md +129 -0
- package/.agent/skills/game-development/mobile-games/SKILL.md +108 -0
- package/.agent/skills/game-development/multiplayer/SKILL.md +132 -0
- package/.agent/skills/game-development/pc-games/SKILL.md +144 -0
- package/.agent/skills/game-development/vr-ar/SKILL.md +123 -0
- package/.agent/skills/game-development/web-games/SKILL.md +150 -0
- package/.agent/skills/geo-fundamentals/SKILL.md +155 -0
- package/.agent/skills/geo-fundamentals/scripts/geo_checker.py +289 -0
- package/.agent/skills/i18n-localization/SKILL.md +154 -0
- package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
- package/.agent/skills/intelligent-routing/SKILL.md +335 -0
- package/.agent/skills/lint-and-validate/SKILL.md +44 -0
- package/.agent/skills/lint-and-validate/scripts/lint_runner.py +184 -0
- package/.agent/skills/lint-and-validate/scripts/type_coverage.py +173 -0
- package/.agent/skills/mcp-builder/SKILL.md +176 -0
- package/.agent/skills/mobile-design/SKILL.md +394 -0
- package/.agent/skills/mobile-design/decision-trees.md +516 -0
- package/.agent/skills/mobile-design/mobile-backend.md +491 -0
- package/.agent/skills/mobile-design/mobile-color-system.md +420 -0
- package/.agent/skills/mobile-design/mobile-debugging.md +122 -0
- package/.agent/skills/mobile-design/mobile-design-thinking.md +355 -0
- package/.agent/skills/mobile-design/mobile-navigation.md +458 -0
- package/.agent/skills/mobile-design/mobile-performance.md +767 -0
- package/.agent/skills/mobile-design/mobile-testing.md +356 -0
- package/.agent/skills/mobile-design/mobile-typography.md +432 -0
- package/.agent/skills/mobile-design/platform-android.md +666 -0
- package/.agent/skills/mobile-design/platform-ios.md +561 -0
- package/.agent/skills/mobile-design/scripts/mobile_audit.py +670 -0
- package/.agent/skills/mobile-design/touch-psychology.md +537 -0
- package/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +311 -0
- package/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +241 -0
- package/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +489 -0
- package/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +263 -0
- package/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +581 -0
- package/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +431 -0
- package/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +683 -0
- package/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +149 -0
- package/.agent/skills/nextjs-react-expert/SKILL.md +286 -0
- package/.agent/skills/nextjs-react-expert/scripts/convert_rules.py +222 -0
- package/.agent/skills/nextjs-react-expert/scripts/react_performance_checker.py +252 -0
- package/.agent/skills/nodejs-best-practices/SKILL.md +333 -0
- package/.agent/skills/parallel-agents/SKILL.md +194 -0
- package/.agent/skills/performance-profiling/SKILL.md +149 -0
- package/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +76 -0
- package/.agent/skills/plan-writing/SKILL.md +152 -0
- package/.agent/skills/powershell-windows/SKILL.md +166 -0
- package/.agent/skills/python-patterns/SKILL.md +441 -0
- package/.agent/skills/red-team-tactics/SKILL.md +203 -0
- package/.agent/skills/rust-pro/SKILL.md +190 -0
- package/.agent/skills/seo-fundamentals/SKILL.md +135 -0
- package/.agent/skills/seo-fundamentals/scripts/seo_checker.py +215 -0
- package/.agent/skills/server-management/SKILL.md +161 -0
- package/.agent/skills/systematic-debugging/SKILL.md +114 -0
- package/.agent/skills/tailwind-patterns/SKILL.md +269 -0
- package/.agent/skills/tdd-workflow/SKILL.md +149 -0
- package/.agent/skills/testing-patterns/SKILL.md +178 -0
- package/.agent/skills/testing-patterns/scripts/test_runner.py +219 -0
- package/.agent/skills/vulnerability-scanner/SKILL.md +276 -0
- package/.agent/skills/vulnerability-scanner/checklists.md +131 -0
- package/.agent/skills/vulnerability-scanner/scripts/security_scan.py +459 -0
- package/.agent/skills/web-design-guidelines/SKILL.md +57 -0
- package/.agent/skills/webapp-testing/SKILL.md +187 -0
- package/.agent/skills/webapp-testing/scripts/playwright_runner.py +173 -0
- package/.agent/workflows/brainstorm.md +113 -0
- package/.agent/workflows/create.md +59 -0
- package/.agent/workflows/debug.md +103 -0
- package/.agent/workflows/deploy.md +176 -0
- package/.agent/workflows/enhance.md +63 -0
- package/.agent/workflows/orchestrate.md +242 -0
- package/.agent/workflows/plan.md +89 -0
- package/.agent/workflows/preview.md +80 -0
- package/.agent/workflows/restore-localize-compat.md +525 -0
- package/.agent/workflows/status.md +86 -0
- package/.agent/workflows/test.md +144 -0
- package/.agent/workflows/ui-ux-pro-max.md +295 -0
- package/AGENT_FLOW.md +609 -0
- package/CHANGELOG.md +68 -0
- package/LICENSE +21 -0
- package/README.md +260 -0
- package/bin/adapters/base.js +63 -0
- package/bin/adapters/codex.js +391 -0
- package/bin/adapters/gemini.js +137 -0
- package/bin/ag-kit.js +1336 -0
- package/bin/core/builder.js +80 -0
- package/bin/core/generator.js +59 -0
- package/bin/core/resource-loader.js +64 -0
- package/bin/core/transformer.js +208 -0
- package/bin/interactive.js +65 -0
- package/bin/utils/atomic-writer.js +97 -0
- package/bin/utils/git-helper.js +68 -0
- package/bin/utils/managed-block.js +65 -0
- package/bin/utils/manifest.js +241 -0
- package/bin/utils.js +82 -0
- package/docs/codex-rules-template.md +36 -0
- package/docs/mapping-spec.md +68 -0
- package/docs/multi-target-adapter.md +80 -0
- package/docs/official/README.md +53 -0
- package/docs/official/antigravity/agent-modes-settings.md +64 -0
- package/docs/official/antigravity/rules-workflows.md +96 -0
- package/docs/official/antigravity/skills.md +147 -0
- package/docs/official/codex/agents-md.md +119 -0
- package/docs/official/codex/config-advanced.md +358 -0
- package/docs/official/codex/config-basic.md +141 -0
- package/docs/official/codex/config-reference.md +223 -0
- package/docs/official/codex/config-sample.md +216 -0
- package/docs/official/codex/mcp.md +107 -0
- package/docs/official/codex/rules.md +79 -0
- package/docs/official/codex/skills.md +114 -0
- package/docs/official/sources-index.md +32 -0
- package/docs/operations.md +145 -0
- package/docs/terminology-style-guide.md +69 -0
- package/package.json +51 -0
- package/scripts/postinstall-check.js +112 -0
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Skill: vulnerability-scanner
|
|
4
|
+
Script: security_scan.py
|
|
5
|
+
Purpose: Validate that security principles from SKILL.md are applied correctly
|
|
6
|
+
Usage: python security_scan.py <project_path> [--scan-type all|deps|secrets|patterns|config]
|
|
7
|
+
Output: JSON with validation findings
|
|
8
|
+
|
|
9
|
+
This script verifies:
|
|
10
|
+
1. Dependencies - Supply chain security (OWASP A03)
|
|
11
|
+
2. Secrets - No hardcoded credentials (OWASP A04)
|
|
12
|
+
3. Code Patterns - Dangerous patterns identified (OWASP A05)
|
|
13
|
+
4. Configuration - Security settings validated (OWASP A02)
|
|
14
|
+
"""
|
|
15
|
+
import subprocess
|
|
16
|
+
import json
|
|
17
|
+
import os
|
|
18
|
+
import sys
|
|
19
|
+
import re
|
|
20
|
+
import argparse
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from typing import Dict, List, Any
|
|
23
|
+
from datetime import datetime
|
|
24
|
+
|
|
25
|
+
# Fix Windows console encoding for Unicode output
|
|
26
|
+
try:
|
|
27
|
+
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
|
28
|
+
sys.stderr.reconfigure(encoding='utf-8', errors='replace')
|
|
29
|
+
except AttributeError:
|
|
30
|
+
pass # Python < 3.7
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# ============================================================================
|
|
34
|
+
# CONFIGURATION
|
|
35
|
+
# ============================================================================
|
|
36
|
+
|
|
37
|
+
SECRET_PATTERNS = [
|
|
38
|
+
# API Keys & Tokens
|
|
39
|
+
(r'api[_-]?key\s*[=:]\s*["\'][^"\']{10,}["\']', "API Key", "high"),
|
|
40
|
+
(r'token\s*[=:]\s*["\'][^"\']{10,}["\']', "Token", "high"),
|
|
41
|
+
(r'bearer\s+[a-zA-Z0-9\-_.]+', "Bearer Token", "critical"),
|
|
42
|
+
|
|
43
|
+
# Cloud Credentials
|
|
44
|
+
(r'AKIA[0-9A-Z]{16}', "AWS Access Key", "critical"),
|
|
45
|
+
(r'aws[_-]?secret[_-]?access[_-]?key\s*[=:]\s*["\'][^"\']+["\']', "AWS Secret", "critical"),
|
|
46
|
+
(r'AZURE[_-]?[A-Z_]+\s*[=:]\s*["\'][^"\']+["\']', "Azure Credential", "critical"),
|
|
47
|
+
(r'GOOGLE[_-]?[A-Z_]+\s*[=:]\s*["\'][^"\']+["\']', "GCP Credential", "critical"),
|
|
48
|
+
|
|
49
|
+
# Database & Connections
|
|
50
|
+
(r'password\s*[=:]\s*["\'][^"\']{4,}["\']', "Password", "high"),
|
|
51
|
+
(r'(mongodb|postgres|mysql|redis):\/\/[^\s"\']+', "Database Connection String", "critical"),
|
|
52
|
+
|
|
53
|
+
# Private Keys
|
|
54
|
+
(r'-----BEGIN\s+(RSA|PRIVATE|EC)\s+KEY-----', "Private Key", "critical"),
|
|
55
|
+
(r'ssh-rsa\s+[A-Za-z0-9+/]+', "SSH Key", "critical"),
|
|
56
|
+
|
|
57
|
+
# JWT
|
|
58
|
+
(r'eyJ[A-Za-z0-9-_]+\.eyJ[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+', "JWT Token", "high"),
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
DANGEROUS_PATTERNS = [
|
|
62
|
+
# Injection risks
|
|
63
|
+
(r'eval\s*\(', "eval() usage", "critical", "Code Injection risk"),
|
|
64
|
+
(r'exec\s*\(', "exec() usage", "critical", "Code Injection risk"),
|
|
65
|
+
(r'new\s+Function\s*\(', "Function constructor", "high", "Code Injection risk"),
|
|
66
|
+
(r'child_process\.exec\s*\(', "child_process.exec", "high", "Command Injection risk"),
|
|
67
|
+
(r'subprocess\.call\s*\([^)]*shell\s*=\s*True', "subprocess with shell=True", "high", "Command Injection risk"),
|
|
68
|
+
|
|
69
|
+
# XSS risks
|
|
70
|
+
(r'dangerouslySetInnerHTML', "dangerouslySetInnerHTML", "high", "XSS risk"),
|
|
71
|
+
(r'\.innerHTML\s*=', "innerHTML assignment", "medium", "XSS risk"),
|
|
72
|
+
(r'document\.write\s*\(', "document.write", "medium", "XSS risk"),
|
|
73
|
+
|
|
74
|
+
# SQL Injection indicators
|
|
75
|
+
(r'["\'][^"\']*\+\s*[a-zA-Z_]+\s*\+\s*["\'].*(?:SELECT|INSERT|UPDATE|DELETE)', "SQL String Concat", "critical", "SQL Injection risk"),
|
|
76
|
+
(r'f"[^"]*(?:SELECT|INSERT|UPDATE|DELETE)[^"]*\{', "SQL f-string", "critical", "SQL Injection risk"),
|
|
77
|
+
|
|
78
|
+
# Insecure configurations
|
|
79
|
+
(r'verify\s*=\s*False', "SSL Verify Disabled", "high", "MITM risk"),
|
|
80
|
+
(r'--insecure', "Insecure flag", "medium", "Security disabled"),
|
|
81
|
+
(r'disable[_-]?ssl', "SSL Disabled", "high", "MITM risk"),
|
|
82
|
+
|
|
83
|
+
# Unsafe deserialization
|
|
84
|
+
(r'pickle\.loads?\s*\(', "pickle usage", "high", "Deserialization risk"),
|
|
85
|
+
(r'yaml\.load\s*\([^)]*\)(?!\s*,\s*Loader)', "Unsafe YAML load", "high", "Deserialization risk"),
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
SKIP_DIRS = {'node_modules', '.git', 'dist', 'build', '__pycache__', '.venv', 'venv', '.next', 'reference'}
|
|
89
|
+
CODE_EXTENSIONS = {'.js', '.ts', '.jsx', '.tsx', '.py', '.go', '.java', '.rb', '.php'}
|
|
90
|
+
CONFIG_EXTENSIONS = {'.json', '.yaml', '.yml', '.toml', '.env', '.env.local', '.env.development'}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# ============================================================================
|
|
94
|
+
# SCANNING FUNCTIONS
|
|
95
|
+
# ============================================================================
|
|
96
|
+
|
|
97
|
+
def scan_dependencies(project_path: str) -> Dict[str, Any]:
|
|
98
|
+
"""
|
|
99
|
+
Validate supply chain security (OWASP A03).
|
|
100
|
+
Checks: npm audit, lock file presence, dependency age.
|
|
101
|
+
"""
|
|
102
|
+
results = {"tool": "dependency_scanner", "findings": [], "status": "[OK] Secure"}
|
|
103
|
+
|
|
104
|
+
# Check for lock files
|
|
105
|
+
lock_files = {
|
|
106
|
+
"npm": ["package-lock.json", "npm-shrinkwrap.json"],
|
|
107
|
+
"yarn": ["yarn.lock"],
|
|
108
|
+
"pnpm": ["pnpm-lock.yaml"],
|
|
109
|
+
"pip": ["requirements.txt", "Pipfile.lock", "poetry.lock"],
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
found_locks = []
|
|
113
|
+
missing_locks = []
|
|
114
|
+
|
|
115
|
+
for manager, files in lock_files.items():
|
|
116
|
+
pkg_file = "package.json" if manager in ["npm", "yarn", "pnpm"] else "setup.py"
|
|
117
|
+
pkg_path = Path(project_path) / pkg_file
|
|
118
|
+
|
|
119
|
+
if pkg_path.exists() or (manager == "pip" and (Path(project_path) / "requirements.txt").exists()):
|
|
120
|
+
has_lock = any((Path(project_path) / f).exists() for f in files)
|
|
121
|
+
if has_lock:
|
|
122
|
+
found_locks.append(manager)
|
|
123
|
+
else:
|
|
124
|
+
missing_locks.append(manager)
|
|
125
|
+
results["findings"].append({
|
|
126
|
+
"type": "Missing Lock File",
|
|
127
|
+
"severity": "high",
|
|
128
|
+
"message": f"{manager}: No lock file found. Supply chain integrity at risk."
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
# Run npm audit if applicable
|
|
132
|
+
if (Path(project_path) / "package.json").exists():
|
|
133
|
+
try:
|
|
134
|
+
result = subprocess.run(
|
|
135
|
+
["npm", "audit", "--json"],
|
|
136
|
+
cwd=project_path,
|
|
137
|
+
capture_output=True,
|
|
138
|
+
text=True,
|
|
139
|
+
shell=True,
|
|
140
|
+
timeout=60
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
try:
|
|
144
|
+
audit_data = json.loads(result.stdout)
|
|
145
|
+
vulnerabilities = audit_data.get("vulnerabilities", {})
|
|
146
|
+
|
|
147
|
+
severity_count = {"critical": 0, "high": 0, "moderate": 0, "low": 0}
|
|
148
|
+
for vuln in vulnerabilities.values():
|
|
149
|
+
sev = vuln.get("severity", "low").lower()
|
|
150
|
+
if sev in severity_count:
|
|
151
|
+
severity_count[sev] += 1
|
|
152
|
+
|
|
153
|
+
if severity_count["critical"] > 0:
|
|
154
|
+
results["status"] = "[!!] Critical vulnerabilities"
|
|
155
|
+
results["findings"].append({
|
|
156
|
+
"type": "npm audit",
|
|
157
|
+
"severity": "critical",
|
|
158
|
+
"message": f"{severity_count['critical']} critical vulnerabilities in dependencies"
|
|
159
|
+
})
|
|
160
|
+
elif severity_count["high"] > 0:
|
|
161
|
+
results["status"] = "[!] High vulnerabilities"
|
|
162
|
+
results["findings"].append({
|
|
163
|
+
"type": "npm audit",
|
|
164
|
+
"severity": "high",
|
|
165
|
+
"message": f"{severity_count['high']} high severity vulnerabilities"
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
results["npm_audit"] = severity_count
|
|
169
|
+
|
|
170
|
+
except json.JSONDecodeError:
|
|
171
|
+
pass
|
|
172
|
+
|
|
173
|
+
except (FileNotFoundError, subprocess.TimeoutExpired):
|
|
174
|
+
pass
|
|
175
|
+
|
|
176
|
+
if not results["findings"]:
|
|
177
|
+
results["status"] = "[OK] Supply chain checks passed"
|
|
178
|
+
|
|
179
|
+
return results
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def scan_secrets(project_path: str) -> Dict[str, Any]:
|
|
183
|
+
"""
|
|
184
|
+
Validate no hardcoded secrets (OWASP A04).
|
|
185
|
+
Checks: API keys, tokens, passwords, cloud credentials.
|
|
186
|
+
"""
|
|
187
|
+
results = {
|
|
188
|
+
"tool": "secret_scanner",
|
|
189
|
+
"findings": [],
|
|
190
|
+
"status": "[OK] No secrets detected",
|
|
191
|
+
"scanned_files": 0,
|
|
192
|
+
"by_severity": {"critical": 0, "high": 0, "medium": 0}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
for root, dirs, files in os.walk(project_path):
|
|
196
|
+
dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
|
|
197
|
+
|
|
198
|
+
for file in files:
|
|
199
|
+
ext = Path(file).suffix.lower()
|
|
200
|
+
if ext not in CODE_EXTENSIONS and ext not in CONFIG_EXTENSIONS:
|
|
201
|
+
continue
|
|
202
|
+
|
|
203
|
+
filepath = Path(root) / file
|
|
204
|
+
results["scanned_files"] += 1
|
|
205
|
+
|
|
206
|
+
try:
|
|
207
|
+
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
|
|
208
|
+
content = f.read()
|
|
209
|
+
|
|
210
|
+
for pattern, secret_type, severity in SECRET_PATTERNS:
|
|
211
|
+
matches = re.findall(pattern, content, re.IGNORECASE)
|
|
212
|
+
if matches:
|
|
213
|
+
results["findings"].append({
|
|
214
|
+
"file": str(filepath.relative_to(project_path)),
|
|
215
|
+
"type": secret_type,
|
|
216
|
+
"severity": severity,
|
|
217
|
+
"count": len(matches)
|
|
218
|
+
})
|
|
219
|
+
results["by_severity"][severity] += len(matches)
|
|
220
|
+
|
|
221
|
+
except Exception:
|
|
222
|
+
pass
|
|
223
|
+
|
|
224
|
+
if results["by_severity"]["critical"] > 0:
|
|
225
|
+
results["status"] = "[!!] CRITICAL: Secrets exposed!"
|
|
226
|
+
elif results["by_severity"]["high"] > 0:
|
|
227
|
+
results["status"] = "[!] HIGH: Secrets found"
|
|
228
|
+
elif sum(results["by_severity"].values()) > 0:
|
|
229
|
+
results["status"] = "[?] Potential secrets detected"
|
|
230
|
+
|
|
231
|
+
# Limit findings for output
|
|
232
|
+
results["findings"] = results["findings"][:15]
|
|
233
|
+
|
|
234
|
+
return results
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def scan_code_patterns(project_path: str) -> Dict[str, Any]:
|
|
238
|
+
"""
|
|
239
|
+
Validate dangerous code patterns (OWASP A05).
|
|
240
|
+
Checks: Injection risks, XSS, unsafe deserialization.
|
|
241
|
+
"""
|
|
242
|
+
results = {
|
|
243
|
+
"tool": "pattern_scanner",
|
|
244
|
+
"findings": [],
|
|
245
|
+
"status": "[OK] No dangerous patterns",
|
|
246
|
+
"scanned_files": 0,
|
|
247
|
+
"by_category": {}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
for root, dirs, files in os.walk(project_path):
|
|
251
|
+
dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
|
|
252
|
+
|
|
253
|
+
for file in files:
|
|
254
|
+
ext = Path(file).suffix.lower()
|
|
255
|
+
if ext not in CODE_EXTENSIONS:
|
|
256
|
+
continue
|
|
257
|
+
|
|
258
|
+
filepath = Path(root) / file
|
|
259
|
+
results["scanned_files"] += 1
|
|
260
|
+
|
|
261
|
+
try:
|
|
262
|
+
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
|
|
263
|
+
lines = f.readlines()
|
|
264
|
+
|
|
265
|
+
for line_num, line in enumerate(lines, 1):
|
|
266
|
+
for pattern, name, severity, category in DANGEROUS_PATTERNS:
|
|
267
|
+
if re.search(pattern, line, re.IGNORECASE):
|
|
268
|
+
results["findings"].append({
|
|
269
|
+
"file": str(filepath.relative_to(project_path)),
|
|
270
|
+
"line": line_num,
|
|
271
|
+
"pattern": name,
|
|
272
|
+
"severity": severity,
|
|
273
|
+
"category": category,
|
|
274
|
+
"snippet": line.strip()[:80]
|
|
275
|
+
})
|
|
276
|
+
results["by_category"][category] = results["by_category"].get(category, 0) + 1
|
|
277
|
+
|
|
278
|
+
except Exception:
|
|
279
|
+
pass
|
|
280
|
+
|
|
281
|
+
critical_count = sum(1 for f in results["findings"] if f["severity"] == "critical")
|
|
282
|
+
high_count = sum(1 for f in results["findings"] if f["severity"] == "high")
|
|
283
|
+
|
|
284
|
+
if critical_count > 0:
|
|
285
|
+
results["status"] = f"[!!] CRITICAL: {critical_count} dangerous patterns"
|
|
286
|
+
elif high_count > 0:
|
|
287
|
+
results["status"] = f"[!] HIGH: {high_count} risky patterns"
|
|
288
|
+
elif results["findings"]:
|
|
289
|
+
results["status"] = "[?] Some patterns need review"
|
|
290
|
+
|
|
291
|
+
# Limit findings
|
|
292
|
+
results["findings"] = results["findings"][:20]
|
|
293
|
+
|
|
294
|
+
return results
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def scan_configuration(project_path: str) -> Dict[str, Any]:
|
|
298
|
+
"""
|
|
299
|
+
Validate security configuration (OWASP A02).
|
|
300
|
+
Checks: Security headers, CORS, debug modes.
|
|
301
|
+
"""
|
|
302
|
+
results = {
|
|
303
|
+
"tool": "config_scanner",
|
|
304
|
+
"findings": [],
|
|
305
|
+
"status": "[OK] Configuration secure",
|
|
306
|
+
"checks": {}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
# Check common config files for issues
|
|
310
|
+
config_issues = [
|
|
311
|
+
(r'"DEBUG"\s*:\s*true', "Debug mode enabled", "high"),
|
|
312
|
+
(r'debug\s*=\s*True', "Debug mode enabled", "high"),
|
|
313
|
+
(r'NODE_ENV.*development', "Development mode in config", "medium"),
|
|
314
|
+
(r'"CORS_ALLOW_ALL".*true', "CORS allow all origins", "high"),
|
|
315
|
+
(r'"Access-Control-Allow-Origin".*\*', "CORS wildcard", "high"),
|
|
316
|
+
(r'allowCredentials.*true.*origin.*\*', "Dangerous CORS combo", "critical"),
|
|
317
|
+
]
|
|
318
|
+
|
|
319
|
+
for root, dirs, files in os.walk(project_path):
|
|
320
|
+
dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
|
|
321
|
+
|
|
322
|
+
for file in files:
|
|
323
|
+
ext = Path(file).suffix.lower()
|
|
324
|
+
if ext not in CONFIG_EXTENSIONS and file not in ['next.config.js', 'webpack.config.js', '.eslintrc.js']:
|
|
325
|
+
continue
|
|
326
|
+
|
|
327
|
+
filepath = Path(root) / file
|
|
328
|
+
|
|
329
|
+
try:
|
|
330
|
+
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
|
|
331
|
+
content = f.read()
|
|
332
|
+
|
|
333
|
+
for pattern, issue, severity in config_issues:
|
|
334
|
+
if re.search(pattern, content, re.IGNORECASE):
|
|
335
|
+
results["findings"].append({
|
|
336
|
+
"file": str(filepath.relative_to(project_path)),
|
|
337
|
+
"issue": issue,
|
|
338
|
+
"severity": severity
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
except Exception:
|
|
342
|
+
pass
|
|
343
|
+
|
|
344
|
+
# Check for security header configurations
|
|
345
|
+
header_files = ["next.config.js", "next.config.mjs", "middleware.ts", "nginx.conf"]
|
|
346
|
+
for hf in header_files:
|
|
347
|
+
hf_path = Path(project_path) / hf
|
|
348
|
+
if hf_path.exists():
|
|
349
|
+
results["checks"]["security_headers_config"] = True
|
|
350
|
+
break
|
|
351
|
+
else:
|
|
352
|
+
results["checks"]["security_headers_config"] = False
|
|
353
|
+
results["findings"].append({
|
|
354
|
+
"issue": "No security headers configuration found",
|
|
355
|
+
"severity": "medium",
|
|
356
|
+
"recommendation": "Configure CSP, HSTS, X-Frame-Options headers"
|
|
357
|
+
})
|
|
358
|
+
|
|
359
|
+
if any(f["severity"] == "critical" for f in results["findings"]):
|
|
360
|
+
results["status"] = "[!!] CRITICAL: Configuration issues"
|
|
361
|
+
elif any(f["severity"] == "high" for f in results["findings"]):
|
|
362
|
+
results["status"] = "[!] HIGH: Configuration review needed"
|
|
363
|
+
elif results["findings"]:
|
|
364
|
+
results["status"] = "[?] Minor configuration issues"
|
|
365
|
+
|
|
366
|
+
return results
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
# ============================================================================
|
|
370
|
+
# MAIN
|
|
371
|
+
# ============================================================================
|
|
372
|
+
|
|
373
|
+
def run_full_scan(project_path: str, scan_type: str = "all") -> Dict[str, Any]:
|
|
374
|
+
"""Execute security validation scans."""
|
|
375
|
+
|
|
376
|
+
report = {
|
|
377
|
+
"project": project_path,
|
|
378
|
+
"timestamp": datetime.now().isoformat(),
|
|
379
|
+
"scan_type": scan_type,
|
|
380
|
+
"scans": {},
|
|
381
|
+
"summary": {
|
|
382
|
+
"total_findings": 0,
|
|
383
|
+
"critical": 0,
|
|
384
|
+
"high": 0,
|
|
385
|
+
"overall_status": "[OK] SECURE"
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
scanners = {
|
|
390
|
+
"deps": ("dependencies", scan_dependencies),
|
|
391
|
+
"secrets": ("secrets", scan_secrets),
|
|
392
|
+
"patterns": ("code_patterns", scan_code_patterns),
|
|
393
|
+
"config": ("configuration", scan_configuration),
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
for key, (name, scanner) in scanners.items():
|
|
397
|
+
if scan_type == "all" or scan_type == key:
|
|
398
|
+
result = scanner(project_path)
|
|
399
|
+
report["scans"][name] = result
|
|
400
|
+
|
|
401
|
+
findings_count = len(result.get("findings", []))
|
|
402
|
+
report["summary"]["total_findings"] += findings_count
|
|
403
|
+
|
|
404
|
+
for finding in result.get("findings", []):
|
|
405
|
+
sev = finding.get("severity", "low")
|
|
406
|
+
if sev == "critical":
|
|
407
|
+
report["summary"]["critical"] += 1
|
|
408
|
+
elif sev == "high":
|
|
409
|
+
report["summary"]["high"] += 1
|
|
410
|
+
|
|
411
|
+
# Determine overall status
|
|
412
|
+
if report["summary"]["critical"] > 0:
|
|
413
|
+
report["summary"]["overall_status"] = "[!!] CRITICAL ISSUES FOUND"
|
|
414
|
+
elif report["summary"]["high"] > 0:
|
|
415
|
+
report["summary"]["overall_status"] = "[!] HIGH RISK ISSUES"
|
|
416
|
+
elif report["summary"]["total_findings"] > 0:
|
|
417
|
+
report["summary"]["overall_status"] = "[?] REVIEW RECOMMENDED"
|
|
418
|
+
|
|
419
|
+
return report
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
def main():
|
|
423
|
+
parser = argparse.ArgumentParser(
|
|
424
|
+
description="Validate security principles from vulnerability-scanner skill"
|
|
425
|
+
)
|
|
426
|
+
parser.add_argument("project_path", nargs="?", default=".", help="Project directory to scan")
|
|
427
|
+
parser.add_argument("--scan-type", choices=["all", "deps", "secrets", "patterns", "config"],
|
|
428
|
+
default="all", help="Type of scan to run")
|
|
429
|
+
parser.add_argument("--output", choices=["json", "summary"], default="json",
|
|
430
|
+
help="Output format")
|
|
431
|
+
|
|
432
|
+
args = parser.parse_args()
|
|
433
|
+
|
|
434
|
+
if not os.path.isdir(args.project_path):
|
|
435
|
+
print(json.dumps({"error": f"Directory not found: {args.project_path}"}))
|
|
436
|
+
sys.exit(1)
|
|
437
|
+
|
|
438
|
+
result = run_full_scan(args.project_path, args.scan_type)
|
|
439
|
+
|
|
440
|
+
if args.output == "summary":
|
|
441
|
+
print(f"\n{'='*60}")
|
|
442
|
+
print(f"Security Scan: {result['project']}")
|
|
443
|
+
print(f"{'='*60}")
|
|
444
|
+
print(f"Status: {result['summary']['overall_status']}")
|
|
445
|
+
print(f"Total Findings: {result['summary']['total_findings']}")
|
|
446
|
+
print(f" Critical: {result['summary']['critical']}")
|
|
447
|
+
print(f" High: {result['summary']['high']}")
|
|
448
|
+
print(f"{'='*60}\n")
|
|
449
|
+
|
|
450
|
+
for scan_name, scan_result in result['scans'].items():
|
|
451
|
+
print(f"\n{scan_name.upper()}: {scan_result['status']}")
|
|
452
|
+
for finding in scan_result.get('findings', [])[:5]:
|
|
453
|
+
print(f" - {finding}")
|
|
454
|
+
else:
|
|
455
|
+
print(json.dumps(result, indent=2))
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
if __name__ == "__main__":
|
|
459
|
+
main()
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web-design-guidelines
|
|
3
|
+
description: 审阅 UI 代码是否符合 Web 界面指南。适用于“审阅我的 UI”“检查无障碍性”“审计设计”“审阅 UX”或“按最佳实践检查网站”等场景。
|
|
4
|
+
metadata:
|
|
5
|
+
author: vercel
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
argument-hint: <file-or-pattern>
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Web 界面指南
|
|
11
|
+
|
|
12
|
+
审阅文件是否符合 Web 界面指南。
|
|
13
|
+
|
|
14
|
+
## 工作方式
|
|
15
|
+
|
|
16
|
+
1. 从下方来源 URL 获取最新指南
|
|
17
|
+
2. 读取指定文件(或提示用户提供文件/匹配路径)
|
|
18
|
+
3. 按获取到的指南逐条检查
|
|
19
|
+
4. 使用精简的 `file:line` 格式输出发现
|
|
20
|
+
|
|
21
|
+
## 指南来源
|
|
22
|
+
|
|
23
|
+
每次审阅前都获取最新指南:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.md
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
使用 `WebFetch` 获取最新规则。获取内容包含完整规则及输出格式说明。
|
|
30
|
+
|
|
31
|
+
## 使用方式
|
|
32
|
+
|
|
33
|
+
当用户提供文件或路径参数时:
|
|
34
|
+
1. 从上述 URL 获取指南
|
|
35
|
+
2. 读取指定文件
|
|
36
|
+
3. 应用获取到的全部规则
|
|
37
|
+
4. 按指南指定格式输出发现
|
|
38
|
+
|
|
39
|
+
如果未指定文件,请先询问用户要审阅哪些文件。
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 相关技能
|
|
44
|
+
|
|
45
|
+
| 技能 | 适用场景 |
|
|
46
|
+
|-------|-------------|
|
|
47
|
+
| **[frontend-design](../frontend-design/SKILL.md)** | 编码前:学习设计原则(色彩、排版、UX 心理学) |
|
|
48
|
+
| **web-design-guidelines**(当前) | 编码后:审计无障碍、性能与最佳实践 |
|
|
49
|
+
|
|
50
|
+
## 设计工作流
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
1. DESIGN → 阅读 frontend-design 原则
|
|
54
|
+
2. CODE → 实现设计
|
|
55
|
+
3. AUDIT → 运行 web-design-guidelines 审阅 ← 当前所处阶段
|
|
56
|
+
4. FIX → 根据审阅发现进行修复
|
|
57
|
+
```
|