@neyugn/agent-kits 0.1.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.
- package/LICENSE +21 -0
- package/README.md +514 -0
- package/README.vi.md +410 -0
- package/README.zh.md +410 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +422 -0
- package/kits/coder/ARCHITECTURE.md +289 -0
- package/kits/coder/agents/ai-engineer.md +344 -0
- package/kits/coder/agents/backend-specialist.md +270 -0
- package/kits/coder/agents/cloud-architect.md +363 -0
- package/kits/coder/agents/code-reviewer.md +284 -0
- package/kits/coder/agents/data-engineer.md +401 -0
- package/kits/coder/agents/database-specialist.md +251 -0
- package/kits/coder/agents/debugger.md +209 -0
- package/kits/coder/agents/devops-engineer.md +281 -0
- package/kits/coder/agents/documentation-writer.md +296 -0
- package/kits/coder/agents/frontend-specialist.md +298 -0
- package/kits/coder/agents/i18n-specialist.md +348 -0
- package/kits/coder/agents/integration-specialist.md +314 -0
- package/kits/coder/agents/mobile-developer.md +271 -0
- package/kits/coder/agents/multi-tenant-architect.md +281 -0
- package/kits/coder/agents/orchestrator.md +263 -0
- package/kits/coder/agents/performance-analyst.md +327 -0
- package/kits/coder/agents/project-planner.md +277 -0
- package/kits/coder/agents/queue-specialist.md +282 -0
- package/kits/coder/agents/realtime-specialist.md +267 -0
- package/kits/coder/agents/security-auditor.md +253 -0
- package/kits/coder/agents/test-engineer.md +315 -0
- package/kits/coder/agents/ux-researcher.md +388 -0
- package/kits/coder/rules/.cursorrules +287 -0
- package/kits/coder/rules/CLAUDE.md +287 -0
- package/kits/coder/rules/CODEX.md +287 -0
- package/kits/coder/rules/GEMINI.md +287 -0
- package/kits/coder/scripts/checklist.py +318 -0
- package/kits/coder/scripts/kit_status.py +292 -0
- package/kits/coder/scripts/skills_manager.py +243 -0
- package/kits/coder/scripts/verify_all.py +391 -0
- package/kits/coder/skills/accessibility-patterns/SKILL.md +372 -0
- package/kits/coder/skills/accessibility-patterns/scripts/a11y_checker.py +211 -0
- package/kits/coder/skills/ai-rag-patterns/SKILL.md +444 -0
- package/kits/coder/skills/api-patterns/SKILL.md +316 -0
- package/kits/coder/skills/api-patterns/assets/.gitkeep +1 -0
- package/kits/coder/skills/api-patterns/references/deep-dive.md +21 -0
- package/kits/coder/skills/api-patterns/scripts/api_validator.py +253 -0
- package/kits/coder/skills/api-patterns/scripts/validate.py +56 -0
- package/kits/coder/skills/auth-patterns/SKILL.md +267 -0
- package/kits/coder/skills/aws-patterns/SKILL.md +576 -0
- package/kits/coder/skills/brainstorming/SKILL.md +370 -0
- package/kits/coder/skills/brainstorming/assets/.gitkeep +1 -0
- package/kits/coder/skills/brainstorming/references/deep-dive.md +21 -0
- package/kits/coder/skills/brainstorming/scripts/validate.py +56 -0
- package/kits/coder/skills/clean-code/SKILL.md +240 -0
- package/kits/coder/skills/clean-code/assets/.gitkeep +1 -0
- package/kits/coder/skills/clean-code/references/deep-dive.md +21 -0
- package/kits/coder/skills/clean-code/scripts/lint_runner.py +186 -0
- package/kits/coder/skills/clean-code/scripts/validate.py +56 -0
- package/kits/coder/skills/database-design/SKILL.md +255 -0
- package/kits/coder/skills/database-design/assets/.gitkeep +1 -0
- package/kits/coder/skills/database-design/references/deep-dive.md +21 -0
- package/kits/coder/skills/database-design/scripts/schema_validator.py +272 -0
- package/kits/coder/skills/database-design/scripts/validate.py +56 -0
- package/kits/coder/skills/docker-patterns/SKILL.md +240 -0
- package/kits/coder/skills/documentation-templates/SKILL.md +441 -0
- package/kits/coder/skills/e2e-testing/SKILL.md +457 -0
- package/kits/coder/skills/flutter-patterns/SKILL.md +330 -0
- package/kits/coder/skills/frontend-design/SKILL.md +127 -0
- package/kits/coder/skills/github-actions/SKILL.md +349 -0
- package/kits/coder/skills/gitlab-ci-patterns/SKILL.md +466 -0
- package/kits/coder/skills/graphql-patterns/SKILL.md +558 -0
- package/kits/coder/skills/i18n-localization/SKILL.md +345 -0
- package/kits/coder/skills/i18n-localization/scripts/i18n_checker.py +267 -0
- package/kits/coder/skills/kubernetes-patterns/SKILL.md +357 -0
- package/kits/coder/skills/mermaid-diagrams/SKILL.md +351 -0
- package/kits/coder/skills/mobile-design/SKILL.md +305 -0
- package/kits/coder/skills/monitoring-observability/SKILL.md +458 -0
- package/kits/coder/skills/multi-tenancy/SKILL.md +317 -0
- package/kits/coder/skills/multi-tenancy/assets/.gitkeep +1 -0
- package/kits/coder/skills/multi-tenancy/references/deep-dive.md +21 -0
- package/kits/coder/skills/multi-tenancy/scripts/validate.py +56 -0
- package/kits/coder/skills/nodejs-best-practices/SKILL.md +220 -0
- package/kits/coder/skills/performance-profiling/SKILL.md +333 -0
- package/kits/coder/skills/performance-profiling/assets/.gitkeep +1 -0
- package/kits/coder/skills/performance-profiling/references/deep-dive.md +21 -0
- package/kits/coder/skills/performance-profiling/scripts/validate.py +56 -0
- package/kits/coder/skills/plan-writing/SKILL.md +360 -0
- package/kits/coder/skills/plan-writing/assets/.gitkeep +1 -0
- package/kits/coder/skills/plan-writing/references/deep-dive.md +21 -0
- package/kits/coder/skills/plan-writing/scripts/validate.py +56 -0
- package/kits/coder/skills/postgres-patterns/SKILL.md +361 -0
- package/kits/coder/skills/prompt-engineering/SKILL.md +277 -0
- package/kits/coder/skills/queue-patterns/SKILL.md +359 -0
- package/kits/coder/skills/queue-patterns/assets/.gitkeep +1 -0
- package/kits/coder/skills/queue-patterns/references/deep-dive.md +21 -0
- package/kits/coder/skills/queue-patterns/scripts/validate.py +56 -0
- package/kits/coder/skills/react-native-patterns/SKILL.md +393 -0
- package/kits/coder/skills/react-patterns/SKILL.md +319 -0
- package/kits/coder/skills/realtime-patterns/SKILL.md +506 -0
- package/kits/coder/skills/realtime-patterns/assets/.gitkeep +1 -0
- package/kits/coder/skills/realtime-patterns/references/deep-dive.md +21 -0
- package/kits/coder/skills/realtime-patterns/scripts/validate.py +56 -0
- package/kits/coder/skills/redis-patterns/SKILL.md +484 -0
- package/kits/coder/skills/security-fundamentals/SKILL.md +363 -0
- package/kits/coder/skills/security-fundamentals/assets/.gitkeep +1 -0
- package/kits/coder/skills/security-fundamentals/references/deep-dive.md +21 -0
- package/kits/coder/skills/security-fundamentals/scripts/security_scan.py +326 -0
- package/kits/coder/skills/security-fundamentals/scripts/validate.py +56 -0
- package/kits/coder/skills/seo-patterns/SKILL.md +262 -0
- package/kits/coder/skills/seo-patterns/scripts/seo_checker.py +211 -0
- package/kits/coder/skills/systematic-debugging/SKILL.md +478 -0
- package/kits/coder/skills/systematic-debugging/assets/.gitkeep +1 -0
- package/kits/coder/skills/systematic-debugging/references/deep-dive.md +21 -0
- package/kits/coder/skills/systematic-debugging/scripts/validate.py +56 -0
- package/kits/coder/skills/tailwind-patterns/SKILL.md +395 -0
- package/kits/coder/skills/terraform-patterns/SKILL.md +470 -0
- package/kits/coder/skills/testing-patterns/SKILL.md +285 -0
- package/kits/coder/skills/testing-patterns/assets/.gitkeep +1 -0
- package/kits/coder/skills/testing-patterns/references/deep-dive.md +21 -0
- package/kits/coder/skills/testing-patterns/scripts/test_runner.py +219 -0
- package/kits/coder/skills/testing-patterns/scripts/validate.py +56 -0
- package/kits/coder/skills/typescript-patterns/SKILL.md +417 -0
- package/kits/coder/skills/ui-ux-pro-max/SKILL.md +364 -0
- package/kits/coder/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/kits/coder/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/kits/coder/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/kits/coder/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/kits/coder/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/kits/coder/skills/ui-ux-pro-max/data/prompts.csv +24 -0
- package/kits/coder/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/kits/coder/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/kits/coder/skills/ui-ux-pro-max/data/styles.csv +59 -0
- package/kits/coder/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/kits/coder/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/kits/coder/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/kits/coder/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/kits/coder/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-314.pyc +0 -0
- package/kits/coder/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-314.pyc +0 -0
- package/kits/coder/skills/ui-ux-pro-max/scripts/core.py +257 -0
- package/kits/coder/skills/ui-ux-pro-max/scripts/design_system.py +488 -0
- package/kits/coder/skills/ui-ux-pro-max/scripts/search.py +76 -0
- package/kits/coder/workflows/.gitkeep +20 -0
- package/kits/coder/workflows/create.md +152 -0
- package/kits/coder/workflows/debug.md +223 -0
- package/kits/coder/workflows/deploy.md +283 -0
- package/kits/coder/workflows/orchestrate.md +243 -0
- package/kits/coder/workflows/plan.md +134 -0
- package/kits/coder/workflows/test.md +237 -0
- package/kits/coder/workflows/ui-ux-pro-max.md +109 -0
- package/package.json +49 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
AGT-Kit Status Reporter
|
|
4
|
+
========================
|
|
5
|
+
|
|
6
|
+
Reports the status of the AGT-Kit installation:
|
|
7
|
+
- Lists all agents and their assigned skills
|
|
8
|
+
- Lists all available skills
|
|
9
|
+
- Lists all workflows
|
|
10
|
+
- Validates kit integrity
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
python .agent/scripts/kit_status.py
|
|
14
|
+
python .agent/scripts/kit_status.py --validate
|
|
15
|
+
python .agent/scripts/kit_status.py --json
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import sys
|
|
19
|
+
import argparse
|
|
20
|
+
import json
|
|
21
|
+
import re
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from typing import Dict, List, Any
|
|
24
|
+
|
|
25
|
+
# ANSI colors
|
|
26
|
+
class Colors:
|
|
27
|
+
HEADER = '\033[95m'
|
|
28
|
+
BLUE = '\033[94m'
|
|
29
|
+
CYAN = '\033[96m'
|
|
30
|
+
GREEN = '\033[92m'
|
|
31
|
+
YELLOW = '\033[93m'
|
|
32
|
+
RED = '\033[91m'
|
|
33
|
+
ENDC = '\033[0m'
|
|
34
|
+
BOLD = '\033[1m'
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def print_header(text: str):
|
|
38
|
+
print(f"\n{Colors.BOLD}{Colors.CYAN}{'='*60}{Colors.ENDC}")
|
|
39
|
+
print(f"{Colors.BOLD}{Colors.CYAN}{text.center(60)}{Colors.ENDC}")
|
|
40
|
+
print(f"{Colors.BOLD}{Colors.CYAN}{'='*60}{Colors.ENDC}\n")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def print_success(text: str):
|
|
44
|
+
print(f"{Colors.GREEN}ā
{text}{Colors.ENDC}")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def print_warning(text: str):
|
|
48
|
+
print(f"{Colors.YELLOW}ā ļø {text}{Colors.ENDC}")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def print_error(text: str):
|
|
52
|
+
print(f"{Colors.RED}ā {text}{Colors.ENDC}")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def find_kit_root() -> Path:
|
|
56
|
+
"""Find the .agent directory from current location or script location."""
|
|
57
|
+
# Try from script location
|
|
58
|
+
script_dir = Path(__file__).parent
|
|
59
|
+
agent_dir = script_dir.parent
|
|
60
|
+
|
|
61
|
+
if (agent_dir / "ARCHITECTURE.md").exists():
|
|
62
|
+
return agent_dir
|
|
63
|
+
|
|
64
|
+
# Try from current working directory
|
|
65
|
+
cwd = Path.cwd()
|
|
66
|
+
for parent in [cwd, *cwd.parents]:
|
|
67
|
+
agent_dir = parent / ".agent"
|
|
68
|
+
if agent_dir.exists() and (agent_dir / "ARCHITECTURE.md").exists():
|
|
69
|
+
return agent_dir
|
|
70
|
+
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def parse_frontmatter(file_path: Path) -> Dict[str, Any]:
|
|
75
|
+
"""Parse YAML frontmatter from a markdown file."""
|
|
76
|
+
try:
|
|
77
|
+
content = file_path.read_text()
|
|
78
|
+
if content.startswith('---'):
|
|
79
|
+
parts = content.split('---', 2)
|
|
80
|
+
if len(parts) >= 3:
|
|
81
|
+
frontmatter = parts[1].strip()
|
|
82
|
+
result = {}
|
|
83
|
+
for line in frontmatter.split('\n'):
|
|
84
|
+
if ':' in line:
|
|
85
|
+
key, value = line.split(':', 1)
|
|
86
|
+
result[key.strip()] = value.strip()
|
|
87
|
+
return result
|
|
88
|
+
except:
|
|
89
|
+
pass
|
|
90
|
+
return {}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def get_agents(agent_dir: Path) -> List[Dict[str, Any]]:
|
|
94
|
+
"""Get list of agents with their metadata."""
|
|
95
|
+
agents = []
|
|
96
|
+
agents_path = agent_dir / "agents"
|
|
97
|
+
|
|
98
|
+
if not agents_path.exists():
|
|
99
|
+
return agents
|
|
100
|
+
|
|
101
|
+
for agent_file in agents_path.glob("*.md"):
|
|
102
|
+
frontmatter = parse_frontmatter(agent_file)
|
|
103
|
+
skills = frontmatter.get("skills", "").replace("[", "").replace("]", "").split(",")
|
|
104
|
+
skills = [s.strip() for s in skills if s.strip()]
|
|
105
|
+
|
|
106
|
+
agents.append({
|
|
107
|
+
"name": agent_file.stem,
|
|
108
|
+
"file": str(agent_file.relative_to(agent_dir)),
|
|
109
|
+
"description": frontmatter.get("description", ""),
|
|
110
|
+
"skills": skills,
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
return sorted(agents, key=lambda x: x["name"])
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def get_skills(agent_dir: Path) -> List[Dict[str, Any]]:
|
|
117
|
+
"""Get list of skills with their metadata."""
|
|
118
|
+
skills = []
|
|
119
|
+
skills_path = agent_dir / "skills"
|
|
120
|
+
|
|
121
|
+
if not skills_path.exists():
|
|
122
|
+
return skills
|
|
123
|
+
|
|
124
|
+
for skill_dir in skills_path.iterdir():
|
|
125
|
+
if not skill_dir.is_dir():
|
|
126
|
+
continue
|
|
127
|
+
|
|
128
|
+
skill_md = skill_dir / "SKILL.md"
|
|
129
|
+
if not skill_md.exists():
|
|
130
|
+
continue
|
|
131
|
+
|
|
132
|
+
frontmatter = parse_frontmatter(skill_md)
|
|
133
|
+
|
|
134
|
+
# Check for scripts
|
|
135
|
+
scripts_path = skill_dir / "scripts"
|
|
136
|
+
has_scripts = scripts_path.exists() and any(scripts_path.glob("*.py"))
|
|
137
|
+
|
|
138
|
+
skills.append({
|
|
139
|
+
"name": skill_dir.name,
|
|
140
|
+
"file": str(skill_md.relative_to(agent_dir)),
|
|
141
|
+
"description": frontmatter.get("description", ""),
|
|
142
|
+
"has_scripts": has_scripts,
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
return sorted(skills, key=lambda x: x["name"])
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def get_workflows(agent_dir: Path) -> List[Dict[str, Any]]:
|
|
149
|
+
"""Get list of workflows."""
|
|
150
|
+
workflows = []
|
|
151
|
+
workflows_path = agent_dir / "workflows"
|
|
152
|
+
|
|
153
|
+
if not workflows_path.exists():
|
|
154
|
+
return workflows
|
|
155
|
+
|
|
156
|
+
for workflow_file in workflows_path.glob("*.md"):
|
|
157
|
+
frontmatter = parse_frontmatter(workflow_file)
|
|
158
|
+
|
|
159
|
+
workflows.append({
|
|
160
|
+
"name": workflow_file.stem,
|
|
161
|
+
"command": f"/{workflow_file.stem}",
|
|
162
|
+
"file": str(workflow_file.relative_to(agent_dir)),
|
|
163
|
+
"description": frontmatter.get("description", ""),
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
return sorted(workflows, key=lambda x: x["name"])
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def validate_kit(agent_dir: Path, agents: List, skills: List, workflows: List) -> Dict[str, Any]:
|
|
170
|
+
"""Validate kit integrity."""
|
|
171
|
+
issues = []
|
|
172
|
+
warnings = []
|
|
173
|
+
|
|
174
|
+
skill_names = {s["name"] for s in skills}
|
|
175
|
+
|
|
176
|
+
# Check agent skill references
|
|
177
|
+
for agent in agents:
|
|
178
|
+
for skill in agent.get("skills", []):
|
|
179
|
+
if skill and skill not in skill_names:
|
|
180
|
+
issues.append(f"Agent '{agent['name']}' references missing skill: {skill}")
|
|
181
|
+
|
|
182
|
+
# Check for skills without SKILL.md
|
|
183
|
+
skills_path = agent_dir / "skills"
|
|
184
|
+
if skills_path.exists():
|
|
185
|
+
for skill_dir in skills_path.iterdir():
|
|
186
|
+
if skill_dir.is_dir() and not (skill_dir / "SKILL.md").exists():
|
|
187
|
+
warnings.append(f"Skill directory '{skill_dir.name}' missing SKILL.md")
|
|
188
|
+
|
|
189
|
+
# Check ARCHITECTURE.md exists
|
|
190
|
+
if not (agent_dir / "ARCHITECTURE.md").exists():
|
|
191
|
+
issues.append("Missing ARCHITECTURE.md")
|
|
192
|
+
|
|
193
|
+
# Check required files
|
|
194
|
+
required_files = ["ARCHITECTURE.md"]
|
|
195
|
+
for rf in required_files:
|
|
196
|
+
if not (agent_dir / rf).exists():
|
|
197
|
+
issues.append(f"Missing required file: {rf}")
|
|
198
|
+
|
|
199
|
+
return {
|
|
200
|
+
"valid": len(issues) == 0,
|
|
201
|
+
"issues": issues,
|
|
202
|
+
"warnings": warnings,
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def print_report(agents: List, skills: List, workflows: List, validation: Dict):
|
|
207
|
+
"""Print formatted status report."""
|
|
208
|
+
print_header("š¤ AGT-KIT STATUS REPORT")
|
|
209
|
+
|
|
210
|
+
# Statistics
|
|
211
|
+
print(f"{Colors.BOLD}š Statistics{Colors.ENDC}")
|
|
212
|
+
print(f" Agents: {len(agents)}")
|
|
213
|
+
print(f" Skills: {len(skills)}")
|
|
214
|
+
print(f" Workflows: {len(workflows)}")
|
|
215
|
+
print()
|
|
216
|
+
|
|
217
|
+
# Agents
|
|
218
|
+
print(f"{Colors.BOLD}š¤ Agents ({len(agents)}){Colors.ENDC}")
|
|
219
|
+
for agent in agents:
|
|
220
|
+
skill_count = len(agent.get("skills", []))
|
|
221
|
+
print(f" ⢠{agent['name']} ({skill_count} skills)")
|
|
222
|
+
print()
|
|
223
|
+
|
|
224
|
+
# Skills with scripts
|
|
225
|
+
skills_with_scripts = [s for s in skills if s.get("has_scripts")]
|
|
226
|
+
print(f"{Colors.BOLD}š§© Skills with Scripts ({len(skills_with_scripts)}/{len(skills)}){Colors.ENDC}")
|
|
227
|
+
for skill in skills_with_scripts:
|
|
228
|
+
print(f" ⢠{skill['name']} ā")
|
|
229
|
+
print()
|
|
230
|
+
|
|
231
|
+
# Workflows
|
|
232
|
+
print(f"{Colors.BOLD}š Workflows ({len(workflows)}){Colors.ENDC}")
|
|
233
|
+
for workflow in workflows:
|
|
234
|
+
print(f" ⢠{workflow['command']} - {workflow.get('description', 'No description')[:50]}")
|
|
235
|
+
print()
|
|
236
|
+
|
|
237
|
+
# Validation
|
|
238
|
+
print(f"{Colors.BOLD}ā
Validation{Colors.ENDC}")
|
|
239
|
+
if validation["valid"]:
|
|
240
|
+
print_success("Kit integrity check passed")
|
|
241
|
+
else:
|
|
242
|
+
for issue in validation["issues"]:
|
|
243
|
+
print_error(issue)
|
|
244
|
+
|
|
245
|
+
for warning in validation.get("warnings", []):
|
|
246
|
+
print_warning(warning)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def main():
|
|
250
|
+
parser = argparse.ArgumentParser(
|
|
251
|
+
description="AGT-Kit Status Reporter",
|
|
252
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
253
|
+
)
|
|
254
|
+
parser.add_argument("--validate", action="store_true", help="Run validation checks")
|
|
255
|
+
parser.add_argument("--json", action="store_true", help="Output as JSON")
|
|
256
|
+
|
|
257
|
+
args = parser.parse_args()
|
|
258
|
+
|
|
259
|
+
agent_dir = find_kit_root()
|
|
260
|
+
|
|
261
|
+
if not agent_dir:
|
|
262
|
+
print_error("Could not find .agent directory")
|
|
263
|
+
sys.exit(1)
|
|
264
|
+
|
|
265
|
+
# Gather data
|
|
266
|
+
agents = get_agents(agent_dir)
|
|
267
|
+
skills = get_skills(agent_dir)
|
|
268
|
+
workflows = get_workflows(agent_dir)
|
|
269
|
+
validation = validate_kit(agent_dir, agents, skills, workflows)
|
|
270
|
+
|
|
271
|
+
if args.json:
|
|
272
|
+
output = {
|
|
273
|
+
"kit_path": str(agent_dir),
|
|
274
|
+
"statistics": {
|
|
275
|
+
"agents": len(agents),
|
|
276
|
+
"skills": len(skills),
|
|
277
|
+
"workflows": len(workflows),
|
|
278
|
+
},
|
|
279
|
+
"agents": agents,
|
|
280
|
+
"skills": skills,
|
|
281
|
+
"workflows": workflows,
|
|
282
|
+
"validation": validation,
|
|
283
|
+
}
|
|
284
|
+
print(json.dumps(output, indent=2))
|
|
285
|
+
else:
|
|
286
|
+
print_report(agents, skills, workflows, validation)
|
|
287
|
+
|
|
288
|
+
sys.exit(0 if validation["valid"] else 1)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
if __name__ == "__main__":
|
|
292
|
+
main()
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Skills Manager - Manage AGT-Kit skills dynamically
|
|
4
|
+
===================================================
|
|
5
|
+
|
|
6
|
+
Enable/disable skills without deleting them.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python3 .agent/scripts/skills_manager.py list # List active skills
|
|
10
|
+
python3 .agent/scripts/skills_manager.py disabled # List disabled skills
|
|
11
|
+
python3 .agent/scripts/skills_manager.py enable SKILL # Enable a skill
|
|
12
|
+
python3 .agent/scripts/skills_manager.py disable SKILL # Disable a skill
|
|
13
|
+
python3 .agent/scripts/skills_manager.py search QUERY # Search skills
|
|
14
|
+
python3 .agent/scripts/skills_manager.py info SKILL # Show skill details
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import sys
|
|
18
|
+
import os
|
|
19
|
+
import re
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
# Fix console encoding
|
|
23
|
+
try:
|
|
24
|
+
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
|
25
|
+
except:
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
# Paths
|
|
29
|
+
SCRIPT_DIR = Path(__file__).parent
|
|
30
|
+
AGENT_DIR = SCRIPT_DIR.parent
|
|
31
|
+
SKILLS_DIR = AGENT_DIR / "skills"
|
|
32
|
+
DISABLED_DIR = SKILLS_DIR / ".disabled"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def parse_frontmatter(content: str) -> dict:
|
|
36
|
+
"""Parse YAML frontmatter from SKILL.md."""
|
|
37
|
+
fm_match = re.search(r'^---\s*\n(.*?)\n---', content, re.DOTALL)
|
|
38
|
+
if not fm_match:
|
|
39
|
+
return {}
|
|
40
|
+
|
|
41
|
+
metadata = {}
|
|
42
|
+
for line in fm_match.group(1).split('\n'):
|
|
43
|
+
if ':' in line:
|
|
44
|
+
key, val = line.split(':', 1)
|
|
45
|
+
metadata[key.strip()] = val.strip().strip('"').strip("'")
|
|
46
|
+
return metadata
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def get_skill_info(skill_path: Path) -> dict:
|
|
50
|
+
"""Get information about a skill."""
|
|
51
|
+
skill_md = skill_path / "SKILL.md"
|
|
52
|
+
info = {
|
|
53
|
+
"name": skill_path.name,
|
|
54
|
+
"path": str(skill_path),
|
|
55
|
+
"has_skill_md": skill_md.exists(),
|
|
56
|
+
"has_scripts": (skill_path / "scripts").exists(),
|
|
57
|
+
"description": "",
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if skill_md.exists():
|
|
61
|
+
try:
|
|
62
|
+
content = skill_md.read_text(encoding='utf-8')
|
|
63
|
+
metadata = parse_frontmatter(content)
|
|
64
|
+
info["description"] = metadata.get("description", "")[:80]
|
|
65
|
+
except:
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
return info
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def list_active():
|
|
72
|
+
"""List all active skills."""
|
|
73
|
+
print("\nš¢ Active Skills\n" + "="*50)
|
|
74
|
+
|
|
75
|
+
skills = sorted([
|
|
76
|
+
d for d in SKILLS_DIR.iterdir()
|
|
77
|
+
if d.is_dir() and not d.name.startswith('.')
|
|
78
|
+
], key=lambda x: x.name)
|
|
79
|
+
|
|
80
|
+
with_scripts = 0
|
|
81
|
+
for skill in skills:
|
|
82
|
+
info = get_skill_info(skill)
|
|
83
|
+
script_icon = "š" if info["has_scripts"] else " "
|
|
84
|
+
desc = f" - {info['description']}" if info["description"] else ""
|
|
85
|
+
print(f" {script_icon} {skill.name}{desc}")
|
|
86
|
+
if info["has_scripts"]:
|
|
87
|
+
with_scripts += 1
|
|
88
|
+
|
|
89
|
+
print(f"\nā
Total: {len(skills)} skills ({with_scripts} with scripts)")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def list_disabled():
|
|
93
|
+
"""List all disabled skills."""
|
|
94
|
+
if not DISABLED_DIR.exists():
|
|
95
|
+
print("ā No disabled skills")
|
|
96
|
+
return
|
|
97
|
+
|
|
98
|
+
print("\nāŖ Disabled Skills\n" + "="*50)
|
|
99
|
+
|
|
100
|
+
disabled = sorted([d for d in DISABLED_DIR.iterdir() if d.is_dir()])
|
|
101
|
+
|
|
102
|
+
for skill in disabled:
|
|
103
|
+
print(f" ⢠{skill.name}")
|
|
104
|
+
|
|
105
|
+
print(f"\nš Total: {len(disabled)} disabled skills")
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def enable_skill(skill_name: str):
|
|
109
|
+
"""Enable a disabled skill."""
|
|
110
|
+
source = DISABLED_DIR / skill_name
|
|
111
|
+
target = SKILLS_DIR / skill_name
|
|
112
|
+
|
|
113
|
+
if not source.exists():
|
|
114
|
+
print(f"ā Skill '{skill_name}' not found in .disabled/")
|
|
115
|
+
return False
|
|
116
|
+
|
|
117
|
+
if target.exists():
|
|
118
|
+
print(f"ā ļø Skill '{skill_name}' already active")
|
|
119
|
+
return False
|
|
120
|
+
|
|
121
|
+
source.rename(target)
|
|
122
|
+
print(f"ā
Enabled: {skill_name}")
|
|
123
|
+
return True
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def disable_skill(skill_name: str):
|
|
127
|
+
"""Disable an active skill."""
|
|
128
|
+
source = SKILLS_DIR / skill_name
|
|
129
|
+
target = DISABLED_DIR / skill_name
|
|
130
|
+
|
|
131
|
+
if not source.exists():
|
|
132
|
+
print(f"ā Skill '{skill_name}' not found")
|
|
133
|
+
return False
|
|
134
|
+
|
|
135
|
+
if source.name.startswith('.'):
|
|
136
|
+
print(f"ā ļø Cannot disable system directory")
|
|
137
|
+
return False
|
|
138
|
+
|
|
139
|
+
DISABLED_DIR.mkdir(exist_ok=True)
|
|
140
|
+
source.rename(target)
|
|
141
|
+
print(f"ā
Disabled: {skill_name}")
|
|
142
|
+
return True
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def search_skills(query: str):
|
|
146
|
+
"""Search skills by name or description."""
|
|
147
|
+
print(f"\nš Searching for '{query}'\n" + "="*50)
|
|
148
|
+
|
|
149
|
+
query_lower = query.lower()
|
|
150
|
+
matches = []
|
|
151
|
+
|
|
152
|
+
for skill_path in SKILLS_DIR.iterdir():
|
|
153
|
+
if not skill_path.is_dir() or skill_path.name.startswith('.'):
|
|
154
|
+
continue
|
|
155
|
+
|
|
156
|
+
info = get_skill_info(skill_path)
|
|
157
|
+
|
|
158
|
+
# Search in name and description
|
|
159
|
+
if query_lower in skill_path.name.lower() or query_lower in info["description"].lower():
|
|
160
|
+
matches.append(info)
|
|
161
|
+
|
|
162
|
+
if matches:
|
|
163
|
+
for info in matches:
|
|
164
|
+
script_icon = "š" if info["has_scripts"] else " "
|
|
165
|
+
desc = f" - {info['description']}" if info["description"] else ""
|
|
166
|
+
print(f" {script_icon} {info['name']}{desc}")
|
|
167
|
+
print(f"\nā
Found {len(matches)} matching skills")
|
|
168
|
+
else:
|
|
169
|
+
print(" No skills found matching your query")
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def show_skill_info(skill_name: str):
|
|
173
|
+
"""Show detailed info about a skill."""
|
|
174
|
+
skill_path = SKILLS_DIR / skill_name
|
|
175
|
+
|
|
176
|
+
if not skill_path.exists():
|
|
177
|
+
print(f"ā Skill '{skill_name}' not found")
|
|
178
|
+
return
|
|
179
|
+
|
|
180
|
+
info = get_skill_info(skill_path)
|
|
181
|
+
skill_md = skill_path / "SKILL.md"
|
|
182
|
+
|
|
183
|
+
print(f"\nš¦ Skill: {skill_name}\n" + "="*50)
|
|
184
|
+
print(f"Path: {info['path']}")
|
|
185
|
+
print(f"Has SKILL.md: {'ā
' if info['has_skill_md'] else 'ā'}")
|
|
186
|
+
print(f"Has Scripts: {'ā
' if info['has_scripts'] else 'ā'}")
|
|
187
|
+
|
|
188
|
+
if info['has_scripts']:
|
|
189
|
+
scripts_dir = skill_path / "scripts"
|
|
190
|
+
scripts = list(scripts_dir.glob("*.py"))
|
|
191
|
+
print(f"\nScripts ({len(scripts)}):")
|
|
192
|
+
for script in scripts:
|
|
193
|
+
print(f" ⢠{script.name}")
|
|
194
|
+
|
|
195
|
+
if skill_md.exists():
|
|
196
|
+
try:
|
|
197
|
+
content = skill_md.read_text(encoding='utf-8')
|
|
198
|
+
metadata = parse_frontmatter(content)
|
|
199
|
+
if metadata.get("description"):
|
|
200
|
+
print(f"\nDescription:\n {metadata['description']}")
|
|
201
|
+
except:
|
|
202
|
+
pass
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def main():
|
|
206
|
+
if len(sys.argv) < 2:
|
|
207
|
+
print(__doc__)
|
|
208
|
+
sys.exit(1)
|
|
209
|
+
|
|
210
|
+
command = sys.argv[1].lower()
|
|
211
|
+
|
|
212
|
+
if command == "list":
|
|
213
|
+
list_active()
|
|
214
|
+
elif command == "disabled":
|
|
215
|
+
list_disabled()
|
|
216
|
+
elif command == "enable":
|
|
217
|
+
if len(sys.argv) < 3:
|
|
218
|
+
print("ā Usage: skills_manager.py enable SKILL_NAME")
|
|
219
|
+
sys.exit(1)
|
|
220
|
+
enable_skill(sys.argv[2])
|
|
221
|
+
elif command == "disable":
|
|
222
|
+
if len(sys.argv) < 3:
|
|
223
|
+
print("ā Usage: skills_manager.py disable SKILL_NAME")
|
|
224
|
+
sys.exit(1)
|
|
225
|
+
disable_skill(sys.argv[2])
|
|
226
|
+
elif command == "search":
|
|
227
|
+
if len(sys.argv) < 3:
|
|
228
|
+
print("ā Usage: skills_manager.py search QUERY")
|
|
229
|
+
sys.exit(1)
|
|
230
|
+
search_skills(sys.argv[2])
|
|
231
|
+
elif command == "info":
|
|
232
|
+
if len(sys.argv) < 3:
|
|
233
|
+
print("ā Usage: skills_manager.py info SKILL_NAME")
|
|
234
|
+
sys.exit(1)
|
|
235
|
+
show_skill_info(sys.argv[2])
|
|
236
|
+
else:
|
|
237
|
+
print(f"ā Unknown command: {command}")
|
|
238
|
+
print(__doc__)
|
|
239
|
+
sys.exit(1)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
if __name__ == "__main__":
|
|
243
|
+
main()
|