code-abyss 1.6.16 → 1.7.0

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.
Files changed (92) hide show
  1. package/package.json +2 -2
  2. package/skills/SKILL.md +24 -16
  3. package/skills/domains/ai/SKILL.md +2 -2
  4. package/skills/domains/ai/prompt-and-eval.md +279 -0
  5. package/skills/domains/architecture/SKILL.md +2 -3
  6. package/skills/domains/architecture/security-arch.md +87 -0
  7. package/skills/domains/data-engineering/SKILL.md +188 -26
  8. package/skills/domains/development/SKILL.md +1 -4
  9. package/skills/domains/devops/SKILL.md +3 -5
  10. package/skills/domains/devops/performance.md +63 -0
  11. package/skills/domains/devops/testing.md +97 -0
  12. package/skills/domains/frontend-design/SKILL.md +12 -3
  13. package/skills/domains/frontend-design/claymorphism/SKILL.md +117 -0
  14. package/skills/domains/frontend-design/claymorphism/references/tokens.css +52 -0
  15. package/skills/domains/frontend-design/engineering.md +287 -0
  16. package/skills/domains/frontend-design/glassmorphism/SKILL.md +138 -0
  17. package/skills/domains/frontend-design/glassmorphism/references/tokens.css +32 -0
  18. package/skills/domains/frontend-design/liquid-glass/SKILL.md +135 -0
  19. package/skills/domains/frontend-design/liquid-glass/references/tokens.css +81 -0
  20. package/skills/domains/frontend-design/neubrutalism/SKILL.md +141 -0
  21. package/skills/domains/frontend-design/neubrutalism/references/tokens.css +44 -0
  22. package/skills/domains/infrastructure/SKILL.md +174 -34
  23. package/skills/domains/mobile/SKILL.md +211 -21
  24. package/skills/domains/orchestration/SKILL.md +1 -0
  25. package/skills/domains/security/SKILL.md +4 -6
  26. package/skills/domains/security/blue-team.md +57 -0
  27. package/skills/domains/security/red-team.md +54 -0
  28. package/skills/domains/security/threat-intel.md +50 -0
  29. package/skills/orchestration/multi-agent/SKILL.md +195 -46
  30. package/skills/run_skill.js +134 -0
  31. package/skills/tools/gen-docs/SKILL.md +6 -4
  32. package/skills/tools/gen-docs/scripts/doc_generator.js +349 -0
  33. package/skills/tools/verify-change/SKILL.md +8 -6
  34. package/skills/tools/verify-change/scripts/change_analyzer.js +270 -0
  35. package/skills/tools/verify-module/SKILL.md +6 -4
  36. package/skills/tools/verify-module/scripts/module_scanner.js +145 -0
  37. package/skills/tools/verify-quality/SKILL.md +5 -3
  38. package/skills/tools/verify-quality/scripts/quality_checker.js +276 -0
  39. package/skills/tools/verify-security/SKILL.md +7 -5
  40. package/skills/tools/verify-security/scripts/security_scanner.js +133 -0
  41. package/skills/__pycache__/run_skill.cpython-312.pyc +0 -0
  42. package/skills/domains/COVERAGE_PLAN.md +0 -232
  43. package/skills/domains/ai/model-evaluation.md +0 -790
  44. package/skills/domains/ai/prompt-engineering.md +0 -703
  45. package/skills/domains/architecture/compliance.md +0 -299
  46. package/skills/domains/architecture/data-security.md +0 -184
  47. package/skills/domains/data-engineering/data-pipeline.md +0 -762
  48. package/skills/domains/data-engineering/data-quality.md +0 -894
  49. package/skills/domains/data-engineering/stream-processing.md +0 -791
  50. package/skills/domains/development/dart.md +0 -963
  51. package/skills/domains/development/kotlin.md +0 -834
  52. package/skills/domains/development/php.md +0 -659
  53. package/skills/domains/development/swift.md +0 -755
  54. package/skills/domains/devops/e2e-testing.md +0 -914
  55. package/skills/domains/devops/performance-testing.md +0 -734
  56. package/skills/domains/devops/testing-strategy.md +0 -667
  57. package/skills/domains/frontend-design/build-tools.md +0 -743
  58. package/skills/domains/frontend-design/performance.md +0 -734
  59. package/skills/domains/frontend-design/testing.md +0 -699
  60. package/skills/domains/infrastructure/gitops.md +0 -735
  61. package/skills/domains/infrastructure/iac.md +0 -855
  62. package/skills/domains/infrastructure/kubernetes.md +0 -1018
  63. package/skills/domains/mobile/android-dev.md +0 -979
  64. package/skills/domains/mobile/cross-platform.md +0 -795
  65. package/skills/domains/mobile/ios-dev.md +0 -931
  66. package/skills/domains/security/secrets-management.md +0 -834
  67. package/skills/domains/security/supply-chain.md +0 -931
  68. package/skills/domains/security/threat-modeling.md +0 -828
  69. package/skills/run_skill.py +0 -153
  70. package/skills/tests/README.md +0 -225
  71. package/skills/tests/SUMMARY.md +0 -362
  72. package/skills/tests/__init__.py +0 -3
  73. package/skills/tests/__pycache__/test_change_analyzer.cpython-312.pyc +0 -0
  74. package/skills/tests/__pycache__/test_doc_generator.cpython-312.pyc +0 -0
  75. package/skills/tests/__pycache__/test_module_scanner.cpython-312.pyc +0 -0
  76. package/skills/tests/__pycache__/test_quality_checker.cpython-312.pyc +0 -0
  77. package/skills/tests/__pycache__/test_security_scanner.cpython-312.pyc +0 -0
  78. package/skills/tests/test_change_analyzer.py +0 -558
  79. package/skills/tests/test_doc_generator.py +0 -538
  80. package/skills/tests/test_module_scanner.py +0 -376
  81. package/skills/tests/test_quality_checker.py +0 -516
  82. package/skills/tests/test_security_scanner.py +0 -426
  83. package/skills/tools/gen-docs/scripts/__pycache__/doc_generator.cpython-312.pyc +0 -0
  84. package/skills/tools/gen-docs/scripts/doc_generator.py +0 -520
  85. package/skills/tools/verify-change/scripts/__pycache__/change_analyzer.cpython-312.pyc +0 -0
  86. package/skills/tools/verify-change/scripts/change_analyzer.py +0 -529
  87. package/skills/tools/verify-module/scripts/__pycache__/module_scanner.cpython-312.pyc +0 -0
  88. package/skills/tools/verify-module/scripts/module_scanner.py +0 -321
  89. package/skills/tools/verify-quality/scripts/__pycache__/quality_checker.cpython-312.pyc +0 -0
  90. package/skills/tools/verify-quality/scripts/quality_checker.py +0 -481
  91. package/skills/tools/verify-security/scripts/__pycache__/security_scanner.cpython-312.pyc +0 -0
  92. package/skills/tools/verify-security/scripts/security_scanner.py +0 -374
