@comate/zulu 1.2.1-beta.1 → 1.3.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 (169) hide show
  1. package/comate-engine/assets/skills/auto-commit-comate/SKILL.md +260 -0
  2. package/comate-engine/assets/skills/auto-commit-comate/references/data_structures.md +189 -0
  3. package/comate-engine/assets/skills/auto-commit-comate/references/new_version_instruction.md +209 -0
  4. package/comate-engine/assets/skills/auto-commit-comate/references/old_version_instruction.md +208 -0
  5. package/comate-engine/assets/skills/auto-commit-comate/scripts/git_diff_cli.py +196 -0
  6. package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/git_utils.py +20 -10
  7. package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/icafe/client.py +69 -40
  8. package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/icafe/farseer.py +8 -9
  9. package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/icafe/matching.py +65 -9
  10. package/comate-engine/assets/skills/auto-commit-comate/scripts/match_card_cli.py +37 -0
  11. package/comate-engine/assets/skills/cnap-comate/SKILL.md +157 -0
  12. package/comate-engine/assets/skills/cnap-comate/references/cases.md +198 -0
  13. package/comate-engine/assets/skills/cnap-comate/references/deploy-troubleshoot.md +15 -0
  14. package/comate-engine/assets/skills/cnap-comate/references/install.md +43 -0
  15. package/comate-engine/assets/skills/cnap-comate/references/kubectl.md +55 -0
  16. package/comate-engine/assets/skills/cnap-comate/references/login.md +125 -0
  17. package/comate-engine/assets/skills/cnap-comate/references/oncall.md +24 -0
  18. package/comate-engine/assets/skills/cnap-comate/scripts/install_cnap_cli.sh +36 -0
  19. package/comate-engine/assets/skills/code-security/SKILL.md +176 -0
  20. package/comate-engine/assets/skills/code-security/references/credential_hosting.md +102 -0
  21. package/comate-engine/assets/skills/code-security/references/vul_repair_sensitive.md +219 -0
  22. package/comate-engine/assets/skills/code-security/scripts/build_repair_info.py +0 -0
  23. package/comate-engine/assets/skills/code-security/scripts/credential_hosting.py +99 -0
  24. package/comate-engine/assets/skills/code-security/scripts/credential_poll.py +350 -0
  25. package/comate-engine/assets/skills/code-security/scripts/http_client.py +173 -0
  26. package/comate-engine/assets/skills/code-security/scripts/parse_scan_result.py +301 -0
  27. package/comate-engine/assets/skills/code-security/scripts/repair_vulnerability.py +261 -0
  28. package/comate-engine/assets/skills/code-security/scripts/report_chat.py +198 -0
  29. package/comate-engine/assets/skills/code-security/scripts/scan_vulnerability.py +316 -0
  30. package/comate-engine/assets/skills/code-security-comate/SKILL.md +219 -0
  31. package/comate-engine/assets/skills/code-security-comate/references/credential_hosting.md +102 -0
  32. package/comate-engine/assets/skills/code-security-comate/references/vul_repair-go_sql_injection.md +399 -0
  33. package/comate-engine/assets/skills/code-security-comate/references/vul_repair-java_sql_injection.md +591 -0
  34. package/comate-engine/assets/skills/code-security-comate/references/vul_repair-php_sql_injection.md +318 -0
  35. package/comate-engine/assets/skills/code-security-comate/references/vul_repair-python_sql_injection.md +198 -0
  36. package/comate-engine/assets/skills/code-security-comate/references/vul_repair_sensitive.md +219 -0
  37. package/comate-engine/assets/skills/code-security-comate/scripts/credential_hosting.py +87 -0
  38. package/comate-engine/assets/skills/code-security-comate/scripts/credential_poll.py +345 -0
  39. package/comate-engine/assets/skills/code-security-comate/scripts/http_client.py +173 -0
  40. package/comate-engine/assets/skills/code-security-comate/scripts/parse_scan_result.py +392 -0
  41. package/comate-engine/assets/skills/code-security-comate/scripts/repair_vulnerability.py +245 -0
  42. package/comate-engine/assets/skills/code-security-comate/scripts/report_chat.py +145 -0
  43. package/comate-engine/assets/skills/code-security-comate/scripts/scan_vulnerability.py +444 -0
  44. package/comate-engine/assets/skills/code-security-comate/scripts/utils.py +153 -0
  45. package/comate-engine/assets/skills/comate-docs-comate/SKILL.md +148 -0
  46. package/comate-engine/assets/skills/comate-docs-comate/references/doc-map-extended.md +78 -0
  47. package/comate-engine/assets/skills/comate-docs-comate/references/models-and-billing.md +51 -0
  48. package/comate-engine/assets/skills/comate-docs-comate/references/product-overview.md +73 -0
  49. package/comate-engine/assets/skills/comate-docs-comate/references/query_content.md +83 -0
  50. package/comate-engine/assets/skills/comate-docs-comate/references/query_repo.md +57 -0
  51. package/comate-engine/assets/skills/comate-docs-comate/scripts/ku_operator.py +1575 -0
  52. package/comate-engine/assets/skills/create-image-comate/SKILL.md +278 -0
  53. package/comate-engine/assets/skills/create-skill-comate/SKILL.md +308 -217
  54. package/comate-engine/assets/skills/create-skill-comate/agents/analyzer.md +274 -0
  55. package/comate-engine/assets/skills/create-skill-comate/agents/comparator.md +202 -0
  56. package/comate-engine/assets/skills/create-skill-comate/agents/grader.md +223 -0
  57. package/comate-engine/assets/skills/create-skill-comate/assets/eval_review.html +146 -0
  58. package/comate-engine/assets/skills/create-skill-comate/eval-viewer/generate_review.py +489 -0
  59. package/comate-engine/assets/skills/create-skill-comate/eval-viewer/viewer.html +1325 -0
  60. package/comate-engine/assets/skills/create-skill-comate/references/schemas.md +430 -0
  61. package/comate-engine/assets/skills/create-skill-comate/scripts/__init__.py +0 -0
  62. package/comate-engine/assets/skills/create-skill-comate/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  63. package/comate-engine/assets/skills/create-skill-comate/scripts/__pycache__/aggregate_benchmark.cpython-311.pyc +0 -0
  64. package/comate-engine/assets/skills/create-skill-comate/scripts/aggregate_benchmark.py +412 -0
  65. package/comate-engine/assets/skills/create-skill-comate/scripts/generate_report.py +334 -0
  66. package/comate-engine/assets/skills/create-skill-comate/scripts/package_skill.py +140 -0
  67. package/comate-engine/assets/skills/create-skill-comate/scripts/utils.py +53 -0
  68. package/comate-engine/assets/skills/find-skills-comate/SKILL.md +15 -12
  69. package/comate-engine/assets/skills/find-skills-comate/scripts/fetch_skills.py +32 -3
  70. package/comate-engine/assets/skills/get-ugate-token-comate/SKILL.md +159 -0
  71. package/comate-engine/assets/skills/get-ugate-token-comate/getUgateToken.py +150 -0
  72. package/comate-engine/assets/skills/icafe-comate/SKILL.md +240 -0
  73. package/comate-engine/assets/skills/icafe-comate/references/ai-workflows.md +233 -0
  74. package/comate-engine/assets/skills/icafe-comate/references/commands.md +1147 -0
  75. package/comate-engine/assets/skills/icafe-comate/references/error-handling.md +164 -0
  76. package/comate-engine/assets/skills/icafe-comate/references/git-auto-bindcard-workflow.md +201 -0
  77. package/comate-engine/assets/skills/icafe-comate/references/git-bindcard-workflow.md +327 -0
  78. package/comate-engine/assets/skills/icafe-comate/references/iql-syntax.md +327 -0
  79. package/comate-engine/assets/skills/icafe-comate/references/platform-concepts.md +317 -0
  80. package/comate-engine/assets/skills/icafe-comate/references/smart-create-workflow.md +171 -0
  81. package/comate-engine/assets/skills/icafe-comate/references/smart-find-workflow.md +127 -0
  82. package/comate-engine/assets/skills/icafe-comate/references/smart-update-workflow.md +118 -0
  83. package/comate-engine/assets/skills/icode-comate/SKILL.md +366 -0
  84. package/comate-engine/assets/skills/icode-comate/references/api/add_reviewers.md +44 -0
  85. package/comate-engine/assets/skills/icode-comate/references/api/build_fetch_command.md +89 -0
  86. package/comate-engine/assets/skills/icode-comate/references/api/check_repo_permission.md +89 -0
  87. package/comate-engine/assets/skills/icode-comate/references/api/create_branch.md +79 -0
  88. package/comate-engine/assets/skills/icode-comate/references/api/create_draft_comment.md +109 -0
  89. package/comate-engine/assets/skills/icode-comate/references/api/get_ai_cr_result.md +190 -0
  90. package/comate-engine/assets/skills/icode-comate/references/api/get_ai_review.md +97 -0
  91. package/comate-engine/assets/skills/icode-comate/references/api/get_diff_content.md +92 -0
  92. package/comate-engine/assets/skills/icode-comate/references/api/get_diff_file.md +88 -0
  93. package/comate-engine/assets/skills/icode-comate/references/api/get_machine_check.md +73 -0
  94. package/comate-engine/assets/skills/icode-comate/references/api/get_my_reviews.md +115 -0
  95. package/comate-engine/assets/skills/icode-comate/references/api/get_person_commit.md +89 -0
  96. package/comate-engine/assets/skills/icode-comate/references/api/get_person_repo.md +63 -0
  97. package/comate-engine/assets/skills/icode-comate/references/api/get_repo_branch.md +62 -0
  98. package/comate-engine/assets/skills/icode-comate/references/api/get_repo_config.md +91 -0
  99. package/comate-engine/assets/skills/icode-comate/references/api/get_repo_members.md +118 -0
  100. package/comate-engine/assets/skills/icode-comate/references/api/get_repo_reviews.md +91 -0
  101. package/comate-engine/assets/skills/icode-comate/references/api/get_review_comments.md +87 -0
  102. package/comate-engine/assets/skills/icode-comate/references/api/get_review_info.md +81 -0
  103. package/comate-engine/assets/skills/icode-comate/references/api/get_submit_settings.md +105 -0
  104. package/comate-engine/assets/skills/icode-comate/references/api/icode-api.md +86 -0
  105. package/comate-engine/assets/skills/icode-comate/references/api/publish_comments.md +72 -0
  106. package/comate-engine/assets/skills/icode-comate/references/api/set_review_score.md +58 -0
  107. package/comate-engine/assets/skills/icode-comate/references/api/start_ai_review.md +77 -0
  108. package/comate-engine/assets/skills/icode-comate/references/api/submit_review.md +50 -0
  109. package/comate-engine/assets/skills/icode-comate/references/api/trigger_ai_cr.md +63 -0
  110. package/comate-engine/assets/skills/icode-comate/references/feature/add-reviewer.md +92 -0
  111. package/comate-engine/assets/skills/icode-comate/references/feature/fix-machine-check.md +144 -0
  112. package/comate-engine/assets/skills/icode-comate/references/feature/merge-cr.md +100 -0
  113. package/comate-engine/assets/skills/icode-comate/references/feature/ssh-setup.md +106 -0
  114. package/comate-engine/assets/skills/icode-comate/references/feature/submit-acr.md +135 -0
  115. package/comate-engine/assets/skills/icode-comate/references/feature/submit-cr.md +123 -0
  116. package/comate-engine/assets/skills/icode-comate/references/git/clone.md +67 -0
  117. package/comate-engine/assets/skills/icode-comate/references/git/icode-git.md +68 -0
  118. package/comate-engine/assets/skills/icode-comate/references/git/push.md +64 -0
  119. package/comate-engine/assets/skills/icode-comate/references/git/push_cr.md +103 -0
  120. package/comate-engine/assets/skills/icode-comate/references/install.md +144 -0
  121. package/comate-engine/assets/skills/icode-comate/references/login.md +111 -0
  122. package/comate-engine/assets/skills/icode-comate/scripts/add-reviewer.sh +154 -0
  123. package/comate-engine/assets/skills/icode-comate/scripts/common.sh +145 -0
  124. package/comate-engine/assets/skills/icode-comate/scripts/fix-machine-check.sh +131 -0
  125. package/comate-engine/assets/skills/icode-comate/scripts/merge-cr.sh +105 -0
  126. package/comate-engine/assets/skills/icode-comate/scripts/ssh-setup.sh +159 -0
  127. package/comate-engine/assets/skills/icode-comate/scripts/submit-acr.sh +236 -0
  128. package/comate-engine/assets/skills/icode-comate/scripts/submit-cr.sh +104 -0
  129. package/comate-engine/assets/skills/icode-comate/scripts/test-preflight.sh +89 -0
  130. package/comate-engine/assets/skills/ku-operator-comate/SKILL.md +121 -0
  131. package/comate-engine/assets/skills/ku-operator-comate/examples.md +190 -0
  132. package/comate-engine/assets/skills/ku-operator-comate/references/add_member.md +49 -0
  133. package/comate-engine/assets/skills/ku-operator-comate/references/change_scope.md +38 -0
  134. package/comate-engine/assets/skills/ku-operator-comate/references/copy_doc.md +50 -0
  135. package/comate-engine/assets/skills/ku-operator-comate/references/create_doc.md +61 -0
  136. package/comate-engine/assets/skills/ku-operator-comate/references/delete_doc.md +31 -0
  137. package/comate-engine/assets/skills/ku-operator-comate/references/edit_content.md +568 -0
  138. package/comate-engine/assets/skills/ku-operator-comate/references/move_doc.md +45 -0
  139. package/comate-engine/assets/skills/ku-operator-comate/references/query_comment.md +79 -0
  140. package/comate-engine/assets/skills/ku-operator-comate/references/query_content.md +83 -0
  141. package/comate-engine/assets/skills/ku-operator-comate/references/query_flowchart.md +84 -0
  142. package/comate-engine/assets/skills/ku-operator-comate/references/query_permission.md +38 -0
  143. package/comate-engine/assets/skills/ku-operator-comate/references/query_recent_view.md +67 -0
  144. package/comate-engine/assets/skills/ku-operator-comate/references/query_repo.md +57 -0
  145. package/comate-engine/assets/skills/ku-operator-comate/references/query_user_info.md +37 -0
  146. package/comate-engine/assets/skills/ku-operator-comate/references/update_member.md +41 -0
  147. package/comate-engine/assets/skills/ku-operator-comate/references/upload_attachment.md +52 -0
  148. package/comate-engine/assets/skills/ku-operator-comate/scripts/ku_operator.py +1575 -0
  149. package/comate-engine/node_modules/better-sqlite3/node_modules/.bin/prebuild-install +2 -2
  150. package/comate-engine/node_modules/tree-sitter-bash/node_modules/.bin/node-gyp-build +2 -2
  151. package/comate-engine/node_modules/tree-sitter-bash/node_modules/.bin/node-gyp-build-optional +2 -2
  152. package/comate-engine/node_modules/tree-sitter-bash/node_modules/.bin/node-gyp-build-test +2 -2
  153. package/comate-engine/package.json +2 -0
  154. package/comate-engine/server.js +263 -79
  155. package/dist/bundle/index.js +8 -8
  156. package/package.json +1 -1
  157. package/comate-engine/assets/skills/figma2code-comate/codeConnect.md +0 -37
  158. package/comate-engine/assets/skills/figma2code-comate/designToken.md +0 -3
  159. package/comate-engine/assets/skills/figma2code-comate/f2cMcp.md +0 -59
  160. package/comate-engine/assets/skills/smart-commit/SKILL.md +0 -646
  161. package/comate-engine/node_modules/@comate/plugin-host/dist/index-AZIho4HV.js +0 -1
  162. package/comate-engine/node_modules/@comate/plugin-host/dist/user-BIpzRUfb.js +0 -44
  163. /package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/references/issue_type_mapping.json +0 -0
  164. /package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/references/query_reference.md +0 -0
  165. /package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/compat.py +0 -0
  166. /package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/create_card_cli.py +0 -0
  167. /package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/icafe/__init__.py +0 -0
  168. /package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/logger.py +0 -0
  169. /package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/recognize_card_cli.py +0 -0
