@event4u/agent-config 1.9.1
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/.agent-src/README.md +64 -0
- package/.agent-src/commands/agent-handoff.md +64 -0
- package/.agent-src/commands/agent-status.md +83 -0
- package/.agent-src/commands/agents-audit.md +243 -0
- package/.agent-src/commands/agents-cleanup.md +169 -0
- package/.agent-src/commands/agents-prepare.md +137 -0
- package/.agent-src/commands/analyze-reference-repo.md +191 -0
- package/.agent-src/commands/bug-fix.md +181 -0
- package/.agent-src/commands/bug-investigate.md +175 -0
- package/.agent-src/commands/commit.md +121 -0
- package/.agent-src/commands/compress.md +177 -0
- package/.agent-src/commands/config-agent-settings.md +126 -0
- package/.agent-src/commands/context-create.md +167 -0
- package/.agent-src/commands/context-refactor.md +170 -0
- package/.agent-src/commands/copilot-agents-init.md +150 -0
- package/.agent-src/commands/copilot-agents-optimize.md +251 -0
- package/.agent-src/commands/create-pr-description.md +112 -0
- package/.agent-src/commands/create-pr.md +76 -0
- package/.agent-src/commands/do-and-judge.md +114 -0
- package/.agent-src/commands/do-in-steps.md +84 -0
- package/.agent-src/commands/e2e-heal.md +98 -0
- package/.agent-src/commands/e2e-plan.md +85 -0
- package/.agent-src/commands/estimate-ticket.md +80 -0
- package/.agent-src/commands/feature-dev.md +111 -0
- package/.agent-src/commands/feature-explore.md +180 -0
- package/.agent-src/commands/feature-plan.md +288 -0
- package/.agent-src/commands/feature-refactor.md +181 -0
- package/.agent-src/commands/feature-roadmap.md +184 -0
- package/.agent-src/commands/fix-ci.md +48 -0
- package/.agent-src/commands/fix-portability.md +97 -0
- package/.agent-src/commands/fix-pr-bot-comments.md +146 -0
- package/.agent-src/commands/fix-pr-comments.md +58 -0
- package/.agent-src/commands/fix-pr-developer-comments.md +152 -0
- package/.agent-src/commands/fix-references.md +94 -0
- package/.agent-src/commands/fix-seeder.md +146 -0
- package/.agent-src/commands/implement-ticket.md +133 -0
- package/.agent-src/commands/jira-ticket.md +71 -0
- package/.agent-src/commands/judge.md +86 -0
- package/.agent-src/commands/memory-add.md +130 -0
- package/.agent-src/commands/memory-full.md +97 -0
- package/.agent-src/commands/memory-promote.md +144 -0
- package/.agent-src/commands/mode.md +121 -0
- package/.agent-src/commands/module-create.md +132 -0
- package/.agent-src/commands/module-explore.md +157 -0
- package/.agent-src/commands/optimize-agents.md +139 -0
- package/.agent-src/commands/optimize-augmentignore.md +262 -0
- package/.agent-src/commands/optimize-rtk-filters.md +120 -0
- package/.agent-src/commands/optimize-skills.md +121 -0
- package/.agent-src/commands/override-create.md +97 -0
- package/.agent-src/commands/override-manage.md +96 -0
- package/.agent-src/commands/package-reset.md +154 -0
- package/.agent-src/commands/package-test.md +154 -0
- package/.agent-src/commands/prepare-for-review.md +91 -0
- package/.agent-src/commands/project-analyze.md +300 -0
- package/.agent-src/commands/project-health.md +95 -0
- package/.agent-src/commands/propose-memory.md +108 -0
- package/.agent-src/commands/quality-fix.md +106 -0
- package/.agent-src/commands/refine-ticket.md +81 -0
- package/.agent-src/commands/review-changes.md +130 -0
- package/.agent-src/commands/review-routing.md +111 -0
- package/.agent-src/commands/roadmap-create.md +110 -0
- package/.agent-src/commands/roadmap-execute.md +68 -0
- package/.agent-src/commands/rule-compliance-audit.md +139 -0
- package/.agent-src/commands/tests-create.md +73 -0
- package/.agent-src/commands/tests-execute.md +58 -0
- package/.agent-src/commands/threat-model.md +115 -0
- package/.agent-src/commands/update-form-request-messages.md +189 -0
- package/.agent-src/commands/upstream-contribute.md +171 -0
- package/.agent-src/contexts/augment-infrastructure.md +181 -0
- package/.agent-src/contexts/documentation-hierarchy.md +142 -0
- package/.agent-src/contexts/model-recommendations.md +142 -0
- package/.agent-src/contexts/override-system.md +187 -0
- package/.agent-src/contexts/skills-and-commands.md +154 -0
- package/.agent-src/contexts/subagent-configuration.md +62 -0
- package/.agent-src/guidelines/agent-infra/agent-interaction-and-decision-quality.md +110 -0
- package/.agent-src/guidelines/agent-infra/break-glass-usage.md +113 -0
- package/.agent-src/guidelines/agent-infra/developer-judgment.md +82 -0
- package/.agent-src/guidelines/agent-infra/engineering-memory-data-format.md +117 -0
- package/.agent-src/guidelines/agent-infra/layered-settings.md +158 -0
- package/.agent-src/guidelines/agent-infra/memory-access.md +121 -0
- package/.agent-src/guidelines/agent-infra/naming.md +69 -0
- package/.agent-src/guidelines/agent-infra/output-patterns.md +117 -0
- package/.agent-src/guidelines/agent-infra/review-routing-data-format.md +144 -0
- package/.agent-src/guidelines/agent-infra/role-contracts.md +211 -0
- package/.agent-src/guidelines/agent-infra/role-mode-router.md +89 -0
- package/.agent-src/guidelines/agent-infra/runtime-layer.md +89 -0
- package/.agent-src/guidelines/agent-infra/self-improvement-pipeline.md +135 -0
- package/.agent-src/guidelines/agent-infra/size-and-scope.md +189 -0
- package/.agent-src/guidelines/agent-infra/tool-integration.md +73 -0
- package/.agent-src/guidelines/docs/readme-size-and-splitting.md +153 -0
- package/.agent-src/guidelines/e2e/playwright.md +363 -0
- package/.agent-src/guidelines/php/api-design.md +115 -0
- package/.agent-src/guidelines/php/artisan-commands.md +81 -0
- package/.agent-src/guidelines/php/blade-ui.md +78 -0
- package/.agent-src/guidelines/php/controllers.md +90 -0
- package/.agent-src/guidelines/php/database.md +111 -0
- package/.agent-src/guidelines/php/eloquent.md +208 -0
- package/.agent-src/guidelines/php/flux.md +80 -0
- package/.agent-src/guidelines/php/general.md +191 -0
- package/.agent-src/guidelines/php/git.md +96 -0
- package/.agent-src/guidelines/php/jobs.md +111 -0
- package/.agent-src/guidelines/php/livewire.md +71 -0
- package/.agent-src/guidelines/php/logging.md +79 -0
- package/.agent-src/guidelines/php/naming.md +89 -0
- package/.agent-src/guidelines/php/patterns/dependency-injection.md +57 -0
- package/.agent-src/guidelines/php/patterns/dtos.md +199 -0
- package/.agent-src/guidelines/php/patterns/events.md +67 -0
- package/.agent-src/guidelines/php/patterns/factory.md +53 -0
- package/.agent-src/guidelines/php/patterns/pipelines.md +66 -0
- package/.agent-src/guidelines/php/patterns/policies.md +66 -0
- package/.agent-src/guidelines/php/patterns/repositories.md +122 -0
- package/.agent-src/guidelines/php/patterns/service-layer.md +64 -0
- package/.agent-src/guidelines/php/patterns/strategy.md +69 -0
- package/.agent-src/guidelines/php/patterns.md +28 -0
- package/.agent-src/guidelines/php/performance.md +92 -0
- package/.agent-src/guidelines/php/resources.md +100 -0
- package/.agent-src/guidelines/php/security.md +110 -0
- package/.agent-src/guidelines/php/sql.md +97 -0
- package/.agent-src/guidelines/php/validations.md +119 -0
- package/.agent-src/guidelines/php/websocket.md +100 -0
- package/.agent-src/personas/README.md +104 -0
- package/.agent-src/personas/ai-agent.md +77 -0
- package/.agent-src/personas/critical-challenger.md +73 -0
- package/.agent-src/personas/developer.md +73 -0
- package/.agent-src/personas/product-owner.md +78 -0
- package/.agent-src/personas/qa.md +67 -0
- package/.agent-src/personas/senior-engineer.md +77 -0
- package/.agent-src/personas/stakeholder.md +78 -0
- package/.agent-src/rules/agent-docs.md +61 -0
- package/.agent-src/rules/analysis-skill-routing.md +48 -0
- package/.agent-src/rules/architecture.md +62 -0
- package/.agent-src/rules/artifact-drafting-protocol.md +73 -0
- package/.agent-src/rules/ask-when-uncertain.md +52 -0
- package/.agent-src/rules/augment-portability.md +38 -0
- package/.agent-src/rules/augment-source-of-truth.md +128 -0
- package/.agent-src/rules/capture-learnings.md +89 -0
- package/.agent-src/rules/cli-output-handling.md +94 -0
- package/.agent-src/rules/commit-conventions.md +64 -0
- package/.agent-src/rules/context-hygiene.md +90 -0
- package/.agent-src/rules/docker-commands.md +55 -0
- package/.agent-src/rules/docs-sync.md +79 -0
- package/.agent-src/rules/downstream-changes.md +70 -0
- package/.agent-src/rules/e2e-testing.md +53 -0
- package/.agent-src/rules/guidelines.md +90 -0
- package/.agent-src/rules/improve-before-implement.md +94 -0
- package/.agent-src/rules/language-and-tone.md +104 -0
- package/.agent-src/rules/laravel-translations.md +48 -0
- package/.agent-src/rules/markdown-safe-codeblocks.md +18 -0
- package/.agent-src/rules/minimal-safe-diff.md +87 -0
- package/.agent-src/rules/missing-tool-handling.md +62 -0
- package/.agent-src/rules/model-recommendation.md +70 -0
- package/.agent-src/rules/package-ci-checks.md +80 -0
- package/.agent-src/rules/php-coding.md +63 -0
- package/.agent-src/rules/preservation-guard.md +29 -0
- package/.agent-src/rules/review-routing-awareness.md +125 -0
- package/.agent-src/rules/reviewer-awareness.md +92 -0
- package/.agent-src/rules/roadmap-progress-sync.md +56 -0
- package/.agent-src/rules/role-mode-adherence.md +54 -0
- package/.agent-src/rules/rule-type-governance.md +46 -0
- package/.agent-src/rules/runtime-safety.md +42 -0
- package/.agent-src/rules/scope-control.md +40 -0
- package/.agent-src/rules/security-sensitive-stop.md +77 -0
- package/.agent-src/rules/size-enforcement.md +29 -0
- package/.agent-src/rules/skill-improvement-trigger.md +58 -0
- package/.agent-src/rules/skill-quality.md +110 -0
- package/.agent-src/rules/slash-commands.md +30 -0
- package/.agent-src/rules/think-before-action.md +91 -0
- package/.agent-src/rules/token-efficiency.md +99 -0
- package/.agent-src/rules/tool-safety.md +36 -0
- package/.agent-src/rules/upstream-proposal.md +76 -0
- package/.agent-src/rules/user-interaction.md +79 -0
- package/.agent-src/rules/verify-before-complete.md +120 -0
- package/.agent-src/scripts/scan-seeder-violations.php +145 -0
- package/.agent-src/scripts/update_roadmap_progress.py +244 -0
- package/.agent-src/skills/adversarial-review/SKILL.md +149 -0
- package/.agent-src/skills/agent-docs-writing/SKILL.md +234 -0
- package/.agent-src/skills/analysis-autonomous-mode/SKILL.md +197 -0
- package/.agent-src/skills/analysis-skill-router/SKILL.md +134 -0
- package/.agent-src/skills/api-design/SKILL.md +104 -0
- package/.agent-src/skills/api-endpoint/SKILL.md +185 -0
- package/.agent-src/skills/api-testing/SKILL.md +206 -0
- package/.agent-src/skills/artisan-commands/SKILL.md +78 -0
- package/.agent-src/skills/authz-review/SKILL.md +171 -0
- package/.agent-src/skills/aws-infrastructure/SKILL.md +152 -0
- package/.agent-src/skills/blade-ui/SKILL.md +75 -0
- package/.agent-src/skills/blast-radius-analyzer/SKILL.md +185 -0
- package/.agent-src/skills/bug-analyzer/SKILL.md +256 -0
- package/.agent-src/skills/check-refs/SKILL.md +72 -0
- package/.agent-src/skills/code-refactoring/SKILL.md +200 -0
- package/.agent-src/skills/code-review/SKILL.md +214 -0
- package/.agent-src/skills/command-routing/SKILL.md +96 -0
- package/.agent-src/skills/command-writing/SKILL.md +143 -0
- package/.agent-src/skills/composer-packages/SKILL.md +172 -0
- package/.agent-src/skills/context-authoring/SKILL.md +157 -0
- package/.agent-src/skills/context-document/SKILL.md +153 -0
- package/.agent-src/skills/conventional-commits-writing/SKILL.md +70 -0
- package/.agent-src/skills/copilot-agents-optimization/SKILL.md +220 -0
- package/.agent-src/skills/copilot-config/SKILL.md +203 -0
- package/.agent-src/skills/dashboard-design/SKILL.md +116 -0
- package/.agent-src/skills/data-flow-mapper/SKILL.md +160 -0
- package/.agent-src/skills/database/SKILL.md +91 -0
- package/.agent-src/skills/dependency-upgrade/SKILL.md +204 -0
- package/.agent-src/skills/description-assist/SKILL.md +169 -0
- package/.agent-src/skills/design-review/SKILL.md +228 -0
- package/.agent-src/skills/devcontainer/SKILL.md +121 -0
- package/.agent-src/skills/developer-like-execution/SKILL.md +276 -0
- package/.agent-src/skills/docker/SKILL.md +245 -0
- package/.agent-src/skills/dto-creator/SKILL.md +117 -0
- package/.agent-src/skills/eloquent/SKILL.md +92 -0
- package/.agent-src/skills/eloquent/evals/last-run.json +99 -0
- package/.agent-src/skills/eloquent/evals/triggers.json +16 -0
- package/.agent-src/skills/estimate-ticket/SKILL.md +186 -0
- package/.agent-src/skills/estimate-ticket/evals/output-schema.yml +20 -0
- package/.agent-src/skills/estimate-ticket/evals/triggers.json +18 -0
- package/.agent-src/skills/fe-design/SKILL.md +223 -0
- package/.agent-src/skills/feature-planning/SKILL.md +226 -0
- package/.agent-src/skills/file-editor/SKILL.md +129 -0
- package/.agent-src/skills/finishing-a-development-branch/SKILL.md +200 -0
- package/.agent-src/skills/flux/SKILL.md +64 -0
- package/.agent-src/skills/git-workflow/SKILL.md +102 -0
- package/.agent-src/skills/github-ci/SKILL.md +122 -0
- package/.agent-src/skills/grafana/SKILL.md +168 -0
- package/.agent-src/skills/guideline-writing/SKILL.md +147 -0
- package/.agent-src/skills/jira-integration/SKILL.md +182 -0
- package/.agent-src/skills/jobs-events/SKILL.md +87 -0
- package/.agent-src/skills/judge-bug-hunter/SKILL.md +157 -0
- package/.agent-src/skills/judge-code-quality/SKILL.md +158 -0
- package/.agent-src/skills/judge-security-auditor/SKILL.md +167 -0
- package/.agent-src/skills/judge-test-coverage/SKILL.md +154 -0
- package/.agent-src/skills/laravel/SKILL.md +195 -0
- package/.agent-src/skills/laravel-horizon/SKILL.md +169 -0
- package/.agent-src/skills/laravel-mail/SKILL.md +193 -0
- package/.agent-src/skills/laravel-middleware/SKILL.md +185 -0
- package/.agent-src/skills/laravel-notifications/SKILL.md +168 -0
- package/.agent-src/skills/laravel-pennant/SKILL.md +188 -0
- package/.agent-src/skills/laravel-pulse/SKILL.md +160 -0
- package/.agent-src/skills/laravel-reverb/SKILL.md +205 -0
- package/.agent-src/skills/laravel-scheduling/SKILL.md +167 -0
- package/.agent-src/skills/laravel-validation/SKILL.md +71 -0
- package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +249 -0
- package/.agent-src/skills/lint-skills/SKILL.md +72 -0
- package/.agent-src/skills/livewire/SKILL.md +79 -0
- package/.agent-src/skills/logging-monitoring/SKILL.md +100 -0
- package/.agent-src/skills/mcp/SKILL.md +193 -0
- package/.agent-src/skills/merge-conflicts/SKILL.md +158 -0
- package/.agent-src/skills/migration-creator/SKILL.md +160 -0
- package/.agent-src/skills/module-management/SKILL.md +154 -0
- package/.agent-src/skills/multi-tenancy/SKILL.md +129 -0
- package/.agent-src/skills/openapi/SKILL.md +154 -0
- package/.agent-src/skills/override-management/SKILL.md +186 -0
- package/.agent-src/skills/performance/SKILL.md +69 -0
- package/.agent-src/skills/performance-analysis/SKILL.md +118 -0
- package/.agent-src/skills/pest-testing/SKILL.md +321 -0
- package/.agent-src/skills/php-coder/SKILL.md +78 -0
- package/.agent-src/skills/php-coder/evals/triggers.json +16 -0
- package/.agent-src/skills/php-debugging/SKILL.md +184 -0
- package/.agent-src/skills/php-service/SKILL.md +96 -0
- package/.agent-src/skills/playwright-testing/SKILL.md +244 -0
- package/.agent-src/skills/project-analysis-core/SKILL.md +138 -0
- package/.agent-src/skills/project-analysis-hypothesis-driven/SKILL.md +130 -0
- package/.agent-src/skills/project-analysis-laravel/SKILL.md +119 -0
- package/.agent-src/skills/project-analysis-nextjs/SKILL.md +123 -0
- package/.agent-src/skills/project-analysis-node-express/SKILL.md +111 -0
- package/.agent-src/skills/project-analysis-react/SKILL.md +119 -0
- package/.agent-src/skills/project-analysis-symfony/SKILL.md +111 -0
- package/.agent-src/skills/project-analysis-zend-laminas/SKILL.md +108 -0
- package/.agent-src/skills/project-analyzer/SKILL.md +341 -0
- package/.agent-src/skills/project-docs/SKILL.md +137 -0
- package/.agent-src/skills/quality-tools/SKILL.md +411 -0
- package/.agent-src/skills/readme-reviewer/SKILL.md +187 -0
- package/.agent-src/skills/readme-writing/SKILL.md +142 -0
- package/.agent-src/skills/readme-writing-package/SKILL.md +185 -0
- package/.agent-src/skills/receiving-code-review/SKILL.md +190 -0
- package/.agent-src/skills/refine-ticket/SKILL.md +310 -0
- package/.agent-src/skills/refine-ticket/detection-map.yml +124 -0
- package/.agent-src/skills/refine-ticket/evals/output-schema.yml +16 -0
- package/.agent-src/skills/refine-ticket/evals/triggers.json +16 -0
- package/.agent-src/skills/requesting-code-review/SKILL.md +199 -0
- package/.agent-src/skills/review-routing/SKILL.md +195 -0
- package/.agent-src/skills/roadmap-management/SKILL.md +303 -0
- package/.agent-src/skills/rtk-output-filtering/SKILL.md +184 -0
- package/.agent-src/skills/rule-writing/SKILL.md +148 -0
- package/.agent-src/skills/security/SKILL.md +79 -0
- package/.agent-src/skills/security-audit/SKILL.md +123 -0
- package/.agent-src/skills/sentry-integration/SKILL.md +170 -0
- package/.agent-src/skills/sequential-thinking/SKILL.md +158 -0
- package/.agent-src/skills/skill-improvement-pipeline/SKILL.md +155 -0
- package/.agent-src/skills/skill-management/SKILL.md +121 -0
- package/.agent-src/skills/skill-reviewer/SKILL.md +218 -0
- package/.agent-src/skills/skill-writing/SKILL.md +291 -0
- package/.agent-src/skills/skill-writing/evals/triggers.json +16 -0
- package/.agent-src/skills/sql-writing/SKILL.md +74 -0
- package/.agent-src/skills/subagent-orchestration/SKILL.md +190 -0
- package/.agent-src/skills/systematic-debugging/SKILL.md +244 -0
- package/.agent-src/skills/technical-specification/SKILL.md +185 -0
- package/.agent-src/skills/terraform/SKILL.md +137 -0
- package/.agent-src/skills/terragrunt/SKILL.md +217 -0
- package/.agent-src/skills/test-driven-development/SKILL.md +252 -0
- package/.agent-src/skills/test-performance/SKILL.md +172 -0
- package/.agent-src/skills/threat-modeling/SKILL.md +189 -0
- package/.agent-src/skills/traefik/SKILL.md +319 -0
- package/.agent-src/skills/universal-project-analysis/SKILL.md +179 -0
- package/.agent-src/skills/upstream-contribute/SKILL.md +255 -0
- package/.agent-src/skills/using-git-worktrees/SKILL.md +148 -0
- package/.agent-src/skills/validate-feature-fit/SKILL.md +113 -0
- package/.agent-src/skills/verify-before-complete/SKILL.md +188 -0
- package/.agent-src/skills/websocket/SKILL.md +75 -0
- package/.agent-src/templates/AGENTS.md +146 -0
- package/.agent-src/templates/agent-settings.md +256 -0
- package/.agent-src/templates/agents/.gitattributes.fragment +16 -0
- package/.agent-src/templates/agents/agent-project-settings.example.yml +138 -0
- package/.agent-src/templates/agents/memory/architecture-decisions.example.yml +95 -0
- package/.agent-src/templates/agents/memory/domain-invariants.example.yml +80 -0
- package/.agent-src/templates/agents/memory/historical-patterns.example.yml +82 -0
- package/.agent-src/templates/agents/memory/incident-learnings.example.yml +113 -0
- package/.agent-src/templates/agents/memory/ownership.example.yml +75 -0
- package/.agent-src/templates/agents/memory/product-rules.example.yml +87 -0
- package/.agent-src/templates/agents/proposal.example.md +143 -0
- package/.agent-src/templates/command.md +84 -0
- package/.agent-src/templates/contexts/auth-model.md +59 -0
- package/.agent-src/templates/contexts/data-sensitivity.md +60 -0
- package/.agent-src/templates/contexts/deployment-order.md +72 -0
- package/.agent-src/templates/contexts/observability.md +64 -0
- package/.agent-src/templates/contexts/tenant-boundaries.md +68 -0
- package/.agent-src/templates/contexts.md +116 -0
- package/.agent-src/templates/copilot-instructions.md +115 -0
- package/.agent-src/templates/features.md +125 -0
- package/.agent-src/templates/github-workflows/memory-hygiene.yml +133 -0
- package/.agent-src/templates/github-workflows/pr-risk-review.yml +123 -0
- package/.agent-src/templates/github-workflows/proposal-drift.yml +118 -0
- package/.agent-src/templates/overrides/command.md +24 -0
- package/.agent-src/templates/overrides/guideline.md +21 -0
- package/.agent-src/templates/overrides/rule.md +19 -0
- package/.agent-src/templates/overrides/skill.md +24 -0
- package/.agent-src/templates/overrides/template.md +21 -0
- package/.agent-src/templates/persona.md +99 -0
- package/.agent-src/templates/roadmaps.md +109 -0
- package/.agent-src/templates/scripts/README.md +195 -0
- package/.agent-src/templates/scripts/check_memory.py +283 -0
- package/.agent-src/templates/scripts/check_memory_proposal.py +180 -0
- package/.agent-src/templates/scripts/historical-bug-patterns.example.yml +84 -0
- package/.agent-src/templates/scripts/implement_ticket/__init__.py +57 -0
- package/.agent-src/templates/scripts/implement_ticket/__main__.py +9 -0
- package/.agent-src/templates/scripts/implement_ticket/cli.py +171 -0
- package/.agent-src/templates/scripts/implement_ticket/delivery_state.py +130 -0
- package/.agent-src/templates/scripts/implement_ticket/dispatcher.py +134 -0
- package/.agent-src/templates/scripts/implement_ticket/persona_policy.py +85 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/__init__.py +49 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/analyze.py +98 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/implement.py +145 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/memory.py +136 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/plan.py +175 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/refine.py +140 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/report.py +195 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/test.py +180 -0
- package/.agent-src/templates/scripts/implement_ticket/steps/verify.py +170 -0
- package/.agent-src/templates/scripts/memory_hash.py +75 -0
- package/.agent-src/templates/scripts/memory_lookup.py +216 -0
- package/.agent-src/templates/scripts/memory_report.py +184 -0
- package/.agent-src/templates/scripts/memory_signal.py +167 -0
- package/.agent-src/templates/scripts/memory_status.py +156 -0
- package/.agent-src/templates/scripts/ownership-map.example.yml +87 -0
- package/.agent-src/templates/scripts/pr-risk-config.example.yml +76 -0
- package/.agent-src/templates/scripts/pr_review_routing.py +340 -0
- package/.agent-src/templates/scripts/pr_risk_review.py +211 -0
- package/.agent-src/templates/skill.md +136 -0
- package/.augment-plugin/marketplace.json +32 -0
- package/.augment-plugin/plugin.json +21 -0
- package/.claude-plugin/marketplace.json +119 -0
- package/AGENTS.md +121 -0
- package/CHANGELOG.md +279 -0
- package/CONTRIBUTING.md +176 -0
- package/LICENSE +21 -0
- package/README.md +357 -0
- package/bin/install.php +38 -0
- package/composer.json +29 -0
- package/config/agent-settings.template.yml +96 -0
- package/config/profiles/balanced.ini +10 -0
- package/config/profiles/full.ini +10 -0
- package/config/profiles/minimal.ini +10 -0
- package/docs/architecture.md +144 -0
- package/docs/customization.md +88 -0
- package/docs/development.md +171 -0
- package/docs/getting-started.md +130 -0
- package/docs/github-topics.md +84 -0
- package/docs/installation.md +376 -0
- package/docs/mcp.md +133 -0
- package/docs/quality.md +98 -0
- package/docs/skills-catalog.md +136 -0
- package/docs/troubleshooting.md +167 -0
- package/llms.txt +130 -0
- package/package.json +31 -0
- package/scripts/audit_skill_descriptions.py +168 -0
- package/scripts/check_compression.py +221 -0
- package/scripts/check_memory.py +341 -0
- package/scripts/check_memory_proposal.py +180 -0
- package/scripts/check_portability.py +320 -0
- package/scripts/check_proposal.py +269 -0
- package/scripts/check_references.py +400 -0
- package/scripts/ci_summary.py +131 -0
- package/scripts/compress.py +671 -0
- package/scripts/compress.sh +18 -0
- package/scripts/first-run.sh +109 -0
- package/scripts/generate_catalog.py +116 -0
- package/scripts/install +151 -0
- package/scripts/install-hooks.sh +29 -0
- package/scripts/install.py +487 -0
- package/scripts/install.sh +637 -0
- package/scripts/install_anthropic_key.sh +101 -0
- package/scripts/inventory_frontmatter.py +164 -0
- package/scripts/lint_marketplace.py +142 -0
- package/scripts/lint_regression.py +232 -0
- package/scripts/mcp_render.py +159 -0
- package/scripts/measure_patterns.py +376 -0
- package/scripts/memory_hash.py +75 -0
- package/scripts/memory_lookup.py +441 -0
- package/scripts/memory_report.py +336 -0
- package/scripts/memory_signal.py +210 -0
- package/scripts/memory_status.py +195 -0
- package/scripts/postinstall.sh +60 -0
- package/scripts/readme_linter.py +580 -0
- package/scripts/refine_ticket_detect.py +623 -0
- package/scripts/requirements-evals.txt +7 -0
- package/scripts/runtime_dispatcher.py +265 -0
- package/scripts/runtime_handler.py +148 -0
- package/scripts/runtime_registry.py +166 -0
- package/scripts/schemas/command.schema.json +32 -0
- package/scripts/schemas/persona.schema.json +42 -0
- package/scripts/schemas/rule.schema.json +28 -0
- package/scripts/schemas/skill.schema.json +73 -0
- package/scripts/setup.sh +230 -0
- package/scripts/setup_eval_venv.sh +58 -0
- package/scripts/skill_linter.py +2175 -0
- package/scripts/skill_trigger_eval.py +651 -0
- package/scripts/tool_registry.py +146 -0
- package/scripts/tools/__init__.py +1 -0
- package/scripts/tools/adapter_errors.py +63 -0
- package/scripts/tools/base_adapter.py +91 -0
- package/scripts/tools/github_adapter.py +128 -0
- package/scripts/tools/jira_adapter.py +115 -0
- package/scripts/update_counts.py +147 -0
- package/scripts/validate_frontmatter.py +424 -0
- package/templates/consumer-settings/README.md +46 -0
- package/templates/consumer-settings/augment-settings.json +12 -0
- package/templates/consumer-settings/claude-settings.json +9 -0
- package/templates/consumer-settings/copilot-settings.json +14 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Sync package-content counts (skills/rules/commands/guidelines) across docs.
|
|
3
|
+
|
|
4
|
+
Source of truth: `.agent-src.uncompressed/`.
|
|
5
|
+
|
|
6
|
+
Target files have explicit regex patterns for each count mention — no
|
|
7
|
+
fuzzy matching, no risk of touching unrelated numbers.
|
|
8
|
+
|
|
9
|
+
Modes:
|
|
10
|
+
update (default) Rewrite each target to match the true counts.
|
|
11
|
+
--check Exit 1 if any target is stale.
|
|
12
|
+
|
|
13
|
+
Run as part of `task sync` (update) and `task ci` (check).
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import argparse
|
|
19
|
+
import re
|
|
20
|
+
import sys
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
24
|
+
SRC = REPO_ROOT / ".agent-src.uncompressed"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def count(kind: str) -> int:
|
|
28
|
+
if kind == "skills":
|
|
29
|
+
return sum(1 for _ in (SRC / "skills").rglob("SKILL.md"))
|
|
30
|
+
if kind == "guidelines":
|
|
31
|
+
# guidelines are grouped by topic subdirectory
|
|
32
|
+
return sum(1 for _ in (SRC / "guidelines").rglob("*.md"))
|
|
33
|
+
if kind == "personas":
|
|
34
|
+
# personas live as flat .md files, README excluded
|
|
35
|
+
pdir = SRC / "personas"
|
|
36
|
+
if not pdir.exists():
|
|
37
|
+
return 0
|
|
38
|
+
return sum(1 for f in pdir.glob("*.md") if f.name != "README.md")
|
|
39
|
+
return sum(1 for _ in (SRC / kind).glob("*.md"))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# file → list of (regex, kind)
|
|
43
|
+
# Each regex MUST use three capture groups: (prefix)(number)(suffix).
|
|
44
|
+
TARGETS: list[tuple[str, list[tuple[str, str]]]] = [
|
|
45
|
+
(
|
|
46
|
+
"README.md",
|
|
47
|
+
[
|
|
48
|
+
(r"(Browse all )(\d+)( commands\])", "commands"),
|
|
49
|
+
(r"(package \(rules \+ )(\d+)( skills)", "skills"),
|
|
50
|
+
(r"(skills \+ )(\d+)( native commands)", "commands"),
|
|
51
|
+
# Hero line: **NNN Skills** · **NNN Rules** · **NNN Commands** · **NNN Guidelines**
|
|
52
|
+
(r"(<strong>)(\d+)( Skills</strong>)", "skills"),
|
|
53
|
+
(r"(<strong>)(\d+)( Rules</strong>)", "rules"),
|
|
54
|
+
(r"(<strong>)(\d+)( Commands</strong>)", "commands"),
|
|
55
|
+
(r"(<strong>)(\d+)( Guidelines</strong>)", "guidelines"),
|
|
56
|
+
],
|
|
57
|
+
),
|
|
58
|
+
(
|
|
59
|
+
"AGENTS.md",
|
|
60
|
+
[
|
|
61
|
+
(r"(skills/\s+\()(\d+)( skills\))", "skills"),
|
|
62
|
+
(r"(rules/\s+\()(\d+)( rules\))", "rules"),
|
|
63
|
+
(r"(commands/\s+\()(\d+)( commands\))", "commands"),
|
|
64
|
+
(r"(guidelines/\s+\()(\d+)( guidelines\))", "guidelines"),
|
|
65
|
+
(r"(personas/\s+\()(\d+)( personas\))", "personas"),
|
|
66
|
+
],
|
|
67
|
+
),
|
|
68
|
+
(
|
|
69
|
+
"docs/getting-started.md",
|
|
70
|
+
[
|
|
71
|
+
(r"(automatically by )(\d+)( rules)", "rules"),
|
|
72
|
+
(r"(Browse all )(\d+)( commands\])", "commands"),
|
|
73
|
+
],
|
|
74
|
+
),
|
|
75
|
+
# Note: ``agents/roadmaps/road-to-stronger-skills.md`` was previously
|
|
76
|
+
# tracked here with a living ``baseline N as of`` pattern. The roadmap
|
|
77
|
+
# was moved to ``skipped/`` on 2026-04-23 (Q35 superseded), so its
|
|
78
|
+
# baseline is frozen as a historical snapshot and is no longer
|
|
79
|
+
# auto-synced.
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def apply_to_text(text: str, patterns: list[tuple[str, str]], counts: dict[str, int]) -> tuple[str, list[tuple[str, int, int]]]:
|
|
84
|
+
"""Return (new_text, drifts). Each drift is (kind, old, new)."""
|
|
85
|
+
drifts: list[tuple[str, int, int]] = []
|
|
86
|
+
new_text = text
|
|
87
|
+
for pattern, kind in patterns:
|
|
88
|
+
compiled = re.compile(pattern)
|
|
89
|
+
matches = list(compiled.finditer(new_text))
|
|
90
|
+
if not matches:
|
|
91
|
+
print(f" ⚠️ pattern missed: /{pattern}/ (kind={kind})", file=sys.stderr)
|
|
92
|
+
continue
|
|
93
|
+
for m in matches:
|
|
94
|
+
old = int(m.group(2))
|
|
95
|
+
new = counts[kind]
|
|
96
|
+
if old != new:
|
|
97
|
+
drifts.append((kind, old, new))
|
|
98
|
+
new_text = compiled.sub(
|
|
99
|
+
lambda m, k=kind: f"{m.group(1)}{counts[k]}{m.group(3)}",
|
|
100
|
+
new_text,
|
|
101
|
+
)
|
|
102
|
+
return new_text, drifts
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def main() -> int:
|
|
106
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
107
|
+
parser.add_argument("--check", action="store_true", help="exit 1 on drift instead of rewriting")
|
|
108
|
+
args = parser.parse_args()
|
|
109
|
+
|
|
110
|
+
counts = {k: count(k) for k in ("skills", "rules", "commands", "guidelines", "personas")}
|
|
111
|
+
print(f"📊 Truth: skills={counts['skills']} rules={counts['rules']} "
|
|
112
|
+
f"commands={counts['commands']} guidelines={counts['guidelines']} "
|
|
113
|
+
f"personas={counts['personas']}")
|
|
114
|
+
|
|
115
|
+
any_drift = False
|
|
116
|
+
any_change = False
|
|
117
|
+
for rel, patterns in TARGETS:
|
|
118
|
+
path = REPO_ROOT / rel
|
|
119
|
+
if not path.exists():
|
|
120
|
+
print(f"❌ Missing target: {rel}", file=sys.stderr)
|
|
121
|
+
return 1
|
|
122
|
+
text = path.read_text(encoding="utf-8")
|
|
123
|
+
new_text, drifts = apply_to_text(text, patterns, counts)
|
|
124
|
+
if drifts:
|
|
125
|
+
any_drift = True
|
|
126
|
+
for kind, old, new in drifts:
|
|
127
|
+
print(f" {'🔴' if args.check else '🔧'} {rel}: {kind} {old} → {new}")
|
|
128
|
+
if new_text != text and not args.check:
|
|
129
|
+
path.write_text(new_text, encoding="utf-8")
|
|
130
|
+
any_change = True
|
|
131
|
+
|
|
132
|
+
if args.check:
|
|
133
|
+
if any_drift:
|
|
134
|
+
print("\n❌ Stale counts detected. Run `task counts-update` to fix.", file=sys.stderr)
|
|
135
|
+
return 1
|
|
136
|
+
print("✅ All counts in sync.")
|
|
137
|
+
return 0
|
|
138
|
+
|
|
139
|
+
if any_change:
|
|
140
|
+
print("✅ Counts updated.")
|
|
141
|
+
else:
|
|
142
|
+
print("✅ Counts already in sync.")
|
|
143
|
+
return 0
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
if __name__ == "__main__":
|
|
147
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Frontmatter validator (stdlib-only Draft-07 subset).
|
|
4
|
+
|
|
5
|
+
Validates the YAML frontmatter of an agent artefact (skill, rule, command,
|
|
6
|
+
persona) against its JSON-Schema in ``scripts/schemas/``.
|
|
7
|
+
|
|
8
|
+
Supported keywords: ``type``, ``required``, ``properties``,
|
|
9
|
+
``additionalProperties``, ``enum``, ``pattern``, ``items``, ``minLength``,
|
|
10
|
+
``maxLength``, ``minItems``, ``minimum``. No ``$ref``, no ``allOf``/``anyOf``
|
|
11
|
+
— the schemas in this repo deliberately stay flat.
|
|
12
|
+
|
|
13
|
+
The goal is a **better error surface**: each violation comes back as a
|
|
14
|
+
``SchemaError`` with ``path`` (dotted JSON pointer), ``rule`` (the schema
|
|
15
|
+
keyword that failed), and a human-readable message.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import json
|
|
21
|
+
import re
|
|
22
|
+
import sys
|
|
23
|
+
from dataclasses import dataclass
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import Any
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
"SchemaError",
|
|
29
|
+
"validate",
|
|
30
|
+
"load_schema",
|
|
31
|
+
"parse_frontmatter",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
_FRONTMATTER_RE = re.compile(r"^---\n(.*?)\n---\n", re.DOTALL)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass(frozen=True)
|
|
38
|
+
class SchemaError:
|
|
39
|
+
path: str
|
|
40
|
+
rule: str
|
|
41
|
+
message: str
|
|
42
|
+
|
|
43
|
+
def format(self, file: str | None = None, line: int | None = None) -> str:
|
|
44
|
+
prefix = file or "<data>"
|
|
45
|
+
if line is not None:
|
|
46
|
+
prefix = f"{prefix}:{line}"
|
|
47
|
+
return f"{prefix} – {self.rule} at {self.path} – {self.message}"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# --- Frontmatter parser (stdlib-only, YAML subset) -------------------------
|
|
51
|
+
|
|
52
|
+
def parse_frontmatter(text: str) -> tuple[dict[str, Any] | None, int]:
|
|
53
|
+
"""Extract and parse the YAML frontmatter block.
|
|
54
|
+
|
|
55
|
+
Returns (parsed_dict, line_offset). ``line_offset`` is the 1-based line
|
|
56
|
+
number where the frontmatter body begins (so error lines can be mapped
|
|
57
|
+
back to the source file).
|
|
58
|
+
Supports: scalar key/value (quoted or bare), booleans (``true``/``false``),
|
|
59
|
+
integers, inline lists (``[a, b]``), block lists (``- a``), and nested
|
|
60
|
+
one-level blocks (``execution:``).
|
|
61
|
+
"""
|
|
62
|
+
match = _FRONTMATTER_RE.search(text)
|
|
63
|
+
if not match:
|
|
64
|
+
return None, 0
|
|
65
|
+
body = match.group(1)
|
|
66
|
+
line_offset = text[: match.start()].count("\n") + 2 # +2 for `---\n`
|
|
67
|
+
return _parse_yaml_block(body), line_offset
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _coerce(value: str) -> Any:
|
|
71
|
+
value = value.strip()
|
|
72
|
+
if value == "":
|
|
73
|
+
return ""
|
|
74
|
+
if (value.startswith('"') and value.endswith('"')) or (
|
|
75
|
+
value.startswith("'") and value.endswith("'")
|
|
76
|
+
):
|
|
77
|
+
return value[1:-1]
|
|
78
|
+
if value.lower() == "true":
|
|
79
|
+
return True
|
|
80
|
+
if value.lower() == "false":
|
|
81
|
+
return False
|
|
82
|
+
if re.fullmatch(r"-?[0-9]+", value):
|
|
83
|
+
return int(value)
|
|
84
|
+
return value
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _parse_inline_list(value: str) -> list[Any]:
|
|
88
|
+
inner = value.strip()[1:-1].strip()
|
|
89
|
+
if not inner:
|
|
90
|
+
return []
|
|
91
|
+
return [_coerce(item) for item in _split_commas(inner)]
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _split_commas(text: str) -> list[str]:
|
|
95
|
+
"""Split on commas that aren't inside quotes. Stdlib-only."""
|
|
96
|
+
parts: list[str] = []
|
|
97
|
+
buf: list[str] = []
|
|
98
|
+
quote: str | None = None
|
|
99
|
+
for ch in text:
|
|
100
|
+
if quote:
|
|
101
|
+
buf.append(ch)
|
|
102
|
+
if ch == quote:
|
|
103
|
+
quote = None
|
|
104
|
+
elif ch in ('"', "'"):
|
|
105
|
+
quote = ch
|
|
106
|
+
buf.append(ch)
|
|
107
|
+
elif ch == ",":
|
|
108
|
+
parts.append("".join(buf).strip())
|
|
109
|
+
buf = []
|
|
110
|
+
else:
|
|
111
|
+
buf.append(ch)
|
|
112
|
+
if buf:
|
|
113
|
+
parts.append("".join(buf).strip())
|
|
114
|
+
return parts
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _parse_yaml_block(body: str) -> dict[str, Any]:
|
|
118
|
+
result: dict[str, Any] = {}
|
|
119
|
+
lines = body.splitlines()
|
|
120
|
+
i = 0
|
|
121
|
+
while i < len(lines):
|
|
122
|
+
line = lines[i]
|
|
123
|
+
stripped = line.rstrip()
|
|
124
|
+
if not stripped.strip() or stripped.lstrip().startswith("#"):
|
|
125
|
+
i += 1
|
|
126
|
+
continue
|
|
127
|
+
if line[0].isspace(): # orphan indented line — skip
|
|
128
|
+
i += 1
|
|
129
|
+
continue
|
|
130
|
+
m = re.match(r"^([\w-]+):\s*(.*)$", stripped)
|
|
131
|
+
if not m:
|
|
132
|
+
i += 1
|
|
133
|
+
continue
|
|
134
|
+
key, raw = m.group(1), m.group(2).strip()
|
|
135
|
+
if raw == "":
|
|
136
|
+
# Nested block or block list — peek ahead.
|
|
137
|
+
peek = lines[i + 1] if i + 1 < len(lines) else ""
|
|
138
|
+
if peek.lstrip().startswith("- "):
|
|
139
|
+
items, consumed = _consume_block_list(lines, i + 1)
|
|
140
|
+
result[key] = items
|
|
141
|
+
i += 1 + consumed
|
|
142
|
+
continue
|
|
143
|
+
if peek and peek[0].isspace():
|
|
144
|
+
nested, consumed = _consume_nested_block(lines, i + 1)
|
|
145
|
+
result[key] = nested
|
|
146
|
+
i += 1 + consumed
|
|
147
|
+
continue
|
|
148
|
+
result[key] = ""
|
|
149
|
+
elif raw.startswith("[") and raw.endswith("]"):
|
|
150
|
+
result[key] = _parse_inline_list(raw)
|
|
151
|
+
else:
|
|
152
|
+
result[key] = _coerce(raw)
|
|
153
|
+
i += 1
|
|
154
|
+
return result
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _consume_block_list(lines: list[str], start: int) -> tuple[list[Any], int]:
|
|
158
|
+
items: list[Any] = []
|
|
159
|
+
i = start
|
|
160
|
+
while i < len(lines):
|
|
161
|
+
line = lines[i]
|
|
162
|
+
if not line.strip():
|
|
163
|
+
i += 1
|
|
164
|
+
continue
|
|
165
|
+
stripped = line.lstrip()
|
|
166
|
+
if not stripped.startswith("- "):
|
|
167
|
+
break
|
|
168
|
+
items.append(_coerce(stripped[2:]))
|
|
169
|
+
i += 1
|
|
170
|
+
return items, i - start
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
# --- Schema loader ---------------------------------------------------------
|
|
174
|
+
|
|
175
|
+
_SCHEMA_DIR = Path(__file__).resolve().parent / "schemas"
|
|
176
|
+
_SCHEMA_CACHE: dict[str, dict[str, Any]] = {}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def load_schema(artefact_type: str) -> dict[str, Any]:
|
|
180
|
+
"""Load and cache a schema by artefact type (skill, rule, command, persona)."""
|
|
181
|
+
if artefact_type in _SCHEMA_CACHE:
|
|
182
|
+
return _SCHEMA_CACHE[artefact_type]
|
|
183
|
+
path = _SCHEMA_DIR / f"{artefact_type}.schema.json"
|
|
184
|
+
if not path.exists():
|
|
185
|
+
raise FileNotFoundError(f"No schema for artefact type '{artefact_type}' at {path}")
|
|
186
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
187
|
+
_SCHEMA_CACHE[artefact_type] = data
|
|
188
|
+
return data
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
# --- Validator core (Draft-07 subset) --------------------------------------
|
|
192
|
+
|
|
193
|
+
_JSON_TYPES: dict[str, tuple[type, ...]] = {
|
|
194
|
+
"object": (dict,),
|
|
195
|
+
"array": (list,),
|
|
196
|
+
"string": (str,),
|
|
197
|
+
"integer": (int,),
|
|
198
|
+
"number": (int, float),
|
|
199
|
+
"boolean": (bool,),
|
|
200
|
+
"null": (type(None),),
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def validate(data: Any, schema: dict[str, Any]) -> list[SchemaError]:
|
|
205
|
+
"""Validate ``data`` against ``schema``; return a list of errors (empty = pass)."""
|
|
206
|
+
errors: list[SchemaError] = []
|
|
207
|
+
_validate_node(data, schema, "$", errors)
|
|
208
|
+
return errors
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def _validate_node(data: Any, schema: dict[str, Any], path: str, errors: list[SchemaError]) -> None:
|
|
212
|
+
# type
|
|
213
|
+
expected_type = schema.get("type")
|
|
214
|
+
if expected_type is not None:
|
|
215
|
+
allowed = _JSON_TYPES.get(expected_type)
|
|
216
|
+
if allowed is None:
|
|
217
|
+
errors.append(SchemaError(path, "type", f"Unsupported schema type '{expected_type}'"))
|
|
218
|
+
return
|
|
219
|
+
# Booleans are a subtype of int in Python — exclude them from integer/number.
|
|
220
|
+
if expected_type in ("integer", "number") and isinstance(data, bool):
|
|
221
|
+
errors.append(SchemaError(path, "type", f"Expected {expected_type}, got boolean"))
|
|
222
|
+
return
|
|
223
|
+
if not isinstance(data, allowed):
|
|
224
|
+
errors.append(SchemaError(
|
|
225
|
+
path, "type",
|
|
226
|
+
f"Expected {expected_type}, got {_typename(data)}",
|
|
227
|
+
))
|
|
228
|
+
return
|
|
229
|
+
|
|
230
|
+
if isinstance(data, dict):
|
|
231
|
+
_validate_object(data, schema, path, errors)
|
|
232
|
+
elif isinstance(data, list):
|
|
233
|
+
_validate_array(data, schema, path, errors)
|
|
234
|
+
elif isinstance(data, str):
|
|
235
|
+
_validate_string(data, schema, path, errors)
|
|
236
|
+
elif isinstance(data, int) and not isinstance(data, bool):
|
|
237
|
+
_validate_integer(data, schema, path, errors)
|
|
238
|
+
|
|
239
|
+
# enum is type-independent
|
|
240
|
+
if "enum" in schema and data not in schema["enum"]:
|
|
241
|
+
errors.append(SchemaError(
|
|
242
|
+
path, "enum",
|
|
243
|
+
f"Value {data!r} is not one of {schema['enum']}",
|
|
244
|
+
))
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def _validate_object(data: dict[str, Any], schema: dict[str, Any], path: str, errors: list[SchemaError]) -> None:
|
|
248
|
+
required = schema.get("required", [])
|
|
249
|
+
for key in required:
|
|
250
|
+
if key not in data:
|
|
251
|
+
errors.append(SchemaError(f"{path}.{key}", "required", f"Missing required property '{key}'"))
|
|
252
|
+
|
|
253
|
+
properties = schema.get("properties", {})
|
|
254
|
+
additional = schema.get("additionalProperties", True)
|
|
255
|
+
|
|
256
|
+
for key, value in data.items():
|
|
257
|
+
child_path = f"{path}.{key}"
|
|
258
|
+
if key in properties:
|
|
259
|
+
_validate_node(value, properties[key], child_path, errors)
|
|
260
|
+
elif additional is False:
|
|
261
|
+
errors.append(SchemaError(
|
|
262
|
+
child_path, "additionalProperties",
|
|
263
|
+
f"Unknown property '{key}' not allowed",
|
|
264
|
+
))
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def _validate_array(data: list[Any], schema: dict[str, Any], path: str, errors: list[SchemaError]) -> None:
|
|
268
|
+
items_schema = schema.get("items")
|
|
269
|
+
if items_schema is not None:
|
|
270
|
+
for index, item in enumerate(data):
|
|
271
|
+
_validate_node(item, items_schema, f"{path}[{index}]", errors)
|
|
272
|
+
min_items = schema.get("minItems")
|
|
273
|
+
if min_items is not None and len(data) < min_items:
|
|
274
|
+
errors.append(SchemaError(path, "minItems", f"Array has {len(data)} items, need ≥ {min_items}"))
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def _validate_string(data: str, schema: dict[str, Any], path: str, errors: list[SchemaError]) -> None:
|
|
278
|
+
pattern = schema.get("pattern")
|
|
279
|
+
if pattern is not None and not re.search(pattern, data):
|
|
280
|
+
errors.append(SchemaError(path, "pattern", f"Value {data!r} does not match /{pattern}/"))
|
|
281
|
+
min_len = schema.get("minLength")
|
|
282
|
+
if min_len is not None and len(data) < min_len:
|
|
283
|
+
errors.append(SchemaError(path, "minLength", f"String length {len(data)} < {min_len}"))
|
|
284
|
+
max_len = schema.get("maxLength")
|
|
285
|
+
if max_len is not None and len(data) > max_len:
|
|
286
|
+
errors.append(SchemaError(path, "maxLength", f"String length {len(data)} > {max_len}"))
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def _validate_integer(data: int, schema: dict[str, Any], path: str, errors: list[SchemaError]) -> None:
|
|
290
|
+
minimum = schema.get("minimum")
|
|
291
|
+
if minimum is not None and data < minimum:
|
|
292
|
+
errors.append(SchemaError(path, "minimum", f"{data} < {minimum}"))
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def _typename(value: Any) -> str:
|
|
296
|
+
if value is None:
|
|
297
|
+
return "null"
|
|
298
|
+
if isinstance(value, bool):
|
|
299
|
+
return "boolean"
|
|
300
|
+
if isinstance(value, int):
|
|
301
|
+
return "integer"
|
|
302
|
+
if isinstance(value, float):
|
|
303
|
+
return "number"
|
|
304
|
+
if isinstance(value, str):
|
|
305
|
+
return "string"
|
|
306
|
+
if isinstance(value, list):
|
|
307
|
+
return "array"
|
|
308
|
+
if isinstance(value, dict):
|
|
309
|
+
return "object"
|
|
310
|
+
return type(value).__name__
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def _consume_nested_block(lines: list[str], start: int) -> tuple[dict[str, Any], int]:
|
|
314
|
+
nested: dict[str, Any] = {}
|
|
315
|
+
i = start
|
|
316
|
+
# Lock in the indent of the outer nested block from the first content
|
|
317
|
+
# line so we know when the block ends.
|
|
318
|
+
block_indent: int | None = None
|
|
319
|
+
while i < len(lines):
|
|
320
|
+
line = lines[i]
|
|
321
|
+
if not line.strip():
|
|
322
|
+
i += 1
|
|
323
|
+
continue
|
|
324
|
+
if not line[0].isspace():
|
|
325
|
+
break
|
|
326
|
+
indent = len(line) - len(line.lstrip())
|
|
327
|
+
if block_indent is None:
|
|
328
|
+
block_indent = indent
|
|
329
|
+
elif indent < block_indent:
|
|
330
|
+
break
|
|
331
|
+
stripped = line.strip()
|
|
332
|
+
if stripped.startswith("#"):
|
|
333
|
+
i += 1
|
|
334
|
+
continue
|
|
335
|
+
m = re.match(r"^([\w-]+):\s*(.*)$", stripped)
|
|
336
|
+
if not m:
|
|
337
|
+
i += 1
|
|
338
|
+
continue
|
|
339
|
+
key, raw = m.group(1), m.group(2).strip()
|
|
340
|
+
if raw.startswith("[") and raw.endswith("]"):
|
|
341
|
+
nested[key] = _parse_inline_list(raw)
|
|
342
|
+
elif raw == "":
|
|
343
|
+
# Value continues on the next line(s). Peek ahead: a block list
|
|
344
|
+
# at deeper indent means this key holds a list; anything else
|
|
345
|
+
# treated as empty string (one-level nesting only).
|
|
346
|
+
peek = lines[i + 1] if i + 1 < len(lines) else ""
|
|
347
|
+
peek_stripped = peek.lstrip()
|
|
348
|
+
peek_indent = len(peek) - len(peek_stripped) if peek_stripped else -1
|
|
349
|
+
if peek_stripped.startswith("- ") and peek_indent > indent:
|
|
350
|
+
items, consumed = _consume_block_list(lines, i + 1)
|
|
351
|
+
nested[key] = items
|
|
352
|
+
i += 1 + consumed
|
|
353
|
+
continue
|
|
354
|
+
nested[key] = ""
|
|
355
|
+
else:
|
|
356
|
+
nested[key] = _coerce(raw)
|
|
357
|
+
i += 1
|
|
358
|
+
return nested, i - start
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
# --- CLI entry point -------------------------------------------------------
|
|
362
|
+
|
|
363
|
+
def _iter_artefacts(root: Path) -> list[tuple[str, Path]]:
|
|
364
|
+
"""Yield ``(artefact_type, path)`` pairs for all lintable artefacts."""
|
|
365
|
+
targets: list[tuple[str, Path]] = []
|
|
366
|
+
mapping = (
|
|
367
|
+
("skill", sorted(root.joinpath("skills").rglob("SKILL.md"))),
|
|
368
|
+
("rule", sorted(root.joinpath("rules").rglob("*.md"))),
|
|
369
|
+
("command", sorted(root.joinpath("commands").rglob("*.md"))),
|
|
370
|
+
("persona", [
|
|
371
|
+
f for f in sorted(root.joinpath("personas").glob("*.md"))
|
|
372
|
+
if f.name.lower() != "readme.md"
|
|
373
|
+
]),
|
|
374
|
+
)
|
|
375
|
+
for artefact_type, files in mapping:
|
|
376
|
+
for f in files:
|
|
377
|
+
if f.is_symlink():
|
|
378
|
+
continue
|
|
379
|
+
targets.append((artefact_type, f))
|
|
380
|
+
return targets
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
def _main() -> int:
|
|
384
|
+
import argparse
|
|
385
|
+
|
|
386
|
+
parser = argparse.ArgumentParser(
|
|
387
|
+
description="Validate agent-artefact frontmatter against JSON-Schema.",
|
|
388
|
+
)
|
|
389
|
+
parser.add_argument(
|
|
390
|
+
"--root",
|
|
391
|
+
default=".agent-src.uncompressed",
|
|
392
|
+
help="Source root to scan (default: .agent-src.uncompressed).",
|
|
393
|
+
)
|
|
394
|
+
args = parser.parse_args()
|
|
395
|
+
|
|
396
|
+
root = Path(args.root)
|
|
397
|
+
if not root.is_dir():
|
|
398
|
+
print(f"error: source root not found: {root}", file=sys.stderr)
|
|
399
|
+
return 2
|
|
400
|
+
|
|
401
|
+
total = 0
|
|
402
|
+
failing = 0
|
|
403
|
+
for artefact_type, path in _iter_artefacts(root):
|
|
404
|
+
total += 1
|
|
405
|
+
text = path.read_text(encoding="utf-8")
|
|
406
|
+
data, _offset = parse_frontmatter(text)
|
|
407
|
+
if data is None:
|
|
408
|
+
# Other tooling flags missing frontmatter; don't double-report.
|
|
409
|
+
continue
|
|
410
|
+
schema = load_schema(artefact_type)
|
|
411
|
+
errors = validate(data, schema)
|
|
412
|
+
if errors:
|
|
413
|
+
failing += 1
|
|
414
|
+
for error in errors:
|
|
415
|
+
print(f"[{artefact_type}] {path}: {error.rule} at "
|
|
416
|
+
f"{error.path} – {error.message}")
|
|
417
|
+
|
|
418
|
+
print(f"\n== Frontmatter schema: {total} artefacts, "
|
|
419
|
+
f"{failing} failing ==")
|
|
420
|
+
return 1 if failing else 0
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
if __name__ == "__main__":
|
|
424
|
+
sys.exit(_main())
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Consumer Settings Templates
|
|
2
|
+
|
|
3
|
+
These templates show how to configure your project to use `agent-config` as a native plugin
|
|
4
|
+
instead of copying files via `install.sh`.
|
|
5
|
+
|
|
6
|
+
## Quick Setup by Tool
|
|
7
|
+
|
|
8
|
+
### Augment CLI
|
|
9
|
+
|
|
10
|
+
1. Add marketplace: `auggie plugin marketplace add event4u-app/agent-config`
|
|
11
|
+
2. Install plugin: `auggie plugin install agent-conf@event4u`
|
|
12
|
+
3. Optional: Copy `augment-settings.json` into your project's `.augment/settings.json` to auto-recommend for your team.
|
|
13
|
+
|
|
14
|
+
### Claude Code
|
|
15
|
+
|
|
16
|
+
1. Add marketplace: `claude plugin marketplace add event4u-app/agent-config`
|
|
17
|
+
2. Install plugin: `claude plugin install agent-conf@event4u`
|
|
18
|
+
3. Optional: Copy `claude-settings.json` into your project's `.claude/settings.json`.
|
|
19
|
+
|
|
20
|
+
### Copilot CLI
|
|
21
|
+
|
|
22
|
+
1. Add marketplace: `copilot plugin marketplace add event4u-app/agent-config`
|
|
23
|
+
2. Install plugin: `copilot plugin install agent-conf@event4u`
|
|
24
|
+
3. Optional: Copy `copilot-settings.json` into your project's `.github/copilot/settings.json`.
|
|
25
|
+
|
|
26
|
+
### Cursor / Cline / Windsurf / Augment VSCode
|
|
27
|
+
|
|
28
|
+
These tools do **not** support plugins yet. Use the classic `install.sh` approach:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
bash vendor/event4u/agent-config/scripts/install.sh --target .
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## What the plugin provides
|
|
35
|
+
|
|
36
|
+
When installed as a plugin, the agent gets access to:
|
|
37
|
+
|
|
38
|
+
- **Rules** — Always-active behavior constraints (`.augment/rules/`)
|
|
39
|
+
- **Skills** — On-demand domain expertise (`.augment/skills/`)
|
|
40
|
+
- **Commands** — Workflow automations (`.augment/commands/`)
|
|
41
|
+
- **Guidelines** — Coding standards (`.augment/guidelines/`)
|
|
42
|
+
|
|
43
|
+
## Auto-updates
|
|
44
|
+
|
|
45
|
+
Plugin marketplaces auto-update in the background (Augment CLI and Claude Code).
|
|
46
|
+
No manual `git pull` or `install.sh` re-runs needed.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"// Instructions": "Copy this into your project's .augment/settings.json to auto-recommend the agent-config marketplace.",
|
|
3
|
+
"// After install": "Run: auggie plugin marketplace add event4u-app/agent-config",
|
|
4
|
+
"// Then enable": "Run: auggie plugin install agent-conf@event4u",
|
|
5
|
+
|
|
6
|
+
"recommendedMarketplaces": [
|
|
7
|
+
"event4u-app/agent-config"
|
|
8
|
+
],
|
|
9
|
+
"enabledPlugins": {
|
|
10
|
+
"agent-conf@event4u": true
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"// Instructions": "Copy this into your project's .claude/settings.json to auto-enable the agent-config plugin.",
|
|
3
|
+
"// After setup": "Claude Code will load the plugin when the marketplace is installed.",
|
|
4
|
+
"// Install marketplace": "Run: claude plugin marketplace add event4u-app/agent-config",
|
|
5
|
+
|
|
6
|
+
"enabledPlugins": {
|
|
7
|
+
"agent-conf@event4u": true
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"// Instructions": "Copy this into your project's .github/copilot/settings.json to auto-recommend the agent-config plugin.",
|
|
3
|
+
"// After setup": "Copilot CLI will auto-install the marketplace and enable the plugin on startup.",
|
|
4
|
+
|
|
5
|
+
"extraKnownMarketplaces": [
|
|
6
|
+
{
|
|
7
|
+
"name": "event4u-agent-config",
|
|
8
|
+
"source": "event4u-app/agent-config"
|
|
9
|
+
}
|
|
10
|
+
],
|
|
11
|
+
"enabledPlugins": {
|
|
12
|
+
"agent-conf@event4u": true
|
|
13
|
+
}
|
|
14
|
+
}
|