@@ -1,529 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- 变更分析器
4
- 分析代码变更,检测文档同步状态,评估变更影响
5
- """
6
-
7
- import os
8
- import re
9
- import sys
10
- import json
11
- import subprocess
12
- from pathlib import Path
13
- from dataclasses import dataclass, field
14
- from typing import List, Dict, Optional, Set
15
- from enum import Enum
16
-
17
-
18
- class ChangeType(Enum):
19
- ADDED = "added"
20
- MODIFIED = "modified"
21
- DELETED = "deleted"
22
- RENAMED = "renamed"
23
-
24
-
25
- class Severity(Enum):
26
- ERROR = "error"
27
- WARNING = "warning"
28
- INFO = "info"
29
-
30
-
31
- @dataclass
32
- class FileChange:
33
- path: str
34
- change_type: ChangeType
35
- additions: int = 0
36
- deletions: int = 0
37
- is_code: bool = False
38
- is_doc: bool = False
39
- is_test: bool = False
40
- is_config: bool = False
41
-
42
-
43
- @dataclass
44
- class Issue:
45
- severity: Severity
46
- message: str
47
- related_files: List[str] = field(default_factory=list)
48
-
49
-
50
- @dataclass
51
- class AnalysisResult:
52
- changes: List[FileChange] = field(default_factory=list)
53
- issues: List[Issue] = field(default_factory=list)
54
- affected_modules: Set[str] = field(default_factory=set)
55
- doc_sync_status: Dict[str, bool] = field(default_factory=dict)
56
-
57
- @property
58
- def passed(self) -> bool:
59
- return not any(i.severity == Severity.ERROR for i in self.issues)
60
-
61
- @property
62
- def total_additions(self) -> int:
63
- return sum(c.additions for c in self.changes)
64
-
65
- @property
66
- def total_deletions(self) -> int:
67
- return sum(c.deletions for c in self.changes)
68
-
69
-
70
- CODE_EXTENSIONS = {'.py', '.go', '.rs', '.ts', '.js', '.jsx', '.tsx', '.java', '.c', '.cpp', '.h', '.hpp'}
71
- DOC_EXTENSIONS = {'.md', '.rst', '.txt', '.adoc'}
72
- TEST_PATTERNS = ['test_', '_test.', '.test.', 'spec_', '_spec.', '/tests/', '/test/', '/__tests__/']
73
- CONFIG_FILES = {'package.json', 'pyproject.toml', 'go.mod', 'Cargo.toml', 'pom.xml', 'Makefile', 'Dockerfile'}
74
-
75
-
76
- def classify_file(path: str) -> FileChange:
77
- """分类文件类型"""
78
- p = Path(path)
79
- suffix = p.suffix.lower()
80
- name = p.name.lower()
81
-
82
- change = FileChange(path=path, change_type=ChangeType.MODIFIED)
83
- change.is_code = suffix in CODE_EXTENSIONS
84
- change.is_doc = suffix in DOC_EXTENSIONS
85
- change.is_test = any(pattern in path.lower() for pattern in TEST_PATTERNS)
86
- change.is_config = name in CONFIG_FILES or suffix in {'.yaml', '.yml', '.json', '.toml', '.ini'}
87
-
88
- return change
89
-
90
-
91
- def normalize_path(path: str) -> str:
92
- """规范化相对路径"""
93
- normalized = path.strip()
94
-
95
- if normalized.startswith('"') and normalized.endswith('"') and len(normalized) >= 2:
96
- normalized = normalized[1:-1]
97
- normalized = normalized.replace('\\"', '"').replace('\\\\', '\\')
98
-
99
- if normalized.startswith("./"):
100
- normalized = normalized[2:]
101
-
102
- return normalized
103
-
104
-
105
- def parse_name_status_line(line: str) -> Optional[FileChange]:
106
- """解析 git diff --name-status 输出行"""
107
- parts = line.split('\t')
108
- if len(parts) < 2:
109
- return None
110
-
111
- status_token = parts[0]
112
- status = status_token[0]
113
- path = normalize_path(parts[-1])
114
-
115
- if not path:
116
- return None
117
-
118
- change = classify_file(path)
119
-
120
- if status == 'A':
121
- change.change_type = ChangeType.ADDED
122
- elif status == 'M':
123
- change.change_type = ChangeType.MODIFIED
124
- elif status == 'D':
125
- change.change_type = ChangeType.DELETED
126
- elif status == 'R':
127
- change.change_type = ChangeType.RENAMED
128
-
129
- return change
130
-
131
-
132
- def parse_porcelain_line(line: str) -> Optional[FileChange]:
133
- """解析 git status --porcelain 输出行"""
134
- if len(line) < 3:
135
- return None
136
-
137
- status = line[:2]
138
- raw_path = line[3:] if len(line) > 3 else ""
139
-
140
- if not raw_path:
141
- return None
142
-
143
- if " -> " in raw_path:
144
- raw_path = raw_path.split(" -> ", 1)[1]
145
-
146
- path = normalize_path(raw_path)
147
- if not path:
148
- return None
149
-
150
- change = classify_file(path)
151
-
152
- if '?' in status or 'A' in status:
153
- change.change_type = ChangeType.ADDED
154
- elif 'R' in status:
155
- change.change_type = ChangeType.RENAMED
156
- elif 'M' in status:
157
- change.change_type = ChangeType.MODIFIED
158
- elif 'D' in status:
159
- change.change_type = ChangeType.DELETED
160
-
161
- return change
162
-
163
-
164
- def is_path_in_module(file_path: str, module: str) -> bool:
165
- """判断文件是否属于模块范围"""
166
- normalized_path = normalize_path(file_path)
167
-
168
- if module == ".":
169
- return len(Path(normalized_path).parts) == 1
170
-
171
- module_prefix = f"{module}/"
172
- return normalized_path == module or normalized_path.startswith(module_prefix)
173
-
174
-
175
- def get_git_changes(base: str = "HEAD~1", target: str = "HEAD") -> List[FileChange]:
176
- """获取 Git 变更"""
177
- changes = []
178
-
179
- try:
180
- # 获取变更文件列表
181
- result = subprocess.run(
182
- ["git", "diff", "--name-status", base, target],
183
- capture_output=True, text=True, check=True
184
- )
185
-
186
- for line in result.stdout.splitlines():
187
- if not line:
188
- continue
189
-
190
- change = parse_name_status_line(line)
191
- if change:
192
- changes.append(change)
193
-
194
- # 获取行数统计
195
- stat_result = subprocess.run(
196
- ["git", "diff", "--numstat", base, target],
197
- capture_output=True, text=True, check=True
198
- )
199
-
200
- stat_map = {}
201
- for line in stat_result.stdout.splitlines():
202
- if not line:
203
- continue
204
- parts = line.split('\t')
205
- if len(parts) >= 3:
206
- adds = int(parts[0]) if parts[0] != '-' else 0
207
- dels = int(parts[1]) if parts[1] != '-' else 0
208
- stat_map[normalize_path(parts[2])] = (adds, dels)
209
-
210
- for change in changes:
211
- if change.path in stat_map:
212
- change.additions, change.deletions = stat_map[change.path]
213
-
214
- except subprocess.CalledProcessError:
215
- pass
216
- except FileNotFoundError:
217
- pass
218
-
219
- return changes
220
-
221
-
222
- def get_staged_changes() -> List[FileChange]:
223
- """获取暂存区变更"""
224
- changes = []
225
-
226
- try:
227
- result = subprocess.run(
228
- ["git", "diff", "--cached", "--name-status"],
229
- capture_output=True, text=True, check=True
230
- )
231
-
232
- for line in result.stdout.splitlines():
233
- if not line:
234
- continue
235
-
236
- change = parse_name_status_line(line)
237
- if change:
238
- changes.append(change)
239
-
240
- except (subprocess.CalledProcessError, FileNotFoundError):
241
- pass
242
-
243
- return changes
244
-
245
-
246
- def get_working_changes() -> List[FileChange]:
247
- """获取工作区变更"""
248
- changes = []
249
-
250
- try:
251
- result = subprocess.run(
252
- ["git", "status", "--porcelain"],
253
- capture_output=True, text=True, check=True
254
- )
255
-
256
- for line in result.stdout.splitlines():
257
- if not line:
258
- continue
259
-
260
- change = parse_porcelain_line(line)
261
- if change:
262
- changes.append(change)
263
-
264
- except (subprocess.CalledProcessError, FileNotFoundError):
265
- pass
266
-
267
- return changes
268
-
269
-
270
- def identify_affected_modules(changes: List[FileChange]) -> Set[str]:
271
- """识别受影响的模块"""
272
- modules = set()
273
-
274
- for change in changes:
275
- normalized_path = normalize_path(change.path)
276
- parts = Path(normalized_path).parts
277
-
278
- if len(parts) == 1:
279
- modules.add(".")
280
- continue
281
-
282
- # 查找模块边界(包含 README.md 或 DESIGN.md 的目录)
283
- for i in range(len(parts)):
284
- potential_module = Path(*parts[:i+1])
285
- if (potential_module / "README.md").exists() or (potential_module / "DESIGN.md").exists():
286
- modules.add(str(potential_module))
287
- break
288
- else:
289
- # 使用顶层目录作为模块
290
- if len(parts) > 1:
291
- modules.add(parts[0])
292
-
293
- return modules
294
-
295
-
296
- def check_doc_sync(changes: List[FileChange], modules: Set[str]) -> tuple[Dict[str, bool], List[Issue]]:
297
- """检查文档同步状态"""
298
- doc_status = {}
299
- issues = []
300
-
301
- code_changes = [c for c in changes if c.is_code and c.change_type != ChangeType.DELETED]
302
- doc_changes = {normalize_path(c.path) for c in changes if c.is_doc}
303
-
304
- # 检查每个模块
305
- for module in modules:
306
- module_path = Path(module)
307
- readme = normalize_path(str(module_path / "README.md"))
308
- design = normalize_path(str(module_path / "DESIGN.md"))
309
-
310
- # 检查模块内是否有代码变更
311
- module_code_changes = [c for c in code_changes if is_path_in_module(c.path, module)]
312
-
313
- if module_code_changes:
314
- # 检查是否有对应的文档更新
315
- readme_updated = readme in doc_changes
316
- design_updated = design in doc_changes
317
-
318
- # 计算变更规模
319
- total_changes = sum(c.additions + c.deletions for c in module_code_changes)
320
-
321
- if total_changes > 50 and not design_updated:
322
- issues.append(Issue(
323
- severity=Severity.WARNING,
324
- message=f"模块 {module} 有较大代码变更 ({total_changes} 行),但 DESIGN.md 未更新",
325
- related_files=[c.path for c in module_code_changes]
326
- ))
327
- doc_status[f"{module}/DESIGN.md"] = False
328
- else:
329
- doc_status[f"{module}/DESIGN.md"] = True
330
-
331
- # 新增文件检查
332
- new_files = [c for c in module_code_changes if c.change_type == ChangeType.ADDED]
333
- if new_files and not readme_updated:
334
- issues.append(Issue(
335
- severity=Severity.INFO,
336
- message=f"模块 {module} 新增了文件,建议更新 README.md",
337
- related_files=[c.path for c in new_files]
338
- ))
339
-
340
- return doc_status, issues
341
-
342
-
343
- def analyze_impact(changes: List[FileChange]) -> List[Issue]:
344
- """分析变更影响"""
345
- issues = []
346
-
347
- # 检查是否只改代码不改测试
348
- code_changes = [c for c in changes if c.is_code and not c.is_test]
349
- test_changes = [c for c in changes if c.is_test]
350
-
351
- if code_changes and not test_changes:
352
- total_code_changes = sum(c.additions + c.deletions for c in code_changes)
353
- if total_code_changes > 30:
354
- issues.append(Issue(
355
- severity=Severity.WARNING,
356
- message=f"代码变更 {total_code_changes} 行,但没有对应的测试更新",
357
- related_files=[c.path for c in code_changes]
358
- ))
359
-
360
- # 检查配置文件变更
361
- config_changes = [c for c in changes if c.is_config]
362
- if config_changes:
363
- issues.append(Issue(
364
- severity=Severity.INFO,
365
- message="配置文件有变更,请确认是否需要更新文档",
366
- related_files=[c.path for c in config_changes]
367
- ))
368
-
369
- # 检查删除操作
370
- deleted = [c for c in changes if c.change_type == ChangeType.DELETED]
371
- if deleted:
372
- issues.append(Issue(
373
- severity=Severity.INFO,
374
- message=f"删除了 {len(deleted)} 个文件,请确认相关引用已清理",
375
- related_files=[c.path for c in deleted]
376
- ))
377
-
378
- return issues
379
-
380
-
381
- def analyze_changes(mode: str = "working") -> AnalysisResult:
382
- """分析变更"""
383
- result = AnalysisResult()
384
-
385
- # 获取变更
386
- if mode == "staged":
387
- result.changes = get_staged_changes()
388
- elif mode == "committed":
389
- result.changes = get_git_changes()
390
- else:
391
- result.changes = get_working_changes()
392
-
393
- if not result.changes:
394
- return result
395
-
396
- # 识别受影响模块
397
- result.affected_modules = identify_affected_modules(result.changes)
398
-
399
- # 检查文档同步
400
- doc_status, doc_issues = check_doc_sync(result.changes, result.affected_modules)
401
- result.doc_sync_status = doc_status
402
- result.issues.extend(doc_issues)
403
-
404
- # 分析影响
405
- impact_issues = analyze_impact(result.changes)
406
- result.issues.extend(impact_issues)
407
-
408
- return result
409
-
410
-
411
- def format_report(result: AnalysisResult, verbose: bool = False) -> str:
412
- """格式化分析报告"""
413
- lines = []
414
- lines.append("=" * 60)
415
- lines.append("变更分析报告")
416
- lines.append("=" * 60)
417
-
418
- lines.append(f"\n变更文件: {len(result.changes)}")
419
- lines.append(f"新增行数: +{result.total_additions}")
420
- lines.append(f"删除行数: -{result.total_deletions}")
421
- lines.append(f"受影响模块: {', '.join(result.affected_modules) or '无'}")
422
- lines.append(f"分析结果: {'✓ 通过' if result.passed else '✗ 需要关注'}")
423
-
424
- if result.changes and verbose:
425
- lines.append("\n" + "-" * 40)
426
- lines.append("变更文件列表:")
427
- lines.append("-" * 40)
428
-
429
- type_icons = {
430
- ChangeType.ADDED: "➕",
431
- ChangeType.MODIFIED: "📝",
432
- ChangeType.DELETED: "➖",
433
- ChangeType.RENAMED: "📋"
434
- }
435
-
436
- for change in result.changes:
437
- icon = type_icons[change.change_type]
438
- tags = []
439
- if change.is_code:
440
- tags.append("代码")
441
- if change.is_doc:
442
- tags.append("文档")
443
- if change.is_test:
444
- tags.append("测试")
445
- if change.is_config:
446
- tags.append("配置")
447
-
448
- tag_str = f" [{', '.join(tags)}]" if tags else ""
449
- lines.append(f" {icon} {change.path}{tag_str} (+{change.additions}/-{change.deletions})")
450
-
451
- if result.issues:
452
- lines.append("\n" + "-" * 40)
453
- lines.append("问题与建议:")
454
- lines.append("-" * 40)
455
-
456
- severity_icons = {"error": "✗", "warning": "⚠", "info": "ℹ"}
457
-
458
- for issue in result.issues:
459
- icon = severity_icons[issue.severity.value]
460
- lines.append(f"\n {icon} [{issue.severity.value.upper()}] {issue.message}")
461
- if verbose and issue.related_files:
462
- for f in issue.related_files[:5]:
463
- lines.append(f" - {f}")
464
- if len(issue.related_files) > 5:
465
- lines.append(f" ... 及其他 {len(issue.related_files) - 5} 个文件")
466
-
467
- if result.doc_sync_status:
468
- lines.append("\n" + "-" * 40)
469
- lines.append("文档同步状态:")
470
- lines.append("-" * 40)
471
-
472
- for doc, synced in result.doc_sync_status.items():
473
- icon = "✓" if synced else "✗"
474
- lines.append(f" {icon} {doc}")
475
-
476
- lines.append("\n" + "=" * 60)
477
- return "\n".join(lines)
478
-
479
-
480
- def main():
481
- import argparse
482
-
483
- parser = argparse.ArgumentParser(description="变更分析器")
484
- parser.add_argument("--mode", choices=["working", "staged", "committed"],
485
- default="working", help="分析模式")
486
- parser.add_argument("-v", "--verbose", action="store_true", help="详细输出")
487
- parser.add_argument("--json", action="store_true", help="JSON 格式输出")
488
-
489
- args = parser.parse_args()
490
-
491
- result = analyze_changes(args.mode)
492
-
493
- if args.json:
494
- output = {
495
- "passed": result.passed,
496
- "total_additions": result.total_additions,
497
- "total_deletions": result.total_deletions,
498
- "affected_modules": list(result.affected_modules),
499
- "changes": [
500
- {
501
- "path": c.path,
502
- "type": c.change_type.value,
503
- "additions": c.additions,
504
- "deletions": c.deletions,
505
- "is_code": c.is_code,
506
- "is_doc": c.is_doc,
507
- "is_test": c.is_test
508
- }
509
- for c in result.changes
510
- ],
511
- "issues": [
512
- {
513
- "severity": i.severity.value,
514
- "message": i.message,
515
- "related_files": i.related_files
516
- }
517
- for i in result.issues
518
- ],
519
- "doc_sync_status": result.doc_sync_status
520
- }
521
- print(json.dumps(output, ensure_ascii=False, indent=2))
522
- else:
523
- print(format_report(result, args.verbose))
524
-
525
- sys.exit(0 if result.passed else 1)
526
-
527
-
528
- if __name__ == "__main__":
529
- main()