@@ -0,0 +1,245 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ 漏洞修复工具 - 根据扫描结果修复指定文件的漏洞。
4
+
5
+ 用法:
6
+ python3 repair_vulnerability.py --root-path <项目目录> --username <用户名> --parsed-result <parsed_result.json路径>
7
+ python3 repair_vulnerability.py --root-path <项目目录> --username <用户名> --vulnerability-info '<漏洞信息JSON>'
8
+
9
+ 支持两种输入方式(二选一):
10
+ --parsed-result: 直接传入 parsed_result.json 路径,脚本自动提取普通漏洞并构建修复信息
11
+ --vulnerability-info: 传入漏洞信息 JSON 字符串
12
+
13
+ 流程:
14
+ 1. 解析漏洞信息,计算待修复文件的哈希
15
+ 2. 调用修复接口
16
+ 3. 如有缺失文件则上传后重试
17
+ 4. 返回包含 diff_content 的修复结果
18
+ """
19
+
20
+ import argparse
21
+ import difflib
22
+ import json
23
+ import logging
24
+ import os
25
+ import sys
26
+ import time
27
+
28
+ import http_client # noqa: F401 (triggers shared logging config)
29
+ import utils
30
+
31
+ logger = logging.getLogger("repair")
32
+
33
+ # 修复轮询最大次数(每次间隔 3 秒,约 10 分钟)
34
+ MAX_REPAIR_POLLS = 200
35
+ REPAIR_POLL_INTERVAL = 3
36
+ MAX_UPLOAD_RETRIES = 10
37
+
38
+
39
+ def diff_file_content(file_path, new_content):
40
+ # type: (str, str) -> str
41
+ """比较原文件与修复后内容,使用 difflib 生成精确 diff,返回 diff 列表 JSON。
42
+
43
+ 每个不连续的变更区域(hunk)生成独立的 {from_content, to_content} 对,
44
+ 确保每个 from_content 都是原文件中的连续子串,可以被 str.replace 精确匹配。
45
+ """
46
+ with open(file_path, "r", encoding="utf-8") as f:
47
+ old_content = f.read()
48
+
49
+ old_lines = old_content.splitlines(keepends=True)
50
+ new_lines = new_content.splitlines(keepends=True)
51
+
52
+ # 使用 unified_diff 找出所有差异区域,n=0 不提供上下文行
53
+ diff = list(difflib.unified_diff(old_lines, new_lines, n=0))
54
+
55
+ diffs = [] # type: list
56
+ current_from = [] # type: list
57
+ current_to = [] # type: list
58
+
59
+ def _flush():
60
+ if current_from or current_to:
61
+ diffs.append({
62
+ "from_content": "".join(current_from),
63
+ "to_content": "".join(current_to),
64
+ })
65
+ del current_from[:]
66
+ del current_to[:]
67
+
68
+ for line in diff:
69
+ if line.startswith("---") or line.startswith("+++"):
70
+ continue
71
+ elif line.startswith("@@"):
72
+ # 新 hunk 开始,先保存上一组
73
+ _flush()
74
+ elif line.startswith("-"):
75
+ current_from.append(line[1:])
76
+ elif line.startswith("+"):
77
+ current_to.append(line[1:])
78
+
79
+ # 保存最后一组
80
+ _flush()
81
+
82
+ return json.dumps(diffs, ensure_ascii=False, indent=2)
83
+
84
+
85
+ def upload_files_for_repair(root_path, missing_files, username, user_id):
86
+ # type: (str, list, str, str) -> None
87
+ """上传修复过程中缺失的文件。"""
88
+ payload = {"files": {}}
89
+ for name in missing_files:
90
+ file_path = os.path.join(root_path, name)
91
+ try:
92
+ content = utils.read_file_content(file_path)
93
+ file_hash = utils.calc_sha256(file_path)
94
+ payload["files"][name] = {"hash": file_hash, "content": content}
95
+ except Exception as e:
96
+ print("警告: 读取文件失败 {}: {}".format(file_path, e), file=sys.stderr)
97
+
98
+ http_client.put(
99
+ "{}/api/v1/upload".format(utils.HOST),
100
+ headers=utils.build_headers(username, user_id),
101
+ json_body=payload,
102
+ )
103
+
104
+
105
+ def repair_vulnerability(root_path, vulnerability_info, username, user_id):
106
+ # type: (str, dict, str, str) -> dict
107
+ """执行漏洞修复,返回包含 diff 的修复结果。"""
108
+ # 计算待修复文件的哈希
109
+ for file_info in vulnerability_info.get("files", []):
110
+ file_path = os.path.join(root_path, file_info["name"])
111
+ if os.path.isfile(file_path):
112
+ file_info["hash"] = utils.calc_sha256(file_path)
113
+
114
+ repair_type = vulnerability_info.get("type", 2)
115
+ file_count = len(vulnerability_info.get("files", []))
116
+ logger.info("repair start: type=%d, files=%d", repair_type, file_count)
117
+ api_url = "{}/api/v2/repair_file".format(utils.HOST)
118
+ print("开始修复...", file=sys.stderr)
119
+
120
+ poll_count = 0
121
+ upload_retry_count = 0
122
+ while poll_count < MAX_REPAIR_POLLS:
123
+ result = http_client.post(
124
+ api_url,
125
+ headers=utils.build_headers(username, user_id),
126
+ json_body=vulnerability_info,
127
+ )
128
+
129
+ # 如有缺失文件,先上传
130
+ missing = result.get("data", {}).get("missingFiles", [])
131
+ if missing:
132
+ upload_retry_count += 1
133
+ if upload_retry_count > MAX_UPLOAD_RETRIES:
134
+ print("错误: 修复上传重试 {} 次后仍有缺失文件".format(MAX_UPLOAD_RETRIES), file=sys.stderr)
135
+ return {"status": -1, "message": "修复上传重试次数超限"}
136
+ print("上传缺失文件: {} 个 (重试 {}/{})".format(len(missing),
137
+ upload_retry_count, MAX_UPLOAD_RETRIES), file=sys.stderr)
138
+ upload_files_for_repair(root_path, missing, username, user_id)
139
+ time.sleep(REPAIR_POLL_INTERVAL)
140
+ continue
141
+
142
+ # status != 0 表示完成
143
+ if result.get("status") != 0:
144
+ # 生成 diff
145
+ files_data = result.get("data", {}).get("files", [])
146
+ for file_data in files_data:
147
+ repaired_content = file_data.get("repairedContent", "")
148
+ if repaired_content:
149
+ file_path = os.path.join(root_path, file_data["name"])
150
+ if os.path.isfile(file_path):
151
+ diff_json = diff_file_content(file_path, repaired_content)
152
+ file_data["diff_content"] = diff_json
153
+ # 置空防止泄露完整源码
154
+ file_data["repairedContent"] = ""
155
+ return result
156
+
157
+ poll_count += 1
158
+ print("修复中,等待结果... ({}/{})".format(poll_count, MAX_REPAIR_POLLS), file=sys.stderr)
159
+ time.sleep(REPAIR_POLL_INTERVAL)
160
+
161
+ print("错误: 修复超时,已轮询 {} 次仍未完成".format(MAX_REPAIR_POLLS), file=sys.stderr)
162
+ return {"status": -1, "message": "修复超时"}
163
+
164
+
165
+ def build_vulnerability_info(parsed):
166
+ # type: (dict) -> dict
167
+ """从 parsed_result.json 构建修复接口所需的 vulnerability-info。"""
168
+ bundle_hash = parsed.get("bundle_hash", "")
169
+ common_vuls = parsed.get("common_vuls", [])
170
+
171
+ file_map = {} # type: dict
172
+ for vul in common_vuls:
173
+ fname = vul.get("file", "")
174
+ if not fname:
175
+ continue
176
+ if fname not in file_map:
177
+ file_map[fname] = {"name": fname, "vulList": []}
178
+ file_map[fname]["vulList"].append({
179
+ "ruleID": vul.get("ruleID", ""),
180
+ "line": vul.get("startLine", 0),
181
+ "hash": vul.get("hash", ""),
182
+ })
183
+
184
+ return {
185
+ "files": list(file_map.values()),
186
+ "type": 2,
187
+ "extra": {
188
+ "bundleHash": bundle_hash,
189
+ },
190
+ }
191
+
192
+
193
+ def main():
194
+ parser = argparse.ArgumentParser(description="代码安全漏洞修复工具")
195
+ parser.add_argument("--root-path", required=True, help="项目根目录")
196
+ parser.add_argument("--username", required=True, help="Comate 用户名")
197
+ parser.add_argument("--vulnerability-info", default=None, help="漏洞信息 JSON 字符串")
198
+ parser.add_argument("--parsed-result", default=None,
199
+ help="解析结果文件路径 (parsed_result.json),与 --vulnerability-info 二选一")
200
+ parser.add_argument("--output-dir", default=None, help="结果输出目录,默认为 skill 临时目录")
201
+ args = parser.parse_args()
202
+
203
+ if not args.vulnerability_info and not args.parsed_result:
204
+ print("错误: 必须提供 --vulnerability-info 或 --parsed-result 之一", file=sys.stderr)
205
+ sys.exit(1)
206
+
207
+ user_id = utils.make_user_id(args.username)
208
+
209
+ logger.info("repair_vulnerability start: username=%s, root_path=%s", args.username, args.root_path)
210
+
211
+ root_path = os.path.realpath(args.root_path)
212
+ if not os.path.isdir(root_path):
213
+ print("错误: 目录不存在 {}".format(root_path), file=sys.stderr)
214
+ sys.exit(1)
215
+
216
+ output_dir = utils.get_output_dir(root_path, args.output_dir)
217
+
218
+ if args.parsed_result:
219
+ try:
220
+ with open(args.parsed_result, "r", encoding="utf-8") as f:
221
+ parsed = json.load(f)
222
+ except Exception as e:
223
+ print("错误: 读取解析结果失败 {}: {}".format(args.parsed_result, e), file=sys.stderr)
224
+ sys.exit(1)
225
+ if not parsed.get("common_vuls"):
226
+ print("无普通漏洞需要修复", file=sys.stderr)
227
+ sys.exit(0)
228
+ vulnerability_info = build_vulnerability_info(parsed)
229
+ else:
230
+ try:
231
+ vulnerability_info = json.loads(args.vulnerability_info)
232
+ except json.JSONDecodeError as e:
233
+ print("错误: 漏洞信息 JSON 解析失败: {}".format(e), file=sys.stderr)
234
+ sys.exit(1)
235
+
236
+ result = repair_vulnerability(root_path, vulnerability_info, args.username, user_id)
237
+
238
+ output_file = os.path.join(output_dir, "repair_result.json")
239
+ with open(output_file, "w", encoding="utf-8") as f:
240
+ json.dump(result, f, ensure_ascii=False, indent=2)
241
+ print(output_file)
242
+
243
+
244
+ if __name__ == "__main__":
245
+ main()
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ 对话结果上报工具 - 扫描成功后向服务端上报本次对话信息。
4
+
5
+ 用法:
6
+ python3 report_chat.py --username <用户名> --chat-id <对话ID>
7
+ --scan-result <扫描结果JSON文件> [--git-url <仓库URL>] [--git-branch <分支>]
8
+ [--ide <IDE名称>] [--query <用户输入>]
9
+
10
+ 接口: POST /api/v1/chats
11
+ """
12
+
13
+ import argparse
14
+ import json
15
+ import logging
16
+ import os
17
+ import sys
18
+
19
+ import http_client # noqa: F401 (triggers shared logging config)
20
+ import utils
21
+
22
+ logger = logging.getLogger("report")
23
+
24
+
25
+ def build_vuls_from_scan_result(scan_result, root_path=""):
26
+ # type: (dict, str) -> list
27
+ """从扫描结果中提取漏洞信息,构造 vuls 数组。"""
28
+ vuls = []
29
+ data = scan_result.get("data", {})
30
+ # 兼容两种结构: data.sarif.runs 或 data.runs
31
+ runs = data.get("sarif", {}).get("runs", []) or data.get("runs", [])
32
+ if not runs:
33
+ return vuls
34
+
35
+ # 按文件聚合漏洞
36
+ file_vuls = {} # type: dict
37
+ for run in runs:
38
+ # 兼容 "results"(标准SARIF) 和 "result"(服务端实际返回)
39
+ results = run.get("results", []) or run.get("result", [])
40
+ for result in results:
41
+ locations = result.get("locations", [])
42
+ vul_hash = result.get("properties", {}).get("hash", "")
43
+ if not vul_hash:
44
+ continue
45
+ for loc in locations:
46
+ file_path = loc.get("physicalLocation", {}).get("artifactLocation", {}).get("uri", "")
47
+ if not file_path:
48
+ continue
49
+ if file_path not in file_vuls:
50
+ file_vuls[file_path] = {
51
+ "fileName": file_path,
52
+ "fileHash": "",
53
+ "vuls": [],
54
+ }
55
+ file_vuls[file_path]["vuls"].append({"vulHash": vul_hash})
56
+
57
+ # 填充 fileHash
58
+ bundle_files = scan_result.get("data", {}).get("bundleFiles", {})
59
+ for file_path, file_info in file_vuls.items():
60
+ fh = bundle_files.get(file_path, "")
61
+ if not fh and root_path:
62
+ fh = utils.calc_sha256_safe(os.path.join(root_path, file_path))
63
+ file_info["fileHash"] = fh
64
+
65
+ vuls = list(file_vuls.values())
66
+ return vuls
67
+
68
+
69
+ def report_chat(chat_id, scan_result, git_url, git_branch, ide, query, root_path="", username="", user_id=""):
70
+ # type: (str, dict, str, str, str, str, str, str, str) -> dict
71
+ """上报对话结果到服务端。"""
72
+ # git_url/git_branch 为空时,自动从 root_path 获取
73
+ if root_path and (not git_url or not git_branch):
74
+ git_info = utils.get_git_info(root_path)
75
+ if not git_url:
76
+ git_url = git_info["gitURL"]
77
+ if not git_branch:
78
+ git_branch = git_info["gitBranch"]
79
+
80
+ vuls = build_vuls_from_scan_result(scan_result, root_path)
81
+
82
+ body = {
83
+ "type": 1,
84
+ "gitInfo": {
85
+ "url": git_url,
86
+ "branch": git_branch,
87
+ },
88
+ "ide": ide,
89
+ "query": query,
90
+ "status": 0,
91
+ "errMessage": "",
92
+ "vuls": vuls,
93
+ }
94
+
95
+ headers = utils.build_headers(username, user_id, chat_id)
96
+ logger.info("report_chat: chat_id=%s, vuls_count=%d, git_url=%s, git_branch=%s",
97
+ chat_id, len(vuls), git_url, git_branch)
98
+ return http_client.post("{}/api/v1/chats".format(utils.HOST), headers=headers, json_body=body)
99
+
100
+
101
+ def main():
102
+ parser = argparse.ArgumentParser(description="对话结果上报工具")
103
+ parser.add_argument("--username", required=True, help="Comate 用户名")
104
+ parser.add_argument("--chat-id", required=True, help="对话唯一标识 (COMATE_SESSION_ID)")
105
+ parser.add_argument("--scan-result", required=True, help="扫描结果 JSON 文件路径")
106
+ parser.add_argument("--root-path", default="", help="项目根目录,用于计算文件哈希")
107
+ parser.add_argument("--git-url", default="", help="Git 仓库 URL")
108
+ parser.add_argument("--git-branch", default="", help="Git 分支")
109
+ parser.add_argument("--ide", default="", help="IDE 名称")
110
+ parser.add_argument("--query", default="", help="用户输入的查询文本")
111
+ args = parser.parse_args()
112
+
113
+ user_id = utils.make_user_id(args.username)
114
+
115
+ logger.info("report_chat start: chat_id=%s, username=%s, scan_result=%s",
116
+ args.chat_id, args.username, args.scan_result)
117
+
118
+ # 读取扫描结果
119
+ scan_result = {}
120
+ try:
121
+ with open(args.scan_result, "r", encoding="utf-8") as f:
122
+ scan_result = json.load(f)
123
+ except Exception as e:
124
+ print("警告: 读取扫描结果失败 {}: {}".format(args.scan_result, e), file=sys.stderr)
125
+
126
+ try:
127
+ result = report_chat(
128
+ chat_id=args.chat_id,
129
+ scan_result=scan_result,
130
+ git_url=args.git_url,
131
+ git_branch=args.git_branch,
132
+ ide=args.ide,
133
+ query=args.query,
134
+ root_path=args.root_path,
135
+ username=args.username,
136
+ user_id=user_id,
137
+ )
138
+ print(json.dumps(result, ensure_ascii=False))
139
+ except Exception as e:
140
+ print("上报失败: {}".format(e), file=sys.stderr)
141
+ sys.exit(1)
142
+
143
+
144
+ if __name__ == "__main__":
145
+ main()