@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,146 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Tool Registry — manages available external tools and their permissions.
|
|
4
|
+
|
|
5
|
+
Responsibilities:
|
|
6
|
+
- Define available tools and their supported actions
|
|
7
|
+
- Validate tool declarations from skills
|
|
8
|
+
- Check tool permissions
|
|
9
|
+
- Report on tool usage across skills
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
python3 scripts/tool_registry.py [--format text|json]
|
|
13
|
+
python3 scripts/tool_registry.py --validate-skill SKILL_TOOLS
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import argparse
|
|
19
|
+
import json
|
|
20
|
+
import sys
|
|
21
|
+
from dataclasses import dataclass, asdict
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from typing import Dict, FrozenSet, List, Optional, Set
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class ToolDefinition:
|
|
28
|
+
"""Definition of an available tool."""
|
|
29
|
+
name: str
|
|
30
|
+
description: str
|
|
31
|
+
supported_actions: FrozenSet[str]
|
|
32
|
+
default_mode: str # "read-only" or "read-write"
|
|
33
|
+
requires_auth: bool
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# --- Built-in tool definitions ---
|
|
37
|
+
TOOL_REGISTRY: Dict[str, ToolDefinition] = {
|
|
38
|
+
"github": ToolDefinition(
|
|
39
|
+
name="github",
|
|
40
|
+
description="GitHub API — PRs, issues, files, commits",
|
|
41
|
+
supported_actions=frozenset({"read_pr", "read_issue", "create_pr", "list_files", "read_commit"}),
|
|
42
|
+
default_mode="read-only",
|
|
43
|
+
requires_auth=True,
|
|
44
|
+
),
|
|
45
|
+
"jira": ToolDefinition(
|
|
46
|
+
name="jira",
|
|
47
|
+
description="Jira API — tickets, search, comments",
|
|
48
|
+
supported_actions=frozenset({"read_ticket", "search_tickets", "add_comment", "transition_ticket"}),
|
|
49
|
+
default_mode="read-only",
|
|
50
|
+
requires_auth=True,
|
|
51
|
+
),
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass
|
|
56
|
+
class ToolValidationResult:
|
|
57
|
+
"""Result of validating tool declarations."""
|
|
58
|
+
valid: bool
|
|
59
|
+
errors: List[str]
|
|
60
|
+
warnings: List[str]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def get_tool(name: str) -> Optional[ToolDefinition]:
|
|
64
|
+
"""Look up a tool by name."""
|
|
65
|
+
return TOOL_REGISTRY.get(name)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def list_tools() -> List[ToolDefinition]:
|
|
69
|
+
"""List all registered tools."""
|
|
70
|
+
return list(TOOL_REGISTRY.values())
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def validate_tool_declarations(allowed_tools: List[str],
|
|
74
|
+
tool_permissions: Optional[Dict] = None) -> ToolValidationResult:
|
|
75
|
+
"""Validate tool declarations from a skill's execution block."""
|
|
76
|
+
errors: List[str] = []
|
|
77
|
+
warnings: List[str] = []
|
|
78
|
+
|
|
79
|
+
for tool_name in allowed_tools:
|
|
80
|
+
tool_def = get_tool(tool_name)
|
|
81
|
+
if tool_def is None:
|
|
82
|
+
errors.append(f"Tool '{tool_name}' is not registered in the tool registry")
|
|
83
|
+
continue
|
|
84
|
+
|
|
85
|
+
# Check permissions if declared
|
|
86
|
+
if tool_permissions and tool_name in tool_permissions:
|
|
87
|
+
perms = tool_permissions[tool_name]
|
|
88
|
+
actions = perms.get("actions", [])
|
|
89
|
+
for action in actions:
|
|
90
|
+
if action not in tool_def.supported_actions:
|
|
91
|
+
errors.append(f"Tool '{tool_name}' does not support action '{action}'")
|
|
92
|
+
|
|
93
|
+
# Check for tools in permissions but not in allowed_tools
|
|
94
|
+
if tool_permissions:
|
|
95
|
+
for tool_name in tool_permissions:
|
|
96
|
+
if tool_name not in allowed_tools:
|
|
97
|
+
warnings.append(f"Tool '{tool_name}' has permissions but is not in allowed_tools")
|
|
98
|
+
|
|
99
|
+
return ToolValidationResult(
|
|
100
|
+
valid=len(errors) == 0,
|
|
101
|
+
errors=errors,
|
|
102
|
+
warnings=warnings,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def main() -> int:
|
|
107
|
+
parser = argparse.ArgumentParser(description="Tool Registry — manage and validate tools")
|
|
108
|
+
parser.add_argument("--format", choices=["text", "json"], default="text")
|
|
109
|
+
parser.add_argument("--validate-tools", nargs="*", help="Tool names to validate")
|
|
110
|
+
args = parser.parse_args()
|
|
111
|
+
|
|
112
|
+
if args.validate_tools is not None:
|
|
113
|
+
result = validate_tool_declarations(args.validate_tools)
|
|
114
|
+
if args.format == "json":
|
|
115
|
+
print(json.dumps(asdict(result), indent=2))
|
|
116
|
+
else:
|
|
117
|
+
if result.valid:
|
|
118
|
+
print(f"✅ All {len(args.validate_tools)} tool declarations are valid")
|
|
119
|
+
else:
|
|
120
|
+
for e in result.errors:
|
|
121
|
+
print(f"❌ {e}")
|
|
122
|
+
for w in result.warnings:
|
|
123
|
+
print(f"⚠️ {w}")
|
|
124
|
+
return 0 if result.valid else 1
|
|
125
|
+
|
|
126
|
+
# List tools
|
|
127
|
+
tools = list_tools()
|
|
128
|
+
if args.format == "json":
|
|
129
|
+
print(json.dumps([{
|
|
130
|
+
"name": t.name, "description": t.description,
|
|
131
|
+
"actions": sorted(t.supported_actions),
|
|
132
|
+
"default_mode": t.default_mode, "requires_auth": t.requires_auth,
|
|
133
|
+
} for t in tools], indent=2))
|
|
134
|
+
else:
|
|
135
|
+
print(f"Registered tools: {len(tools)}\n")
|
|
136
|
+
for t in tools:
|
|
137
|
+
actions = ", ".join(sorted(t.supported_actions))
|
|
138
|
+
print(f" {t.name} ({t.default_mode})")
|
|
139
|
+
print(f" {t.description}")
|
|
140
|
+
print(f" Actions: {actions}")
|
|
141
|
+
print()
|
|
142
|
+
return 0
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
if __name__ == "__main__":
|
|
146
|
+
sys.exit(main())
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Tool adapters package
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Shared error types for tool adapters.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from enum import Enum
|
|
10
|
+
from typing import Optional
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AdapterErrorType(str, Enum):
|
|
14
|
+
"""Categorized adapter errors."""
|
|
15
|
+
AUTH_FAILURE = "auth_failure"
|
|
16
|
+
NOT_FOUND = "not_found"
|
|
17
|
+
RATE_LIMIT = "rate_limit"
|
|
18
|
+
TIMEOUT = "timeout"
|
|
19
|
+
NETWORK = "network"
|
|
20
|
+
VALIDATION = "validation"
|
|
21
|
+
UNKNOWN = "unknown"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class AdapterError:
|
|
26
|
+
"""Structured adapter error."""
|
|
27
|
+
adapter: str
|
|
28
|
+
action: str
|
|
29
|
+
error_type: AdapterErrorType
|
|
30
|
+
message: str
|
|
31
|
+
status_code: Optional[int] = None
|
|
32
|
+
retry_after: Optional[int] = None
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def is_retryable(self) -> bool:
|
|
36
|
+
"""Whether this error can be retried."""
|
|
37
|
+
return self.error_type in (
|
|
38
|
+
AdapterErrorType.RATE_LIMIT,
|
|
39
|
+
AdapterErrorType.TIMEOUT,
|
|
40
|
+
AdapterErrorType.NETWORK,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def classify_http_error(adapter: str, action: str, status_code: int, message: str) -> AdapterError:
|
|
45
|
+
"""Classify an HTTP error into a structured AdapterError."""
|
|
46
|
+
if status_code == 401 or status_code == 403:
|
|
47
|
+
error_type = AdapterErrorType.AUTH_FAILURE
|
|
48
|
+
elif status_code == 404:
|
|
49
|
+
error_type = AdapterErrorType.NOT_FOUND
|
|
50
|
+
elif status_code == 429:
|
|
51
|
+
error_type = AdapterErrorType.RATE_LIMIT
|
|
52
|
+
elif status_code >= 500:
|
|
53
|
+
error_type = AdapterErrorType.NETWORK
|
|
54
|
+
else:
|
|
55
|
+
error_type = AdapterErrorType.UNKNOWN
|
|
56
|
+
|
|
57
|
+
return AdapterError(
|
|
58
|
+
adapter=adapter,
|
|
59
|
+
action=action,
|
|
60
|
+
error_type=error_type,
|
|
61
|
+
message=message,
|
|
62
|
+
status_code=status_code,
|
|
63
|
+
)
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Base Tool Adapter — abstract contract for tool integrations.
|
|
4
|
+
|
|
5
|
+
All tool adapters must:
|
|
6
|
+
1. Inherit from BaseToolAdapter
|
|
7
|
+
2. Define supported_actions
|
|
8
|
+
3. Implement execute_action
|
|
9
|
+
4. Implement check_auth
|
|
10
|
+
|
|
11
|
+
No real API calls are made — adapters return structured results.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from abc import ABC, abstractmethod
|
|
17
|
+
from dataclasses import dataclass
|
|
18
|
+
from typing import Any, Dict, FrozenSet, List, Optional
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class ToolAction:
|
|
23
|
+
"""Structured representation of a tool action request."""
|
|
24
|
+
tool_name: str
|
|
25
|
+
action: str
|
|
26
|
+
params: Dict[str, Any]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class ToolResult:
|
|
31
|
+
"""Structured result from a tool action."""
|
|
32
|
+
tool_name: str
|
|
33
|
+
action: str
|
|
34
|
+
success: bool
|
|
35
|
+
data: Optional[Dict[str, Any]] = None
|
|
36
|
+
error: Optional[str] = None
|
|
37
|
+
|
|
38
|
+
def to_dict(self) -> dict:
|
|
39
|
+
result = {
|
|
40
|
+
"tool": self.tool_name,
|
|
41
|
+
"action": self.action,
|
|
42
|
+
"success": self.success,
|
|
43
|
+
}
|
|
44
|
+
if self.data:
|
|
45
|
+
result["data"] = self.data
|
|
46
|
+
if self.error:
|
|
47
|
+
result["error"] = self.error
|
|
48
|
+
return result
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class BaseToolAdapter(ABC):
|
|
52
|
+
"""Abstract base for tool adapters."""
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
@abstractmethod
|
|
56
|
+
def name(self) -> str:
|
|
57
|
+
"""Tool name (must match registry entry)."""
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
@abstractmethod
|
|
61
|
+
def supported_actions(self) -> FrozenSet[str]:
|
|
62
|
+
"""Set of supported action names."""
|
|
63
|
+
|
|
64
|
+
@abstractmethod
|
|
65
|
+
def check_auth(self) -> bool:
|
|
66
|
+
"""Check if authentication is available. Does NOT make API calls."""
|
|
67
|
+
|
|
68
|
+
@abstractmethod
|
|
69
|
+
def execute_action(self, action: ToolAction) -> ToolResult:
|
|
70
|
+
"""Execute a tool action. Returns structured result."""
|
|
71
|
+
|
|
72
|
+
def validate_action(self, action: ToolAction) -> Optional[str]:
|
|
73
|
+
"""Validate an action before execution. Returns error message or None."""
|
|
74
|
+
if action.tool_name != self.name:
|
|
75
|
+
return f"Action tool '{action.tool_name}' does not match adapter '{self.name}'"
|
|
76
|
+
if action.action not in self.supported_actions:
|
|
77
|
+
return (f"Action '{action.action}' not supported by '{self.name}'; "
|
|
78
|
+
f"valid: {', '.join(sorted(self.supported_actions))}")
|
|
79
|
+
return None
|
|
80
|
+
|
|
81
|
+
def safe_execute(self, action: ToolAction) -> ToolResult:
|
|
82
|
+
"""Validate and execute an action safely."""
|
|
83
|
+
error = self.validate_action(action)
|
|
84
|
+
if error:
|
|
85
|
+
return ToolResult(
|
|
86
|
+
tool_name=self.name,
|
|
87
|
+
action=action.action,
|
|
88
|
+
success=False,
|
|
89
|
+
error=error,
|
|
90
|
+
)
|
|
91
|
+
return self.execute_action(action)
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
GitHub Tool Adapter — read-only GitHub API interactions.
|
|
4
|
+
|
|
5
|
+
Read-only actions use real API calls when GITHUB_TOKEN is available.
|
|
6
|
+
Write actions remain scaffold-only (never auto-executed).
|
|
7
|
+
Falls back to scaffold data when no token is present.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
import os
|
|
14
|
+
from typing import Any, Dict, FrozenSet, Optional
|
|
15
|
+
from urllib.error import HTTPError, URLError
|
|
16
|
+
from urllib.request import Request, urlopen
|
|
17
|
+
|
|
18
|
+
from tools.base_adapter import BaseToolAdapter, ToolAction, ToolResult
|
|
19
|
+
|
|
20
|
+
GITHUB_API = "https://api.github.com"
|
|
21
|
+
TIMEOUT_SECONDS = 15
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class GitHubAdapter(BaseToolAdapter):
|
|
25
|
+
"""Adapter for GitHub API interactions."""
|
|
26
|
+
|
|
27
|
+
READ_ACTIONS = frozenset({"read_pr", "read_issue", "list_files", "read_commit"})
|
|
28
|
+
WRITE_ACTIONS = frozenset({"create_pr"})
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def name(self) -> str:
|
|
32
|
+
return "github"
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def supported_actions(self) -> FrozenSet[str]:
|
|
36
|
+
return self.READ_ACTIONS | self.WRITE_ACTIONS
|
|
37
|
+
|
|
38
|
+
def check_auth(self) -> bool:
|
|
39
|
+
return bool(os.environ.get("GITHUB_TOKEN"))
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def _token(self) -> Optional[str]:
|
|
43
|
+
return os.environ.get("GITHUB_TOKEN")
|
|
44
|
+
|
|
45
|
+
def _api_get(self, path: str) -> Dict[str, Any]:
|
|
46
|
+
"""Make an authenticated GET request to the GitHub API."""
|
|
47
|
+
url = f"{GITHUB_API}/{path.lstrip('/')}"
|
|
48
|
+
headers = {"Accept": "application/vnd.github+json"}
|
|
49
|
+
if self._token:
|
|
50
|
+
headers["Authorization"] = f"Bearer {self._token}"
|
|
51
|
+
req = Request(url, headers=headers, method="GET")
|
|
52
|
+
with urlopen(req, timeout=TIMEOUT_SECONDS) as resp:
|
|
53
|
+
return json.loads(resp.read().decode())
|
|
54
|
+
|
|
55
|
+
def execute_action(self, action: ToolAction) -> ToolResult:
|
|
56
|
+
handler = {
|
|
57
|
+
"read_pr": self._read_pr,
|
|
58
|
+
"read_issue": self._read_issue,
|
|
59
|
+
"list_files": self._list_files,
|
|
60
|
+
"read_commit": self._read_commit,
|
|
61
|
+
"create_pr": self._create_pr,
|
|
62
|
+
}.get(action.action)
|
|
63
|
+
|
|
64
|
+
if not handler:
|
|
65
|
+
return ToolResult(
|
|
66
|
+
tool_name=self.name, action=action.action,
|
|
67
|
+
success=False, error=f"Unsupported action: {action.action}",
|
|
68
|
+
)
|
|
69
|
+
return handler(action)
|
|
70
|
+
|
|
71
|
+
def _read_pr(self, action: ToolAction) -> ToolResult:
|
|
72
|
+
owner = action.params.get("owner", "")
|
|
73
|
+
repo = action.params.get("repo", "")
|
|
74
|
+
number = action.params.get("number", "")
|
|
75
|
+
if not all([owner, repo, number]) or not self._token:
|
|
76
|
+
return self._scaffold("read_pr", action)
|
|
77
|
+
try:
|
|
78
|
+
data = self._api_get(f"repos/{owner}/{repo}/pulls/{number}")
|
|
79
|
+
return ToolResult(tool_name=self.name, action="read_pr", success=True, data=data)
|
|
80
|
+
except (HTTPError, URLError, TimeoutError) as e:
|
|
81
|
+
return ToolResult(tool_name=self.name, action="read_pr", success=False, error=str(e))
|
|
82
|
+
|
|
83
|
+
def _read_issue(self, action: ToolAction) -> ToolResult:
|
|
84
|
+
owner = action.params.get("owner", "")
|
|
85
|
+
repo = action.params.get("repo", "")
|
|
86
|
+
number = action.params.get("number", "")
|
|
87
|
+
if not all([owner, repo, number]) or not self._token:
|
|
88
|
+
return self._scaffold("read_issue", action)
|
|
89
|
+
try:
|
|
90
|
+
data = self._api_get(f"repos/{owner}/{repo}/issues/{number}")
|
|
91
|
+
return ToolResult(tool_name=self.name, action="read_issue", success=True, data=data)
|
|
92
|
+
except (HTTPError, URLError, TimeoutError) as e:
|
|
93
|
+
return ToolResult(tool_name=self.name, action="read_issue", success=False, error=str(e))
|
|
94
|
+
|
|
95
|
+
def _list_files(self, action: ToolAction) -> ToolResult:
|
|
96
|
+
owner = action.params.get("owner", "")
|
|
97
|
+
repo = action.params.get("repo", "")
|
|
98
|
+
number = action.params.get("number", "")
|
|
99
|
+
if not all([owner, repo, number]) or not self._token:
|
|
100
|
+
return self._scaffold("list_files", action)
|
|
101
|
+
try:
|
|
102
|
+
data = self._api_get(f"repos/{owner}/{repo}/pulls/{number}/files")
|
|
103
|
+
return ToolResult(tool_name=self.name, action="list_files", success=True, data=data)
|
|
104
|
+
except (HTTPError, URLError, TimeoutError) as e:
|
|
105
|
+
return ToolResult(tool_name=self.name, action="list_files", success=False, error=str(e))
|
|
106
|
+
|
|
107
|
+
def _read_commit(self, action: ToolAction) -> ToolResult:
|
|
108
|
+
owner = action.params.get("owner", "")
|
|
109
|
+
repo = action.params.get("repo", "")
|
|
110
|
+
sha = action.params.get("sha", "")
|
|
111
|
+
if not all([owner, repo, sha]) or not self._token:
|
|
112
|
+
return self._scaffold("read_commit", action)
|
|
113
|
+
try:
|
|
114
|
+
data = self._api_get(f"repos/{owner}/{repo}/commits/{sha}")
|
|
115
|
+
return ToolResult(tool_name=self.name, action="read_commit", success=True, data=data)
|
|
116
|
+
except (HTTPError, URLError, TimeoutError) as e:
|
|
117
|
+
return ToolResult(tool_name=self.name, action="read_commit", success=False, error=str(e))
|
|
118
|
+
|
|
119
|
+
def _create_pr(self, action: ToolAction) -> ToolResult:
|
|
120
|
+
"""Write action — scaffold only, never auto-executed."""
|
|
121
|
+
return self._scaffold("create_pr", action)
|
|
122
|
+
|
|
123
|
+
def _scaffold(self, action_name: str, action: ToolAction) -> ToolResult:
|
|
124
|
+
"""Return scaffold data when no token or params are missing."""
|
|
125
|
+
return ToolResult(
|
|
126
|
+
tool_name=self.name, action=action_name, success=True,
|
|
127
|
+
data={"scaffold": True, "action": action_name, "params": action.params},
|
|
128
|
+
)
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Jira Tool Adapter — read-only Jira API interactions.
|
|
4
|
+
|
|
5
|
+
Read-only actions use real API calls when JIRA_API_TOKEN + JIRA_BASE_URL are set.
|
|
6
|
+
Write actions remain scaffold-only (never auto-executed).
|
|
7
|
+
Falls back to scaffold data when no credentials are present.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import base64
|
|
13
|
+
import json
|
|
14
|
+
import os
|
|
15
|
+
from typing import Any, Dict, FrozenSet, Optional
|
|
16
|
+
from urllib.error import HTTPError, URLError
|
|
17
|
+
from urllib.request import Request, urlopen
|
|
18
|
+
|
|
19
|
+
from tools.base_adapter import BaseToolAdapter, ToolAction, ToolResult
|
|
20
|
+
|
|
21
|
+
TIMEOUT_SECONDS = 15
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class JiraAdapter(BaseToolAdapter):
|
|
25
|
+
"""Adapter for Jira API interactions."""
|
|
26
|
+
|
|
27
|
+
READ_ACTIONS = frozenset({"read_ticket", "search_tickets"})
|
|
28
|
+
WRITE_ACTIONS = frozenset({"add_comment", "transition_ticket"})
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def name(self) -> str:
|
|
32
|
+
return "jira"
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def supported_actions(self) -> FrozenSet[str]:
|
|
36
|
+
return self.READ_ACTIONS | self.WRITE_ACTIONS
|
|
37
|
+
|
|
38
|
+
def check_auth(self) -> bool:
|
|
39
|
+
return bool(self._token) and bool(self._base_url)
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def _token(self) -> Optional[str]:
|
|
43
|
+
return os.environ.get("JIRA_API_TOKEN")
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def _base_url(self) -> Optional[str]:
|
|
47
|
+
url = os.environ.get("JIRA_BASE_URL", "")
|
|
48
|
+
return url.rstrip("/") if url else None
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def _email(self) -> Optional[str]:
|
|
52
|
+
return os.environ.get("JIRA_EMAIL")
|
|
53
|
+
|
|
54
|
+
def _api_get(self, path: str) -> Dict[str, Any]:
|
|
55
|
+
"""Make an authenticated GET request to the Jira API."""
|
|
56
|
+
url = f"{self._base_url}/rest/api/3/{path.lstrip('/')}"
|
|
57
|
+
headers = {"Accept": "application/json"}
|
|
58
|
+
if self._email and self._token:
|
|
59
|
+
creds = base64.b64encode(f"{self._email}:{self._token}".encode()).decode()
|
|
60
|
+
headers["Authorization"] = f"Basic {creds}"
|
|
61
|
+
elif self._token:
|
|
62
|
+
headers["Authorization"] = f"Bearer {self._token}"
|
|
63
|
+
req = Request(url, headers=headers, method="GET")
|
|
64
|
+
with urlopen(req, timeout=TIMEOUT_SECONDS) as resp:
|
|
65
|
+
return json.loads(resp.read().decode())
|
|
66
|
+
|
|
67
|
+
def execute_action(self, action: ToolAction) -> ToolResult:
|
|
68
|
+
handler = {
|
|
69
|
+
"read_ticket": self._read_ticket,
|
|
70
|
+
"search_tickets": self._search_tickets,
|
|
71
|
+
"add_comment": self._add_comment,
|
|
72
|
+
"transition_ticket": self._transition_ticket,
|
|
73
|
+
}.get(action.action)
|
|
74
|
+
|
|
75
|
+
if not handler:
|
|
76
|
+
return ToolResult(
|
|
77
|
+
tool_name=self.name, action=action.action,
|
|
78
|
+
success=False, error=f"Unsupported action: {action.action}",
|
|
79
|
+
)
|
|
80
|
+
return handler(action)
|
|
81
|
+
|
|
82
|
+
def _read_ticket(self, action: ToolAction) -> ToolResult:
|
|
83
|
+
key = action.params.get("key", "")
|
|
84
|
+
if not key or not self.check_auth():
|
|
85
|
+
return self._scaffold("read_ticket", action)
|
|
86
|
+
try:
|
|
87
|
+
data = self._api_get(f"issue/{key}")
|
|
88
|
+
return ToolResult(tool_name=self.name, action="read_ticket", success=True, data=data)
|
|
89
|
+
except (HTTPError, URLError, TimeoutError) as e:
|
|
90
|
+
return ToolResult(tool_name=self.name, action="read_ticket", success=False, error=str(e))
|
|
91
|
+
|
|
92
|
+
def _search_tickets(self, action: ToolAction) -> ToolResult:
|
|
93
|
+
jql = action.params.get("jql", "")
|
|
94
|
+
if not jql or not self.check_auth():
|
|
95
|
+
return self._scaffold("search_tickets", action)
|
|
96
|
+
try:
|
|
97
|
+
encoded_jql = jql.replace(" ", "%20")
|
|
98
|
+
data = self._api_get(f"search?jql={encoded_jql}&maxResults=20")
|
|
99
|
+
return ToolResult(tool_name=self.name, action="search_tickets", success=True, data=data)
|
|
100
|
+
except (HTTPError, URLError, TimeoutError) as e:
|
|
101
|
+
return ToolResult(tool_name=self.name, action="search_tickets", success=False, error=str(e))
|
|
102
|
+
|
|
103
|
+
def _add_comment(self, action: ToolAction) -> ToolResult:
|
|
104
|
+
"""Write action — scaffold only."""
|
|
105
|
+
return self._scaffold("add_comment", action)
|
|
106
|
+
|
|
107
|
+
def _transition_ticket(self, action: ToolAction) -> ToolResult:
|
|
108
|
+
"""Write action — scaffold only."""
|
|
109
|
+
return self._scaffold("transition_ticket", action)
|
|
110
|
+
|
|
111
|
+
def _scaffold(self, action_name: str, action: ToolAction) -> ToolResult:
|
|
112
|
+
return ToolResult(
|
|
113
|
+
tool_name=self.name, action=action_name, success=True,
|
|
114
|
+
data={"scaffold": True, "action": action_name, "params": action.params},
|
|
115
|
+
)
|