@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.
Files changed (446) hide show
  1. package/.agent-src/README.md +64 -0
  2. package/.agent-src/commands/agent-handoff.md +64 -0
  3. package/.agent-src/commands/agent-status.md +83 -0
  4. package/.agent-src/commands/agents-audit.md +243 -0
  5. package/.agent-src/commands/agents-cleanup.md +169 -0
  6. package/.agent-src/commands/agents-prepare.md +137 -0
  7. package/.agent-src/commands/analyze-reference-repo.md +191 -0
  8. package/.agent-src/commands/bug-fix.md +181 -0
  9. package/.agent-src/commands/bug-investigate.md +175 -0
  10. package/.agent-src/commands/commit.md +121 -0
  11. package/.agent-src/commands/compress.md +177 -0
  12. package/.agent-src/commands/config-agent-settings.md +126 -0
  13. package/.agent-src/commands/context-create.md +167 -0
  14. package/.agent-src/commands/context-refactor.md +170 -0
  15. package/.agent-src/commands/copilot-agents-init.md +150 -0
  16. package/.agent-src/commands/copilot-agents-optimize.md +251 -0
  17. package/.agent-src/commands/create-pr-description.md +112 -0
  18. package/.agent-src/commands/create-pr.md +76 -0
  19. package/.agent-src/commands/do-and-judge.md +114 -0
  20. package/.agent-src/commands/do-in-steps.md +84 -0
  21. package/.agent-src/commands/e2e-heal.md +98 -0
  22. package/.agent-src/commands/e2e-plan.md +85 -0
  23. package/.agent-src/commands/estimate-ticket.md +80 -0
  24. package/.agent-src/commands/feature-dev.md +111 -0
  25. package/.agent-src/commands/feature-explore.md +180 -0
  26. package/.agent-src/commands/feature-plan.md +288 -0
  27. package/.agent-src/commands/feature-refactor.md +181 -0
  28. package/.agent-src/commands/feature-roadmap.md +184 -0
  29. package/.agent-src/commands/fix-ci.md +48 -0
  30. package/.agent-src/commands/fix-portability.md +97 -0
  31. package/.agent-src/commands/fix-pr-bot-comments.md +146 -0
  32. package/.agent-src/commands/fix-pr-comments.md +58 -0
  33. package/.agent-src/commands/fix-pr-developer-comments.md +152 -0
  34. package/.agent-src/commands/fix-references.md +94 -0
  35. package/.agent-src/commands/fix-seeder.md +146 -0
  36. package/.agent-src/commands/implement-ticket.md +133 -0
  37. package/.agent-src/commands/jira-ticket.md +71 -0
  38. package/.agent-src/commands/judge.md +86 -0
  39. package/.agent-src/commands/memory-add.md +130 -0
  40. package/.agent-src/commands/memory-full.md +97 -0
  41. package/.agent-src/commands/memory-promote.md +144 -0
  42. package/.agent-src/commands/mode.md +121 -0
  43. package/.agent-src/commands/module-create.md +132 -0
  44. package/.agent-src/commands/module-explore.md +157 -0
  45. package/.agent-src/commands/optimize-agents.md +139 -0
  46. package/.agent-src/commands/optimize-augmentignore.md +262 -0
  47. package/.agent-src/commands/optimize-rtk-filters.md +120 -0
  48. package/.agent-src/commands/optimize-skills.md +121 -0
  49. package/.agent-src/commands/override-create.md +97 -0
  50. package/.agent-src/commands/override-manage.md +96 -0
  51. package/.agent-src/commands/package-reset.md +154 -0
  52. package/.agent-src/commands/package-test.md +154 -0
  53. package/.agent-src/commands/prepare-for-review.md +91 -0
  54. package/.agent-src/commands/project-analyze.md +300 -0
  55. package/.agent-src/commands/project-health.md +95 -0
  56. package/.agent-src/commands/propose-memory.md +108 -0
  57. package/.agent-src/commands/quality-fix.md +106 -0
  58. package/.agent-src/commands/refine-ticket.md +81 -0
  59. package/.agent-src/commands/review-changes.md +130 -0
  60. package/.agent-src/commands/review-routing.md +111 -0
  61. package/.agent-src/commands/roadmap-create.md +110 -0
  62. package/.agent-src/commands/roadmap-execute.md +68 -0
  63. package/.agent-src/commands/rule-compliance-audit.md +139 -0
  64. package/.agent-src/commands/tests-create.md +73 -0
  65. package/.agent-src/commands/tests-execute.md +58 -0
  66. package/.agent-src/commands/threat-model.md +115 -0
  67. package/.agent-src/commands/update-form-request-messages.md +189 -0
  68. package/.agent-src/commands/upstream-contribute.md +171 -0
  69. package/.agent-src/contexts/augment-infrastructure.md +181 -0
  70. package/.agent-src/contexts/documentation-hierarchy.md +142 -0
  71. package/.agent-src/contexts/model-recommendations.md +142 -0
  72. package/.agent-src/contexts/override-system.md +187 -0
  73. package/.agent-src/contexts/skills-and-commands.md +154 -0
  74. package/.agent-src/contexts/subagent-configuration.md +62 -0
  75. package/.agent-src/guidelines/agent-infra/agent-interaction-and-decision-quality.md +110 -0
  76. package/.agent-src/guidelines/agent-infra/break-glass-usage.md +113 -0
  77. package/.agent-src/guidelines/agent-infra/developer-judgment.md +82 -0
  78. package/.agent-src/guidelines/agent-infra/engineering-memory-data-format.md +117 -0
  79. package/.agent-src/guidelines/agent-infra/layered-settings.md +158 -0
  80. package/.agent-src/guidelines/agent-infra/memory-access.md +121 -0
  81. package/.agent-src/guidelines/agent-infra/naming.md +69 -0
  82. package/.agent-src/guidelines/agent-infra/output-patterns.md +117 -0
  83. package/.agent-src/guidelines/agent-infra/review-routing-data-format.md +144 -0
  84. package/.agent-src/guidelines/agent-infra/role-contracts.md +211 -0
  85. package/.agent-src/guidelines/agent-infra/role-mode-router.md +89 -0
  86. package/.agent-src/guidelines/agent-infra/runtime-layer.md +89 -0
  87. package/.agent-src/guidelines/agent-infra/self-improvement-pipeline.md +135 -0
  88. package/.agent-src/guidelines/agent-infra/size-and-scope.md +189 -0
  89. package/.agent-src/guidelines/agent-infra/tool-integration.md +73 -0
  90. package/.agent-src/guidelines/docs/readme-size-and-splitting.md +153 -0
  91. package/.agent-src/guidelines/e2e/playwright.md +363 -0
  92. package/.agent-src/guidelines/php/api-design.md +115 -0
  93. package/.agent-src/guidelines/php/artisan-commands.md +81 -0
  94. package/.agent-src/guidelines/php/blade-ui.md +78 -0
  95. package/.agent-src/guidelines/php/controllers.md +90 -0
  96. package/.agent-src/guidelines/php/database.md +111 -0
  97. package/.agent-src/guidelines/php/eloquent.md +208 -0
  98. package/.agent-src/guidelines/php/flux.md +80 -0
  99. package/.agent-src/guidelines/php/general.md +191 -0
  100. package/.agent-src/guidelines/php/git.md +96 -0
  101. package/.agent-src/guidelines/php/jobs.md +111 -0
  102. package/.agent-src/guidelines/php/livewire.md +71 -0
  103. package/.agent-src/guidelines/php/logging.md +79 -0
  104. package/.agent-src/guidelines/php/naming.md +89 -0
  105. package/.agent-src/guidelines/php/patterns/dependency-injection.md +57 -0
  106. package/.agent-src/guidelines/php/patterns/dtos.md +199 -0
  107. package/.agent-src/guidelines/php/patterns/events.md +67 -0
  108. package/.agent-src/guidelines/php/patterns/factory.md +53 -0
  109. package/.agent-src/guidelines/php/patterns/pipelines.md +66 -0
  110. package/.agent-src/guidelines/php/patterns/policies.md +66 -0
  111. package/.agent-src/guidelines/php/patterns/repositories.md +122 -0
  112. package/.agent-src/guidelines/php/patterns/service-layer.md +64 -0
  113. package/.agent-src/guidelines/php/patterns/strategy.md +69 -0
  114. package/.agent-src/guidelines/php/patterns.md +28 -0
  115. package/.agent-src/guidelines/php/performance.md +92 -0
  116. package/.agent-src/guidelines/php/resources.md +100 -0
  117. package/.agent-src/guidelines/php/security.md +110 -0
  118. package/.agent-src/guidelines/php/sql.md +97 -0
  119. package/.agent-src/guidelines/php/validations.md +119 -0
  120. package/.agent-src/guidelines/php/websocket.md +100 -0
  121. package/.agent-src/personas/README.md +104 -0
  122. package/.agent-src/personas/ai-agent.md +77 -0
  123. package/.agent-src/personas/critical-challenger.md +73 -0
  124. package/.agent-src/personas/developer.md +73 -0
  125. package/.agent-src/personas/product-owner.md +78 -0
  126. package/.agent-src/personas/qa.md +67 -0
  127. package/.agent-src/personas/senior-engineer.md +77 -0
  128. package/.agent-src/personas/stakeholder.md +78 -0
  129. package/.agent-src/rules/agent-docs.md +61 -0
  130. package/.agent-src/rules/analysis-skill-routing.md +48 -0
  131. package/.agent-src/rules/architecture.md +62 -0
  132. package/.agent-src/rules/artifact-drafting-protocol.md +73 -0
  133. package/.agent-src/rules/ask-when-uncertain.md +52 -0
  134. package/.agent-src/rules/augment-portability.md +38 -0
  135. package/.agent-src/rules/augment-source-of-truth.md +128 -0
  136. package/.agent-src/rules/capture-learnings.md +89 -0
  137. package/.agent-src/rules/cli-output-handling.md +94 -0
  138. package/.agent-src/rules/commit-conventions.md +64 -0
  139. package/.agent-src/rules/context-hygiene.md +90 -0
  140. package/.agent-src/rules/docker-commands.md +55 -0
  141. package/.agent-src/rules/docs-sync.md +79 -0
  142. package/.agent-src/rules/downstream-changes.md +70 -0
  143. package/.agent-src/rules/e2e-testing.md +53 -0
  144. package/.agent-src/rules/guidelines.md +90 -0
  145. package/.agent-src/rules/improve-before-implement.md +94 -0
  146. package/.agent-src/rules/language-and-tone.md +104 -0
  147. package/.agent-src/rules/laravel-translations.md +48 -0
  148. package/.agent-src/rules/markdown-safe-codeblocks.md +18 -0
  149. package/.agent-src/rules/minimal-safe-diff.md +87 -0
  150. package/.agent-src/rules/missing-tool-handling.md +62 -0
  151. package/.agent-src/rules/model-recommendation.md +70 -0
  152. package/.agent-src/rules/package-ci-checks.md +80 -0
  153. package/.agent-src/rules/php-coding.md +63 -0
  154. package/.agent-src/rules/preservation-guard.md +29 -0
  155. package/.agent-src/rules/review-routing-awareness.md +125 -0
  156. package/.agent-src/rules/reviewer-awareness.md +92 -0
  157. package/.agent-src/rules/roadmap-progress-sync.md +56 -0
  158. package/.agent-src/rules/role-mode-adherence.md +54 -0
  159. package/.agent-src/rules/rule-type-governance.md +46 -0
  160. package/.agent-src/rules/runtime-safety.md +42 -0
  161. package/.agent-src/rules/scope-control.md +40 -0
  162. package/.agent-src/rules/security-sensitive-stop.md +77 -0
  163. package/.agent-src/rules/size-enforcement.md +29 -0
  164. package/.agent-src/rules/skill-improvement-trigger.md +58 -0
  165. package/.agent-src/rules/skill-quality.md +110 -0
  166. package/.agent-src/rules/slash-commands.md +30 -0
  167. package/.agent-src/rules/think-before-action.md +91 -0
  168. package/.agent-src/rules/token-efficiency.md +99 -0
  169. package/.agent-src/rules/tool-safety.md +36 -0
  170. package/.agent-src/rules/upstream-proposal.md +76 -0
  171. package/.agent-src/rules/user-interaction.md +79 -0
  172. package/.agent-src/rules/verify-before-complete.md +120 -0
  173. package/.agent-src/scripts/scan-seeder-violations.php +145 -0
  174. package/.agent-src/scripts/update_roadmap_progress.py +244 -0
  175. package/.agent-src/skills/adversarial-review/SKILL.md +149 -0
  176. package/.agent-src/skills/agent-docs-writing/SKILL.md +234 -0
  177. package/.agent-src/skills/analysis-autonomous-mode/SKILL.md +197 -0
  178. package/.agent-src/skills/analysis-skill-router/SKILL.md +134 -0
  179. package/.agent-src/skills/api-design/SKILL.md +104 -0
  180. package/.agent-src/skills/api-endpoint/SKILL.md +185 -0
  181. package/.agent-src/skills/api-testing/SKILL.md +206 -0
  182. package/.agent-src/skills/artisan-commands/SKILL.md +78 -0
  183. package/.agent-src/skills/authz-review/SKILL.md +171 -0
  184. package/.agent-src/skills/aws-infrastructure/SKILL.md +152 -0
  185. package/.agent-src/skills/blade-ui/SKILL.md +75 -0
  186. package/.agent-src/skills/blast-radius-analyzer/SKILL.md +185 -0
  187. package/.agent-src/skills/bug-analyzer/SKILL.md +256 -0
  188. package/.agent-src/skills/check-refs/SKILL.md +72 -0
  189. package/.agent-src/skills/code-refactoring/SKILL.md +200 -0
  190. package/.agent-src/skills/code-review/SKILL.md +214 -0
  191. package/.agent-src/skills/command-routing/SKILL.md +96 -0
  192. package/.agent-src/skills/command-writing/SKILL.md +143 -0
  193. package/.agent-src/skills/composer-packages/SKILL.md +172 -0
  194. package/.agent-src/skills/context-authoring/SKILL.md +157 -0
  195. package/.agent-src/skills/context-document/SKILL.md +153 -0
  196. package/.agent-src/skills/conventional-commits-writing/SKILL.md +70 -0
  197. package/.agent-src/skills/copilot-agents-optimization/SKILL.md +220 -0
  198. package/.agent-src/skills/copilot-config/SKILL.md +203 -0
  199. package/.agent-src/skills/dashboard-design/SKILL.md +116 -0
  200. package/.agent-src/skills/data-flow-mapper/SKILL.md +160 -0
  201. package/.agent-src/skills/database/SKILL.md +91 -0
  202. package/.agent-src/skills/dependency-upgrade/SKILL.md +204 -0
  203. package/.agent-src/skills/description-assist/SKILL.md +169 -0
  204. package/.agent-src/skills/design-review/SKILL.md +228 -0
  205. package/.agent-src/skills/devcontainer/SKILL.md +121 -0
  206. package/.agent-src/skills/developer-like-execution/SKILL.md +276 -0
  207. package/.agent-src/skills/docker/SKILL.md +245 -0
  208. package/.agent-src/skills/dto-creator/SKILL.md +117 -0
  209. package/.agent-src/skills/eloquent/SKILL.md +92 -0
  210. package/.agent-src/skills/eloquent/evals/last-run.json +99 -0
  211. package/.agent-src/skills/eloquent/evals/triggers.json +16 -0
  212. package/.agent-src/skills/estimate-ticket/SKILL.md +186 -0
  213. package/.agent-src/skills/estimate-ticket/evals/output-schema.yml +20 -0
  214. package/.agent-src/skills/estimate-ticket/evals/triggers.json +18 -0
  215. package/.agent-src/skills/fe-design/SKILL.md +223 -0
  216. package/.agent-src/skills/feature-planning/SKILL.md +226 -0
  217. package/.agent-src/skills/file-editor/SKILL.md +129 -0
  218. package/.agent-src/skills/finishing-a-development-branch/SKILL.md +200 -0
  219. package/.agent-src/skills/flux/SKILL.md +64 -0
  220. package/.agent-src/skills/git-workflow/SKILL.md +102 -0
  221. package/.agent-src/skills/github-ci/SKILL.md +122 -0
  222. package/.agent-src/skills/grafana/SKILL.md +168 -0
  223. package/.agent-src/skills/guideline-writing/SKILL.md +147 -0
  224. package/.agent-src/skills/jira-integration/SKILL.md +182 -0
  225. package/.agent-src/skills/jobs-events/SKILL.md +87 -0
  226. package/.agent-src/skills/judge-bug-hunter/SKILL.md +157 -0
  227. package/.agent-src/skills/judge-code-quality/SKILL.md +158 -0
  228. package/.agent-src/skills/judge-security-auditor/SKILL.md +167 -0
  229. package/.agent-src/skills/judge-test-coverage/SKILL.md +154 -0
  230. package/.agent-src/skills/laravel/SKILL.md +195 -0
  231. package/.agent-src/skills/laravel-horizon/SKILL.md +169 -0
  232. package/.agent-src/skills/laravel-mail/SKILL.md +193 -0
  233. package/.agent-src/skills/laravel-middleware/SKILL.md +185 -0
  234. package/.agent-src/skills/laravel-notifications/SKILL.md +168 -0
  235. package/.agent-src/skills/laravel-pennant/SKILL.md +188 -0
  236. package/.agent-src/skills/laravel-pulse/SKILL.md +160 -0
  237. package/.agent-src/skills/laravel-reverb/SKILL.md +205 -0
  238. package/.agent-src/skills/laravel-scheduling/SKILL.md +167 -0
  239. package/.agent-src/skills/laravel-validation/SKILL.md +71 -0
  240. package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +249 -0
  241. package/.agent-src/skills/lint-skills/SKILL.md +72 -0
  242. package/.agent-src/skills/livewire/SKILL.md +79 -0
  243. package/.agent-src/skills/logging-monitoring/SKILL.md +100 -0
  244. package/.agent-src/skills/mcp/SKILL.md +193 -0
  245. package/.agent-src/skills/merge-conflicts/SKILL.md +158 -0
  246. package/.agent-src/skills/migration-creator/SKILL.md +160 -0
  247. package/.agent-src/skills/module-management/SKILL.md +154 -0
  248. package/.agent-src/skills/multi-tenancy/SKILL.md +129 -0
  249. package/.agent-src/skills/openapi/SKILL.md +154 -0
  250. package/.agent-src/skills/override-management/SKILL.md +186 -0
  251. package/.agent-src/skills/performance/SKILL.md +69 -0
  252. package/.agent-src/skills/performance-analysis/SKILL.md +118 -0
  253. package/.agent-src/skills/pest-testing/SKILL.md +321 -0
  254. package/.agent-src/skills/php-coder/SKILL.md +78 -0
  255. package/.agent-src/skills/php-coder/evals/triggers.json +16 -0
  256. package/.agent-src/skills/php-debugging/SKILL.md +184 -0
  257. package/.agent-src/skills/php-service/SKILL.md +96 -0
  258. package/.agent-src/skills/playwright-testing/SKILL.md +244 -0
  259. package/.agent-src/skills/project-analysis-core/SKILL.md +138 -0
  260. package/.agent-src/skills/project-analysis-hypothesis-driven/SKILL.md +130 -0
  261. package/.agent-src/skills/project-analysis-laravel/SKILL.md +119 -0
  262. package/.agent-src/skills/project-analysis-nextjs/SKILL.md +123 -0
  263. package/.agent-src/skills/project-analysis-node-express/SKILL.md +111 -0
  264. package/.agent-src/skills/project-analysis-react/SKILL.md +119 -0
  265. package/.agent-src/skills/project-analysis-symfony/SKILL.md +111 -0
  266. package/.agent-src/skills/project-analysis-zend-laminas/SKILL.md +108 -0
  267. package/.agent-src/skills/project-analyzer/SKILL.md +341 -0
  268. package/.agent-src/skills/project-docs/SKILL.md +137 -0
  269. package/.agent-src/skills/quality-tools/SKILL.md +411 -0
  270. package/.agent-src/skills/readme-reviewer/SKILL.md +187 -0
  271. package/.agent-src/skills/readme-writing/SKILL.md +142 -0
  272. package/.agent-src/skills/readme-writing-package/SKILL.md +185 -0
  273. package/.agent-src/skills/receiving-code-review/SKILL.md +190 -0
  274. package/.agent-src/skills/refine-ticket/SKILL.md +310 -0
  275. package/.agent-src/skills/refine-ticket/detection-map.yml +124 -0
  276. package/.agent-src/skills/refine-ticket/evals/output-schema.yml +16 -0
  277. package/.agent-src/skills/refine-ticket/evals/triggers.json +16 -0
  278. package/.agent-src/skills/requesting-code-review/SKILL.md +199 -0
  279. package/.agent-src/skills/review-routing/SKILL.md +195 -0
  280. package/.agent-src/skills/roadmap-management/SKILL.md +303 -0
  281. package/.agent-src/skills/rtk-output-filtering/SKILL.md +184 -0
  282. package/.agent-src/skills/rule-writing/SKILL.md +148 -0
  283. package/.agent-src/skills/security/SKILL.md +79 -0
  284. package/.agent-src/skills/security-audit/SKILL.md +123 -0
  285. package/.agent-src/skills/sentry-integration/SKILL.md +170 -0
  286. package/.agent-src/skills/sequential-thinking/SKILL.md +158 -0
  287. package/.agent-src/skills/skill-improvement-pipeline/SKILL.md +155 -0
  288. package/.agent-src/skills/skill-management/SKILL.md +121 -0
  289. package/.agent-src/skills/skill-reviewer/SKILL.md +218 -0
  290. package/.agent-src/skills/skill-writing/SKILL.md +291 -0
  291. package/.agent-src/skills/skill-writing/evals/triggers.json +16 -0
  292. package/.agent-src/skills/sql-writing/SKILL.md +74 -0
  293. package/.agent-src/skills/subagent-orchestration/SKILL.md +190 -0
  294. package/.agent-src/skills/systematic-debugging/SKILL.md +244 -0
  295. package/.agent-src/skills/technical-specification/SKILL.md +185 -0
  296. package/.agent-src/skills/terraform/SKILL.md +137 -0
  297. package/.agent-src/skills/terragrunt/SKILL.md +217 -0
  298. package/.agent-src/skills/test-driven-development/SKILL.md +252 -0
  299. package/.agent-src/skills/test-performance/SKILL.md +172 -0
  300. package/.agent-src/skills/threat-modeling/SKILL.md +189 -0
  301. package/.agent-src/skills/traefik/SKILL.md +319 -0
  302. package/.agent-src/skills/universal-project-analysis/SKILL.md +179 -0
  303. package/.agent-src/skills/upstream-contribute/SKILL.md +255 -0
  304. package/.agent-src/skills/using-git-worktrees/SKILL.md +148 -0
  305. package/.agent-src/skills/validate-feature-fit/SKILL.md +113 -0
  306. package/.agent-src/skills/verify-before-complete/SKILL.md +188 -0
  307. package/.agent-src/skills/websocket/SKILL.md +75 -0
  308. package/.agent-src/templates/AGENTS.md +146 -0
  309. package/.agent-src/templates/agent-settings.md +256 -0
  310. package/.agent-src/templates/agents/.gitattributes.fragment +16 -0
  311. package/.agent-src/templates/agents/agent-project-settings.example.yml +138 -0
  312. package/.agent-src/templates/agents/memory/architecture-decisions.example.yml +95 -0
  313. package/.agent-src/templates/agents/memory/domain-invariants.example.yml +80 -0
  314. package/.agent-src/templates/agents/memory/historical-patterns.example.yml +82 -0
  315. package/.agent-src/templates/agents/memory/incident-learnings.example.yml +113 -0
  316. package/.agent-src/templates/agents/memory/ownership.example.yml +75 -0
  317. package/.agent-src/templates/agents/memory/product-rules.example.yml +87 -0
  318. package/.agent-src/templates/agents/proposal.example.md +143 -0
  319. package/.agent-src/templates/command.md +84 -0
  320. package/.agent-src/templates/contexts/auth-model.md +59 -0
  321. package/.agent-src/templates/contexts/data-sensitivity.md +60 -0
  322. package/.agent-src/templates/contexts/deployment-order.md +72 -0
  323. package/.agent-src/templates/contexts/observability.md +64 -0
  324. package/.agent-src/templates/contexts/tenant-boundaries.md +68 -0
  325. package/.agent-src/templates/contexts.md +116 -0
  326. package/.agent-src/templates/copilot-instructions.md +115 -0
  327. package/.agent-src/templates/features.md +125 -0
  328. package/.agent-src/templates/github-workflows/memory-hygiene.yml +133 -0
  329. package/.agent-src/templates/github-workflows/pr-risk-review.yml +123 -0
  330. package/.agent-src/templates/github-workflows/proposal-drift.yml +118 -0
  331. package/.agent-src/templates/overrides/command.md +24 -0
  332. package/.agent-src/templates/overrides/guideline.md +21 -0
  333. package/.agent-src/templates/overrides/rule.md +19 -0
  334. package/.agent-src/templates/overrides/skill.md +24 -0
  335. package/.agent-src/templates/overrides/template.md +21 -0
  336. package/.agent-src/templates/persona.md +99 -0
  337. package/.agent-src/templates/roadmaps.md +109 -0
  338. package/.agent-src/templates/scripts/README.md +195 -0
  339. package/.agent-src/templates/scripts/check_memory.py +283 -0
  340. package/.agent-src/templates/scripts/check_memory_proposal.py +180 -0
  341. package/.agent-src/templates/scripts/historical-bug-patterns.example.yml +84 -0
  342. package/.agent-src/templates/scripts/implement_ticket/__init__.py +57 -0
  343. package/.agent-src/templates/scripts/implement_ticket/__main__.py +9 -0
  344. package/.agent-src/templates/scripts/implement_ticket/cli.py +171 -0
  345. package/.agent-src/templates/scripts/implement_ticket/delivery_state.py +130 -0
  346. package/.agent-src/templates/scripts/implement_ticket/dispatcher.py +134 -0
  347. package/.agent-src/templates/scripts/implement_ticket/persona_policy.py +85 -0
  348. package/.agent-src/templates/scripts/implement_ticket/steps/__init__.py +49 -0
  349. package/.agent-src/templates/scripts/implement_ticket/steps/analyze.py +98 -0
  350. package/.agent-src/templates/scripts/implement_ticket/steps/implement.py +145 -0
  351. package/.agent-src/templates/scripts/implement_ticket/steps/memory.py +136 -0
  352. package/.agent-src/templates/scripts/implement_ticket/steps/plan.py +175 -0
  353. package/.agent-src/templates/scripts/implement_ticket/steps/refine.py +140 -0
  354. package/.agent-src/templates/scripts/implement_ticket/steps/report.py +195 -0
  355. package/.agent-src/templates/scripts/implement_ticket/steps/test.py +180 -0
  356. package/.agent-src/templates/scripts/implement_ticket/steps/verify.py +170 -0
  357. package/.agent-src/templates/scripts/memory_hash.py +75 -0
  358. package/.agent-src/templates/scripts/memory_lookup.py +216 -0
  359. package/.agent-src/templates/scripts/memory_report.py +184 -0
  360. package/.agent-src/templates/scripts/memory_signal.py +167 -0
  361. package/.agent-src/templates/scripts/memory_status.py +156 -0
  362. package/.agent-src/templates/scripts/ownership-map.example.yml +87 -0
  363. package/.agent-src/templates/scripts/pr-risk-config.example.yml +76 -0
  364. package/.agent-src/templates/scripts/pr_review_routing.py +340 -0
  365. package/.agent-src/templates/scripts/pr_risk_review.py +211 -0
  366. package/.agent-src/templates/skill.md +136 -0
  367. package/.augment-plugin/marketplace.json +32 -0
  368. package/.augment-plugin/plugin.json +21 -0
  369. package/.claude-plugin/marketplace.json +119 -0
  370. package/AGENTS.md +121 -0
  371. package/CHANGELOG.md +279 -0
  372. package/CONTRIBUTING.md +176 -0
  373. package/LICENSE +21 -0
  374. package/README.md +357 -0
  375. package/bin/install.php +38 -0
  376. package/composer.json +29 -0
  377. package/config/agent-settings.template.yml +96 -0
  378. package/config/profiles/balanced.ini +10 -0
  379. package/config/profiles/full.ini +10 -0
  380. package/config/profiles/minimal.ini +10 -0
  381. package/docs/architecture.md +144 -0
  382. package/docs/customization.md +88 -0
  383. package/docs/development.md +171 -0
  384. package/docs/getting-started.md +130 -0
  385. package/docs/github-topics.md +84 -0
  386. package/docs/installation.md +376 -0
  387. package/docs/mcp.md +133 -0
  388. package/docs/quality.md +98 -0
  389. package/docs/skills-catalog.md +136 -0
  390. package/docs/troubleshooting.md +167 -0
  391. package/llms.txt +130 -0
  392. package/package.json +31 -0
  393. package/scripts/audit_skill_descriptions.py +168 -0
  394. package/scripts/check_compression.py +221 -0
  395. package/scripts/check_memory.py +341 -0
  396. package/scripts/check_memory_proposal.py +180 -0
  397. package/scripts/check_portability.py +320 -0
  398. package/scripts/check_proposal.py +269 -0
  399. package/scripts/check_references.py +400 -0
  400. package/scripts/ci_summary.py +131 -0
  401. package/scripts/compress.py +671 -0
  402. package/scripts/compress.sh +18 -0
  403. package/scripts/first-run.sh +109 -0
  404. package/scripts/generate_catalog.py +116 -0
  405. package/scripts/install +151 -0
  406. package/scripts/install-hooks.sh +29 -0
  407. package/scripts/install.py +487 -0
  408. package/scripts/install.sh +637 -0
  409. package/scripts/install_anthropic_key.sh +101 -0
  410. package/scripts/inventory_frontmatter.py +164 -0
  411. package/scripts/lint_marketplace.py +142 -0
  412. package/scripts/lint_regression.py +232 -0
  413. package/scripts/mcp_render.py +159 -0
  414. package/scripts/measure_patterns.py +376 -0
  415. package/scripts/memory_hash.py +75 -0
  416. package/scripts/memory_lookup.py +441 -0
  417. package/scripts/memory_report.py +336 -0
  418. package/scripts/memory_signal.py +210 -0
  419. package/scripts/memory_status.py +195 -0
  420. package/scripts/postinstall.sh +60 -0
  421. package/scripts/readme_linter.py +580 -0
  422. package/scripts/refine_ticket_detect.py +623 -0
  423. package/scripts/requirements-evals.txt +7 -0
  424. package/scripts/runtime_dispatcher.py +265 -0
  425. package/scripts/runtime_handler.py +148 -0
  426. package/scripts/runtime_registry.py +166 -0
  427. package/scripts/schemas/command.schema.json +32 -0
  428. package/scripts/schemas/persona.schema.json +42 -0
  429. package/scripts/schemas/rule.schema.json +28 -0
  430. package/scripts/schemas/skill.schema.json +73 -0
  431. package/scripts/setup.sh +230 -0
  432. package/scripts/setup_eval_venv.sh +58 -0
  433. package/scripts/skill_linter.py +2175 -0
  434. package/scripts/skill_trigger_eval.py +651 -0
  435. package/scripts/tool_registry.py +146 -0
  436. package/scripts/tools/__init__.py +1 -0
  437. package/scripts/tools/adapter_errors.py +63 -0
  438. package/scripts/tools/base_adapter.py +91 -0
  439. package/scripts/tools/github_adapter.py +128 -0
  440. package/scripts/tools/jira_adapter.py +115 -0
  441. package/scripts/update_counts.py +147 -0
  442. package/scripts/validate_frontmatter.py +424 -0
  443. package/templates/consumer-settings/README.md +46 -0
  444. package/templates/consumer-settings/augment-settings.json +12 -0
  445. package/templates/consumer-settings/claude-settings.json +9 -0
  446. package/templates/consumer-settings/copilot-settings.json +14 -0
