Skip to content

Commit ae6949b

Browse files
frankxaiclaude
andcommitted
feat(ci): ACOS health check + ecosystem monitor + QUICKSTART.md
- Daily health check: validates skills, commands, hooks syntax, cross-references - Weekly ecosystem monitor: tracks stars/forks/issues across 14 core repos - QUICKSTART.md: 2-minute install guide (was missing, README referenced it) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6aba189 commit ae6949b

3 files changed

Lines changed: 249 additions & 119 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: ACOS Health Check
2+
3+
on:
4+
schedule:
5+
- cron: '0 6 * * *'
6+
push:
7+
branches: [main]
8+
paths:
9+
- '.claude/skills/**'
10+
- '.claude/commands/**'
11+
- '.claude/agents/**'
12+
- '.claude/hooks/**'
13+
workflow_dispatch:
14+
15+
jobs:
16+
health-check:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- name: Count assets
22+
id: count
23+
run: |
24+
SKILLS=$(find .claude/skills -name "SKILL.md" 2>/dev/null | wc -l)
25+
COMMANDS=$(find .claude/commands -name "*.md" 2>/dev/null | wc -l)
26+
AGENTS=$(find .claude/agents -name "*.md" 2>/dev/null | wc -l)
27+
HOOKS=$(find .claude/hooks \( -name "*.sh" -o -name "*.js" -o -name "*.ts" \) 2>/dev/null | wc -l)
28+
echo "skills=$SKILLS" >> "$GITHUB_OUTPUT"
29+
echo "commands=$COMMANDS" >> "$GITHUB_OUTPUT"
30+
echo "agents=$AGENTS" >> "$GITHUB_OUTPUT"
31+
echo "hooks=$HOOKS" >> "$GITHUB_OUTPUT"
32+
echo "Skills: $SKILLS | Commands: $COMMANDS | Agents: $AGENTS | Hooks: $HOOKS"
33+
34+
- name: Validate skills
35+
run: |
36+
ERRORS=0
37+
find .claude/skills -name "SKILL.md" | while read -r skill; do
38+
NAME=$(dirname "$skill" | xargs basename)
39+
if [ ! -s "$skill" ]; then
40+
echo "ERROR: $NAME — empty SKILL.md"
41+
ERRORS=$((ERRORS + 1))
42+
fi
43+
WORDS=$(wc -w < "$skill")
44+
if [ "$WORDS" -lt 50 ]; then
45+
echo "WARN: $NAME — $WORDS words (stub)"
46+
fi
47+
done
48+
49+
- name: Check hook syntax
50+
run: |
51+
find .claude/hooks -name "*.sh" 2>/dev/null | while read -r hook; do
52+
NAME=$(basename "$hook")
53+
if bash -n "$hook" 2>/dev/null; then
54+
echo "OK: $NAME"
55+
else
56+
echo "ERROR: $NAME — syntax error"
57+
fi
58+
done
59+
60+
- name: Cross-reference check
61+
run: |
62+
if [ -f ".claude/skills/skill-rules.json" ]; then
63+
python3 << 'PYEOF'
64+
import json, os
65+
rules = json.load(open('.claude/skills/skill-rules.json'))
66+
categories = rules.get('categories', {})
67+
missing = 0
68+
for cat, data in categories.items():
69+
for s in data.get('skills', []):
70+
path = os.path.join('.claude/skills', s, 'SKILL.md')
71+
if not os.path.exists(path):
72+
print(f'WARN: skill-rules references "{s}" but not found')
73+
missing += 1
74+
print(f'Cross-ref check: {missing} missing references')
75+
PYEOF
76+
fi
77+
78+
- name: Generate health badge data
79+
if: always()
80+
env:
81+
SKILLS: ${{ steps.count.outputs.skills }}
82+
COMMANDS: ${{ steps.count.outputs.commands }}
83+
AGENTS: ${{ steps.count.outputs.agents }}
84+
HOOKS: ${{ steps.count.outputs.hooks }}
85+
run: |
86+
TOTAL=$((SKILLS + COMMANDS + AGENTS + HOOKS))
87+
echo "ACOS v11 Health: $TOTAL total assets ($SKILLS skills, $COMMANDS commands, $AGENTS agents, $HOOKS hooks)"
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
name: Ecosystem Monitor
2+
3+
on:
4+
schedule:
5+
- cron: '0 8 * * 1'
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
monitor:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Install GitHub CLI
18+
run: |
19+
type -p gh >/dev/null 2>&1 && exit 0
20+
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
21+
sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
22+
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
23+
sudo apt update && sudo apt install gh -y
24+
25+
- name: Collect ecosystem stats
26+
env:
27+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
28+
run: |
29+
python3 << 'PYEOF'
30+
import subprocess, json, datetime
31+
32+
ECOSYSTEM = [
33+
"agentic-creator-os",
34+
"agentic-creator-skills",
35+
"frankx.ai-vercel-website",
36+
"FrankX",
37+
"arcanea",
38+
"Starlight-Intelligence-System",
39+
"production-agent-patterns",
40+
"ai-architect-academy",
41+
"claude-skills-library",
42+
"vibe-os",
43+
"mcp-doctor",
44+
"arcanea-code",
45+
"arcanea-flow",
46+
"claude-codex-gemini-opencode-settings",
47+
]
48+
49+
report = []
50+
report.append("# ACOS Ecosystem Intelligence Report")
51+
report.append(f"**Generated**: {datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M UTC')}")
52+
report.append("")
53+
report.append("| Repo | Stars | Forks | Issues | Last Push |")
54+
report.append("|------|-------|-------|--------|-----------|")
55+
56+
total_stars = 0
57+
total_forks = 0
58+
59+
for repo in ECOSYSTEM:
60+
try:
61+
result = subprocess.run(
62+
['gh', 'api', f'repos/frankxai/{repo}',
63+
'--jq', '{s:.stargazers_count,f:.forks_count,i:.open_issues_count,p:.pushed_at}'],
64+
capture_output=True, text=True, timeout=15
65+
)
66+
info = json.loads(result.stdout)
67+
s, f, i = info.get('s',0), info.get('f',0), info.get('i',0)
68+
p = info.get('p','?')[:10]
69+
total_stars += s
70+
total_forks += f
71+
report.append(f"| {repo} | {s} | {f} | {i} | {p} |")
72+
except:
73+
report.append(f"| {repo} | ? | ? | ? | error |")
74+
75+
report.append(f"| **TOTAL** | **{total_stars}** | **{total_forks}** | | |")
76+
report.append("")
77+
78+
# Account-wide summary
79+
result = subprocess.run(
80+
['gh', 'repo', 'list', 'frankxai', '--limit', '200',
81+
'--json', 'name,isArchived,stargazerCount'],
82+
capture_output=True, text=True
83+
)
84+
all_repos = json.loads(result.stdout) if result.stdout else []
85+
active = [r for r in all_repos if not r.get('isArchived')]
86+
all_stars = sum(r.get('stargazerCount', 0) for r in active)
87+
88+
report.append("## Account Summary")
89+
report.append(f"- Active repos: {len(active)}")
90+
report.append(f"- Archived: {len(all_repos) - len(active)}")
91+
report.append(f"- Total stars: {all_stars}")
92+
93+
import os
94+
os.makedirs('docs', exist_ok=True)
95+
with open('docs/ecosystem-report.md', 'w') as f:
96+
f.write('\n'.join(report))
97+
print('\n'.join(report))
98+
PYEOF
99+
100+
- name: Commit report
101+
run: |
102+
git config user.name "ACOS Bot"
103+
git config user.email "acos@frankx.ai"
104+
git add docs/ecosystem-report.md
105+
git diff --staged --quiet || git commit -m "chore(docs): weekly ecosystem report [skip ci]"
106+
git push

0 commit comments

Comments
 (0)