code-abyss 1.6.16 → 1.7.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/README.md +8 -6
- package/bin/install.js +59 -163
- package/bin/lib/ccline.js +82 -0
- package/bin/lib/utils.js +61 -0
- package/package.json +5 -2
- package/skills/SKILL.md +24 -16
- package/skills/domains/ai/SKILL.md +2 -2
- package/skills/domains/ai/prompt-and-eval.md +279 -0
- package/skills/domains/architecture/SKILL.md +2 -3
- package/skills/domains/architecture/security-arch.md +87 -0
- package/skills/domains/data-engineering/SKILL.md +188 -26
- package/skills/domains/development/SKILL.md +1 -4
- package/skills/domains/devops/SKILL.md +3 -5
- package/skills/domains/devops/performance.md +63 -0
- package/skills/domains/devops/testing.md +97 -0
- package/skills/domains/frontend-design/SKILL.md +12 -3
- package/skills/domains/frontend-design/claymorphism/SKILL.md +117 -0
- package/skills/domains/frontend-design/claymorphism/references/tokens.css +52 -0
- package/skills/domains/frontend-design/engineering.md +287 -0
- package/skills/domains/frontend-design/glassmorphism/SKILL.md +138 -0
- package/skills/domains/frontend-design/glassmorphism/references/tokens.css +32 -0
- package/skills/domains/frontend-design/liquid-glass/SKILL.md +135 -0
- package/skills/domains/frontend-design/liquid-glass/references/tokens.css +81 -0
- package/skills/domains/frontend-design/neubrutalism/SKILL.md +141 -0
- package/skills/domains/frontend-design/neubrutalism/references/tokens.css +44 -0
- package/skills/domains/infrastructure/SKILL.md +174 -34
- package/skills/domains/mobile/SKILL.md +211 -21
- package/skills/domains/orchestration/SKILL.md +1 -0
- package/skills/domains/security/SKILL.md +4 -6
- package/skills/domains/security/blue-team.md +57 -0
- package/skills/domains/security/red-team.md +54 -0
- package/skills/domains/security/threat-intel.md +50 -0
- package/skills/orchestration/multi-agent/SKILL.md +195 -46
- package/skills/run_skill.js +139 -0
- package/skills/tools/gen-docs/SKILL.md +6 -4
- package/skills/tools/gen-docs/scripts/doc_generator.js +363 -0
- package/skills/tools/lib/shared.js +98 -0
- package/skills/tools/verify-change/SKILL.md +8 -6
- package/skills/tools/verify-change/scripts/change_analyzer.js +289 -0
- package/skills/tools/verify-module/SKILL.md +6 -4
- package/skills/tools/verify-module/scripts/module_scanner.js +171 -0
- package/skills/tools/verify-quality/SKILL.md +5 -3
- package/skills/tools/verify-quality/scripts/quality_checker.js +337 -0
- package/skills/tools/verify-security/SKILL.md +7 -5
- package/skills/tools/verify-security/scripts/security_scanner.js +283 -0
- package/skills/__pycache__/run_skill.cpython-312.pyc +0 -0
- package/skills/domains/COVERAGE_PLAN.md +0 -232
- package/skills/domains/ai/model-evaluation.md +0 -790
- package/skills/domains/ai/prompt-engineering.md +0 -703
- package/skills/domains/architecture/compliance.md +0 -299
- package/skills/domains/architecture/data-security.md +0 -184
- package/skills/domains/data-engineering/data-pipeline.md +0 -762
- package/skills/domains/data-engineering/data-quality.md +0 -894
- package/skills/domains/data-engineering/stream-processing.md +0 -791
- package/skills/domains/development/dart.md +0 -963
- package/skills/domains/development/kotlin.md +0 -834
- package/skills/domains/development/php.md +0 -659
- package/skills/domains/development/swift.md +0 -755
- package/skills/domains/devops/e2e-testing.md +0 -914
- package/skills/domains/devops/performance-testing.md +0 -734
- package/skills/domains/devops/testing-strategy.md +0 -667
- package/skills/domains/frontend-design/build-tools.md +0 -743
- package/skills/domains/frontend-design/performance.md +0 -734
- package/skills/domains/frontend-design/testing.md +0 -699
- package/skills/domains/infrastructure/gitops.md +0 -735
- package/skills/domains/infrastructure/iac.md +0 -855
- package/skills/domains/infrastructure/kubernetes.md +0 -1018
- package/skills/domains/mobile/android-dev.md +0 -979
- package/skills/domains/mobile/cross-platform.md +0 -795
- package/skills/domains/mobile/ios-dev.md +0 -931
- package/skills/domains/security/secrets-management.md +0 -834
- package/skills/domains/security/supply-chain.md +0 -931
- package/skills/domains/security/threat-modeling.md +0 -828
- package/skills/run_skill.py +0 -153
- package/skills/tests/README.md +0 -225
- package/skills/tests/SUMMARY.md +0 -362
- package/skills/tests/__init__.py +0 -3
- package/skills/tests/__pycache__/test_change_analyzer.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_doc_generator.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_module_scanner.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_quality_checker.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_security_scanner.cpython-312.pyc +0 -0
- package/skills/tests/test_change_analyzer.py +0 -558
- package/skills/tests/test_doc_generator.py +0 -538
- package/skills/tests/test_module_scanner.py +0 -376
- package/skills/tests/test_quality_checker.py +0 -516
- package/skills/tests/test_security_scanner.py +0 -426
- package/skills/tools/gen-docs/scripts/__pycache__/doc_generator.cpython-312.pyc +0 -0
- package/skills/tools/gen-docs/scripts/doc_generator.py +0 -520
- package/skills/tools/verify-change/scripts/__pycache__/change_analyzer.cpython-312.pyc +0 -0
- package/skills/tools/verify-change/scripts/change_analyzer.py +0 -529
- package/skills/tools/verify-module/scripts/__pycache__/module_scanner.cpython-312.pyc +0 -0
- package/skills/tools/verify-module/scripts/module_scanner.py +0 -321
- package/skills/tools/verify-quality/scripts/__pycache__/quality_checker.cpython-312.pyc +0 -0
- package/skills/tools/verify-quality/scripts/quality_checker.py +0 -481
- package/skills/tools/verify-security/scripts/__pycache__/security_scanner.cpython-312.pyc +0 -0
- package/skills/tools/verify-security/scripts/security_scanner.py +0 -374
|
@@ -1,321 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
模块结构扫描器
|
|
4
|
-
检测模块完整性:目录结构、必需文档、代码组织
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import os
|
|
8
|
-
import sys
|
|
9
|
-
import json
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
from dataclasses import dataclass, field
|
|
12
|
-
from typing import List, Dict, Optional
|
|
13
|
-
from enum import Enum
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class Severity(Enum):
|
|
17
|
-
ERROR = "error"
|
|
18
|
-
WARNING = "warning"
|
|
19
|
-
INFO = "info"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@dataclass
|
|
23
|
-
class Issue:
|
|
24
|
-
severity: Severity
|
|
25
|
-
message: str
|
|
26
|
-
path: Optional[str] = None
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@dataclass
|
|
30
|
-
class ScanResult:
|
|
31
|
-
module_path: str
|
|
32
|
-
issues: List[Issue] = field(default_factory=list)
|
|
33
|
-
structure: Dict = field(default_factory=dict)
|
|
34
|
-
|
|
35
|
-
@property
|
|
36
|
-
def passed(self) -> bool:
|
|
37
|
-
return not any(i.severity == Severity.ERROR for i in self.issues)
|
|
38
|
-
|
|
39
|
-
@property
|
|
40
|
-
def error_count(self) -> int:
|
|
41
|
-
return sum(1 for i in self.issues if i.severity == Severity.ERROR)
|
|
42
|
-
|
|
43
|
-
@property
|
|
44
|
-
def warning_count(self) -> int:
|
|
45
|
-
return sum(1 for i in self.issues if i.severity == Severity.WARNING)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
REQUIRED_FILES = {
|
|
49
|
-
"README.md": "模块说明文档",
|
|
50
|
-
"DESIGN.md": "设计决策文档",
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
RECOMMENDED_DIRS = {
|
|
54
|
-
"src": "源代码目录",
|
|
55
|
-
"tests": "测试目录",
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
ALTERNATIVE_SRC_DIRS = ["src", "lib", "pkg", "internal", "cmd", "app"]
|
|
59
|
-
ALTERNATIVE_TEST_DIRS = ["tests", "test", "__tests__", "spec"]
|
|
60
|
-
ROOT_SCRIPT_FILES = {
|
|
61
|
-
"install.sh",
|
|
62
|
-
"uninstall.sh",
|
|
63
|
-
"install.ps1",
|
|
64
|
-
"uninstall.ps1",
|
|
65
|
-
"Dockerfile",
|
|
66
|
-
"Makefile",
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def scan_module(path: str) -> ScanResult:
|
|
71
|
-
"""扫描模块完整性"""
|
|
72
|
-
module_path = Path(path).resolve()
|
|
73
|
-
result = ScanResult(module_path=str(module_path))
|
|
74
|
-
|
|
75
|
-
if not module_path.exists():
|
|
76
|
-
result.issues.append(Issue(
|
|
77
|
-
severity=Severity.ERROR,
|
|
78
|
-
message=f"路径不存在: {module_path}"
|
|
79
|
-
))
|
|
80
|
-
return result
|
|
81
|
-
|
|
82
|
-
if not module_path.is_dir():
|
|
83
|
-
result.issues.append(Issue(
|
|
84
|
-
severity=Severity.ERROR,
|
|
85
|
-
message=f"不是目录: {module_path}"
|
|
86
|
-
))
|
|
87
|
-
return result
|
|
88
|
-
|
|
89
|
-
# 扫描目录结构
|
|
90
|
-
result.structure = scan_structure(module_path)
|
|
91
|
-
|
|
92
|
-
# 检查必需文档
|
|
93
|
-
check_required_files(module_path, result)
|
|
94
|
-
|
|
95
|
-
# 检查源码目录
|
|
96
|
-
check_source_dirs(module_path, result)
|
|
97
|
-
|
|
98
|
-
# 检查测试目录
|
|
99
|
-
check_test_dirs(module_path, result)
|
|
100
|
-
|
|
101
|
-
# 检查文档质量
|
|
102
|
-
check_doc_quality(module_path, result)
|
|
103
|
-
|
|
104
|
-
return result
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def scan_structure(path: Path, depth: int = 3) -> Dict:
|
|
108
|
-
"""递归扫描目录结构"""
|
|
109
|
-
structure = {"name": path.name, "type": "dir", "children": []}
|
|
110
|
-
|
|
111
|
-
if depth <= 0:
|
|
112
|
-
return structure
|
|
113
|
-
|
|
114
|
-
try:
|
|
115
|
-
for item in sorted(path.iterdir()):
|
|
116
|
-
if item.name.startswith('.'):
|
|
117
|
-
continue
|
|
118
|
-
if item.is_file():
|
|
119
|
-
structure["children"].append({
|
|
120
|
-
"name": item.name,
|
|
121
|
-
"type": "file",
|
|
122
|
-
"size": item.stat().st_size
|
|
123
|
-
})
|
|
124
|
-
elif item.is_dir():
|
|
125
|
-
structure["children"].append(
|
|
126
|
-
scan_structure(item, depth - 1)
|
|
127
|
-
)
|
|
128
|
-
except PermissionError:
|
|
129
|
-
pass
|
|
130
|
-
|
|
131
|
-
return structure
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
def check_required_files(path: Path, result: ScanResult):
|
|
135
|
-
"""检查必需文件"""
|
|
136
|
-
for filename, desc in REQUIRED_FILES.items():
|
|
137
|
-
filepath = path / filename
|
|
138
|
-
if not filepath.exists():
|
|
139
|
-
result.issues.append(Issue(
|
|
140
|
-
severity=Severity.ERROR,
|
|
141
|
-
message=f"缺少必需文档: {filename} ({desc})",
|
|
142
|
-
path=str(filepath)
|
|
143
|
-
))
|
|
144
|
-
elif filepath.stat().st_size < 50:
|
|
145
|
-
result.issues.append(Issue(
|
|
146
|
-
severity=Severity.WARNING,
|
|
147
|
-
message=f"文档内容过少: {filename} (< 50 bytes)",
|
|
148
|
-
path=str(filepath)
|
|
149
|
-
))
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
def check_source_dirs(path: Path, result: ScanResult):
|
|
153
|
-
"""检查源码目录"""
|
|
154
|
-
found = False
|
|
155
|
-
for dirname in ALTERNATIVE_SRC_DIRS:
|
|
156
|
-
if (path / dirname).is_dir():
|
|
157
|
-
found = True
|
|
158
|
-
break
|
|
159
|
-
|
|
160
|
-
# 检查是否有代码文件在根目录
|
|
161
|
-
code_extensions = {'.py', '.go', '.rs', '.ts', '.js', '.java', '.sh', '.ps1'}
|
|
162
|
-
root_code_files = [f for f in path.iterdir()
|
|
163
|
-
if f.is_file() and f.suffix in code_extensions]
|
|
164
|
-
root_script_files = [f for f in path.iterdir() if f.is_file() and f.name in ROOT_SCRIPT_FILES]
|
|
165
|
-
|
|
166
|
-
if root_code_files or root_script_files:
|
|
167
|
-
found = True
|
|
168
|
-
if len(root_code_files) > 5:
|
|
169
|
-
result.issues.append(Issue(
|
|
170
|
-
severity=Severity.WARNING,
|
|
171
|
-
message=f"根目录代码文件过多 ({len(root_code_files)}个),建议整理到 src/ 目录"
|
|
172
|
-
))
|
|
173
|
-
|
|
174
|
-
if not found:
|
|
175
|
-
result.issues.append(Issue(
|
|
176
|
-
severity=Severity.WARNING,
|
|
177
|
-
message="未找到源码目录或代码文件"
|
|
178
|
-
))
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
def check_test_dirs(path: Path, result: ScanResult):
|
|
182
|
-
"""检查测试目录"""
|
|
183
|
-
found = False
|
|
184
|
-
for dirname in ALTERNATIVE_TEST_DIRS:
|
|
185
|
-
if (path / dirname).is_dir():
|
|
186
|
-
found = True
|
|
187
|
-
break
|
|
188
|
-
|
|
189
|
-
# 检查是否有测试文件
|
|
190
|
-
test_patterns = ['test_', '_test.', '.test.', 'spec_', '_spec.']
|
|
191
|
-
for f in path.rglob('*'):
|
|
192
|
-
if f.is_file() and any(p in f.name for p in test_patterns):
|
|
193
|
-
found = True
|
|
194
|
-
break
|
|
195
|
-
|
|
196
|
-
if not found:
|
|
197
|
-
result.issues.append(Issue(
|
|
198
|
-
severity=Severity.WARNING,
|
|
199
|
-
message="未找到测试目录或测试文件"
|
|
200
|
-
))
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
def check_doc_quality(path: Path, result: ScanResult):
|
|
204
|
-
"""检查文档质量"""
|
|
205
|
-
readme = path / "README.md"
|
|
206
|
-
design = path / "DESIGN.md"
|
|
207
|
-
|
|
208
|
-
if readme.exists():
|
|
209
|
-
content = readme.read_text(encoding='utf-8', errors='ignore')
|
|
210
|
-
|
|
211
|
-
# 检查必要章节
|
|
212
|
-
required_sections = ['#'] # 至少有标题
|
|
213
|
-
if not any(s in content for s in required_sections):
|
|
214
|
-
result.issues.append(Issue(
|
|
215
|
-
severity=Severity.WARNING,
|
|
216
|
-
message="README.md 缺少标题",
|
|
217
|
-
path=str(readme)
|
|
218
|
-
))
|
|
219
|
-
|
|
220
|
-
# 检查使用说明
|
|
221
|
-
usage_keywords = ['usage', 'install', '使用', '安装', 'example', '示例']
|
|
222
|
-
if not any(k in content.lower() for k in usage_keywords):
|
|
223
|
-
result.issues.append(Issue(
|
|
224
|
-
severity=Severity.INFO,
|
|
225
|
-
message="README.md 建议添加使用说明或示例",
|
|
226
|
-
path=str(readme)
|
|
227
|
-
))
|
|
228
|
-
|
|
229
|
-
if design.exists():
|
|
230
|
-
content = design.read_text(encoding='utf-8', errors='ignore')
|
|
231
|
-
|
|
232
|
-
# 检查设计决策记录
|
|
233
|
-
decision_keywords = ['决策', 'decision', '选择', 'choice', '权衡', 'trade']
|
|
234
|
-
if not any(k in content.lower() for k in decision_keywords):
|
|
235
|
-
result.issues.append(Issue(
|
|
236
|
-
severity=Severity.INFO,
|
|
237
|
-
message="DESIGN.md 建议记录设计决策和权衡",
|
|
238
|
-
path=str(design)
|
|
239
|
-
))
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
def format_report(result: ScanResult, verbose: bool = False) -> str:
|
|
243
|
-
"""格式化扫描报告"""
|
|
244
|
-
lines = []
|
|
245
|
-
lines.append("=" * 60)
|
|
246
|
-
lines.append("模块完整性扫描报告")
|
|
247
|
-
lines.append("=" * 60)
|
|
248
|
-
lines.append(f"\n模块路径: {result.module_path}")
|
|
249
|
-
lines.append(f"扫描结果: {'✓ 通过' if result.passed else '✗ 未通过'}")
|
|
250
|
-
lines.append(f"错误: {result.error_count} | 警告: {result.warning_count}")
|
|
251
|
-
|
|
252
|
-
if result.issues:
|
|
253
|
-
lines.append("\n" + "-" * 40)
|
|
254
|
-
lines.append("问题列表:")
|
|
255
|
-
lines.append("-" * 40)
|
|
256
|
-
|
|
257
|
-
for issue in result.issues:
|
|
258
|
-
icon = {"error": "✗", "warning": "⚠", "info": "ℹ"}[issue.severity.value]
|
|
259
|
-
lines.append(f" {icon} [{issue.severity.value.upper()}] {issue.message}")
|
|
260
|
-
if issue.path and verbose:
|
|
261
|
-
lines.append(f" 路径: {issue.path}")
|
|
262
|
-
|
|
263
|
-
if verbose and result.structure:
|
|
264
|
-
lines.append("\n" + "-" * 40)
|
|
265
|
-
lines.append("目录结构:")
|
|
266
|
-
lines.append("-" * 40)
|
|
267
|
-
lines.append(format_structure(result.structure))
|
|
268
|
-
|
|
269
|
-
lines.append("\n" + "=" * 60)
|
|
270
|
-
return "\n".join(lines)
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
def format_structure(structure: Dict, indent: int = 0) -> str:
|
|
274
|
-
"""格式化目录结构"""
|
|
275
|
-
lines = []
|
|
276
|
-
prefix = " " * indent
|
|
277
|
-
|
|
278
|
-
if structure["type"] == "dir":
|
|
279
|
-
lines.append(f"{prefix}📁 {structure['name']}/")
|
|
280
|
-
for child in structure.get("children", []):
|
|
281
|
-
lines.append(format_structure(child, indent + 1))
|
|
282
|
-
else:
|
|
283
|
-
size = structure.get("size", 0)
|
|
284
|
-
size_str = f"({size} B)" if size < 1024 else f"({size // 1024} KB)"
|
|
285
|
-
lines.append(f"{prefix}📄 {structure['name']} {size_str}")
|
|
286
|
-
|
|
287
|
-
return "\n".join(lines)
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
def main():
|
|
291
|
-
import argparse
|
|
292
|
-
|
|
293
|
-
parser = argparse.ArgumentParser(description="模块完整性扫描器")
|
|
294
|
-
parser.add_argument("path", nargs="?", default=".", help="模块路径")
|
|
295
|
-
parser.add_argument("-v", "--verbose", action="store_true", help="详细输出")
|
|
296
|
-
parser.add_argument("--json", action="store_true", help="JSON 格式输出")
|
|
297
|
-
|
|
298
|
-
args = parser.parse_args()
|
|
299
|
-
|
|
300
|
-
result = scan_module(args.path)
|
|
301
|
-
|
|
302
|
-
if args.json:
|
|
303
|
-
output = {
|
|
304
|
-
"module_path": result.module_path,
|
|
305
|
-
"passed": result.passed,
|
|
306
|
-
"error_count": result.error_count,
|
|
307
|
-
"warning_count": result.warning_count,
|
|
308
|
-
"issues": [
|
|
309
|
-
{"severity": i.severity.value, "message": i.message, "path": i.path}
|
|
310
|
-
for i in result.issues
|
|
311
|
-
]
|
|
312
|
-
}
|
|
313
|
-
print(json.dumps(output, ensure_ascii=False, indent=2))
|
|
314
|
-
else:
|
|
315
|
-
print(format_report(result, args.verbose))
|
|
316
|
-
|
|
317
|
-
sys.exit(0 if result.passed else 1)
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
if __name__ == "__main__":
|
|
321
|
-
main()
|