项目文件夹

文件
AI不止语 187c7e7d9e feat: 同步上游 GIS(13) + Security(10) 两个新部门并翻译为中文 (#86)
上游 783f6a7 之后新增了 gis/ 与 security/ 两个部门(对应 #572),本次同步翻译:
- gis/ 13 个:GIS 分析师、空间数据工程师/科学家、地理处理、Web GIS、GeoAI/ML、
  无人机实景测绘、BIM/GIS、地图制图、三维场景、质检、解决方案、技术顾问
- security/ 10 个:应用安全、安全架构、云安全、区块链审计、合规审计、事件响应、
  渗透测试、高级安全运营、威胁检测、威胁情报
- 智能体总数 216 → 239,英文翻译 165 → 188,部门 → 含 GIS/安全
- 更新 CATALOG / AGENT-LIST / UPSTREAM / README(中文+繁体)
- convert.sh / install.sh / lint-agents.sh 的部门目录列表加入 gis、security

注:上游同期还有零散新增 agent(engineering/specialized 等)尚未同步,已在 UPSTREAM.md 记为 TODO。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 04:16:22 +08:00

207 行
5.0 KiB
Bash
可执行文件

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
#!/usr/bin/env bash
#
# lint-agents.sh — 验证智能体 Markdown 文件
# 1. YAML frontmatter 必须包含 name, description, color, emoji (ERROR)
# 2. 推荐章节仅做警告 (WARN)
# 3. 文件必须有实质内容
#
# Usage: ./scripts/lint-agents.sh [file ...]
# If no files given, scans all agent directories.
set -euo pipefail
# 与 scripts/convert.sh 中的 AGENT_DIRS 保持同步
AGENT_DIRS=(
academic
design
engineering
finance
game-development
gis
hr
legal
marketing
paid-media
product
project-management
sales
security
spatial-computing
specialized
strategy
supply-chain
support
testing
)
REQUIRED_FRONTMATTER=("name" "description" "color" "emoji")
# 中英文任一即可——本仓库以中文为主,英文版用于上游同步
RECOMMENDED_SECTION_PATTERNS=(
"身份|记忆|Identity"
"核心使命|Core Mission"
"关键规则|Critical Rules"
)
errors=0
warnings=0
classify_header_target() {
local header_lower="$1"
# 中文版支持中英文章节标题
if [[ "$header_lower" =~ 身份 ]] ||
[[ "$header_lower" =~ identity ]] ||
[[ "$header_lower" =~ learning.*memory ]] ||
[[ "$header_lower" =~ 记忆 ]] ||
[[ "$header_lower" =~ communication ]] ||
[[ "$header_lower" =~ 沟通 ]] ||
[[ "$header_lower" =~ critical.rule ]] ||
[[ "$header_lower" =~ 关键规则 ]] ||
[[ "$header_lower" =~ rules.you.must.follow ]] ||
[[ "$header_lower" =~ 核心使命 ]] ||
[[ "$header_lower" =~ core.mission ]]; then
printf 'soul'
else
printf 'agents'
fi
}
lint_file() {
local file="$1"
if [[ ! -f "$file" ]]; then
echo "ERROR $file: 文件不存在"
errors=$((errors + 1))
return
fi
# 1. 检查 frontmatter 分隔符
local first_line
first_line=$(head -1 "$file")
if [[ "$first_line" != "---" ]]; then
echo "ERROR $file: 缺少 frontmatter 开头的 ---"
errors=$((errors + 1))
return
fi
# 提取 frontmatter(在两个 --- 之间)
local frontmatter
frontmatter=$(awk 'NR==1{next} /^---$/{exit} {print}' "$file")
if [[ -z "$frontmatter" ]]; then
echo "ERROR $file: frontmatter 为空或格式错误"
errors=$((errors + 1))
return
fi
# 2. 检查必须的 frontmatter 字段
for field in "${REQUIRED_FRONTMATTER[@]}"; do
if ! echo "$frontmatter" | grep -qE "^${field}:"; then
echo "ERROR $file: 缺少 frontmatter 字段 '${field}'"
errors=$((errors + 1))
fi
done
# 3. 检查推荐章节(仅警告)
local body
body=$(awk 'BEGIN{n=0} /^---$/{n++; next} n>=2{print}' "$file")
for pattern in "${RECOMMENDED_SECTION_PATTERNS[@]}"; do
if ! echo "$body" | grep -qiE "$pattern"; then
echo "WARN $file: 缺少推荐章节 (匹配: ${pattern})"
warnings=$((warnings + 1))
fi
done
# 4. 检查文件有实质内容(awk 处理 macOS/BSD wc 前导空格)
local word_count
word_count=$(echo "$body" | wc -w | awk '{print $1}')
if [[ "${word_count:-0}" -lt 50 ]]; then
echo "WARN $file: 正文内容过短(< 50 词)"
warnings=$((warnings + 1))
fi
# 5. 检查章节标题分类
local soul_headers=0
local agents_headers=0
while IFS= read -r line; do
if [[ "$line" =~ ^##[[:space:]] ]]; then
local header_lower
header_lower=$(printf '%s' "$line" | tr '[:upper:]' '[:lower:]')
local target
target=$(classify_header_target "$header_lower")
if [[ "$target" == "soul" ]]; then
soul_headers=$((soul_headers + 1))
else
agents_headers=$((agents_headers + 1))
fi
fi
done <<< "$body"
if [[ $soul_headers -eq 0 ]]; then
echo "WARN $file: 没有映射到 SOUL.md 的章节标题"
warnings=$((warnings + 1))
fi
if [[ $agents_headers -eq 0 ]]; then
echo "WARN $file: 没有映射到 AGENTS.md 的章节标题"
warnings=$((warnings + 1))
fi
}
# 非角色文件(排除 lint 检查)
EXCLUDE_FILES=(
strategy/QUICKSTART.md
strategy/EXECUTIVE-BRIEF.md
strategy/nexus-strategy.md
)
# 收集需要检查的文件
files=()
if [[ $# -gt 0 ]]; then
files=("$@")
else
for dir in "${AGENT_DIRS[@]}"; do
if [[ -d "$dir" ]]; then
# 只扫描一级目录下的 .md 文件,跳过子目录(如 strategy/playbooks/
while IFS= read -r f; do
files+=("$f")
done < <(find "$dir" -maxdepth 1 -name "*.md" -type f | sort)
fi
done
# 排除非角色文件
for i in "${!files[@]}"; do
for exc in "${EXCLUDE_FILES[@]}"; do
if [[ "${files[$i]}" == "$exc" ]]; then
unset 'files[i]'
break
fi
done
done
# 重建索引
files=("${files[@]}")
fi
if [[ ${#files[@]} -eq 0 ]]; then
echo "未找到智能体文件。"
exit 1
fi
echo "正在检查 ${#files[@]} 个智能体文件..."
echo ""
for file in "${files[@]}"; do
lint_file "$file"
done
echo ""
echo "结果: ${errors} 个错误, ${warnings} 个警告, 共 ${#files[@]} 个文件。"
if [[ $errors -gt 0 ]]; then
echo "❌ 未通过:合并前请修复以上错误。"
exit 1
else
echo "✅ 通过"
exit 0
fi