@comate/zulu 1.4.0-beta.2 → 1.4.0-beta.3
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/comate-engine/assets/skills/auto-commit/SKILL.md +241 -0
- package/comate-engine/assets/skills/auto-commit/references/data_structures.md +183 -0
- package/comate-engine/assets/skills/auto-commit/references/interaction_instruction.md +220 -0
- package/comate-engine/assets/skills/auto-commit/references/issue_type_mapping.json +19 -0
- package/comate-engine/assets/skills/auto-commit/references/query_reference.md +176 -0
- package/comate-engine/assets/skills/auto-commit/scripts/build_git_commit_payload.py +195 -0
- package/comate-engine/assets/skills/auto-commit/scripts/build_icafe_cards_payload.py +80 -0
- package/comate-engine/assets/skills/auto-commit/scripts/cache_manager.py +69 -0
- package/comate-engine/assets/skills/auto-commit/scripts/create_card_cli.py +67 -0
- package/comate-engine/assets/skills/auto-commit/scripts/git_diff_cli.py +201 -0
- package/comate-engine/assets/skills/auto-commit/scripts/git_utils.py +230 -0
- package/comate-engine/assets/skills/auto-commit/scripts/icafe/__init__.py +66 -0
- package/comate-engine/assets/skills/auto-commit/scripts/icafe/client.py +473 -0
- package/comate-engine/assets/skills/auto-commit/scripts/icafe/farseer.py +52 -0
- package/comate-engine/assets/skills/auto-commit/scripts/icafe/matching.py +784 -0
- package/comate-engine/assets/skills/auto-commit/scripts/logger.py +32 -0
- package/comate-engine/assets/skills/auto-commit/scripts/match_card_cli.py +41 -0
- package/comate-engine/assets/skills/auto-commit/scripts/payload_validators.py +309 -0
- package/comate-engine/assets/skills/auto-commit/scripts/recognize_card_cli.py +63 -0
- package/comate-engine/assets/skills/{automation-browser-comate → automation-browser}/SKILL.md +1 -0
- package/comate-engine/assets/skills/{cnap-comate → cnap}/SKILL.md +1 -0
- package/comate-engine/assets/skills/code-review/SKILL.md +202 -0
- package/comate-engine/assets/skills/code-review/agents/correctness-reviewer.md +62 -0
- package/comate-engine/assets/skills/code-review/agents/custom-reviewer.md +53 -0
- package/comate-engine/assets/skills/code-review/agents/meta-reviewer.md +84 -0
- package/comate-engine/assets/skills/code-review/agents/reliability-reviewer.md +72 -0
- package/comate-engine/assets/skills/code-review/agents/reuse-reviewer.md +101 -0
- package/comate-engine/assets/skills/code-review/agents/style-reviewer.md +65 -0
- package/comate-engine/assets/skills/code-review/evals/SKILL.md +334 -0
- package/comate-engine/assets/skills/code-review/evals/agents/gt-generator.md +76 -0
- package/comate-engine/assets/skills/code-review/evals/agents/miner.md +87 -0
- package/comate-engine/assets/skills/code-review/evals/agents/score-judge.md +168 -0
- package/comate-engine/assets/skills/code-review/evals/references/cli-query-template.md +114 -0
- package/comate-engine/assets/skills/code-review/evals/references/gt-schema.md +77 -0
- package/comate-engine/assets/skills/code-review/references/custom-rules/RULE_TEMPLATE.md +141 -0
- package/comate-engine/assets/skills/code-review/references/dispatch-template.md +142 -0
- package/comate-engine/assets/skills/code-review/references/output-schema.md +197 -0
- package/comate-engine/assets/skills/code-review/references/report-format.md +41 -0
- package/comate-engine/assets/skills/code-review/references/rules/Go/GO_AUTH_RULES.md +29 -0
- package/comate-engine/assets/skills/code-review/references/rules/Go/GO_CORRECTNESS_RULES.md +111 -0
- package/comate-engine/assets/skills/code-review/references/rules/Go/GO_RESOURCE_CONCURRENCY_RULES.md +190 -0
- package/comate-engine/assets/skills/code-review/references/rules/Go/GO_STYLE_RULES.md +354 -0
- package/comate-engine/assets/skills/code-review/references/rules/Java/JAVA_AUTH_RULES.md +34 -0
- package/comate-engine/assets/skills/code-review/references/rules/Java/JAVA_CORRECTNESS_RULES.md +207 -0
- package/comate-engine/assets/skills/code-review/references/rules/Java/JAVA_RESOURCE_CONCURRENCY_RULES.md +220 -0
- package/comate-engine/assets/skills/code-review/references/rules/Java/JAVA_STYLE_RULES.md +306 -0
- package/comate-engine/assets/skills/code-review/references/rules/Js/JS_AUTH_RULES.md +48 -0
- package/comate-engine/assets/skills/code-review/references/rules/Js/JS_CORRECTNESS_RULES.md +364 -0
- package/comate-engine/assets/skills/code-review/references/rules/Js/JS_RESOURCE_CONCURRENCY_RULES.md +180 -0
- package/comate-engine/assets/skills/code-review/references/rules/Js/JS_STYLE_RULES.md +350 -0
- package/comate-engine/assets/skills/code-review/references/rules/Python/PYTHON_AUTH_RULES.md +38 -0
- package/comate-engine/assets/skills/code-review/references/rules/Python/PYTHON_CORRECTNESS_RULES.md +255 -0
- package/comate-engine/assets/skills/code-review/references/rules/Python/PYTHON_RESOURCE_CONCURRENCY_RULES.md +180 -0
- package/comate-engine/assets/skills/code-review/references/rules/Python/PYTHON_STYLE_RULES.md +195 -0
- package/comate-engine/assets/skills/code-review/references/telemetry.md +27 -0
- package/comate-engine/assets/skills/{code-security-comate → code-security}/SKILL.md +1 -0
- package/comate-engine/assets/skills/{comate-docs-comate → comate-docs}/SKILL.md +1 -1
- package/comate-engine/assets/skills/create-automation-tasks-comate/SKILL.md +300 -0
- package/comate-engine/assets/skills/create-automation-tasks-comate/references/backend_dev.md +109 -0
- package/comate-engine/assets/skills/create-automation-tasks-comate/references/env_setup.md +130 -0
- package/comate-engine/assets/skills/create-automation-tasks-comate/references/frontend_dev.md +74 -0
- package/comate-engine/assets/skills/create-automation-tasks-comate/references/git_operations.md +88 -0
- package/comate-engine/assets/skills/create-automation-tasks-comate/references/long_running_task.md +96 -0
- package/comate-engine/assets/skills/create-automation-tasks-comate/references/testing_strategy.md +94 -0
- package/comate-engine/assets/skills/create-automation-tasks-comate/scripts/check_config.py +397 -0
- package/comate-engine/assets/skills/{create-rule-comate → create-rule}/SKILL.md +1 -0
- package/comate-engine/assets/skills/{create-skill-comate → create-skill}/SKILL.md +1 -1
- package/comate-engine/assets/skills/{figma2code-comate → figma2code}/SKILL.md +1 -0
- package/comate-engine/assets/skills/{icafe-comate → icafe}/SKILL.md +1 -13
- package/comate-engine/assets/skills/{icode-comate → icode}/SKILL.md +1 -0
- package/comate-engine/node_modules/@comate/plugin-shared-internals/dist/index.js +3 -3
- package/comate-engine/server.js +136 -82
- package/dist/bundle/index.js +20 -9
- package/package.json +1 -1
- /package/comate-engine/assets/skills/{cnap-comate → cnap}/references/cases.md +0 -0
- /package/comate-engine/assets/skills/{cnap-comate → cnap}/references/deploy-troubleshoot.md +0 -0
- /package/comate-engine/assets/skills/{cnap-comate → cnap}/references/install.md +0 -0
- /package/comate-engine/assets/skills/{cnap-comate → cnap}/references/kubectl.md +0 -0
- /package/comate-engine/assets/skills/{cnap-comate → cnap}/references/login.md +0 -0
- /package/comate-engine/assets/skills/{cnap-comate → cnap}/references/oncall.md +0 -0
- /package/comate-engine/assets/skills/{cnap-comate → cnap}/scripts/install_cnap_cli.sh +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/references/credential_hosting.md +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/references/vul_repair-go_sql_injection.md +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/references/vul_repair-java_sql_injection.md +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/references/vul_repair-php_sql_injection.md +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/references/vul_repair-python_sql_injection.md +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/references/vul_repair_sensitive.md +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/credential_hosting.py +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/credential_poll.py +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/http_client.py +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/parse_scan_result.py +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/repair_vulnerability.py +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/report_chat.py +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/scan_vulnerability.py +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/utils.py +0 -0
- /package/comate-engine/assets/skills/{comate-docs-comate → comate-docs}/references/doc-map-extended.md +0 -0
- /package/comate-engine/assets/skills/{comate-docs-comate → comate-docs}/references/models-and-billing.md +0 -0
- /package/comate-engine/assets/skills/{comate-docs-comate → comate-docs}/references/product-overview.md +0 -0
- /package/comate-engine/assets/skills/{create-image-comate → create-image}/SKILL.md +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/LICENSE.txt +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/agents/analyzer.md +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/agents/comparator.md +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/agents/grader.md +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/assets/eval_review.html +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/eval-viewer/generate_review.py +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/eval-viewer/viewer.html +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/references/schemas.md +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/__init__.py +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/__pycache__/aggregate_benchmark.cpython-311.pyc +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/aggregate_benchmark.py +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/generate_report.py +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/package_skill.py +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/quick_validate.py +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/utils.py +0 -0
- /package/comate-engine/assets/skills/{create-subagent-comate → create-subagent}/SKILL.md +0 -0
- /package/comate-engine/assets/skills/{figma2code-comate → figma2code}/references/codeConnect.md +0 -0
- /package/comate-engine/assets/skills/{figma2code-comate → figma2code}/references/designToken.md +0 -0
- /package/comate-engine/assets/skills/{figma2code-comate → figma2code}/references/image2design.md +0 -0
- /package/comate-engine/assets/skills/{find-skills-comate → find-skills}/SKILL.md +0 -0
- /package/comate-engine/assets/skills/{find-skills-comate → find-skills}/scripts/fetch_skills.py +0 -0
- /package/comate-engine/assets/skills/{find-skills-comate → find-skills}/scripts/get_download_url.py +0 -0
- /package/comate-engine/assets/skills/{find-skills-comate → find-skills}/scripts/install_skill.py +0 -0
- /package/comate-engine/assets/skills/{find-skills-comate → find-skills}/scripts/preview_skill.py +0 -0
- /package/comate-engine/assets/skills/{get-ugate-token-comate → get-ugate-token}/SKILL.md +0 -0
- /package/comate-engine/assets/skills/{get-ugate-token-comate → get-ugate-token}/getUgateToken.py +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/ai-workflows.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/commands.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/error-handling.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/git-auto-bindcard-workflow.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/git-bindcard-workflow.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/iql-syntax.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/platform-concepts.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/smart-create-workflow.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/smart-find-workflow.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/smart-update-workflow.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/add_reviewers.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/build_fetch_command.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/check_repo_permission.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/create_branch.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/create_draft_comment.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_ai_cr_result.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_ai_review.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_diff_content.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_diff_file.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_machine_check.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_my_reviews.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_person_commit.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_person_repo.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_repo_branch.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_repo_config.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_repo_members.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_repo_reviews.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_review_comments.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_review_info.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_submit_settings.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/icode-api.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/publish_comments.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/set_review_score.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/start_ai_review.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/submit_review.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/trigger_ai_cr.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/feature/add-reviewer.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/feature/fix-machine-check.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/feature/merge-cr.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/feature/ssh-setup.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/feature/submit-acr.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/feature/submit-cr.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/git/clone.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/git/icode-git.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/git/push.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/git/push_cr.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/install.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/login.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/add-reviewer.sh +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/common.sh +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/fix-machine-check.sh +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/merge-cr.sh +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/ssh-setup.sh +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/submit-acr.sh +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/submit-cr.sh +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/test-preflight.sh +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/SKILL.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/examples.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/add_member.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/change_scope.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/copy_doc.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/create_doc.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/delete_doc.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/edit_content.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/move_doc.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/query_comment.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/query_content.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/query_flowchart.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/query_permission.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/query_recent_view.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/query_repo.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/query_user_info.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/update_member.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/upload_attachment.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/scripts/ku_operator.py +0 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"""命令行工具:获取 workspace 的 git diff 摘要
|
|
2
|
+
|
|
3
|
+
用法:
|
|
4
|
+
python3 git_diff_cli.py --workspace /path/to/project
|
|
5
|
+
|
|
6
|
+
输出:
|
|
7
|
+
JSON 格式的 diff 摘要,包含 changed_files、stat_summary、diff_content 等字段。
|
|
8
|
+
失败时输出 {"error": "错误信息"}。
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import argparse
|
|
12
|
+
import json
|
|
13
|
+
import os
|
|
14
|
+
import subprocess
|
|
15
|
+
import sys
|
|
16
|
+
|
|
17
|
+
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
18
|
+
from cache_manager import update_git_diff
|
|
19
|
+
|
|
20
|
+
# tracked diff 最大行数
|
|
21
|
+
MAX_TRACKED_DIFF_LINES = 300
|
|
22
|
+
# untracked diff 最大行数
|
|
23
|
+
MAX_UNTRACKED_DIFF_LINES = 200
|
|
24
|
+
# 合并后 diff 最大总行数
|
|
25
|
+
MAX_TOTAL_DIFF_LINES = 500
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def run_git(args, cwd, timeout=10):
|
|
29
|
+
"""执行 git 命令,返回 stdout 字符串。失败返回空字符串。"""
|
|
30
|
+
try:
|
|
31
|
+
result = subprocess.run(
|
|
32
|
+
["git"] + args,
|
|
33
|
+
capture_output=True, text=True, encoding="utf-8", errors="replace",
|
|
34
|
+
timeout=timeout, cwd=cwd
|
|
35
|
+
)
|
|
36
|
+
if result.returncode == 0:
|
|
37
|
+
return result.stdout
|
|
38
|
+
return ""
|
|
39
|
+
except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
|
|
40
|
+
return ""
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def parse_numstat(cwd):
|
|
44
|
+
"""通过 git diff HEAD --numstat 获取 tracked 文件变更统计。"""
|
|
45
|
+
output = run_git(["diff", "HEAD", "--numstat"], cwd)
|
|
46
|
+
files = []
|
|
47
|
+
for line in output.strip().splitlines():
|
|
48
|
+
if not line:
|
|
49
|
+
continue
|
|
50
|
+
parts = line.split("\t")
|
|
51
|
+
if len(parts) != 3:
|
|
52
|
+
continue
|
|
53
|
+
ins_str, del_str, file_path = parts
|
|
54
|
+
# binary 文件的 numstat 输出是 - - filename
|
|
55
|
+
insertions = int(ins_str) if ins_str != "-" else 0
|
|
56
|
+
deletions = int(del_str) if del_str != "-" else 0
|
|
57
|
+
files.append({
|
|
58
|
+
"file": file_path,
|
|
59
|
+
"insertions": insertions,
|
|
60
|
+
"deletions": deletions,
|
|
61
|
+
})
|
|
62
|
+
return files
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def get_untracked_files(cwd):
|
|
66
|
+
"""获取 untracked 文件列表。"""
|
|
67
|
+
output = run_git(["ls-files", "--others", "--exclude-standard"], cwd)
|
|
68
|
+
return [f for f in output.strip().splitlines() if f]
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def get_tracked_diff(cwd):
|
|
72
|
+
"""获取 tracked 文件的 diff 内容,截断到 MAX_TRACKED_DIFF_LINES 行。"""
|
|
73
|
+
output = run_git(["diff", "HEAD"], cwd, timeout=30)
|
|
74
|
+
lines = output.splitlines()
|
|
75
|
+
truncated = len(lines) > MAX_TRACKED_DIFF_LINES
|
|
76
|
+
if truncated:
|
|
77
|
+
lines = lines[:MAX_TRACKED_DIFF_LINES]
|
|
78
|
+
return "\n".join(lines), truncated
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def get_untracked_diff_and_stats(cwd, untracked_files):
|
|
82
|
+
"""获取 untracked 文件的 diff 和变更统计。
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
(changed_files, diff_content, truncated)
|
|
86
|
+
"""
|
|
87
|
+
changed_files = []
|
|
88
|
+
diff_lines = []
|
|
89
|
+
total_lines = 0
|
|
90
|
+
truncated = False
|
|
91
|
+
|
|
92
|
+
for file_path in untracked_files:
|
|
93
|
+
full_path = os.path.join(cwd, file_path)
|
|
94
|
+
try:
|
|
95
|
+
with open(full_path, "r", encoding="utf-8", errors="replace") as f:
|
|
96
|
+
lines = f.readlines()
|
|
97
|
+
except (OSError, IOError):
|
|
98
|
+
continue
|
|
99
|
+
|
|
100
|
+
insertions = len(lines)
|
|
101
|
+
if insertions > 0:
|
|
102
|
+
changed_files.append({
|
|
103
|
+
"file": file_path,
|
|
104
|
+
"insertions": insertions,
|
|
105
|
+
"deletions": 0,
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
# 构造 unified diff 格式的输出
|
|
109
|
+
file_diff_lines = [
|
|
110
|
+
f"diff --git a/{file_path} b/{file_path}",
|
|
111
|
+
"new file mode 100644",
|
|
112
|
+
f"--- /dev/null",
|
|
113
|
+
f"+++ b/{file_path}",
|
|
114
|
+
f"@@ -0,0 +1,{insertions} @@",
|
|
115
|
+
] + [f"+{line.rstrip()}" for line in lines]
|
|
116
|
+
|
|
117
|
+
# 检查总行数上限
|
|
118
|
+
remaining = MAX_UNTRACKED_DIFF_LINES - total_lines
|
|
119
|
+
if remaining <= 0:
|
|
120
|
+
truncated = True
|
|
121
|
+
break
|
|
122
|
+
if len(file_diff_lines) > remaining:
|
|
123
|
+
file_diff_lines = file_diff_lines[:remaining]
|
|
124
|
+
truncated = True
|
|
125
|
+
diff_lines.extend(file_diff_lines)
|
|
126
|
+
total_lines += len(file_diff_lines)
|
|
127
|
+
|
|
128
|
+
return changed_files, "\n".join(diff_lines), truncated
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def build_stat_summary(changed_files):
|
|
132
|
+
"""构建统计摘要字符串,如 '3 files, +130, -78'。"""
|
|
133
|
+
total_ins = sum(f["insertions"] for f in changed_files)
|
|
134
|
+
total_del = sum(f["deletions"] for f in changed_files)
|
|
135
|
+
n = len(changed_files)
|
|
136
|
+
return f"{n} file{'s' if n != 1 else ''}, +{total_ins}, -{total_del}"
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def main():
|
|
140
|
+
"""解析命令行参数并输出 workspace 的 git diff 摘要 JSON。"""
|
|
141
|
+
parser = argparse.ArgumentParser(description="获取 workspace 的 git diff 摘要")
|
|
142
|
+
parser.add_argument("--workspace", required=True, help="workspace 路径")
|
|
143
|
+
parser.add_argument("--max-diff-lines", type=int, default=MAX_TOTAL_DIFF_LINES,
|
|
144
|
+
help="diff 内容最大总行数")
|
|
145
|
+
args = parser.parse_args()
|
|
146
|
+
|
|
147
|
+
workspace = os.path.abspath(args.workspace)
|
|
148
|
+
if not os.path.isdir(workspace):
|
|
149
|
+
print(json.dumps({"error": f"workspace 路径不存在: {workspace}"}))
|
|
150
|
+
sys.exit(1)
|
|
151
|
+
|
|
152
|
+
max_total = args.max_diff_lines
|
|
153
|
+
|
|
154
|
+
try:
|
|
155
|
+
# 1. tracked 文件变更统计
|
|
156
|
+
tracked_files = parse_numstat(workspace)
|
|
157
|
+
|
|
158
|
+
# 2. untracked 文件列表
|
|
159
|
+
untracked_files = get_untracked_files(workspace)
|
|
160
|
+
|
|
161
|
+
# 3. tracked diff 内容
|
|
162
|
+
tracked_diff, tracked_truncated = get_tracked_diff(workspace)
|
|
163
|
+
|
|
164
|
+
# 4. untracked diff 和统计
|
|
165
|
+
untracked_changed, untracked_diff, untracked_truncated = \
|
|
166
|
+
get_untracked_diff_and_stats(workspace, untracked_files)
|
|
167
|
+
|
|
168
|
+
# 5. 合并 changed_files
|
|
169
|
+
all_changed = tracked_files + untracked_changed
|
|
170
|
+
|
|
171
|
+
# 6. 合并 diff 内容,检查总行数上限
|
|
172
|
+
tracked_lines = tracked_diff.splitlines() if tracked_diff else []
|
|
173
|
+
untracked_lines = untracked_diff.splitlines() if untracked_diff else []
|
|
174
|
+
all_lines = tracked_lines + untracked_lines
|
|
175
|
+
truncated = tracked_truncated or untracked_truncated or len(all_lines) > max_total
|
|
176
|
+
if len(all_lines) > max_total:
|
|
177
|
+
all_lines = all_lines[:max_total]
|
|
178
|
+
diff_content = "\n".join(all_lines)
|
|
179
|
+
|
|
180
|
+
# 7. 构建输出
|
|
181
|
+
has_changes = bool(all_changed) or bool(untracked_files)
|
|
182
|
+
output = {
|
|
183
|
+
"workspace": workspace,
|
|
184
|
+
"changed_files": all_changed,
|
|
185
|
+
"untracked_files": untracked_files,
|
|
186
|
+
"stat_summary": build_stat_summary(all_changed) if all_changed else "",
|
|
187
|
+
"has_changes": has_changes,
|
|
188
|
+
"diff_content": diff_content,
|
|
189
|
+
"truncated": truncated,
|
|
190
|
+
}
|
|
191
|
+
# 写入统一缓存
|
|
192
|
+
update_git_diff(workspace, output)
|
|
193
|
+
print(json.dumps(output, ensure_ascii=False))
|
|
194
|
+
|
|
195
|
+
except Exception as e:
|
|
196
|
+
print(json.dumps({"error": f"获取 diff 摘要异常: {type(e).__name__}: {e}"}))
|
|
197
|
+
sys.exit(1)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
if __name__ == "__main__":
|
|
201
|
+
main()
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"""Git 工具函数"""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import subprocess
|
|
5
|
+
import re
|
|
6
|
+
from typing import Dict, List, Any, Optional
|
|
7
|
+
|
|
8
|
+
from icafe.client import (
|
|
9
|
+
DEFAULT_MAX_COMMITS,
|
|
10
|
+
DEFAULT_MAX_DIFF_LINES,
|
|
11
|
+
GIT_LOG_FALSE_POSITIVE_PREFIXES,
|
|
12
|
+
)
|
|
13
|
+
from logger import get_logger
|
|
14
|
+
|
|
15
|
+
logger = get_logger()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _get_username_from_arg_or_env(username: Optional[str] = None) -> Optional[str]:
|
|
19
|
+
"""从命令行参数或环境变量获取用户名
|
|
20
|
+
|
|
21
|
+
优先使用传入的 username 参数(来自命令行 --username),
|
|
22
|
+
回退到环境变量 COMATE_USERNAME。
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
username: 通过命令行参数传入的用户名
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
用户名字符串;未设置或未替换时返回 None
|
|
29
|
+
"""
|
|
30
|
+
# 优先使用命令行参数
|
|
31
|
+
if username and 'COMATE_USERNAME' not in username:
|
|
32
|
+
return username
|
|
33
|
+
# 回退到环境变量
|
|
34
|
+
value = os.environ.get('COMATE_USERNAME', '')
|
|
35
|
+
if value and 'COMATE_USERNAME' not in value:
|
|
36
|
+
return value
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def get_current_user(username: Optional[str] = None) -> Optional[str]:
|
|
41
|
+
"""获取当前用户 ID
|
|
42
|
+
|
|
43
|
+
优先级:
|
|
44
|
+
1. 通过参数传入的用户名(来自命令行 --username)
|
|
45
|
+
2. 环境变量 COMATE_USERNAME
|
|
46
|
+
3. git config user.email 提取 @ 前的用户名
|
|
47
|
+
4. git config user.name
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
username: 通过命令行参数传入的用户名
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
用户 ID 字符串,如 "dongkexin01";无法获取时返回 None
|
|
54
|
+
"""
|
|
55
|
+
# 1. 优先从参数或环境变量获取用户名
|
|
56
|
+
comate_username = _get_username_from_arg_or_env(username)
|
|
57
|
+
logger.info("skill.md username: %s", comate_username)
|
|
58
|
+
if comate_username:
|
|
59
|
+
logger.info("用户识别: source=arg_or_env, user=%s", comate_username)
|
|
60
|
+
return comate_username
|
|
61
|
+
|
|
62
|
+
# 2. 从 git config user.email 提取
|
|
63
|
+
try:
|
|
64
|
+
result = subprocess.run(
|
|
65
|
+
["git", "config", "user.email"],
|
|
66
|
+
capture_output=True, text=True, encoding="utf-8", errors="replace",
|
|
67
|
+
timeout=5
|
|
68
|
+
)
|
|
69
|
+
if result.returncode == 0 and result.stdout.strip():
|
|
70
|
+
username = result.stdout.strip().split("@")[0]
|
|
71
|
+
if username:
|
|
72
|
+
logger.info("用户识别: source=email, user=%s", username)
|
|
73
|
+
return username
|
|
74
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
# 3. 回退到 git config user.name
|
|
78
|
+
try:
|
|
79
|
+
result = subprocess.run(
|
|
80
|
+
["git", "config", "user.name"],
|
|
81
|
+
capture_output=True, text=True, encoding="utf-8", errors="replace",
|
|
82
|
+
timeout=5
|
|
83
|
+
)
|
|
84
|
+
if result.returncode == 0 and result.stdout.strip():
|
|
85
|
+
username = result.stdout.strip()
|
|
86
|
+
logger.info("用户识别: source=name, user=%s", username)
|
|
87
|
+
return username
|
|
88
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
89
|
+
pass
|
|
90
|
+
|
|
91
|
+
logger.warning("无法获取用户 ID,所有来源均失败")
|
|
92
|
+
return None
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def get_git_diff_summary(max_diff_lines: int = DEFAULT_MAX_DIFF_LINES) -> Optional[Dict[str, Any]]:
|
|
96
|
+
"""获取当前工作区的 git diff 摘要
|
|
97
|
+
|
|
98
|
+
执行 git diff HEAD 获取所有未提交的变更(包括暂存和未暂存),
|
|
99
|
+
并提取变更文件列表和 diff 内容摘要。
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
max_diff_lines: diff 输出的最大行数,超出部分截断。默认 500。
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
包含 diff 信息的字典:
|
|
106
|
+
{
|
|
107
|
+
"changed_files": ["path/to/file1.ts", ...],
|
|
108
|
+
"stat_summary": "git diff --stat 输出的摘要行",
|
|
109
|
+
"diff_content": "截断后的 diff 全文",
|
|
110
|
+
"truncated": bool
|
|
111
|
+
}
|
|
112
|
+
非 git 仓库或无变更时返回 None
|
|
113
|
+
"""
|
|
114
|
+
try:
|
|
115
|
+
stat_result = subprocess.run(
|
|
116
|
+
["git", "diff", "HEAD", "--stat"],
|
|
117
|
+
capture_output=True, text=True, encoding="utf-8", errors="replace",
|
|
118
|
+
timeout=10
|
|
119
|
+
)
|
|
120
|
+
if stat_result.returncode != 0 or not stat_result.stdout.strip():
|
|
121
|
+
logger.info("git diff 无变更")
|
|
122
|
+
return None
|
|
123
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
124
|
+
logger.info("git diff 无变更")
|
|
125
|
+
return None
|
|
126
|
+
|
|
127
|
+
stat_lines = stat_result.stdout.strip().splitlines()
|
|
128
|
+
changed_files = []
|
|
129
|
+
for line in stat_lines[:-1]:
|
|
130
|
+
file_path = line.split("|")[0].strip()
|
|
131
|
+
if file_path:
|
|
132
|
+
changed_files.append(file_path)
|
|
133
|
+
stat_summary = stat_lines[-1].strip() if stat_lines else ""
|
|
134
|
+
|
|
135
|
+
if not changed_files:
|
|
136
|
+
logger.info("git diff 无变更")
|
|
137
|
+
return None
|
|
138
|
+
|
|
139
|
+
try:
|
|
140
|
+
diff_result = subprocess.run(
|
|
141
|
+
["git", "diff", "HEAD"],
|
|
142
|
+
capture_output=True, text=True, encoding="utf-8", errors="replace",
|
|
143
|
+
timeout=30
|
|
144
|
+
)
|
|
145
|
+
diff_content = diff_result.stdout if diff_result.returncode == 0 else ""
|
|
146
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
147
|
+
diff_content = ""
|
|
148
|
+
|
|
149
|
+
lines = diff_content.splitlines()
|
|
150
|
+
truncated = len(lines) > max_diff_lines
|
|
151
|
+
if truncated:
|
|
152
|
+
diff_content = "\n".join(lines[:max_diff_lines]) + "\n... (truncated)"
|
|
153
|
+
|
|
154
|
+
logger.info("git diff: %d 个文件, %s, truncated=%s", len(changed_files), stat_summary, truncated)
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
"changed_files": changed_files,
|
|
158
|
+
"stat_summary": stat_summary,
|
|
159
|
+
"diff_content": diff_content,
|
|
160
|
+
"truncated": truncated,
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def extract_space_ids_from_git_log(
|
|
165
|
+
max_commits: int = DEFAULT_MAX_COMMITS,
|
|
166
|
+
known_prefixes: Optional[List[str]] = None,
|
|
167
|
+
) -> List[str]:
|
|
168
|
+
"""从 git commit message 中提取 iCafe 空间前缀
|
|
169
|
+
|
|
170
|
+
优先使用已知的空间前缀列表进行精确匹配(支持含连字符的前缀如 DevOps-iScan),
|
|
171
|
+
回退到正则启发式提取。
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
max_commits: 扫描的最大提交数量
|
|
175
|
+
known_prefixes: 已知的空间 prefixCode 列表(来自 API)。
|
|
176
|
+
提供时优先用精确匹配;未提供时用正则启发式。
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
去重后的空间前缀列表(保留原始大小写),按提交次数降序排列。
|
|
180
|
+
非 git 仓库或无匹配时返回空列表。
|
|
181
|
+
"""
|
|
182
|
+
try:
|
|
183
|
+
result = subprocess.run(
|
|
184
|
+
["git", "log", "--oneline", "-n", str(max_commits)],
|
|
185
|
+
capture_output=True, text=True, encoding="utf-8", errors="replace",
|
|
186
|
+
timeout=10
|
|
187
|
+
)
|
|
188
|
+
if result.returncode != 0:
|
|
189
|
+
return []
|
|
190
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
191
|
+
return []
|
|
192
|
+
|
|
193
|
+
log_text = result.stdout.strip()
|
|
194
|
+
if not log_text:
|
|
195
|
+
return []
|
|
196
|
+
|
|
197
|
+
# 策略 1:用已知前缀精确匹配 "前缀-数字"
|
|
198
|
+
if known_prefixes:
|
|
199
|
+
counter: Dict[str, int] = {}
|
|
200
|
+
for prefix in known_prefixes:
|
|
201
|
+
pat = re.compile(re.escape(prefix) + r'-\d+', re.IGNORECASE)
|
|
202
|
+
count = len(pat.findall(log_text))
|
|
203
|
+
if count > 0:
|
|
204
|
+
counter[prefix] = count
|
|
205
|
+
if counter:
|
|
206
|
+
sorted_prefixes = sorted(counter, key=counter.get, reverse=True)
|
|
207
|
+
logger.info("git log 提取前缀: %s, 策略=精确匹配", sorted_prefixes)
|
|
208
|
+
return sorted_prefixes
|
|
209
|
+
|
|
210
|
+
# 策略 2:正则启发式兜底(无已知前缀或精确匹配无结果)
|
|
211
|
+
# 支持含连字符的复合前缀,如 DevOps-iScan-36261、TPUE-EE-2-22
|
|
212
|
+
# 贪婪匹配:最后一个 -数字 是卡片 ID,前面所有部分都是空间前缀
|
|
213
|
+
pattern = re.compile(r'\b([a-zA-Z][a-zA-Z0-9_]*(?:-[a-zA-Z0-9_]+)*)-(\d+)\b')
|
|
214
|
+
counter_fallback: Dict[str, int] = {}
|
|
215
|
+
|
|
216
|
+
for line in log_text.splitlines():
|
|
217
|
+
for match in pattern.finditer(line):
|
|
218
|
+
raw_prefix = match.group(1)
|
|
219
|
+
prefix_lower = raw_prefix.lower()
|
|
220
|
+
# 检查前缀首段是否是常见误报(如 feat-xxx、fix-xxx)
|
|
221
|
+
first_segment = raw_prefix.split('-', 1)[0].lower()
|
|
222
|
+
if first_segment in GIT_LOG_FALSE_POSITIVE_PREFIXES:
|
|
223
|
+
continue
|
|
224
|
+
if len(raw_prefix) <= 1:
|
|
225
|
+
continue
|
|
226
|
+
counter_fallback[prefix_lower] = counter_fallback.get(prefix_lower, 0) + 1
|
|
227
|
+
|
|
228
|
+
sorted_prefixes = sorted(counter_fallback, key=counter_fallback.get, reverse=True)
|
|
229
|
+
logger.info("git log 提取前缀: %s, 策略=正则启发式", sorted_prefixes)
|
|
230
|
+
return sorted_prefixes
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""iCafe Card Query Client - 卡片条件查询助手
|
|
2
|
+
|
|
3
|
+
提供 iCafe 平台卡片条件查询相关的 API 接口封装,
|
|
4
|
+
支持通过 IQL 表达式、卡片 ID、空间等维度灵活查询卡片信息。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .client import (
|
|
8
|
+
ICafeQueryConfig,
|
|
9
|
+
ICafeQueryClient,
|
|
10
|
+
# 常量
|
|
11
|
+
ICAFE_BASE_URL,
|
|
12
|
+
FARSEER_BASE_URL,
|
|
13
|
+
DEFAULT_TIMEOUT,
|
|
14
|
+
DEFAULT_LOOKBACK_DAYS,
|
|
15
|
+
DEFAULT_MAX_RECORDS,
|
|
16
|
+
DEFAULT_MAX_COMMITS,
|
|
17
|
+
DEFAULT_MAX_DIFF_LINES,
|
|
18
|
+
GIT_LOG_FALSE_POSITIVE_PREFIXES,
|
|
19
|
+
ISSUE_TYPE_MAP,
|
|
20
|
+
ISSUE_TYPE_NAME_MAP,
|
|
21
|
+
)
|
|
22
|
+
from git_utils import (
|
|
23
|
+
get_current_user,
|
|
24
|
+
get_git_diff_summary,
|
|
25
|
+
extract_space_ids_from_git_log,
|
|
26
|
+
)
|
|
27
|
+
from .matching import (
|
|
28
|
+
auto_detect_space,
|
|
29
|
+
find_matching_card,
|
|
30
|
+
match_diff_to_cards,
|
|
31
|
+
build_type_filter_iql,
|
|
32
|
+
format_card_summary,
|
|
33
|
+
format_query_result,
|
|
34
|
+
)
|
|
35
|
+
from .farseer import get_binding_card_types
|
|
36
|
+
|
|
37
|
+
__all__ = [
|
|
38
|
+
# 配置和客户端
|
|
39
|
+
'ICafeQueryConfig',
|
|
40
|
+
'ICafeQueryClient',
|
|
41
|
+
# 常量
|
|
42
|
+
'ICAFE_BASE_URL',
|
|
43
|
+
'FARSEER_BASE_URL',
|
|
44
|
+
'DEFAULT_TIMEOUT',
|
|
45
|
+
'DEFAULT_LOOKBACK_DAYS',
|
|
46
|
+
'DEFAULT_MAX_RECORDS',
|
|
47
|
+
'DEFAULT_MAX_COMMITS',
|
|
48
|
+
'DEFAULT_MAX_DIFF_LINES',
|
|
49
|
+
'GIT_LOG_FALSE_POSITIVE_PREFIXES',
|
|
50
|
+
'ISSUE_TYPE_MAP',
|
|
51
|
+
'ISSUE_TYPE_NAME_MAP',
|
|
52
|
+
# Git 工具
|
|
53
|
+
'get_current_user',
|
|
54
|
+
'get_git_diff_summary',
|
|
55
|
+
'extract_space_ids_from_git_log',
|
|
56
|
+
# 自动检测和匹配
|
|
57
|
+
'auto_detect_space',
|
|
58
|
+
'find_matching_card',
|
|
59
|
+
'match_diff_to_cards',
|
|
60
|
+
'build_type_filter_iql',
|
|
61
|
+
# 格式化
|
|
62
|
+
'format_card_summary',
|
|
63
|
+
'format_query_result',
|
|
64
|
+
# Farseer API
|
|
65
|
+
'get_binding_card_types',
|
|
66
|
+
]
|