@softspark/ai-toolkit 1.0.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/AGENTS.md +412 -0
- package/CHANGELOG.md +68 -0
- package/LICENSE +21 -0
- package/README.md +632 -0
- package/action.yml +53 -0
- package/app/.claude-plugin/plugin.json +44 -0
- package/app/ARCHITECTURE.md +306 -0
- package/app/CLAUDE.md.template +23 -0
- package/app/agents/ai-engineer.md +128 -0
- package/app/agents/backend-specialist.md +193 -0
- package/app/agents/business-intelligence.md +54 -0
- package/app/agents/chaos-monkey.md +67 -0
- package/app/agents/chief-of-staff.md +51 -0
- package/app/agents/code-archaeologist.md +127 -0
- package/app/agents/code-reviewer.md +184 -0
- package/app/agents/command-expert.md +131 -0
- package/app/agents/data-analyst.md +205 -0
- package/app/agents/data-scientist.md +151 -0
- package/app/agents/database-architect.md +317 -0
- package/app/agents/debugger.md +238 -0
- package/app/agents/devops-implementer.md +194 -0
- package/app/agents/documenter.md +364 -0
- package/app/agents/explorer-agent.md +145 -0
- package/app/agents/fact-checker.md +172 -0
- package/app/agents/frontend-specialist.md +209 -0
- package/app/agents/game-developer.md +216 -0
- package/app/agents/incident-responder.md +226 -0
- package/app/agents/infrastructure-architect.md +127 -0
- package/app/agents/infrastructure-validator.md +247 -0
- package/app/agents/llm-ops-engineer.md +237 -0
- package/app/agents/mcp-expert.md +228 -0
- package/app/agents/mcp-server-architect.md +195 -0
- package/app/agents/mcp-testing-engineer.md +292 -0
- package/app/agents/meta-architect.md +58 -0
- package/app/agents/ml-engineer.md +136 -0
- package/app/agents/mobile-developer.md +190 -0
- package/app/agents/night-watchman.md +55 -0
- package/app/agents/nlp-engineer.md +154 -0
- package/app/agents/orchestrator.md +437 -0
- package/app/agents/performance-optimizer.md +254 -0
- package/app/agents/predictive-analyst.md +57 -0
- package/app/agents/product-manager.md +194 -0
- package/app/agents/project-planner.md +287 -0
- package/app/agents/prompt-engineer.md +103 -0
- package/app/agents/qa-automation-engineer.md +182 -0
- package/app/agents/rag-engineer.md +201 -0
- package/app/agents/research-synthesizer.md +138 -0
- package/app/agents/search-specialist.md +101 -0
- package/app/agents/security-architect.md +62 -0
- package/app/agents/security-auditor.md +293 -0
- package/app/agents/seo-specialist.md +111 -0
- package/app/agents/system-governor.md +57 -0
- package/app/agents/tech-lead.md +62 -0
- package/app/agents/technical-researcher.md +103 -0
- package/app/agents/test-engineer.md +264 -0
- package/app/constitution.md +38 -0
- package/app/hooks/_profile-check.sh +11 -0
- package/app/hooks/guard-destructive.sh +74 -0
- package/app/hooks/guard-path.sh +73 -0
- package/app/hooks/post-tool-use.sh +35 -0
- package/app/hooks/pre-compact.sh +31 -0
- package/app/hooks/quality-check.sh +22 -0
- package/app/hooks/quality-gate.sh +49 -0
- package/app/hooks/save-session.sh +24 -0
- package/app/hooks/session-end.sh +37 -0
- package/app/hooks/session-start.sh +29 -0
- package/app/hooks/subagent-start.sh +16 -0
- package/app/hooks/subagent-stop.sh +16 -0
- package/app/hooks/track-usage.sh +50 -0
- package/app/hooks/user-prompt-submit.sh +25 -0
- package/app/hooks.json +178 -0
- package/app/mcp-defaults.json +23 -0
- package/app/output-styles/golden-rules.md +43 -0
- package/app/plugins/README.md +19 -0
- package/app/plugins/csharp-pack/README.md +11 -0
- package/app/plugins/csharp-pack/plugin.json +18 -0
- package/app/plugins/enterprise-pack/README.md +16 -0
- package/app/plugins/enterprise-pack/hooks/output-style.sh +6 -0
- package/app/plugins/enterprise-pack/hooks/status-line.sh +8 -0
- package/app/plugins/enterprise-pack/plugin.json +24 -0
- package/app/plugins/frontend-pack/README.md +14 -0
- package/app/plugins/frontend-pack/plugin.json +22 -0
- package/app/plugins/java-pack/README.md +11 -0
- package/app/plugins/java-pack/plugin.json +18 -0
- package/app/plugins/kotlin-pack/README.md +11 -0
- package/app/plugins/kotlin-pack/plugin.json +18 -0
- package/app/plugins/memory-pack/README.md +24 -0
- package/app/plugins/memory-pack/hooks/observation-capture.sh +67 -0
- package/app/plugins/memory-pack/hooks/session-summary.sh +71 -0
- package/app/plugins/memory-pack/plugin.json +22 -0
- package/app/plugins/memory-pack/scripts/init_db.py +81 -0
- package/app/plugins/memory-pack/scripts/strip_private.py +22 -0
- package/app/plugins/memory-pack/skills/mem-search/SKILL.md +70 -0
- package/app/plugins/research-pack/README.md +14 -0
- package/app/plugins/research-pack/plugin.json +22 -0
- package/app/plugins/ruby-pack/README.md +11 -0
- package/app/plugins/ruby-pack/plugin.json +18 -0
- package/app/plugins/rust-pack/README.md +11 -0
- package/app/plugins/rust-pack/plugin.json +18 -0
- package/app/plugins/security-pack/README.md +15 -0
- package/app/plugins/security-pack/plugin.json +23 -0
- package/app/plugins/swift-pack/README.md +11 -0
- package/app/plugins/swift-pack/plugin.json +18 -0
- package/app/rules/claude-toolkit-rules.md +21 -0
- package/app/rules/git-conventions.md +5 -0
- package/app/rules/quality-gates.md +10 -0
- package/app/skills/_lib/__init__.py +1 -0
- package/app/skills/_lib/detect_utils.py +150 -0
- package/app/skills/agent-creator/SKILL.md +82 -0
- package/app/skills/analyze/SKILL.md +92 -0
- package/app/skills/analyze/scripts/complexity.py +165 -0
- package/app/skills/api-patterns/SKILL.md +305 -0
- package/app/skills/app-builder/SKILL.md +187 -0
- package/app/skills/architecture-audit/SKILL.md +141 -0
- package/app/skills/architecture-decision/SKILL.md +55 -0
- package/app/skills/architecture-decision/templates/adr-template.md +36 -0
- package/app/skills/biz-scan/SKILL.md +30 -0
- package/app/skills/briefing/SKILL.md +27 -0
- package/app/skills/build/SKILL.md +97 -0
- package/app/skills/build/scripts/detect-build.py +151 -0
- package/app/skills/chaos/SKILL.md +32 -0
- package/app/skills/ci/SKILL.md +77 -0
- package/app/skills/ci/scripts/ci-detect.py +135 -0
- package/app/skills/ci/templates/github-actions-node.yml +38 -0
- package/app/skills/ci/templates/github-actions-python.yml +42 -0
- package/app/skills/ci-cd-patterns/SKILL.md +299 -0
- package/app/skills/clean-code/SKILL.md +110 -0
- package/app/skills/clean-code/reference/dart.md +18 -0
- package/app/skills/clean-code/reference/go.md +23 -0
- package/app/skills/clean-code/reference/php.md +32 -0
- package/app/skills/clean-code/reference/python.md +180 -0
- package/app/skills/clean-code/reference/typescript.md +26 -0
- package/app/skills/command-creator/SKILL.md +83 -0
- package/app/skills/commit/SKILL.md +98 -0
- package/app/skills/commit/scripts/pre-commit-check.py +87 -0
- package/app/skills/commit/templates/conventional-commit.md +52 -0
- package/app/skills/csharp-patterns/SKILL.md +450 -0
- package/app/skills/database-patterns/SKILL.md +297 -0
- package/app/skills/debug/SKILL.md +154 -0
- package/app/skills/debug/scripts/error-parser.py +187 -0
- package/app/skills/debugging-tactics/SKILL.md +136 -0
- package/app/skills/deploy/SKILL.md +130 -0
- package/app/skills/deploy/scripts/pre_deploy_check.py +171 -0
- package/app/skills/deploy/templates/deployment-checklist.md +31 -0
- package/app/skills/design-an-interface/SKILL.md +105 -0
- package/app/skills/design-engineering/SKILL.md +260 -0
- package/app/skills/docker-devops/SKILL.md +303 -0
- package/app/skills/docs/SKILL.md +145 -0
- package/app/skills/docs/scripts/doc-inventory.py +176 -0
- package/app/skills/docs/templates/adr-template.md +36 -0
- package/app/skills/docs/templates/readme-template.md +67 -0
- package/app/skills/documentation-standards/SKILL.md +191 -0
- package/app/skills/ecommerce-patterns/SKILL.md +209 -0
- package/app/skills/evaluate/SKILL.md +132 -0
- package/app/skills/evolve/SKILL.md +27 -0
- package/app/skills/explain/SKILL.md +54 -0
- package/app/skills/explain/scripts/dependency-graph.py +215 -0
- package/app/skills/explore/SKILL.md +112 -0
- package/app/skills/explore/scripts/visualize.py +117 -0
- package/app/skills/fix/SKILL.md +78 -0
- package/app/skills/fix/scripts/error-classifier.py +191 -0
- package/app/skills/flutter-patterns/SKILL.md +254 -0
- package/app/skills/git-mastery/SKILL.md +70 -0
- package/app/skills/grill-me/SKILL.md +38 -0
- package/app/skills/health/SKILL.md +91 -0
- package/app/skills/health/scripts/health_check.py +162 -0
- package/app/skills/hive-mind/SKILL.md +56 -0
- package/app/skills/hook-creator/SKILL.md +107 -0
- package/app/skills/index/SKILL.md +74 -0
- package/app/skills/instinct-review/SKILL.md +77 -0
- package/app/skills/java-patterns/SKILL.md +442 -0
- package/app/skills/kotlin-patterns/SKILL.md +446 -0
- package/app/skills/lint/SKILL.md +103 -0
- package/app/skills/lint/scripts/detect-linters.py +112 -0
- package/app/skills/mcp-patterns/SKILL.md +270 -0
- package/app/skills/mem-search/SKILL.md +70 -0
- package/app/skills/migrate/SKILL.md +90 -0
- package/app/skills/migrate/scripts/migration-status.py +195 -0
- package/app/skills/migration-patterns/SKILL.md +260 -0
- package/app/skills/night-watch/SKILL.md +28 -0
- package/app/skills/observability-patterns/SKILL.md +203 -0
- package/app/skills/onboard/SKILL.md +76 -0
- package/app/skills/orchestrate/SKILL.md +86 -0
- package/app/skills/panic/SKILL.md +30 -0
- package/app/skills/performance-profiling/SKILL.md +59 -0
- package/app/skills/plan/SKILL.md +110 -0
- package/app/skills/plan/templates/plan-template.md +40 -0
- package/app/skills/plan-writing/SKILL.md +201 -0
- package/app/skills/plugin-creator/SKILL.md +78 -0
- package/app/skills/pr/SKILL.md +129 -0
- package/app/skills/pr/scripts/pr-summary.py +175 -0
- package/app/skills/prd-to-issues/SKILL.md +108 -0
- package/app/skills/prd-to-plan/SKILL.md +120 -0
- package/app/skills/predict/SKILL.md +30 -0
- package/app/skills/qa-session/SKILL.md +110 -0
- package/app/skills/rag-patterns/SKILL.md +203 -0
- package/app/skills/refactor/SKILL.md +124 -0
- package/app/skills/refactor/scripts/refactor-scan.py +210 -0
- package/app/skills/refactor-plan/SKILL.md +112 -0
- package/app/skills/repeat/SKILL.md +149 -0
- package/app/skills/research-mastery/SKILL.md +56 -0
- package/app/skills/review/SKILL.md +141 -0
- package/app/skills/review/scripts/diff-analyzer.py +170 -0
- package/app/skills/rollback/SKILL.md +87 -0
- package/app/skills/rollback/scripts/rollback_info.py +149 -0
- package/app/skills/ruby-patterns/SKILL.md +454 -0
- package/app/skills/rust-patterns/SKILL.md +446 -0
- package/app/skills/search/SKILL.md +64 -0
- package/app/skills/security-patterns/SKILL.md +91 -0
- package/app/skills/security-patterns/reference/authentication.md +37 -0
- package/app/skills/security-patterns/reference/authorization.md +22 -0
- package/app/skills/security-patterns/reference/input-validation.md +30 -0
- package/app/skills/security-patterns/reference/oauth-csrf-audit.md +131 -0
- package/app/skills/skill-creator/SKILL.md +154 -0
- package/app/skills/skill-creator/templates/dashboard/index.html +130 -0
- package/app/skills/skill-creator/templates/reasoning-engine/assets/example.json +12 -0
- package/app/skills/skill-creator/templates/reasoning-engine/search.py +110 -0
- package/app/skills/subagent-development/SKILL.md +225 -0
- package/app/skills/subagent-development/reference/code-quality-reviewer-prompt.md +145 -0
- package/app/skills/subagent-development/reference/implementer-prompt.md +118 -0
- package/app/skills/subagent-development/reference/spec-reviewer-prompt.md +100 -0
- package/app/skills/swarm/SKILL.md +81 -0
- package/app/skills/swift-patterns/SKILL.md +500 -0
- package/app/skills/tdd/SKILL.md +174 -0
- package/app/skills/tdd/reference/deep-modules.md +32 -0
- package/app/skills/tdd/reference/interface-design.md +32 -0
- package/app/skills/tdd/reference/mocking.md +52 -0
- package/app/skills/tdd/reference/refactoring.md +10 -0
- package/app/skills/tdd/reference/tests.md +59 -0
- package/app/skills/teams/SKILL.md +101 -0
- package/app/skills/test/SKILL.md +107 -0
- package/app/skills/test/scripts/detect-runner.py +113 -0
- package/app/skills/testing-patterns/SKILL.md +73 -0
- package/app/skills/testing-patterns/reference/flutter-testing.md +33 -0
- package/app/skills/testing-patterns/reference/go-testing.md +52 -0
- package/app/skills/testing-patterns/reference/php-phpunit.md +39 -0
- package/app/skills/testing-patterns/reference/python-pytest.md +228 -0
- package/app/skills/testing-patterns/reference/typescript-vitest.md +50 -0
- package/app/skills/triage-issue/SKILL.md +120 -0
- package/app/skills/typescript-patterns/SKILL.md +256 -0
- package/app/skills/ubiquitous-language/SKILL.md +74 -0
- package/app/skills/verification-before-completion/SKILL.md +108 -0
- package/app/skills/workflow/SKILL.md +250 -0
- package/app/skills/write-a-prd/SKILL.md +129 -0
- package/app/skills/write-a-prd/reference/visual-companion.md +78 -0
- package/app/skills/write-a-prd/scripts/frame-template.html +111 -0
- package/app/skills/write-a-prd/scripts/visual-server.cjs +79 -0
- package/app/templates/skill/generator/SKILL.md.template +40 -0
- package/app/templates/skill/knowledge/SKILL.md.template +52 -0
- package/app/templates/skill/linter/SKILL.md.template +34 -0
- package/app/templates/skill/reviewer/SKILL.md.template +51 -0
- package/app/templates/skill/workflow/SKILL.md.template +49 -0
- package/benchmarks/README.md +111 -0
- package/benchmarks/ecosystem-dashboard.json +148 -0
- package/benchmarks/ecosystem-harvest.json +148 -0
- package/benchmarks/results.json +38 -0
- package/benchmarks/run.py +351 -0
- package/bin/ai-toolkit.js +345 -0
- package/kb/best-practices/README.md +11 -0
- package/kb/howto/README.md +11 -0
- package/kb/procedures/maintenance-sop.md +306 -0
- package/kb/reference/agents-catalog.md +124 -0
- package/kb/reference/anti-pattern-registry-format.md +221 -0
- package/kb/reference/architecture-overview.md +232 -0
- package/kb/reference/benchmark-config.md +62 -0
- package/kb/reference/ci-integration.md +66 -0
- package/kb/reference/claude-ecosystem-benchmark-snapshot.md +80 -0
- package/kb/reference/claude-ecosystem-expansion-foundations.md +102 -0
- package/kb/reference/commands-catalog.md +21 -0
- package/kb/reference/distribution-model.md +63 -0
- package/kb/reference/global-install-model.md +56 -0
- package/kb/reference/hierarchical-override-pattern.md +200 -0
- package/kb/reference/hooks-catalog.md +306 -0
- package/kb/reference/integrations.md +88 -0
- package/kb/reference/language-packs.md +52 -0
- package/kb/reference/merge-friendly-install-model.md +58 -0
- package/kb/reference/plugin-pack-conventions.md +151 -0
- package/kb/reference/quick-wins-implementation-summary.md +70 -0
- package/kb/reference/skill-templates.md +50 -0
- package/kb/reference/skills-catalog.md +215 -0
- package/kb/reference/skills-unification.md +57 -0
- package/kb/reference/stats.md +69 -0
- package/kb/reference/sync.md +76 -0
- package/kb/troubleshooting/README.md +11 -0
- package/llms-full.txt +3068 -0
- package/llms.txt +39 -0
- package/package.json +75 -0
- package/scripts/_common.py +160 -0
- package/scripts/add_rule.py +50 -0
- package/scripts/benchmark_config.py +127 -0
- package/scripts/benchmark_ecosystem.py +288 -0
- package/scripts/check_deps.py +260 -0
- package/scripts/create_skill.py +118 -0
- package/scripts/doctor.py +504 -0
- package/scripts/eject.py +113 -0
- package/scripts/emission.py +256 -0
- package/scripts/evaluate_skills.py +260 -0
- package/scripts/frontmatter.py +58 -0
- package/scripts/generate_agents_md.py +91 -0
- package/scripts/generate_aider_conf.py +51 -0
- package/scripts/generate_cline.py +35 -0
- package/scripts/generate_copilot.py +30 -0
- package/scripts/generate_cursor_rules.py +35 -0
- package/scripts/generate_gemini.py +28 -0
- package/scripts/generate_llms_txt.py +164 -0
- package/scripts/generate_roo_modes.py +80 -0
- package/scripts/generate_windsurf.py +35 -0
- package/scripts/generator_base.py +140 -0
- package/scripts/harvest_ecosystem.py +50 -0
- package/scripts/inject_rule_cli.py +101 -0
- package/scripts/inject_section_cli.py +47 -0
- package/scripts/injection.py +180 -0
- package/scripts/install.py +236 -0
- package/scripts/install_git_hooks.py +71 -0
- package/scripts/install_steps/__init__.py +5 -0
- package/scripts/install_steps/ai_tools.py +261 -0
- package/scripts/install_steps/hooks.py +90 -0
- package/scripts/install_steps/markers.py +79 -0
- package/scripts/install_steps/symlinks.py +87 -0
- package/scripts/merge-hooks.py +192 -0
- package/scripts/plugin.py +642 -0
- package/scripts/plugin_schema.py +138 -0
- package/scripts/remove_rule.py +58 -0
- package/scripts/stats.py +81 -0
- package/scripts/sync.py +215 -0
- package/scripts/uninstall.py +292 -0
- package/scripts/validate.py +700 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generate .aider.conf.yml configuration.
|
|
3
|
+
|
|
4
|
+
Usage: ./scripts/generate_aider_conf.py > .aider.conf.yml
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main() -> None:
|
|
15
|
+
print("# Aider configuration generated by ai-toolkit")
|
|
16
|
+
print("# Regenerate using: ai-toolkit install --local")
|
|
17
|
+
print()
|
|
18
|
+
print("# Use the architect mode for complex tasks, aligned with our 2-phase workflow")
|
|
19
|
+
print("architect: true")
|
|
20
|
+
print()
|
|
21
|
+
print("# Read global rules ")
|
|
22
|
+
print("read:")
|
|
23
|
+
print(' - ".claude/CLAUDE.md"')
|
|
24
|
+
print(' - ".claude/constitution.md"')
|
|
25
|
+
print(' - "AGENTS.md"')
|
|
26
|
+
print()
|
|
27
|
+
print("# Linting commands for quality gates")
|
|
28
|
+
print("lint-cmd:")
|
|
29
|
+
print(' - "python: ruff check"')
|
|
30
|
+
print(' - "typescript: npx eslint"')
|
|
31
|
+
print(' - "javascript: npx eslint"')
|
|
32
|
+
print(' - "php: ./vendor/bin/phpstan analyse"')
|
|
33
|
+
print(' - "go: go vet"')
|
|
34
|
+
print()
|
|
35
|
+
print("# Model configuration")
|
|
36
|
+
print("model: claude-sonnet-4-6")
|
|
37
|
+
print("editor-model: claude-sonnet-4-6")
|
|
38
|
+
print()
|
|
39
|
+
print("# Auto-commit message formatting (matches our conventional commits)")
|
|
40
|
+
print(
|
|
41
|
+
'commit_prompt: "Write a short, concise commit message following'
|
|
42
|
+
' Conventional Commits (feat/fix/chore/docs/test/refactor)."'
|
|
43
|
+
)
|
|
44
|
+
print()
|
|
45
|
+
print("# Disable auto-commits if you prefer using the /commit slash skill explicitly")
|
|
46
|
+
print("# auto-commits: false")
|
|
47
|
+
print()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if __name__ == "__main__":
|
|
51
|
+
main()
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generate .clinerules from app/agents/*.md and app/skills/*/SKILL.md.
|
|
3
|
+
|
|
4
|
+
Usage: ./scripts/generate_cline.py > .clinerules
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
12
|
+
from generator_base import render_generator
|
|
13
|
+
|
|
14
|
+
if __name__ == "__main__":
|
|
15
|
+
render_generator({
|
|
16
|
+
"title": "# Cline Rules — generated from ai-toolkit agents",
|
|
17
|
+
"header_lines": [
|
|
18
|
+
"# Auto-generated by scripts/generate-cline.sh — do not edit manually.",
|
|
19
|
+
"# Regenerate: ./scripts/generate-cline.sh > .clinerules",
|
|
20
|
+
],
|
|
21
|
+
"intro_template": (
|
|
22
|
+
"This repository uses the ai-toolkit — a shared AI development toolkit"
|
|
23
|
+
" with {agents} specialized agent personas and {skills} skills."
|
|
24
|
+
),
|
|
25
|
+
"agents_section": "## Available Agent Personas",
|
|
26
|
+
"agents_intro": "Apply the expertise of these agents when working on relevant tasks:",
|
|
27
|
+
"agents_format": "headings",
|
|
28
|
+
"agents_level": "##",
|
|
29
|
+
"skills_section": "## Available Skills",
|
|
30
|
+
"skills_intro": "The following skills are available as slash commands or knowledge sources:",
|
|
31
|
+
"skills_format": "headings",
|
|
32
|
+
"skills_level": "##",
|
|
33
|
+
"trailing_newline_after_skills": True,
|
|
34
|
+
"guidelines": ["general"],
|
|
35
|
+
})
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generate .github/copilot-instructions.md from app/agents/*.md and app/skills/*/SKILL.md.
|
|
3
|
+
|
|
4
|
+
Usage: ./scripts/generate_copilot.py > .github/copilot-instructions.md
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
12
|
+
from generator_base import render_generator
|
|
13
|
+
|
|
14
|
+
if __name__ == "__main__":
|
|
15
|
+
render_generator({
|
|
16
|
+
"title": "# GitHub Copilot Instructions",
|
|
17
|
+
"intro_template": (
|
|
18
|
+
"This repository uses the ai-toolkit — a shared AI development toolkit"
|
|
19
|
+
" with {agents} specialized agent personas and {skills} skills."
|
|
20
|
+
),
|
|
21
|
+
"agents_section": "## Available Agent Personas",
|
|
22
|
+
"agents_intro": "Apply the expertise of these agents when working on relevant tasks:",
|
|
23
|
+
"agents_format": "headings",
|
|
24
|
+
"agents_level": "###",
|
|
25
|
+
"skills_section": "## Available Skills",
|
|
26
|
+
"skills_intro": "The following skills are available as slash commands or knowledge sources:",
|
|
27
|
+
"skills_format": "headings",
|
|
28
|
+
"skills_level": "###",
|
|
29
|
+
"guidelines": ["quality"],
|
|
30
|
+
})
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generate .cursorrules from app/agents/*.md and app/skills/*/SKILL.md.
|
|
3
|
+
|
|
4
|
+
Usage: ./scripts/generate_cursor_rules.py > .cursorrules
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
12
|
+
from generator_base import render_generator
|
|
13
|
+
|
|
14
|
+
if __name__ == "__main__":
|
|
15
|
+
render_generator({
|
|
16
|
+
"title": "# Cursor Rules — generated from ai-toolkit agents",
|
|
17
|
+
"header_lines": [
|
|
18
|
+
"# Auto-generated by scripts/generate-cursor-rules.sh — do not edit manually.",
|
|
19
|
+
"# Regenerate: ./scripts/generate-cursor-rules.sh > .cursorrules",
|
|
20
|
+
],
|
|
21
|
+
"intro_template": (
|
|
22
|
+
"This repository uses the ai-toolkit — a shared AI development toolkit"
|
|
23
|
+
" with {agents} specialized agent personas and {skills} skills."
|
|
24
|
+
),
|
|
25
|
+
"agents_section": "## Available Agent Personas",
|
|
26
|
+
"agents_intro": "Apply the expertise of these agents when working on relevant tasks:",
|
|
27
|
+
"agents_format": "headings",
|
|
28
|
+
"agents_level": "##",
|
|
29
|
+
"skills_section": "## Available Skills",
|
|
30
|
+
"skills_intro": "The following skills are available as slash commands or knowledge sources:",
|
|
31
|
+
"skills_format": "headings",
|
|
32
|
+
"skills_level": "##",
|
|
33
|
+
"trailing_newline_after_skills": True,
|
|
34
|
+
"guidelines": ["general"],
|
|
35
|
+
})
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generate GEMINI.md from app/agents/*.md and app/skills/*/SKILL.md.
|
|
3
|
+
|
|
4
|
+
Usage: ./scripts/generate_gemini.py > GEMINI.md
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
12
|
+
from generator_base import render_generator
|
|
13
|
+
|
|
14
|
+
if __name__ == "__main__":
|
|
15
|
+
render_generator({
|
|
16
|
+
"title": "# AI Toolkit — Gemini CLI Configuration",
|
|
17
|
+
"intro_template": (
|
|
18
|
+
"Shared AI development toolkit with {agents} specialized agents,"
|
|
19
|
+
" {skills} skills, quality hooks, and a safety constitution."
|
|
20
|
+
),
|
|
21
|
+
"agents_section": "## Available Agents ({agents})",
|
|
22
|
+
"agents_intro": "Specialized agent personas — apply their expertise for relevant tasks:",
|
|
23
|
+
"agents_format": "bullets",
|
|
24
|
+
"skills_section": "## Available Skills ({skills})",
|
|
25
|
+
"skills_intro": "Skills are invocable slash commands or auto-loaded knowledge sources:",
|
|
26
|
+
"skills_format": "bullets",
|
|
27
|
+
"guidelines": ["quality_standards", "workflow"],
|
|
28
|
+
})
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generate llms.txt and llms-full.txt from kb/ docs.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
./scripts/generate_llms_txt.py -> llms.txt (index only)
|
|
6
|
+
./scripts/generate_llms_txt.py --full -> llms-full.txt (full content)
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import re
|
|
11
|
+
import sys
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
15
|
+
from _common import agents_dir, frontmatter_field, skill_count, skills_dir, toolkit_dir
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _relative(path: Path) -> str:
|
|
19
|
+
"""Return path relative to toolkit_dir."""
|
|
20
|
+
return str(path.relative_to(toolkit_dir))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _title_from_md(filepath: Path) -> str:
|
|
24
|
+
"""Extract the first ``# `` heading from a markdown file, or fallback to stem."""
|
|
25
|
+
with open(filepath, encoding="utf-8") as f:
|
|
26
|
+
for line in f:
|
|
27
|
+
if line.startswith("# "):
|
|
28
|
+
return line[2:].strip()
|
|
29
|
+
return filepath.stem
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _find_kb_files() -> list[Path]:
|
|
33
|
+
"""Find all .md files under kb/, sorted."""
|
|
34
|
+
kb_dir = toolkit_dir / "kb"
|
|
35
|
+
if not kb_dir.is_dir():
|
|
36
|
+
return []
|
|
37
|
+
return sorted(kb_dir.rglob("*.md"))
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _find_skill_files() -> list[Path]:
|
|
41
|
+
"""Find all SKILL.md files, sorted."""
|
|
42
|
+
return sorted(skills_dir.rglob("SKILL.md"))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _find_agent_files() -> list[Path]:
|
|
46
|
+
"""Find all agent .md files, sorted."""
|
|
47
|
+
return sorted(agents_dir.glob("*.md"))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _count_skills() -> int:
|
|
51
|
+
"""Count skill directories containing SKILL.md."""
|
|
52
|
+
return skill_count()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _count_agents() -> int:
|
|
56
|
+
"""Count agent .md files."""
|
|
57
|
+
return sum(1 for f in agents_dir.glob("*.md") if f.is_file())
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def generate_index() -> None:
|
|
61
|
+
"""Print the llms.txt index."""
|
|
62
|
+
skills = _count_skills()
|
|
63
|
+
agents = _count_agents()
|
|
64
|
+
|
|
65
|
+
print("# ai-toolkit")
|
|
66
|
+
print()
|
|
67
|
+
print(
|
|
68
|
+
f"> Professional-grade Claude Code toolkit: {skills} skills,"
|
|
69
|
+
f" {agents} agents, machine-enforced constitution, quality hooks."
|
|
70
|
+
)
|
|
71
|
+
print()
|
|
72
|
+
print("## Documentation")
|
|
73
|
+
print()
|
|
74
|
+
|
|
75
|
+
readme = toolkit_dir / "README.md"
|
|
76
|
+
if readme.is_file():
|
|
77
|
+
print("- [README](README.md): Installation, usage, and feature overview")
|
|
78
|
+
changelog = toolkit_dir / "CHANGELOG.md"
|
|
79
|
+
if changelog.is_file():
|
|
80
|
+
print("- [CHANGELOG](CHANGELOG.md): Version history")
|
|
81
|
+
contributing = toolkit_dir / "CONTRIBUTING.md"
|
|
82
|
+
if contributing.is_file():
|
|
83
|
+
print("- [CONTRIBUTING](CONTRIBUTING.md): How to add agents and skills")
|
|
84
|
+
architecture = toolkit_dir / "app" / "ARCHITECTURE.md"
|
|
85
|
+
if architecture.is_file():
|
|
86
|
+
print("- [ARCHITECTURE](app/ARCHITECTURE.md): System design")
|
|
87
|
+
constitution = toolkit_dir / "app" / "constitution.md"
|
|
88
|
+
if constitution.is_file():
|
|
89
|
+
print("- [CONSTITUTION](app/constitution.md): Safety rules")
|
|
90
|
+
|
|
91
|
+
kb_files = _find_kb_files()
|
|
92
|
+
if kb_files:
|
|
93
|
+
print()
|
|
94
|
+
print("## Knowledge Base")
|
|
95
|
+
print()
|
|
96
|
+
for f in kb_files:
|
|
97
|
+
rel = _relative(f)
|
|
98
|
+
title = _title_from_md(f)
|
|
99
|
+
print(f"- [{title}]({rel})")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def generate_skills_listing() -> None:
|
|
103
|
+
"""Print the skills listing section."""
|
|
104
|
+
print()
|
|
105
|
+
print("## Skills")
|
|
106
|
+
print()
|
|
107
|
+
|
|
108
|
+
for skill_file in _find_skill_files():
|
|
109
|
+
skill_name = frontmatter_field(skill_file, "name")
|
|
110
|
+
if not skill_name:
|
|
111
|
+
skill_name = skill_file.parent.name
|
|
112
|
+
skill_desc = frontmatter_field(skill_file, "description")
|
|
113
|
+
print(f"- **{skill_name}**: {skill_desc}")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def generate_agents_listing() -> None:
|
|
117
|
+
"""Print the agents listing section."""
|
|
118
|
+
print()
|
|
119
|
+
print("## Agents")
|
|
120
|
+
print()
|
|
121
|
+
|
|
122
|
+
for agent_file in _find_agent_files():
|
|
123
|
+
if not agent_file.is_file():
|
|
124
|
+
continue
|
|
125
|
+
agent_name = frontmatter_field(agent_file, "name")
|
|
126
|
+
if not agent_name:
|
|
127
|
+
agent_name = agent_file.stem
|
|
128
|
+
agent_desc = frontmatter_field(agent_file, "description")
|
|
129
|
+
print(f"- **{agent_name}**: {agent_desc}")
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def generate_full() -> None:
|
|
133
|
+
"""Print full llms-full.txt with all KB content inlined."""
|
|
134
|
+
generate_index()
|
|
135
|
+
generate_skills_listing()
|
|
136
|
+
generate_agents_listing()
|
|
137
|
+
|
|
138
|
+
kb_files = _find_kb_files()
|
|
139
|
+
if kb_files:
|
|
140
|
+
print()
|
|
141
|
+
print("---")
|
|
142
|
+
print()
|
|
143
|
+
|
|
144
|
+
for f in kb_files:
|
|
145
|
+
rel = _relative(f)
|
|
146
|
+
print(f"## {rel}")
|
|
147
|
+
print()
|
|
148
|
+
sys.stdout.write(f.read_text(encoding="utf-8"))
|
|
149
|
+
print()
|
|
150
|
+
print("---")
|
|
151
|
+
print()
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def main() -> None:
|
|
155
|
+
full_mode = "--full" in sys.argv[1:]
|
|
156
|
+
|
|
157
|
+
if full_mode:
|
|
158
|
+
generate_full()
|
|
159
|
+
else:
|
|
160
|
+
generate_index()
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
if __name__ == "__main__":
|
|
164
|
+
main()
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generate .roomodes JSON from app/agents/*.md.
|
|
3
|
+
|
|
4
|
+
Usage: ./scripts/generate_roo_modes.py > .roomodes
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
12
|
+
from _common import agents_dir, frontmatter_field
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _json_escape(s: str) -> str:
|
|
16
|
+
"""Escape a string for safe JSON embedding (no stdlib json dependency needed)."""
|
|
17
|
+
s = s.replace("\\", "\\\\")
|
|
18
|
+
s = s.replace('"', '\\"')
|
|
19
|
+
s = s.replace("\n", "\\n")
|
|
20
|
+
s = s.replace("\t", "\\t")
|
|
21
|
+
s = s.replace("\r", "")
|
|
22
|
+
return s
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _read_body(filepath: Path) -> str:
|
|
26
|
+
"""Read file content after YAML frontmatter (after second --- delimiter).
|
|
27
|
+
|
|
28
|
+
Trailing blank lines are stripped to match bash ``$(...)`` behaviour.
|
|
29
|
+
"""
|
|
30
|
+
lines: list[str] = []
|
|
31
|
+
fence_count = 0
|
|
32
|
+
with open(filepath, encoding="utf-8") as f:
|
|
33
|
+
for line in f:
|
|
34
|
+
stripped = line.rstrip("\n")
|
|
35
|
+
if stripped == "---":
|
|
36
|
+
fence_count += 1
|
|
37
|
+
continue
|
|
38
|
+
if fence_count >= 2:
|
|
39
|
+
lines.append(line.rstrip("\n"))
|
|
40
|
+
# Strip trailing empty lines (bash command substitution strips trailing newlines)
|
|
41
|
+
while lines and not lines[-1]:
|
|
42
|
+
lines.pop()
|
|
43
|
+
return "\n".join(lines)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def main() -> None:
|
|
47
|
+
first = True
|
|
48
|
+
sys.stdout.write('{\n "customModes": [\n')
|
|
49
|
+
|
|
50
|
+
for agent_file in sorted(agents_dir.glob("*.md")):
|
|
51
|
+
if not agent_file.is_file():
|
|
52
|
+
continue
|
|
53
|
+
|
|
54
|
+
slug = agent_file.stem
|
|
55
|
+
name = frontmatter_field(agent_file, "name")
|
|
56
|
+
description = frontmatter_field(agent_file, "description")
|
|
57
|
+
|
|
58
|
+
if not name or not description:
|
|
59
|
+
continue
|
|
60
|
+
|
|
61
|
+
role_def = _read_body(agent_file)
|
|
62
|
+
role_text = f"{description}\n\n{role_def}"
|
|
63
|
+
|
|
64
|
+
if first:
|
|
65
|
+
first = False
|
|
66
|
+
else:
|
|
67
|
+
sys.stdout.write(",\n")
|
|
68
|
+
|
|
69
|
+
sys.stdout.write(" {\n")
|
|
70
|
+
sys.stdout.write(f' "slug": "{_json_escape(slug)}",\n')
|
|
71
|
+
sys.stdout.write(f' "name": "{_json_escape(name)}",\n')
|
|
72
|
+
sys.stdout.write(f' "roleDefinition": "{_json_escape(role_text)}",\n')
|
|
73
|
+
sys.stdout.write(' "groups": ["read", "edit", "command", "mcp"]\n')
|
|
74
|
+
sys.stdout.write(" }")
|
|
75
|
+
|
|
76
|
+
sys.stdout.write("\n ]\n}\n")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
if __name__ == "__main__":
|
|
80
|
+
main()
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generate .windsurfrules from app/agents/*.md and app/skills/*/SKILL.md.
|
|
3
|
+
|
|
4
|
+
Usage: ./scripts/generate_windsurf.py > .windsurfrules
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
12
|
+
from generator_base import render_generator
|
|
13
|
+
|
|
14
|
+
if __name__ == "__main__":
|
|
15
|
+
render_generator({
|
|
16
|
+
"title": "# Windsurf Rules — generated from ai-toolkit agents",
|
|
17
|
+
"header_lines": [
|
|
18
|
+
"# Auto-generated by scripts/generate-windsurf.sh — do not edit manually.",
|
|
19
|
+
"# Regenerate: ./scripts/generate-windsurf.sh > .windsurfrules",
|
|
20
|
+
],
|
|
21
|
+
"intro_template": (
|
|
22
|
+
"This repository uses the ai-toolkit — a shared AI development toolkit"
|
|
23
|
+
" with {agents} specialized agent personas and {skills} skills."
|
|
24
|
+
),
|
|
25
|
+
"agents_section": "## Available Agent Personas",
|
|
26
|
+
"agents_intro": "Apply the expertise of these agents when working on relevant tasks:",
|
|
27
|
+
"agents_format": "headings",
|
|
28
|
+
"agents_level": "##",
|
|
29
|
+
"skills_section": "## Available Skills",
|
|
30
|
+
"skills_intro": "The following skills are available as slash commands or knowledge sources:",
|
|
31
|
+
"skills_format": "headings",
|
|
32
|
+
"skills_level": "##",
|
|
33
|
+
"trailing_newline_after_skills": True,
|
|
34
|
+
"guidelines": ["general"],
|
|
35
|
+
})
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"""Shared generator pipeline for producing AI tool configs.
|
|
2
|
+
|
|
3
|
+
Each generator declares its output format via a config dict.
|
|
4
|
+
This module handles the shared pipeline: count → emit → wrap.
|
|
5
|
+
|
|
6
|
+
Stdlib-only.
|
|
7
|
+
|
|
8
|
+
Usage::
|
|
9
|
+
|
|
10
|
+
from generator_base import render_generator
|
|
11
|
+
|
|
12
|
+
render_generator({
|
|
13
|
+
"title": "# Cursor Rules",
|
|
14
|
+
"header_lines": ["# Auto-generated..."],
|
|
15
|
+
"intro_template": "This repo uses ai-toolkit with {agents} agents and {skills} skills.",
|
|
16
|
+
"agents_section": "## Available Agent Personas",
|
|
17
|
+
"agents_format": "headings", # "headings" or "bullets"
|
|
18
|
+
"agents_level": "##", # heading level (for "headings" format)
|
|
19
|
+
"skills_section": "## Available Skills",
|
|
20
|
+
"skills_format": "headings", # "headings" or "bullets"
|
|
21
|
+
"skills_level": "##", # heading level (for "headings" format)
|
|
22
|
+
"guidelines_fn": "general", # "general"|"quality"|"quality_standards"|"workflow"|None
|
|
23
|
+
"use_markers": True, # wrap in TOOLKIT markers
|
|
24
|
+
"trailing_newline_after_skills": True, # extra blank line after skills
|
|
25
|
+
})
|
|
26
|
+
"""
|
|
27
|
+
from __future__ import annotations
|
|
28
|
+
|
|
29
|
+
import sys
|
|
30
|
+
|
|
31
|
+
from emission import (
|
|
32
|
+
count_agents_and_skills,
|
|
33
|
+
emit_agents_bullets,
|
|
34
|
+
emit_agents_headings,
|
|
35
|
+
emit_skills_bullets,
|
|
36
|
+
emit_skills_headings,
|
|
37
|
+
generate_general_guidelines,
|
|
38
|
+
generate_quality_guidelines,
|
|
39
|
+
generate_quality_standards,
|
|
40
|
+
generate_workflow_guidelines,
|
|
41
|
+
print_toolkit_end,
|
|
42
|
+
print_toolkit_start,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Map guideline names to functions
|
|
46
|
+
_GUIDELINES = {
|
|
47
|
+
"general": generate_general_guidelines,
|
|
48
|
+
"quality": generate_quality_guidelines,
|
|
49
|
+
"quality_standards": generate_quality_standards,
|
|
50
|
+
"workflow": generate_workflow_guidelines,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def render_generator(config: dict) -> None:
|
|
55
|
+
"""Render a generator output based on a declarative config.
|
|
56
|
+
|
|
57
|
+
Config keys:
|
|
58
|
+
title: str — main heading line
|
|
59
|
+
header_lines: list[str] — additional header lines (comments etc)
|
|
60
|
+
intro_template: str — format string with {agents} and {skills}
|
|
61
|
+
agents_section: str — heading for agents section
|
|
62
|
+
agents_format: "headings" | "bullets"
|
|
63
|
+
agents_level: str — heading level for headings format (default "##")
|
|
64
|
+
skills_section: str — heading for skills section
|
|
65
|
+
skills_format: "headings" | "bullets"
|
|
66
|
+
skills_level: str — heading level for headings format (default "##")
|
|
67
|
+
guidelines: list[str] — list of guideline block names to include
|
|
68
|
+
use_markers: bool — wrap in TOOLKIT markers (default True)
|
|
69
|
+
trailing_newline_after_skills: bool — extra blank line after skills emit
|
|
70
|
+
"""
|
|
71
|
+
agents, skills = count_agents_and_skills()
|
|
72
|
+
|
|
73
|
+
if config.get("use_markers", True):
|
|
74
|
+
print_toolkit_start()
|
|
75
|
+
|
|
76
|
+
# Title
|
|
77
|
+
if "title" in config:
|
|
78
|
+
print(config["title"])
|
|
79
|
+
|
|
80
|
+
# Header lines
|
|
81
|
+
for line in config.get("header_lines", []):
|
|
82
|
+
print(line)
|
|
83
|
+
|
|
84
|
+
# Intro
|
|
85
|
+
if "intro_template" in config:
|
|
86
|
+
if config.get("header_lines") or "title" in config:
|
|
87
|
+
print()
|
|
88
|
+
print(config["intro_template"].format(agents=agents, skills=skills))
|
|
89
|
+
|
|
90
|
+
# Agents section
|
|
91
|
+
if "agents_section" in config:
|
|
92
|
+
print()
|
|
93
|
+
print(config["agents_section"].format(agents=agents, skills=skills))
|
|
94
|
+
print()
|
|
95
|
+
agents_intro = config.get("agents_intro")
|
|
96
|
+
if agents_intro:
|
|
97
|
+
print(agents_intro)
|
|
98
|
+
print()
|
|
99
|
+
|
|
100
|
+
fmt = config.get("agents_format", "headings")
|
|
101
|
+
level = config.get("agents_level", "##")
|
|
102
|
+
if fmt == "bullets":
|
|
103
|
+
print(emit_agents_bullets())
|
|
104
|
+
else:
|
|
105
|
+
print(emit_agents_headings(level))
|
|
106
|
+
|
|
107
|
+
# Skills section
|
|
108
|
+
if "skills_section" in config:
|
|
109
|
+
# Bullets format needs a separator; headings already end with blank line
|
|
110
|
+
if config.get("agents_format") == "bullets":
|
|
111
|
+
print()
|
|
112
|
+
print(config["skills_section"].format(agents=agents, skills=skills))
|
|
113
|
+
print()
|
|
114
|
+
skills_intro = config.get("skills_intro")
|
|
115
|
+
if skills_intro:
|
|
116
|
+
print(skills_intro)
|
|
117
|
+
print()
|
|
118
|
+
|
|
119
|
+
fmt = config.get("skills_format", "headings")
|
|
120
|
+
level = config.get("skills_level", "##")
|
|
121
|
+
if fmt == "bullets":
|
|
122
|
+
print(emit_skills_bullets())
|
|
123
|
+
else:
|
|
124
|
+
# Use sys.stdout.write to match original output (no trailing newline)
|
|
125
|
+
sys.stdout.write(emit_skills_headings(level))
|
|
126
|
+
|
|
127
|
+
if config.get("trailing_newline_after_skills", False):
|
|
128
|
+
print()
|
|
129
|
+
|
|
130
|
+
# Guidelines
|
|
131
|
+
for guideline_name in config.get("guidelines", []):
|
|
132
|
+
print()
|
|
133
|
+
fn = _GUIDELINES.get(guideline_name)
|
|
134
|
+
if fn:
|
|
135
|
+
print(fn())
|
|
136
|
+
|
|
137
|
+
# End marker
|
|
138
|
+
if config.get("use_markers", True):
|
|
139
|
+
print()
|
|
140
|
+
print_toolkit_end()
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""harvest-ecosystem — Refresh machine-readable ecosystem snapshot.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
harvest_ecosystem.py [--offline] [--out FILE]
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import subprocess
|
|
10
|
+
import sys
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
14
|
+
from _common import toolkit_dir
|
|
15
|
+
|
|
16
|
+
OUTFILE = toolkit_dir / "benchmarks" / "ecosystem-harvest.json"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def main() -> None:
|
|
20
|
+
outfile = str(OUTFILE)
|
|
21
|
+
passthrough: list[str] = []
|
|
22
|
+
|
|
23
|
+
args = sys.argv[1:]
|
|
24
|
+
i = 0
|
|
25
|
+
while i < len(args):
|
|
26
|
+
if args[i] == "--out":
|
|
27
|
+
i += 1
|
|
28
|
+
if i < len(args):
|
|
29
|
+
outfile = args[i]
|
|
30
|
+
else:
|
|
31
|
+
passthrough.append(args[i])
|
|
32
|
+
i += 1
|
|
33
|
+
|
|
34
|
+
Path(outfile).parent.mkdir(parents=True, exist_ok=True)
|
|
35
|
+
|
|
36
|
+
cmd = [
|
|
37
|
+
sys.executable,
|
|
38
|
+
str(toolkit_dir / "scripts" / "benchmark_ecosystem.py"),
|
|
39
|
+
"--dashboard-json",
|
|
40
|
+
*passthrough,
|
|
41
|
+
"--out", outfile,
|
|
42
|
+
]
|
|
43
|
+
result = subprocess.run(cmd)
|
|
44
|
+
if result.returncode == 0:
|
|
45
|
+
print(f"Harvested ecosystem snapshot: {outfile}")
|
|
46
|
+
sys.exit(result.returncode)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
main()
|