@@ -0,0 +1,580 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ README quality linter for agent-config repositories.
4
+
5
+ Detects weak, misleading, or incomplete READMEs by cross-checking
6
+ against actual repository files (Taskfile.yml, package.json, etc.).
7
+
8
+ Checks:
9
+ - Missing title, summary, installation, usage example
10
+ - Weak quickstart (example too far from install)
11
+ - Missing compatibility/requirements for packages
12
+ - Generic boilerplate phrases
13
+ - Command mismatches (documented but not in repo)
14
+ - Bad section order (architecture before install)
15
+ - Overloaded README (too long)
16
+ - Missing dev workflow when tests/CI exist
17
+
18
+ Exit codes:
19
+ 0 = pass
20
+ 1 = warnings only
21
+ 2 = errors
22
+ 3 = internal error
23
+ """
24
+
25
+ from __future__ import annotations
26
+
27
+ import argparse
28
+ import json
29
+ import re
30
+ import sys
31
+ from dataclasses import dataclass, asdict, field
32
+ from pathlib import Path
33
+ from typing import List, Literal, Optional
34
+
35
+ Severity = Literal["error", "warning", "info"]
36
+ RepoType = Literal["package", "app", "cli", "internal", "unknown"]
37
+
38
+
39
+ # --- Patterns ---
40
+
41
+ H1_PATTERN = re.compile(r"^# .+", re.MULTILINE)
42
+ H2_PATTERN = re.compile(r"^## (.+?)\s*$", re.MULTILINE)
43
+ CODE_BLOCK_PATTERN = re.compile(r"```[\s\S]*?```", re.MULTILINE)
44
+ INLINE_COMMAND_PATTERN = re.compile(r"`((?:task|npm run|make)\s+[\w:_-]+(?:\s+[\w:_-]+)?)`")
45
+
46
+ # Built-in commands that are always valid (not custom scripts)
47
+ BUILTIN_COMMANDS = {
48
+ "composer install", "composer update", "composer require", "composer remove",
49
+ "npm install", "npm uninstall", "npm init", "npm test", "npm start",
50
+ "yarn add", "yarn remove", "yarn install",
51
+ "pnpm add", "pnpm remove", "pnpm install",
52
+ "php artisan", "cargo build", "cargo test", "go build", "go test",
53
+ "git clone", "git submodule",
54
+ }
55
+
56
+ INSTALL_HEADINGS = {
57
+ "installation", "install", "setup", "getting started", "quickstart",
58
+ "how to install", "installing",
59
+ }
60
+ USAGE_HEADINGS = {
61
+ "usage", "quickstart", "quick start", "getting started",
62
+ "how to use", "how it works", "basic usage", "examples",
63
+ "minimal example", "minimal usage",
64
+ }
65
+ COMPAT_HEADINGS = {
66
+ "requirements", "compatibility", "prerequisites", "supported versions",
67
+ "system requirements", "dependencies",
68
+ }
69
+ DEV_HEADINGS = {
70
+ "development", "contributing", "testing", "dev", "local development",
71
+ "developer guide", "running tests", "development setup",
72
+ }
73
+ ARCHITECTURE_HEADINGS = {
74
+ "architecture", "internals", "design", "how it works internally",
75
+ "technical details", "implementation",
76
+ }
77
+
78
+ GENERIC_BOILERPLATE = [
79
+ r"(?i)\bmodern and scalable\b",
80
+ r"(?i)\bpowerful and flexible\b",
81
+ r"(?i)\bsimple and intuitive\b",
82
+ r"(?i)\bblazing fast\b",
83
+ r"(?i)\bnext[- ]gen(?:eration)?\b",
84
+ r"(?i)\bworld[- ]class\b",
85
+ r"(?i)\bcutting[- ]edge\b",
86
+ r"(?i)\bseamless(?:ly)? integrat",
87
+ r"(?i)\brobust and reliable\b",
88
+ r"(?i)\blightweight yet powerful\b",
89
+ ]
90
+
91
+ OVERLOADED_LINE_THRESHOLD = 500
92
+ WEAK_QUICKSTART_LINE_GAP = 80
93
+
94
+
95
+ # --- Data classes ---
96
+
97
+ @dataclass
98
+ class Issue:
99
+ severity: Severity
100
+ code: str
101
+ message: str
102
+
103
+
104
+ @dataclass
105
+ class ReadmeLintResult:
106
+ file: str
107
+ repo_type: RepoType
108
+ status: Literal["pass", "pass_with_warnings", "fail"]
109
+ issues: List[Issue]
110
+ line_count: int
111
+
112
+
113
+ @dataclass
114
+ class RepoContext:
115
+ """Extracted context about the repository."""
116
+ repo_type: RepoType = "unknown"
117
+ has_composer: bool = False
118
+ has_package_json: bool = False
119
+ has_taskfile: bool = False
120
+ has_makefile: bool = False
121
+ has_dockerfile: bool = False
122
+ has_tests: bool = False
123
+ has_ci: bool = False
124
+ taskfile_tasks: list[str] = field(default_factory=list)
125
+ npm_scripts: list[str] = field(default_factory=list)
126
+ composer_scripts: list[str] = field(default_factory=list)
127
+ make_targets: list[str] = field(default_factory=list)
128
+
129
+
130
+ # --- Repo detection ---
131
+
132
+ def detect_repo_context(root: Path) -> RepoContext:
133
+ ctx = RepoContext()
134
+ ctx.has_composer = (root / "composer.json").exists()
135
+ ctx.has_package_json = (root / "package.json").exists()
136
+ ctx.has_taskfile = (root / "Taskfile.yml").exists() or (root / "Taskfile.yaml").exists()
137
+ ctx.has_makefile = (root / "Makefile").exists()
138
+ ctx.has_dockerfile = (root / "Dockerfile").exists() or (root / "docker-compose.yml").exists()
139
+ ctx.has_tests = (root / "tests").is_dir() or (root / "test").is_dir()
140
+ ctx.has_ci = (root / ".github" / "workflows").is_dir()
141
+
142
+ # Extract available commands
143
+ ctx.taskfile_tasks = _extract_taskfile_tasks(root)
144
+ ctx.npm_scripts = _extract_npm_scripts(root)
145
+ ctx.composer_scripts = _extract_composer_scripts(root)
146
+ ctx.make_targets = _extract_make_targets(root)
147
+
148
+ # Detect repo type
149
+ ctx.repo_type = _detect_repo_type(root, ctx)
150
+ return ctx
151
+
152
+
153
+ def _detect_repo_type(root: Path, ctx: RepoContext) -> RepoType:
154
+ # Package signals
155
+ if ctx.has_composer:
156
+ try:
157
+ data = json.loads((root / "composer.json").read_text())
158
+ pkg_type = data.get("type", "")
159
+ if pkg_type in ("library", "composer-plugin", "symfony-bundle"):
160
+ return "package"
161
+ # No app bootstrap = likely package
162
+ if not (root / "artisan").exists() and not (root / "public" / "index.php").exists():
163
+ return "package"
164
+ except (json.JSONDecodeError, OSError):
165
+ pass
166
+
167
+ if ctx.has_package_json:
168
+ try:
169
+ data = json.loads((root / "package.json").read_text())
170
+ if data.get("main") or data.get("exports") or data.get("module"):
171
+ return "package"
172
+ except (json.JSONDecodeError, OSError):
173
+ pass
174
+
175
+ # CLI signals
176
+ bin_dir = root / "bin"
177
+ if bin_dir.is_dir() and any(bin_dir.iterdir()):
178
+ return "cli"
179
+
180
+ # App signals
181
+ if (root / "artisan").exists() or (root / "public" / "index.php").exists():
182
+ return "app"
183
+ if ctx.has_dockerfile and (root / "src").is_dir():
184
+ return "app"
185
+
186
+ # Internal/config signals
187
+ augment_dir = root / ".augment"
188
+ agents_dir = root / "agents"
189
+ if augment_dir.is_dir() or agents_dir.is_dir():
190
+ return "internal"
191
+
192
+ return "unknown"
193
+
194
+
195
+ def _extract_taskfile_tasks(root: Path) -> list[str]:
196
+ for name in ("Taskfile.yml", "Taskfile.yaml"):
197
+ path = root / name
198
+ if path.exists():
199
+ try:
200
+ text = path.read_text()
201
+ return re.findall(r"^\s{2}([\w_-]+):", text, re.MULTILINE)
202
+ except OSError:
203
+ pass
204
+ return []
205
+
206
+
207
+ def _extract_npm_scripts(root: Path) -> list[str]:
208
+ path = root / "package.json"
209
+ if path.exists():
210
+ try:
211
+ data = json.loads(path.read_text())
212
+ return list(data.get("scripts", {}).keys())
213
+ except (json.JSONDecodeError, OSError):
214
+ pass
215
+ return []
216
+
217
+
218
+ def _extract_composer_scripts(root: Path) -> list[str]:
219
+ path = root / "composer.json"
220
+ if path.exists():
221
+ try:
222
+ data = json.loads(path.read_text())
223
+ return list(data.get("scripts", {}).keys())
224
+ except (json.JSONDecodeError, OSError):
225
+ pass
226
+ return []
227
+
228
+
229
+ def _extract_make_targets(root: Path) -> list[str]:
230
+ path = root / "Makefile"
231
+ if path.exists():
232
+ try:
233
+ text = path.read_text()
234
+ return re.findall(r"^([\w_-]+)\s*:", text, re.MULTILINE)
235
+ except OSError:
236
+ pass
237
+ return []
238
+
239
+
240
+ # --- Core checks ---
241
+
242
+ def lint_readme(readme_path: Path, repo_root: Path) -> ReadmeLintResult:
243
+ """Run all checks on a README file."""
244
+ issues: list[Issue] = []
245
+ text = readme_path.read_text(encoding="utf-8")
246
+ lines = text.splitlines()
247
+ line_count = len(lines)
248
+ ctx = detect_repo_context(repo_root)
249
+
250
+ headings = [m.group(1).strip() for m in H2_PATTERN.finditer(text)]
251
+ headings_lower = {h.lower() for h in headings}
252
+
253
+ # 1. Missing title
254
+ if not H1_PATTERN.search(text):
255
+ issues.append(Issue("error", "readme_missing_title", "No H1 heading found"))
256
+
257
+ # 2. Missing summary
258
+ _check_summary(text, issues)
259
+
260
+ # 3. Missing installation
261
+ _check_installation(headings_lower, ctx, issues)
262
+
263
+ # 4. Missing usage example
264
+ _check_usage_example(text, headings_lower, ctx, issues)
265
+
266
+ # 5. Weak quickstart
267
+ _check_quickstart_distance(text, headings, issues)
268
+
269
+ # 6. Missing compatibility (packages)
270
+ _check_compatibility(headings_lower, ctx, issues)
271
+
272
+ # 7. Generic boilerplate
273
+ _check_boilerplate(text, issues)
274
+
275
+ # 8. Missing dev workflow
276
+ _check_dev_workflow(headings_lower, ctx, issues)
277
+
278
+ # 9. Command mismatches
279
+ _check_command_mismatches(text, ctx, issues)
280
+
281
+ # 10. Bad section order
282
+ _check_section_order(headings, issues)
283
+
284
+ # 11. Overloaded README
285
+ _check_overloaded(line_count, issues)
286
+
287
+ # Determine status
288
+ has_errors = any(i.severity == "error" for i in issues)
289
+ has_warnings = any(i.severity == "warning" for i in issues)
290
+ if has_errors:
291
+ status = "fail"
292
+ elif has_warnings:
293
+ status = "pass_with_warnings"
294
+ else:
295
+ status = "pass"
296
+
297
+ return ReadmeLintResult(
298
+ file=str(readme_path),
299
+ repo_type=ctx.repo_type,
300
+ status=status,
301
+ issues=issues,
302
+ line_count=line_count,
303
+ )
304
+
305
+
306
+ # --- Individual checks ---
307
+
308
+ def _check_summary(text: str, issues: list[Issue]) -> None:
309
+ """Check if there's a summary paragraph after the title."""
310
+ h1 = H1_PATTERN.search(text)
311
+ if not h1:
312
+ return
313
+ after_title = text[h1.end():h1.end() + 300]
314
+ # Strip leading whitespace and check for text before next heading
315
+ after_stripped = after_title.strip()
316
+ if not after_stripped or after_stripped.startswith("## ") or after_stripped.startswith("```"):
317
+ issues.append(Issue("warning", "readme_missing_summary",
318
+ "No summary paragraph after title"))
319
+
320
+
321
+ def _check_installation(headings_lower: set[str], ctx: RepoContext, issues: list[Issue]) -> None:
322
+ """Check for installation/setup section."""
323
+ if ctx.repo_type in ("unknown",):
324
+ return
325
+ if not headings_lower & INSTALL_HEADINGS:
326
+ severity = "error" if ctx.repo_type in ("package", "app", "cli") else "warning"
327
+ issues.append(Issue(severity, "readme_missing_installation",
328
+ f"No installation/setup section found ({ctx.repo_type} repo)"))
329
+
330
+
331
+ def _check_usage_example(text: str, headings_lower: set[str], ctx: RepoContext,
332
+ issues: list[Issue]) -> None:
333
+ """Check for usage examples with code blocks."""
334
+ if ctx.repo_type == "unknown":
335
+ return
336
+ has_usage_heading = bool(headings_lower & USAGE_HEADINGS)
337
+ code_blocks = CODE_BLOCK_PATTERN.findall(text)
338
+ if not code_blocks:
339
+ issues.append(Issue("error" if ctx.repo_type == "package" else "warning",
340
+ "readme_missing_usage_example",
341
+ "No code blocks found — likely missing usage examples"))
342
+ elif not has_usage_heading and ctx.repo_type in ("package", "cli"):
343
+ issues.append(Issue("warning", "readme_missing_usage_example",
344
+ "No usage/quickstart section heading found"))
345
+
346
+
347
+ def _check_quickstart_distance(text: str, headings: list[str], issues: list[Issue]) -> None:
348
+ """Check if first code block appears too far after install heading."""
349
+ install_line = None
350
+ first_code_line = None
351
+ lines = text.splitlines()
352
+ for i, line in enumerate(lines):
353
+ if install_line is None:
354
+ heading_text = re.match(r"^## (.+)", line)
355
+ if heading_text and heading_text.group(1).strip().lower() in INSTALL_HEADINGS:
356
+ install_line = i
357
+ if first_code_line is None and line.startswith("```"):
358
+ first_code_line = i
359
+
360
+ if install_line is not None and first_code_line is not None:
361
+ gap = first_code_line - install_line
362
+ if gap > WEAK_QUICKSTART_LINE_GAP:
363
+ issues.append(Issue("warning", "readme_weak_quickstart",
364
+ f"First code block is {gap} lines after install heading"))
365
+
366
+
367
+ def _check_compatibility(headings_lower: set[str], ctx: RepoContext,
368
+ issues: list[Issue]) -> None:
369
+ """Check for requirements/compatibility section in packages."""
370
+ if ctx.repo_type != "package":
371
+ return
372
+ if not headings_lower & COMPAT_HEADINGS:
373
+ issues.append(Issue("warning", "readme_missing_compatibility",
374
+ "Package repo has no requirements/compatibility section"))
375
+
376
+
377
+ def _check_boilerplate(text: str, issues: list[Issue]) -> None:
378
+ """Detect generic marketing boilerplate."""
379
+ matches = []
380
+ for pattern in GENERIC_BOILERPLATE:
381
+ found = re.findall(pattern, text)
382
+ matches.extend(found)
383
+ if matches:
384
+ examples = ", ".join(f'"{m}"' for m in matches[:3])
385
+ issues.append(Issue("warning", "readme_generic_boilerplate",
386
+ f"Generic boilerplate detected: {examples}"))
387
+
388
+
389
+ def _check_dev_workflow(headings_lower: set[str], ctx: RepoContext,
390
+ issues: list[Issue]) -> None:
391
+ """Check for dev/testing section when repo has tests or CI."""
392
+ if not (ctx.has_tests or ctx.has_ci):
393
+ return
394
+ if not headings_lower & DEV_HEADINGS:
395
+ issues.append(Issue("warning", "readme_missing_dev_workflow",
396
+ "Repo has tests/CI but README has no development/testing section"))
397
+
398
+
399
+ def _check_command_mismatches(text: str, ctx: RepoContext, issues: list[Issue]) -> None:
400
+ """Check if commands in README actually exist in the repo."""
401
+ documented_commands = INLINE_COMMAND_PATTERN.findall(text)
402
+ if not documented_commands:
403
+ return
404
+
405
+ known_commands: set[str] = set()
406
+ for task in ctx.taskfile_tasks:
407
+ known_commands.add(f"task {task}")
408
+ for script in ctx.npm_scripts:
409
+ known_commands.add(f"npm {script}")
410
+ known_commands.add(f"npm run {script}")
411
+ for script in ctx.composer_scripts:
412
+ known_commands.add(f"composer {script}")
413
+ for target in ctx.make_targets:
414
+ known_commands.add(f"make {target}")
415
+
416
+ if not known_commands:
417
+ return # Can't verify without extracted commands
418
+
419
+ mismatches = []
420
+ for cmd in documented_commands:
421
+ cmd_clean = cmd.strip()
422
+ # Check if any known command is a prefix match
423
+ if not any(cmd_clean.startswith(known) or known.startswith(cmd_clean)
424
+ for known in known_commands):
425
+ mismatches.append(cmd_clean)
426
+
427
+ if mismatches:
428
+ examples = ", ".join(f"`{m}`" for m in mismatches[:5])
429
+ issues.append(Issue("warning", "readme_command_mismatch",
430
+ f"Commands in README not found in repo: {examples}"))
431
+
432
+
433
+ def _check_section_order(headings: list[str], issues: list[Issue]) -> None:
434
+ """Check if architecture/internals appear before installation/usage."""
435
+ install_idx = None
436
+ arch_idx = None
437
+ for i, h in enumerate(headings):
438
+ h_lower = h.lower()
439
+ if install_idx is None and h_lower in INSTALL_HEADINGS | USAGE_HEADINGS:
440
+ install_idx = i
441
+ if arch_idx is None and h_lower in ARCHITECTURE_HEADINGS:
442
+ arch_idx = i
443
+
444
+ if arch_idx is not None and install_idx is not None and arch_idx < install_idx:
445
+ issues.append(Issue("warning", "readme_bad_section_order",
446
+ "Architecture/internals section appears before installation/usage"))
447
+
448
+
449
+ def _check_overloaded(line_count: int, issues: list[Issue]) -> None:
450
+ """Check if README is too long."""
451
+ if line_count > OVERLOADED_LINE_THRESHOLD:
452
+ issues.append(Issue("warning", "readme_overloaded",
453
+ f"README has {line_count} lines (threshold: {OVERLOADED_LINE_THRESHOLD})."
454
+ " Consider moving deep content to /docs"))
455
+
456
+
457
+ # --- Output formatting ---
458
+
459
+ def format_text(result: ReadmeLintResult) -> str:
460
+ """Format result as human-readable text."""
461
+ status_icon = {"pass": "✅", "pass_with_warnings": "⚠️", "fail": "❌"}
462
+ lines = [f"{status_icon.get(result.status, '?')} {result.file} "
463
+ f"(type: {result.repo_type}, {result.line_count} lines)"]
464
+
465
+ if not result.issues:
466
+ lines.append(" No issues found.")
467
+ return "\n".join(lines)
468
+
469
+ severity_icon = {"error": "❌", "warning": "⚠️", "info": "ℹ️"}
470
+ for issue in result.issues:
471
+ icon = severity_icon.get(issue.severity, "?")
472
+ lines.append(f" {icon} [{issue.code}] {issue.message}")
473
+
474
+ return "\n".join(lines)
475
+
476
+
477
+ def format_json(result: ReadmeLintResult) -> str:
478
+ """Format result as JSON."""
479
+ data = {
480
+ "file": result.file,
481
+ "repo_type": result.repo_type,
482
+ "status": result.status,
483
+ "line_count": result.line_count,
484
+ "issues": [asdict(i) for i in result.issues],
485
+ "summary": {
486
+ "error": sum(1 for i in result.issues if i.severity == "error"),
487
+ "warning": sum(1 for i in result.issues if i.severity == "warning"),
488
+ "info": sum(1 for i in result.issues if i.severity == "info"),
489
+ },
490
+ }
491
+ return json.dumps(data, indent=2)
492
+
493
+
494
+ def format_markdown(result: ReadmeLintResult) -> str:
495
+ """Format result as markdown for PR comments."""
496
+ lines = [f"## 📝 README Lint: {result.file}", ""]
497
+ lines.append(f"**Repo type:** {result.repo_type} · **Lines:** {result.line_count}")
498
+ lines.append("")
499
+
500
+ if not result.issues:
501
+ lines.append("✅ No issues found.")
502
+ return "\n".join(lines)
503
+
504
+ errors = [i for i in result.issues if i.severity == "error"]
505
+ warnings = [i for i in result.issues if i.severity == "warning"]
506
+ infos = [i for i in result.issues if i.severity == "info"]
507
+
508
+ lines.append(f"| Errors | Warnings | Info |")
509
+ lines.append(f"|---|---|---|")
510
+ lines.append(f"| {len(errors)} | {len(warnings)} | {len(infos)} |")
511
+ lines.append("")
512
+
513
+ if errors:
514
+ lines.append("### ❌ Errors")
515
+ lines.append("")
516
+ for i in errors:
517
+ lines.append(f"- `{i.code}`: {i.message}")
518
+ lines.append("")
519
+
520
+ if warnings:
521
+ lines.append("### ⚠️ Warnings")
522
+ lines.append("")
523
+ for i in warnings:
524
+ lines.append(f"- `{i.code}`: {i.message}")
525
+ lines.append("")
526
+
527
+ if infos:
528
+ lines.append("### ℹ️ Info")
529
+ lines.append("")
530
+ for i in infos:
531
+ lines.append(f"- `{i.code}`: {i.message}")
532
+
533
+ return "\n".join(lines)
534
+
535
+
536
+ # --- CLI ---
537
+
538
+ def main() -> int:
539
+ parser = argparse.ArgumentParser(description="README quality linter")
540
+ parser.add_argument("readme", nargs="?", default="README.md",
541
+ help="Path to README file (default: README.md)")
542
+ parser.add_argument("--root", default=".",
543
+ help="Repository root directory (default: cwd)")
544
+ parser.add_argument("--format", choices=["text", "json", "markdown"], default="text",
545
+ help="Output format (default: text)")
546
+ parser.add_argument("--strict", action="store_true",
547
+ help="Treat warnings as errors")
548
+ args = parser.parse_args()
549
+
550
+ readme_path = Path(args.readme)
551
+ repo_root = Path(args.root)
552
+
553
+ if not readme_path.exists():
554
+ print(f"❌ README not found: {readme_path}", file=sys.stderr)
555
+ return 3
556
+
557
+ try:
558
+ result = lint_readme(readme_path, repo_root)
559
+ except Exception as e:
560
+ print(f"❌ Internal error: {e}", file=sys.stderr)
561
+ return 3
562
+
563
+ if args.format == "json":
564
+ print(format_json(result))
565
+ elif args.format == "markdown":
566
+ print(format_markdown(result))
567
+ else:
568
+ print(format_text(result))
569
+
570
+ if result.status == "fail":
571
+ return 2
572
+ if result.status == "pass_with_warnings" and args.strict:
573
+ return 2
574
+ if result.status == "pass_with_warnings":
575
+ return 1
576
+ return 0
577
+
578
+
579
+ if __name__ == "__main__":
580
+ sys.exit(main())