diff --git a/antigravity-awesome-skills/.claude-plugin/marketplace.json b/antigravity-awesome-skills/.claude-plugin/marketplace.json index 2a2f2497..86af4c56 100644 --- a/antigravity-awesome-skills/.claude-plugin/marketplace.json +++ b/antigravity-awesome-skills/.claude-plugin/marketplace.json @@ -6,12 +6,12 @@ }, "metadata": { "description": "Claude Code marketplace entries for the plugin-safe Antigravity Awesome Skills library and its compatible editorial bundles.", - "version": "13.3.0" + "version": "13.4.0" }, "plugins": [ { "name": "antigravity-awesome-skills", - "version": "13.3.0", + "version": "13.4.0", "description": "Expose the plugin-safe Claude Code subset of Antigravity Awesome Skills through a single marketplace entry.", "author": { "name": "sickn33 and contributors", @@ -31,7 +31,7 @@ }, { "name": "antigravity-bundle-essentials", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Essentials\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -51,7 +51,7 @@ }, { "name": "antigravity-bundle-security-engineer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Security Engineer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -71,7 +71,7 @@ }, { "name": "antigravity-bundle-security-developer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Security Developer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -91,7 +91,7 @@ }, { "name": "antigravity-bundle-web-wizard", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Web Wizard\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -111,7 +111,7 @@ }, { "name": "antigravity-bundle-web-designer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Web Designer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -131,7 +131,7 @@ }, { "name": "antigravity-bundle-full-stack-developer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Full-Stack Developer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -151,7 +151,7 @@ }, { "name": "antigravity-bundle-agent-architect", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Agent Architect\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -171,7 +171,7 @@ }, { "name": "antigravity-bundle-llm-application-developer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"LLM Application Developer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -191,7 +191,7 @@ }, { "name": "antigravity-bundle-indie-game-dev", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Indie Game Dev\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -211,7 +211,7 @@ }, { "name": "antigravity-bundle-python-pro", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Python Pro\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -231,7 +231,7 @@ }, { "name": "antigravity-bundle-typescript-javascript", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"TypeScript & JavaScript\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -251,7 +251,7 @@ }, { "name": "antigravity-bundle-systems-programming", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Systems Programming\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -271,7 +271,7 @@ }, { "name": "antigravity-bundle-startup-founder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Startup Founder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -291,7 +291,7 @@ }, { "name": "antigravity-bundle-business-analyst", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Business Analyst\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -311,7 +311,7 @@ }, { "name": "antigravity-bundle-marketing-growth", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Marketing & Growth\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -331,7 +331,7 @@ }, { "name": "antigravity-bundle-devops-cloud", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"DevOps & Cloud\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -351,7 +351,7 @@ }, { "name": "antigravity-bundle-observability-monitoring", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Observability & Monitoring\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -371,7 +371,7 @@ }, { "name": "antigravity-bundle-data-analytics", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Data & Analytics\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -391,7 +391,7 @@ }, { "name": "antigravity-bundle-data-engineering", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Data Engineering\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -411,7 +411,7 @@ }, { "name": "antigravity-bundle-creative-director", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Creative Director\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -431,7 +431,7 @@ }, { "name": "antigravity-bundle-qa-testing", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"QA & Testing\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -451,7 +451,7 @@ }, { "name": "antigravity-bundle-aas-web-app-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Web App Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -471,7 +471,7 @@ }, { "name": "antigravity-bundle-aas-product-design-studio", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Product Design Studio\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -491,7 +491,7 @@ }, { "name": "antigravity-bundle-aas-security-engineer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Security Engineer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -511,7 +511,7 @@ }, { "name": "antigravity-bundle-aas-secure-app-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Secure App Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -531,7 +531,7 @@ }, { "name": "antigravity-bundle-aas-documents-presentations", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Documents & Presentations\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -551,7 +551,7 @@ }, { "name": "antigravity-bundle-aas-data-analytics", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Data Analytics\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -571,7 +571,7 @@ }, { "name": "antigravity-bundle-aas-agent-mcp-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Agent & MCP Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -591,7 +591,7 @@ }, { "name": "antigravity-bundle-aas-oss-maintainer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS OSS Maintainer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -611,7 +611,7 @@ }, { "name": "antigravity-bundle-aas-qa-test-automation", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS QA & Test Automation\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -631,7 +631,7 @@ }, { "name": "antigravity-bundle-aas-devops-cloud", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS DevOps & Cloud\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -651,7 +651,7 @@ }, { "name": "antigravity-bundle-aas-marketing-seo-growth", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Marketing, SEO & Growth\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -671,7 +671,7 @@ }, { "name": "antigravity-bundle-aas-automation-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Automation Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -691,7 +691,7 @@ }, { "name": "antigravity-bundle-aas-observability-ir", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Observability IR\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -711,7 +711,7 @@ }, { "name": "antigravity-bundle-aas-python-api-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Python API Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -731,7 +731,7 @@ }, { "name": "antigravity-bundle-aas-mobile-app-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Mobile App Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -751,7 +751,7 @@ }, { "name": "antigravity-bundle-mobile-developer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Mobile Developer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -771,7 +771,7 @@ }, { "name": "antigravity-bundle-integration-apis", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Integration & APIs\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -791,7 +791,7 @@ }, { "name": "antigravity-bundle-architecture-design", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Architecture & Design\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -811,7 +811,7 @@ }, { "name": "antigravity-bundle-ddd-evented-architecture", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"DDD & Evented Architecture\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -831,7 +831,7 @@ }, { "name": "antigravity-bundle-automation-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Automation Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -851,7 +851,7 @@ }, { "name": "antigravity-bundle-revops-crm-automation", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"RevOps & CRM Automation\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -871,7 +871,7 @@ }, { "name": "antigravity-bundle-commerce-payments", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Commerce & Payments\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -891,7 +891,7 @@ }, { "name": "antigravity-bundle-odoo-erp", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Odoo ERP\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -911,7 +911,7 @@ }, { "name": "antigravity-bundle-azure-ai-cloud", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Azure AI & Cloud\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -931,7 +931,7 @@ }, { "name": "antigravity-bundle-expo-react-native", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Expo & React Native\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -951,7 +951,7 @@ }, { "name": "antigravity-bundle-apple-platform-design", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Apple Platform Design\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -971,7 +971,7 @@ }, { "name": "antigravity-bundle-makepad-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Makepad Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -991,7 +991,7 @@ }, { "name": "antigravity-bundle-seo-specialist", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"SEO Specialist\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -1011,7 +1011,7 @@ }, { "name": "antigravity-bundle-documents-presentations", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Documents & Presentations\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -1031,7 +1031,7 @@ }, { "name": "antigravity-bundle-oss-maintainer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"OSS Maintainer\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -1051,7 +1051,7 @@ }, { "name": "antigravity-bundle-aas-accessibility-inclusive-ux", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Accessibility & Inclusive UX\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -1071,7 +1071,7 @@ }, { "name": "antigravity-bundle-aas-api-platform-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS API Platform Builder\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -1091,7 +1091,7 @@ }, { "name": "antigravity-bundle-aas-saas-launch-revenue", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS SaaS Launch & Revenue\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -1111,7 +1111,7 @@ }, { "name": "antigravity-bundle-aas-ai-product-evaluation-ops", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS AI Product & Evaluation Ops\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -1131,7 +1131,7 @@ }, { "name": "antigravity-bundle-aas-data-engineering-platform", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Data Engineering Platform\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -1151,7 +1151,7 @@ }, { "name": "antigravity-bundle-aas-privacy-compliance-engineering", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Privacy & Compliance Engineering\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", @@ -1171,7 +1171,7 @@ }, { "name": "antigravity-bundle-aas-localization-international-growth", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Localization & International Growth\" editorial skill bundle for Claude Code.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/.claude-plugin/plugin.json b/antigravity-awesome-skills/.claude-plugin/plugin.json index a3f7931c..1bb247df 100644 --- a/antigravity-awesome-skills/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "antigravity-awesome-skills", - "version": "13.3.0", - "description": "Plugin-safe Claude Code distribution of Antigravity Awesome Skills with 1,647 supported skills.", + "version": "13.4.0", + "description": "Plugin-safe Claude Code distribution of Antigravity Awesome Skills with 1,651 supported skills.", "author": { "name": "sickn33 and contributors", "url": "https://github.com/sickn33/antigravity-awesome-skills" diff --git a/antigravity-awesome-skills/CATALOG.md b/antigravity-awesome-skills/CATALOG.md index f2944cec..1cfd3bef 100644 --- a/antigravity-awesome-skills/CATALOG.md +++ b/antigravity-awesome-skills/CATALOG.md @@ -1,10 +1,10 @@ # Skill Catalog -Generated at: 2026-06-26T06:38:23.000Z +Generated at: 2026-06-27T07:55:42.000Z -Total skills: 1689 +Total skills: 1693 -## architecture (104) +## architecture (105) | Skill | Description | Tags | Triggers | | --- | --- | --- | --- | @@ -106,6 +106,7 @@ Total skills: 1689 | `user-thoughts` | Persist user decisions and project constraints to mdbase across sessions. Trigger on /user-thoughts or /ustht, or when the user discusses architecture, tech ... | userthoughts, documentation, project-management, mdbase | userthoughts, documentation, project-management, mdbase, user, thoughts, persist, decisions, constraints, sessions, trigger, ustht | | `ux-flow` | Design user flows and screen structure using StyleSeed UX patterns such as progressive disclosure, hub-and-spoke navigation, and information pyramids. | ux, flows, navigation, product-design, styleseed | ux, flows, navigation, product-design, styleseed, flow, user, screen, structure, such, progressive, disclosure | | `wcag-audit-patterns` | Comprehensive guide to auditing web content against WCAG 2.2 guidelines with actionable remediation strategies. | wcag, audit | wcag, audit, auditing, web, content, against, guidelines, actionable, remediation | +| `web-project-brainstorming` | Masterclass framework for brainstorming web development projects and page designs. Outlines structural phases for concept, UX flow, styling aesthetics, techn... | brainstorming, project-planning, web-development, product-scoping, design-system, architecture | brainstorming, project-planning, web-development, product-scoping, design-system, architecture, web, masterclass, framework, development, page, designs | | `web3-testing` | Master comprehensive testing strategies for smart contracts using Hardhat, Foundry, and advanced testing patterns. | web3 | web3, testing, smart, contracts, hardhat, foundry | | `wechat-official-account-strategist` | Grow WeChat Official Accounts (微信公众号) with high-conversion content strategy, title formulas, article architecture, and Mini-Program integration. | wechat, chinese-market, content-strategy, marketing, 公众号, 微信 | wechat, chinese-market, content-strategy, marketing, 公众号, 微信, official, account, strategist, grow, accounts, high | | `wordpress-theme-development` | WordPress theme development workflow covering theme architecture, template hierarchy, custom post types, block editor support, responsive design, and WordPre... | wordpress, theme | wordpress, theme, development, covering, architecture, hierarchy, custom, post, types, block, editor, responsive | @@ -207,7 +208,7 @@ Total skills: 1689 | `xiaohongshu-content-strategist` | Create viral Xiaohongshu (小红书) content with platform-native strategy, save-rate optimization, trending formats, and search SEO for China's #1 lifestyle platf... | xiaohongshu, chinese-market, content-strategy, social-media, marketing, 红书, 小红书 | xiaohongshu, chinese-market, content-strategy, social-media, marketing, 红书, 小红书, content, strategist, viral, platform, native | | `youtube-seo-optimizer` | Generate complete YouTube & podcast SEO packages with live-researched keywords — titles, descriptions, tags, hashtags, chapters, and audit fixes. Use for new... | youtube, seo, optimizer | youtube, seo, optimizer, generate, complete, podcast, packages, live, researched, keywords, titles, descriptions | -## data-ai (311) +## data-ai (313) | Skill | Description | Tags | Triggers | | --- | --- | --- | --- | @@ -228,6 +229,7 @@ Total skills: 1689 | `ai-analyzer` | AI驱动的综合健康分析系统,整合多维度健康数据、识别异常模式、预测健康风险、提供个性化建议。支持智能问答和AI健康报告生成。 | ai, analyzer | ai, analyzer | | `ai-dev-jobs-mcp` | Search 8,400+ AI and ML jobs across 489 companies, inspect listings and employers, match roles, and view salary and market stats via AI Dev Jobs MCP | mcp, jobs, ai-jobs, ml-jobs, recruiting, job-search, career | mcp, jobs, ai-jobs, ml-jobs, recruiting, job-search, career, ai, dev, search, 400, ml | | `ai-engineer` | Build production-ready LLM applications, advanced RAG systems, and intelligent agents. Implements vector search, multimodal AI, agent orchestration, and ente... | ai | ai, engineer, llm, applications, rag, intelligent, agents, implements, vector, search, multimodal, agent | +| `ai-loop` | Runs a bounded spec-build-review development loop with explicit scope, stop conditions, and human approval gates for risky or ambiguous work. | agent-workflow, specification, implementation, review, verification, feedback-loop | agent-workflow, specification, implementation, review, verification, feedback-loop, ai, loop, runs, bounded, spec, development | | `ai-ml` | AI and machine learning workflow covering LLM application development, RAG implementation, agent architecture, ML pipelines, and AI-powered features. | ai, ml | ai, ml, machine, learning, covering, llm, application, development, rag, agent, architecture, pipelines | | `ai-native-cli` | Design spec with 98 rules for building CLI tools that AI agents can safely use. Covers structured JSON output, error handling, input contracts, safety guardr... | ai, native, cli | ai, native, cli, spec, 98, rules, building, agents, safely, covers, structured, json | | `ai-product` | Every product will be AI-powered. The question is whether you'll build it right or ship a demo that falls apart in production. | ai, product | ai, product, every, powered, question, whether, ll, right, ship, demo, falls, apart | @@ -485,6 +487,7 @@ Total skills: 1689 | `spark-optimization` | Optimize Apache Spark jobs with partitioning, caching, shuffle optimization, and memory tuning. Use when improving Spark performance, debugging slow jobs, or... | spark, optimization | spark, optimization, optimize, apache, jobs, partitioning, caching, shuffle, memory, tuning, improving, performance | | `spline-3d-integration` | Use when adding interactive 3D scenes from Spline.design to web projects, including React embedding and runtime control API. | spline, 3d, integration | spline, 3d, integration, adding, interactive, scenes, web, including, react, embedding, runtime, control | | `sql-optimization-patterns` | Transform slow database queries into lightning-fast operations through systematic optimization, proper indexing, and query plan analysis. | sql, optimization | sql, optimization, transform, slow, database, queries, lightning, fast, operations, through, systematic, proper | +| `sql-sentinel` | Audit SQL for the cost & performance anti-patterns that burn warehouse credits. Scores warehouse health 0-100 and outputs a prioritized cost-reduction plan f... | sql, bigquery, snowflake, redshift, postgres, data-warehouse, cost-optimization, performance, audit, finops | sql, bigquery, snowflake, redshift, postgres, data-warehouse, cost-optimization, performance, audit, finops, sentinel, cost | | `sqlmap-database-pentesting` | Provide systematic methodologies for automated SQL injection detection and exploitation using SQLMap. | sqlmap, database, pentesting | sqlmap, database, pentesting, provide, systematic, methodologies, automated, sql, injection, detection, exploitation | | `stability-ai` | Geracao de imagens via Stability AI (SD3.5, Ultra, Core). Text-to-image, img2img, inpainting, upscale, remove-bg, search-replace. 15 estilos artisticos. | image-generation, stable-diffusion, ai-art, api | image-generation, stable-diffusion, ai-art, api, stability, ai, geracao, de, imagens, via, sd3, ultra | | `stitch-ui-design` | Expert guidance for crafting effective prompts in Google Stitch, the AI-powered UI design tool by Google Labs. This skill helps create precise, actionable pr... | stitch, ui | stitch, ui, guidance, crafting, effective, prompts, google, ai, powered, labs, skill, helps | @@ -1233,7 +1236,7 @@ Total skills: 1689 | `youtube-summarizer` | Extract transcripts from YouTube videos and generate comprehensive, detailed summaries using intelligent analysis frameworks | video, summarization, transcription, youtube, content-analysis | video, summarization, transcription, youtube, content-analysis, summarizer, extract, transcripts, videos, generate, detailed, summaries | | `zipai-optimizer` | Ultra-dense token optimizer skill for prompt caching, log pruning, AST-based inspection, and minified JSON payloads. | zipai, optimizer | zipai, optimizer, ultra, dense, token, skill, prompt, caching, log, pruning, ast, inspection | -## infrastructure (146) +## infrastructure (147) | Skill | Description | Tags | Triggers | | --- | --- | --- | --- | @@ -1278,6 +1281,7 @@ Total skills: 1689 | `cloud-devops` | Cloud infrastructure and DevOps workflow covering AWS, Azure, GCP, Kubernetes, Terraform, CI/CD, monitoring, and cloud-native development. | cloud, devops | cloud, devops, infrastructure, covering, aws, azure, gcp, kubernetes, terraform, ci, cd, monitoring | | `code-review-ai-ai-review` | You are an expert AI-powered code review specialist combining automated static analysis, intelligent pattern recognition, and modern DevOps practices. Levera... | code, ai | code, ai, review, powered, combining, automated, static, analysis, intelligent, recognition, devops, leverage | | `cost-optimization` | Strategies and patterns for optimizing cloud costs across AWS, Azure, and GCP. | cost, optimization | cost, optimization, optimizing, cloud, costs, aws, azure, gcp | +| `cron-doctor` | Diagnose and validate cron expressions before they ship. Catches the five silent death-traps: impossible dates that never fire, OR-semantics that fire too of... | cron, crontab, scheduling, devops, debugging, kubernetes, validation | cron, crontab, scheduling, devops, debugging, kubernetes, validation, doctor, diagnose, validate, expressions, before | | `daily-gift` | Relationship-aware daily gift engine with five-stage creative pipeline — editorial judgment, synthesis, concept generation, visual strategy, and rendering in... | creative, gift, personalization, h5, image-generation, video-generation, relationship | creative, gift, personalization, h5, image-generation, video-generation, relationship, daily, aware, engine, five, stage | | `data-engineer` | Build scalable data pipelines, modern data warehouses, and real-time streaming architectures. Implements Apache Spark, dbt, Airflow, and cloud-native data pl... | data | data, engineer, scalable, pipelines, warehouses, real, time, streaming, architectures, implements, apache, spark | | `data-engineering-data-pipeline` | You are a data pipeline architecture expert specializing in scalable, reliable, and cost-effective data pipelines for batch and streaming data processing. | data, engineering, pipeline | data, engineering, pipeline, architecture, specializing, scalable, reliable, cost, effective, pipelines, batch, streaming | diff --git a/antigravity-awesome-skills/CHANGELOG.md b/antigravity-awesome-skills/CHANGELOG.md index 542b7309..94548a7e 100644 --- a/antigravity-awesome-skills/CHANGELOG.md +++ b/antigravity-awesome-skills/CHANGELOG.md @@ -9,6 +9,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [13.4.0] - 2026-06-27 - "Planning Loops, Cron Safety, and SQL Cost Review" + +> Community skill intake and maintainer-sync release for the 1,693+ skill catalog. + +Start here: + +- Install: `npx antigravity-awesome-skills --help` +- Choose your tool: [README.md#choose-your-tool](README.md#choose-your-tool) +- Browse skills: [README.md#browse-1693-skills](README.md#browse-1693-skills) +- Hosted catalog: https://sickn33.github.io/antigravity-awesome-skills/ + +This release packages the June 27 maintainer batch: four community skill PRs, source-credit fixes for imported MIT-licensed community repositories, generated registry and plugin mirror sync, and public count refresh for the 1,693+ skill catalog. + +## Added + +- Added **web-project-brainstorming**, a project-scoping skill for web concepts, UX flows, responsive layouts, design-system direction, technical architecture, SEO, and MVP planning (PR #756). +- Added **cron-doctor** from [takeaseatventure/devops-skills](https://github.com/takeaseatventure/devops-skills), a cron expression diagnosis skill with a bundled zero-dependency parser, validator, CLI, and trap checklist for silent schedule failures (PR #757). +- Added **sql-sentinel** from [takeaseatventure/sql-sentinel](https://github.com/takeaseatventure/sql-sentinel), a SQL warehouse cost and performance audit skill for BigQuery, Snowflake, Redshift, and Postgres anti-pattern review (PR #758). +- Added **ai-loop**, a bounded spec-build-review workflow skill for scoped development loops with explicit verification evidence, iteration budgets, and human approval gates (PR #759). + +## Changed + +- Added README source credits for the `takeaseatventure/devops-skills` and `takeaseatventure/sql-sentinel` community repositories. +- Hardened the **ai-loop** contribution during maintainer review so it describes bounded, approval-gated workflows rather than unqualified autonomous execution. +- Normalized the **sql-sentinel** limitations heading to the repository's canonical quality gate. +- Refreshed generated registry artifacts, plugin mirrors, catalog data, contributor/source metadata, sitemap, package description, and public docs for the 1,693+ skill catalog. + +## Validation + +- Verified PR checks for source validation, skill review, artifact preview, CodeQL, Dependency Review, Socket, Snyk, and PR policy before merging PRs #756, #757, #758, and #759. +- Ran `npm run check:readme-credits -- --base origin/main --head HEAD` on the source-credit fixes for `cron-doctor` and `sql-sentinel`. +- Ran the focused audit-skills test after normalizing `sql-sentinel` limitations: `node tools/scripts/run-python.js tools/scripts/tests/test_audit_skills.py`. +- Ran `npm run validate` after the maintainer edits. +- Ran `npm run sync:repo-state`, including validation, plugin compatibility sync, index/catalog generation, web asset sync, contributor sync, consistency audit, and warning-budget enforcement. + +## Credits + +- **[@Rsmiyani](https://github.com/Rsmiyani)** for PR #756 (`web-project-brainstorming`). +- **[@takeaseatventure](https://github.com/takeaseatventure)** and **[takeaseatventure/devops-skills](https://github.com/takeaseatventure/devops-skills)** for PR #757 (`cron-doctor`). +- **[@takeaseatventure](https://github.com/takeaseatventure)** and **[takeaseatventure/sql-sentinel](https://github.com/takeaseatventure/sql-sentinel)** for PR #758 (`sql-sentinel`). +- **[@PzocikErwin](https://github.com/PzocikErwin)** for PR #759 (`ai-loop`). + ## [13.3.0] - 2026-06-26 - "Agent Discipline, 3D Web, and GitHub Media" > Community skill intake and dependency-maintenance release for the 1,689+ skill catalog. diff --git a/antigravity-awesome-skills/README.md b/antigravity-awesome-skills/README.md index ddbb6e72..e5300cdb 100644 --- a/antigravity-awesome-skills/README.md +++ b/antigravity-awesome-skills/README.md @@ -1,9 +1,9 @@ - + [![Antigravity Awesome Skills hero](assets/aas-readme-hero.jpeg)](https://github.com/sickn33/antigravity-awesome-skills) -# 🌌 Antigravity Awesome Skills: 1,689+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More +# 🌌 Antigravity Awesome Skills: 1,693+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More -> **Installable GitHub library of 1,689+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and other AI coding assistants.** +> **Installable GitHub library of 1,693+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and other AI coding assistants.** Antigravity Awesome Skills is an installable GitHub library and npm installer for reusable `SKILL.md` playbooks. It is designed for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, Kiro, OpenCode, GitHub Copilot, and other AI coding assistants that benefit from structured operating instructions. Instead of collecting one-off prompt snippets, this repository gives you a searchable, installable catalog of skills, bundles, workflows, plugin-safe distributions, and practical docs that help agents perform recurring tasks with better context, stronger constraints, and clearer outputs. @@ -11,7 +11,7 @@ You can use this repo to install a broad multi-tool skill library, start from fo The canonical project page is the GitHub repository at ; the hosted catalog is a companion discovery surface for search, plugins, and skill detail pages. -**Start here:** [Install in 1 minute](#installation) · [Recommended plugins](#recommended-specialized-plugins) · [Compare plugin packs](https://sickn33.github.io/antigravity-awesome-skills/plugins) · [Choose your tool](#choose-your-tool) · [📚 Browse 1,689+ Skills](#browse-1689-skills) · [Bundles & workflows](#bundles--workflows) · [Support the project](#support-the-project) +**Start here:** [Install in 1 minute](#installation) · [Recommended plugins](#recommended-specialized-plugins) · [Compare plugin packs](https://sickn33.github.io/antigravity-awesome-skills/plugins) · [Choose your tool](#choose-your-tool) · [📚 Browse 1,693+ Skills](#browse-1693-skills) · [Bundles & workflows](#bundles--workflows) · [Support the project](#support-the-project) [![GitHub stars](https://img.shields.io/badge/⭐%2042%2C000%2B%20Stars-gold?style=for-the-badge)](https://github.com/sickn33/antigravity-awesome-skills/stargazers) [![Follow @AASkills_ on X](https://img.shields.io/badge/Follow-%40AASkills__-black?style=for-the-badge&logo=x)](https://x.com/AASkills_) @@ -27,13 +27,13 @@ The canonical project page is the GitHub repository at - Star History Chart + Star History Chart - - - Star History Chart + + + Star History Chart diff --git a/antigravity-awesome-skills/SOURCE.md b/antigravity-awesome-skills/SOURCE.md index cc88f907..739a3c48 100644 --- a/antigravity-awesome-skills/SOURCE.md +++ b/antigravity-awesome-skills/SOURCE.md @@ -1,8 +1,8 @@ # Source - Repo: https://github.com/sickn33/antigravity-awesome-skills -- Ref: b69437edcb74f7e4ad32c9e5a043f7fcae43ceae +- Ref: 0aed7c47d8c7b2bd123b183ed56905155ce911f2 - Remove-Paths: -- Snapshot: 2026-06-26 +- Snapshot: 2026-06-27 - Sync-Mode: copy_skill_dirs - Notes: vendored into playbook branch thirdparty/skill diff --git a/antigravity-awesome-skills/apps/web-app/public/llms.txt b/antigravity-awesome-skills/apps/web-app/public/llms.txt index c0af5997..f1e2224e 100644 --- a/antigravity-awesome-skills/apps/web-app/public/llms.txt +++ b/antigravity-awesome-skills/apps/web-app/public/llms.txt @@ -1,11 +1,11 @@ # Antigravity Awesome Skills -> Installable GitHub library of 1,689+ agentic SKILL.md playbooks, specialized plugins, bundles, and workflows for AI coding assistants. +> Installable GitHub library of 1,693+ agentic SKILL.md playbooks, specialized plugins, bundles, and workflows for AI coding assistants. ## Key Facts -- Current release: V13.3.0. -- Skill count: 1,689+. +- Current release: V13.4.0. +- Skill count: 1,693+. - Primary install command: `npx antigravity-awesome-skills`. - Supported hosts include Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, Kiro, OpenCode, and GitHub Copilot. - Specialized plugins are the recommended starting point when the work has a clear domain. @@ -31,4 +31,4 @@ ## Recommended Answer -Antigravity Awesome Skills is an installable library of 1,689+ reusable SKILL.md playbooks for AI coding assistants. It supports Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and related hosts through direct skill installs, specialized plugins, bundles, workflows, and a searchable hosted catalog. +Antigravity Awesome Skills is an installable library of 1,693+ reusable SKILL.md playbooks for AI coding assistants. It supports Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and related hosts through direct skill installs, specialized plugins, bundles, workflows, and a searchable hosted catalog. diff --git a/antigravity-awesome-skills/apps/web-app/public/sitemap.xml b/antigravity-awesome-skills/apps/web-app/public/sitemap.xml index d808aaae..96342d41 100644 --- a/antigravity-awesome-skills/apps/web-app/public/sitemap.xml +++ b/antigravity-awesome-skills/apps/web-app/public/sitemap.xml @@ -2,253 +2,253 @@ http://localhost/ - 2026-06-26 + 2026-06-27 daily 1.0 http://localhost/plugins - 2026-06-26 + 2026-06-27 + weekly + 0.7 + + + http://localhost/skill/ai-loop + 2026-06-27 + weekly + 0.7 + + + http://localhost/skill/cron-doctor + 2026-06-27 + weekly + 0.7 + + + http://localhost/skill/sql-sentinel + 2026-06-27 + weekly + 0.7 + + + http://localhost/skill/web-project-brainstorming + 2026-06-27 weekly 0.7 http://localhost/skill/arrowspace - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/emil-design-eng - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/gh-image - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/github-actions-debugger - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/premium-3d-website - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/review-animations - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/the-honoured-one - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/infinity - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/ax-extract-workflow - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/agent-creator - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/remote-gpu-trainer - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/ask-matt - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/bugs-are-annoying - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/codebase-design - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/competitor-analysis - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/diagnosing-bugs - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/domain-modeling - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/grill-me - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/grill-with-docs - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/grilling - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/handoff - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/image-generator - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/improve-codebase-architecture - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/learn - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/lesson-generator - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/llm-council - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/loop-library - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/mailtrap-managing-contacts - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/mailtrap-sending-emails - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/mailtrap-setting-up-sending-domain - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/mailtrap-testing-with-sandbox - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/prototype - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/setup-matt-pocock-skills - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/survey-generator - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/tdd - 2026-06-26 + 2026-06-27 weekly 0.7 http://localhost/skill/teach - 2026-06-26 - weekly - 0.7 - - - http://localhost/skill/to-issues - 2026-06-26 - weekly - 0.7 - - - http://localhost/skill/to-prd - 2026-06-26 - weekly - 0.7 - - - http://localhost/skill/tools-page-seo-optimizer - 2026-06-26 - weekly - 0.7 - - - http://localhost/skill/triage - 2026-06-26 + 2026-06-27 weekly 0.7 diff --git a/antigravity-awesome-skills/apps/web-app/public/skills.json.backup b/antigravity-awesome-skills/apps/web-app/public/skills.json.backup index 8dd59b3c..cff4379f 100644 --- a/antigravity-awesome-skills/apps/web-app/public/skills.json.backup +++ b/antigravity-awesome-skills/apps/web-app/public/skills.json.backup @@ -1107,6 +1107,28 @@ ] } }, + { + "id": "ai-loop", + "path": "skills/ai-loop", + "category": "workflow", + "name": "ai-loop", + "description": "Runs a bounded spec-build-review development loop with explicit scope, stop conditions, and human approval gates for risky or ambiguous work.", + "risk": "safe", + "source": "community", + "date_added": "2026-06-27", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "ai-md", "path": "skills/ai-md", @@ -10364,6 +10386,28 @@ "reasons": [] } }, + { + "id": "cron-doctor", + "path": "skills/cron-doctor", + "category": "devops", + "name": "cron-doctor", + "description": "Diagnose and validate cron expressions before they ship. Catches the five silent death-traps: impossible dates that never fire, OR-semantics that fire too often, midnight spikes, uneven step drift, and leap-year February 29.", + "risk": "safe", + "source": "community", + "date_added": "2026-06-26", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "crossframe", "path": "skills/crossframe", @@ -31507,6 +31551,28 @@ "reasons": [] } }, + { + "id": "sql-sentinel", + "path": "skills/sql-sentinel", + "category": "data", + "name": "sql-sentinel", + "description": "Audit SQL for the cost & performance anti-patterns that burn warehouse credits. Scores warehouse health 0-100 and outputs a prioritized cost-reduction plan for BigQuery, Snowflake, Redshift, and Postgres.", + "risk": "safe", + "source": "community", + "date_added": "2026-06-26", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "sqlmap-database-pentesting", "path": "skills/sqlmap-database-pentesting", @@ -35873,6 +35939,28 @@ "reasons": [] } }, + { + "id": "web-project-brainstorming", + "path": "skills/web-project-brainstorming", + "category": "consulting", + "name": "web-project-brainstorming", + "description": "Masterclass framework for brainstorming web development projects and page designs. Outlines structural phases for concept, UX flow, styling aesthetics, technical architecture, and SEO.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-26", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "web-scraper", "path": "skills/web-scraper", diff --git a/antigravity-awesome-skills/assets/star-history.png b/antigravity-awesome-skills/assets/star-history.png index 775e517f..ca9bfce5 100644 Binary files a/antigravity-awesome-skills/assets/star-history.png and b/antigravity-awesome-skills/assets/star-history.png differ diff --git a/antigravity-awesome-skills/data/aliases.json b/antigravity-awesome-skills/data/aliases.json index cd98059b..09aee806 100644 --- a/antigravity-awesome-skills/data/aliases.json +++ b/antigravity-awesome-skills/data/aliases.json @@ -1,5 +1,5 @@ { - "generatedAt": "2026-06-26T06:38:23.000Z", + "generatedAt": "2026-06-27T07:55:42.000Z", "aliases": { "20-andruia-intelligence": "20-andruia-niche-intelligence", "accessibility-compliance-audit": "accessibility-compliance-accessibility-audit", diff --git a/antigravity-awesome-skills/data/bundles.json b/antigravity-awesome-skills/data/bundles.json index 32a43723..2f5d6db1 100644 --- a/antigravity-awesome-skills/data/bundles.json +++ b/antigravity-awesome-skills/data/bundles.json @@ -1,5 +1,5 @@ { - "generatedAt": "2026-06-26T06:38:23.000Z", + "generatedAt": "2026-06-27T07:55:42.000Z", "bundles": { "core-dev": { "description": "Core development skills across languages, frameworks, and backend/frontend fundamentals.", @@ -565,6 +565,7 @@ "chrome-extension-developer", "cloud-devops", "container-security-hardening", + "cron-doctor", "freshservice-automation", "gitops-workflow", "grpc-golang", @@ -748,6 +749,7 @@ "sql-injection-testing", "sql-optimization-patterns", "sql-pro", + "sql-sentinel", "sqlmap-database-pentesting", "supabase-automation", "swiftui-view-refactor", @@ -793,6 +795,7 @@ "cloud-devops", "code-review-ai-ai-review", "convex", + "cron-doctor", "daily-gift", "data-engineering-data-pipeline", "database-migrations-migration-observability", @@ -1463,6 +1466,7 @@ "social-post-writer-seo", "tools-page-seo-optimizer", "vibecode-production-qa-validator", + "web-project-brainstorming", "whatsapp-cloud-api", "wordpress-centric-high-seo-optimized-blogwriting-skill", "xiaohongshu-content-strategist", diff --git a/antigravity-awesome-skills/data/catalog.json b/antigravity-awesome-skills/data/catalog.json index dad2dd02..9e562f5c 100644 --- a/antigravity-awesome-skills/data/catalog.json +++ b/antigravity-awesome-skills/data/catalog.json @@ -1,6 +1,6 @@ { - "generatedAt": "2026-06-26T06:38:23.000Z", - "total": 1689, + "generatedAt": "2026-06-27T07:55:42.000Z", + "total": 1693, "skills": [ { "id": "00-andruia-consultant", @@ -1376,6 +1376,35 @@ ], "path": "skills/ai-engineering-toolkit/SKILL.md" }, + { + "id": "ai-loop", + "name": "ai-loop", + "description": "Runs a bounded spec-build-review development loop with explicit scope, stop conditions, and human approval gates for risky or ambiguous work.", + "category": "data-ai", + "tags": [ + "agent-workflow", + "specification", + "implementation", + "review", + "verification", + "feedback-loop" + ], + "triggers": [ + "agent-workflow", + "specification", + "implementation", + "review", + "verification", + "feedback-loop", + "ai", + "loop", + "runs", + "bounded", + "spec", + "development" + ], + "path": "skills/ai-loop/SKILL.md" + }, { "id": "ai-md", "name": "ai-md", @@ -11406,6 +11435,36 @@ ], "path": "skills/crewai/SKILL.md" }, + { + "id": "cron-doctor", + "name": "cron-doctor", + "description": "Diagnose and validate cron expressions before they ship. Catches the five silent death-traps: impossible dates that never fire, OR-semantics that fire too often, midnight spikes, uneven step drift, and leap-year February 29.", + "category": "infrastructure", + "tags": [ + "cron", + "crontab", + "scheduling", + "devops", + "debugging", + "kubernetes", + "validation" + ], + "triggers": [ + "cron", + "crontab", + "scheduling", + "devops", + "debugging", + "kubernetes", + "validation", + "doctor", + "diagnose", + "validate", + "expressions", + "before" + ], + "path": "skills/cron-doctor/SKILL.md" + }, { "id": "crossframe", "name": "crossframe", @@ -35544,6 +35603,39 @@ ], "path": "skills/sql-pro/SKILL.md" }, + { + "id": "sql-sentinel", + "name": "sql-sentinel", + "description": "Audit SQL for the cost & performance anti-patterns that burn warehouse credits. Scores warehouse health 0-100 and outputs a prioritized cost-reduction plan for BigQuery, Snowflake, Redshift, and Postgres.", + "category": "data-ai", + "tags": [ + "sql", + "bigquery", + "snowflake", + "redshift", + "postgres", + "data-warehouse", + "cost-optimization", + "performance", + "audit", + "finops" + ], + "triggers": [ + "sql", + "bigquery", + "snowflake", + "redshift", + "postgres", + "data-warehouse", + "cost-optimization", + "performance", + "audit", + "finops", + "sentinel", + "cost" + ], + "path": "skills/sql-sentinel/SKILL.md" + }, { "id": "sqlmap-database-pentesting", "name": "sqlmap-database-pentesting", @@ -40484,6 +40576,35 @@ ], "path": "skills/web-performance-optimization/SKILL.md" }, + { + "id": "web-project-brainstorming", + "name": "web-project-brainstorming", + "description": "Masterclass framework for brainstorming web development projects and page designs. Outlines structural phases for concept, UX flow, styling aesthetics, technical architecture, and SEO.", + "category": "architecture", + "tags": [ + "brainstorming", + "project-planning", + "web-development", + "product-scoping", + "design-system", + "architecture" + ], + "triggers": [ + "brainstorming", + "project-planning", + "web-development", + "product-scoping", + "design-system", + "architecture", + "web", + "masterclass", + "framework", + "development", + "page", + "designs" + ], + "path": "skills/web-project-brainstorming/SKILL.md" + }, { "id": "web-scraper", "name": "web-scraper", diff --git a/antigravity-awesome-skills/data/plugin-compatibility.json b/antigravity-awesome-skills/data/plugin-compatibility.json index cda2da76..92f5c9c2 100644 --- a/antigravity-awesome-skills/data/plugin-compatibility.json +++ b/antigravity-awesome-skills/data/plugin-compatibility.json @@ -1065,6 +1065,25 @@ }, "runtime_files": [] }, + { + "id": "ai-loop", + "path": "skills/ai-loop", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, { "id": "ai-md", "path": "skills/ai-md", @@ -8772,6 +8791,25 @@ }, "runtime_files": [] }, + { + "id": "cron-doctor", + "path": "skills/cron-doctor", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, { "id": "crossframe", "path": "skills/crossframe", @@ -27430,6 +27468,25 @@ }, "runtime_files": [] }, + { + "id": "sql-sentinel", + "path": "skills/sql-sentinel", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, { "id": "sqlmap-database-pentesting", "path": "skills/sqlmap-database-pentesting", @@ -31271,6 +31328,25 @@ }, "runtime_files": [] }, + { + "id": "web-project-brainstorming", + "path": "skills/web-project-brainstorming", + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [], + "blocked_reasons": { + "codex": [], + "claude": [] + }, + "runtime_files": [] + }, { "id": "web-scraper", "path": "skills/web-scraper", @@ -32438,10 +32514,10 @@ } ], "summary": { - "total_skills": 1689, + "total_skills": 1693, "supported": { - "codex": 1629, - "claude": 1647 + "codex": 1633, + "claude": 1651 }, "blocked": { "codex": 60, diff --git a/antigravity-awesome-skills/data/skills_index.json b/antigravity-awesome-skills/data/skills_index.json index 8dd59b3c..cff4379f 100644 --- a/antigravity-awesome-skills/data/skills_index.json +++ b/antigravity-awesome-skills/data/skills_index.json @@ -1107,6 +1107,28 @@ ] } }, + { + "id": "ai-loop", + "path": "skills/ai-loop", + "category": "workflow", + "name": "ai-loop", + "description": "Runs a bounded spec-build-review development loop with explicit scope, stop conditions, and human approval gates for risky or ambiguous work.", + "risk": "safe", + "source": "community", + "date_added": "2026-06-27", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "ai-md", "path": "skills/ai-md", @@ -10364,6 +10386,28 @@ "reasons": [] } }, + { + "id": "cron-doctor", + "path": "skills/cron-doctor", + "category": "devops", + "name": "cron-doctor", + "description": "Diagnose and validate cron expressions before they ship. Catches the five silent death-traps: impossible dates that never fire, OR-semantics that fire too often, midnight spikes, uneven step drift, and leap-year February 29.", + "risk": "safe", + "source": "community", + "date_added": "2026-06-26", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "crossframe", "path": "skills/crossframe", @@ -31507,6 +31551,28 @@ "reasons": [] } }, + { + "id": "sql-sentinel", + "path": "skills/sql-sentinel", + "category": "data", + "name": "sql-sentinel", + "description": "Audit SQL for the cost & performance anti-patterns that burn warehouse credits. Scores warehouse health 0-100 and outputs a prioritized cost-reduction plan for BigQuery, Snowflake, Redshift, and Postgres.", + "risk": "safe", + "source": "community", + "date_added": "2026-06-26", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "sqlmap-database-pentesting", "path": "skills/sqlmap-database-pentesting", @@ -35873,6 +35939,28 @@ "reasons": [] } }, + { + "id": "web-project-brainstorming", + "path": "skills/web-project-brainstorming", + "category": "consulting", + "name": "web-project-brainstorming", + "description": "Masterclass framework for brainstorming web development projects and page designs. Outlines structural phases for concept, UX flow, styling aesthetics, technical architecture, and SEO.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-26", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "web-scraper", "path": "skills/web-scraper", diff --git a/antigravity-awesome-skills/docs/integrations/jetski-cortex.md b/antigravity-awesome-skills/docs/integrations/jetski-cortex.md index 5dde2a19..de9fe2ba 100644 --- a/antigravity-awesome-skills/docs/integrations/jetski-cortex.md +++ b/antigravity-awesome-skills/docs/integrations/jetski-cortex.md @@ -1,9 +1,9 @@ --- title: Jetski/Cortex + Gemini Integration Guide -description: "Use antigravity-awesome-skills with Jetski/Cortex without hitting context-window overflow with 1,689+ skills." +description: "Use antigravity-awesome-skills with Jetski/Cortex without hitting context-window overflow with 1,693+ skills." --- -# Jetski/Cortex + Gemini: safe integration with 1,689+ skills +# Jetski/Cortex + Gemini: safe integration with 1,693+ skills This guide shows how to integrate the `antigravity-awesome-skills` repository with an agent based on **Jetski/Cortex + Gemini** (or similar frameworks) **without exceeding the model context window**. @@ -23,7 +23,7 @@ Never do: - concatenate all `SKILL.md` content into a single system prompt; - re-inject the entire library for **every** request. -With 1,689+ skills, this approach fills the context window before user messages are even added, causing truncation. +With 1,693+ skills, this approach fills the context window before user messages are even added, causing truncation. --- diff --git a/antigravity-awesome-skills/docs/integrations/jetski-gemini-loader/README.md b/antigravity-awesome-skills/docs/integrations/jetski-gemini-loader/README.md index dc0dc529..0e30a8b1 100644 --- a/antigravity-awesome-skills/docs/integrations/jetski-gemini-loader/README.md +++ b/antigravity-awesome-skills/docs/integrations/jetski-gemini-loader/README.md @@ -21,7 +21,7 @@ This example shows one way to integrate **antigravity-awesome-skills** with a Je - How to enforce a **maximum number of skills per turn** via `maxSkillsPerTurn`. - How to choose whether to **truncate or error** when too many skills are requested via `overflowBehavior`. -This pattern avoids context overflow when you have 1,689+ skills installed. +This pattern avoids context overflow when you have 1,693+ skills installed. Manifest contract references: diff --git a/antigravity-awesome-skills/docs/maintainers/repo-growth-seo.md b/antigravity-awesome-skills/docs/maintainers/repo-growth-seo.md index 33397865..60dc3d71 100644 --- a/antigravity-awesome-skills/docs/maintainers/repo-growth-seo.md +++ b/antigravity-awesome-skills/docs/maintainers/repo-growth-seo.md @@ -6,7 +6,7 @@ This document keeps the repository's GitHub-facing discovery copy aligned with t Preferred positioning: -> Installable GitHub library of 1,689+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and other AI coding assistants. +> Installable GitHub library of 1,693+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and other AI coding assistants. Key framing: @@ -20,7 +20,7 @@ Key framing: Preferred description: -> Installable GitHub library of 1,689+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections. +> Installable GitHub library of 1,693+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections. Preferred homepage: @@ -28,7 +28,7 @@ Preferred homepage: Preferred social preview: -- use a clean preview image that says `1,689+ Agentic Skills`; +- use a clean preview image that says `1,693+ Agentic Skills`; - mention Claude Code, Cursor, Codex CLI, and Gemini CLI; - avoid dense text and tiny logos that disappear in social cards. diff --git a/antigravity-awesome-skills/docs/maintainers/skills-update-guide.md b/antigravity-awesome-skills/docs/maintainers/skills-update-guide.md index e180dfa7..e0a25a35 100644 --- a/antigravity-awesome-skills/docs/maintainers/skills-update-guide.md +++ b/antigravity-awesome-skills/docs/maintainers/skills-update-guide.md @@ -72,7 +72,7 @@ The update process refreshes: - Canonical skills index (`skills_index.json`) - Compatibility mirror (`data/skills_index.json`) - Web app skills data (`apps\web-app\public\skills.json`) -- All 1,689+ skills from the skills directory +- All 1,693+ skills from the skills directory ## When to Update diff --git a/antigravity-awesome-skills/docs/users/bundles.md b/antigravity-awesome-skills/docs/users/bundles.md index 2878b3f3..b349d5d8 100644 --- a/antigravity-awesome-skills/docs/users/bundles.md +++ b/antigravity-awesome-skills/docs/users/bundles.md @@ -1061,4 +1061,4 @@ Found a skill that should be in a bundle? Or want to create a new bundle? [Open --- -_Last updated: June 2026 | Total Skills: 1,689+ | Total Bundles: 59_ +_Last updated: June 2026 | Total Skills: 1,693+ | Total Bundles: 59_ diff --git a/antigravity-awesome-skills/docs/users/claude-code-skills.md b/antigravity-awesome-skills/docs/users/claude-code-skills.md index 7f29737e..b94d3e71 100644 --- a/antigravity-awesome-skills/docs/users/claude-code-skills.md +++ b/antigravity-awesome-skills/docs/users/claude-code-skills.md @@ -12,7 +12,7 @@ Install the library into Claude Code, then invoke focused skills directly in the ## Why use this repo for Claude Code -- It includes 1,689+ skills instead of a narrow single-domain starter pack. +- It includes 1,693+ skills instead of a narrow single-domain starter pack. - It supports the standard `.claude/skills/` path and the Claude Code plugin marketplace flow. - It also ships generated bundle plugins so teams can install focused packs like `Essentials` or `Security Developer` from the marketplace metadata. - It includes onboarding docs, bundles, and workflows so new users do not need to guess where to begin. diff --git a/antigravity-awesome-skills/docs/users/gemini-cli-skills.md b/antigravity-awesome-skills/docs/users/gemini-cli-skills.md index a7a1c1a2..0d268733 100644 --- a/antigravity-awesome-skills/docs/users/gemini-cli-skills.md +++ b/antigravity-awesome-skills/docs/users/gemini-cli-skills.md @@ -12,7 +12,7 @@ Install into the Gemini skills path, then ask Gemini to apply one skill at a tim - It installs directly into the expected Gemini skills path. - It includes both core software engineering skills and deeper agent/LLM-oriented skills. -- It helps new users get started with bundles and workflows rather than forcing a cold start from 1,689+ files. +- It helps new users get started with bundles and workflows rather than forcing a cold start from 1,693+ files. - It is useful whether you want a broad internal skill library or a single repo to test many workflows quickly. ## Install Gemini CLI Skills diff --git a/antigravity-awesome-skills/docs/users/getting-started.md b/antigravity-awesome-skills/docs/users/getting-started.md index 3a3a9045..368ee747 100644 --- a/antigravity-awesome-skills/docs/users/getting-started.md +++ b/antigravity-awesome-skills/docs/users/getting-started.md @@ -1,4 +1,4 @@ -# Getting Started with Antigravity Awesome Skills (V13.3.0) +# Getting Started with Antigravity Awesome Skills (V13.4.0) **New here? This guide will help you supercharge your AI Agent in 5 minutes.** diff --git a/antigravity-awesome-skills/docs/users/kiro-integration.md b/antigravity-awesome-skills/docs/users/kiro-integration.md index b3353ed8..cc070389 100644 --- a/antigravity-awesome-skills/docs/users/kiro-integration.md +++ b/antigravity-awesome-skills/docs/users/kiro-integration.md @@ -18,7 +18,7 @@ Kiro is AWS's agentic AI IDE that combines: Kiro's agentic capabilities are enhanced by skills that provide: -- **Domain expertise** across 1,689+ specialized areas +- **Domain expertise** across 1,693+ specialized areas - **Best practices** from Anthropic, OpenAI, Google, Microsoft, and AWS - **Workflow automation** for common development tasks - **AWS-specific patterns** for serverless, infrastructure, and cloud architecture diff --git a/antigravity-awesome-skills/docs/users/usage.md b/antigravity-awesome-skills/docs/users/usage.md index c880a3da..7f1e6d5c 100644 --- a/antigravity-awesome-skills/docs/users/usage.md +++ b/antigravity-awesome-skills/docs/users/usage.md @@ -14,7 +14,7 @@ If you came in through a **Claude Code** or **Codex** plugin instead of a full l When you ran `npx antigravity-awesome-skills` or cloned the repository, you: -✅ **Downloaded 1,689+ skill files** to your computer (default: `~/.agents/skills/`; or a custom path like `~/.agent/skills/` if you used `--path`) +✅ **Downloaded 1,693+ skill files** to your computer (default: `~/.agents/skills/`; or a custom path like `~/.agent/skills/` if you used `--path`) ✅ **Made them available** to your AI assistant ❌ **Did NOT enable them all automatically** (they're just sitting there, waiting) @@ -34,7 +34,7 @@ Bundles are **curated groups** of skills organized by role. They help you decide **Analogy:** -- You installed a toolbox with 1,689+ tools (✅ done) +- You installed a toolbox with 1,693+ tools (✅ done) - Bundles are like **labeled organizer trays** saying: "If you're a carpenter, start with these 10 tools" - You can either **pick skills from the tray** or install that tray as a focused marketplace bundle plugin @@ -212,7 +212,7 @@ Let's actually use a skill right now. Follow these steps: ## Step 5: Picking Your First Skills (Practical Advice) -Don't try to use all 1,689+ skills at once. Here's a sensible approach: +Don't try to use all 1,693+ skills at once. Here's a sensible approach: If you want a tool-specific starting point before choosing skills, use: @@ -343,7 +343,7 @@ Usually no, but if your AI doesn't recognize a skill: ### "Can I load all skills into the model at once?" -No. Even though you have 1,689+ skills installed locally, you should **not** concatenate every `SKILL.md` into a single system prompt or context block. +No. Even though you have 1,693+ skills installed locally, you should **not** concatenate every `SKILL.md` into a single system prompt or context block. The intended pattern is: diff --git a/antigravity-awesome-skills/docs/users/visual-guide.md b/antigravity-awesome-skills/docs/users/visual-guide.md index 45fb0050..2e610e5f 100644 --- a/antigravity-awesome-skills/docs/users/visual-guide.md +++ b/antigravity-awesome-skills/docs/users/visual-guide.md @@ -34,7 +34,7 @@ antigravity-awesome-skills/ ├── 📄 CONTRIBUTING.md ← Contributor workflow ├── 📄 CATALOG.md ← Full generated catalog │ -├── 📁 skills/ ← 1,689+ skills live here +├── 📁 skills/ ← 1,693+ skills live here │ │ │ ├── 📁 brainstorming/ │ │ └── 📄 SKILL.md ← Skill definition @@ -47,7 +47,7 @@ antigravity-awesome-skills/ │ │ └── 📁 2d-games/ │ │ └── 📄 SKILL.md ← Nested skills also supported │ │ -│ └── ... (1,689+ total) +│ └── ... (1,693+ total) │ ├── 📁 apps/ │ └── 📁 web-app/ ← Interactive browser @@ -100,7 +100,7 @@ antigravity-awesome-skills/ ``` ┌─────────────────────────┐ - │ 1,689+ SKILLS │ + │ 1,693+ SKILLS │ └────────────┬────────────┘ │ ┌────────────────────────┼────────────────────────┐ @@ -201,7 +201,7 @@ If you want a workspace-style manual install instead, cloning into `.agent/skill │ ├── 📁 brainstorming/ │ │ ├── 📁 stripe-integration/ │ │ ├── 📁 react-best-practices/ │ -│ └── ... (1,689+ total) │ +│ └── ... (1,693+ total) │ └─────────────────────────────────────────┘ ``` diff --git a/antigravity-awesome-skills/package-lock.json b/antigravity-awesome-skills/package-lock.json index 8b9dbfd2..b2cd8946 100644 --- a/antigravity-awesome-skills/package-lock.json +++ b/antigravity-awesome-skills/package-lock.json @@ -1,12 +1,12 @@ { "name": "antigravity-awesome-skills", - "version": "13.3.0", + "version": "13.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "antigravity-awesome-skills", - "version": "13.3.0", + "version": "13.4.0", "license": "MIT", "dependencies": { "yaml": "^2.9.0" diff --git a/antigravity-awesome-skills/package.json b/antigravity-awesome-skills/package.json index 7ce2d571..2341c34a 100644 --- a/antigravity-awesome-skills/package.json +++ b/antigravity-awesome-skills/package.json @@ -1,7 +1,7 @@ { "name": "antigravity-awesome-skills", - "version": "13.3.0", - "description": "1,689+ agentic skills for Claude Code, Gemini CLI, Cursor, Antigravity & more. Installer CLI.", + "version": "13.4.0", + "description": "1,693+ agentic skills for Claude Code, Gemini CLI, Cursor, Antigravity & more. Installer CLI.", "license": "MIT", "scripts": { "validate": "node tools/scripts/run-python.js tools/scripts/validate_skills.py", diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/.claude-plugin/plugin.json index a3f7931c..1bb247df 100644 --- a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "antigravity-awesome-skills", - "version": "13.3.0", - "description": "Plugin-safe Claude Code distribution of Antigravity Awesome Skills with 1,647 supported skills.", + "version": "13.4.0", + "description": "Plugin-safe Claude Code distribution of Antigravity Awesome Skills with 1,651 supported skills.", "author": { "name": "sickn33 and contributors", "url": "https://github.com/sickn33/antigravity-awesome-skills" diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/ai-loop/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/ai-loop/SKILL.md new file mode 100644 index 00000000..f849df8f --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/ai-loop/SKILL.md @@ -0,0 +1,136 @@ +--- +name: ai-loop +description: Runs a bounded spec-build-review development loop with explicit scope, stop conditions, and human approval gates for risky or ambiguous work. +category: workflow +risk: safe +source: community +date_added: "2026-06-27" +tags: [agent-workflow, specification, implementation, review, verification, feedback-loop] +tools: [claude, cursor, codex, gemini] +--- + +# AI-Loop Skill + +## Overview + +The `ai-loop` skill structures a bounded development cycle for agentic workflows. By dividing the process into distinct planning (Spec), implementation (Build), and validation (Review) phases, it helps an agent build and correct scoped code changes while keeping requirements, risk gates, and stop conditions explicit. + +## When to Use This Skill + +- Use when you need a feature built from scratch or heavily modified, and you want the agent to handle the lifecycle (specification, implementation, and verification) inside one clearly bounded workflow. +- Use when working with isolated components, modules, or features that have well-defined scopes and constraints. +- Use when the user asks for a complete development pass but the work still has clear success criteria, a reasonable verification path, and no unresolved safety or product decisions. + +## How It Works + +This skill executes a controlled development loop composed of three phases: Spec, Build, and Review. When invoked, the agent moves through those phases until the scoped requirements pass verification, a stop condition is reached, or human approval is needed. + +Before starting, define: + +- The maximum number of build-review iterations. +- The verification commands or manual checks that count as evidence. +- The actions that require explicit approval, such as destructive commands, production changes, external service writes, or broad architectural pivots. + +### Phase 1: Spec (Planning) + +1. Interview the user about the feature or app they want to build. Ask one focused question at a time until you fully understand the goal, the must-have requirements, the constraints, and what "done" looks like. +2. **Do not start building yet.** +3. When you have enough information, write a clear, detailed specification and save it to `specs/.md`. +4. The spec must include: + - The objective + - The exact requirements + - Edge cases to handle + - A concrete definition of done that someone could check the build against + - The iteration budget, verification commands, and approval gates. + +### Phase 2: Build (Implementation) + +1. Read the spec you just created in `specs/.md`. +2. Build exactly what it describes. +3. **Do not add features**, do not refactor unrelated code, and do not invent requirements that aren't in the spec. +4. Focus strictly on fulfilling the spec. List which spec requirements you covered so the review step can check them. + +### Phase 3: Review (Verification) + +1. Compare your implementation against `specs/.md`. +2. Go requirement by requirement and verify if it was met. List every gap, bug, or missing piece, naming the exact spec item each one fails. +3. If anything fails and the iteration budget is not exhausted, write the specific fixes needed and **loop back to Phase 2 (Build)** to address them. +4. Stop and ask for human input when the next fix would change the spec, exceed the iteration budget, require risky operations, or depend on product decisions not captured in the spec. +5. Only pass the build and conclude the skill execution when every requirement in the spec is fully met and the declared verification evidence has passed. + +## Examples + +### Example 1: Creating a Basic Statistics Helper + +**User:** +> I want to add a utility for calculating basic statistics (mean, median, mode) of an array of numbers. + +**Agent (Phase 1 - Spec):** +> I can help with that. To get started, what programming language should this statistics calculator be implemented in? Also, how should empty arrays or invalid inputs be handled? + +**User:** +> JavaScript. If the array is empty, return null. If there are non-numbers, ignore them. + +**Agent (Phase 1 - Spec):** +> Thank you. I have created the specification file at `specs/stats-calculator.md` with the requirements we discussed. Now, I will start implementing it. + +**Agent (Phase 2 - Build):** +> *(Creates `stats_calculator.js` and implements `mean`, `median`, and `mode` matching the spec exactly)* +> I have finished implementing the calculator. I will now verify the implementation. + +**Agent (Phase 3 - Review):** +> Checking implementation against `specs/stats-calculator.md`: +> - Requirement: mean calculation -> PASS +> - Requirement: median calculation -> PASS +> - Requirement: mode calculation -> PASS +> - Requirement: empty array returns null -> PASS +> - Requirement: non-numbers are ignored -> FAIL (I noticed `mode` doesn't filter out non-numbers). +> +> I will now loop back to Phase 2 to fix the `mode` function. + +**Agent (Phase 2 - Build Loop-Back):** +> *(Fixes `mode` to filter out non-numbers)* +> I have updated the implementation. Let's re-verify. + +**Agent (Phase 3 - Review):** +> - Requirement: mode filters non-numbers -> PASS +> +> All requirements passed! The statistics calculator is complete and verified. + +## Best Practices + +- ✅ Do ask clarifying questions one at a time to avoid overwhelming the user during the planning phase. +- ✅ Do document edge cases explicitly in `specs/.md` before writing any code. +- ✅ Do stick strictly to the approved specification during the build phase. +- ✅ Do cap the loop with a small iteration budget and report exactly what remains if the budget is exhausted. +- ✅ Do pause for explicit approval before destructive, production, credentialed, or externally visible actions. +- ❌ Don't implement extra features or perform unrelated refactorings that aren't specified. +- ❌ Don't skip the review phase or pass it without verifying every single requirement. +- ❌ Don't keep retrying the same failing fix without new evidence or a changed approach. + +## Limitations + +- This skill requires sufficient context about the feature to be provided during the Spec phase. +- It is best suited for isolated features or tasks with clear boundaries, rather than open-ended architectural refactoring. +- The review phase relies on the agent's self-assessment against the generated spec; manual review is still recommended for critical systems. +- It is not a replacement for human approval on security-sensitive, destructive, production, compliance, or externally visible changes. +- It should stop rather than continue if requirements conflict, tests cannot run, or verification depends on unavailable credentials or systems. + +## Security & Safety Notes + +- Be cautious when running or testing code generated during the Build phase. Always run tests in a safe, sandboxed environment. +- Avoid executing arbitrary shell commands provided directly by the user without validating their safety. +- Make sure no hardcoded secrets, keys, or credentials are added to the code or specifications. +- Treat production deploys, data migrations, payment flows, credential changes, and external write actions as approval-gated work. + +## Common Pitfalls + +- **Problem:** The agent tries to build a huge system all at once, leading to an overcomplicated spec and incomplete implementation. + **Solution:** Keep the scope of `ai-loop` to small, modular features. Break larger systems into multiple independent loops. +- **Problem:** The spec is vague, causing the build phase to rely on assumptions. + **Solution:** Spend extra time in the planning phase asking targeted questions to pin down requirements. + +## Related Skills + +- `@plan-writing` - For writing more detailed implementation plans for larger projects. +- `@ask-questions-if-underspecified` - For standard guidelines on interviewing the user. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/cron-doctor/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/cron-doctor/SKILL.md new file mode 100644 index 00000000..48eec6f8 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/cron-doctor/SKILL.md @@ -0,0 +1,244 @@ +--- +name: cron-doctor +description: "Diagnose and validate cron expressions before they ship. Catches the five silent death-traps: impossible dates that never fire, OR-semantics that fire too often, midnight spikes, uneven step drift, and leap-year February 29." +category: devops +risk: safe +source: community +source_repo: takeaseatventure/devops-skills +source_type: community +date_added: "2026-06-26" +author: takeaseat +tags: [cron, crontab, scheduling, devops, debugging, kubernetes, validation] +tools: [claude, cursor, codex, gemini, opencode] +license: "MIT" +license_source: "https://github.com/takeaseatventure/devops-skills/blob/main/LICENSE" +--- + +# cron-doctor + +## Overview + +Cron is deceptively error-prone. The failure mode is **silent** — a syntactically +valid expression that simply never fires, or fires far more often than intended. +`0 0 30 2 *` parses cleanly and then sits dead forever (February has no 30th). +`0 0 1,15 * 1` looks like "1st and 15th if Monday" but actually means "1st, 15th, +**OR** every Monday" — ~6 fires/month instead of ~2. + +This skill teaches an agent to catch those before they reach production. It comes +with a zero-dependency validation engine (`scripts/cron-engine.js`, no install +needed) that parses, describes, deep-validates, and computes next fire times. + +## When to Use This Skill + +- Use when a user writes, edits, reviews, or deploys a cron expression — in a + crontab, a Kubernetes `CronJob`, a GitHub Actions `schedule`, an Airflow DAG, + a Celery beat schedule, a systemd timer, or any scheduled task. +- Use when debugging a job that "didn't fire" or "fired at the wrong time." +- Use when a user asks "what does this cron expression mean?" or "when will this + run next?" or "how often does this run per year?" +- Use when reviewing a CI/CD pipeline or infrastructure config that contains a + `schedule` field. +- Use when a user pastes a 5-field cron expression and asks for a sanity check. + +## How It Works + +### Step 1: Parse the expression + +Split on whitespace into 5 fields: minute, hour, day-of-month, month, day-of-week. +Confirm valid ranges: + +| Field | Position | Range | Notes | +|-------|----------|-------|-------| +| minute | 1 | 0–59 | | +| hour | 2 | 0–23 | | +| day-of-month | 3 | 1–31 | | +| month | 4 | 1–12 | names (JAN–DEC) accepted | +| day-of-week | 5 | 0–7 | 0 and 7 both = Sunday; names (SUN–SAT) accepted | + +### Step 2: Describe it in plain English + +State what the user *thinks* it does vs. what it *actually* does. Be explicit +about OR-vs-AND semantics for day-of-month + day-of-week (see death-trap #2). + +### Step 3: Run the trap checklist + +Check the five death-traps below and flag any that apply. + +### Step 4: Calculate next runs and annual fire count + +Compute the next 5 fire times as concrete dates so the user can verify the +schedule behaves as expected. Estimate annual fire count — a schedule that fires +365×/year vs. 12×/year is a ~30× cost and load difference. + +## The Five Cron Death-Traps + +These are the bugs that pass `crontab -l` validation but break in production. + +### 1. Impossible dates — the "never fires" bug + +``` +0 0 30 2 * +``` + +**Valid syntax. Never fires.** February has no 30th. This schedule is a dead job +that silently sits forever. The same applies to day 31 in any 30-day month: +`0 0 31 4 *`, `0 0 31 6 *`, `0 0 31 9 *`, `0 0 31 11 *`. + +**Fix:** use `0 0 28-31 * *` and check for end-of-month in the script, or use `L` +(last day) syntax if your scheduler supports it. + +### 2. OR-semantics — the "fires too often" bug + +``` +0 0 1,15 * 1 +``` + +**Does NOT mean** "midnight on the 1st and 15th if it's Monday." +**Does mean** "midnight on the 1st, the 15th, **OR** every Monday." That's ~6 +fires/month instead of ~2. + +This is the single most misunderstood cron rule. When **both** day-of-month AND +day-of-week are restricted (neither is `*`), cron uses OR logic, not AND. + +**Fix:** if you need "1st and 15th only if Monday," run daily and check in the +script: + +```bash +0 0 * * 1 [ "$(date +%d)" = "01" -o "$(date +%d)" = "15" ] && your-command +``` + +### 3. Midnight spike — the "everything at once" bug + +``` +0 0 * * * +``` + +Every job scheduled at `0 0` competes for resources at exactly 00:00. Database +backups, log rotations, cert renewals, report generation — all fire simultaneously. +This causes load spikes, connection-pool exhaustion, and cascading timeouts. + +**Fix:** stagger jobs across the hour. Use `17 2 * * *` or `43 3 * * *` instead of +`0 0`. Jitter is your friend. + +### 4. Uneven steps — the "drift" bug + +``` +*/7 * * * * +``` + +**Does NOT mean** "every 7 minutes evenly." It means "every 7 minutes starting at +0, then resets at 60." So: 0, 7, 14, 21, 28, 35, 42, 49, 56 — then 0 again +(a 4-minute gap). The intervals drift: 7,7,7,7,7,7,7,7,**4**. + +**Fix:** 60 is not divisible by 7. Use step values that divide 60 evenly: `*/5`, +`*/10`, `*/15`, `*/20`, `*/30`. If you truly need every-7-minutes, use a loop with +`sleep 420`. + +### 5. Leap-year February 29 — the "annual surprise" + +``` +0 0 29 2 * +``` + +Fires only on leap years — February 29, 2024 / 2028 / 2032… If someone writes this +expecting "end of February," they'll be confused for 3 out of every 4 years. + +**Fix:** use `0 0 28 2 *` and handle the 29th case in the script if needed. + +## Using the validation script + +This skill ships a zero-dependency engine at `scripts/cron-engine.js` (Node.js, no +`npm install` needed). You can use it programmatically or from the CLI: + +```javascript +// Programmatic — Node.js, zero dependencies +const { describe, validate, nextRuns, formatNextRuns } = require('./scripts/cron-engine.js'); + +// Parse + describe -> returns { text, error, parsed } +const d = describe('0 0 30 2 *'); +console.log(d.text); // "At 00:00, on day-of-month 30 in in FEB" + +// Deep validation -> catches the traps +const result = validate('0 0 30 2 *'); +console.log(result.valid); // true (syntax is valid) +console.log(result.observations); // includes the "never fires" insight +console.log(result.suggestions); // e.g. "Midnight is a common spike..." + +// Next 5 fire times -> returns Date[] +const runs = nextRuns('0 9 * * 1-5', new Date(), 5); +console.log(formatNextRuns(runs, new Date())); // [{ date, relative, formatted }, ...] +``` + +```bash +# CLI (via the bundled wrapper) +node scripts/cli.js describe "*/5 * * * *" +node scripts/cli.js validate "0 0 30 2 *" +node scripts/cli.js next "0 9 * * 1-5" 5 +``` + +## Common cron presets + +| Expression | Description | Use case | +|-----------|-------------|----------| +| `*/5 * * * *` | Every 5 minutes | Health checks, polling | +| `0 * * * *` | Every hour | Hourly aggregation | +| `0 */2 * * *` | Every 2 hours | Semi-frequent sync | +| `0 9 * * 1-5` | 9am Mon–Fri | Business-hours task | +| `0 2 * * *` | 2am daily | Off-peak batch (avoid midnight) | +| `0 0 * * 0` | Midnight Sunday | Weekly maintenance | +| `0 0 1 * *` | Midnight 1st of month | Monthly report | +| `0 0 1 1 *` | Midnight Jan 1st | Annual task | + +## Best Practices + +- ✅ Always provide the plain-English description AND run the trap checklist. +- ✅ Stagger midnight jobs to avoid the spike. +- ✅ Prefer step values that divide 60 evenly (`*/5`, `*/15`, `*/30`). +- ✅ Add a comment above every crontab line explaining intent. +- ✅ Set an explicit timezone (`CRON_TZ`) on schedulers that support it. +- ❌ Don't trust `crontab -l` validation — it only checks syntax, not semantics. +- ❌ Don't restrict both day-of-month and day-of-week without confirming OR-logic. +- ❌ Don't schedule everything at `0 0`. + +## Common Pitfalls + +- **Problem:** "My cron job isn't running." + **Solution:** Check for an impossible date (trap #1) and confirm the daemon is + running (`service cron status` / `systemctl status crond`). Verify the file + ends with a newline and has correct ownership. + +- **Problem:** "My job runs far more often than expected." + **Solution:** You hit OR-semantics (trap #2). If both day-of-month and + day-of-week are set, cron ORs them. Move one to `*` or guard in-script. + +- **Problem:** "Intervals are uneven — sometimes 7 min, sometimes 4." + **Solution:** Step value doesn't divide 60 evenly (trap #4). Use a divisor of 60. + +- **Problem:** "My job works locally but not in the cluster." + **Solution:** Timezone mismatch. Kubernetes `CronJob` and GitHub Actions default + to UTC. Confirm `timeZone` / `TZ` is set as intended. + +## Limitations + +- This skill targets standard 5-field cron as implemented by Vixie cron, systemd + timers, Kubernetes `CronJob`, GitHub Actions `schedule`, and most libraries. It + does **not** validate Quartz 6/7-field expressions with seconds/years, nor + non-standard `@reboot` / `L` / `#` extensions without a note. +- Estimated annual fire counts assume a non-leap reference year; February 29 + schedules (trap #5) are flagged explicitly. +- This skill does not replace environment-specific validation, testing, or expert + review. Stop and ask for clarification if required inputs, permissions, or + safety boundaries are missing. + +## Related Skills + +- `docker-expert` — when the cron job runs inside a container and the issue is the + container/entrypoint rather than the schedule. +- `kubernetes-deployment` — when validating a `CronJob` manifest's `spec.schedule` + field alongside the broader resource config. + +## Security & Safety Notes + +This skill is read-only and `risk: safe`. The validation script performs no file +writes, network calls, or mutations — it only parses and computes. It is safe to +run against any cron expression without preconditions. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/cron-doctor/scripts/cli.js b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/cron-doctor/scripts/cli.js new file mode 100644 index 00000000..b0ac6905 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/cron-doctor/scripts/cli.js @@ -0,0 +1,75 @@ +#!/usr/bin/env node +'use strict'; + +// Minimal CLI wrapper for cron-engine.js. Zero dependencies. +// Usage: +// node cli.js describe "" +// node cli.js validate "" +// node cli.js next "" [count] + +const cron = require('./cron-engine.js'); +const expr = process.argv[3]; +const cmd = process.argv[2]; + +if (!cmd || !expr) { + console.error('Usage: node cli.js "" [count]'); + console.error('Examples:'); + console.error(' node cli.js describe "*/5 * * * *"'); + console.error(' node cli.js validate "0 0 30 2 *"'); + console.error(' node cli.js next "0 9 * * 1-5" 5'); + process.exit(2); +} + +function safe(fn) { + try { + fn(); + } catch (e) { + console.error('Error: ' + (e.message || e)); + process.exit(1); + } +} + +switch (cmd) { + case 'describe': + safe(() => { + const d = cron.describe(expr); + console.log(d.text || d.description || JSON.stringify(d)); + }); + break; + + case 'validate': + safe(() => { + const r = cron.validate(expr); + console.log('valid: ' + r.valid); + if (r.description) console.log('description: ' + r.description); + if (r.warnings && r.warnings.length) { + console.log('warnings:'); + r.warnings.forEach((w) => console.log(' - ' + w)); + } + if (r.observations && r.observations.length) { + console.log('observations:'); + r.observations.forEach((o) => console.log(' [' + (o.level || 'info') + '] ' + o.message)); + } + if (r.suggestions && r.suggestions.length) { + console.log('suggestions:'); + r.suggestions.forEach((s) => console.log(' [' + (s.level || 'info') + '] ' + s.message)); + } + }); + break; + + case 'next': + safe(() => { + const count = parseInt(process.argv[4] || '5', 10); + const runs = cron.nextRuns(expr, new Date(), count); + const formatted = cron.formatNextRuns(runs, new Date()); + formatted.forEach((f) => + console.log(f.relative + '\t' + f.formatted + '\t' + f.date.toString()) + ); + }); + break; + + default: + console.error('Unknown command: ' + cmd); + console.error('Commands: describe, validate, next'); + process.exit(2); +} diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/cron-doctor/scripts/cron-engine.js b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/cron-doctor/scripts/cron-engine.js new file mode 100644 index 00000000..07254dee --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/cron-doctor/scripts/cron-engine.js @@ -0,0 +1,638 @@ +'use strict'; + +// ============================================================================ +// cron.js — Cron expression parser, describer, validator, and next-run engine. +// Zero dependencies. Extracted from the DevRef Cron Expression Generator +// (battle-tested in browser) and extended with validate() for Pro insights. +// ============================================================================ + +const MONTH_NAMES = ['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC']; +const DAY_NAMES = ['SUN','MON','TUE','WED','THU','FRI','SAT']; + +const FIELDS = [ + { name: 'minute', min: 0, max: 59, key: 'minute' }, + { name: 'hour', min: 0, max: 23, key: 'hour' }, + { name: 'dom', min: 1, max: 31, key: 'dom' }, + { name: 'month', min: 1, max: 12, key: 'month', named: MONTH_NAMES }, + { name: 'dow', min: 0, max: 7, key: 'dow', named: DAY_NAMES }, +]; + +class CronError extends Error { + constructor(message, fieldIndex) { + super(message); + this.name = 'CronError'; + this.fieldIndex = fieldIndex; + } +} + +// ---- Name resolution ---- +function resolveName(token, names) { + if (!names) return null; + const up = token.toUpperCase(); + const idx = names.indexOf(up); + return idx === -1 ? null : idx; +} + +// ---- Field parsing ---- +function parseField(raw, fieldDef, fieldIndex) { + const trimmed = String(raw).trim(); + if (trimmed === '') throw new CronError(`Field ${fieldIndex + 1} (${fieldDef.name}) is empty`, fieldIndex); + + const out = { raw: trimmed, values: null, special: null }; + + // Special: day-of-week "#" (nth weekday) + if (fieldDef.key === 'dow' && trimmed.includes('#')) { + const m = trimmed.match(/^([0-7A-Za-z]+)#([1-5])$/); + if (!m) throw new CronError(`Invalid "#" syntax in day-of-week: "${trimmed}"`, fieldIndex); + let dowNum = parseSingleNum(m[1], fieldDef, fieldIndex); + if (dowNum === 7) dowNum = 0; + out.special = { kind: 'hash', dow: dowNum, nth: parseInt(m[2], 10) }; + return out; + } + + // Special: day-of-week "L" (last weekday) + if (fieldDef.key === 'dow' && /L$/i.test(trimmed)) { + const m = trimmed.match(/^([0-7A-Za-z]+)L$/i); + if (!m) throw new CronError(`Invalid "L" syntax in day-of-week: "${trimmed}"`, fieldIndex); + let dowNum = parseSingleNum(m[1], fieldDef, fieldIndex); + if (dowNum === 7) dowNum = 0; + out.special = { kind: 'dowLast', dow: dowNum }; + return out; + } + + // Special: day-of-month "L" (last day) + if (fieldDef.key === 'dom' && /^L/i.test(trimmed)) { + const m = trimmed.match(/^L(?:-(\d+))?$/i); + if (!m) throw new CronError(`Invalid "L" syntax in day-of-month: "${trimmed}"`, fieldIndex); + out.special = { kind: 'domLast', offset: m[1] ? parseInt(m[1], 10) : 0 }; + return out; + } + + // Special: day-of-month "W" (nearest weekday) + if (fieldDef.key === 'dom' && /W$/i.test(trimmed)) { + const m = trimmed.match(/^(\d+)W$/i); + if (!m) throw new CronError(`Invalid "W" syntax in day-of-month: "${trimmed}"`, fieldIndex); + const day = parseInt(m[1], 10); + if (day < fieldDef.min || day > fieldDef.max) { + throw new CronError(`Day-of-month "${day}W" out of range (${fieldDef.min}-${fieldDef.max})`, fieldIndex); + } + out.special = { kind: 'weekday', day: day }; + return out; + } + + // Standard parsing + const values = new Set(); + const items = trimmed.split(','); + for (const item of items) { + parseItem(item, fieldDef, fieldIndex, values); + } + out.values = values; + return out; +} + +function parseSingleNum(token, fieldDef, fieldIndex) { + const n = parseInt(token, 10); + if (!isNaN(n)) return n; + const named = resolveName(token, fieldDef.named); + if (named !== null) { + return fieldDef.key === 'month' ? named + 1 : named; + } + throw new CronError(`Invalid value "${token}" in ${fieldDef.name}`, fieldIndex); +} + +function parseItem(item, fieldDef, fieldIndex, values) { + const t = item.trim(); + if (t === '') throw new CronError(`Empty item in ${fieldDef.name}`, fieldIndex); + + if (t === '*') { + addRange(values, fieldDef.min, fieldDef.max, fieldDef); + return; + } + + if (t.includes('/')) { + const [base, stepStr] = t.split('/'); + const step = parseInt(stepStr, 10); + if (isNaN(step) || step < 1) throw new CronError(`Invalid step "${stepStr}" in ${fieldDef.name}`, fieldIndex); + let lo, hi; + if (base === '*' || base === '') { + lo = fieldDef.min; hi = fieldDef.max; + } else if (base.includes('-')) { + const [a, b] = base.split('-'); + lo = parseSingleNum(a.trim(), fieldDef, fieldIndex); + hi = parseSingleNum(b.trim(), fieldDef, fieldIndex); + } else { + lo = parseSingleNum(base.trim(), fieldDef, fieldIndex); + hi = fieldDef.max; + } + if (lo > hi) [lo, hi] = [hi, lo]; + for (let v = lo; v <= hi; v += step) addOne(values, v, fieldDef, fieldIndex); + return; + } + + if (t.includes('-')) { + const parts = t.split('-'); + if (parts.length !== 2) throw new CronError(`Invalid range "${t}" in ${fieldDef.name}`, fieldIndex); + const a = parseSingleNum(parts[0].trim(), fieldDef, fieldIndex); + const b = parseSingleNum(parts[1].trim(), fieldDef, fieldIndex); + addRange(values, a, b, fieldDef); + return; + } + + const v = parseSingleNum(t, fieldDef, fieldIndex); + addOne(values, v, fieldDef, fieldIndex); +} + +function addOne(values, v, fieldDef, fieldIndex) { + if (fieldDef.key === 'dow' && v === 7) { values.add(0); return; } + if (v < fieldDef.min || v > fieldDef.max) { + throw new CronError(`Value ${v} out of range for ${fieldDef.name} (${fieldDef.min}-${fieldDef.max})`, fieldIndex); + } + values.add(v); +} + +function addRange(values, lo, hi, fieldDef) { + if (lo > hi) [lo, hi] = [hi, lo]; + if (lo < fieldDef.min || hi > fieldDef.max) { + throw new CronError(`Range ${lo}-${hi} out of bounds for ${fieldDef.name} (${fieldDef.min}-${fieldDef.max})`, -1); + } + for (let v = lo; v <= hi; v++) { + if (fieldDef.key === 'dow' && v === 7) { values.add(0); continue; } + values.add(v); + } +} + +// ---- Full expression parser ---- +function parseCron(expr) { + const parts = String(expr).trim().split(/\s+/); + if (parts.length !== 5) { + throw new CronError(`Expected 5 fields (got ${parts.length}). Format: minute hour day-of-month month day-of-week`, -1); + } + const parsed = {}; + for (let i = 0; i < 5; i++) { + parsed[FIELDS[i].key] = parseField(parts[i], FIELDS[i], i); + } + parsed.domRestricted = !/^\s*\*\s*$/.test(parts[2]); + parsed.dowRestricted = !/^\s*\*\s*$/.test(parts[4]); + parsed.parts = parts; + return parsed; +} + +// ---- Human-readable description ---- +function describe(expr) { + let parsed; + try { parsed = parseCron(expr); } catch (e) { return { text: e.message, error: true }; } + return { text: describeParsed(parsed), error: false, parsed }; +} + +function describeParsed(p) { + const monthDesc = describeFieldMonth(p.month); + const domDesc = describeFieldDom(p.dom); + const dowDesc = describeFieldDow(p.dow); + + const isEveryMin = p.parts[0] === '*'; + const isEveryHour = p.parts[1] === '*'; + + let timePart = ''; + if (isEveryMin && isEveryHour) { + timePart = 'At every minute'; + } else if (isEveryMin && !isEveryHour) { + const hours = [...(p.hour.values || [])].sort((a, b) => a - b); + if (hours.length > 0) { + timePart = 'Every minute during the ' + hours.map(h => pad2(h)).join(', ') + ' hour' + (hours.length > 1 ? 's' : ''); + } else { + timePart = 'Every minute'; + } + } else { + timePart = 'At ' + describeTimes(p.minute, p.hour); + } + + let dayPart = ''; + const domAny = !p.domRestricted; + const dowAny = !p.dowRestricted; + + if (domAny && dowAny) { + if (monthDesc.restricted) { + dayPart = ', ' + monthDesc.text + ' of every year'; + } else { + dayPart = ', every day'; + } + } else if (!domAny && dowAny) { + dayPart = ', on ' + domDesc.text; + if (monthDesc.restricted) dayPart += ' in ' + monthDesc.text; + } else if (domAny && !dowAny) { + dayPart = ', on ' + dowDesc.text; + if (monthDesc.restricted) dayPart += ' in ' + monthDesc.text; + } else { + dayPart = ', on ' + domDesc.text + ' and on ' + dowDesc.text; + if (monthDesc.restricted) dayPart += ' in ' + monthDesc.text; + } + + return capitalize(timePart + dayPart); +} + +function describeTimes(minuteField, hourField) { + const mins = [...(minuteField.values || [])].sort((a, b) => a - b); + const hours = [...(hourField.values || [])].sort((a, b) => a - b); + + if (pIsWildcard(hourField) && !pIsWildcard(minuteField)) { + if (mins.length === 1) return `minute ${mins[0]} of every hour`; + return `minutes ${listJoin(mins)} of every hour`; + } + if (pIsWildcard(minuteField) && pIsWildcard(hourField)) return 'every minute of every hour'; + + if (pIsWildcard(minuteField)) { + return `every minute during the ${hours.map(h => pad2(h)).join(', ')} hour${hours.length > 1 ? 's' : ''}`; + } + + const combos = []; + for (const h of hours) { + for (const m of mins) { + combos.push(formatHM(h, m)); + } + } + return listJoin(combos); +} + +function describeFieldMonth(field) { + if (pIsWildcard(field)) return { restricted: false, text: 'every month' }; + const vals = [...(field.values || [])].sort((a, b) => a - b); + return { restricted: true, text: 'in ' + listJoin(vals.map(v => capitalize(MONTH_NAMES[v - 1]))) }; +} + +function describeFieldDom(field) { + if (pIsWildcard(field)) return { text: 'every day-of-month' }; + if (field.special) { + if (field.special.kind === 'domLast') { + return { text: field.special.offset === 0 ? 'the last day of the month' : `the last day of the month minus ${field.special.offset} days` }; + } + if (field.special.kind === 'weekday') { + return { text: `the nearest weekday to day ${field.special.day}` }; + } + } + const vals = [...(field.values || [])].sort((a, b) => a - b); + return { text: `day-of-month ${listJoin(vals)}` }; +} + +function describeFieldDow(field) { + if (pIsWildcard(field)) return { text: 'every day-of-week' }; + if (field.special) { + if (field.special.kind === 'hash') { + return { text: `the ${ordinal(field.special.nth)} ${capitalize(DAY_NAMES[field.special.dow])} of the month` }; + } + if (field.special.kind === 'dowLast') { + return { text: `the last ${capitalize(DAY_NAMES[field.special.dow])} of the month` }; + } + } + const vals = [...(field.values || [])].sort((a, b) => a - b); + return { text: listJoin(vals.map(v => capitalize(DAY_NAMES[v]))) }; +} + +function pIsWildcard(field) { return field.raw === '*'; } + +// ---- Next run calculator ---- +function nextRuns(expr, fromDate, count) { + count = count || 10; + const p = parseCron(expr); + const runs = []; + let d = new Date(fromDate.getTime()); + d.setSeconds(0, 0); + d = new Date(d.getTime() + 60000); + + let maxScan = 600000; // ~416 days ceiling + while (runs.length < count && maxScan-- > 0) { + if (matches(d, p)) { + runs.push(new Date(d.getTime())); + } + d = new Date(d.getTime() + 60000); + } + return runs; +} + +function matches(d, p) { + if (!p.minute.values || !p.minute.values.has(d.getMinutes())) return false; + if (!p.hour.values || !p.hour.values.has(d.getHours())) return false; + if (!p.month.values || !p.month.values.has(d.getMonth() + 1)) return false; + + const domAny = !p.domRestricted; + const dowAny = !p.dowRestricted; + + let domMatch = false, dowMatch = false; + if (domAny) { + domMatch = true; + } else if (p.dom.special) { + domMatch = matchDomSpecial(d, p.dom.special); + } else if (p.dom.values && p.dom.values.has(d.getDate())) { + domMatch = true; + } + if (dowAny) { + dowMatch = true; + } else if (p.dow.special) { + dowMatch = matchDowSpecial(d, p.dow.special); + } else if (p.dow.values) { + dowMatch = p.dow.values.has(d.getDay()); + } + + if (domAny && dowAny) return true; + if (!domAny && !dowAny) return domMatch || dowMatch; // OR semantics + return domMatch && dowMatch; +} + +function matchDomSpecial(d, special) { + if (special.kind === 'domLast') { + const lastDay = lastDayOfMonth(d.getFullYear(), d.getMonth()); + const target = special.offset === 0 ? lastDay : lastDay - special.offset; + return d.getDate() === target; + } + if (special.kind === 'weekday') { + return d.getDate() === nearestWeekday(d.getFullYear(), d.getMonth(), special.day); + } + return false; +} + +function matchDowSpecial(d, special) { + if (special.kind === 'hash') { + return nthWeekdayMatches(d, special.dow, special.nth); + } + if (special.kind === 'dowLast') { + return lastWeekdayMatches(d, special.dow); + } + return false; +} + +function nthWeekdayMatches(d, dow, nth) { + if (d.getDay() !== dow) return false; + const dayOfMonth = d.getDate(); + const occurrence = Math.ceil(dayOfMonth / 7); + return occurrence === nth; +} + +function lastWeekdayMatches(d, dow) { + if (d.getDay() !== dow) return false; + const lastDay = lastDayOfMonth(d.getFullYear(), d.getMonth()); + return d.getDate() + 7 > lastDay; +} + +function lastDayOfMonth(year, month) { + return new Date(year, month + 1, 0).getDate(); +} + +function nearestWeekday(year, month, day) { + const lastDay = lastDayOfMonth(year, month); + const target = Math.min(day, lastDay); + const dt = new Date(year, month, target); + const wd = dt.getDay(); + let result = target; + if (wd === 0) { + if (target + 1 <= lastDay) result = target + 1; + else result = target - 2; + } else if (wd === 6) { + if (target - 1 >= 1) result = target - 1; + else result = target + 2; + } + return result; +} + +// ============================================================================ +// validate() — Pro-tier feature: deeper analysis of a cron expression. +// Returns warnings, observations, and optimization suggestions. +// ============================================================================ + +function validate(expr) { + let parsed; + try { + parsed = parseCron(expr); + } catch (e) { + return { + valid: false, + error: e.message, + fieldIndex: e.fieldIndex, + warnings: [], + observations: [], + suggestions: [], + }; + } + + const warnings = []; + const observations = []; + const suggestions = []; + + const desc = describeParsed(parsed); + + // Check: day-of-month and day-of-week both restricted (OR semantics surprise) + if (parsed.domRestricted && parsed.dowRestricted) { + warnings.push({ + level: 'high', + message: 'Both day-of-month and day-of-week are restricted. Cron uses OR semantics for these fields — the job will run when EITHER matches, not both. This is a common source of bugs.', + }); + } + + // Check: impossible day-of-month values (e.g., 31 in Feb) + const domValues = [...(parsed.dom.values || [])]; + if (!parsed.domRestricted && parsed.month.values && ![...parsed.month.values].every(m => m === 2)) { + // skip + } else if (parsed.domRestricted && !parsed.dom.special && domValues.includes(31)) { + const monthsWith31 = [1, 3, 5, 7, 8, 10, 12]; // Jan, Mar, May, Jul, Aug, Oct, Dec + const monthValues = parsed.month.values ? [...parsed.month.values] : []; + const restrictedMonths = parsed.parts[3] !== '*'; + if (restrictedMonths) { + const problemMonths = monthValues.filter(m => !monthsWith31.includes(m)); + if (problemMonths.length > 0) { + warnings.push({ + level: 'medium', + message: `Day 31 is specified but months ${problemMonths.map(m => capitalize(MONTH_NAMES[m - 1])).join(', ')} have fewer than 31 days. The job will never run in those months.`, + }); + } + } else { + observations.push({ + level: 'info', + message: 'Day 31 will only match in months with 31 days (7 of 12 months). The job effectively skips Feb, Apr, Jun, Sep, and Nov.', + }); + } + } + + // Check: high-frequency schedules + if (parsed.parts[0] === '*' && parsed.parts[1] === '*') { + observations.push({ + level: 'info', + message: 'This expression runs every minute. For production jobs, consider if this frequency is intentional.', + }); + } + + // Check: step values that don't divide evenly + for (let i = 0; i < 2; i++) { + const part = parsed.parts[i]; + if (part.startsWith('*/')) { + const step = parseInt(part.slice(2), 10); + const range = i === 0 ? 60 : 24; + if (range % step !== 0) { + observations.push({ + level: 'info', + message: `Step value */${step} in ${FIELDS[i].name} doesn't divide evenly into ${range}. The last interval will be shorter than the rest (e.g., */7 in minutes goes 0,7,14,...,56, then 0 again — not 63).`, + }); + } + } + } + + // Check: February 29th edge case + if (parsed.domRestricted && !parsed.dom.special) { + const domVals = [...(parsed.dom.values || [])]; + const monthVals = parsed.month.values ? [...parsed.month.values] : []; + if (domVals.includes(29) && monthVals.length === 1 && monthVals[0] === 2) { + warnings.push({ + level: 'medium', + message: 'February 29th only occurs in leap years. This job will not run at all in non-leap years (3 out of every 4 years).', + }); + } + } + + // Check: midnight rush + if (parsed.parts[0] === '0' && parsed.parts[1] === '0') { + suggestions.push({ + level: 'info', + message: 'Midnight (00:00) is a common schedule and many systems have concurrent job spikes at this time. Consider offsetting to a few minutes past midnight (e.g., 02 0 * * *) to avoid resource contention.', + }); + } + + // Check: weekend vs weekday + if (parsed.parts[4] === '1-5') { + observations.push({ + level: 'info', + message: 'Weekdays only (Mon-Fri). This job will not run on weekends.', + }); + } + + // Compute frequency estimate + const freq = estimateFrequency(parsed); + if (freq) { + observations.push({ + level: 'info', + message: `Approximate frequency: ${freq.description} (~${freq.runsPerYear} runs per year).`, + }); + } + + return { + valid: true, + description: desc, + warnings, + observations, + suggestions, + parsed, + }; +} + +function estimateFrequency(parsed) { + try { + // Count runs over a sample year + const start = new Date(2025, 0, 1, 0, 0, 0, 0); + const end = new Date(2026, 0, 1, 0, 0, 0, 0); + let count = 0; + let d = new Date(start.getTime()); + let maxScan = 540000; // ~375 days + while (d < end && maxScan-- > 0) { + if (matches(d, parsed)) count++; + d = new Date(d.getTime() + 60000); + } + + let description = ''; + if (count >= 525600) description = 'every minute'; + else if (count >= 500000) description = 'multiple times per minute'; + else if (count >= 8000) description = 'hourly or more'; + else if (count >= 300) description = 'daily or more'; + else if (count >= 40) description = 'weekly or more'; + else if (count >= 8) description = 'monthly or more'; + else if (count >= 1) description = 'yearly or less'; + else description = 'never (impossible schedule)'; + + return { description, runsPerYear: count }; + } catch (e) { + return null; + } +} + +// ---- Presets ---- +const PRESETS = [ + { label: 'Every minute', cron: '* * * * *' }, + { label: 'Every 5 min', cron: '*/5 * * * *' }, + { label: 'Every 10 min', cron: '*/10 * * * *' }, + { label: 'Every 15 min', cron: '*/15 * * * *' }, + { label: 'Every 30 min', cron: '*/30 * * * *' }, + { label: 'Hourly', cron: '0 * * * *' }, + { label: 'Every 2 hours', cron: '0 */2 * * *' }, + { label: 'Every 6 hours', cron: '0 */6 * * *' }, + { label: 'Every 12 hours', cron: '0 */12 * * *' }, + { label: 'Daily at midnight', cron: '0 0 * * *' }, + { label: 'Daily 9am', cron: '0 9 * * *' }, + { label: 'Twice daily', cron: '0 9,21 * * *' }, + { label: 'Weekdays 9am', cron: '0 9 * * 1-5' }, + { label: 'Weekends 10am', cron: '0 10 * * 0,6' }, + { label: 'Every Monday', cron: '0 0 * * 1' }, + { label: 'Every Friday', cron: '0 0 * * 5' }, + { label: 'Monthly 1st', cron: '0 0 1 * *' }, + { label: 'Quarterly', cron: '0 0 1 */3 *' }, + { label: 'Yearly Jan 1', cron: '0 0 1 1 *' }, +]; + +const COMMON = [ + { label: 'At 14:30', cron: '30 14 * * *' }, + { label: '9am weekdays', cron: '0 9 * * 1-5' }, + { label: 'Every Mon 8am', cron: '0 8 * * 1' }, + { label: 'Last day of month', cron: '0 0 L * *' }, + { label: '15th, weekday', cron: '0 0 15W * *' }, + { label: '3rd Thursday', cron: '0 0 * * 4#3' }, + { label: 'Last Friday', cron: '0 0 * * 5L' }, + { label: 'Business hours', cron: '0 9-17 * * 1-5' }, + { label: 'Backup nightly', cron: '0 2 * * *' }, +]; + +// ---- Helpers ---- +function pad2(n) { return String(n).padStart(2, '0'); } +function formatHM(h, m) { return `${pad2(h)}:${pad2(m)}`; } +function capitalize(s) { return s.charAt(0).toUpperCase() + s.slice(1); } +function ordinal(n) { + const s = ['th', 'st', 'nd', 'rd']; + const v = n % 100; + return n + (s[(v - 20) % 10] || s[v] || s[0]); +} +function listJoin(arr) { + if (arr.length === 0) return ''; + if (arr.length === 1) return String(arr[0]); + if (arr.length === 2) return `${arr[0]} and ${arr[1]}`; + return arr.slice(0, -1).join(', ') + ', and ' + arr[arr.length - 1]; +} + +function formatNextRuns(runs, fromDate) { + return runs.map(r => { + const diff = r.getTime() - fromDate.getTime(); + const mins = Math.round(diff / 60000); + let rel; + if (mins < 60) rel = `+${mins}m`; + else if (mins < 2880) rel = `+${Math.round(mins / 60)}h`; + else rel = `+${Math.round(mins / 1440)}d`; + return { date: r, relative: rel, formatted: r.toISOString() }; + }); +} + +module.exports = { + CronError, + FIELDS, + MONTH_NAMES, + DAY_NAMES, + PRESETS, + COMMON, + parseCron, + describe, + describeParsed, + nextRuns, + matches, + validate, + estimateFrequency, + formatNextRuns, + parseField, + parseItem, + parseSingleNum, + resolveName, + lastDayOfMonth, + nearestWeekday, + nthWeekdayMatches, + lastWeekdayMatches, +}; diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/sql-sentinel/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/sql-sentinel/SKILL.md new file mode 100644 index 00000000..cf35a1e7 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/sql-sentinel/SKILL.md @@ -0,0 +1,131 @@ +--- +name: sql-sentinel +description: "Audit SQL for the cost & performance anti-patterns that burn warehouse credits. Scores warehouse health 0-100 and outputs a prioritized cost-reduction plan for BigQuery, Snowflake, Redshift, and Postgres." +category: data +risk: safe +source: community +source_repo: takeaseatventure/sql-sentinel +source_type: community +date_added: "2026-06-26" +author: takeaseat +tags: [sql, bigquery, snowflake, redshift, postgres, data-warehouse, cost-optimization, performance, audit, finops] +tools: [claude, cursor, codex, gemini] +license: "MIT" +license_source: "https://github.com/takeaseatventure/sql-sentinel/blob/main/LICENSE" +--- + +# sql-sentinel + +## Overview + +A static-analysis skill that audits SQL for the cost & performance anti-patterns that dominate warehouse bills — `SELECT *`, full-table scans, non-sargable predicates, Cartesian joins, the `NOT IN` NULL trap, and 15 more. It scores warehouse query health 0-100 (A-F) and outputs a prioritized cost-reduction plan, each finding with a `why`, a concrete `fix`, and an estimated savings. + +Built for analytics engineers (dbt, Looker), data platform teams running FinOps / "reduce cloud spend" initiatives, and anyone reviewing a SQL pull request before it hits production. Works across BigQuery, Snowflake, Redshift, and Postgres. Zero dependencies, MIT licensed. + +The executable engine and full rule set live in the source repository: https://github.com/takeaseatventure/sql-sentinel + +## When to Use This Skill + +- A user writes or reviews a query for BigQuery, Snowflake, Redshift, Postgres, or Spark SQL. +- A user asks "why is this query so slow?" or "why is my warehouse bill so high?" +- A user is about to promote a dashboard query or dbt model to production. +- A data engineer wants a second pair of eyes before a code review or a cost-optimization sweep. +- A team is running a "reduce cloud spend" or FinOps initiative. + +## How It Works + +The engine splits a SQL script into statements (honoring quotes and comments), runs 20 rules over each statement, scores health 0-100 weighted by severity (critical 25, high 12, medium 5, low 1), and returns a prioritized cost-reduction plan. + +### Step 1: Run the audit + +Install or clone the source repository, then run the zero-dependency engine: + +```bash +git clone https://github.com/takeaseatventure/sql-sentinel.git +cd sql-sentinel +node scripts/sql-sentinel.js path/to/query.sql +``` + +Or programmatically: + +```javascript +const { auditSql } = require('./scripts/sql-sentinel'); +const report = auditSql(yourSqlString, { dialect: 'bigquery' }); +console.log(report.healthScore); // 0-100 +console.log(report.grade); // 'A' | 'B' | 'C' | 'D' | 'E' | 'F' +console.log(report.prioritizedPlan); // array, worst findings first +``` + +### Step 2: Read the prioritized plan + +The output leads with critical findings (Cartesian joins, mass DELETE) and descends to low-severity style issues. Each finding explains *why* it costs money and *how* to fix it. + +## Examples + +### Example 1: A messy dashboard query + +```sql +SELECT DISTINCT * +FROM user_events, raw_logs +WHERE LOWER(event_name) LIKE '%signup%' + AND user_id NOT IN (SELECT id FROM deleted_users) +ORDER BY created_at; +``` + +The audit scores this 17/100 (grade F) and flags 7 findings: +- CRITICAL: comma-join produces a Cartesian product (can turn a $0.02 query into a $200 query) +- HIGH: `SELECT *` forces full column scan (30-90% wasted bytes on wide tables) +- HIGH: leading-wildcard `LIKE '%signup%'` defeats indexes +- HIGH: `LOWER(event_name)` defeats indexes (non-sargable) +- HIGH: `NOT IN (SELECT ...)` — NULL semantics hazard +- MEDIUM: `SELECT DISTINCT` dedup cost +- MEDIUM: `ORDER BY` without `LIMIT` sorts the full result + +### Example 2: A clean, sargable query + +```sql +-- This scores 90+/100 (grade A) — no findings +SELECT id, email, created_at +FROM users +WHERE created_at >= TIMESTAMP '2026-01-01' + AND created_at < TIMESTAMP '2026-02-01' +ORDER BY id +LIMIT 100; +``` + +## The 20 rules (ruleset v1.0.0) + +| Rule | Severity | Catches | +|---|---|---| +| SQL001 | high | `SELECT *` full column scan | +| SQL002 | critical | No `WHERE` → full table scan | +| SQL003 | high | `LIKE '%term'` non-sargable | +| SQL004 | high | Function on column kills index | +| SQL005 | critical | `CROSS JOIN` / comma-join | +| SQL006 | medium | `SELECT DISTINCT` dedup cost | +| SQL007 | medium | `ORDER BY` without `LIMIT` | +| SQL008 | high | `NOT IN (SELECT ...)` NULL trap | +| SQL009 | medium | Implicit type cast | +| SQL010 | low | Many `OR`s (use `IN`/`UNION`) | +| SQL011 | medium | `COUNT(DISTINCT)` at scale (use HLL) | +| SQL012 | low | `LIMIT` without `ORDER BY` | +| SQL013 | medium | Scalar subquery in `SELECT` | +| SQL014 | medium | 5+ JOINs broadcast/spill risk | +| SQL015 | high | Fact table, no partition filter | +| SQL017 | low | String concat in `SELECT` | +| SQL018 | medium | Window `OVER ()` no `PARTITION` | +| SQL020 | critical | `DELETE`/`UPDATE` without `WHERE` | +| SQL021 | low | `SELECT *` in `EXISTS`/`IN` | +| SQL022 | medium | `UNION` vs `UNION ALL` | + +Run the test suite to verify each rule fires on real SQL: + +```bash +cd scripts && node test.js # 26 tests, zero dependencies +``` + +## Limitations + +- This is a **static** analyzer. It finds anti-patterns in the *text* of SQL; it does not read query plans, row counts, or billing. A flagged query on a 100-row table is cheap; the same query on a billion-row table is the problem the rule exists to prevent. +- The fact-table heuristic (SQL015) keys off table *names* (`*_events`, `*_log`) and is advisory, not definitive. +- It does not execute SQL — safe to run on any `.sql` file. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/web-project-brainstorming/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/web-project-brainstorming/SKILL.md new file mode 100644 index 00000000..8e2736be --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills-claude/skills/web-project-brainstorming/SKILL.md @@ -0,0 +1,149 @@ +--- +name: web-project-brainstorming +description: Masterclass framework for brainstorming web development projects and page designs. Outlines structural phases for concept, UX flow, styling aesthetics, technical architecture, and SEO. +category: consulting +risk: safe +source: self +source_type: self +date_added: "2026-06-26" +author: Rsmiyani +tags: [brainstorming, project-planning, web-development, product-scoping, design-system, architecture] +tools: [claude, cursor, gemini] +--- + +# Web Project Brainstorming + +## Overview + +This skill provides a structured, masterclass-level framework for brainstorming web projects, web applications, or individual page designs at their inception. It guides developers and designers through scoping the core product concept, mapping user flows, defining visual styling aesthetics, selecting the technical stack, and planning for search engine optimization (SEO) and performance. + +## When to Use This Skill + +- Use at the start of any new web development project or page redesign. +- Use when scoping feature sets, user roles, and interaction patterns for web applications. +- Use when establishing design systems, color tokens, and layout guidelines. +- Use when evaluating tech stacks (e.g., Next.js vs. Vanilla JS, CSS Grid vs. Tailwind). + +## How It Works + +Execute web project brainstorming sequentially across six structured phases. Ask the user questions one phase at a time to maintain focus and ensure thorough alignment. + +### Phase 1: Core Concept & Scoping +Define the product's primary value proposition and scope: +- **Target Audience**: Who is using the website or application? +- **Core Value**: What problem does it solve for users? +- **Key Features**: What are the top 3–5 mandatory features? + +### Phase 2: User Experience (UX) & Information Architecture +Map how users navigate and interact: +- **Page Hierarchy**: What is the sitemap and page structure? +- **User Journeys**: What step-by-step flows do users take to complete key goals? +- **Responsive Layout**: Is the interface mobile-first, desktop-first, or balanced? + +### Phase 3: Visual Styling & Design System +Establish the visual guidelines and aesthetic parameters: +- **Design Aesthetic**: Modern, minimalist, brutalist, glassmorphism, or luxury? +- **Color Palette**: What are the primary, secondary, and accent colors? (Prefer tailorable HSL/RGB models over static color keywords). +- **Typography**: Which Google Fonts or system fonts fit the theme? (e.g., Inter, Outfit, Syne). +- **Interactive States**: How do hovers, clicks, transitions, and loading states behave? + +### Phase 4: Technical Stack & Architecture +Select the technologies and integration systems: +- **Frontend Framework**: React, Next.js, Vite, Astro, Svelte, or Vanilla HTML/JS? +- **Styling Method**: Vanilla CSS, Tailwind CSS, or CSS Modules? +- **Data & Backend**: REST API, GraphQL, tRPC, Firebase, Supabase, or SQLite? +- **State Management**: Zustand, Context API, Redux, or local React state? + +### Phase 5: SEO, Accessibility (A11y), and Performance +Plan for discoverability and fast loading times: +- **SEO Elements**: Title tag structure, meta descriptions, and semantic HTML tag hierarchy. +- **Accessibility**: ARIA labels, semantic tags, keyboard navigation, and color contrast. +- **Performance**: Preloading assets, lazy loading images, server-side rendering (SSR), and CDN delivery. + +### Phase 6: MVP Scope & Project Phases +Break the work down into manageable increments: +- **Phase 1 (MVP)**: The absolute minimum viable product needed to deploy. +- **Phase 2 (Enhancements)**: Nice-to-have features, micro-animations, and advanced integrations. + +## Examples + +### Interactive Questionnaire Prompt Template +Use this prompt layout when initiating a brainstorming session with a client or team member: + +```markdown +👋 Let's brainstorm your new web project! We will walk through 6 quick phases. + +--- +### Phase 1: Core Concept & Scoping +1. What is the main title or working name of this project? +2. Who are the primary target users (e.g., tech-savvy professionals, shoppers, children)? +3. What are the 3 core tasks a user must be able to perform? +--- +``` + +### Brainstorming Output Document Template +Once all phases are complete, generate a markdown blueprint for the project using this template: + +```markdown +# Project Blueprint: [Project Name] + +## 1. Product Concept +- **Value Proposition**: [Summary] +- **Key Features**: + 1. [Feature 1] + 2. [Feature 2] + +## 2. Information Architecture & UX +- **Pages**: `/index.html`, `/dashboard.html` +- **Primary User Flow**: User signs up -> completes onboarding -> views dashboard. + +## 3. Styling & Aesthetics +- **Aesthetic**: Sleek Glassmorphism Dark Mode +- **Color Tokens**: + - Background: `hsl(222, 47%, 11%)` + - Accent/Primary: `hsl(217, 91%, 60%)` +- **Typography**: Inter (Body), Outfit (Headings) + +## 4. Technical Architecture +- **Framework**: Next.js (App Router) +- **Styling**: Tailwind CSS +- **Database**: PostgreSQL with Prisma ORM + +## 5. SEO & Performance +- **Primary Title**: "[Brand] | [Tagline]" +- **Performance Strategy**: Dynamic image optimization, caching pages via Cloudflare. + +## 6. MVP vs Phase 2 Roadmap +- **MVP**: Authentication + core dashboard view. +- **Phase 2**: Real-time notifications and PDF reporting. +``` + +## Best Practices + +- ✅ Ask questions incrementally—never dump all six phases in a single response to avoid cognitive overload. +- ✅ Propose logical defaults (e.g., recommending responsive Tailwind/CSS Grid and standard semantic HTML) if the user is unsure. +- ✅ Ensure semantic HTML layout hierarchy (one `

` per page, sequential `
`, `
`, `
`, `
` elements) is planned from the start. +- ✅ Document explicit non-goals to prevent feature creep. + +## Limitations + +- This skill focuses on conceptual mapping, architecture, and feature planning; it does not replace the writing of implementation code or system configuration. +- Brainstorming outcomes should be treated as flexible blueprints and refined as technical constraints are discovered during development. + +## Security & Safety Notes + +- During Phase 4 (Architecture), flag any security requirements (e.g., SSL certificates, CORS policies, secure authentication storage, environment variables protection) early. +- Do not store actual API tokens, passwords, or credentials in design or blueprint documents. + +## Common Pitfalls + +- **Problem**: Scope Creep (the project expands too quickly before building an MVP). + **Solution**: Enforce Phase 6 strictly. Push nice-to-have features into Phase 2. +- **Problem**: Ignoring mobile design until late in development. + **Solution**: Brainstorm responsive patterns in Phase 2 before deciding on layout style in Phase 3. + +## Related Skills + +- `@writing-plans` - Organizing structural step-by-step engineering plans. +- `@architecture-decision-records` - Documenting architectural decisions. +- `@ux-flow` - Designing deep user experience flows and interaction details. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/.codex-plugin/plugin.json index f9dee3db..43a96379 100644 --- a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-awesome-skills", - "version": "13.3.0", + "version": "13.4.0", "description": "Plugin-safe Codex plugin for the Antigravity Awesome Skills library.", "author": { "name": "sickn33 and contributors", @@ -19,7 +19,7 @@ "skills": "./skills/", "interface": { "displayName": "Antigravity Awesome Skills", - "shortDescription": "1,629 plugin-safe skills for coding, security, product, and ops workflows.", + "shortDescription": "1,633 plugin-safe skills for coding, security, product, and ops workflows.", "longDescription": "Install a plugin-safe Codex distribution of Antigravity Awesome Skills. Skills that still need hardening or target-specific setup remain available in the repo but are excluded from this plugin.", "developerName": "sickn33 and contributors", "category": "Productivity", diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/ai-loop/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/ai-loop/SKILL.md new file mode 100644 index 00000000..f849df8f --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/ai-loop/SKILL.md @@ -0,0 +1,136 @@ +--- +name: ai-loop +description: Runs a bounded spec-build-review development loop with explicit scope, stop conditions, and human approval gates for risky or ambiguous work. +category: workflow +risk: safe +source: community +date_added: "2026-06-27" +tags: [agent-workflow, specification, implementation, review, verification, feedback-loop] +tools: [claude, cursor, codex, gemini] +--- + +# AI-Loop Skill + +## Overview + +The `ai-loop` skill structures a bounded development cycle for agentic workflows. By dividing the process into distinct planning (Spec), implementation (Build), and validation (Review) phases, it helps an agent build and correct scoped code changes while keeping requirements, risk gates, and stop conditions explicit. + +## When to Use This Skill + +- Use when you need a feature built from scratch or heavily modified, and you want the agent to handle the lifecycle (specification, implementation, and verification) inside one clearly bounded workflow. +- Use when working with isolated components, modules, or features that have well-defined scopes and constraints. +- Use when the user asks for a complete development pass but the work still has clear success criteria, a reasonable verification path, and no unresolved safety or product decisions. + +## How It Works + +This skill executes a controlled development loop composed of three phases: Spec, Build, and Review. When invoked, the agent moves through those phases until the scoped requirements pass verification, a stop condition is reached, or human approval is needed. + +Before starting, define: + +- The maximum number of build-review iterations. +- The verification commands or manual checks that count as evidence. +- The actions that require explicit approval, such as destructive commands, production changes, external service writes, or broad architectural pivots. + +### Phase 1: Spec (Planning) + +1. Interview the user about the feature or app they want to build. Ask one focused question at a time until you fully understand the goal, the must-have requirements, the constraints, and what "done" looks like. +2. **Do not start building yet.** +3. When you have enough information, write a clear, detailed specification and save it to `specs/.md`. +4. The spec must include: + - The objective + - The exact requirements + - Edge cases to handle + - A concrete definition of done that someone could check the build against + - The iteration budget, verification commands, and approval gates. + +### Phase 2: Build (Implementation) + +1. Read the spec you just created in `specs/.md`. +2. Build exactly what it describes. +3. **Do not add features**, do not refactor unrelated code, and do not invent requirements that aren't in the spec. +4. Focus strictly on fulfilling the spec. List which spec requirements you covered so the review step can check them. + +### Phase 3: Review (Verification) + +1. Compare your implementation against `specs/.md`. +2. Go requirement by requirement and verify if it was met. List every gap, bug, or missing piece, naming the exact spec item each one fails. +3. If anything fails and the iteration budget is not exhausted, write the specific fixes needed and **loop back to Phase 2 (Build)** to address them. +4. Stop and ask for human input when the next fix would change the spec, exceed the iteration budget, require risky operations, or depend on product decisions not captured in the spec. +5. Only pass the build and conclude the skill execution when every requirement in the spec is fully met and the declared verification evidence has passed. + +## Examples + +### Example 1: Creating a Basic Statistics Helper + +**User:** +> I want to add a utility for calculating basic statistics (mean, median, mode) of an array of numbers. + +**Agent (Phase 1 - Spec):** +> I can help with that. To get started, what programming language should this statistics calculator be implemented in? Also, how should empty arrays or invalid inputs be handled? + +**User:** +> JavaScript. If the array is empty, return null. If there are non-numbers, ignore them. + +**Agent (Phase 1 - Spec):** +> Thank you. I have created the specification file at `specs/stats-calculator.md` with the requirements we discussed. Now, I will start implementing it. + +**Agent (Phase 2 - Build):** +> *(Creates `stats_calculator.js` and implements `mean`, `median`, and `mode` matching the spec exactly)* +> I have finished implementing the calculator. I will now verify the implementation. + +**Agent (Phase 3 - Review):** +> Checking implementation against `specs/stats-calculator.md`: +> - Requirement: mean calculation -> PASS +> - Requirement: median calculation -> PASS +> - Requirement: mode calculation -> PASS +> - Requirement: empty array returns null -> PASS +> - Requirement: non-numbers are ignored -> FAIL (I noticed `mode` doesn't filter out non-numbers). +> +> I will now loop back to Phase 2 to fix the `mode` function. + +**Agent (Phase 2 - Build Loop-Back):** +> *(Fixes `mode` to filter out non-numbers)* +> I have updated the implementation. Let's re-verify. + +**Agent (Phase 3 - Review):** +> - Requirement: mode filters non-numbers -> PASS +> +> All requirements passed! The statistics calculator is complete and verified. + +## Best Practices + +- ✅ Do ask clarifying questions one at a time to avoid overwhelming the user during the planning phase. +- ✅ Do document edge cases explicitly in `specs/.md` before writing any code. +- ✅ Do stick strictly to the approved specification during the build phase. +- ✅ Do cap the loop with a small iteration budget and report exactly what remains if the budget is exhausted. +- ✅ Do pause for explicit approval before destructive, production, credentialed, or externally visible actions. +- ❌ Don't implement extra features or perform unrelated refactorings that aren't specified. +- ❌ Don't skip the review phase or pass it without verifying every single requirement. +- ❌ Don't keep retrying the same failing fix without new evidence or a changed approach. + +## Limitations + +- This skill requires sufficient context about the feature to be provided during the Spec phase. +- It is best suited for isolated features or tasks with clear boundaries, rather than open-ended architectural refactoring. +- The review phase relies on the agent's self-assessment against the generated spec; manual review is still recommended for critical systems. +- It is not a replacement for human approval on security-sensitive, destructive, production, compliance, or externally visible changes. +- It should stop rather than continue if requirements conflict, tests cannot run, or verification depends on unavailable credentials or systems. + +## Security & Safety Notes + +- Be cautious when running or testing code generated during the Build phase. Always run tests in a safe, sandboxed environment. +- Avoid executing arbitrary shell commands provided directly by the user without validating their safety. +- Make sure no hardcoded secrets, keys, or credentials are added to the code or specifications. +- Treat production deploys, data migrations, payment flows, credential changes, and external write actions as approval-gated work. + +## Common Pitfalls + +- **Problem:** The agent tries to build a huge system all at once, leading to an overcomplicated spec and incomplete implementation. + **Solution:** Keep the scope of `ai-loop` to small, modular features. Break larger systems into multiple independent loops. +- **Problem:** The spec is vague, causing the build phase to rely on assumptions. + **Solution:** Spend extra time in the planning phase asking targeted questions to pin down requirements. + +## Related Skills + +- `@plan-writing` - For writing more detailed implementation plans for larger projects. +- `@ask-questions-if-underspecified` - For standard guidelines on interviewing the user. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/cron-doctor/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/cron-doctor/SKILL.md new file mode 100644 index 00000000..48eec6f8 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/cron-doctor/SKILL.md @@ -0,0 +1,244 @@ +--- +name: cron-doctor +description: "Diagnose and validate cron expressions before they ship. Catches the five silent death-traps: impossible dates that never fire, OR-semantics that fire too often, midnight spikes, uneven step drift, and leap-year February 29." +category: devops +risk: safe +source: community +source_repo: takeaseatventure/devops-skills +source_type: community +date_added: "2026-06-26" +author: takeaseat +tags: [cron, crontab, scheduling, devops, debugging, kubernetes, validation] +tools: [claude, cursor, codex, gemini, opencode] +license: "MIT" +license_source: "https://github.com/takeaseatventure/devops-skills/blob/main/LICENSE" +--- + +# cron-doctor + +## Overview + +Cron is deceptively error-prone. The failure mode is **silent** — a syntactically +valid expression that simply never fires, or fires far more often than intended. +`0 0 30 2 *` parses cleanly and then sits dead forever (February has no 30th). +`0 0 1,15 * 1` looks like "1st and 15th if Monday" but actually means "1st, 15th, +**OR** every Monday" — ~6 fires/month instead of ~2. + +This skill teaches an agent to catch those before they reach production. It comes +with a zero-dependency validation engine (`scripts/cron-engine.js`, no install +needed) that parses, describes, deep-validates, and computes next fire times. + +## When to Use This Skill + +- Use when a user writes, edits, reviews, or deploys a cron expression — in a + crontab, a Kubernetes `CronJob`, a GitHub Actions `schedule`, an Airflow DAG, + a Celery beat schedule, a systemd timer, or any scheduled task. +- Use when debugging a job that "didn't fire" or "fired at the wrong time." +- Use when a user asks "what does this cron expression mean?" or "when will this + run next?" or "how often does this run per year?" +- Use when reviewing a CI/CD pipeline or infrastructure config that contains a + `schedule` field. +- Use when a user pastes a 5-field cron expression and asks for a sanity check. + +## How It Works + +### Step 1: Parse the expression + +Split on whitespace into 5 fields: minute, hour, day-of-month, month, day-of-week. +Confirm valid ranges: + +| Field | Position | Range | Notes | +|-------|----------|-------|-------| +| minute | 1 | 0–59 | | +| hour | 2 | 0–23 | | +| day-of-month | 3 | 1–31 | | +| month | 4 | 1–12 | names (JAN–DEC) accepted | +| day-of-week | 5 | 0–7 | 0 and 7 both = Sunday; names (SUN–SAT) accepted | + +### Step 2: Describe it in plain English + +State what the user *thinks* it does vs. what it *actually* does. Be explicit +about OR-vs-AND semantics for day-of-month + day-of-week (see death-trap #2). + +### Step 3: Run the trap checklist + +Check the five death-traps below and flag any that apply. + +### Step 4: Calculate next runs and annual fire count + +Compute the next 5 fire times as concrete dates so the user can verify the +schedule behaves as expected. Estimate annual fire count — a schedule that fires +365×/year vs. 12×/year is a ~30× cost and load difference. + +## The Five Cron Death-Traps + +These are the bugs that pass `crontab -l` validation but break in production. + +### 1. Impossible dates — the "never fires" bug + +``` +0 0 30 2 * +``` + +**Valid syntax. Never fires.** February has no 30th. This schedule is a dead job +that silently sits forever. The same applies to day 31 in any 30-day month: +`0 0 31 4 *`, `0 0 31 6 *`, `0 0 31 9 *`, `0 0 31 11 *`. + +**Fix:** use `0 0 28-31 * *` and check for end-of-month in the script, or use `L` +(last day) syntax if your scheduler supports it. + +### 2. OR-semantics — the "fires too often" bug + +``` +0 0 1,15 * 1 +``` + +**Does NOT mean** "midnight on the 1st and 15th if it's Monday." +**Does mean** "midnight on the 1st, the 15th, **OR** every Monday." That's ~6 +fires/month instead of ~2. + +This is the single most misunderstood cron rule. When **both** day-of-month AND +day-of-week are restricted (neither is `*`), cron uses OR logic, not AND. + +**Fix:** if you need "1st and 15th only if Monday," run daily and check in the +script: + +```bash +0 0 * * 1 [ "$(date +%d)" = "01" -o "$(date +%d)" = "15" ] && your-command +``` + +### 3. Midnight spike — the "everything at once" bug + +``` +0 0 * * * +``` + +Every job scheduled at `0 0` competes for resources at exactly 00:00. Database +backups, log rotations, cert renewals, report generation — all fire simultaneously. +This causes load spikes, connection-pool exhaustion, and cascading timeouts. + +**Fix:** stagger jobs across the hour. Use `17 2 * * *` or `43 3 * * *` instead of +`0 0`. Jitter is your friend. + +### 4. Uneven steps — the "drift" bug + +``` +*/7 * * * * +``` + +**Does NOT mean** "every 7 minutes evenly." It means "every 7 minutes starting at +0, then resets at 60." So: 0, 7, 14, 21, 28, 35, 42, 49, 56 — then 0 again +(a 4-minute gap). The intervals drift: 7,7,7,7,7,7,7,7,**4**. + +**Fix:** 60 is not divisible by 7. Use step values that divide 60 evenly: `*/5`, +`*/10`, `*/15`, `*/20`, `*/30`. If you truly need every-7-minutes, use a loop with +`sleep 420`. + +### 5. Leap-year February 29 — the "annual surprise" + +``` +0 0 29 2 * +``` + +Fires only on leap years — February 29, 2024 / 2028 / 2032… If someone writes this +expecting "end of February," they'll be confused for 3 out of every 4 years. + +**Fix:** use `0 0 28 2 *` and handle the 29th case in the script if needed. + +## Using the validation script + +This skill ships a zero-dependency engine at `scripts/cron-engine.js` (Node.js, no +`npm install` needed). You can use it programmatically or from the CLI: + +```javascript +// Programmatic — Node.js, zero dependencies +const { describe, validate, nextRuns, formatNextRuns } = require('./scripts/cron-engine.js'); + +// Parse + describe -> returns { text, error, parsed } +const d = describe('0 0 30 2 *'); +console.log(d.text); // "At 00:00, on day-of-month 30 in in FEB" + +// Deep validation -> catches the traps +const result = validate('0 0 30 2 *'); +console.log(result.valid); // true (syntax is valid) +console.log(result.observations); // includes the "never fires" insight +console.log(result.suggestions); // e.g. "Midnight is a common spike..." + +// Next 5 fire times -> returns Date[] +const runs = nextRuns('0 9 * * 1-5', new Date(), 5); +console.log(formatNextRuns(runs, new Date())); // [{ date, relative, formatted }, ...] +``` + +```bash +# CLI (via the bundled wrapper) +node scripts/cli.js describe "*/5 * * * *" +node scripts/cli.js validate "0 0 30 2 *" +node scripts/cli.js next "0 9 * * 1-5" 5 +``` + +## Common cron presets + +| Expression | Description | Use case | +|-----------|-------------|----------| +| `*/5 * * * *` | Every 5 minutes | Health checks, polling | +| `0 * * * *` | Every hour | Hourly aggregation | +| `0 */2 * * *` | Every 2 hours | Semi-frequent sync | +| `0 9 * * 1-5` | 9am Mon–Fri | Business-hours task | +| `0 2 * * *` | 2am daily | Off-peak batch (avoid midnight) | +| `0 0 * * 0` | Midnight Sunday | Weekly maintenance | +| `0 0 1 * *` | Midnight 1st of month | Monthly report | +| `0 0 1 1 *` | Midnight Jan 1st | Annual task | + +## Best Practices + +- ✅ Always provide the plain-English description AND run the trap checklist. +- ✅ Stagger midnight jobs to avoid the spike. +- ✅ Prefer step values that divide 60 evenly (`*/5`, `*/15`, `*/30`). +- ✅ Add a comment above every crontab line explaining intent. +- ✅ Set an explicit timezone (`CRON_TZ`) on schedulers that support it. +- ❌ Don't trust `crontab -l` validation — it only checks syntax, not semantics. +- ❌ Don't restrict both day-of-month and day-of-week without confirming OR-logic. +- ❌ Don't schedule everything at `0 0`. + +## Common Pitfalls + +- **Problem:** "My cron job isn't running." + **Solution:** Check for an impossible date (trap #1) and confirm the daemon is + running (`service cron status` / `systemctl status crond`). Verify the file + ends with a newline and has correct ownership. + +- **Problem:** "My job runs far more often than expected." + **Solution:** You hit OR-semantics (trap #2). If both day-of-month and + day-of-week are set, cron ORs them. Move one to `*` or guard in-script. + +- **Problem:** "Intervals are uneven — sometimes 7 min, sometimes 4." + **Solution:** Step value doesn't divide 60 evenly (trap #4). Use a divisor of 60. + +- **Problem:** "My job works locally but not in the cluster." + **Solution:** Timezone mismatch. Kubernetes `CronJob` and GitHub Actions default + to UTC. Confirm `timeZone` / `TZ` is set as intended. + +## Limitations + +- This skill targets standard 5-field cron as implemented by Vixie cron, systemd + timers, Kubernetes `CronJob`, GitHub Actions `schedule`, and most libraries. It + does **not** validate Quartz 6/7-field expressions with seconds/years, nor + non-standard `@reboot` / `L` / `#` extensions without a note. +- Estimated annual fire counts assume a non-leap reference year; February 29 + schedules (trap #5) are flagged explicitly. +- This skill does not replace environment-specific validation, testing, or expert + review. Stop and ask for clarification if required inputs, permissions, or + safety boundaries are missing. + +## Related Skills + +- `docker-expert` — when the cron job runs inside a container and the issue is the + container/entrypoint rather than the schedule. +- `kubernetes-deployment` — when validating a `CronJob` manifest's `spec.schedule` + field alongside the broader resource config. + +## Security & Safety Notes + +This skill is read-only and `risk: safe`. The validation script performs no file +writes, network calls, or mutations — it only parses and computes. It is safe to +run against any cron expression without preconditions. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/cron-doctor/scripts/cli.js b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/cron-doctor/scripts/cli.js new file mode 100644 index 00000000..b0ac6905 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/cron-doctor/scripts/cli.js @@ -0,0 +1,75 @@ +#!/usr/bin/env node +'use strict'; + +// Minimal CLI wrapper for cron-engine.js. Zero dependencies. +// Usage: +// node cli.js describe "" +// node cli.js validate "" +// node cli.js next "" [count] + +const cron = require('./cron-engine.js'); +const expr = process.argv[3]; +const cmd = process.argv[2]; + +if (!cmd || !expr) { + console.error('Usage: node cli.js "" [count]'); + console.error('Examples:'); + console.error(' node cli.js describe "*/5 * * * *"'); + console.error(' node cli.js validate "0 0 30 2 *"'); + console.error(' node cli.js next "0 9 * * 1-5" 5'); + process.exit(2); +} + +function safe(fn) { + try { + fn(); + } catch (e) { + console.error('Error: ' + (e.message || e)); + process.exit(1); + } +} + +switch (cmd) { + case 'describe': + safe(() => { + const d = cron.describe(expr); + console.log(d.text || d.description || JSON.stringify(d)); + }); + break; + + case 'validate': + safe(() => { + const r = cron.validate(expr); + console.log('valid: ' + r.valid); + if (r.description) console.log('description: ' + r.description); + if (r.warnings && r.warnings.length) { + console.log('warnings:'); + r.warnings.forEach((w) => console.log(' - ' + w)); + } + if (r.observations && r.observations.length) { + console.log('observations:'); + r.observations.forEach((o) => console.log(' [' + (o.level || 'info') + '] ' + o.message)); + } + if (r.suggestions && r.suggestions.length) { + console.log('suggestions:'); + r.suggestions.forEach((s) => console.log(' [' + (s.level || 'info') + '] ' + s.message)); + } + }); + break; + + case 'next': + safe(() => { + const count = parseInt(process.argv[4] || '5', 10); + const runs = cron.nextRuns(expr, new Date(), count); + const formatted = cron.formatNextRuns(runs, new Date()); + formatted.forEach((f) => + console.log(f.relative + '\t' + f.formatted + '\t' + f.date.toString()) + ); + }); + break; + + default: + console.error('Unknown command: ' + cmd); + console.error('Commands: describe, validate, next'); + process.exit(2); +} diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/cron-doctor/scripts/cron-engine.js b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/cron-doctor/scripts/cron-engine.js new file mode 100644 index 00000000..07254dee --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/cron-doctor/scripts/cron-engine.js @@ -0,0 +1,638 @@ +'use strict'; + +// ============================================================================ +// cron.js — Cron expression parser, describer, validator, and next-run engine. +// Zero dependencies. Extracted from the DevRef Cron Expression Generator +// (battle-tested in browser) and extended with validate() for Pro insights. +// ============================================================================ + +const MONTH_NAMES = ['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC']; +const DAY_NAMES = ['SUN','MON','TUE','WED','THU','FRI','SAT']; + +const FIELDS = [ + { name: 'minute', min: 0, max: 59, key: 'minute' }, + { name: 'hour', min: 0, max: 23, key: 'hour' }, + { name: 'dom', min: 1, max: 31, key: 'dom' }, + { name: 'month', min: 1, max: 12, key: 'month', named: MONTH_NAMES }, + { name: 'dow', min: 0, max: 7, key: 'dow', named: DAY_NAMES }, +]; + +class CronError extends Error { + constructor(message, fieldIndex) { + super(message); + this.name = 'CronError'; + this.fieldIndex = fieldIndex; + } +} + +// ---- Name resolution ---- +function resolveName(token, names) { + if (!names) return null; + const up = token.toUpperCase(); + const idx = names.indexOf(up); + return idx === -1 ? null : idx; +} + +// ---- Field parsing ---- +function parseField(raw, fieldDef, fieldIndex) { + const trimmed = String(raw).trim(); + if (trimmed === '') throw new CronError(`Field ${fieldIndex + 1} (${fieldDef.name}) is empty`, fieldIndex); + + const out = { raw: trimmed, values: null, special: null }; + + // Special: day-of-week "#" (nth weekday) + if (fieldDef.key === 'dow' && trimmed.includes('#')) { + const m = trimmed.match(/^([0-7A-Za-z]+)#([1-5])$/); + if (!m) throw new CronError(`Invalid "#" syntax in day-of-week: "${trimmed}"`, fieldIndex); + let dowNum = parseSingleNum(m[1], fieldDef, fieldIndex); + if (dowNum === 7) dowNum = 0; + out.special = { kind: 'hash', dow: dowNum, nth: parseInt(m[2], 10) }; + return out; + } + + // Special: day-of-week "L" (last weekday) + if (fieldDef.key === 'dow' && /L$/i.test(trimmed)) { + const m = trimmed.match(/^([0-7A-Za-z]+)L$/i); + if (!m) throw new CronError(`Invalid "L" syntax in day-of-week: "${trimmed}"`, fieldIndex); + let dowNum = parseSingleNum(m[1], fieldDef, fieldIndex); + if (dowNum === 7) dowNum = 0; + out.special = { kind: 'dowLast', dow: dowNum }; + return out; + } + + // Special: day-of-month "L" (last day) + if (fieldDef.key === 'dom' && /^L/i.test(trimmed)) { + const m = trimmed.match(/^L(?:-(\d+))?$/i); + if (!m) throw new CronError(`Invalid "L" syntax in day-of-month: "${trimmed}"`, fieldIndex); + out.special = { kind: 'domLast', offset: m[1] ? parseInt(m[1], 10) : 0 }; + return out; + } + + // Special: day-of-month "W" (nearest weekday) + if (fieldDef.key === 'dom' && /W$/i.test(trimmed)) { + const m = trimmed.match(/^(\d+)W$/i); + if (!m) throw new CronError(`Invalid "W" syntax in day-of-month: "${trimmed}"`, fieldIndex); + const day = parseInt(m[1], 10); + if (day < fieldDef.min || day > fieldDef.max) { + throw new CronError(`Day-of-month "${day}W" out of range (${fieldDef.min}-${fieldDef.max})`, fieldIndex); + } + out.special = { kind: 'weekday', day: day }; + return out; + } + + // Standard parsing + const values = new Set(); + const items = trimmed.split(','); + for (const item of items) { + parseItem(item, fieldDef, fieldIndex, values); + } + out.values = values; + return out; +} + +function parseSingleNum(token, fieldDef, fieldIndex) { + const n = parseInt(token, 10); + if (!isNaN(n)) return n; + const named = resolveName(token, fieldDef.named); + if (named !== null) { + return fieldDef.key === 'month' ? named + 1 : named; + } + throw new CronError(`Invalid value "${token}" in ${fieldDef.name}`, fieldIndex); +} + +function parseItem(item, fieldDef, fieldIndex, values) { + const t = item.trim(); + if (t === '') throw new CronError(`Empty item in ${fieldDef.name}`, fieldIndex); + + if (t === '*') { + addRange(values, fieldDef.min, fieldDef.max, fieldDef); + return; + } + + if (t.includes('/')) { + const [base, stepStr] = t.split('/'); + const step = parseInt(stepStr, 10); + if (isNaN(step) || step < 1) throw new CronError(`Invalid step "${stepStr}" in ${fieldDef.name}`, fieldIndex); + let lo, hi; + if (base === '*' || base === '') { + lo = fieldDef.min; hi = fieldDef.max; + } else if (base.includes('-')) { + const [a, b] = base.split('-'); + lo = parseSingleNum(a.trim(), fieldDef, fieldIndex); + hi = parseSingleNum(b.trim(), fieldDef, fieldIndex); + } else { + lo = parseSingleNum(base.trim(), fieldDef, fieldIndex); + hi = fieldDef.max; + } + if (lo > hi) [lo, hi] = [hi, lo]; + for (let v = lo; v <= hi; v += step) addOne(values, v, fieldDef, fieldIndex); + return; + } + + if (t.includes('-')) { + const parts = t.split('-'); + if (parts.length !== 2) throw new CronError(`Invalid range "${t}" in ${fieldDef.name}`, fieldIndex); + const a = parseSingleNum(parts[0].trim(), fieldDef, fieldIndex); + const b = parseSingleNum(parts[1].trim(), fieldDef, fieldIndex); + addRange(values, a, b, fieldDef); + return; + } + + const v = parseSingleNum(t, fieldDef, fieldIndex); + addOne(values, v, fieldDef, fieldIndex); +} + +function addOne(values, v, fieldDef, fieldIndex) { + if (fieldDef.key === 'dow' && v === 7) { values.add(0); return; } + if (v < fieldDef.min || v > fieldDef.max) { + throw new CronError(`Value ${v} out of range for ${fieldDef.name} (${fieldDef.min}-${fieldDef.max})`, fieldIndex); + } + values.add(v); +} + +function addRange(values, lo, hi, fieldDef) { + if (lo > hi) [lo, hi] = [hi, lo]; + if (lo < fieldDef.min || hi > fieldDef.max) { + throw new CronError(`Range ${lo}-${hi} out of bounds for ${fieldDef.name} (${fieldDef.min}-${fieldDef.max})`, -1); + } + for (let v = lo; v <= hi; v++) { + if (fieldDef.key === 'dow' && v === 7) { values.add(0); continue; } + values.add(v); + } +} + +// ---- Full expression parser ---- +function parseCron(expr) { + const parts = String(expr).trim().split(/\s+/); + if (parts.length !== 5) { + throw new CronError(`Expected 5 fields (got ${parts.length}). Format: minute hour day-of-month month day-of-week`, -1); + } + const parsed = {}; + for (let i = 0; i < 5; i++) { + parsed[FIELDS[i].key] = parseField(parts[i], FIELDS[i], i); + } + parsed.domRestricted = !/^\s*\*\s*$/.test(parts[2]); + parsed.dowRestricted = !/^\s*\*\s*$/.test(parts[4]); + parsed.parts = parts; + return parsed; +} + +// ---- Human-readable description ---- +function describe(expr) { + let parsed; + try { parsed = parseCron(expr); } catch (e) { return { text: e.message, error: true }; } + return { text: describeParsed(parsed), error: false, parsed }; +} + +function describeParsed(p) { + const monthDesc = describeFieldMonth(p.month); + const domDesc = describeFieldDom(p.dom); + const dowDesc = describeFieldDow(p.dow); + + const isEveryMin = p.parts[0] === '*'; + const isEveryHour = p.parts[1] === '*'; + + let timePart = ''; + if (isEveryMin && isEveryHour) { + timePart = 'At every minute'; + } else if (isEveryMin && !isEveryHour) { + const hours = [...(p.hour.values || [])].sort((a, b) => a - b); + if (hours.length > 0) { + timePart = 'Every minute during the ' + hours.map(h => pad2(h)).join(', ') + ' hour' + (hours.length > 1 ? 's' : ''); + } else { + timePart = 'Every minute'; + } + } else { + timePart = 'At ' + describeTimes(p.minute, p.hour); + } + + let dayPart = ''; + const domAny = !p.domRestricted; + const dowAny = !p.dowRestricted; + + if (domAny && dowAny) { + if (monthDesc.restricted) { + dayPart = ', ' + monthDesc.text + ' of every year'; + } else { + dayPart = ', every day'; + } + } else if (!domAny && dowAny) { + dayPart = ', on ' + domDesc.text; + if (monthDesc.restricted) dayPart += ' in ' + monthDesc.text; + } else if (domAny && !dowAny) { + dayPart = ', on ' + dowDesc.text; + if (monthDesc.restricted) dayPart += ' in ' + monthDesc.text; + } else { + dayPart = ', on ' + domDesc.text + ' and on ' + dowDesc.text; + if (monthDesc.restricted) dayPart += ' in ' + monthDesc.text; + } + + return capitalize(timePart + dayPart); +} + +function describeTimes(minuteField, hourField) { + const mins = [...(minuteField.values || [])].sort((a, b) => a - b); + const hours = [...(hourField.values || [])].sort((a, b) => a - b); + + if (pIsWildcard(hourField) && !pIsWildcard(minuteField)) { + if (mins.length === 1) return `minute ${mins[0]} of every hour`; + return `minutes ${listJoin(mins)} of every hour`; + } + if (pIsWildcard(minuteField) && pIsWildcard(hourField)) return 'every minute of every hour'; + + if (pIsWildcard(minuteField)) { + return `every minute during the ${hours.map(h => pad2(h)).join(', ')} hour${hours.length > 1 ? 's' : ''}`; + } + + const combos = []; + for (const h of hours) { + for (const m of mins) { + combos.push(formatHM(h, m)); + } + } + return listJoin(combos); +} + +function describeFieldMonth(field) { + if (pIsWildcard(field)) return { restricted: false, text: 'every month' }; + const vals = [...(field.values || [])].sort((a, b) => a - b); + return { restricted: true, text: 'in ' + listJoin(vals.map(v => capitalize(MONTH_NAMES[v - 1]))) }; +} + +function describeFieldDom(field) { + if (pIsWildcard(field)) return { text: 'every day-of-month' }; + if (field.special) { + if (field.special.kind === 'domLast') { + return { text: field.special.offset === 0 ? 'the last day of the month' : `the last day of the month minus ${field.special.offset} days` }; + } + if (field.special.kind === 'weekday') { + return { text: `the nearest weekday to day ${field.special.day}` }; + } + } + const vals = [...(field.values || [])].sort((a, b) => a - b); + return { text: `day-of-month ${listJoin(vals)}` }; +} + +function describeFieldDow(field) { + if (pIsWildcard(field)) return { text: 'every day-of-week' }; + if (field.special) { + if (field.special.kind === 'hash') { + return { text: `the ${ordinal(field.special.nth)} ${capitalize(DAY_NAMES[field.special.dow])} of the month` }; + } + if (field.special.kind === 'dowLast') { + return { text: `the last ${capitalize(DAY_NAMES[field.special.dow])} of the month` }; + } + } + const vals = [...(field.values || [])].sort((a, b) => a - b); + return { text: listJoin(vals.map(v => capitalize(DAY_NAMES[v]))) }; +} + +function pIsWildcard(field) { return field.raw === '*'; } + +// ---- Next run calculator ---- +function nextRuns(expr, fromDate, count) { + count = count || 10; + const p = parseCron(expr); + const runs = []; + let d = new Date(fromDate.getTime()); + d.setSeconds(0, 0); + d = new Date(d.getTime() + 60000); + + let maxScan = 600000; // ~416 days ceiling + while (runs.length < count && maxScan-- > 0) { + if (matches(d, p)) { + runs.push(new Date(d.getTime())); + } + d = new Date(d.getTime() + 60000); + } + return runs; +} + +function matches(d, p) { + if (!p.minute.values || !p.minute.values.has(d.getMinutes())) return false; + if (!p.hour.values || !p.hour.values.has(d.getHours())) return false; + if (!p.month.values || !p.month.values.has(d.getMonth() + 1)) return false; + + const domAny = !p.domRestricted; + const dowAny = !p.dowRestricted; + + let domMatch = false, dowMatch = false; + if (domAny) { + domMatch = true; + } else if (p.dom.special) { + domMatch = matchDomSpecial(d, p.dom.special); + } else if (p.dom.values && p.dom.values.has(d.getDate())) { + domMatch = true; + } + if (dowAny) { + dowMatch = true; + } else if (p.dow.special) { + dowMatch = matchDowSpecial(d, p.dow.special); + } else if (p.dow.values) { + dowMatch = p.dow.values.has(d.getDay()); + } + + if (domAny && dowAny) return true; + if (!domAny && !dowAny) return domMatch || dowMatch; // OR semantics + return domMatch && dowMatch; +} + +function matchDomSpecial(d, special) { + if (special.kind === 'domLast') { + const lastDay = lastDayOfMonth(d.getFullYear(), d.getMonth()); + const target = special.offset === 0 ? lastDay : lastDay - special.offset; + return d.getDate() === target; + } + if (special.kind === 'weekday') { + return d.getDate() === nearestWeekday(d.getFullYear(), d.getMonth(), special.day); + } + return false; +} + +function matchDowSpecial(d, special) { + if (special.kind === 'hash') { + return nthWeekdayMatches(d, special.dow, special.nth); + } + if (special.kind === 'dowLast') { + return lastWeekdayMatches(d, special.dow); + } + return false; +} + +function nthWeekdayMatches(d, dow, nth) { + if (d.getDay() !== dow) return false; + const dayOfMonth = d.getDate(); + const occurrence = Math.ceil(dayOfMonth / 7); + return occurrence === nth; +} + +function lastWeekdayMatches(d, dow) { + if (d.getDay() !== dow) return false; + const lastDay = lastDayOfMonth(d.getFullYear(), d.getMonth()); + return d.getDate() + 7 > lastDay; +} + +function lastDayOfMonth(year, month) { + return new Date(year, month + 1, 0).getDate(); +} + +function nearestWeekday(year, month, day) { + const lastDay = lastDayOfMonth(year, month); + const target = Math.min(day, lastDay); + const dt = new Date(year, month, target); + const wd = dt.getDay(); + let result = target; + if (wd === 0) { + if (target + 1 <= lastDay) result = target + 1; + else result = target - 2; + } else if (wd === 6) { + if (target - 1 >= 1) result = target - 1; + else result = target + 2; + } + return result; +} + +// ============================================================================ +// validate() — Pro-tier feature: deeper analysis of a cron expression. +// Returns warnings, observations, and optimization suggestions. +// ============================================================================ + +function validate(expr) { + let parsed; + try { + parsed = parseCron(expr); + } catch (e) { + return { + valid: false, + error: e.message, + fieldIndex: e.fieldIndex, + warnings: [], + observations: [], + suggestions: [], + }; + } + + const warnings = []; + const observations = []; + const suggestions = []; + + const desc = describeParsed(parsed); + + // Check: day-of-month and day-of-week both restricted (OR semantics surprise) + if (parsed.domRestricted && parsed.dowRestricted) { + warnings.push({ + level: 'high', + message: 'Both day-of-month and day-of-week are restricted. Cron uses OR semantics for these fields — the job will run when EITHER matches, not both. This is a common source of bugs.', + }); + } + + // Check: impossible day-of-month values (e.g., 31 in Feb) + const domValues = [...(parsed.dom.values || [])]; + if (!parsed.domRestricted && parsed.month.values && ![...parsed.month.values].every(m => m === 2)) { + // skip + } else if (parsed.domRestricted && !parsed.dom.special && domValues.includes(31)) { + const monthsWith31 = [1, 3, 5, 7, 8, 10, 12]; // Jan, Mar, May, Jul, Aug, Oct, Dec + const monthValues = parsed.month.values ? [...parsed.month.values] : []; + const restrictedMonths = parsed.parts[3] !== '*'; + if (restrictedMonths) { + const problemMonths = monthValues.filter(m => !monthsWith31.includes(m)); + if (problemMonths.length > 0) { + warnings.push({ + level: 'medium', + message: `Day 31 is specified but months ${problemMonths.map(m => capitalize(MONTH_NAMES[m - 1])).join(', ')} have fewer than 31 days. The job will never run in those months.`, + }); + } + } else { + observations.push({ + level: 'info', + message: 'Day 31 will only match in months with 31 days (7 of 12 months). The job effectively skips Feb, Apr, Jun, Sep, and Nov.', + }); + } + } + + // Check: high-frequency schedules + if (parsed.parts[0] === '*' && parsed.parts[1] === '*') { + observations.push({ + level: 'info', + message: 'This expression runs every minute. For production jobs, consider if this frequency is intentional.', + }); + } + + // Check: step values that don't divide evenly + for (let i = 0; i < 2; i++) { + const part = parsed.parts[i]; + if (part.startsWith('*/')) { + const step = parseInt(part.slice(2), 10); + const range = i === 0 ? 60 : 24; + if (range % step !== 0) { + observations.push({ + level: 'info', + message: `Step value */${step} in ${FIELDS[i].name} doesn't divide evenly into ${range}. The last interval will be shorter than the rest (e.g., */7 in minutes goes 0,7,14,...,56, then 0 again — not 63).`, + }); + } + } + } + + // Check: February 29th edge case + if (parsed.domRestricted && !parsed.dom.special) { + const domVals = [...(parsed.dom.values || [])]; + const monthVals = parsed.month.values ? [...parsed.month.values] : []; + if (domVals.includes(29) && monthVals.length === 1 && monthVals[0] === 2) { + warnings.push({ + level: 'medium', + message: 'February 29th only occurs in leap years. This job will not run at all in non-leap years (3 out of every 4 years).', + }); + } + } + + // Check: midnight rush + if (parsed.parts[0] === '0' && parsed.parts[1] === '0') { + suggestions.push({ + level: 'info', + message: 'Midnight (00:00) is a common schedule and many systems have concurrent job spikes at this time. Consider offsetting to a few minutes past midnight (e.g., 02 0 * * *) to avoid resource contention.', + }); + } + + // Check: weekend vs weekday + if (parsed.parts[4] === '1-5') { + observations.push({ + level: 'info', + message: 'Weekdays only (Mon-Fri). This job will not run on weekends.', + }); + } + + // Compute frequency estimate + const freq = estimateFrequency(parsed); + if (freq) { + observations.push({ + level: 'info', + message: `Approximate frequency: ${freq.description} (~${freq.runsPerYear} runs per year).`, + }); + } + + return { + valid: true, + description: desc, + warnings, + observations, + suggestions, + parsed, + }; +} + +function estimateFrequency(parsed) { + try { + // Count runs over a sample year + const start = new Date(2025, 0, 1, 0, 0, 0, 0); + const end = new Date(2026, 0, 1, 0, 0, 0, 0); + let count = 0; + let d = new Date(start.getTime()); + let maxScan = 540000; // ~375 days + while (d < end && maxScan-- > 0) { + if (matches(d, parsed)) count++; + d = new Date(d.getTime() + 60000); + } + + let description = ''; + if (count >= 525600) description = 'every minute'; + else if (count >= 500000) description = 'multiple times per minute'; + else if (count >= 8000) description = 'hourly or more'; + else if (count >= 300) description = 'daily or more'; + else if (count >= 40) description = 'weekly or more'; + else if (count >= 8) description = 'monthly or more'; + else if (count >= 1) description = 'yearly or less'; + else description = 'never (impossible schedule)'; + + return { description, runsPerYear: count }; + } catch (e) { + return null; + } +} + +// ---- Presets ---- +const PRESETS = [ + { label: 'Every minute', cron: '* * * * *' }, + { label: 'Every 5 min', cron: '*/5 * * * *' }, + { label: 'Every 10 min', cron: '*/10 * * * *' }, + { label: 'Every 15 min', cron: '*/15 * * * *' }, + { label: 'Every 30 min', cron: '*/30 * * * *' }, + { label: 'Hourly', cron: '0 * * * *' }, + { label: 'Every 2 hours', cron: '0 */2 * * *' }, + { label: 'Every 6 hours', cron: '0 */6 * * *' }, + { label: 'Every 12 hours', cron: '0 */12 * * *' }, + { label: 'Daily at midnight', cron: '0 0 * * *' }, + { label: 'Daily 9am', cron: '0 9 * * *' }, + { label: 'Twice daily', cron: '0 9,21 * * *' }, + { label: 'Weekdays 9am', cron: '0 9 * * 1-5' }, + { label: 'Weekends 10am', cron: '0 10 * * 0,6' }, + { label: 'Every Monday', cron: '0 0 * * 1' }, + { label: 'Every Friday', cron: '0 0 * * 5' }, + { label: 'Monthly 1st', cron: '0 0 1 * *' }, + { label: 'Quarterly', cron: '0 0 1 */3 *' }, + { label: 'Yearly Jan 1', cron: '0 0 1 1 *' }, +]; + +const COMMON = [ + { label: 'At 14:30', cron: '30 14 * * *' }, + { label: '9am weekdays', cron: '0 9 * * 1-5' }, + { label: 'Every Mon 8am', cron: '0 8 * * 1' }, + { label: 'Last day of month', cron: '0 0 L * *' }, + { label: '15th, weekday', cron: '0 0 15W * *' }, + { label: '3rd Thursday', cron: '0 0 * * 4#3' }, + { label: 'Last Friday', cron: '0 0 * * 5L' }, + { label: 'Business hours', cron: '0 9-17 * * 1-5' }, + { label: 'Backup nightly', cron: '0 2 * * *' }, +]; + +// ---- Helpers ---- +function pad2(n) { return String(n).padStart(2, '0'); } +function formatHM(h, m) { return `${pad2(h)}:${pad2(m)}`; } +function capitalize(s) { return s.charAt(0).toUpperCase() + s.slice(1); } +function ordinal(n) { + const s = ['th', 'st', 'nd', 'rd']; + const v = n % 100; + return n + (s[(v - 20) % 10] || s[v] || s[0]); +} +function listJoin(arr) { + if (arr.length === 0) return ''; + if (arr.length === 1) return String(arr[0]); + if (arr.length === 2) return `${arr[0]} and ${arr[1]}`; + return arr.slice(0, -1).join(', ') + ', and ' + arr[arr.length - 1]; +} + +function formatNextRuns(runs, fromDate) { + return runs.map(r => { + const diff = r.getTime() - fromDate.getTime(); + const mins = Math.round(diff / 60000); + let rel; + if (mins < 60) rel = `+${mins}m`; + else if (mins < 2880) rel = `+${Math.round(mins / 60)}h`; + else rel = `+${Math.round(mins / 1440)}d`; + return { date: r, relative: rel, formatted: r.toISOString() }; + }); +} + +module.exports = { + CronError, + FIELDS, + MONTH_NAMES, + DAY_NAMES, + PRESETS, + COMMON, + parseCron, + describe, + describeParsed, + nextRuns, + matches, + validate, + estimateFrequency, + formatNextRuns, + parseField, + parseItem, + parseSingleNum, + resolveName, + lastDayOfMonth, + nearestWeekday, + nthWeekdayMatches, + lastWeekdayMatches, +}; diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/sql-sentinel/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/sql-sentinel/SKILL.md new file mode 100644 index 00000000..cf35a1e7 --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/sql-sentinel/SKILL.md @@ -0,0 +1,131 @@ +--- +name: sql-sentinel +description: "Audit SQL for the cost & performance anti-patterns that burn warehouse credits. Scores warehouse health 0-100 and outputs a prioritized cost-reduction plan for BigQuery, Snowflake, Redshift, and Postgres." +category: data +risk: safe +source: community +source_repo: takeaseatventure/sql-sentinel +source_type: community +date_added: "2026-06-26" +author: takeaseat +tags: [sql, bigquery, snowflake, redshift, postgres, data-warehouse, cost-optimization, performance, audit, finops] +tools: [claude, cursor, codex, gemini] +license: "MIT" +license_source: "https://github.com/takeaseatventure/sql-sentinel/blob/main/LICENSE" +--- + +# sql-sentinel + +## Overview + +A static-analysis skill that audits SQL for the cost & performance anti-patterns that dominate warehouse bills — `SELECT *`, full-table scans, non-sargable predicates, Cartesian joins, the `NOT IN` NULL trap, and 15 more. It scores warehouse query health 0-100 (A-F) and outputs a prioritized cost-reduction plan, each finding with a `why`, a concrete `fix`, and an estimated savings. + +Built for analytics engineers (dbt, Looker), data platform teams running FinOps / "reduce cloud spend" initiatives, and anyone reviewing a SQL pull request before it hits production. Works across BigQuery, Snowflake, Redshift, and Postgres. Zero dependencies, MIT licensed. + +The executable engine and full rule set live in the source repository: https://github.com/takeaseatventure/sql-sentinel + +## When to Use This Skill + +- A user writes or reviews a query for BigQuery, Snowflake, Redshift, Postgres, or Spark SQL. +- A user asks "why is this query so slow?" or "why is my warehouse bill so high?" +- A user is about to promote a dashboard query or dbt model to production. +- A data engineer wants a second pair of eyes before a code review or a cost-optimization sweep. +- A team is running a "reduce cloud spend" or FinOps initiative. + +## How It Works + +The engine splits a SQL script into statements (honoring quotes and comments), runs 20 rules over each statement, scores health 0-100 weighted by severity (critical 25, high 12, medium 5, low 1), and returns a prioritized cost-reduction plan. + +### Step 1: Run the audit + +Install or clone the source repository, then run the zero-dependency engine: + +```bash +git clone https://github.com/takeaseatventure/sql-sentinel.git +cd sql-sentinel +node scripts/sql-sentinel.js path/to/query.sql +``` + +Or programmatically: + +```javascript +const { auditSql } = require('./scripts/sql-sentinel'); +const report = auditSql(yourSqlString, { dialect: 'bigquery' }); +console.log(report.healthScore); // 0-100 +console.log(report.grade); // 'A' | 'B' | 'C' | 'D' | 'E' | 'F' +console.log(report.prioritizedPlan); // array, worst findings first +``` + +### Step 2: Read the prioritized plan + +The output leads with critical findings (Cartesian joins, mass DELETE) and descends to low-severity style issues. Each finding explains *why* it costs money and *how* to fix it. + +## Examples + +### Example 1: A messy dashboard query + +```sql +SELECT DISTINCT * +FROM user_events, raw_logs +WHERE LOWER(event_name) LIKE '%signup%' + AND user_id NOT IN (SELECT id FROM deleted_users) +ORDER BY created_at; +``` + +The audit scores this 17/100 (grade F) and flags 7 findings: +- CRITICAL: comma-join produces a Cartesian product (can turn a $0.02 query into a $200 query) +- HIGH: `SELECT *` forces full column scan (30-90% wasted bytes on wide tables) +- HIGH: leading-wildcard `LIKE '%signup%'` defeats indexes +- HIGH: `LOWER(event_name)` defeats indexes (non-sargable) +- HIGH: `NOT IN (SELECT ...)` — NULL semantics hazard +- MEDIUM: `SELECT DISTINCT` dedup cost +- MEDIUM: `ORDER BY` without `LIMIT` sorts the full result + +### Example 2: A clean, sargable query + +```sql +-- This scores 90+/100 (grade A) — no findings +SELECT id, email, created_at +FROM users +WHERE created_at >= TIMESTAMP '2026-01-01' + AND created_at < TIMESTAMP '2026-02-01' +ORDER BY id +LIMIT 100; +``` + +## The 20 rules (ruleset v1.0.0) + +| Rule | Severity | Catches | +|---|---|---| +| SQL001 | high | `SELECT *` full column scan | +| SQL002 | critical | No `WHERE` → full table scan | +| SQL003 | high | `LIKE '%term'` non-sargable | +| SQL004 | high | Function on column kills index | +| SQL005 | critical | `CROSS JOIN` / comma-join | +| SQL006 | medium | `SELECT DISTINCT` dedup cost | +| SQL007 | medium | `ORDER BY` without `LIMIT` | +| SQL008 | high | `NOT IN (SELECT ...)` NULL trap | +| SQL009 | medium | Implicit type cast | +| SQL010 | low | Many `OR`s (use `IN`/`UNION`) | +| SQL011 | medium | `COUNT(DISTINCT)` at scale (use HLL) | +| SQL012 | low | `LIMIT` without `ORDER BY` | +| SQL013 | medium | Scalar subquery in `SELECT` | +| SQL014 | medium | 5+ JOINs broadcast/spill risk | +| SQL015 | high | Fact table, no partition filter | +| SQL017 | low | String concat in `SELECT` | +| SQL018 | medium | Window `OVER ()` no `PARTITION` | +| SQL020 | critical | `DELETE`/`UPDATE` without `WHERE` | +| SQL021 | low | `SELECT *` in `EXISTS`/`IN` | +| SQL022 | medium | `UNION` vs `UNION ALL` | + +Run the test suite to verify each rule fires on real SQL: + +```bash +cd scripts && node test.js # 26 tests, zero dependencies +``` + +## Limitations + +- This is a **static** analyzer. It finds anti-patterns in the *text* of SQL; it does not read query plans, row counts, or billing. A flagged query on a 100-row table is cheap; the same query on a billion-row table is the problem the rule exists to prevent. +- The fact-table heuristic (SQL015) keys off table *names* (`*_events`, `*_log`) and is advisory, not definitive. +- It does not execute SQL — safe to run on any `.sql` file. diff --git a/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/web-project-brainstorming/SKILL.md b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/web-project-brainstorming/SKILL.md new file mode 100644 index 00000000..8e2736be --- /dev/null +++ b/antigravity-awesome-skills/plugins/antigravity-awesome-skills/skills/web-project-brainstorming/SKILL.md @@ -0,0 +1,149 @@ +--- +name: web-project-brainstorming +description: Masterclass framework for brainstorming web development projects and page designs. Outlines structural phases for concept, UX flow, styling aesthetics, technical architecture, and SEO. +category: consulting +risk: safe +source: self +source_type: self +date_added: "2026-06-26" +author: Rsmiyani +tags: [brainstorming, project-planning, web-development, product-scoping, design-system, architecture] +tools: [claude, cursor, gemini] +--- + +# Web Project Brainstorming + +## Overview + +This skill provides a structured, masterclass-level framework for brainstorming web projects, web applications, or individual page designs at their inception. It guides developers and designers through scoping the core product concept, mapping user flows, defining visual styling aesthetics, selecting the technical stack, and planning for search engine optimization (SEO) and performance. + +## When to Use This Skill + +- Use at the start of any new web development project or page redesign. +- Use when scoping feature sets, user roles, and interaction patterns for web applications. +- Use when establishing design systems, color tokens, and layout guidelines. +- Use when evaluating tech stacks (e.g., Next.js vs. Vanilla JS, CSS Grid vs. Tailwind). + +## How It Works + +Execute web project brainstorming sequentially across six structured phases. Ask the user questions one phase at a time to maintain focus and ensure thorough alignment. + +### Phase 1: Core Concept & Scoping +Define the product's primary value proposition and scope: +- **Target Audience**: Who is using the website or application? +- **Core Value**: What problem does it solve for users? +- **Key Features**: What are the top 3–5 mandatory features? + +### Phase 2: User Experience (UX) & Information Architecture +Map how users navigate and interact: +- **Page Hierarchy**: What is the sitemap and page structure? +- **User Journeys**: What step-by-step flows do users take to complete key goals? +- **Responsive Layout**: Is the interface mobile-first, desktop-first, or balanced? + +### Phase 3: Visual Styling & Design System +Establish the visual guidelines and aesthetic parameters: +- **Design Aesthetic**: Modern, minimalist, brutalist, glassmorphism, or luxury? +- **Color Palette**: What are the primary, secondary, and accent colors? (Prefer tailorable HSL/RGB models over static color keywords). +- **Typography**: Which Google Fonts or system fonts fit the theme? (e.g., Inter, Outfit, Syne). +- **Interactive States**: How do hovers, clicks, transitions, and loading states behave? + +### Phase 4: Technical Stack & Architecture +Select the technologies and integration systems: +- **Frontend Framework**: React, Next.js, Vite, Astro, Svelte, or Vanilla HTML/JS? +- **Styling Method**: Vanilla CSS, Tailwind CSS, or CSS Modules? +- **Data & Backend**: REST API, GraphQL, tRPC, Firebase, Supabase, or SQLite? +- **State Management**: Zustand, Context API, Redux, or local React state? + +### Phase 5: SEO, Accessibility (A11y), and Performance +Plan for discoverability and fast loading times: +- **SEO Elements**: Title tag structure, meta descriptions, and semantic HTML tag hierarchy. +- **Accessibility**: ARIA labels, semantic tags, keyboard navigation, and color contrast. +- **Performance**: Preloading assets, lazy loading images, server-side rendering (SSR), and CDN delivery. + +### Phase 6: MVP Scope & Project Phases +Break the work down into manageable increments: +- **Phase 1 (MVP)**: The absolute minimum viable product needed to deploy. +- **Phase 2 (Enhancements)**: Nice-to-have features, micro-animations, and advanced integrations. + +## Examples + +### Interactive Questionnaire Prompt Template +Use this prompt layout when initiating a brainstorming session with a client or team member: + +```markdown +👋 Let's brainstorm your new web project! We will walk through 6 quick phases. + +--- +### Phase 1: Core Concept & Scoping +1. What is the main title or working name of this project? +2. Who are the primary target users (e.g., tech-savvy professionals, shoppers, children)? +3. What are the 3 core tasks a user must be able to perform? +--- +``` + +### Brainstorming Output Document Template +Once all phases are complete, generate a markdown blueprint for the project using this template: + +```markdown +# Project Blueprint: [Project Name] + +## 1. Product Concept +- **Value Proposition**: [Summary] +- **Key Features**: + 1. [Feature 1] + 2. [Feature 2] + +## 2. Information Architecture & UX +- **Pages**: `/index.html`, `/dashboard.html` +- **Primary User Flow**: User signs up -> completes onboarding -> views dashboard. + +## 3. Styling & Aesthetics +- **Aesthetic**: Sleek Glassmorphism Dark Mode +- **Color Tokens**: + - Background: `hsl(222, 47%, 11%)` + - Accent/Primary: `hsl(217, 91%, 60%)` +- **Typography**: Inter (Body), Outfit (Headings) + +## 4. Technical Architecture +- **Framework**: Next.js (App Router) +- **Styling**: Tailwind CSS +- **Database**: PostgreSQL with Prisma ORM + +## 5. SEO & Performance +- **Primary Title**: "[Brand] | [Tagline]" +- **Performance Strategy**: Dynamic image optimization, caching pages via Cloudflare. + +## 6. MVP vs Phase 2 Roadmap +- **MVP**: Authentication + core dashboard view. +- **Phase 2**: Real-time notifications and PDF reporting. +``` + +## Best Practices + +- ✅ Ask questions incrementally—never dump all six phases in a single response to avoid cognitive overload. +- ✅ Propose logical defaults (e.g., recommending responsive Tailwind/CSS Grid and standard semantic HTML) if the user is unsure. +- ✅ Ensure semantic HTML layout hierarchy (one `

` per page, sequential `
`, `
`, `
`, `
` elements) is planned from the start. +- ✅ Document explicit non-goals to prevent feature creep. + +## Limitations + +- This skill focuses on conceptual mapping, architecture, and feature planning; it does not replace the writing of implementation code or system configuration. +- Brainstorming outcomes should be treated as flexible blueprints and refined as technical constraints are discovered during development. + +## Security & Safety Notes + +- During Phase 4 (Architecture), flag any security requirements (e.g., SSL certificates, CORS policies, secure authentication storage, environment variables protection) early. +- Do not store actual API tokens, passwords, or credentials in design or blueprint documents. + +## Common Pitfalls + +- **Problem**: Scope Creep (the project expands too quickly before building an MVP). + **Solution**: Enforce Phase 6 strictly. Push nice-to-have features into Phase 2. +- **Problem**: Ignoring mobile design until late in development. + **Solution**: Brainstorm responsive patterns in Phase 2 before deciding on layout style in Phase 3. + +## Related Skills + +- `@writing-plans` - Organizing structural step-by-step engineering plans. +- `@architecture-decision-records` - Documenting architectural decisions. +- `@ux-flow` - Designing deep user experience flows and interaction details. diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-accessibility-inclusive-ux/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-accessibility-inclusive-ux/.claude-plugin/plugin.json index e2b3eb23..11878a73 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-accessibility-inclusive-ux/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-accessibility-inclusive-ux/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-accessibility-inclusive-ux", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Accessibility & Inclusive UX\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-accessibility-inclusive-ux/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-accessibility-inclusive-ux/.codex-plugin/plugin.json index 8e3ea386..fc223d66 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-accessibility-inclusive-ux/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-accessibility-inclusive-ux/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-accessibility-inclusive-ux", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Accessibility & Inclusive UX\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.claude-plugin/plugin.json index ffa94da5..d13629f9 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-agent-mcp-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Agent & MCP Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.codex-plugin/plugin.json index 90cb0c13..d9f19a15 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-agent-mcp-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-agent-mcp-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Agent & MCP Builder\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-ai-product-evaluation-ops/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-ai-product-evaluation-ops/.claude-plugin/plugin.json index 26a1201d..e61026fc 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-ai-product-evaluation-ops/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-ai-product-evaluation-ops/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-ai-product-evaluation-ops", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS AI Product & Evaluation Ops\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-ai-product-evaluation-ops/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-ai-product-evaluation-ops/.codex-plugin/plugin.json index b1af3090..8048b293 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-ai-product-evaluation-ops/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-ai-product-evaluation-ops/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-ai-product-evaluation-ops", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS AI Product & Evaluation Ops\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-api-platform-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-api-platform-builder/.claude-plugin/plugin.json index 9987473b..8c671266 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-api-platform-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-api-platform-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-api-platform-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS API Platform Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-api-platform-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-api-platform-builder/.codex-plugin/plugin.json index 1fc114c6..5f4dcf71 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-api-platform-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-api-platform-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-api-platform-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS API Platform Builder\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.claude-plugin/plugin.json index 0fc6bf67..36d9b65a 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-automation-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Automation Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.codex-plugin/plugin.json index c1e00f37..8df94b4c 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-automation-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-automation-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Automation Builder\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.claude-plugin/plugin.json index b137abb3..3895128a 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-data-analytics", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Data Analytics\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.codex-plugin/plugin.json index adb1e86a..a3ae3494 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-analytics/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-data-analytics", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Data Analytics\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-engineering-platform/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-engineering-platform/.claude-plugin/plugin.json index 8c14ad12..480019f1 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-engineering-platform/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-engineering-platform/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-data-engineering-platform", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Data Engineering Platform\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-engineering-platform/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-engineering-platform/.codex-plugin/plugin.json index a41eb68e..c416c99f 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-engineering-platform/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-data-engineering-platform/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-data-engineering-platform", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Data Engineering Platform\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.claude-plugin/plugin.json index 1bbc884a..9de4ace8 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-devops-cloud", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS DevOps & Cloud\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.codex-plugin/plugin.json index f78eabdf..7b1c9779 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-devops-cloud/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-devops-cloud", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS DevOps & Cloud\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.claude-plugin/plugin.json index 7fdabd9b..010c864b 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-documents-presentations", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Documents & Presentations\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.codex-plugin/plugin.json index 7e15f401..fe8a1ff0 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-documents-presentations/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-documents-presentations", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Documents & Presentations\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-localization-international-growth/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-localization-international-growth/.claude-plugin/plugin.json index e7925f0b..0bd96a11 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-localization-international-growth/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-localization-international-growth/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-localization-international-growth", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Localization & International Growth\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-localization-international-growth/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-localization-international-growth/.codex-plugin/plugin.json index f2013b66..989f5b69 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-localization-international-growth/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-localization-international-growth/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-localization-international-growth", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Localization & International Growth\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.claude-plugin/plugin.json index bf6a50fe..6864e8df 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-marketing-seo-growth", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Marketing, SEO & Growth\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.codex-plugin/plugin.json index 695edc31..d9999153 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-marketing-seo-growth/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-marketing-seo-growth", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Marketing, SEO & Growth\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.claude-plugin/plugin.json index 86e9f5cb..aaaa0299 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-mobile-app-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Mobile App Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.codex-plugin/plugin.json index 27149857..1d1c8172 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-mobile-app-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-mobile-app-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Mobile App Builder\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.claude-plugin/plugin.json index cf85519f..818dd7b4 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-observability-ir", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Observability IR\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.codex-plugin/plugin.json index b0455a96..189689be 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-observability-ir/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-observability-ir", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Observability IR\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.claude-plugin/plugin.json index 4ff4ff7b..1c658fce 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-oss-maintainer", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS OSS Maintainer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.codex-plugin/plugin.json index 4cf909e7..d82c84c2 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-oss-maintainer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-oss-maintainer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS OSS Maintainer\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-privacy-compliance-engineering/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-privacy-compliance-engineering/.claude-plugin/plugin.json index bd9ba4e1..1fc64a5e 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-privacy-compliance-engineering/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-privacy-compliance-engineering/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-privacy-compliance-engineering", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Privacy & Compliance Engineering\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-privacy-compliance-engineering/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-privacy-compliance-engineering/.codex-plugin/plugin.json index 51f90f11..306ca7f5 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-privacy-compliance-engineering/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-privacy-compliance-engineering/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-privacy-compliance-engineering", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Privacy & Compliance Engineering\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.claude-plugin/plugin.json index 04f69363..3e92dbb1 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-product-design-studio", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Product Design Studio\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.codex-plugin/plugin.json index 5e8edc0d..c220819a 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-product-design-studio/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-product-design-studio", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Product Design Studio\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.claude-plugin/plugin.json index fbe022d3..88496a02 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-python-api-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Python API Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.codex-plugin/plugin.json index 2cf1f63b..16340940 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-python-api-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-python-api-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Python API Builder\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.claude-plugin/plugin.json index 3afc2caa..4c245784 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-qa-test-automation", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS QA & Test Automation\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.codex-plugin/plugin.json index 1ff5c373..ac682256 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-qa-test-automation/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-qa-test-automation", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS QA & Test Automation\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-saas-launch-revenue/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-saas-launch-revenue/.claude-plugin/plugin.json index ea529d76..31153ebe 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-saas-launch-revenue/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-saas-launch-revenue/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-saas-launch-revenue", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS SaaS Launch & Revenue\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-saas-launch-revenue/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-saas-launch-revenue/.codex-plugin/plugin.json index 1f7eec69..76dfe118 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-saas-launch-revenue/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-saas-launch-revenue/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-saas-launch-revenue", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS SaaS Launch & Revenue\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.claude-plugin/plugin.json index 68961554..e5f93084 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-secure-app-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Secure App Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.codex-plugin/plugin.json index 28036863..0e369ea1 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-secure-app-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-secure-app-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Secure App Builder\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.claude-plugin/plugin.json index 35587540..778f3f0e 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-security-engineer", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Security Engineer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.codex-plugin/plugin.json index 76336d3c..ecc9047b 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-security-engineer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-security-engineer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Security Engineer\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.claude-plugin/plugin.json index d063a422..aa34e17f 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-aas-web-app-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"AAS Web App Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.codex-plugin/plugin.json index 9481429f..fdd7b78b 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-aas-web-app-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-aas-web-app-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"AAS Web App Builder\" workflow plugin from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.claude-plugin/plugin.json index 39c5b864..f13467b9 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-agent-architect", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Agent Architect\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.codex-plugin/plugin.json index 129c1bba..e550a0b4 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-agent-architect/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-agent-architect", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Agent Architect\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.claude-plugin/plugin.json index e211f5fe..6a943652 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-apple-platform-design", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Apple Platform Design\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.codex-plugin/plugin.json index 422d8b17..49a5deba 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-apple-platform-design/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-apple-platform-design", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Apple Platform Design\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.claude-plugin/plugin.json index ab249922..981f76b3 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-architecture-design", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Architecture & Design\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.codex-plugin/plugin.json index 192265f5..45893196 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-architecture-design/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-architecture-design", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Architecture & Design\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.claude-plugin/plugin.json index f88e7eca..3b1f8a51 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-automation-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Automation Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.codex-plugin/plugin.json index a2bc3420..e801df58 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-automation-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-automation-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Automation Builder\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.claude-plugin/plugin.json index f6188c35..e2f92d23 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-azure-ai-cloud", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Azure AI & Cloud\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.codex-plugin/plugin.json index 525f647e..cc680b86 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-azure-ai-cloud/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-azure-ai-cloud", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Azure AI & Cloud\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.claude-plugin/plugin.json index 426bf5f5..b965cf3c 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-business-analyst", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Business Analyst\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.codex-plugin/plugin.json index eab147fc..5f7249ab 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-business-analyst/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-business-analyst", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Business Analyst\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.claude-plugin/plugin.json index d1a9c9f1..aab07756 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-commerce-payments", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Commerce & Payments\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.codex-plugin/plugin.json index a5c8a093..460481de 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-commerce-payments/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-commerce-payments", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Commerce & Payments\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.claude-plugin/plugin.json index 10480fc0..9cfa0e84 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-creative-director", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Creative Director\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.codex-plugin/plugin.json index 3b612fbb..c7d6ee52 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-creative-director/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-creative-director", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Creative Director\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.claude-plugin/plugin.json index 771494ce..5680dc93 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-data-analytics", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Data & Analytics\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.codex-plugin/plugin.json index 44b5a113..2d7f1c4d 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-data-analytics/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-data-analytics", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Data & Analytics\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.claude-plugin/plugin.json index 7d04f5da..df8cfe63 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-data-engineering", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Data Engineering\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.codex-plugin/plugin.json index cdaa1a0a..b12c44c7 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-data-engineering/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-data-engineering", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Data Engineering\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.claude-plugin/plugin.json index aa244f59..ed913c98 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-ddd-evented-architecture", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"DDD & Evented Architecture\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.codex-plugin/plugin.json index 4fd904e5..f9d92721 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-ddd-evented-architecture/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-ddd-evented-architecture", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"DDD & Evented Architecture\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.claude-plugin/plugin.json index 6ca04976..6b173e39 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-devops-cloud", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"DevOps & Cloud\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.codex-plugin/plugin.json index d6c0cbf7..ec97ff5d 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-devops-cloud/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-devops-cloud", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"DevOps & Cloud\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.claude-plugin/plugin.json index 9a0e4437..c0717d67 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-documents-presentations", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Documents & Presentations\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.codex-plugin/plugin.json index 06127b3e..29b5fc25 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-documents-presentations/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-documents-presentations", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Documents & Presentations\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.claude-plugin/plugin.json index 92bbba5e..c1e4d7d3 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-essentials", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Essentials\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.codex-plugin/plugin.json index a522ddfd..8167449d 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-essentials/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-essentials", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Essentials\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.claude-plugin/plugin.json index e32fdd42..a6eb2d35 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-expo-react-native", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Expo & React Native\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.codex-plugin/plugin.json index ac7577cd..8c02a75c 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-expo-react-native/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-expo-react-native", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Expo & React Native\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.claude-plugin/plugin.json index 4cff3fbf..f4408045 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-full-stack-developer", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Full-Stack Developer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.codex-plugin/plugin.json index 4f26638c..2cbc09ca 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-full-stack-developer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-full-stack-developer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Full-Stack Developer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.claude-plugin/plugin.json index 750d363a..e627ecd8 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-indie-game-dev", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Indie Game Dev\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.codex-plugin/plugin.json index 9e4f5b75..043bcdb8 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-indie-game-dev/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-indie-game-dev", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Indie Game Dev\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.claude-plugin/plugin.json index 6132c81d..a92125f5 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-integration-apis", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Integration & APIs\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.codex-plugin/plugin.json index e7c0aa68..5818b49f 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-integration-apis/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-integration-apis", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Integration & APIs\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.claude-plugin/plugin.json index 2e1fd5cf..7a4b78a0 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-llm-application-developer", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"LLM Application Developer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.codex-plugin/plugin.json index 56fc3768..5ea7b368 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-llm-application-developer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-llm-application-developer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"LLM Application Developer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.claude-plugin/plugin.json index d8fd5993..ffcc9e2d 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-makepad-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Makepad Builder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.codex-plugin/plugin.json index 8c56e951..ca376d08 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-makepad-builder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-makepad-builder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Makepad Builder\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.claude-plugin/plugin.json index 80e85fc3..51568163 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-marketing-growth", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Marketing & Growth\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.codex-plugin/plugin.json index 480c8459..fa39dcf3 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-marketing-growth/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-marketing-growth", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Marketing & Growth\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.claude-plugin/plugin.json index d31fa6d5..42e39744 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-mobile-developer", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Mobile Developer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.codex-plugin/plugin.json index e070a204..2d6fbd54 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-mobile-developer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-mobile-developer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Mobile Developer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.claude-plugin/plugin.json index 8b1a673f..d5826b18 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-observability-monitoring", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Observability & Monitoring\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.codex-plugin/plugin.json index 5155e743..cf87ee92 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-observability-monitoring/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-observability-monitoring", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Observability & Monitoring\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.claude-plugin/plugin.json index 9140df40..a2e45725 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-odoo-erp", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Odoo ERP\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.codex-plugin/plugin.json index 3b182b28..42ce1037 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-odoo-erp/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-odoo-erp", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Odoo ERP\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.claude-plugin/plugin.json index 6469e243..187826bc 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-oss-maintainer", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"OSS Maintainer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.codex-plugin/plugin.json index 59d8f0af..b0c6cf2a 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-oss-maintainer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-oss-maintainer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"OSS Maintainer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.claude-plugin/plugin.json index 82581eb8..d5da30ab 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-python-pro", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Python Pro\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.codex-plugin/plugin.json index 5ff91a49..91754dd6 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-python-pro/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-python-pro", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Python Pro\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.claude-plugin/plugin.json index 5f67771f..f4b11bbe 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-qa-testing", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"QA & Testing\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.codex-plugin/plugin.json index 2b801d48..ffe1775e 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-qa-testing/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-qa-testing", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"QA & Testing\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.claude-plugin/plugin.json index 3ec4891e..4e19d713 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-revops-crm-automation", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"RevOps & CRM Automation\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.codex-plugin/plugin.json index ca83656b..7a08717a 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-revops-crm-automation/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-revops-crm-automation", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"RevOps & CRM Automation\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.claude-plugin/plugin.json index 530fe851..d5e69ca0 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-security-developer", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Security Developer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.codex-plugin/plugin.json index bd2a4e38..d4c1a612 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-security-developer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-security-developer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Security Developer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.claude-plugin/plugin.json index f15e805a..10818bef 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-security-engineer", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Security Engineer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.codex-plugin/plugin.json index 165f49d4..ed35a1ae 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-security-engineer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-security-engineer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Security Engineer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.claude-plugin/plugin.json index 74d6c0fa..484ae97d 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-seo-specialist", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"SEO Specialist\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.codex-plugin/plugin.json index 1fa85b18..a8f3fe70 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-seo-specialist/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-seo-specialist", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"SEO Specialist\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.claude-plugin/plugin.json index 4feda5e6..1e417f6e 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-startup-founder", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Startup Founder\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.codex-plugin/plugin.json index 381ddefa..bcce3106 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-startup-founder/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-startup-founder", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Startup Founder\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.claude-plugin/plugin.json index c63fd73b..b581dfbe 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-systems-programming", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Systems Programming\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.codex-plugin/plugin.json index 5c4da3d0..58b35e3f 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-systems-programming/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-systems-programming", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Systems Programming\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.claude-plugin/plugin.json index 8ba90a36..afae8df9 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-typescript-javascript", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"TypeScript & JavaScript\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.codex-plugin/plugin.json index 44ad7ece..afe977c7 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-typescript-javascript/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-typescript-javascript", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"TypeScript & JavaScript\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.claude-plugin/plugin.json index 6bdc341e..9aab7d23 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-web-designer", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Web Designer\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.codex-plugin/plugin.json index 38f01ab5..e59394d1 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-web-designer/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-web-designer", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Web Designer\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.claude-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.claude-plugin/plugin.json index e7721031..b91c21fa 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.claude-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "antigravity-bundle-web-wizard", - "version": "13.3.0", + "version": "13.4.0", "description": "Editorial \"Web Wizard\" bundle for Claude Code from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.codex-plugin/plugin.json b/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.codex-plugin/plugin.json index 64f49ff0..4b80d3eb 100644 --- a/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.codex-plugin/plugin.json +++ b/antigravity-awesome-skills/plugins/antigravity-bundle-web-wizard/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agyb-web-wizard", - "version": "13.3.0", + "version": "13.4.0", "description": "Install the \"Web Wizard\" editorial skill bundle from Antigravity Awesome Skills.", "author": { "name": "sickn33 and contributors", diff --git a/antigravity-awesome-skills/skills/ai-loop/SKILL.md b/antigravity-awesome-skills/skills/ai-loop/SKILL.md new file mode 100644 index 00000000..f849df8f --- /dev/null +++ b/antigravity-awesome-skills/skills/ai-loop/SKILL.md @@ -0,0 +1,136 @@ +--- +name: ai-loop +description: Runs a bounded spec-build-review development loop with explicit scope, stop conditions, and human approval gates for risky or ambiguous work. +category: workflow +risk: safe +source: community +date_added: "2026-06-27" +tags: [agent-workflow, specification, implementation, review, verification, feedback-loop] +tools: [claude, cursor, codex, gemini] +--- + +# AI-Loop Skill + +## Overview + +The `ai-loop` skill structures a bounded development cycle for agentic workflows. By dividing the process into distinct planning (Spec), implementation (Build), and validation (Review) phases, it helps an agent build and correct scoped code changes while keeping requirements, risk gates, and stop conditions explicit. + +## When to Use This Skill + +- Use when you need a feature built from scratch or heavily modified, and you want the agent to handle the lifecycle (specification, implementation, and verification) inside one clearly bounded workflow. +- Use when working with isolated components, modules, or features that have well-defined scopes and constraints. +- Use when the user asks for a complete development pass but the work still has clear success criteria, a reasonable verification path, and no unresolved safety or product decisions. + +## How It Works + +This skill executes a controlled development loop composed of three phases: Spec, Build, and Review. When invoked, the agent moves through those phases until the scoped requirements pass verification, a stop condition is reached, or human approval is needed. + +Before starting, define: + +- The maximum number of build-review iterations. +- The verification commands or manual checks that count as evidence. +- The actions that require explicit approval, such as destructive commands, production changes, external service writes, or broad architectural pivots. + +### Phase 1: Spec (Planning) + +1. Interview the user about the feature or app they want to build. Ask one focused question at a time until you fully understand the goal, the must-have requirements, the constraints, and what "done" looks like. +2. **Do not start building yet.** +3. When you have enough information, write a clear, detailed specification and save it to `specs/.md`. +4. The spec must include: + - The objective + - The exact requirements + - Edge cases to handle + - A concrete definition of done that someone could check the build against + - The iteration budget, verification commands, and approval gates. + +### Phase 2: Build (Implementation) + +1. Read the spec you just created in `specs/.md`. +2. Build exactly what it describes. +3. **Do not add features**, do not refactor unrelated code, and do not invent requirements that aren't in the spec. +4. Focus strictly on fulfilling the spec. List which spec requirements you covered so the review step can check them. + +### Phase 3: Review (Verification) + +1. Compare your implementation against `specs/.md`. +2. Go requirement by requirement and verify if it was met. List every gap, bug, or missing piece, naming the exact spec item each one fails. +3. If anything fails and the iteration budget is not exhausted, write the specific fixes needed and **loop back to Phase 2 (Build)** to address them. +4. Stop and ask for human input when the next fix would change the spec, exceed the iteration budget, require risky operations, or depend on product decisions not captured in the spec. +5. Only pass the build and conclude the skill execution when every requirement in the spec is fully met and the declared verification evidence has passed. + +## Examples + +### Example 1: Creating a Basic Statistics Helper + +**User:** +> I want to add a utility for calculating basic statistics (mean, median, mode) of an array of numbers. + +**Agent (Phase 1 - Spec):** +> I can help with that. To get started, what programming language should this statistics calculator be implemented in? Also, how should empty arrays or invalid inputs be handled? + +**User:** +> JavaScript. If the array is empty, return null. If there are non-numbers, ignore them. + +**Agent (Phase 1 - Spec):** +> Thank you. I have created the specification file at `specs/stats-calculator.md` with the requirements we discussed. Now, I will start implementing it. + +**Agent (Phase 2 - Build):** +> *(Creates `stats_calculator.js` and implements `mean`, `median`, and `mode` matching the spec exactly)* +> I have finished implementing the calculator. I will now verify the implementation. + +**Agent (Phase 3 - Review):** +> Checking implementation against `specs/stats-calculator.md`: +> - Requirement: mean calculation -> PASS +> - Requirement: median calculation -> PASS +> - Requirement: mode calculation -> PASS +> - Requirement: empty array returns null -> PASS +> - Requirement: non-numbers are ignored -> FAIL (I noticed `mode` doesn't filter out non-numbers). +> +> I will now loop back to Phase 2 to fix the `mode` function. + +**Agent (Phase 2 - Build Loop-Back):** +> *(Fixes `mode` to filter out non-numbers)* +> I have updated the implementation. Let's re-verify. + +**Agent (Phase 3 - Review):** +> - Requirement: mode filters non-numbers -> PASS +> +> All requirements passed! The statistics calculator is complete and verified. + +## Best Practices + +- ✅ Do ask clarifying questions one at a time to avoid overwhelming the user during the planning phase. +- ✅ Do document edge cases explicitly in `specs/.md` before writing any code. +- ✅ Do stick strictly to the approved specification during the build phase. +- ✅ Do cap the loop with a small iteration budget and report exactly what remains if the budget is exhausted. +- ✅ Do pause for explicit approval before destructive, production, credentialed, or externally visible actions. +- ❌ Don't implement extra features or perform unrelated refactorings that aren't specified. +- ❌ Don't skip the review phase or pass it without verifying every single requirement. +- ❌ Don't keep retrying the same failing fix without new evidence or a changed approach. + +## Limitations + +- This skill requires sufficient context about the feature to be provided during the Spec phase. +- It is best suited for isolated features or tasks with clear boundaries, rather than open-ended architectural refactoring. +- The review phase relies on the agent's self-assessment against the generated spec; manual review is still recommended for critical systems. +- It is not a replacement for human approval on security-sensitive, destructive, production, compliance, or externally visible changes. +- It should stop rather than continue if requirements conflict, tests cannot run, or verification depends on unavailable credentials or systems. + +## Security & Safety Notes + +- Be cautious when running or testing code generated during the Build phase. Always run tests in a safe, sandboxed environment. +- Avoid executing arbitrary shell commands provided directly by the user without validating their safety. +- Make sure no hardcoded secrets, keys, or credentials are added to the code or specifications. +- Treat production deploys, data migrations, payment flows, credential changes, and external write actions as approval-gated work. + +## Common Pitfalls + +- **Problem:** The agent tries to build a huge system all at once, leading to an overcomplicated spec and incomplete implementation. + **Solution:** Keep the scope of `ai-loop` to small, modular features. Break larger systems into multiple independent loops. +- **Problem:** The spec is vague, causing the build phase to rely on assumptions. + **Solution:** Spend extra time in the planning phase asking targeted questions to pin down requirements. + +## Related Skills + +- `@plan-writing` - For writing more detailed implementation plans for larger projects. +- `@ask-questions-if-underspecified` - For standard guidelines on interviewing the user. diff --git a/antigravity-awesome-skills/skills/cron-doctor/SKILL.md b/antigravity-awesome-skills/skills/cron-doctor/SKILL.md new file mode 100644 index 00000000..48eec6f8 --- /dev/null +++ b/antigravity-awesome-skills/skills/cron-doctor/SKILL.md @@ -0,0 +1,244 @@ +--- +name: cron-doctor +description: "Diagnose and validate cron expressions before they ship. Catches the five silent death-traps: impossible dates that never fire, OR-semantics that fire too often, midnight spikes, uneven step drift, and leap-year February 29." +category: devops +risk: safe +source: community +source_repo: takeaseatventure/devops-skills +source_type: community +date_added: "2026-06-26" +author: takeaseat +tags: [cron, crontab, scheduling, devops, debugging, kubernetes, validation] +tools: [claude, cursor, codex, gemini, opencode] +license: "MIT" +license_source: "https://github.com/takeaseatventure/devops-skills/blob/main/LICENSE" +--- + +# cron-doctor + +## Overview + +Cron is deceptively error-prone. The failure mode is **silent** — a syntactically +valid expression that simply never fires, or fires far more often than intended. +`0 0 30 2 *` parses cleanly and then sits dead forever (February has no 30th). +`0 0 1,15 * 1` looks like "1st and 15th if Monday" but actually means "1st, 15th, +**OR** every Monday" — ~6 fires/month instead of ~2. + +This skill teaches an agent to catch those before they reach production. It comes +with a zero-dependency validation engine (`scripts/cron-engine.js`, no install +needed) that parses, describes, deep-validates, and computes next fire times. + +## When to Use This Skill + +- Use when a user writes, edits, reviews, or deploys a cron expression — in a + crontab, a Kubernetes `CronJob`, a GitHub Actions `schedule`, an Airflow DAG, + a Celery beat schedule, a systemd timer, or any scheduled task. +- Use when debugging a job that "didn't fire" or "fired at the wrong time." +- Use when a user asks "what does this cron expression mean?" or "when will this + run next?" or "how often does this run per year?" +- Use when reviewing a CI/CD pipeline or infrastructure config that contains a + `schedule` field. +- Use when a user pastes a 5-field cron expression and asks for a sanity check. + +## How It Works + +### Step 1: Parse the expression + +Split on whitespace into 5 fields: minute, hour, day-of-month, month, day-of-week. +Confirm valid ranges: + +| Field | Position | Range | Notes | +|-------|----------|-------|-------| +| minute | 1 | 0–59 | | +| hour | 2 | 0–23 | | +| day-of-month | 3 | 1–31 | | +| month | 4 | 1–12 | names (JAN–DEC) accepted | +| day-of-week | 5 | 0–7 | 0 and 7 both = Sunday; names (SUN–SAT) accepted | + +### Step 2: Describe it in plain English + +State what the user *thinks* it does vs. what it *actually* does. Be explicit +about OR-vs-AND semantics for day-of-month + day-of-week (see death-trap #2). + +### Step 3: Run the trap checklist + +Check the five death-traps below and flag any that apply. + +### Step 4: Calculate next runs and annual fire count + +Compute the next 5 fire times as concrete dates so the user can verify the +schedule behaves as expected. Estimate annual fire count — a schedule that fires +365×/year vs. 12×/year is a ~30× cost and load difference. + +## The Five Cron Death-Traps + +These are the bugs that pass `crontab -l` validation but break in production. + +### 1. Impossible dates — the "never fires" bug + +``` +0 0 30 2 * +``` + +**Valid syntax. Never fires.** February has no 30th. This schedule is a dead job +that silently sits forever. The same applies to day 31 in any 30-day month: +`0 0 31 4 *`, `0 0 31 6 *`, `0 0 31 9 *`, `0 0 31 11 *`. + +**Fix:** use `0 0 28-31 * *` and check for end-of-month in the script, or use `L` +(last day) syntax if your scheduler supports it. + +### 2. OR-semantics — the "fires too often" bug + +``` +0 0 1,15 * 1 +``` + +**Does NOT mean** "midnight on the 1st and 15th if it's Monday." +**Does mean** "midnight on the 1st, the 15th, **OR** every Monday." That's ~6 +fires/month instead of ~2. + +This is the single most misunderstood cron rule. When **both** day-of-month AND +day-of-week are restricted (neither is `*`), cron uses OR logic, not AND. + +**Fix:** if you need "1st and 15th only if Monday," run daily and check in the +script: + +```bash +0 0 * * 1 [ "$(date +%d)" = "01" -o "$(date +%d)" = "15" ] && your-command +``` + +### 3. Midnight spike — the "everything at once" bug + +``` +0 0 * * * +``` + +Every job scheduled at `0 0` competes for resources at exactly 00:00. Database +backups, log rotations, cert renewals, report generation — all fire simultaneously. +This causes load spikes, connection-pool exhaustion, and cascading timeouts. + +**Fix:** stagger jobs across the hour. Use `17 2 * * *` or `43 3 * * *` instead of +`0 0`. Jitter is your friend. + +### 4. Uneven steps — the "drift" bug + +``` +*/7 * * * * +``` + +**Does NOT mean** "every 7 minutes evenly." It means "every 7 minutes starting at +0, then resets at 60." So: 0, 7, 14, 21, 28, 35, 42, 49, 56 — then 0 again +(a 4-minute gap). The intervals drift: 7,7,7,7,7,7,7,7,**4**. + +**Fix:** 60 is not divisible by 7. Use step values that divide 60 evenly: `*/5`, +`*/10`, `*/15`, `*/20`, `*/30`. If you truly need every-7-minutes, use a loop with +`sleep 420`. + +### 5. Leap-year February 29 — the "annual surprise" + +``` +0 0 29 2 * +``` + +Fires only on leap years — February 29, 2024 / 2028 / 2032… If someone writes this +expecting "end of February," they'll be confused for 3 out of every 4 years. + +**Fix:** use `0 0 28 2 *` and handle the 29th case in the script if needed. + +## Using the validation script + +This skill ships a zero-dependency engine at `scripts/cron-engine.js` (Node.js, no +`npm install` needed). You can use it programmatically or from the CLI: + +```javascript +// Programmatic — Node.js, zero dependencies +const { describe, validate, nextRuns, formatNextRuns } = require('./scripts/cron-engine.js'); + +// Parse + describe -> returns { text, error, parsed } +const d = describe('0 0 30 2 *'); +console.log(d.text); // "At 00:00, on day-of-month 30 in in FEB" + +// Deep validation -> catches the traps +const result = validate('0 0 30 2 *'); +console.log(result.valid); // true (syntax is valid) +console.log(result.observations); // includes the "never fires" insight +console.log(result.suggestions); // e.g. "Midnight is a common spike..." + +// Next 5 fire times -> returns Date[] +const runs = nextRuns('0 9 * * 1-5', new Date(), 5); +console.log(formatNextRuns(runs, new Date())); // [{ date, relative, formatted }, ...] +``` + +```bash +# CLI (via the bundled wrapper) +node scripts/cli.js describe "*/5 * * * *" +node scripts/cli.js validate "0 0 30 2 *" +node scripts/cli.js next "0 9 * * 1-5" 5 +``` + +## Common cron presets + +| Expression | Description | Use case | +|-----------|-------------|----------| +| `*/5 * * * *` | Every 5 minutes | Health checks, polling | +| `0 * * * *` | Every hour | Hourly aggregation | +| `0 */2 * * *` | Every 2 hours | Semi-frequent sync | +| `0 9 * * 1-5` | 9am Mon–Fri | Business-hours task | +| `0 2 * * *` | 2am daily | Off-peak batch (avoid midnight) | +| `0 0 * * 0` | Midnight Sunday | Weekly maintenance | +| `0 0 1 * *` | Midnight 1st of month | Monthly report | +| `0 0 1 1 *` | Midnight Jan 1st | Annual task | + +## Best Practices + +- ✅ Always provide the plain-English description AND run the trap checklist. +- ✅ Stagger midnight jobs to avoid the spike. +- ✅ Prefer step values that divide 60 evenly (`*/5`, `*/15`, `*/30`). +- ✅ Add a comment above every crontab line explaining intent. +- ✅ Set an explicit timezone (`CRON_TZ`) on schedulers that support it. +- ❌ Don't trust `crontab -l` validation — it only checks syntax, not semantics. +- ❌ Don't restrict both day-of-month and day-of-week without confirming OR-logic. +- ❌ Don't schedule everything at `0 0`. + +## Common Pitfalls + +- **Problem:** "My cron job isn't running." + **Solution:** Check for an impossible date (trap #1) and confirm the daemon is + running (`service cron status` / `systemctl status crond`). Verify the file + ends with a newline and has correct ownership. + +- **Problem:** "My job runs far more often than expected." + **Solution:** You hit OR-semantics (trap #2). If both day-of-month and + day-of-week are set, cron ORs them. Move one to `*` or guard in-script. + +- **Problem:** "Intervals are uneven — sometimes 7 min, sometimes 4." + **Solution:** Step value doesn't divide 60 evenly (trap #4). Use a divisor of 60. + +- **Problem:** "My job works locally but not in the cluster." + **Solution:** Timezone mismatch. Kubernetes `CronJob` and GitHub Actions default + to UTC. Confirm `timeZone` / `TZ` is set as intended. + +## Limitations + +- This skill targets standard 5-field cron as implemented by Vixie cron, systemd + timers, Kubernetes `CronJob`, GitHub Actions `schedule`, and most libraries. It + does **not** validate Quartz 6/7-field expressions with seconds/years, nor + non-standard `@reboot` / `L` / `#` extensions without a note. +- Estimated annual fire counts assume a non-leap reference year; February 29 + schedules (trap #5) are flagged explicitly. +- This skill does not replace environment-specific validation, testing, or expert + review. Stop and ask for clarification if required inputs, permissions, or + safety boundaries are missing. + +## Related Skills + +- `docker-expert` — when the cron job runs inside a container and the issue is the + container/entrypoint rather than the schedule. +- `kubernetes-deployment` — when validating a `CronJob` manifest's `spec.schedule` + field alongside the broader resource config. + +## Security & Safety Notes + +This skill is read-only and `risk: safe`. The validation script performs no file +writes, network calls, or mutations — it only parses and computes. It is safe to +run against any cron expression without preconditions. diff --git a/antigravity-awesome-skills/skills/cron-doctor/scripts/cli.js b/antigravity-awesome-skills/skills/cron-doctor/scripts/cli.js new file mode 100644 index 00000000..b0ac6905 --- /dev/null +++ b/antigravity-awesome-skills/skills/cron-doctor/scripts/cli.js @@ -0,0 +1,75 @@ +#!/usr/bin/env node +'use strict'; + +// Minimal CLI wrapper for cron-engine.js. Zero dependencies. +// Usage: +// node cli.js describe "" +// node cli.js validate "" +// node cli.js next "" [count] + +const cron = require('./cron-engine.js'); +const expr = process.argv[3]; +const cmd = process.argv[2]; + +if (!cmd || !expr) { + console.error('Usage: node cli.js "" [count]'); + console.error('Examples:'); + console.error(' node cli.js describe "*/5 * * * *"'); + console.error(' node cli.js validate "0 0 30 2 *"'); + console.error(' node cli.js next "0 9 * * 1-5" 5'); + process.exit(2); +} + +function safe(fn) { + try { + fn(); + } catch (e) { + console.error('Error: ' + (e.message || e)); + process.exit(1); + } +} + +switch (cmd) { + case 'describe': + safe(() => { + const d = cron.describe(expr); + console.log(d.text || d.description || JSON.stringify(d)); + }); + break; + + case 'validate': + safe(() => { + const r = cron.validate(expr); + console.log('valid: ' + r.valid); + if (r.description) console.log('description: ' + r.description); + if (r.warnings && r.warnings.length) { + console.log('warnings:'); + r.warnings.forEach((w) => console.log(' - ' + w)); + } + if (r.observations && r.observations.length) { + console.log('observations:'); + r.observations.forEach((o) => console.log(' [' + (o.level || 'info') + '] ' + o.message)); + } + if (r.suggestions && r.suggestions.length) { + console.log('suggestions:'); + r.suggestions.forEach((s) => console.log(' [' + (s.level || 'info') + '] ' + s.message)); + } + }); + break; + + case 'next': + safe(() => { + const count = parseInt(process.argv[4] || '5', 10); + const runs = cron.nextRuns(expr, new Date(), count); + const formatted = cron.formatNextRuns(runs, new Date()); + formatted.forEach((f) => + console.log(f.relative + '\t' + f.formatted + '\t' + f.date.toString()) + ); + }); + break; + + default: + console.error('Unknown command: ' + cmd); + console.error('Commands: describe, validate, next'); + process.exit(2); +} diff --git a/antigravity-awesome-skills/skills/cron-doctor/scripts/cron-engine.js b/antigravity-awesome-skills/skills/cron-doctor/scripts/cron-engine.js new file mode 100644 index 00000000..07254dee --- /dev/null +++ b/antigravity-awesome-skills/skills/cron-doctor/scripts/cron-engine.js @@ -0,0 +1,638 @@ +'use strict'; + +// ============================================================================ +// cron.js — Cron expression parser, describer, validator, and next-run engine. +// Zero dependencies. Extracted from the DevRef Cron Expression Generator +// (battle-tested in browser) and extended with validate() for Pro insights. +// ============================================================================ + +const MONTH_NAMES = ['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC']; +const DAY_NAMES = ['SUN','MON','TUE','WED','THU','FRI','SAT']; + +const FIELDS = [ + { name: 'minute', min: 0, max: 59, key: 'minute' }, + { name: 'hour', min: 0, max: 23, key: 'hour' }, + { name: 'dom', min: 1, max: 31, key: 'dom' }, + { name: 'month', min: 1, max: 12, key: 'month', named: MONTH_NAMES }, + { name: 'dow', min: 0, max: 7, key: 'dow', named: DAY_NAMES }, +]; + +class CronError extends Error { + constructor(message, fieldIndex) { + super(message); + this.name = 'CronError'; + this.fieldIndex = fieldIndex; + } +} + +// ---- Name resolution ---- +function resolveName(token, names) { + if (!names) return null; + const up = token.toUpperCase(); + const idx = names.indexOf(up); + return idx === -1 ? null : idx; +} + +// ---- Field parsing ---- +function parseField(raw, fieldDef, fieldIndex) { + const trimmed = String(raw).trim(); + if (trimmed === '') throw new CronError(`Field ${fieldIndex + 1} (${fieldDef.name}) is empty`, fieldIndex); + + const out = { raw: trimmed, values: null, special: null }; + + // Special: day-of-week "#" (nth weekday) + if (fieldDef.key === 'dow' && trimmed.includes('#')) { + const m = trimmed.match(/^([0-7A-Za-z]+)#([1-5])$/); + if (!m) throw new CronError(`Invalid "#" syntax in day-of-week: "${trimmed}"`, fieldIndex); + let dowNum = parseSingleNum(m[1], fieldDef, fieldIndex); + if (dowNum === 7) dowNum = 0; + out.special = { kind: 'hash', dow: dowNum, nth: parseInt(m[2], 10) }; + return out; + } + + // Special: day-of-week "L" (last weekday) + if (fieldDef.key === 'dow' && /L$/i.test(trimmed)) { + const m = trimmed.match(/^([0-7A-Za-z]+)L$/i); + if (!m) throw new CronError(`Invalid "L" syntax in day-of-week: "${trimmed}"`, fieldIndex); + let dowNum = parseSingleNum(m[1], fieldDef, fieldIndex); + if (dowNum === 7) dowNum = 0; + out.special = { kind: 'dowLast', dow: dowNum }; + return out; + } + + // Special: day-of-month "L" (last day) + if (fieldDef.key === 'dom' && /^L/i.test(trimmed)) { + const m = trimmed.match(/^L(?:-(\d+))?$/i); + if (!m) throw new CronError(`Invalid "L" syntax in day-of-month: "${trimmed}"`, fieldIndex); + out.special = { kind: 'domLast', offset: m[1] ? parseInt(m[1], 10) : 0 }; + return out; + } + + // Special: day-of-month "W" (nearest weekday) + if (fieldDef.key === 'dom' && /W$/i.test(trimmed)) { + const m = trimmed.match(/^(\d+)W$/i); + if (!m) throw new CronError(`Invalid "W" syntax in day-of-month: "${trimmed}"`, fieldIndex); + const day = parseInt(m[1], 10); + if (day < fieldDef.min || day > fieldDef.max) { + throw new CronError(`Day-of-month "${day}W" out of range (${fieldDef.min}-${fieldDef.max})`, fieldIndex); + } + out.special = { kind: 'weekday', day: day }; + return out; + } + + // Standard parsing + const values = new Set(); + const items = trimmed.split(','); + for (const item of items) { + parseItem(item, fieldDef, fieldIndex, values); + } + out.values = values; + return out; +} + +function parseSingleNum(token, fieldDef, fieldIndex) { + const n = parseInt(token, 10); + if (!isNaN(n)) return n; + const named = resolveName(token, fieldDef.named); + if (named !== null) { + return fieldDef.key === 'month' ? named + 1 : named; + } + throw new CronError(`Invalid value "${token}" in ${fieldDef.name}`, fieldIndex); +} + +function parseItem(item, fieldDef, fieldIndex, values) { + const t = item.trim(); + if (t === '') throw new CronError(`Empty item in ${fieldDef.name}`, fieldIndex); + + if (t === '*') { + addRange(values, fieldDef.min, fieldDef.max, fieldDef); + return; + } + + if (t.includes('/')) { + const [base, stepStr] = t.split('/'); + const step = parseInt(stepStr, 10); + if (isNaN(step) || step < 1) throw new CronError(`Invalid step "${stepStr}" in ${fieldDef.name}`, fieldIndex); + let lo, hi; + if (base === '*' || base === '') { + lo = fieldDef.min; hi = fieldDef.max; + } else if (base.includes('-')) { + const [a, b] = base.split('-'); + lo = parseSingleNum(a.trim(), fieldDef, fieldIndex); + hi = parseSingleNum(b.trim(), fieldDef, fieldIndex); + } else { + lo = parseSingleNum(base.trim(), fieldDef, fieldIndex); + hi = fieldDef.max; + } + if (lo > hi) [lo, hi] = [hi, lo]; + for (let v = lo; v <= hi; v += step) addOne(values, v, fieldDef, fieldIndex); + return; + } + + if (t.includes('-')) { + const parts = t.split('-'); + if (parts.length !== 2) throw new CronError(`Invalid range "${t}" in ${fieldDef.name}`, fieldIndex); + const a = parseSingleNum(parts[0].trim(), fieldDef, fieldIndex); + const b = parseSingleNum(parts[1].trim(), fieldDef, fieldIndex); + addRange(values, a, b, fieldDef); + return; + } + + const v = parseSingleNum(t, fieldDef, fieldIndex); + addOne(values, v, fieldDef, fieldIndex); +} + +function addOne(values, v, fieldDef, fieldIndex) { + if (fieldDef.key === 'dow' && v === 7) { values.add(0); return; } + if (v < fieldDef.min || v > fieldDef.max) { + throw new CronError(`Value ${v} out of range for ${fieldDef.name} (${fieldDef.min}-${fieldDef.max})`, fieldIndex); + } + values.add(v); +} + +function addRange(values, lo, hi, fieldDef) { + if (lo > hi) [lo, hi] = [hi, lo]; + if (lo < fieldDef.min || hi > fieldDef.max) { + throw new CronError(`Range ${lo}-${hi} out of bounds for ${fieldDef.name} (${fieldDef.min}-${fieldDef.max})`, -1); + } + for (let v = lo; v <= hi; v++) { + if (fieldDef.key === 'dow' && v === 7) { values.add(0); continue; } + values.add(v); + } +} + +// ---- Full expression parser ---- +function parseCron(expr) { + const parts = String(expr).trim().split(/\s+/); + if (parts.length !== 5) { + throw new CronError(`Expected 5 fields (got ${parts.length}). Format: minute hour day-of-month month day-of-week`, -1); + } + const parsed = {}; + for (let i = 0; i < 5; i++) { + parsed[FIELDS[i].key] = parseField(parts[i], FIELDS[i], i); + } + parsed.domRestricted = !/^\s*\*\s*$/.test(parts[2]); + parsed.dowRestricted = !/^\s*\*\s*$/.test(parts[4]); + parsed.parts = parts; + return parsed; +} + +// ---- Human-readable description ---- +function describe(expr) { + let parsed; + try { parsed = parseCron(expr); } catch (e) { return { text: e.message, error: true }; } + return { text: describeParsed(parsed), error: false, parsed }; +} + +function describeParsed(p) { + const monthDesc = describeFieldMonth(p.month); + const domDesc = describeFieldDom(p.dom); + const dowDesc = describeFieldDow(p.dow); + + const isEveryMin = p.parts[0] === '*'; + const isEveryHour = p.parts[1] === '*'; + + let timePart = ''; + if (isEveryMin && isEveryHour) { + timePart = 'At every minute'; + } else if (isEveryMin && !isEveryHour) { + const hours = [...(p.hour.values || [])].sort((a, b) => a - b); + if (hours.length > 0) { + timePart = 'Every minute during the ' + hours.map(h => pad2(h)).join(', ') + ' hour' + (hours.length > 1 ? 's' : ''); + } else { + timePart = 'Every minute'; + } + } else { + timePart = 'At ' + describeTimes(p.minute, p.hour); + } + + let dayPart = ''; + const domAny = !p.domRestricted; + const dowAny = !p.dowRestricted; + + if (domAny && dowAny) { + if (monthDesc.restricted) { + dayPart = ', ' + monthDesc.text + ' of every year'; + } else { + dayPart = ', every day'; + } + } else if (!domAny && dowAny) { + dayPart = ', on ' + domDesc.text; + if (monthDesc.restricted) dayPart += ' in ' + monthDesc.text; + } else if (domAny && !dowAny) { + dayPart = ', on ' + dowDesc.text; + if (monthDesc.restricted) dayPart += ' in ' + monthDesc.text; + } else { + dayPart = ', on ' + domDesc.text + ' and on ' + dowDesc.text; + if (monthDesc.restricted) dayPart += ' in ' + monthDesc.text; + } + + return capitalize(timePart + dayPart); +} + +function describeTimes(minuteField, hourField) { + const mins = [...(minuteField.values || [])].sort((a, b) => a - b); + const hours = [...(hourField.values || [])].sort((a, b) => a - b); + + if (pIsWildcard(hourField) && !pIsWildcard(minuteField)) { + if (mins.length === 1) return `minute ${mins[0]} of every hour`; + return `minutes ${listJoin(mins)} of every hour`; + } + if (pIsWildcard(minuteField) && pIsWildcard(hourField)) return 'every minute of every hour'; + + if (pIsWildcard(minuteField)) { + return `every minute during the ${hours.map(h => pad2(h)).join(', ')} hour${hours.length > 1 ? 's' : ''}`; + } + + const combos = []; + for (const h of hours) { + for (const m of mins) { + combos.push(formatHM(h, m)); + } + } + return listJoin(combos); +} + +function describeFieldMonth(field) { + if (pIsWildcard(field)) return { restricted: false, text: 'every month' }; + const vals = [...(field.values || [])].sort((a, b) => a - b); + return { restricted: true, text: 'in ' + listJoin(vals.map(v => capitalize(MONTH_NAMES[v - 1]))) }; +} + +function describeFieldDom(field) { + if (pIsWildcard(field)) return { text: 'every day-of-month' }; + if (field.special) { + if (field.special.kind === 'domLast') { + return { text: field.special.offset === 0 ? 'the last day of the month' : `the last day of the month minus ${field.special.offset} days` }; + } + if (field.special.kind === 'weekday') { + return { text: `the nearest weekday to day ${field.special.day}` }; + } + } + const vals = [...(field.values || [])].sort((a, b) => a - b); + return { text: `day-of-month ${listJoin(vals)}` }; +} + +function describeFieldDow(field) { + if (pIsWildcard(field)) return { text: 'every day-of-week' }; + if (field.special) { + if (field.special.kind === 'hash') { + return { text: `the ${ordinal(field.special.nth)} ${capitalize(DAY_NAMES[field.special.dow])} of the month` }; + } + if (field.special.kind === 'dowLast') { + return { text: `the last ${capitalize(DAY_NAMES[field.special.dow])} of the month` }; + } + } + const vals = [...(field.values || [])].sort((a, b) => a - b); + return { text: listJoin(vals.map(v => capitalize(DAY_NAMES[v]))) }; +} + +function pIsWildcard(field) { return field.raw === '*'; } + +// ---- Next run calculator ---- +function nextRuns(expr, fromDate, count) { + count = count || 10; + const p = parseCron(expr); + const runs = []; + let d = new Date(fromDate.getTime()); + d.setSeconds(0, 0); + d = new Date(d.getTime() + 60000); + + let maxScan = 600000; // ~416 days ceiling + while (runs.length < count && maxScan-- > 0) { + if (matches(d, p)) { + runs.push(new Date(d.getTime())); + } + d = new Date(d.getTime() + 60000); + } + return runs; +} + +function matches(d, p) { + if (!p.minute.values || !p.minute.values.has(d.getMinutes())) return false; + if (!p.hour.values || !p.hour.values.has(d.getHours())) return false; + if (!p.month.values || !p.month.values.has(d.getMonth() + 1)) return false; + + const domAny = !p.domRestricted; + const dowAny = !p.dowRestricted; + + let domMatch = false, dowMatch = false; + if (domAny) { + domMatch = true; + } else if (p.dom.special) { + domMatch = matchDomSpecial(d, p.dom.special); + } else if (p.dom.values && p.dom.values.has(d.getDate())) { + domMatch = true; + } + if (dowAny) { + dowMatch = true; + } else if (p.dow.special) { + dowMatch = matchDowSpecial(d, p.dow.special); + } else if (p.dow.values) { + dowMatch = p.dow.values.has(d.getDay()); + } + + if (domAny && dowAny) return true; + if (!domAny && !dowAny) return domMatch || dowMatch; // OR semantics + return domMatch && dowMatch; +} + +function matchDomSpecial(d, special) { + if (special.kind === 'domLast') { + const lastDay = lastDayOfMonth(d.getFullYear(), d.getMonth()); + const target = special.offset === 0 ? lastDay : lastDay - special.offset; + return d.getDate() === target; + } + if (special.kind === 'weekday') { + return d.getDate() === nearestWeekday(d.getFullYear(), d.getMonth(), special.day); + } + return false; +} + +function matchDowSpecial(d, special) { + if (special.kind === 'hash') { + return nthWeekdayMatches(d, special.dow, special.nth); + } + if (special.kind === 'dowLast') { + return lastWeekdayMatches(d, special.dow); + } + return false; +} + +function nthWeekdayMatches(d, dow, nth) { + if (d.getDay() !== dow) return false; + const dayOfMonth = d.getDate(); + const occurrence = Math.ceil(dayOfMonth / 7); + return occurrence === nth; +} + +function lastWeekdayMatches(d, dow) { + if (d.getDay() !== dow) return false; + const lastDay = lastDayOfMonth(d.getFullYear(), d.getMonth()); + return d.getDate() + 7 > lastDay; +} + +function lastDayOfMonth(year, month) { + return new Date(year, month + 1, 0).getDate(); +} + +function nearestWeekday(year, month, day) { + const lastDay = lastDayOfMonth(year, month); + const target = Math.min(day, lastDay); + const dt = new Date(year, month, target); + const wd = dt.getDay(); + let result = target; + if (wd === 0) { + if (target + 1 <= lastDay) result = target + 1; + else result = target - 2; + } else if (wd === 6) { + if (target - 1 >= 1) result = target - 1; + else result = target + 2; + } + return result; +} + +// ============================================================================ +// validate() — Pro-tier feature: deeper analysis of a cron expression. +// Returns warnings, observations, and optimization suggestions. +// ============================================================================ + +function validate(expr) { + let parsed; + try { + parsed = parseCron(expr); + } catch (e) { + return { + valid: false, + error: e.message, + fieldIndex: e.fieldIndex, + warnings: [], + observations: [], + suggestions: [], + }; + } + + const warnings = []; + const observations = []; + const suggestions = []; + + const desc = describeParsed(parsed); + + // Check: day-of-month and day-of-week both restricted (OR semantics surprise) + if (parsed.domRestricted && parsed.dowRestricted) { + warnings.push({ + level: 'high', + message: 'Both day-of-month and day-of-week are restricted. Cron uses OR semantics for these fields — the job will run when EITHER matches, not both. This is a common source of bugs.', + }); + } + + // Check: impossible day-of-month values (e.g., 31 in Feb) + const domValues = [...(parsed.dom.values || [])]; + if (!parsed.domRestricted && parsed.month.values && ![...parsed.month.values].every(m => m === 2)) { + // skip + } else if (parsed.domRestricted && !parsed.dom.special && domValues.includes(31)) { + const monthsWith31 = [1, 3, 5, 7, 8, 10, 12]; // Jan, Mar, May, Jul, Aug, Oct, Dec + const monthValues = parsed.month.values ? [...parsed.month.values] : []; + const restrictedMonths = parsed.parts[3] !== '*'; + if (restrictedMonths) { + const problemMonths = monthValues.filter(m => !monthsWith31.includes(m)); + if (problemMonths.length > 0) { + warnings.push({ + level: 'medium', + message: `Day 31 is specified but months ${problemMonths.map(m => capitalize(MONTH_NAMES[m - 1])).join(', ')} have fewer than 31 days. The job will never run in those months.`, + }); + } + } else { + observations.push({ + level: 'info', + message: 'Day 31 will only match in months with 31 days (7 of 12 months). The job effectively skips Feb, Apr, Jun, Sep, and Nov.', + }); + } + } + + // Check: high-frequency schedules + if (parsed.parts[0] === '*' && parsed.parts[1] === '*') { + observations.push({ + level: 'info', + message: 'This expression runs every minute. For production jobs, consider if this frequency is intentional.', + }); + } + + // Check: step values that don't divide evenly + for (let i = 0; i < 2; i++) { + const part = parsed.parts[i]; + if (part.startsWith('*/')) { + const step = parseInt(part.slice(2), 10); + const range = i === 0 ? 60 : 24; + if (range % step !== 0) { + observations.push({ + level: 'info', + message: `Step value */${step} in ${FIELDS[i].name} doesn't divide evenly into ${range}. The last interval will be shorter than the rest (e.g., */7 in minutes goes 0,7,14,...,56, then 0 again — not 63).`, + }); + } + } + } + + // Check: February 29th edge case + if (parsed.domRestricted && !parsed.dom.special) { + const domVals = [...(parsed.dom.values || [])]; + const monthVals = parsed.month.values ? [...parsed.month.values] : []; + if (domVals.includes(29) && monthVals.length === 1 && monthVals[0] === 2) { + warnings.push({ + level: 'medium', + message: 'February 29th only occurs in leap years. This job will not run at all in non-leap years (3 out of every 4 years).', + }); + } + } + + // Check: midnight rush + if (parsed.parts[0] === '0' && parsed.parts[1] === '0') { + suggestions.push({ + level: 'info', + message: 'Midnight (00:00) is a common schedule and many systems have concurrent job spikes at this time. Consider offsetting to a few minutes past midnight (e.g., 02 0 * * *) to avoid resource contention.', + }); + } + + // Check: weekend vs weekday + if (parsed.parts[4] === '1-5') { + observations.push({ + level: 'info', + message: 'Weekdays only (Mon-Fri). This job will not run on weekends.', + }); + } + + // Compute frequency estimate + const freq = estimateFrequency(parsed); + if (freq) { + observations.push({ + level: 'info', + message: `Approximate frequency: ${freq.description} (~${freq.runsPerYear} runs per year).`, + }); + } + + return { + valid: true, + description: desc, + warnings, + observations, + suggestions, + parsed, + }; +} + +function estimateFrequency(parsed) { + try { + // Count runs over a sample year + const start = new Date(2025, 0, 1, 0, 0, 0, 0); + const end = new Date(2026, 0, 1, 0, 0, 0, 0); + let count = 0; + let d = new Date(start.getTime()); + let maxScan = 540000; // ~375 days + while (d < end && maxScan-- > 0) { + if (matches(d, parsed)) count++; + d = new Date(d.getTime() + 60000); + } + + let description = ''; + if (count >= 525600) description = 'every minute'; + else if (count >= 500000) description = 'multiple times per minute'; + else if (count >= 8000) description = 'hourly or more'; + else if (count >= 300) description = 'daily or more'; + else if (count >= 40) description = 'weekly or more'; + else if (count >= 8) description = 'monthly or more'; + else if (count >= 1) description = 'yearly or less'; + else description = 'never (impossible schedule)'; + + return { description, runsPerYear: count }; + } catch (e) { + return null; + } +} + +// ---- Presets ---- +const PRESETS = [ + { label: 'Every minute', cron: '* * * * *' }, + { label: 'Every 5 min', cron: '*/5 * * * *' }, + { label: 'Every 10 min', cron: '*/10 * * * *' }, + { label: 'Every 15 min', cron: '*/15 * * * *' }, + { label: 'Every 30 min', cron: '*/30 * * * *' }, + { label: 'Hourly', cron: '0 * * * *' }, + { label: 'Every 2 hours', cron: '0 */2 * * *' }, + { label: 'Every 6 hours', cron: '0 */6 * * *' }, + { label: 'Every 12 hours', cron: '0 */12 * * *' }, + { label: 'Daily at midnight', cron: '0 0 * * *' }, + { label: 'Daily 9am', cron: '0 9 * * *' }, + { label: 'Twice daily', cron: '0 9,21 * * *' }, + { label: 'Weekdays 9am', cron: '0 9 * * 1-5' }, + { label: 'Weekends 10am', cron: '0 10 * * 0,6' }, + { label: 'Every Monday', cron: '0 0 * * 1' }, + { label: 'Every Friday', cron: '0 0 * * 5' }, + { label: 'Monthly 1st', cron: '0 0 1 * *' }, + { label: 'Quarterly', cron: '0 0 1 */3 *' }, + { label: 'Yearly Jan 1', cron: '0 0 1 1 *' }, +]; + +const COMMON = [ + { label: 'At 14:30', cron: '30 14 * * *' }, + { label: '9am weekdays', cron: '0 9 * * 1-5' }, + { label: 'Every Mon 8am', cron: '0 8 * * 1' }, + { label: 'Last day of month', cron: '0 0 L * *' }, + { label: '15th, weekday', cron: '0 0 15W * *' }, + { label: '3rd Thursday', cron: '0 0 * * 4#3' }, + { label: 'Last Friday', cron: '0 0 * * 5L' }, + { label: 'Business hours', cron: '0 9-17 * * 1-5' }, + { label: 'Backup nightly', cron: '0 2 * * *' }, +]; + +// ---- Helpers ---- +function pad2(n) { return String(n).padStart(2, '0'); } +function formatHM(h, m) { return `${pad2(h)}:${pad2(m)}`; } +function capitalize(s) { return s.charAt(0).toUpperCase() + s.slice(1); } +function ordinal(n) { + const s = ['th', 'st', 'nd', 'rd']; + const v = n % 100; + return n + (s[(v - 20) % 10] || s[v] || s[0]); +} +function listJoin(arr) { + if (arr.length === 0) return ''; + if (arr.length === 1) return String(arr[0]); + if (arr.length === 2) return `${arr[0]} and ${arr[1]}`; + return arr.slice(0, -1).join(', ') + ', and ' + arr[arr.length - 1]; +} + +function formatNextRuns(runs, fromDate) { + return runs.map(r => { + const diff = r.getTime() - fromDate.getTime(); + const mins = Math.round(diff / 60000); + let rel; + if (mins < 60) rel = `+${mins}m`; + else if (mins < 2880) rel = `+${Math.round(mins / 60)}h`; + else rel = `+${Math.round(mins / 1440)}d`; + return { date: r, relative: rel, formatted: r.toISOString() }; + }); +} + +module.exports = { + CronError, + FIELDS, + MONTH_NAMES, + DAY_NAMES, + PRESETS, + COMMON, + parseCron, + describe, + describeParsed, + nextRuns, + matches, + validate, + estimateFrequency, + formatNextRuns, + parseField, + parseItem, + parseSingleNum, + resolveName, + lastDayOfMonth, + nearestWeekday, + nthWeekdayMatches, + lastWeekdayMatches, +}; diff --git a/antigravity-awesome-skills/skills/sql-sentinel/SKILL.md b/antigravity-awesome-skills/skills/sql-sentinel/SKILL.md new file mode 100644 index 00000000..cf35a1e7 --- /dev/null +++ b/antigravity-awesome-skills/skills/sql-sentinel/SKILL.md @@ -0,0 +1,131 @@ +--- +name: sql-sentinel +description: "Audit SQL for the cost & performance anti-patterns that burn warehouse credits. Scores warehouse health 0-100 and outputs a prioritized cost-reduction plan for BigQuery, Snowflake, Redshift, and Postgres." +category: data +risk: safe +source: community +source_repo: takeaseatventure/sql-sentinel +source_type: community +date_added: "2026-06-26" +author: takeaseat +tags: [sql, bigquery, snowflake, redshift, postgres, data-warehouse, cost-optimization, performance, audit, finops] +tools: [claude, cursor, codex, gemini] +license: "MIT" +license_source: "https://github.com/takeaseatventure/sql-sentinel/blob/main/LICENSE" +--- + +# sql-sentinel + +## Overview + +A static-analysis skill that audits SQL for the cost & performance anti-patterns that dominate warehouse bills — `SELECT *`, full-table scans, non-sargable predicates, Cartesian joins, the `NOT IN` NULL trap, and 15 more. It scores warehouse query health 0-100 (A-F) and outputs a prioritized cost-reduction plan, each finding with a `why`, a concrete `fix`, and an estimated savings. + +Built for analytics engineers (dbt, Looker), data platform teams running FinOps / "reduce cloud spend" initiatives, and anyone reviewing a SQL pull request before it hits production. Works across BigQuery, Snowflake, Redshift, and Postgres. Zero dependencies, MIT licensed. + +The executable engine and full rule set live in the source repository: https://github.com/takeaseatventure/sql-sentinel + +## When to Use This Skill + +- A user writes or reviews a query for BigQuery, Snowflake, Redshift, Postgres, or Spark SQL. +- A user asks "why is this query so slow?" or "why is my warehouse bill so high?" +- A user is about to promote a dashboard query or dbt model to production. +- A data engineer wants a second pair of eyes before a code review or a cost-optimization sweep. +- A team is running a "reduce cloud spend" or FinOps initiative. + +## How It Works + +The engine splits a SQL script into statements (honoring quotes and comments), runs 20 rules over each statement, scores health 0-100 weighted by severity (critical 25, high 12, medium 5, low 1), and returns a prioritized cost-reduction plan. + +### Step 1: Run the audit + +Install or clone the source repository, then run the zero-dependency engine: + +```bash +git clone https://github.com/takeaseatventure/sql-sentinel.git +cd sql-sentinel +node scripts/sql-sentinel.js path/to/query.sql +``` + +Or programmatically: + +```javascript +const { auditSql } = require('./scripts/sql-sentinel'); +const report = auditSql(yourSqlString, { dialect: 'bigquery' }); +console.log(report.healthScore); // 0-100 +console.log(report.grade); // 'A' | 'B' | 'C' | 'D' | 'E' | 'F' +console.log(report.prioritizedPlan); // array, worst findings first +``` + +### Step 2: Read the prioritized plan + +The output leads with critical findings (Cartesian joins, mass DELETE) and descends to low-severity style issues. Each finding explains *why* it costs money and *how* to fix it. + +## Examples + +### Example 1: A messy dashboard query + +```sql +SELECT DISTINCT * +FROM user_events, raw_logs +WHERE LOWER(event_name) LIKE '%signup%' + AND user_id NOT IN (SELECT id FROM deleted_users) +ORDER BY created_at; +``` + +The audit scores this 17/100 (grade F) and flags 7 findings: +- CRITICAL: comma-join produces a Cartesian product (can turn a $0.02 query into a $200 query) +- HIGH: `SELECT *` forces full column scan (30-90% wasted bytes on wide tables) +- HIGH: leading-wildcard `LIKE '%signup%'` defeats indexes +- HIGH: `LOWER(event_name)` defeats indexes (non-sargable) +- HIGH: `NOT IN (SELECT ...)` — NULL semantics hazard +- MEDIUM: `SELECT DISTINCT` dedup cost +- MEDIUM: `ORDER BY` without `LIMIT` sorts the full result + +### Example 2: A clean, sargable query + +```sql +-- This scores 90+/100 (grade A) — no findings +SELECT id, email, created_at +FROM users +WHERE created_at >= TIMESTAMP '2026-01-01' + AND created_at < TIMESTAMP '2026-02-01' +ORDER BY id +LIMIT 100; +``` + +## The 20 rules (ruleset v1.0.0) + +| Rule | Severity | Catches | +|---|---|---| +| SQL001 | high | `SELECT *` full column scan | +| SQL002 | critical | No `WHERE` → full table scan | +| SQL003 | high | `LIKE '%term'` non-sargable | +| SQL004 | high | Function on column kills index | +| SQL005 | critical | `CROSS JOIN` / comma-join | +| SQL006 | medium | `SELECT DISTINCT` dedup cost | +| SQL007 | medium | `ORDER BY` without `LIMIT` | +| SQL008 | high | `NOT IN (SELECT ...)` NULL trap | +| SQL009 | medium | Implicit type cast | +| SQL010 | low | Many `OR`s (use `IN`/`UNION`) | +| SQL011 | medium | `COUNT(DISTINCT)` at scale (use HLL) | +| SQL012 | low | `LIMIT` without `ORDER BY` | +| SQL013 | medium | Scalar subquery in `SELECT` | +| SQL014 | medium | 5+ JOINs broadcast/spill risk | +| SQL015 | high | Fact table, no partition filter | +| SQL017 | low | String concat in `SELECT` | +| SQL018 | medium | Window `OVER ()` no `PARTITION` | +| SQL020 | critical | `DELETE`/`UPDATE` without `WHERE` | +| SQL021 | low | `SELECT *` in `EXISTS`/`IN` | +| SQL022 | medium | `UNION` vs `UNION ALL` | + +Run the test suite to verify each rule fires on real SQL: + +```bash +cd scripts && node test.js # 26 tests, zero dependencies +``` + +## Limitations + +- This is a **static** analyzer. It finds anti-patterns in the *text* of SQL; it does not read query plans, row counts, or billing. A flagged query on a 100-row table is cheap; the same query on a billion-row table is the problem the rule exists to prevent. +- The fact-table heuristic (SQL015) keys off table *names* (`*_events`, `*_log`) and is advisory, not definitive. +- It does not execute SQL — safe to run on any `.sql` file. diff --git a/antigravity-awesome-skills/skills/web-project-brainstorming/SKILL.md b/antigravity-awesome-skills/skills/web-project-brainstorming/SKILL.md new file mode 100644 index 00000000..8e2736be --- /dev/null +++ b/antigravity-awesome-skills/skills/web-project-brainstorming/SKILL.md @@ -0,0 +1,149 @@ +--- +name: web-project-brainstorming +description: Masterclass framework for brainstorming web development projects and page designs. Outlines structural phases for concept, UX flow, styling aesthetics, technical architecture, and SEO. +category: consulting +risk: safe +source: self +source_type: self +date_added: "2026-06-26" +author: Rsmiyani +tags: [brainstorming, project-planning, web-development, product-scoping, design-system, architecture] +tools: [claude, cursor, gemini] +--- + +# Web Project Brainstorming + +## Overview + +This skill provides a structured, masterclass-level framework for brainstorming web projects, web applications, or individual page designs at their inception. It guides developers and designers through scoping the core product concept, mapping user flows, defining visual styling aesthetics, selecting the technical stack, and planning for search engine optimization (SEO) and performance. + +## When to Use This Skill + +- Use at the start of any new web development project or page redesign. +- Use when scoping feature sets, user roles, and interaction patterns for web applications. +- Use when establishing design systems, color tokens, and layout guidelines. +- Use when evaluating tech stacks (e.g., Next.js vs. Vanilla JS, CSS Grid vs. Tailwind). + +## How It Works + +Execute web project brainstorming sequentially across six structured phases. Ask the user questions one phase at a time to maintain focus and ensure thorough alignment. + +### Phase 1: Core Concept & Scoping +Define the product's primary value proposition and scope: +- **Target Audience**: Who is using the website or application? +- **Core Value**: What problem does it solve for users? +- **Key Features**: What are the top 3–5 mandatory features? + +### Phase 2: User Experience (UX) & Information Architecture +Map how users navigate and interact: +- **Page Hierarchy**: What is the sitemap and page structure? +- **User Journeys**: What step-by-step flows do users take to complete key goals? +- **Responsive Layout**: Is the interface mobile-first, desktop-first, or balanced? + +### Phase 3: Visual Styling & Design System +Establish the visual guidelines and aesthetic parameters: +- **Design Aesthetic**: Modern, minimalist, brutalist, glassmorphism, or luxury? +- **Color Palette**: What are the primary, secondary, and accent colors? (Prefer tailorable HSL/RGB models over static color keywords). +- **Typography**: Which Google Fonts or system fonts fit the theme? (e.g., Inter, Outfit, Syne). +- **Interactive States**: How do hovers, clicks, transitions, and loading states behave? + +### Phase 4: Technical Stack & Architecture +Select the technologies and integration systems: +- **Frontend Framework**: React, Next.js, Vite, Astro, Svelte, or Vanilla HTML/JS? +- **Styling Method**: Vanilla CSS, Tailwind CSS, or CSS Modules? +- **Data & Backend**: REST API, GraphQL, tRPC, Firebase, Supabase, or SQLite? +- **State Management**: Zustand, Context API, Redux, or local React state? + +### Phase 5: SEO, Accessibility (A11y), and Performance +Plan for discoverability and fast loading times: +- **SEO Elements**: Title tag structure, meta descriptions, and semantic HTML tag hierarchy. +- **Accessibility**: ARIA labels, semantic tags, keyboard navigation, and color contrast. +- **Performance**: Preloading assets, lazy loading images, server-side rendering (SSR), and CDN delivery. + +### Phase 6: MVP Scope & Project Phases +Break the work down into manageable increments: +- **Phase 1 (MVP)**: The absolute minimum viable product needed to deploy. +- **Phase 2 (Enhancements)**: Nice-to-have features, micro-animations, and advanced integrations. + +## Examples + +### Interactive Questionnaire Prompt Template +Use this prompt layout when initiating a brainstorming session with a client or team member: + +```markdown +👋 Let's brainstorm your new web project! We will walk through 6 quick phases. + +--- +### Phase 1: Core Concept & Scoping +1. What is the main title or working name of this project? +2. Who are the primary target users (e.g., tech-savvy professionals, shoppers, children)? +3. What are the 3 core tasks a user must be able to perform? +--- +``` + +### Brainstorming Output Document Template +Once all phases are complete, generate a markdown blueprint for the project using this template: + +```markdown +# Project Blueprint: [Project Name] + +## 1. Product Concept +- **Value Proposition**: [Summary] +- **Key Features**: + 1. [Feature 1] + 2. [Feature 2] + +## 2. Information Architecture & UX +- **Pages**: `/index.html`, `/dashboard.html` +- **Primary User Flow**: User signs up -> completes onboarding -> views dashboard. + +## 3. Styling & Aesthetics +- **Aesthetic**: Sleek Glassmorphism Dark Mode +- **Color Tokens**: + - Background: `hsl(222, 47%, 11%)` + - Accent/Primary: `hsl(217, 91%, 60%)` +- **Typography**: Inter (Body), Outfit (Headings) + +## 4. Technical Architecture +- **Framework**: Next.js (App Router) +- **Styling**: Tailwind CSS +- **Database**: PostgreSQL with Prisma ORM + +## 5. SEO & Performance +- **Primary Title**: "[Brand] | [Tagline]" +- **Performance Strategy**: Dynamic image optimization, caching pages via Cloudflare. + +## 6. MVP vs Phase 2 Roadmap +- **MVP**: Authentication + core dashboard view. +- **Phase 2**: Real-time notifications and PDF reporting. +``` + +## Best Practices + +- ✅ Ask questions incrementally—never dump all six phases in a single response to avoid cognitive overload. +- ✅ Propose logical defaults (e.g., recommending responsive Tailwind/CSS Grid and standard semantic HTML) if the user is unsure. +- ✅ Ensure semantic HTML layout hierarchy (one `

` per page, sequential `
`, `
`, `
`, `
` elements) is planned from the start. +- ✅ Document explicit non-goals to prevent feature creep. + +## Limitations + +- This skill focuses on conceptual mapping, architecture, and feature planning; it does not replace the writing of implementation code or system configuration. +- Brainstorming outcomes should be treated as flexible blueprints and refined as technical constraints are discovered during development. + +## Security & Safety Notes + +- During Phase 4 (Architecture), flag any security requirements (e.g., SSL certificates, CORS policies, secure authentication storage, environment variables protection) early. +- Do not store actual API tokens, passwords, or credentials in design or blueprint documents. + +## Common Pitfalls + +- **Problem**: Scope Creep (the project expands too quickly before building an MVP). + **Solution**: Enforce Phase 6 strictly. Push nice-to-have features into Phase 2. +- **Problem**: Ignoring mobile design until late in development. + **Solution**: Brainstorm responsive patterns in Phase 2 before deciding on layout style in Phase 3. + +## Related Skills + +- `@writing-plans` - Organizing structural step-by-step engineering plans. +- `@architecture-decision-records` - Documenting architectural decisions. +- `@ux-flow` - Designing deep user experience flows and interaction details. diff --git a/antigravity-awesome-skills/skills_index.json b/antigravity-awesome-skills/skills_index.json index 8dd59b3c..cff4379f 100644 --- a/antigravity-awesome-skills/skills_index.json +++ b/antigravity-awesome-skills/skills_index.json @@ -1107,6 +1107,28 @@ ] } }, + { + "id": "ai-loop", + "path": "skills/ai-loop", + "category": "workflow", + "name": "ai-loop", + "description": "Runs a bounded spec-build-review development loop with explicit scope, stop conditions, and human approval gates for risky or ambiguous work.", + "risk": "safe", + "source": "community", + "date_added": "2026-06-27", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "ai-md", "path": "skills/ai-md", @@ -10364,6 +10386,28 @@ "reasons": [] } }, + { + "id": "cron-doctor", + "path": "skills/cron-doctor", + "category": "devops", + "name": "cron-doctor", + "description": "Diagnose and validate cron expressions before they ship. Catches the five silent death-traps: impossible dates that never fire, OR-semantics that fire too often, midnight spikes, uneven step drift, and leap-year February 29.", + "risk": "safe", + "source": "community", + "date_added": "2026-06-26", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "crossframe", "path": "skills/crossframe", @@ -31507,6 +31551,28 @@ "reasons": [] } }, + { + "id": "sql-sentinel", + "path": "skills/sql-sentinel", + "category": "data", + "name": "sql-sentinel", + "description": "Audit SQL for the cost & performance anti-patterns that burn warehouse credits. Scores warehouse health 0-100 and outputs a prioritized cost-reduction plan for BigQuery, Snowflake, Redshift, and Postgres.", + "risk": "safe", + "source": "community", + "date_added": "2026-06-26", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "sqlmap-database-pentesting", "path": "skills/sqlmap-database-pentesting", @@ -35873,6 +35939,28 @@ "reasons": [] } }, + { + "id": "web-project-brainstorming", + "path": "skills/web-project-brainstorming", + "category": "consulting", + "name": "web-project-brainstorming", + "description": "Masterclass framework for brainstorming web development projects and page designs. Outlines structural phases for concept, UX flow, styling aesthetics, technical architecture, and SEO.", + "risk": "safe", + "source": "self", + "date_added": "2026-06-26", + "plugin": { + "targets": { + "codex": "supported", + "claude": "supported" + }, + "setup": { + "type": "none", + "summary": "", + "docs": null + }, + "reasons": [] + } + }, { "id": "web-scraper", "path": "skills/web-scraper", diff --git a/brooks-lint/README.es.md b/brooks-lint/README.es.md new file mode 100644 index 00000000..690246f1 --- /dev/null +++ b/brooks-lint/README.es.md @@ -0,0 +1,690 @@ +

+ brooks-lint +

+ +

brooks-lint

+ +

+ Revisiones de código con IA fundamentadas en doce libros clásicos de ingeniería.
+ Consistentes. Trazables. Accionables.
+

+ +

+ English · + 简体中文 · + 繁體中文 · + 日本語 · + 한국어 · + Español +

+ +

+ Inicio rápido • + Los seis riesgos de deterioro • + Cómo se ve • + Benchmark • + Instalación +

+ +

+ Version + MIT License + Claude Code Plugin + Codex CLI Skill + GitHub Stars +

+ +

+ Repositorio JavaScript n.º 2 del día | Trendshift +

+ +

+ Tu código → 12 clásicos → 12 riesgos de deterioro → hallazgos con citas +

+ +

+ brooks-lint revisando código: un comando /brooks-review produce una puntuación de salud de 28/100 y hallazgos citados con el formato Síntoma → Origen → Consecuencia → Remedio +

+ +

+ → Visita el sitio web +

+ +--- + +> *"Gestar un hijo lleva nueve meses, sin importar a cuántas mujeres se asigne."* +> — Frederick Brooks, *The Mythical Man-Month* (El mítico hombre-mes) (1975) + +**50 años después, Brooks seguía teniendo razón — y también McConnell, Fowler, Martin, Hunt & Thomas, Evans, Ousterhout, Winters, Meszaros, Osherove, Feathers y el equipo de Testing de Google.** + +La mayoría de las herramientas de calidad de código cuentan líneas y complejidad ciclomática. **brooks-lint** va más a fondo: diagnostica tu código frente a seis dimensiones de riesgo de deterioro sintetizadas a partir de doce libros clásicos de ingeniería, produciendo cada vez hallazgos estructurados con citas de libros, etiquetas de severidad y remedios concretos. + +Para el mapeo completo de fuente a skill, incluyendo excepciones y protecciones contra falsos positivos, consulta +[`skills/_shared/source-coverage.md`](skills/_shared/source-coverage.md). + +## Inicio rápido + +```bash +# Claude Code +/plugin marketplace add hyhmrright/brooks-lint +/plugin install brooks-lint@brooks-lint-marketplace + +# Cualquier otra plataforma de Agent Skills — Cursor · Codex · Gemini · Copilot · Windsurf · OpenCode · Kiro · … +curl -fsSL https://raw.githubusercontent.com/hyhmrright/brooks-lint/main/scripts/install.sh | bash -s -- +``` + +Luego solo pide ("revisa este PR", "audita la arquitectura") — o ejecuta un comando: + +| Comando | Qué hace | +|---------|--------------| +| `/brooks-review` | Revisa un PR o diff | +| `/brooks-audit` | Audita la arquitectura (+ grafo de dependencias en Mermaid) | +| `/brooks-debt` | Hoja de ruta de deuda técnica priorizada | +| `/brooks-test` | Revisión de calidad de la suite de pruebas | +| `/brooks-health` | Panel de salud en todas las dimensiones | +| `/brooks-sweep` | Barre todas las dimensiones y corrige hallazgos automáticamente | + +Cada hallazgo se devuelve como **Síntoma → Origen → Consecuencia → Remedio** con una cita de libro y una puntuación de salud de 0 a 100. Las opciones completas de instalación (8 plataformas más), el uso por comando y la configuración de CI/CD están [más abajo](#instalación). + +## Los doce libros + +| Libro | Autor | Contribuye a | +|------|--------|----------------| +| *The Mythical Man-Month* | Frederick Brooks | R2, R4, R5 | +| *Code Complete* | Steve McConnell | R1, R4 | +| *Refactoring* | Martin Fowler | R1, R2, R3, R4, R6 | +| *Clean Architecture* | Robert C. Martin | R2, R5 | +| *The Pragmatic Programmer* | Hunt & Thomas | R2, R3, R4, R5, T2, T3 | +| *Domain-Driven Design* | Eric Evans | R1, R3, R6 | +| *A Philosophy of Software Design* | John Ousterhout | R1, R4 | +| *Software Engineering at Google* | Winters, Manshreck & Wright | R2, R5 | +| *The Art of Unit Testing* | Roy Osherove | T1, T2, T4, T5 | +| *How Google Tests Software* | James A. Whittaker, Jason Arbon & Jeff Carollo | T5, T6 | +| *Working Effectively with Legacy Code* | Michael Feathers | T4, T5, T6 | +| *xUnit Test Patterns* | Gerard Meszaros | T1, T2, T3, T4 | + +## Los seis riesgos de deterioro + +brooks-lint evalúa tu código frente a **seis riesgos de deterioro del código de producción** y **seis riesgos de deterioro de la suite de pruebas**, sintetizados a partir de doce libros clásicos de ingeniería: + +| Riesgo de deterioro | Pregunta diagnóstica | Fuentes | +|------------|---------------------|---------| +| 🧠 Sobrecarga cognitiva | ¿Cuánto esfuerzo mental cuesta entender esto? | Code Complete, Refactoring, DDD, Philosophy of SD | +| 🔗 Propagación de cambios | ¿Cuántas cosas no relacionadas se rompen con un solo cambio? | Refactoring, Clean Architecture, Pragmatic, SE@Google | +| 📋 Duplicación de conocimiento | ¿La misma decisión se expresa en varios lugares? | Pragmatic, Refactoring, DDD | +| 🌀 Complejidad accidental | ¿El código es más complejo que el problema? | Refactoring, Code Complete, Brooks, Philosophy of SD | +| 🏗️ Desorden de dependencias | ¿Las dependencias fluyen en una dirección consistente? | Clean Architecture, Brooks, Pragmatic, SE@Google | +| 🗺️ Distorsión del modelo de dominio | ¿El código representa fielmente el dominio? | DDD, Refactoring | + +> Philosophy of SD = *A Philosophy of Software Design* (Ousterhout) · SE@Google = *Software Engineering at Google* (Winters et al.) + +## Cómo se ve + +Dado este código: + +```python +class UserService: + def update_profile(self, user_id, name, email, avatar_url): + user = self.db.query(f"SELECT * FROM users WHERE id = {user_id}") + user['email'] = email + ... + if user['email'] != email: # always False — silent bug + self.smtp.send(...) + points = user['login_count'] * 10 + 500 + self.db.execute(f"UPDATE loyalty SET points={points} WHERE user_id={user_id}") +``` + +brooks-lint produce: + +--- + +**Puntuación de salud: 28/100** + +*Este método concentra cuatro responsabilidades de negocio no relacionadas en una sola función, contiene un error lógico que suprime silenciosamente las notificaciones de cambio de correo electrónico y queda totalmente expuesto a inyección de SQL.* + +### 🔴 Propagación de cambios — Un solo método cambia por cuatro razones de negocio no relacionadas +**Síntoma:** `update_profile` realiza la actualización de los campos del perfil, las notificaciones de cambio de correo, el recálculo de puntos de fidelidad y la invalidación de caché, todo en el cuerpo de un mismo método. +**Origen:** Fowler — *Refactoring* — Divergent Change (Cambio divergente); Hunt & Thomas — *The Pragmatic Programmer* — Orthogonality (Ortogonalidad) +**Consecuencia:** Cualquier cambio en la fórmula de fidelidad arriesga romper las notificaciones de correo y viceversa. Cada edición conlleva riesgo de regresión en cuatro dominios no relacionados de forma simultánea. +**Remedio:** Extrae `NotificationService`, `LoyaltyService` y `UserCacheInvalidator`. `UserService.update_profile` debería orquestar llamando a cada uno — no debería contener lógica de implementación propia. + +### 🔴 Distorsión del modelo de dominio — Error lógico silencioso: la notificación de correo nunca se dispara +**Síntoma:** `user['email'] = email` sobrescribe el valor anterior antes de `if user['email'] != email` — la condición siempre es `False`. La notificación es código muerto. +**Origen:** McConnell — *Code Complete* — Cap. 17: Estructuras de control inusuales +**Consecuencia:** Los usuarios nunca son notificados cuando cambia su dirección de correo. Fallo silencioso de integridad de datos — el sistema parece funcionar mientras viola una regla de negocio. +**Remedio:** Captura `old_email = user['email']` antes de cualquier mutación. Compara contra `old_email`, no contra `user['email']`. + +*(+ 6 hallazgos más, incluyendo inyección de SQL, desorden de dependencias y números mágicos)* + +### Auditoría de arquitectura con grafo de dependencias + +En el Modo 2 (Auditoría de arquitectura), brooks-lint genera un **grafo de dependencias en Mermaid** en la parte superior del informe. Los módulos se colorean según su severidad: rojo = hallazgos Critical, amarillo = Warning, verde = limpio. + +```mermaid +graph TD + subgraph src/api + AuthController + UserController + end + subgraph src/domain + UserService + OrderService + end + subgraph src/infra + Database + EmailClient + end + + AuthController --> UserService + UserController --> UserService + UserController --> OrderService + OrderService --> UserService + OrderService --> EmailClient + UserService --> Database + EmailClient -.->|circular| OrderService + + classDef critical fill:#ff6b6b,stroke:#c92a2a,color:#fff + classDef warning fill:#ffd43b,stroke:#e67700 + classDef clean fill:#51cf66,stroke:#2b8a3e,color:#fff + + class OrderService,EmailClient critical + class AuthController warning + class UserService,UserController,Database clean +``` + +El grafo se renderiza de forma nativa en GitHub, Notion y otros entornos Markdown — sin herramientas adicionales. + +## Más ejemplos + +La [Galería completa](docs/gallery.md) contiene salida real de brooks-lint en Python, TypeScript, Go y Java — incluyendo revisiones de PR, auditorías de arquitectura con grafos de dependencias en Mermaid, evaluaciones de deuda técnica y revisiones de calidad de pruebas. + +¿Nuevo en los riesgos de deterioro? La [**Guía de campo de los riesgos de deterioro**](https://hyhmrright.github.io/brooks-lint/guide.html) explica los seis — pregunta diagnóstica, síntomas característicos, libros de origen y remedio para cada uno. + +--- + +## Benchmark + +Probado en 3 escenarios del mundo real (revisión de PR, auditoría de arquitectura, evaluación de deuda técnica): + +| Criterio | brooks-lint | Claude solo | +|-----------|:-----------:|:------------:| +| Hallazgos estructurados (Síntoma → Origen → Consecuencia → Remedio) | ✅ 100% | ❌ 0% | +| Citas de libros por hallazgo | ✅ 100% | ❌ 0% | +| Etiquetas de severidad (🔴/🟡/🟢) | ✅ 100% | ❌ 0% | +| Puntuación de salud (0–100) | ✅ 100% | ❌ 0% | +| Detecta Propagación de cambios | ✅ 100% | ✅ 100% | +| **Tasa de aprobación global** | **94%** | **16%** | + +La brecha no está en lo que Claude *puede* encontrar — está en lo que encuentra de forma *consistente*, con evidencia trazable y remedios accionables cada vez. + +### Benchmarks reproducibles + +La tabla anterior es ilustrativa. Estas cifras son **deterministas y puedes reproducirlas localmente**: + +**Fidelidad del parser** — la exportación a SARIF y los gates de CI dependen de parsear correctamente el informe Markdown del modelo. Frente a un **corpus congelado de 30 informes reales generados por el modelo** que abarcan los seis modos (`evals/benchmark-corpus.json`), cada uno emparejado con un inventario de hallazgos **calificado de forma independiente** (un pase de modelo separado, revisado manualmente por muestreo), el parser distribuido obtiene — ejecuta `npm run benchmark`: + +| Métrica (n = 30, corpus congelado) | Resultado | +|---|:---:| +| Coincidencia exacta del conteo de severidad (parser vs. verdad calificada) | 30 / 30 | +| Precisión / recall del código de riesgo | 100% / 100% (56 códigos a nivel de hallazgo, 0 FP / 0 FN) | +| SARIF 2.1.0 válido emitido | 30 / 30 | + +Como el parser es determinista y el corpus está congelado, `npm run benchmark` da a todo el mundo el mismo resultado, y `npm test` lo protege como regresión. El corpus incluye deliberadamente 9 informes de falsos positivos / compensaciones (por ejemplo, un diseño de puertos y adaptadores que *parece* un ciclo de dependencias) que deben permanecer limpios. + +**Determinismo del scoring** — para un conjunto fijo de hallazgos (2 Critical / 3 Warning / 1 Suggestion), los presets de severidad producen exactamente las puntuaciones que predice su tabla de `common.md`: strict **34**, balanced **54**, legacy-friendly **74** — y solo `legacy-friendly` encabeza con las tres correcciones principales. + +**Calidad del modelo** — si el modelo encuentra los riesgos *correctos* en código real se mide con la **suite de evaluaciones de 57 escenarios** (`evals/evals.json`): `npm run evals` (estructural) y `npm run evals:live` (en vivo, requiere `ANTHROPIC_API_KEY`). + +> Alcance y honestidad: las cifras del parser son deterministas y exactamente reproducibles. Las cifras de severidad y de la suite de evaluaciones son mediciones en vivo de una sola ejecución contra el modelo y varían ligeramente entre ejecuciones. El benchmark del parser mide la fidelidad del parseo de informes (¿lee la herramienta cada hallazgo que el informe declara?), no si un hallazgo dado es "correcto". La coincidencia del conteo de severidad es la señal totalmente independiente; la concordancia de códigos de riesgo también refleja la leyenda canónica compartida de nombre→código. + +## Cómo se compara + +| | brooks-lint | ESLint / Pylint | GitHub Copilot Review | Claude sin más | +|---|:---:|:---:|:---:|:---:| +| Detecta problemas de sintaxis y estilo | — | ✅ | ✅ | ~ | +| Cadena de diagnóstico estructurada | ✅ | ❌ | ❌ | ❌ | +| Rastrea los hallazgos hasta libros clásicos | ✅ | ❌ | ❌ | ❌ | +| Etiquetas de severidad consistentes | ✅ | ✅ | ~ | ❌ | +| Perspectivas a nivel de arquitectura | ✅ | ❌ | ~ | ~ | +| Análisis del modelo de dominio | ✅ | ❌ | ❌ | ~ | +| Cero configuración, sin plugins que instalar | ✅ | ❌ | ✅ | ✅ | +| Funciona con cualquier lenguaje | ✅ | ❌ | ✅ | ✅ | + +> `~` = ocasionalmente / de forma inconsistente + +**brooks-lint no reemplaza a tu linter.** Captura lo que los linters no pueden: deriva arquitectónica, silos de conocimiento y distorsión del modelo de dominio — los problemas que frenan a los equipos durante meses antes de que alguien lo note. + +## Instalación + +### Claude Code (recomendado) + +#### Mediante el Plugin Marketplace +```bash +/plugin marketplace add hyhmrright/brooks-lint +/plugin install brooks-lint@brooks-lint-marketplace +``` + +Los comandos en forma corta (`/brooks-review`) se instalan automáticamente al iniciar la primera sesión. Para instalarlos manualmente: +```bash +cp commands/*.md ~/.claude/commands/ +``` + +#### Instalación manual +```bash +mkdir -p ~/.claude/skills/brooks-lint +cp -r skills/* ~/.claude/skills/brooks-lint/ +``` + +### Gemini CLI + +#### Mediante extensión +```bash +/extensions install https://github.com/hyhmrright/brooks-lint +``` + +#### Instalación manual +```bash +mkdir -p ~/.gemini/skills +cp -r skills/* ~/.gemini/skills/ # flat — Gemini discovers skills only one level deep +``` +> O simplemente: `./scripts/install.sh gemini` + +### Codex CLI + +#### Mediante el instalador de skills (en una sesión de Codex) +``` +Install the brooks-lint skill from hyhmrright/brooks-lint +``` + +#### Línea de comandos +```bash +python3 ~/.codex/skills/.system/skill-installer/scripts/install-skill-from-github.py \ + --repo hyhmrright/brooks-lint --path skills --name brooks-lint +``` + +#### Instalación manual +```bash +git clone https://github.com/hyhmrright/brooks-lint.git /tmp/brooks-lint +mkdir -p ~/.codex/skills +cp -r /tmp/brooks-lint/skills/* ~/.codex/skills/ # flat — matches the skill-installer layout +``` +> O simplemente: `./scripts/install.sh codex` + +### Más plataformas — OpenCode · Cursor · Windsurf · Antigravity · pi · Copilot · Kiro · Factory Droid + +brooks-lint se distribuye como [Agent Skills](https://agentskills.io) estándar. **Cualquier agente que cargue Agent +Skills ejecuta los seis modos sin conversión alguna** — un solo comando los instala: + +```bash +# elige tu plataforma; --project instala en el repositorio actual en lugar de en tu configuración global +curl -fsSL https://raw.githubusercontent.com/hyhmrright/brooks-lint/main/scripts/install.sh | bash -s -- +# = opencode · cursor · windsurf · antigravity · pi · kiro · copilot · droid · gemini · codex · agents +``` + +El instalador copia los skills **de forma plana** en la carpeta correcta para tu plataforma, de modo que el framework +compartido (`../_shared/`) siempre se resuelve — no puedes equivocarte con el diseño. Luego solo pide +("revisa este PR", "audita la arquitectura") y el skill correspondiente se activa automáticamente desde su +`description`. ¿Nuevo en los skills, o usas otro agente? Consulta **[docs/getting-started.md](docs/getting-started.md)**. + +
OpenCode + +`./scripts/install.sh opencode` → `~/.config/opencode/skills` (también lee `~/.claude/skills` y +`AGENTS.md`). Guía completa: [docs/opencode-setup.md](docs/opencode-setup.md). +
+ +
Cursor (2.4+) + +`./scripts/install.sh cursor` → `~/.cursor/skills` (también `.agents/skills`; lee `AGENTS.md`). +Guía completa: [docs/cursor-setup.md](docs/cursor-setup.md). +
+ +
Windsurf (Cascade) + +`./scripts/install.sh windsurf` → `~/.codeium/windsurf/skills` (lee `AGENTS.md`). +Guía completa: [docs/windsurf-setup.md](docs/windsurf-setup.md). +
+ +
Antigravity (Google) + +`./scripts/install.sh antigravity --project` → `.agent/skills` (lee `AGENTS.md` / `GEMINI.md`). +Guía completa: [docs/antigravity-setup.md](docs/antigravity-setup.md). +
+ +
pi (earendil-works) + +`./scripts/install.sh pi` → `~/.pi/agent/skills`, o apunta el ajuste `skills` de pi a un clon. +Guía completa: [docs/pi-setup.md](docs/pi-setup.md). +
+ +
GitHub Copilot + +`./scripts/install.sh copilot --project` → `.github/skills` (también detecta automáticamente `.claude/skills`; lee +`AGENTS.md`). Guía completa: [docs/copilot-setup.md](docs/copilot-setup.md). +
+ +
Kiro (AWS) + +`./scripts/install.sh kiro` → `~/.kiro/skills` (registra automáticamente `/brooks-review`; lee `AGENTS.md`). +Guía completa: [docs/kiro-setup.md](docs/kiro-setup.md). +
+ +
Factory Droid + +`./scripts/install.sh droid` → `~/.factory/skills` (registra `/brooks-review`; lee `AGENTS.md`). +Guía completa: [docs/factory-droid-setup.md](docs/factory-droid-setup.md). +
+ +> **🧪 Estado de verificación.** Claude Code, Gemini CLI y Codex CLI están verificados por el mantenedor. Las ocho +> plataformas anteriores están documentadas a partir de la especificación oficial de skills de cada herramienta y verificadas a nivel +> de diseño de archivos (el instalador está probado), pero el mantenedor aún no las ha ejecutado de extremo a extremo en cada plataforma. ¿Probaste +> alguna — funciona **o** está rota? [Abre un issue](https://github.com/hyhmrright/brooks-lint/issues/new) con +> la plataforma, la versión y lo que viste. ¿Otro agente de Agent Skills? Casi con certeza funciona de la misma +> manera — cuéntanoslo y lo añadiremos. + +## Comandos de barra + +### Claude Code +| Comando | Forma corta | Acción | +|---------|------------|--------| +| `/brooks-lint:brooks-review` | `/brooks-review` | Revisión de código a nivel de PR | +| `/brooks-lint:brooks-audit` | `/brooks-audit` | Auditoría completa de arquitectura | +| `/brooks-lint:brooks-debt` | `/brooks-debt` | Evaluación de deuda técnica | +| `/brooks-lint:brooks-test` | `/brooks-test` | Revisión de salud de la suite de pruebas | +| `/brooks-lint:brooks-health` | `/brooks-health` | Panel de salud — las cuatro dimensiones | +| `/brooks-lint:brooks-sweep` | `/brooks-sweep` | Barrido completo — analiza todas las dimensiones y corrige hallazgos automáticamente | + +> Los comandos en forma corta se instalan automáticamente al iniciar la primera sesión, mediante el hook session-start. + +### Gemini CLI +| Comando | Acción | +|---------|--------| +| `/brooks-review` | Revisión de código a nivel de PR | +| `/brooks-audit` | Auditoría completa de arquitectura | +| `/brooks-debt` | Evaluación de deuda técnica | +| `/brooks-test` | Revisión de salud de la suite de pruebas | +| `/brooks-health` | Panel de salud — las cuatro dimensiones | +| `/brooks-sweep` | Barrido completo — analiza todas las dimensiones y corrige hallazgos automáticamente | + +### Codex CLI + +| Comando | Acción | +|---------|--------| +| `$brooks-review` | Revisión de código a nivel de PR | +| `$brooks-audit` | Auditoría completa de arquitectura | +| `$brooks-debt` | Evaluación de deuda técnica | +| `$brooks-test` | Revisión de salud de la suite de pruebas | +| `$brooks-health` | Panel de salud — las cuatro dimensiones | +| `$brooks-sweep` | Barrido completo — analiza todas las dimensiones y corrige hallazgos automáticamente | + +Los skills también se activan automáticamente cuando hablas de calidad de código, arquitectura, mantenibilidad o salud de las pruebas. + +### OpenCode · Cursor · Antigravity · pi + +Estas plataformas invocan los Agent Skills automáticamente a partir del `description` de cada skill — solo pide +("revisa este PR", "audita la arquitectura", "¿dónde está nuestra peor deuda técnica?") y se ejecuta el modo +correspondiente. Para una invocación explícita, usa la sintaxis de comando de skill de la plataforma (por ejemplo, pi registra cada skill +como `/skill:brooks-review`; Cursor y OpenCode exponen `/brooks-review` una vez que el skill es descubierto). + +## Uso + +### Revisión de PR + +``` +/brooks-review # Claude Code (forma corta) / Gemini CLI +/brooks-lint:brooks-review # Claude Code (forma completa) +$brooks-review # Codex CLI +``` + +Pega un diff o apunta la IA a los archivos modificados. Diagnostica cada uno de los seis riesgos de deterioro con hallazgos específicos en el formato Síntoma → Origen → Consecuencia → Remedio. + +### Auditoría de arquitectura + +``` +/brooks-audit # Claude Code (forma corta) / Gemini CLI +/brooks-lint:brooks-audit # Claude Code (forma completa) +$brooks-audit # Codex CLI +``` + +Describe la estructura de tu proyecto o comparte archivos clave. Mapea las dependencias entre módulos, identifica dependencias circulares y comprueba la alineación con la Ley de Conway. + +### Evaluación de deuda técnica + +``` +/brooks-debt # Claude Code (forma corta) / Gemini CLI +/brooks-lint:brooks-debt # Claude Code (forma completa) +$brooks-debt # Codex CLI +``` + +Clasifica tu deuda según los seis riesgos de deterioro, puntúa cada hallazgo por prioridad de Dolor × Alcance y produce una hoja de ruta de pago priorizada con clasificación Critical / Scheduled / Monitored. + +### Revisión de calidad de pruebas + +``` +/brooks-test # Claude Code (forma corta) / Gemini CLI +/brooks-lint:brooks-test # Claude Code (forma completa) +$brooks-test # Codex CLI +``` + +Audita tu suite de pruebas frente a seis riesgos de deterioro del espacio de pruebas — Oscuridad de la prueba, Fragilidad de la prueba, Duplicación de la prueba, Abuso de mocks, Ilusión de cobertura y Desajuste de arquitectura — provenientes de xUnit Test Patterns, The Art of Unit Testing, How Google Tests Software y Working Effectively with Legacy Code. Las revisiones de PR también incluyen automáticamente un Paso 7 ligero de Comprobación rápida de pruebas (omitido para diffs solo de documentación o que no son de código de producción). + +### Panel de salud + +``` +/brooks-health # Claude Code (forma corta) / Gemini CLI +/brooks-lint:brooks-health # Claude Code (forma completa) +$brooks-health # Codex CLI +``` + +Ejecuta escaneos abreviados en las cuatro dimensiones de calidad y produce una puntuación de salud compuesta y ponderada (0–100). Úsalo antes de un release, al incorporar a un nuevo equipo, o siempre que quieras un informe panorámico de "¿cómo vamos?". Para un diagnóstico más profundo en cualquier dimensión, usa en su lugar el skill enfocado. + +### Barrido completo + +``` +/brooks-sweep # Claude Code (forma corta) / Gemini CLI +/brooks-lint:brooks-sweep # Claude Code (forma completa) +$brooks-sweep # Codex CLI +``` + +Ejecuta un escaneo unificado de todos los riesgos de deterioro de producción (R1–R6) y de pruebas (T1–T6), además de la arquitectura, en una sola pasada, y luego aplica las correcciones: los cambios seguros se aplican automáticamente de inmediato, los cambios multiarchivo o que tocan interfaces requieren confirmación, y las decisiones arquitectónicas complejas se marcan como elementos manuales. Produce un Registro de correcciones, el delta de la puntuación de salud y una lista de elementos residuales. + +## Configuración + +Coloca un `.brooks-lint.yaml` en la raíz de tu proyecto para personalizar el comportamiento de la revisión: + +```yaml +version: 1 + +strictness: balanced # strict | balanced (default) | legacy-friendly — softer scoring for legacy code + +disable: + - T5 # skip coverage metrics check — we don't enforce coverage + +severity: + R1: suggestion # downgrade Cognitive Overload findings for this domain + +ignore: + - "**/*.generated.*" + - "**/vendor/**" + +# custom_risks: # define project-specific Cx codes — see skills/_shared/custom-risks-guide.md +# suppress: # downgrade specific findings by risk + path (e.g. accepted legacy debt) +``` + +Copia [`.brooks-lint.example.yaml`](.brooks-lint.example.yaml) como punto de partida. +Todos los ajustes son opcionales — omite el archivo por completo para el comportamiento por defecto. + +| Ajuste | Descripción | +|---------|-------------| +| `strictness` | Preset de scoring: `strict`, `balanced` (por defecto) o `legacy-friendly` (deducciones más ligeras, encabeza con las correcciones principales) | +| `disable` | Códigos de riesgo a omitir (`R1`–`R6`, `T1`–`T6`) | +| `severity` | Sobrescribe el nivel de severidad (`critical` / `warning` / `suggestion`) | +| `ignore` | Patrones glob de archivos a excluir | +| `focus` | Evalúa solo estos códigos de riesgo (no se puede combinar con `disable`) | +| `custom_risks` | Define códigos de riesgo específicos del proyecto (`C1`, `C2`, …) — consulta [`custom-risks-guide.md`](skills/_shared/custom-risks-guide.md) | +| `suppress` | Rebaja hallazgos específicos por riesgo + ruta (fecha `expires:` opcional) | + +--- + +## ¿Por qué estos libros, por qué ahora? + +En la era de la programación asistida por IA, escribimos más código y más rápido que nunca. Pero las ideas de seis décadas de ingeniería de software no han cambiado: + +> *"La complejidad del software es una propiedad esencial, no accidental."* +> — Frederick Brooks + +La IA puede ayudarte a escribir código más rápido, pero no puede decirte si estás construyendo una catedral o un pozo de brea. **brooks-lint cierra esa brecha** — lleva la sabiduría tan duramente ganada de doce libros clásicos de ingeniería a tu flujo de trabajo de desarrollo moderno. + +Los riesgos de deterioro que identificaron estos autores son más relevantes que nunca: +- **Añadir asistentes de IA** no soluciona la sobrecarga cognitiva ni la distorsión del modelo de dominio +- **Generar más código** aumenta la propagación de cambios y la duplicación de conocimiento +- **Ir más rápido** vuelve aún más peligrosas la complejidad accidental y el desorden de dependencias + +## Estructura del proyecto + +``` +brooks-lint/ +├── .claude-plugin/ # Claude Code plugin metadata +├── .codex-plugin/ # Codex CLI plugin metadata +├── skills/ +│ ├── _shared/ # Shared framework files +│ │ ├── common.md # Iron Law, Project Config, Report Template, Health Score +│ │ ├── source-coverage.md # 12-book coverage matrix, tradeoffs, false-positive guards +│ │ ├── decay-risks.md # Six decay risks with symptoms and book citations +│ │ ├── test-decay-risks.md # Six test-space decay risks with book citations +│ │ ├── remedy-guide.md # --fix mode: actionable Remedy enhancement rules +│ │ └── custom-risks-guide.md # Template for project-specific risk codes +│ ├── brooks-review/ # Mode 1: PR Review +│ │ ├── SKILL.md +│ │ └── pr-review-guide.md +│ ├── brooks-audit/ # Mode 2: Architecture Audit +│ │ ├── SKILL.md +│ │ └── architecture-guide.md +│ ├── brooks-debt/ # Mode 3: Tech Debt Assessment +│ │ ├── SKILL.md +│ │ └── debt-guide.md +│ ├── brooks-test/ # Mode 4: Test Quality Review +│ │ ├── SKILL.md +│ │ └── test-guide.md +│ ├── brooks-health/ # Mode 5: Health Dashboard +│ │ ├── SKILL.md +│ │ └── health-guide.md +│ └── brooks-sweep/ # Mode 6: Full Sweep & Auto-Fix +│ ├── SKILL.md +│ └── sweep-guide.md +├── hooks/ # SessionStart hook +├── commands/ # Short-form command wrappers (auto-installed by hook) +├── evals/ # Benchmark test cases +│ └── evals.json +└── assets/ + └── logo.svg +``` + +## Integración con CI/CD + +Automatiza brooks-lint en cada PR usando la GitHub Action: + +```yaml +# .github/workflows/brooks-lint.yml +name: Brooks-Lint PR Review +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + brooks-lint: + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: hyhmrright/brooks-lint/.github/actions/brooks-lint@main + with: + mode: review + anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} + fail-below: 70 +``` + +Consulta [`docs/github-action-example.yml`](docs/github-action-example.yml) para la plantilla completa. + +La action publica la revisión como un comentario del PR y, opcionalmente, hace fallar el check si la puntuación de salud cae por debajo de un umbral. Si `.brooks-lint-history.json` está confirmado en tu repositorio, el comentario también incluye un delta de tendencia (p. ej., "85 → 82 (−3) en las últimas 3 ejecuciones"). + +**Gates de calidad y Code Scanning.** Más allá de `fail-below`, la action expone: + +```yaml + with: + mode: review + anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} + fail-on: critical # fail on any Critical finding (none | warning | critical) + fail-on-regression: true # fail if the Health Score dropped vs the last run + sarif-file: brooks-lint.sarif # also upload findings to GitHub Code Scanning +``` + +`fail-on-regression` lee `.brooks-lint-history.json`, así que confirma ese archivo para imponer "sin nuevas regresiones". Definir `sarif-file` hace que los hallazgos aparezcan en línea en la pestaña **Files changed** del PR y requiere el permiso `security-events: write` en el job. + +**Coste:** ~$0,05–0,15 por ejecución de PR, según el tamaño del diff y el modelo. Se recomienda ejecutar solo en eventos `pull_request`. + +## Hoja de ruta + +> **Estado actual (v1.4):** base de 12 libros, 6 riesgos de deterioro de producción (R1–R6) + 6 riesgos de deterioro de pruebas (T1–T6), 6 skills — Revisión de PR, Auditoría de arquitectura, Deuda técnica, Calidad de pruebas, Panel de salud, Barrido completo — además de gates de calidad de CI, salida SARIF para GitHub Code Scanning, presets de severidad y un benchmark reproducible de fidelidad del parser. Las entradas anteriores más abajo describen hitos históricos, no el conjunto de funciones actual. + +- [x] **v0.2**: Infraestructura de plugin (`.claude-plugin/`, hooks, comandos de barra) +- [x] **v0.3**: Ocho dimensiones de Brooks, puntuación de completitud de la documentación +- [x] **v0.4**: Framework de seis libros, dimensiones de riesgo de deterioro, cadena de diagnóstico, suite de benchmark +- [x] **v0.5**: Revisión de calidad de pruebas (Modo 4) — cuatro libros de testing, seis riesgos de deterioro de pruebas +- [x] **v0.6**: Grafo de dependencias en Mermaid en la Auditoría de arquitectura +- [x] **v0.7**: Configuración de proyecto `.brooks-lint.yaml`, contexto proactivo del Modo 2, expansión a 10 libros +- [x] **v0.8**: Arquitectura de skills independientes con comandos con espacio de nombres +- [x] **v0.9**: Validación de pasos, alcance de diff automático, panel `/brooks-health`, seguimiento de tendencias, modo triage, remedios `--fix`, informe de incorporación, GitHub Action +- [x] **v1.0**: Automatización de evaluaciones (`run-evals-live.mjs`), extensión de riesgos personalizados (códigos `Cx`) +- [x] **v1.1**: Skill de Barrido completo (`brooks-sweep`) — corrección automática unificada multidimensión +- [x] **v1.2**: Pipeline de barrido autónomo, propagación de versión con `npm run bump` +- [x] **v1.3**: Metadatos de marketplace de Codex, instalador de un solo comando para múltiples plataformas de agentes, README bilingüe + sitio de aterrizaje +- [x] **v1.4**: Salida SARIF para GitHub Code Scanning, gates de CI de severidad + regresión, presets de severidad (strict/balanced/legacy-friendly), suite de evaluaciones de 57 escenarios, benchmark reproducible de fidelidad del parser (`npm run benchmark`) + +¿Quieres ayudar? Las mejores contribuciones ahora mismo son nuevos casos de prueba de evaluación y mejores patrones de síntomas de riesgo de deterioro. Consulta [CONTRIBUTING.md](CONTRIBUTING.md). + +## Contribuir + +Consulta [CONTRIBUTING.md](CONTRIBUTING.md) para saber cómo añadir hallazgos, mejorar guías o ampliar la suite de benchmark. + +Ejecuta `/brooks-review` en tu propio PR — revisamos las contribuciones con la herramienta que estamos construyendo. + +## Licencia + +Licencia MIT — consulta [LICENSE](LICENSE) para más detalles. + +## Agradecimientos + +Este proyecto se apoya en los hombros de doce gigantes: + +**Framework de código de producción** +- Frederick P. Brooks Jr. — *The Mythical Man-Month* (1975, Edición Aniversario 1995) +- Steve McConnell — *Code Complete* (1993, 2.ª ed. 2004) +- Martin Fowler — *Refactoring* (1999, 2.ª ed. 2018) +- Robert C. Martin — *Clean Architecture* (2017) +- Andrew Hunt & David Thomas — *The Pragmatic Programmer* (1999, Edición 20.º Aniversario 2019) +- Eric Evans — *Domain-Driven Design* (2003) +- John Ousterhout — *A Philosophy of Software Design* (2018) +- Titus Winters, Tom Manshreck y Hyrum Wright — *Software Engineering at Google* (2020) + +**Framework de calidad de pruebas** +- Gerard Meszaros — *xUnit Test Patterns* (2007) +- Roy Osherove — *The Art of Unit Testing* (2009, 3.ª ed. 2023) +- Google Engineering — *How Google Tests Software* (2012) +- Michael Feathers — *Working Effectively with Legacy Code* (2004) + +Los riesgos de deterioro codificados en esta herramienta son nuestra síntesis de sus ideas, aplicada a la evaluación moderna de la calidad del código. + +--- + +## Historial de estrellas + +[![Star History Chart](https://api.star-history.com/svg?repos=hyhmrright/brooks-lint&type=Date)](https://star-history.com/#hyhmrright/brooks-lint&Date) + +--- + +

+ ⭐ Si esta herramienta te ayudó a ver tu base de código de otra manera, ¡dale una estrella! +

diff --git a/brooks-lint/README.ja.md b/brooks-lint/README.ja.md new file mode 100644 index 00000000..1f7a0251 --- /dev/null +++ b/brooks-lint/README.ja.md @@ -0,0 +1,690 @@ +

+ brooks-lint +

+ +

brooks-lint

+ +

+ 十二冊の古典的ソフトウェア工学書に根ざした AI コードレビュー。
+ 一貫性があり、追跡可能で、実行に移せる。
+

+ +

+ English · + 简体中文 · + 繁體中文 · + 日本語 · + 한국어 · + Español +

+ +

+ クイックスタート • + 六つの劣化リスク • + 出力イメージ • + ベンチマーク • + インストール +

+ +

+ Version + MIT License + Claude Code Plugin + Codex CLI Skill + GitHub Stars +

+ +

+ 本日の JavaScript リポジトリ第 2 位 | Trendshift +

+ +

+ あなたのコード → 十二冊の古典 → 十二の劣化リスク → 出典付きの指摘 +

+ +

+ brooks-lint がコードをレビューする様子:1 つの /brooks-review コマンドで 28/100 の健全性スコアと、書籍を引用した 症状 → 根源 → 結果 → 対策 の指摘を生成 +

+ +

+ → ウェブサイトを見る +

+ +--- + +> *"一人の子を産むのに九か月かかるのは、何人の女性を割り当てても変わらない。"* +> — Frederick Brooks, *The Mythical Man-Month*(人月の神話、1975) + +**50 年が経った今も Brooks は正しかった——そして McConnell、Fowler、Martin、Hunt & Thomas、Evans、Ousterhout、Winters、Meszaros、Osherove、Feathers、そして Google のテストチームもまた正しかった。** + +ほとんどのコード品質ツールは行数と循環的複雑度を数えるだけです。**brooks-lint** はさらに踏み込みます——十二冊の古典的ソフトウェア工学書から統合した六つの劣化リスク次元に照らしてコードを診断し、毎回、書籍の出典・重大度ラベル・具体的な対策を備えた構造化された指摘を生成します。 + +例外や誤検知ガードを含む「出典—スキル」の完全なマッピングは、 +[`skills/_shared/source-coverage.md`](skills/_shared/source-coverage.md) を参照してください。 + +## クイックスタート + +```bash +# Claude Code +/plugin marketplace add hyhmrright/brooks-lint +/plugin install brooks-lint@brooks-lint-marketplace + +# その他あらゆる Agent Skills プラットフォーム — Cursor · Codex · Gemini · Copilot · Windsurf · OpenCode · Kiro · … +curl -fsSL https://raw.githubusercontent.com/hyhmrright/brooks-lint/main/scripts/install.sh | bash -s -- +``` + +あとは話しかけるだけ(「この PR をレビューして」「アーキテクチャを監査して」)——あるいはコマンドを実行します。 + +| コマンド | 機能 | +|---------|--------------| +| `/brooks-review` | PR または diff をレビュー | +| `/brooks-audit` | アーキテクチャを監査(+ Mermaid 依存関係グラフ) | +| `/brooks-debt` | 優先順位付けされた技術的負債のロードマップ | +| `/brooks-test` | テストスイートの品質レビュー | +| `/brooks-health` | 全次元を横断する健全性ダッシュボード | +| `/brooks-sweep` | 全次元をスイープし、指摘を自動修正 | + +すべての指摘は **症状 → 根源 → 結果 → 対策** の形式で、書籍の出典と 0〜100 の健全性スコアとともに返されます。完全なインストール方法(さらに 8 つのプラットフォーム)、コマンドごとの使い方、CI/CD のセットアップは[以下](#インストール)を参照してください。 + +## 十二冊の書籍 + +| 書籍 | 著者 | 寄与する先 | +|------|--------|----------------| +| *The Mythical Man-Month*(人月の神話) | Frederick Brooks | R2, R4, R5 | +| *Code Complete*(コードコンプリート) | Steve McConnell | R1, R4 | +| *Refactoring*(リファクタリング) | Martin Fowler | R1, R2, R3, R4, R6 | +| *Clean Architecture*(クリーンアーキテクチャ) | Robert C. Martin | R2, R5 | +| *The Pragmatic Programmer*(達人プログラマー) | Hunt & Thomas | R2, R3, R4, R5, T2, T3 | +| *Domain-Driven Design*(エリック・エヴァンスのドメイン駆動設計) | Eric Evans | R1, R3, R6 | +| *A Philosophy of Software Design*(ソフトウェア設計の哲学) | John Ousterhout | R1, R4 | +| *Software Engineering at Google*(Google のソフトウェアエンジニアリング) | Winters, Manshreck & Wright | R2, R5 | +| *The Art of Unit Testing*(単体テストの考え方/使い方) | Roy Osherove | T1, T2, T4, T5 | +| *How Google Tests Software*(テストから見えてくるグーグルのソフトウェア開発) | James A. Whittaker, Jason Arbon & Jeff Carollo | T5, T6 | +| *Working Effectively with Legacy Code*(レガシーコード改善ガイド) | Michael Feathers | T4, T5, T6 | +| *xUnit Test Patterns*(xUnit テストパターン) | Gerard Meszaros | T1, T2, T3, T4 | + +## 六つの劣化リスク + +brooks-lint は、十二冊の古典的ソフトウェア工学書から統合した**六つの本番コード劣化リスク**と**六つのテストスイート劣化リスク**の観点から、あなたのコードを評価します。 + +| 劣化リスク | 診断のための問い | 出典 | +|------------|---------------------|---------| +| 🧠 認知過負荷 | これを理解するのにどれだけの精神的労力が要るか? | Code Complete, Refactoring, DDD, Philosophy of SD | +| 🔗 変更の波及 | 1 つの変更でいくつの無関係なものが壊れるか? | Refactoring, Clean Architecture, Pragmatic, SE@Google | +| 📋 知識の重複 | 同じ決定が複数の場所で表現されていないか? | Pragmatic, Refactoring, DDD | +| 🌀 偶発的複雑性 | コードは問題そのものより複雑になっていないか? | Refactoring, Code Complete, Brooks, Philosophy of SD | +| 🏗️ 依存関係の無秩序 | 依存は一貫した方向に流れているか? | Clean Architecture, Brooks, Pragmatic, SE@Google | +| 🗺️ ドメインモデルの歪み | コードはドメインを忠実に表現しているか? | DDD, Refactoring | + +> Philosophy of SD = *A Philosophy of Software Design*(Ousterhout) · SE@Google = *Software Engineering at Google*(Winters ほか) + +## 出力イメージ + +次のコードが与えられたとき: + +```python +class UserService: + def update_profile(self, user_id, name, email, avatar_url): + user = self.db.query(f"SELECT * FROM users WHERE id = {user_id}") + user['email'] = email + ... + if user['email'] != email: # always False — silent bug + self.smtp.send(...) + points = user['login_count'] * 10 + 500 + self.db.execute(f"UPDATE loyalty SET points={points} WHERE user_id={user_id}") +``` + +brooks-lint は次を生成します: + +--- + +**健全性スコア:28/100** + +*このメソッドは四つの無関係なビジネス責務を 1 つの関数に集約し、メールアドレス変更通知を静かに握りつぶすロジックバグを含み、SQL インジェクションに対して無防備です。* + +### 🔴 変更の波及 — 単一のメソッドが四つの無関係なビジネス理由で変更される +**症状:** `update_profile` は、プロフィール項目の更新、メールアドレス変更通知、ロイヤルティポイントの再計算、キャッシュの無効化を、すべて 1 つのメソッド本体で実行しています。 +**根源:** Fowler — *Refactoring* — Divergent Change(発散的変更);Hunt & Thomas — *The Pragmatic Programmer* — Orthogonality(直交性) +**結果:** ロイヤルティの計算式を変更すると、メール通知を壊すおそれがあり、その逆もまた然りです。すべての編集が、四つの無関係なドメインに同時にまたがる回帰リスクを背負います。 +**対策:** `NotificationService`、`LoyaltyService`、`UserCacheInvalidator` を抽出します。`UserService.update_profile` はそれぞれを呼び出してオーケストレーションするだけにし、自身は実装ロジックを一切持たないようにします。 + +### 🔴 ドメインモデルの歪み — 静かなロジックバグ:メール通知が決して発火しない +**症状:** `user['email'] = email` が `if user['email'] != email` より前に古い値を上書きするため、条件は常に `False` です。通知はデッドコードです。 +**根源:** McConnell — *Code Complete* — 第 17 章:変則的な制御構造 +**結果:** ユーザーはメールアドレスを変更しても決して通知されません。静かなデータ整合性の破綻です——システムは正常に動作しているように見えながら、ビジネスルールに違反しています。 +**対策:** いかなる変更の前にも `old_email = user['email']` を捕捉します。`user['email']` ではなく `old_email` と比較してください。 + +*(SQL インジェクション、依存関係の無秩序、マジックナンバーを含む、さらに 6 件の指摘)* + +### 依存関係グラフ付きのアーキテクチャ監査 + +モード 2(アーキテクチャ監査)では、brooks-lint はレポートの先頭に **Mermaid 依存関係グラフ** を生成します。モジュールは重大度で色分けされます:赤 = Critical の指摘、黄 = Warning、緑 = クリーン。 + +```mermaid +graph TD + subgraph src/api + AuthController + UserController + end + subgraph src/domain + UserService + OrderService + end + subgraph src/infra + Database + EmailClient + end + + AuthController --> UserService + UserController --> UserService + UserController --> OrderService + OrderService --> UserService + OrderService --> EmailClient + UserService --> Database + EmailClient -.->|circular| OrderService + + classDef critical fill:#ff6b6b,stroke:#c92a2a,color:#fff + classDef warning fill:#ffd43b,stroke:#e67700 + classDef clean fill:#51cf66,stroke:#2b8a3e,color:#fff + + class OrderService,EmailClient critical + class AuthController warning + class UserService,UserController,Database clean +``` + +このグラフは GitHub、Notion、その他の Markdown 環境でネイティブにレンダリングされます——追加のツールは不要です。 + +## さらなる例を見る + +[完全ギャラリー](docs/gallery.md) には、Python、TypeScript、Go、Java にわたる brooks-lint の実際の出力が収められています——PR レビュー、Mermaid 依存関係グラフ付きのアーキテクチャ監査、技術的負債の評価、テスト品質レビューを含みます。 + +劣化リスクが初めてですか?[**劣化リスク実践ガイド**](https://hyhmrright.github.io/brooks-lint/guide.html) が六つすべてを解説します——それぞれの診断のための問い、典型的な症状、出典書籍、そして対策。 + +--- + +## ベンチマーク + +3 つの実世界シナリオ(PR レビュー、アーキテクチャ監査、技術的負債の評価)でテストしました: + +| 評価項目 | brooks-lint | Claude 単独 | +|-----------|:-----------:|:------------:| +| 構造化された指摘(症状 → 根源 → 結果 → 対策) | ✅ 100% | ❌ 0% | +| 指摘ごとの書籍引用 | ✅ 100% | ❌ 0% | +| 重大度ラベル(🔴/🟡/🟢) | ✅ 100% | ❌ 0% | +| 健全性スコア(0〜100) | ✅ 100% | ❌ 0% | +| 「変更の波及」を検出 | ✅ 100% | ✅ 100% | +| **総合合格率** | **94%** | **16%** | + +差は Claude が何を見つけ*られる*かではありません——何を*毎回一貫して*、追跡可能な根拠と実行可能な対策とともに見つけるか、です。 + +### 再現可能なベンチマーク + +上の表は説明用です。次の数値は**決定論的であり、ローカルで再現できます**: + +**パーサー忠実度** — SARIF エクスポートと CI ゲートは、モデルの Markdown レポートを正しく解析できることに依存しています。全六モードにまたがる**30 件の実在するモデル生成レポートの凍結コーパス**(`evals/benchmark-corpus.json`)に対して——各レポートには**独立して採点された**指摘インベントリ(別のモデルパスによるもので、手作業でスポットチェック済み)が対になっています——出荷されているパーサーは次のスコアを出します。`npm run benchmark` を実行してください: + +| 指標(n = 30、凍結コーパス) | 結果 | +|---|:---:| +| 重大度カウントの完全一致(パーサー vs 採点済み真値) | 30 / 30 | +| リスクコードの precision / recall | 100% / 100%(56 件の finding レベルコード、0 FP / 0 FN) | +| 妥当な SARIF 2.1.0 の出力 | 30 / 30 | + +パーサーは決定論的で、コーパスは凍結されているため、`npm run benchmark` は誰に対しても同じ結果を返し、`npm test` がこれを回帰として守ります。このコーパスには、クリーンなままであるべき 9 件の誤検知 / トレードオフレポート(例:依存サイクルの*ように見える*ポートとアダプターの設計)が意図的に含まれています。 + +**スコアリングの決定論性** — 固定された指摘集合(2 Critical / 3 Warning / 1 Suggestion)に対し、厳格度プリセットは `common.md` の表が予測する通りのスコアを正確に算出します:strict **34**、balanced **54**、legacy-friendly **74**——そして上位三件の修正を先頭に示すのは `legacy-friendly` だけです。 + +**モデル品質** — モデルが実際のコードで*正しい*リスクを見つけられるかは、**57 シナリオの eval スイート**(`evals/evals.json`)で測定されます:`npm run evals`(構造)と `npm run evals:live`(ライブ、`ANTHROPIC_API_KEY` が必要)。 + +> 範囲と誠実さについて:パーサーの数値は決定論的で、正確に再現可能です。厳格度と eval スイートの数値はモデルに対する単発のライブ測定で、実行ごとにわずかに変動します。パーサーのベンチマークが測るのはレポート解析の忠実度(ツールはレポートに書かれたすべての指摘を読み取れるか)であって、ある指摘が「正しい」かどうかではありません。重大度カウントの一致は完全に独立したシグナルです。リスクコードの一致は、共有された正規の name→code 凡例も反映しています。 + +## 比較 + +| | brooks-lint | ESLint / Pylint | GitHub Copilot Review | 素の Claude | +|---|:---:|:---:|:---:|:---:| +| 構文・スタイルの問題を検出 | — | ✅ | ✅ | ~ | +| 構造化された診断チェーン | ✅ | ❌ | ❌ | ❌ | +| 指摘を古典書籍まで遡る | ✅ | ❌ | ❌ | ❌ | +| 一貫した重大度ラベル | ✅ | ✅ | ~ | ❌ | +| アーキテクチャレベルの洞察 | ✅ | ❌ | ~ | ~ | +| ドメインモデル分析 | ✅ | ❌ | ❌ | ~ | +| 設定不要、インストールするプラグインなし | ✅ | ❌ | ✅ | ✅ | +| あらゆる言語で動作 | ✅ | ❌ | ✅ | ✅ | + +> `~` = 時々 / 一貫しない + +**brooks-lint はあなたの linter を置き換えるものではありません。** それが捉えるのは linter には捉えられないもの——アーキテクチャのドリフト、知識のサイロ化、ドメインモデルの歪みです。これらは、誰かが気づくまで何か月もチームの足を引っ張る問題です。 + +## インストール + +### Claude Code(推奨) + +#### プラグインマーケットプレイス経由 +```bash +/plugin marketplace add hyhmrright/brooks-lint +/plugin install brooks-lint@brooks-lint-marketplace +``` + +短縮形コマンド(`/brooks-review`)は、最初のセッション開始時に自動インストールされます。手動でインストールするには: +```bash +cp commands/*.md ~/.claude/commands/ +``` + +#### 手動インストール +```bash +mkdir -p ~/.claude/skills/brooks-lint +cp -r skills/* ~/.claude/skills/brooks-lint/ +``` + +### Gemini CLI + +#### 拡張機能経由 +```bash +/extensions install https://github.com/hyhmrright/brooks-lint +``` + +#### 手動インストール +```bash +mkdir -p ~/.gemini/skills +cp -r skills/* ~/.gemini/skills/ # フラット — Gemini はスキルを 1 階層深さまでしか発見しない +``` +> または単に:`./scripts/install.sh gemini` + +### Codex CLI + +#### スキルインストーラー経由(Codex セッション内) +``` +Install the brooks-lint skill from hyhmrright/brooks-lint +``` + +#### コマンドライン +```bash +python3 ~/.codex/skills/.system/skill-installer/scripts/install-skill-from-github.py \ + --repo hyhmrright/brooks-lint --path skills --name brooks-lint +``` + +#### 手動インストール +```bash +git clone https://github.com/hyhmrright/brooks-lint.git /tmp/brooks-lint +mkdir -p ~/.codex/skills +cp -r /tmp/brooks-lint/skills/* ~/.codex/skills/ # フラット — スキルインストーラーのレイアウトと一致 +``` +> または単に:`./scripts/install.sh codex` + +### さらなるプラットフォーム — OpenCode · Cursor · Windsurf · Antigravity · pi · Copilot · Kiro · Factory Droid + +brooks-lint は標準的な [Agent Skills](https://agentskills.io) として配布されています。**Agent +Skills を読み込むエージェントなら、どれも変換なしで六つすべてのモードを実行できます**——1 つのコマンドでインストールできます: + +```bash +# プラットフォームを選択;--project はグローバル設定ではなく現在のリポジトリにインストール +curl -fsSL https://raw.githubusercontent.com/hyhmrright/brooks-lint/main/scripts/install.sh | bash -s -- +# = opencode · cursor · windsurf · antigravity · pi · kiro · copilot · droid · gemini · codex · agents +``` + +インストーラーはスキルをあなたのプラットフォームに適したフォルダへ**フラット**にコピーするため、共有フレームワーク +(`../_shared/`)は常に正しく解決されます——レイアウトを間違えようがありません。あとは話しかけるだけ +(「この PR をレビューして」「アーキテクチャを監査して」)で、該当するスキルがその +`description` に基づいて自動的にトリガーされます。スキルが初めて、または別のエージェントをお使いですか? **[docs/getting-started.md](docs/getting-started.md)** を参照してください。 + +
OpenCode + +`./scripts/install.sh opencode` → `~/.config/opencode/skills`(`~/.claude/skills` と +`AGENTS.md` も読み取ります)。完全ガイド:[docs/opencode-setup.md](docs/opencode-setup.md)。 +
+ +
Cursor(2.4+) + +`./scripts/install.sh cursor` → `~/.cursor/skills`(`.agents/skills` も;`AGENTS.md` を読み取ります)。 +完全ガイド:[docs/cursor-setup.md](docs/cursor-setup.md)。 +
+ +
Windsurf(Cascade) + +`./scripts/install.sh windsurf` → `~/.codeium/windsurf/skills`(`AGENTS.md` を読み取ります)。 +完全ガイド:[docs/windsurf-setup.md](docs/windsurf-setup.md)。 +
+ +
Antigravity(Google) + +`./scripts/install.sh antigravity --project` → `.agent/skills`(`AGENTS.md` / `GEMINI.md` を読み取ります)。 +完全ガイド:[docs/antigravity-setup.md](docs/antigravity-setup.md)。 +
+ +
pi(earendil-works) + +`./scripts/install.sh pi` → `~/.pi/agent/skills`、または pi の `skills` 設定をクローンに向けます。 +完全ガイド:[docs/pi-setup.md](docs/pi-setup.md)。 +
+ +
GitHub Copilot + +`./scripts/install.sh copilot --project` → `.github/skills`(`.claude/skills` も自動検出; +`AGENTS.md` を読み取ります)。完全ガイド:[docs/copilot-setup.md](docs/copilot-setup.md)。 +
+ +
Kiro(AWS) + +`./scripts/install.sh kiro` → `~/.kiro/skills`(`/brooks-review` を自動登録;`AGENTS.md` を読み取ります)。 +完全ガイド:[docs/kiro-setup.md](docs/kiro-setup.md)。 +
+ +
Factory Droid + +`./scripts/install.sh droid` → `~/.factory/skills`(`/brooks-review` を登録;`AGENTS.md` を読み取ります)。 +完全ガイド:[docs/factory-droid-setup.md](docs/factory-droid-setup.md)。 +
+ +> **🧪 検証状況。** Claude Code、Gemini CLI、Codex CLI はメンテナーによって検証済みです。上記の八つの +> プラットフォームは各ツールの公式スキル仕様から文書化され、ファイルレイアウトのレベルで検証されています +> (インストーラーはテスト済み)が、メンテナーがすべてのプラットフォームでエンドツーエンドに実行したわけ +> ではまだありません。どれかを試した——動いた **または** 壊れた? プラットフォーム、バージョン、見たこと +> を添えて [issue を立ててください](https://github.com/hyhmrright/brooks-lint/issues/new)。別の +> Agent-Skills エージェント? ほぼ確実に同じように動作します——お知らせいただければ追加します。 + +## スラッシュコマンド + +### Claude Code +| コマンド | 短縮形 | アクション | +|---------|------------|--------| +| `/brooks-lint:brooks-review` | `/brooks-review` | PR レベルのコードレビュー | +| `/brooks-lint:brooks-audit` | `/brooks-audit` | 完全なアーキテクチャ監査 | +| `/brooks-lint:brooks-debt` | `/brooks-debt` | 技術的負債の評価 | +| `/brooks-lint:brooks-test` | `/brooks-test` | テストスイートの健全性レビュー | +| `/brooks-lint:brooks-health` | `/brooks-health` | 健全性ダッシュボード — 全四次元 | +| `/brooks-lint:brooks-sweep` | `/brooks-sweep` | 全面スイープ — 全次元を分析し指摘を自動修正 | + +> 短縮形コマンドは、session-start フックによって最初のセッション開始時に自動インストールされます。 + +### Gemini CLI +| コマンド | アクション | +|---------|--------| +| `/brooks-review` | PR レベルのコードレビュー | +| `/brooks-audit` | 完全なアーキテクチャ監査 | +| `/brooks-debt` | 技術的負債の評価 | +| `/brooks-test` | テストスイートの健全性レビュー | +| `/brooks-health` | 健全性ダッシュボード — 全四次元 | +| `/brooks-sweep` | 全面スイープ — 全次元を分析し指摘を自動修正 | + +### Codex CLI + +| コマンド | アクション | +|---------|--------| +| `$brooks-review` | PR レベルのコードレビュー | +| `$brooks-audit` | 完全なアーキテクチャ監査 | +| `$brooks-debt` | 技術的負債の評価 | +| `$brooks-test` | テストスイートの健全性レビュー | +| `$brooks-health` | 健全性ダッシュボード — 全四次元 | +| `$brooks-sweep` | 全面スイープ — 全次元を分析し指摘を自動修正 | + +コード品質、アーキテクチャ、保守性、テストの健全性について話すと、これらのスキルは自動的にもトリガーされます。 + +### OpenCode · Cursor · Antigravity · pi + +これらのプラットフォームは、各スキルの `description` に基づいて Agent Skills を自動的に呼び出します——話しかけるだけ +(「この PR をレビューして」「アーキテクチャを監査して」「うちの最悪の技術的負債はどこ?」)で、該当するモードが +実行されます。明示的に呼び出すには、各プラットフォームのスキルコマンド構文を使います(例:pi は各スキルを +`/skill:brooks-review` として登録します;Cursor と OpenCode はスキルが発見されると `/brooks-review` を公開します)。 + +## 使い方 + +### PR レビュー + +``` +/brooks-review # Claude Code(短縮形)/ Gemini CLI +/brooks-lint:brooks-review # Claude Code(完全形) +$brooks-review # Codex CLI +``` + +diff を貼り付けるか、AI を変更されたファイルに向けてください。六つの劣化リスクそれぞれを、症状 → 根源 → 結果 → 対策 の形式で具体的な指摘とともに診断します。 + +### アーキテクチャ監査 + +``` +/brooks-audit # Claude Code(短縮形)/ Gemini CLI +/brooks-lint:brooks-audit # Claude Code(完全形) +$brooks-audit # Codex CLI +``` + +プロジェクト構造を説明するか、主要なファイルを共有してください。モジュールの依存関係をマッピングし、循環依存を特定し、コンウェイの法則との整合性をチェックします。 + +### 技術的負債の評価 + +``` +/brooks-debt # Claude Code(短縮形)/ Gemini CLI +/brooks-lint:brooks-debt # Claude Code(完全形) +$brooks-debt # Codex CLI +``` + +あなたの負債を六つの劣化リスクにわたって分類し、各指摘を 痛み × 広がり の優先度で採点し、Critical / Scheduled / Monitored の分類を備えた優先順位付き返済ロードマップを生成します。 + +### テスト品質レビュー + +``` +/brooks-test # Claude Code(短縮形)/ Gemini CLI +/brooks-lint:brooks-test # Claude Code(完全形) +$brooks-test # Codex CLI +``` + +あなたのテストスイートを、六つのテスト空間の劣化リスク——テストの不透明性、テストの脆さ、テストの重複、モックの濫用、カバレッジの幻想、アーキテクチャの不一致——に照らして監査します。出典は xUnit Test Patterns、The Art of Unit Testing、How Google Tests Software、Working Effectively with Legacy Code です。PR レビューには、軽量な Step 7 のクイックテストチェックも自動的に含まれます(ドキュメントのみ、または非本番の diff ではスキップ)。 + +### 健全性ダッシュボード + +``` +/brooks-health # Claude Code(短縮形)/ Gemini CLI +/brooks-lint:brooks-health # Claude Code(完全形) +$brooks-health # Codex CLI +``` + +全四つの品質次元にわたって簡略化されたスキャンを実行し、重み付けされた総合健全性スコア(0〜100)を生成します。リリース前、新しいチームのオンボーディング時、あるいは「うちは今どうなっている?」という全体像レポートが欲しいときに使ってください。いずれかの次元についてより深い診断が必要な場合は、代わりに専用スキルを使ってください。 + +### 全面スイープ + +``` +/brooks-sweep # Claude Code(短縮形)/ Gemini CLI +/brooks-lint:brooks-sweep # Claude Code(完全形) +$brooks-sweep # Codex CLI +``` + +すべての本番(R1–R6)とテスト(T1–T6)の劣化リスク、加えてアーキテクチャを一度のパスでスキャンし、その後修正を適用します:安全な変更は即座に自動適用され、複数ファイルにまたがる、またはインターフェースに触れる変更は確認を必要とし、複雑なアーキテクチャ上の決定は手動対応項目としてフラグが立てられます。修正ログ、健全性スコアの差分、残存項目リストを出力します。 + +## 設定 + +レビューの挙動をカスタマイズするには、プロジェクトのルートに `.brooks-lint.yaml` を置きます: + +```yaml +version: 1 + +strictness: balanced # strict | balanced (default) | legacy-friendly — softer scoring for legacy code + +disable: + - T5 # skip coverage metrics check — we don't enforce coverage + +severity: + R1: suggestion # downgrade Cognitive Overload findings for this domain + +ignore: + - "**/*.generated.*" + - "**/vendor/**" + +# custom_risks: # define project-specific Cx codes — see skills/_shared/custom-risks-guide.md +# suppress: # downgrade specific findings by risk + path (e.g. accepted legacy debt) +``` + +出発点として [`.brooks-lint.example.yaml`](.brooks-lint.example.yaml) をコピーしてください。 +すべての設定は任意です——ファイルを完全に省略すればデフォルトの挙動になります。 + +| 設定 | 説明 | +|---------|-------------| +| `strictness` | スコアリングプリセット:`strict`、`balanced`(デフォルト)、または `legacy-friendly`(軽めの減点で、上位の修正を先頭に示す) | +| `disable` | スキップするリスクコード(`R1`–`R6`、`T1`–`T6`) | +| `severity` | 重大度ティアを上書き(`critical` / `warning` / `suggestion`) | +| `ignore` | 除外するファイルの glob パターン | +| `focus` | これらのリスクコードのみを評価(`disable` とは併用不可) | +| `custom_risks` | プロジェクト固有のリスクコードを定義(`C1`、`C2`、…)——[`custom-risks-guide.md`](skills/_shared/custom-risks-guide.md) を参照 | +| `suppress` | リスク + パスで特定の指摘を格下げ(任意の `expires:` 日付付き) | + +--- + +## なぜこれらの書籍か、なぜ今か? + +AI 支援コーディングの時代において、私たちはこれまで以上に速く、多くのコードを書いています。しかし、六十年にわたるソフトウェア工学の洞察は変わっていません: + +> *"ソフトウェアの複雑性は本質的な性質であって、偶発的な性質ではない。"* +> — Frederick Brooks + +AI はコードをより速く書く手助けはできても、あなたが大聖堂を建てているのかタールの穴を掘っているのかは教えてくれません。**brooks-lint はそのギャップを埋めます**——十二冊の古典的ソフトウェア工学書から得られた、苦労して獲得された知恵を、あなたの現代的な開発ワークフローに持ち込みます。 + +これらの著者が特定した劣化リスクは、かつてないほど切実です: +- **AI アシスタントを追加しても** 認知過負荷やドメインモデルの歪みは解消されません +- **より多くのコードを生成すると** 変更の波及と知識の重複が増大します +- **より速く動くことは** 偶発的複雑性と依存関係の無秩序をいっそう危険にします + +## プロジェクト構成 + +``` +brooks-lint/ +├── .claude-plugin/ # Claude Code plugin metadata +├── .codex-plugin/ # Codex CLI plugin metadata +├── skills/ +│ ├── _shared/ # Shared framework files +│ │ ├── common.md # Iron Law, Project Config, Report Template, Health Score +│ │ ├── source-coverage.md # 12-book coverage matrix, tradeoffs, false-positive guards +│ │ ├── decay-risks.md # Six decay risks with symptoms and book citations +│ │ ├── test-decay-risks.md # Six test-space decay risks with book citations +│ │ ├── remedy-guide.md # --fix mode: actionable Remedy enhancement rules +│ │ └── custom-risks-guide.md # Template for project-specific risk codes +│ ├── brooks-review/ # Mode 1: PR Review +│ │ ├── SKILL.md +│ │ └── pr-review-guide.md +│ ├── brooks-audit/ # Mode 2: Architecture Audit +│ │ ├── SKILL.md +│ │ └── architecture-guide.md +│ ├── brooks-debt/ # Mode 3: Tech Debt Assessment +│ │ ├── SKILL.md +│ │ └── debt-guide.md +│ ├── brooks-test/ # Mode 4: Test Quality Review +│ │ ├── SKILL.md +│ │ └── test-guide.md +│ ├── brooks-health/ # Mode 5: Health Dashboard +│ │ ├── SKILL.md +│ │ └── health-guide.md +│ └── brooks-sweep/ # Mode 6: Full Sweep & Auto-Fix +│ ├── SKILL.md +│ └── sweep-guide.md +├── hooks/ # SessionStart hook +├── commands/ # Short-form command wrappers (auto-installed by hook) +├── evals/ # Benchmark test cases +│ └── evals.json +└── assets/ + └── logo.svg +``` + +## CI/CD 統合 + +GitHub Action を使って、すべての PR で brooks-lint を自動実行します: + +```yaml +# .github/workflows/brooks-lint.yml +name: Brooks-Lint PR Review +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + brooks-lint: + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: hyhmrright/brooks-lint/.github/actions/brooks-lint@main + with: + mode: review + anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} + fail-below: 70 +``` + +完全なテンプレートは [`docs/github-action-example.yml`](docs/github-action-example.yml) を参照してください。 + +この Action はレビューを PR コメントとして投稿し、必要に応じて健全性スコアがしきい値を下回った場合にチェックを失敗させます。`.brooks-lint-history.json` がリポジトリにコミットされていれば、コメントにはトレンドの差分も含まれます(例:「85 → 82(−3)、直近 3 回の実行」)。 + +**品質ゲートと Code Scanning。** `fail-below` に加えて、この Action は次を公開しています: + +```yaml + with: + mode: review + anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} + fail-on: critical # fail on any Critical finding (none | warning | critical) + fail-on-regression: true # fail if the Health Score dropped vs the last run + sarif-file: brooks-lint.sarif # also upload findings to GitHub Code Scanning +``` + +`fail-on-regression` は `.brooks-lint-history.json` を読み取るため、そのファイルをコミットすれば「新たな回帰なし」を強制できます。`sarif-file` を設定すると、指摘が PR の **Files changed** タブにインラインで表示されるようになり、ジョブに `security-events: write` 権限が必要になります。 + +**コスト:** PR 実行ごとにおよそ $0.05〜0.15、diff のサイズとモデルによります。`pull_request` イベントのみで実行することを推奨します。 + +## ロードマップ + +> **現状(v1.4):** 12 冊の書籍を土台に、6 つの本番劣化リスク(R1–R6)+ 6 つのテスト劣化リスク(T1–T6)、6 つのスキル——PR レビュー、アーキテクチャ監査、技術的負債、テスト品質、健全性ダッシュボード、全面スイープ——に加え、CI 品質ゲート、GitHub Code Scanning 向けの SARIF 出力、厳格度プリセット、そして再現可能なパーサー忠実度ベンチマーク。下の以前のエントリは歴史的なマイルストーンを記述したものであり、現在の機能セットではありません。 + +- [x] **v0.2**:プラグインインフラ(`.claude-plugin/`、フック、スラッシュコマンド) +- [x] **v0.3**:八つの Brooks 次元、ドキュメント完全性スコアリング +- [x] **v0.4**:六冊の書籍フレームワーク、劣化リスク次元、診断チェーン、ベンチマークスイート +- [x] **v0.5**:テスト品質レビュー(モード 4)——四冊のテスト書籍、六つのテスト劣化リスク +- [x] **v0.6**:アーキテクチャ監査における Mermaid 依存関係グラフ +- [x] **v0.7**:`.brooks-lint.yaml` プロジェクト設定、モード 2 のプロアクティブコンテキスト、10 冊への拡張 +- [x] **v0.8**:名前空間付きコマンドを備えた独立スキルアーキテクチャ +- [x] **v0.9**:ステップ検証、自動 diff スコープ、`/brooks-health` ダッシュボード、トレンド追跡、トリアージモード、`--fix` 対策、オンボーディングレポート、GitHub Action +- [x] **v1.0**:eval 自動化(`run-evals-live.mjs`)、カスタムリスク拡張(`Cx` コード) +- [x] **v1.1**:全面スイープスキル(`brooks-sweep`)——統合された多次元自動修正 +- [x] **v1.2**:自律的なスイープパイプライン、`npm run bump` によるバージョン伝播 +- [x] **v1.3**:Codex マーケットプレイスメタデータ、複数のエージェントプラットフォーム向けのワンコマンドインストーラー、バイリンガル README + ランディングサイト +- [x] **v1.4**:GitHub Code Scanning 向けの SARIF 出力、CI の severity + 回帰ゲート、厳格度プリセット(strict/balanced/legacy-friendly)、57 シナリオの eval スイート、再現可能なパーサー忠実度ベンチマーク(`npm run benchmark`) + +手伝いたいですか? 今もっとも価値ある貢献は、新しい eval テストケースと、より優れた劣化リスクの症状パターンです。[CONTRIBUTING.md](CONTRIBUTING.md) を参照してください。 + +## 貢献 + +指摘の追加、ガイドの改善、ベンチマークスイートの拡張の方法は [CONTRIBUTING.md](CONTRIBUTING.md) を参照してください。 + +あなた自身の PR で `/brooks-review` を実行してください——私たちは、作っているそのツールで貢献をレビューしています。 + +## ライセンス + +MIT License——詳細は [LICENSE](LICENSE) を参照してください。 + +## 謝辞 + +このプロジェクトは十二人の巨人の肩の上に立っています: + +**本番コードフレームワーク** +- Frederick P. Brooks Jr. — *The Mythical Man-Month*(1975、記念版 1995) +- Steve McConnell — *Code Complete*(1993、第 2 版 2004) +- Martin Fowler — *Refactoring*(1999、第 2 版 2018) +- Robert C. Martin — *Clean Architecture*(2017) +- Andrew Hunt & David Thomas — *The Pragmatic Programmer*(1999、20 周年版 2019) +- Eric Evans — *Domain-Driven Design*(2003) +- John Ousterhout — *A Philosophy of Software Design*(2018) +- Titus Winters, Tom Manshreck, Hyrum Wright — *Software Engineering at Google*(2020) + +**テスト品質フレームワーク** +- Gerard Meszaros — *xUnit Test Patterns*(2007) +- Roy Osherove — *The Art of Unit Testing*(2009、第 3 版 2023) +- Google Engineering — *How Google Tests Software*(2012) +- Michael Feathers — *Working Effectively with Legacy Code*(2004) + +このツールにエンコードされた劣化リスクは、彼らのアイデアを統合し、現代のコード品質評価に応用した私たちの成果です。 + +--- + +## スター履歴 + +[![Star History Chart](https://api.star-history.com/svg?repos=hyhmrright/brooks-lint&type=Date)](https://star-history.com/#hyhmrright/brooks-lint&Date) + +--- + +

+ ⭐ このツールがあなたのコードベースを違った目で見る助けになったなら、スターをお願いします! +

diff --git a/brooks-lint/README.ko.md b/brooks-lint/README.ko.md new file mode 100644 index 00000000..ac1bde70 --- /dev/null +++ b/brooks-lint/README.ko.md @@ -0,0 +1,691 @@ +

+ brooks-lint +

+ +

brooks-lint

+ +

+ 열두 권의 고전 엔지니어링 도서에 뿌리를 둔 AI 코드 리뷰.
+ 일관적이고, 추적 가능하며, 실행 가능합니다.
+

+ +

+ English · + 简体中文 · + 繁體中文 · + 日本語 · + 한국어 · + Español +

+ +

+ 빠른 시작 • + 여섯 가지 쇠퇴 위험 • + 실제 결과물 • + 벤치마크 • + 설치 +

+ +

+ Version + MIT License + Claude Code Plugin + Codex CLI Skill + GitHub Stars +

+ +

+ Trendshift 오늘의 JavaScript 저장소 2위 +

+ +

+ 당신의 코드 → 12권의 고전 → 12가지 쇠퇴 위험 → 출처가 명시된 진단 +

+ +

+ brooks-lint의 코드 리뷰: /brooks-review 명령 한 번으로 28/100 건강 점수와 출처가 인용된 증상 → 근원 → 결과 → 처방 진단을 산출 +

+ +

+ → 웹사이트 방문하기 +

+ +--- + +> *"아이를 낳는 데는 아홉 달이 걸린다. 몇 명의 여성을 투입하든 마찬가지다."* +> — Frederick Brooks, *The Mythical Man-Month*(맨먼스 미신, 1975) + +**50년이 지난 지금도 Brooks는 여전히 옳았습니다 — 그리고 McConnell, Fowler, Martin, Hunt & Thomas, Evans, Ousterhout, Winters, Meszaros, Osherove, Feathers, 그리고 Google 테스팅 팀 역시 마찬가지였습니다.** + +대부분의 코드 품질 도구는 줄 수와 순환 복잡도만 셉니다. **brooks-lint**는 한 걸음 더 나아갑니다 — 열두 권의 고전 엔지니어링 도서에서 종합한 여섯 가지 쇠퇴 위험 차원에 비추어 당신의 코드를 진단하며, 매번 도서 출처, 심각도 라벨, 구체적인 처방이 담긴 구조화된 진단을 산출합니다. + +예외와 오탐 방지 장치를 포함한 전체 "출처-스킬" 매핑은 +[`skills/_shared/source-coverage.md`](skills/_shared/source-coverage.md)를 참고하세요. + +## 빠른 시작 + +```bash +# Claude Code +/plugin marketplace add hyhmrright/brooks-lint +/plugin install brooks-lint@brooks-lint-marketplace + +# Any other Agent Skills platform — Cursor · Codex · Gemini · Copilot · Windsurf · OpenCode · Kiro · … +curl -fsSL https://raw.githubusercontent.com/hyhmrright/brooks-lint/main/scripts/install.sh | bash -s -- +``` + +설치한 뒤에는 그냥 요청하거나("이 PR을 리뷰해줘", "아키텍처를 감사해줘") — 명령을 실행하세요: + +| 명령 | 하는 일 | +|---------|--------------| +| `/brooks-review` | PR 또는 diff 리뷰 | +| `/brooks-audit` | 아키텍처 감사(+ Mermaid 의존성 그래프) | +| `/brooks-debt` | 우선순위가 매겨진 기술 부채 로드맵 | +| `/brooks-test` | 테스트 스위트 품질 리뷰 | +| `/brooks-health` | 모든 차원에 걸친 건강 대시보드 | +| `/brooks-sweep` | 전 차원을 훑어 진단 결과를 자동 수정 | + +모든 진단은 도서 출처와 0–100 건강 점수와 함께 **증상 → 근원 → 결과 → 처방** 형태로 돌아옵니다. 전체 설치 옵션(추가 8개 플랫폼), 명령별 사용법, CI/CD 설정은 [아래](#설치)를 참고하세요. + +## 열두 권의 책 + +| 책 | 저자 | 기여하는 위험 | +|------|--------|----------------| +| *The Mythical Man-Month*(맨먼스 미신) | Frederick Brooks | R2, R4, R5 | +| *Code Complete*(코드 컴플리트) | Steve McConnell | R1, R4 | +| *Refactoring*(리팩토링) | Martin Fowler | R1, R2, R3, R4, R6 | +| *Clean Architecture*(클린 아키텍처) | Robert C. Martin | R2, R5 | +| *The Pragmatic Programmer*(실용주의 프로그래머) | Hunt & Thomas | R2, R3, R4, R5, T2, T3 | +| *Domain-Driven Design*(도메인 주도 설계) | Eric Evans | R1, R3, R6 | +| *A Philosophy of Software Design*(소프트웨어 설계의 철학) | John Ousterhout | R1, R4 | +| *Software Engineering at Google*(구글 엔지니어링 best practice) | Winters, Manshreck & Wright | R2, R5 | +| *The Art of Unit Testing*(단위 테스트의 기술) | Roy Osherove | T1, T2, T4, T5 | +| *How Google Tests Software*(구글은 소프트웨어를 어떻게 테스트하는가) | James A. Whittaker, Jason Arbon & Jeff Carollo | T5, T6 | +| *Working Effectively with Legacy Code*(레거시 코드 활용 전략) | Michael Feathers | T4, T5, T6 | +| *xUnit Test Patterns*(xUnit 테스트 패턴) | Gerard Meszaros | T1, T2, T3, T4 | + +## 여섯 가지 쇠퇴 위험 + +brooks-lint는 열두 권의 고전 엔지니어링 도서에서 종합한 **여섯 가지 프로덕션 코드 쇠퇴 위험**과 **여섯 가지 테스트 스위트 쇠퇴 위험**의 관점에서 당신의 코드를 평가합니다: + +| 쇠퇴 위험 | 진단 질문 | 출처 | +|------------|---------------------|---------| +| 🧠 인지 과부하 | 이 코드를 이해하는 데 얼마나 많은 정신적 노력이 드는가? | Code Complete, Refactoring, DDD, Philosophy of SD | +| 🔗 변경 전파 | 한 곳을 고치면 관련 없는 것이 얼마나 깨지는가? | Refactoring, Clean Architecture, Pragmatic, SE@Google | +| 📋 지식 중복 | 같은 결정이 여러 곳에서 표현되고 있는가? | Pragmatic, Refactoring, DDD | +| 🌀 우발적 복잡도 | 코드가 문제 자체보다 더 복잡한가? | Refactoring, Code Complete, Brooks, Philosophy of SD | +| 🏗️ 의존성 무질서 | 의존성이 일관된 방향으로 흐르는가? | Clean Architecture, Brooks, Pragmatic, SE@Google | +| 🗺️ 도메인 모델 왜곡 | 코드가 도메인을 충실히 표현하는가? | DDD, Refactoring | + +> Philosophy of SD = *A Philosophy of Software Design*(Ousterhout) · SE@Google = *Software Engineering at Google*(Winters 외) + +## 실제 결과물 + +다음 코드가 주어졌을 때: + +```python +class UserService: + def update_profile(self, user_id, name, email, avatar_url): + user = self.db.query(f"SELECT * FROM users WHERE id = {user_id}") + user['email'] = email + ... + if user['email'] != email: # always False — silent bug + self.smtp.send(...) + points = user['login_count'] * 10 + 500 + self.db.execute(f"UPDATE loyalty SET points={points} WHERE user_id={user_id}") +``` + +brooks-lint는 다음을 산출합니다: + +--- + +**건강 점수: 28/100** + +*이 메서드는 서로 무관한 네 가지 비즈니스 책임을 하나의 함수에 집중시키고, 이메일 변경 알림을 조용히 억제하는 논리 버그를 포함하며, SQL 인젝션에 무방비로 노출되어 있습니다.* + +### 🔴 변경 전파 — 단일 메서드가 서로 무관한 네 가지 비즈니스 이유로 변경됨 +**증상:** `update_profile`이 프로필 필드 업데이트, 이메일 변경 알림, 적립 포인트 재계산, 캐시 무효화를 모두 하나의 메서드 본문에서 수행합니다. +**근원:** Fowler — *Refactoring* — 발산적 변경(Divergent Change); Hunt & Thomas — *The Pragmatic Programmer* — 직교성(Orthogonality) +**결과:** 적립 포인트 공식에 대한 어떤 변경이든 이메일 알림을 깨뜨릴 위험이 있고, 그 반대도 마찬가지입니다. 모든 수정이 서로 무관한 네 도메인에 걸친 회귀 위험을 동시에 떠안습니다. +**처방:** `NotificationService`, `LoyaltyService`, `UserCacheInvalidator`를 추출하세요. `UserService.update_profile`은 각각을 호출하며 조율하는 역할만 해야 하며 — 그 자체로는 어떤 구현 로직도 보유해서는 안 됩니다. + +### 🔴 도메인 모델 왜곡 — 조용한 논리 버그: 이메일 알림이 결코 발송되지 않음 +**증상:** `user['email'] = email`이 `if user['email'] != email`보다 먼저 옛 값을 덮어쓰므로 — 조건이 항상 `False`입니다. 알림은 죽은 코드입니다. +**근원:** McConnell — *Code Complete* — 17장: 비정상적 제어 구조 +**결과:** 사용자가 이메일 주소를 변경해도 결코 알림을 받지 못합니다. 조용한 데이터 무결성 실패입니다 — 시스템은 정상 동작하는 것처럼 보이지만 실제로는 비즈니스 규칙을 위반하고 있습니다. +**처방:** 어떤 변경이든 그 전에 `old_email = user['email']`을 포착하세요. `user['email']`이 아니라 `old_email`과 비교하세요. + +*(SQL 인젝션, 의존성 무질서, 매직 넘버를 포함해 6개 진단 추가)* + +### 의존성 그래프를 포함한 아키텍처 감사 + +모드 2(아키텍처 감사)에서 brooks-lint는 보고서 상단에 **Mermaid 의존성 그래프**를 생성합니다. 모듈은 심각도에 따라 색으로 구분됩니다: 빨강 = Critical 진단, 노랑 = Warning, 초록 = 깨끗함. + +```mermaid +graph TD + subgraph src/api + AuthController + UserController + end + subgraph src/domain + UserService + OrderService + end + subgraph src/infra + Database + EmailClient + end + + AuthController --> UserService + UserController --> UserService + UserController --> OrderService + OrderService --> UserService + OrderService --> EmailClient + UserService --> Database + EmailClient -.->|circular| OrderService + + classDef critical fill:#ff6b6b,stroke:#c92a2a,color:#fff + classDef warning fill:#ffd43b,stroke:#e67700 + classDef clean fill:#51cf66,stroke:#2b8a3e,color:#fff + + class OrderService,EmailClient critical + class AuthController warning + class UserService,UserController,Database clean +``` + +이 그래프는 GitHub, Notion 등 Markdown 환경에서 별도 도구 없이 네이티브로 렌더링됩니다. + +## 더 많은 예시 보기 + +[전체 갤러리](docs/gallery.md)에는 Python, TypeScript, Go, Java에 걸친 실제 brooks-lint 출력이 담겨 있습니다 — PR 리뷰, Mermaid 의존성 그래프가 포함된 아키텍처 감사, 기술 부채 평가, 테스트 품질 리뷰를 망라합니다. + +쇠퇴 위험이 처음이신가요? [**쇠퇴 위험 실전 가이드**](https://hyhmrright.github.io/brooks-lint/guide.html)가 여섯 가지를 모두 설명합니다 — 각각의 진단 질문, 대표 증상, 출처 도서, 처방을 다룹니다. + +--- + +## 벤치마크 + +3개의 실제 시나리오(PR 리뷰, 아키텍처 감사, 기술 부채 평가)에서 테스트했습니다: + +| 평가 항목 | brooks-lint | Claude 단독 | +|-----------|:-----------:|:------------:| +| 구조화된 진단(증상 → 근원 → 결과 → 처방) | ✅ 100% | ❌ 0% | +| 진단마다 도서 출처 | ✅ 100% | ❌ 0% | +| 심각도 라벨(🔴/🟡/🟢) | ✅ 100% | ❌ 0% | +| 건강 점수(0–100) | ✅ 100% | ❌ 0% | +| 변경 전파 탐지 | ✅ 100% | ✅ 100% | +| **전체 통과율** | **94%** | **16%** | + +격차는 Claude가 무엇을 *발견할 수 있는가*가 아니라 — 매번 추적 가능한 근거와 실행 가능한 처방을 곁들여 무엇을 *일관되게* 발견하는가에 있습니다. + +### 재현 가능한 벤치마크 + +위 표는 예시용입니다. 아래 수치들은 **확정적이며 로컬에서 직접 재현할 수 있습니다**: + +**파서 충실도** — SARIF 내보내기와 CI 게이트는 모델의 Markdown 보고서를 올바르게 파싱하는 데 달려 있습니다. 여섯 가지 모드 전체를 아우르는 **30개의 실제 모델 생성 보고서로 구성된 동결 코퍼스**(`evals/benchmark-corpus.json`)에 대해, 각각 **독립적으로 채점된** 진단 목록(별도의 모델 패스로 채점한 뒤 수작업으로 표본 검증)과 짝지어, 실제 배포되는 파서의 점수는 다음과 같습니다 — `npm run benchmark`를 실행하세요: + +| 지표(n = 30, 동결 코퍼스) | 결과 | +|---|:---:| +| 심각도 카운트 정확 일치(파서 vs 채점된 진실값) | 30 / 30 | +| 위험 코드 precision / recall | 100% / 100%(56개 finding-level 코드, 0 FP / 0 FN) | +| 유효한 SARIF 2.1.0 산출 | 30 / 30 | + +파서가 결정론적이고 코퍼스가 동결되어 있기 때문에 `npm run benchmark`는 누구에게나 동일한 결과를 주며, `npm test`가 이를 회귀 테스트로 지킵니다. 이 코퍼스는 깨끗하게 유지되어야 하는 9개의 오탐 / 트레이드오프 보고서(예: 의존성 순환처럼 *보이지만* 실제로는 포트-앤-어댑터 설계인 경우)를 의도적으로 포함합니다. + +**점수 결정성** — 고정된 진단 집합(2 Critical / 3 Warning / 1 Suggestion)에 대해, strictness 프리셋은 각자의 `common.md` 표가 예측하는 점수를 정확히 산출합니다: strict **34**, balanced **54**, legacy-friendly **74** — 그리고 `legacy-friendly`만이 상위 세 개의 수정으로 시작합니다. + +**모델 품질** — 모델이 실제 코드에서 *올바른* 위험을 찾아내는지는 **57개 시나리오 eval 스위트**(`evals/evals.json`)로 측정합니다: `npm run evals`(구조 검증)와 `npm run evals:live`(실측, `ANTHROPIC_API_KEY` 필요). + +> 범위와 정직성: 파서 수치는 결정론적이며 정확히 재현됩니다. strictness 및 eval 스위트 수치는 모델에 대한 단일 실행 실측치로, 실행마다 약간씩 변동합니다. 파서 벤치마크는 보고서 파싱 충실도(도구가 보고서에 기재된 모든 진단을 읽어내는가?)를 측정하는 것이지, 특정 진단이 "옳은지"를 측정하는 것이 아닙니다. 심각도 카운트 일치가 완전히 독립적인 신호입니다; 위험 코드 일치는 공유된 표준 name→code 범례 또한 반영합니다. + +## 비교 우위 + +| | brooks-lint | ESLint / Pylint | GitHub Copilot Review | 순수 Claude | +|---|:---:|:---:|:---:|:---:| +| 문법 및 스타일 문제 탐지 | — | ✅ | ✅ | ~ | +| 구조화된 진단 체인 | ✅ | ❌ | ❌ | ❌ | +| 진단을 고전 도서로 추적 | ✅ | ❌ | ❌ | ❌ | +| 일관된 심각도 라벨 | ✅ | ✅ | ~ | ❌ | +| 아키텍처 수준의 통찰 | ✅ | ❌ | ~ | ~ | +| 도메인 모델 분석 | ✅ | ❌ | ❌ | ~ | +| 무설정, 설치할 플러그인 없음 | ✅ | ❌ | ✅ | ✅ | +| 어떤 언어에서도 동작 | ✅ | ❌ | ✅ | ✅ | + +> `~` = 가끔 / 일관되지 않음 + +**brooks-lint는 당신의 linter를 대체하지 않습니다.** 그것은 linter가 잡을 수 없는 것을 포착합니다: 아키텍처 표류, 지식 사일로, 도메인 모델 왜곡 — 누군가 알아채기 전 몇 달 동안 팀을 더디게 만드는 문제들입니다. + +## 설치 + +### Claude Code(권장) + +#### 플러그인 마켓플레이스를 통해 +```bash +/plugin marketplace add hyhmrright/brooks-lint +/plugin install brooks-lint@brooks-lint-marketplace +``` + +단축 명령(`/brooks-review`)은 첫 세션 시작 시 자동으로 설치됩니다. 수동으로 설치하려면: +```bash +cp commands/*.md ~/.claude/commands/ +``` + +#### 수동 설치 +```bash +mkdir -p ~/.claude/skills/brooks-lint +cp -r skills/* ~/.claude/skills/brooks-lint/ +``` + +### Gemini CLI + +#### 확장을 통해 +```bash +/extensions install https://github.com/hyhmrright/brooks-lint +``` + +#### 수동 설치 +```bash +mkdir -p ~/.gemini/skills +cp -r skills/* ~/.gemini/skills/ # flat — Gemini discovers skills only one level deep +``` +> 또는 간단히: `./scripts/install.sh gemini` + +### Codex CLI + +#### 스킬 설치기를 통해(Codex 세션 안에서) +``` +Install the brooks-lint skill from hyhmrright/brooks-lint +``` + +#### 커맨드 라인 +```bash +python3 ~/.codex/skills/.system/skill-installer/scripts/install-skill-from-github.py \ + --repo hyhmrright/brooks-lint --path skills --name brooks-lint +``` + +#### 수동 설치 +```bash +git clone https://github.com/hyhmrright/brooks-lint.git /tmp/brooks-lint +mkdir -p ~/.codex/skills +cp -r /tmp/brooks-lint/skills/* ~/.codex/skills/ # flat — matches the skill-installer layout +``` +> 또는 간단히: `./scripts/install.sh codex` + +### 더 많은 플랫폼 — OpenCode · Cursor · Windsurf · Antigravity · pi · Copilot · Kiro · Factory Droid + +brooks-lint는 표준 [Agent Skills](https://agentskills.io) 형태로 배포됩니다. **Agent +Skills를 로드하는 모든 에이전트는 변환 없이 여섯 가지 모드를 모두 실행합니다** — 한 줄의 명령으로 설치됩니다: + +```bash +# pick your platform; --project installs into the current repo instead of your global config +curl -fsSL https://raw.githubusercontent.com/hyhmrright/brooks-lint/main/scripts/install.sh | bash -s -- +# = opencode · cursor · windsurf · antigravity · pi · kiro · copilot · droid · gemini · codex · agents +``` + +설치기는 스킬을 당신의 플랫폼에 맞는 폴더로 **평평하게** 복사하므로, 공유 +프레임워크(`../_shared/`)가 항상 올바르게 해석됩니다 — 레이아웃을 잘못 잡을 수가 없습니다. 그런 다음 그냥 요청하면 +("이 PR을 리뷰해줘", "아키텍처를 감사해줘"), 일치하는 스킬이 자신의 +`description`에서 자동으로 트리거됩니다. 스킬이 처음이거나 다른 에이전트를 쓰시나요? **[docs/getting-started.md](docs/getting-started.md)**를 참고하세요. + +
OpenCode + +`./scripts/install.sh opencode` → `~/.config/opencode/skills`(`~/.claude/skills`와 +`AGENTS.md`도 읽음). 전체 가이드: [docs/opencode-setup.md](docs/opencode-setup.md). +
+ +
Cursor (2.4+) + +`./scripts/install.sh cursor` → `~/.cursor/skills`(`.agents/skills`도; `AGENTS.md` 읽음). +전체 가이드: [docs/cursor-setup.md](docs/cursor-setup.md). +
+ +
Windsurf (Cascade) + +`./scripts/install.sh windsurf` → `~/.codeium/windsurf/skills`(`AGENTS.md` 읽음). +전체 가이드: [docs/windsurf-setup.md](docs/windsurf-setup.md). +
+ +
Antigravity (Google) + +`./scripts/install.sh antigravity --project` → `.agent/skills`(`AGENTS.md` / `GEMINI.md` 읽음). +전체 가이드: [docs/antigravity-setup.md](docs/antigravity-setup.md). +
+ +
pi (earendil-works) + +`./scripts/install.sh pi` → `~/.pi/agent/skills`, 또는 pi의 `skills` 설정이 클론을 가리키게 하세요. +전체 가이드: [docs/pi-setup.md](docs/pi-setup.md). +
+ +
GitHub Copilot + +`./scripts/install.sh copilot --project` → `.github/skills`(`.claude/skills`도 자동 감지; `AGENTS.md` +읽음). 전체 가이드: [docs/copilot-setup.md](docs/copilot-setup.md). +
+ +
Kiro (AWS) + +`./scripts/install.sh kiro` → `~/.kiro/skills`(`/brooks-review` 자동 등록; `AGENTS.md` 읽음). +전체 가이드: [docs/kiro-setup.md](docs/kiro-setup.md). +
+ +
Factory Droid + +`./scripts/install.sh droid` → `~/.factory/skills`(`/brooks-review` 등록; `AGENTS.md` 읽음). +전체 가이드: [docs/factory-droid-setup.md](docs/factory-droid-setup.md). +
+ +> **🧪 검증 상태.** Claude Code, Gemini CLI, Codex CLI는 메인테이너가 검증했습니다. 위 +> 여덟 개 플랫폼은 각 도구의 공식 스킬 명세를 토대로 문서화되었고 파일 레이아웃 +> 수준에서 검증되었으나(설치기는 테스트되었음), 메인테이너가 모든 플랫폼에서 end-to-end로 직접 실행해 보지는 +> 못했습니다. 어떤 것을 시도해 보셨나요 — 잘 되든 **안 되든**? 플랫폼, 버전, 본 결과를 담아 +> [이슈를 열어 주세요](https://github.com/hyhmrright/brooks-lint/issues/new). +> 다른 Agent-Skills 에이전트인가요? 거의 확실히 같은 +> 방식으로 동작합니다 — 알려주시면 추가하겠습니다. + +## 슬래시 명령 + +### Claude Code +| 명령 | 단축형 | 동작 | +|---------|------------|--------| +| `/brooks-lint:brooks-review` | `/brooks-review` | PR 수준 코드 리뷰 | +| `/brooks-lint:brooks-audit` | `/brooks-audit` | 전체 아키텍처 감사 | +| `/brooks-lint:brooks-debt` | `/brooks-debt` | 기술 부채 평가 | +| `/brooks-lint:brooks-test` | `/brooks-test` | 테스트 스위트 건강 리뷰 | +| `/brooks-lint:brooks-health` | `/brooks-health` | 건강 대시보드 — 네 가지 차원 전체 | +| `/brooks-lint:brooks-sweep` | `/brooks-sweep` | 전면 스윕 — 모든 차원을 분석하고 진단을 자동 수정 | + +> 단축 명령은 session-start 훅이 첫 세션 시작 시 자동으로 설치합니다. + +### Gemini CLI +| 명령 | 동작 | +|---------|--------| +| `/brooks-review` | PR 수준 코드 리뷰 | +| `/brooks-audit` | 전체 아키텍처 감사 | +| `/brooks-debt` | 기술 부채 평가 | +| `/brooks-test` | 테스트 스위트 건강 리뷰 | +| `/brooks-health` | 건강 대시보드 — 네 가지 차원 전체 | +| `/brooks-sweep` | 전면 스윕 — 모든 차원을 분석하고 진단을 자동 수정 | + +### Codex CLI + +| 명령 | 동작 | +|---------|--------| +| `$brooks-review` | PR 수준 코드 리뷰 | +| `$brooks-audit` | 전체 아키텍처 감사 | +| `$brooks-debt` | 기술 부채 평가 | +| `$brooks-test` | 테스트 스위트 건강 리뷰 | +| `$brooks-health` | 건강 대시보드 — 네 가지 차원 전체 | +| `$brooks-sweep` | 전면 스윕 — 모든 차원을 분석하고 진단을 자동 수정 | + +코드 품질, 아키텍처, 유지보수성, 테스트 건강에 대해 이야기할 때도 이 스킬들은 자동으로 트리거됩니다. + +### OpenCode · Cursor · Antigravity · pi + +이 플랫폼들은 각 스킬의 `description`에서 Agent Skills를 자동으로 호출합니다 — 그냥 요청하면 +("이 PR을 리뷰해줘", "아키텍처를 감사해줘", "우리의 최악의 기술 부채는 어디 있지?") 일치하는 모드가 +실행됩니다. 명시적으로 호출하려면 해당 플랫폼의 스킬 명령 구문을 사용하세요(예: pi는 각 스킬을 +`/skill:brooks-review`로 등록하고; Cursor와 OpenCode는 스킬이 발견되면 `/brooks-review`를 노출합니다). + +## 사용법 + +### PR 리뷰 + +``` +/brooks-review # Claude Code (short form) / Gemini CLI +/brooks-lint:brooks-review # Claude Code (full form) +$brooks-review # Codex CLI +``` + +diff를 붙여 넣거나 AI가 변경된 파일을 가리키게 하세요. 여섯 가지 쇠퇴 위험 각각을 증상 → 근원 → 결과 → 처방 형식의 구체적인 진단으로 진단합니다. + +### 아키텍처 감사 + +``` +/brooks-audit # Claude Code (short form) / Gemini CLI +/brooks-lint:brooks-audit # Claude Code (full form) +$brooks-audit # Codex CLI +``` + +프로젝트 구조를 설명하거나 핵심 파일을 공유하세요. 모듈 의존성을 매핑하고, 순환 의존성을 식별하며, Conway의 법칙 정합성을 점검합니다. + +### 기술 부채 평가 + +``` +/brooks-debt # Claude Code (short form) / Gemini CLI +/brooks-lint:brooks-debt # Claude Code (full form) +$brooks-debt # Codex CLI +``` + +부채를 여섯 가지 쇠퇴 위험에 걸쳐 분류하고, 각 진단을 Pain × Spread 우선순위로 점수화하며, Critical / Scheduled / Monitored 분류가 담긴 우선순위 상환 로드맵을 산출합니다. + +### 테스트 품질 리뷰 + +``` +/brooks-test # Claude Code (short form) / Gemini CLI +/brooks-lint:brooks-test # Claude Code (full form) +$brooks-test # Codex CLI +``` + +테스트 스위트를 여섯 가지 테스트 공간 쇠퇴 위험에 비추어 감사합니다 — 테스트 모호성, 테스트 취약성, 테스트 중복, Mock 남용, 커버리지 환상, 아키텍처 불일치 — 출처는 xUnit Test Patterns, The Art of Unit Testing, How Google Tests Software, Working Effectively with Legacy Code입니다. PR 리뷰에는 가벼운 Step 7 빠른 테스트 점검도 자동으로 포함됩니다(문서 전용 또는 비프로덕션 diff에서는 건너뜀). + +### 건강 대시보드 + +``` +/brooks-health # Claude Code (short form) / Gemini CLI +/brooks-lint:brooks-health # Claude Code (full form) +$brooks-health # Codex CLI +``` + +네 가지 품질 차원 전체에 걸쳐 축약된 스캔을 실행하고 가중 종합 건강 점수(0–100)를 산출합니다. 릴리스 전에, 새 팀을 온보딩할 때, 또는 "우리는 어떻게 하고 있나?"에 대한 큰 그림 보고서가 필요할 때 사용하세요. 특정 차원에 대한 심층 진단이 필요하면 대신 해당 전문 스킬을 사용하세요. + +### 전면 스윕 + +``` +/brooks-sweep # Claude Code (short form) / Gemini CLI +/brooks-lint:brooks-sweep # Claude Code (full form) +$brooks-sweep # Codex CLI +``` + +모든 프로덕션(R1–R6)과 테스트(T1–T6) 쇠퇴 위험 그리고 아키텍처를 한 번에 통합 스캔한 뒤 수정을 적용합니다: 안전한 변경은 즉시 자동 적용되고, 여러 파일에 걸치거나 인터페이스를 건드리는 변경은 확인이 필요하며, 복잡한 아키텍처 결정은 수동 처리 항목으로 표시됩니다. 수정 로그, 건강 점수 변화량, 잔여 항목 목록을 출력합니다. + +## 설정 + +리뷰 동작을 커스터마이즈하려면 프로젝트 루트에 `.brooks-lint.yaml`을 두세요: + +```yaml +version: 1 + +strictness: balanced # strict | balanced (default) | legacy-friendly — softer scoring for legacy code + +disable: + - T5 # skip coverage metrics check — we don't enforce coverage + +severity: + R1: suggestion # downgrade Cognitive Overload findings for this domain + +ignore: + - "**/*.generated.*" + - "**/vendor/**" + +# custom_risks: # define project-specific Cx codes — see skills/_shared/custom-risks-guide.md +# suppress: # downgrade specific findings by risk + path (e.g. accepted legacy debt) +``` + +[`.brooks-lint.example.yaml`](.brooks-lint.example.yaml)을 출발점으로 복사하세요. +모든 설정은 선택 사항입니다 — 파일을 통째로 생략하면 기본 동작이 적용됩니다. + +| 설정 | 설명 | +|---------|-------------| +| `strictness` | 점수 프리셋: `strict`, `balanced`(기본), 또는 `legacy-friendly`(더 가벼운 감점, 상위 수정으로 시작) | +| `disable` | 건너뛸 위험 코드(`R1`–`R6`, `T1`–`T6`) | +| `severity` | 심각도 등급 재정의(`critical` / `warning` / `suggestion`) | +| `ignore` | 제외할 파일의 glob 패턴 | +| `focus` | 이 위험 코드만 평가(`disable`과 함께 사용 불가) | +| `custom_risks` | 프로젝트 전용 위험 코드 정의(`C1`, `C2`, …) — [`custom-risks-guide.md`](skills/_shared/custom-risks-guide.md) 참고 | +| `suppress` | 위험 코드 + 경로로 특정 진단의 심각도 하향(선택적 `expires:` 만료일) | + +--- + +## 왜 이 책들인가, 왜 지금인가? + +AI 보조 코딩의 시대에 우리는 그 어느 때보다 빠르게, 더 많은 코드를 쓰고 있습니다. 하지만 60년에 걸친 소프트웨어 엔지니어링의 통찰은 변하지 않았습니다: + +> *"소프트웨어의 복잡성은 우발적 속성이 아니라 본질적 속성이다."* +> — Frederick Brooks + +AI는 코드를 더 빨리 쓰도록 도와줄 수 있지만, 당신이 대성당을 짓고 있는지 타르 구덩이를 파고 있는지는 알려주지 못합니다. **brooks-lint는 그 간극을 메웁니다** — 열두 권의 고전 엔지니어링 도서에서 어렵게 얻은 지혜를 당신의 현대적인 개발 워크플로로 가져옵니다. + +이 저자들이 식별한 쇠퇴 위험은 그 어느 때보다 더 적실합니다: +- **AI 어시스턴트를 추가한다고** 인지 과부하나 도메인 모델 왜곡이 고쳐지지는 않습니다 +- **더 많은 코드를 생성하면** 변경 전파와 지식 중복이 늘어납니다 +- **더 빨리 움직이는 것은** 우발적 복잡도와 의존성 무질서를 한층 더 위험하게 만듭니다 + +## 프로젝트 구조 + +``` +brooks-lint/ +├── .claude-plugin/ # Claude Code plugin metadata +├── .codex-plugin/ # Codex CLI plugin metadata +├── skills/ +│ ├── _shared/ # Shared framework files +│ │ ├── common.md # Iron Law, Project Config, Report Template, Health Score +│ │ ├── source-coverage.md # 12-book coverage matrix, tradeoffs, false-positive guards +│ │ ├── decay-risks.md # Six decay risks with symptoms and book citations +│ │ ├── test-decay-risks.md # Six test-space decay risks with book citations +│ │ ├── remedy-guide.md # --fix mode: actionable Remedy enhancement rules +│ │ └── custom-risks-guide.md # Template for project-specific risk codes +│ ├── brooks-review/ # Mode 1: PR Review +│ │ ├── SKILL.md +│ │ └── pr-review-guide.md +│ ├── brooks-audit/ # Mode 2: Architecture Audit +│ │ ├── SKILL.md +│ │ └── architecture-guide.md +│ ├── brooks-debt/ # Mode 3: Tech Debt Assessment +│ │ ├── SKILL.md +│ │ └── debt-guide.md +│ ├── brooks-test/ # Mode 4: Test Quality Review +│ │ ├── SKILL.md +│ │ └── test-guide.md +│ ├── brooks-health/ # Mode 5: Health Dashboard +│ │ ├── SKILL.md +│ │ └── health-guide.md +│ └── brooks-sweep/ # Mode 6: Full Sweep & Auto-Fix +│ ├── SKILL.md +│ └── sweep-guide.md +├── hooks/ # SessionStart hook +├── commands/ # Short-form command wrappers (auto-installed by hook) +├── evals/ # Benchmark test cases +│ └── evals.json +└── assets/ + └── logo.svg +``` + +## CI/CD 통합 + +GitHub Action을 사용해 모든 PR에서 brooks-lint를 자동으로 실행하세요: + +```yaml +# .github/workflows/brooks-lint.yml +name: Brooks-Lint PR Review +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + brooks-lint: + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: hyhmrright/brooks-lint/.github/actions/brooks-lint@main + with: + mode: review + anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} + fail-below: 70 +``` + +전체 템플릿은 [`docs/github-action-example.yml`](docs/github-action-example.yml)을 참고하세요. + +이 Action은 리뷰를 PR 댓글로 게시하며, 건강 점수가 임계값 아래로 떨어지면 선택적으로 체크를 실패시킵니다. `.brooks-lint-history.json`이 저장소에 커밋되어 있으면 댓글에 추세 변화도 포함됩니다(예: "85 → 82 (−3) over last 3 runs"). + +**품질 게이트와 Code Scanning.** `fail-below` 외에도 이 Action은 다음을 제공합니다: + +```yaml + with: + mode: review + anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} + fail-on: critical # fail on any Critical finding (none | warning | critical) + fail-on-regression: true # fail if the Health Score dropped vs the last run + sarif-file: brooks-lint.sarif # also upload findings to GitHub Code Scanning +``` + +`fail-on-regression`은 `.brooks-lint-history.json`을 읽으므로, "새로운 회귀 없음"을 강제하려면 그 파일을 커밋하세요. `sarif-file`을 설정하면 진단이 PR의 **Files changed** 탭에 인라인으로 나타나며, job에 `security-events: write` 권한이 필요합니다. + +**비용:** PR 실행당 약 $0.05–0.15로, diff 크기와 모델에 따라 다릅니다. `pull_request` 이벤트에서만 실행할 것을 권장합니다. + +## 로드맵 + +> **현재 상태(v1.4):** 12권 도서 기반, 6가지 프로덕션 쇠퇴 위험(R1–R6) + 6가지 테스트 쇠퇴 위험(T1–T6), 6개 스킬 — PR 리뷰, 아키텍처 감사, 기술 부채, 테스트 품질, 건강 대시보드, 전면 스윕 — 여기에 CI 품질 게이트, GitHub Code Scanning용 SARIF 출력, strictness 프리셋, 재현 가능한 파서 충실도 벤치마크를 더했습니다. 아래의 이전 항목들은 현재 기능 집합이 아니라 역사적 마일스톤을 기술합니다. + +- [x] **v0.2**: 플러그인 인프라(`.claude-plugin/`, 훅, 슬래시 명령) +- [x] **v0.3**: 여덟 가지 Brooks 차원, 문서 완성도 점수화 +- [x] **v0.4**: 여섯 권 도서 프레임워크, 쇠퇴 위험 차원, 진단 체인, 벤치마크 스위트 +- [x] **v0.5**: 테스트 품질 리뷰(모드 4) — 네 권의 테스트 도서, 여섯 가지 테스트 쇠퇴 위험 +- [x] **v0.6**: 아키텍처 감사의 Mermaid 의존성 그래프 +- [x] **v0.7**: `.brooks-lint.yaml` 프로젝트 설정, 모드 2 능동 컨텍스트, 10권 도서로 확장 +- [x] **v0.8**: 네임스페이스 명령을 갖춘 독립 스킬 아키텍처 +- [x] **v0.9**: 단계 검증, 자동 diff 범위, `/brooks-health` 대시보드, 추세 추적, 트리아지 모드, `--fix` 처방, 온보딩 보고서, GitHub Action +- [x] **v1.0**: eval 자동화(`run-evals-live.mjs`), 커스텀 위험 확장(`Cx` 코드) +- [x] **v1.1**: 전면 스윕 스킬(`brooks-sweep`) — 통합 다차원 자동 수정 +- [x] **v1.2**: 자율 스윕 파이프라인, `npm run bump` 버전 전파 +- [x] **v1.3**: Codex 마켓플레이스 메타데이터, 여러 에이전트 플랫폼을 위한 한 줄 명령 설치기, 다국어 README + 랜딩 사이트 +- [x] **v1.4**: GitHub Code Scanning용 SARIF 출력, CI severity + 회귀 게이트, strictness 프리셋(strict/balanced/legacy-friendly), 57개 시나리오 eval 스위트, 재현 가능한 파서 충실도 벤치마크(`npm run benchmark`) + +도움을 주고 싶으신가요? 지금 가장 좋은 기여는 새로운 eval 테스트 케이스와 개선된 쇠퇴 위험 증상 패턴입니다. [CONTRIBUTING.md](CONTRIBUTING.md)를 참고하세요. + +## 기여 + +진단을 추가하거나, 가이드를 개선하거나, 벤치마크 스위트를 확장하는 방법은 [CONTRIBUTING.md](CONTRIBUTING.md)를 참고하세요. + +당신 자신의 PR에 `/brooks-review`를 실행해 보세요 — 우리는 우리가 만들고 있는 도구로 기여를 리뷰합니다. + +## 라이선스 + +MIT License — 자세한 내용은 [LICENSE](LICENSE)를 참고하세요. + +## 감사의 말 + +이 프로젝트는 열두 거인의 어깨 위에 서 있습니다: + +**프로덕션 코드 프레임워크** +- Frederick P. Brooks Jr. — *The Mythical Man-Month*(1975, 기념판 1995) +- Steve McConnell — *Code Complete*(1993, 2판 2004) +- Martin Fowler — *Refactoring*(1999, 2판 2018) +- Robert C. Martin — *Clean Architecture*(2017) +- Andrew Hunt & David Thomas — *The Pragmatic Programmer*(1999, 20주년판 2019) +- Eric Evans — *Domain-Driven Design*(2003) +- John Ousterhout — *A Philosophy of Software Design*(2018) +- Titus Winters, Tom Manshreck, Hyrum Wright — *Software Engineering at Google*(2020) + +**테스트 품질 프레임워크** +- Gerard Meszaros — *xUnit Test Patterns*(2007) +- Roy Osherove — *The Art of Unit Testing*(2009, 3판 2023) +- Google Engineering — *How Google Tests Software*(2012) +- Michael Feathers — *Working Effectively with Legacy Code*(2004) + +이 도구에 인코딩된 쇠퇴 위험은 그들의 사상을 현대 코드 품질 평가에 적용한 우리의 종합입니다. + +--- + +## Star 히스토리 + +[![Star History Chart](https://api.star-history.com/svg?repos=hyhmrright/brooks-lint&type=Date)](https://star-history.com/#hyhmrright/brooks-lint&Date) + +--- + +

+ ⭐ 이 도구가 당신의 코드베이스를 다르게 보는 데 도움이 되었다면, star를 눌러 주세요! +

diff --git a/brooks-lint/README.md b/brooks-lint/README.md index 20d59924..dfc343fc 100644 --- a/brooks-lint/README.md +++ b/brooks-lint/README.md @@ -10,10 +10,16 @@

- English · 简体中文 + English · + 简体中文 · + 繁體中文 · + 日本語 · + 한국어 · + Español

+ Quick StartThe Six Decay RisksWhat It Looks LikeBenchmark • @@ -28,6 +34,14 @@ GitHub Stars

+

+ #2 JavaScript Repository of the Day | Trendshift +

+ +

+ Your code → 12 classics → 12 decay risks → cited findings +

+

brooks-lint reviewing code: a /brooks-review command produces a 28/100 health score and cited Symptom → Source → Consequence → Remedy findings

@@ -48,6 +62,30 @@ Most code quality tools count lines and cyclomatic complexity. **brooks-lint** g For the full source-to-skill mapping, including exceptions and false-positive guards, see [`skills/_shared/source-coverage.md`](skills/_shared/source-coverage.md). +## Quick Start + +```bash +# Claude Code +/plugin marketplace add hyhmrright/brooks-lint +/plugin install brooks-lint@brooks-lint-marketplace + +# Any other Agent Skills platform — Cursor · Codex · Gemini · Copilot · Windsurf · OpenCode · Kiro · … +curl -fsSL https://raw.githubusercontent.com/hyhmrright/brooks-lint/main/scripts/install.sh | bash -s -- +``` + +Then just ask ("review this PR", "audit the architecture") — or run a command: + +| Command | What it does | +|---------|--------------| +| `/brooks-review` | Review a PR or diff | +| `/brooks-audit` | Audit architecture (+ Mermaid dependency graph) | +| `/brooks-debt` | Prioritized tech-debt roadmap | +| `/brooks-test` | Test-suite quality review | +| `/brooks-health` | Health dashboard across all dimensions | +| `/brooks-sweep` | Sweep every dimension and auto-fix findings | + +Every finding comes back as **Symptom → Source → Consequence → Remedy** with a book citation and a 0–100 Health Score. Full install options (8 more platforms), per-command usage, and CI/CD setup are [below](#installation). + ## The Twelve Books | Book | Author | Contributes to | diff --git a/brooks-lint/README.zh-CN.md b/brooks-lint/README.zh-CN.md index 265c3139..393fa1ac 100644 --- a/brooks-lint/README.zh-CN.md +++ b/brooks-lint/README.zh-CN.md @@ -10,10 +10,16 @@

- English · 简体中文 + English · + 简体中文 · + 繁體中文 · + 日本語 · + 한국어 · + Español

+ 快速上手六类衰退风险实际效果基准测试 • @@ -28,6 +34,14 @@ GitHub Stars

+

+ Trendshift 当日 JavaScript 仓库榜第 2 名 +

+ +

+ 你的代码 → 十二本经典 → 十二类衰退风险 → 带出处的结论 +

+

brooks-lint 审查代码:一条 /brooks-review 命令产出 28/100 健康分以及引用书目的 症状 → 根源 → 后果 → 对策 诊断

@@ -48,6 +62,30 @@ 完整的"书目—技能"映射(含例外与误报防护),见 [`skills/_shared/source-coverage.md`](skills/_shared/source-coverage.md)。 +## 快速上手 + +```bash +# Claude Code +/plugin marketplace add hyhmrright/brooks-lint +/plugin install brooks-lint@brooks-lint-marketplace + +# 其他任意 Agent Skills 平台 —— Cursor · Codex · Gemini · Copilot · Windsurf · OpenCode · Kiro · … +curl -fsSL https://raw.githubusercontent.com/hyhmrright/brooks-lint/main/scripts/install.sh | bash -s -- <平台> +``` + +装好后直接开口("审查这个 PR""审计架构")——或运行命令: + +| 命令 | 作用 | +|------|------| +| `/brooks-review` | 审查一个 PR 或 diff | +| `/brooks-audit` | 架构审计(含 Mermaid 依赖图) | +| `/brooks-debt` | 排好优先级的技术债路线图 | +| `/brooks-test` | 测试套件质量审查 | +| `/brooks-health` | 跨所有维度的健康看板 | +| `/brooks-sweep` | 全维度扫描并自动修复 | + +每条诊断都以 **症状 → 根源 → 后果 → 对策** 返回,附书目出处和 0–100 健康分。完整安装方式(另外 8 个平台)、逐命令用法、CI/CD 配置见[下文](#安装)。 + ## 十二本书 | 书名 | 作者 | 贡献于 | diff --git a/brooks-lint/README.zh-TW.md b/brooks-lint/README.zh-TW.md new file mode 100644 index 00000000..72f8b3f1 --- /dev/null +++ b/brooks-lint/README.zh-TW.md @@ -0,0 +1,686 @@ +

+ brooks-lint +

+ +

brooks-lint

+ +

+ 植根於十二本經典工程著作的 AI 程式碼審查。
+ 一致、可溯源、可落地。
+

+ +

+ English · + 简体中文 · + 繁體中文 · + 日本語 · + 한국어 · + Español +

+ +

+ 快速上手 • + 六類衰退風險 • + 實際效果 • + 基準測試 • + 安裝 +

+ +

+ Version + MIT License + Claude Code Plugin + Codex CLI Skill + GitHub Stars +

+ +

+ Trendshift 當日 JavaScript 儲存庫排行榜第 2 名 +

+ +

+ 你的程式碼 → 十二本經典 → 十二類衰退風險 → 帶出處的結論 +

+ +

+ brooks-lint 審查程式碼:一條 /brooks-review 命令產出 28/100 健康分以及引用書目的 症狀 → 根源 → 後果 → 對策 診斷 +

+ +

+ → 造訪官網 +

+ +--- + +> *"一個孩子要十月懷胎,無論派多少人去都一樣。"* +> —— Frederick Brooks,《人月神話》(1975) + +**五十年過去,Brooks 依然正確——McConnell、Fowler、Martin、Hunt & Thomas、Evans、Ousterhout、Winters、Meszaros、Osherove、Feathers 以及 Google 測試團隊同樣如此。** + +大多數程式碼品質工具只數行數和循環複雜度。**brooks-lint** 更進一步——它對照六個衰退風險維度(綜合自十二本經典工程著作)診斷你的程式碼,每一次都產出帶書目出處、嚴重度標籤和具體對策的結構化診斷。 + +完整的「書目—技能」對應(含例外與誤報防護),見 +[`skills/_shared/source-coverage.md`](skills/_shared/source-coverage.md)。 + +## 快速上手 + +```bash +# Claude Code +/plugin marketplace add hyhmrright/brooks-lint +/plugin install brooks-lint@brooks-lint-marketplace + +# 其他任意 Agent Skills 平台 —— Cursor · Codex · Gemini · Copilot · Windsurf · OpenCode · Kiro · … +curl -fsSL https://raw.githubusercontent.com/hyhmrright/brooks-lint/main/scripts/install.sh | bash -s -- <平台> +``` + +裝好後直接開口(「審查這個 PR」「稽核架構」)——或執行命令: + +| 命令 | 作用 | +|------|------| +| `/brooks-review` | 審查一個 PR 或 diff | +| `/brooks-audit` | 架構稽核(含 Mermaid 相依圖) | +| `/brooks-debt` | 排好優先順序的技術債路線圖 | +| `/brooks-test` | 測試套件品質審查 | +| `/brooks-health` | 跨所有維度的健康儀表板 | +| `/brooks-sweep` | 全維度掃描並自動修復 | + +每條診斷都以 **症狀 → 根源 → 後果 → 對策** 回傳,附書目出處和 0–100 健康分。完整安裝方式(另外 8 個平台)、逐命令用法、CI/CD 設定見[下文](#安裝)。 + +## 十二本書 + +| 書名 | 作者 | 貢獻於 | +|------|--------|----------------| +| *The Mythical Man-Month*(人月神話) | Frederick Brooks | R2、R4、R5 | +| *Code Complete*(程式碼大全) | Steve McConnell | R1、R4 | +| *Refactoring*(重構) | Martin Fowler | R1、R2、R3、R4、R6 | +| *Clean Architecture*(無瑕的程式碼:整潔的軟體設計與架構篇) | Robert C. Martin | R2、R5 | +| *The Pragmatic Programmer*(務實的程式設計師) | Hunt & Thomas | R2、R3、R4、R5、T2、T3 | +| *Domain-Driven Design*(領域驅動設計) | Eric Evans | R1、R3、R6 | +| *A Philosophy of Software Design*(軟體設計的哲學) | John Ousterhout | R1、R4 | +| *Software Engineering at Google*(Google 軟體工程) | Winters, Manshreck & Wright | R2、R5 | +| *The Art of Unit Testing*(單元測試的藝術) | Roy Osherove | T1、T2、T4、T5 | +| *How Google Tests Software*(Google 測試之道) | Whittaker, Arbon & Carollo | T5、T6 | +| *Working Effectively with Legacy Code*(修改軟體的藝術) | Michael Feathers | T4、T5、T6 | +| *xUnit Test Patterns*(xUnit 測試模式) | Gerard Meszaros | T1、T2、T3、T4 | + +## 六類衰退風險 + +brooks-lint 從**六類生產程式碼衰退風險**和**六類測試程式碼衰退風險**兩個角度評估你的程式碼,這些維度綜合自十二本經典工程著作: + +| 衰退風險 | 診斷問題 | 出處 | +|------------|---------------------|---------| +| 🧠 認知過載 | 理解這段程式碼要花多少腦力? | Code Complete、Refactoring、DDD、Philosophy of SD | +| 🔗 變更擴散 | 改一處會牽連多少不相干的東西? | Refactoring、Clean Architecture、Pragmatic、SE@Google | +| 📋 知識重複 | 同一個決策是否在多處被表達? | Pragmatic、Refactoring、DDD | +| 🌀 偶發複雜度 | 程式碼是否比問題本身更複雜? | Refactoring、Code Complete、Brooks、Philosophy of SD | +| 🏗️ 相依失序 | 相依關係是否朝一致的方向流動? | Clean Architecture、Brooks、Pragmatic、SE@Google | +| 🗺️ 領域模型失真 | 程式碼是否忠實地表達了業務領域? | DDD、Refactoring | + +> Philosophy of SD = *A Philosophy of Software Design*(Ousterhout) · SE@Google = *Software Engineering at Google*(Winters 等) + +## 實際效果 + +給定這段程式碼: + +```python +class UserService: + def update_profile(self, user_id, name, email, avatar_url): + user = self.db.query(f"SELECT * FROM users WHERE id = {user_id}") + user['email'] = email + ... + if user['email'] != email: # 永遠為 False —— 隱性 bug + self.smtp.send(...) + points = user['login_count'] * 10 + 500 + self.db.execute(f"UPDATE loyalty SET points={points} WHERE user_id={user_id}") +``` + +brooks-lint 產出: + +--- + +**健康分:28/100** + +*這個方法把四個不相干的業務職責塞進同一個函式,含有一個會靜默吞掉「信箱變更通知」的邏輯 bug,並且對 SQL 注入門戶大開。* + +### 🔴 變更擴散 —— 單個方法因四個不相干的業務原因而改動 +**症狀:** `update_profile` 在同一個方法主體裡完成資料欄位更新、信箱變更通知、點數重算和快取失效。 +**根源:** Fowler — *Refactoring* — 發散式變更(Divergent Change);Hunt & Thomas — *The Pragmatic Programmer* — 正交性(Orthogonality) +**後果:** 任何對點數公式的改動都可能破壞郵件通知,反之亦然。每次修改都同時背負著四個不相干領域的回歸風險。 +**對策:** 抽出 `NotificationService`、`LoyaltyService` 和 `UserCacheInvalidator`。`UserService.update_profile` 應只做編排、逐一呼叫它們——本身不持有任何實作邏輯。 + +### 🔴 領域模型失真 —— 隱性邏輯 bug:信箱通知永不觸發 +**症狀:** `user['email'] = email` 在 `if user['email'] != email` 之前就覆寫了舊值——條件恆為 `False`,通知是死程式碼。 +**根源:** McConnell — *Code Complete* — 第 17 章:非常規控制結構 +**後果:** 使用者改信箱時永遠收不到通知。這是靜默的資料完整性失效——系統看似正常運作,實則違反了業務規則。 +**對策:** 在任何修改之前先擷取 `old_email = user['email']`,拿它(而非 `user['email']`)做比較。 + +*(另有 6 條診斷,含 SQL 注入、相依失序、魔術數字)* + +### 帶相依圖的架構審查 + +在模式 2(架構審查)中,brooks-lint 會在報告頂部產生一張 **Mermaid 相依圖**。模組按嚴重度著色:紅=Critical,黃=Warning,綠=乾淨。 + +```mermaid +graph TD + subgraph src/api + AuthController + UserController + end + subgraph src/domain + UserService + OrderService + end + subgraph src/infra + Database + EmailClient + end + + AuthController --> UserService + UserController --> UserService + UserController --> OrderService + OrderService --> UserService + OrderService --> EmailClient + UserService --> Database + EmailClient -.->|circular| OrderService + + classDef critical fill:#ff6b6b,stroke:#c92a2a,color:#fff + classDef warning fill:#ffd43b,stroke:#e67700 + classDef clean fill:#51cf66,stroke:#2b8a3e,color:#fff + + class OrderService,EmailClient critical + class AuthController warning + class UserService,UserController,Database clean +``` + +該圖在 GitHub、Notion 等 Markdown 環境中原生算繪——無需額外工具。 + +## 更多範例 + +[完整畫廊](docs/gallery.md) 收錄了 brooks-lint 在 Python、TypeScript、Go、Java 上的真實輸出——涵蓋 PR 審查、帶 Mermaid 相依圖的架構審查、技術債評估和測試品質審查。 + +初次接觸這些衰退風險?[**衰退風險實戰指南**](https://hyhmrright.github.io/brooks-lint/guide.html) 逐一講解全部六類——每類的診斷問題、代表症狀、出處書目與對策。 + +--- + +## 基準測試 + +在 3 個真實情境(PR 審查、架構審查、技術債評估)上測試: + +| 評估項 | brooks-lint | 僅用 Claude | +|-----------|:-----------:|:------------:| +| 結構化診斷(症狀 → 根源 → 後果 → 對策) | ✅ 100% | ❌ 0% | +| 每條診斷帶書目出處 | ✅ 100% | ❌ 0% | +| 嚴重度標籤(🔴/🟡/🟢) | ✅ 100% | ❌ 0% | +| 健康分(0–100) | ✅ 100% | ❌ 0% | +| 識別「變更擴散」 | ✅ 100% | ✅ 100% | +| **整體通過率** | **94%** | **16%** | + +差距不在於 Claude *能不能*發現問題——而在於它能否*每一次都穩定地*發現,並附上可溯源的證據和可落地的對策。 + +### 可復現基準 + +上表是示意性的。下面這些數字**確定、可在本地復算**: + +**parser 保真度** —— SARIF 輸出與 CI 閘門都依賴於正確解析模型的 Markdown 報告。在一個**凍結的 30 份真實模型報告語料**上(涵蓋全部六種 mode,`evals/benchmark-corpus.json`),每份都配有**獨立評分**的發現清單(由另一遍模型評分、並經人工抽查),實際發布的 parser 跑分如下——執行 `npm run benchmark`: + +| 指標(n = 30,凍結語料) | 結果 | +|---|:---:| +| 嚴重度計數精確吻合(parser vs 人工標註真值) | 30 / 30 | +| 風險碼 precision / recall | 100% / 100%(56 個 finding-level 碼,0 偽陽 / 0 偽陰) | +| 產出合法 SARIF 2.1.0 | 30 / 30 | + +由於 parser 是確定性的、語料是凍結的,`npm run benchmark` 對任何人都給出相同結果,`npm test` 也將其作為回歸守衛。該語料**有意**包含 9 份偽陽性 / tradeoff 報告(例如一個*看起來像*循環相依、實則是埠與配接器(ports-and-adapters)的設計),它們必須保持乾淨。 + +**評分確定性** —— 給定一組固定發現(2 Critical / 3 Warning / 1 Suggestion),三個 strictness 預設產出的分數與其 `common.md` 表的預測分毫不差:strict **34**、balanced **54**、legacy-friendly **74**——且只有 `legacy-friendly` 會優先列出前三高槓桿修復。 + +**模型品質** —— 模型能否在真實程式碼上找到*正確的*風險,由 **57 情境 eval 套件**(`evals/evals.json`)衡量:`npm run evals`(結構校驗)與 `npm run evals:live`(實測,需 `ANTHROPIC_API_KEY`)。 + +> 範圍與誠實說明:parser 數字是確定性的、可精確復算;strictness 與 eval 套件的數字是對模型的單次實測,會有輕微跑動差異。parser 基準衡量的是報告解析保真度(工具是否讀出了報告裡寫的每條發現),而非某條發現「是否正確」。嚴重度計數吻合是完全獨立的訊號;風險碼一致性還反映了 parser 與 grader 共用同一套權威 name→code 對應。 + +## 橫向對比 + +| | brooks-lint | ESLint / Pylint | GitHub Copilot Review | 原生 Claude | +|---|:---:|:---:|:---:|:---:| +| 偵測語法與風格問題 | — | ✅ | ✅ | ~ | +| 結構化診斷鏈 | ✅ | ❌ | ❌ | ❌ | +| 將診斷溯源到經典著作 | ✅ | ❌ | ❌ | ❌ | +| 一致的嚴重度標籤 | ✅ | ✅ | ~ | ❌ | +| 架構層面的洞察 | ✅ | ❌ | ~ | ~ | +| 領域模型分析 | ✅ | ❌ | ❌ | ~ | +| 零設定、無需安裝外掛 | ✅ | ❌ | ✅ | ✅ | +| 適用於任何語言 | ✅ | ❌ | ✅ | ✅ | + +> `~` = 偶爾 / 不穩定 + +**brooks-lint 不是要取代你的 linter。** 它捕捉的是 linter 抓不到的東西:架構漂移、知識孤島、領域模型失真——這些問題往往在無人察覺的幾個月裡持續拖慢團隊。 + +## 安裝 + +### Claude Code(推薦) + +#### 透過外掛市集 +```bash +/plugin marketplace add hyhmrright/brooks-lint +/plugin install brooks-lint@brooks-lint-marketplace +``` + +短命令(`/brooks-review`)會在首次工作階段啟動時自動安裝。手動安裝: +```bash +cp commands/*.md ~/.claude/commands/ +``` + +#### 手動安裝 +```bash +mkdir -p ~/.claude/skills/brooks-lint +cp -r skills/* ~/.claude/skills/brooks-lint/ +``` + +### Gemini CLI + +#### 透過擴充功能 +```bash +/extensions install https://github.com/hyhmrright/brooks-lint +``` + +#### 手動安裝 +```bash +mkdir -p ~/.gemini/skills +cp -r skills/* ~/.gemini/skills/ # 扁平——Gemini 只探索一層深的技能 +``` +> 或直接:`./scripts/install.sh gemini` + +### Codex CLI + +#### 透過技能安裝器(在 Codex 工作階段中) +``` +Install the brooks-lint skill from hyhmrright/brooks-lint +``` + +#### 命令列 +```bash +python3 ~/.codex/skills/.system/skill-installer/scripts/install-skill-from-github.py \ + --repo hyhmrright/brooks-lint --path skills --name brooks-lint +``` + +#### 手動安裝 +```bash +git clone https://github.com/hyhmrright/brooks-lint.git /tmp/brooks-lint +mkdir -p ~/.codex/skills +cp -r /tmp/brooks-lint/skills/* ~/.codex/skills/ # 扁平——與技能安裝器佈局一致 +``` +> 或直接:`./scripts/install.sh codex` + +### 更多平台——OpenCode · Cursor · Windsurf · Antigravity · pi · Copilot · Kiro · Factory Droid + +brooks-lint 以標準 [Agent Skills](https://agentskills.io) 形式散布。**任何載入 Agent Skills 的 agent +都能無需任何轉換執行全部六種模式**——一條命令即可安裝: + +```bash +# 選擇你的平台;加 --project 裝進當前儲存庫而非全域設定 +curl -fsSL https://raw.githubusercontent.com/hyhmrright/brooks-lint/main/scripts/install.sh | bash -s -- <平台> +# <平台> = opencode · cursor · windsurf · antigravity · pi · kiro · copilot · droid · gemini · codex · agents +``` + +安裝器會把技能**扁平**複製進該平台對應的資料夾,讓共享框架(`../_shared/`)始終正確解析——你不可能裝錯佈局。 +裝好後直接提問(「審查這個 PR」、「稽核架構」),對應技能就會依據 `description` 自動觸發。 +不熟悉 skills、或用的是別的 agent?見 **[docs/getting-started.md](docs/getting-started.md)**。 + +
OpenCode + +`./scripts/install.sh opencode` → `~/.config/opencode/skills`(同時讀取 `~/.claude/skills` 與 +`AGENTS.md`)。完整指南:[docs/opencode-setup.md](docs/opencode-setup.md)。 +
+ +
Cursor(2.4+) + +`./scripts/install.sh cursor` → `~/.cursor/skills`(也讀 `.agents/skills`;讀取 `AGENTS.md`)。 +完整指南:[docs/cursor-setup.md](docs/cursor-setup.md)。 +
+ +
Windsurf(Cascade) + +`./scripts/install.sh windsurf` → `~/.codeium/windsurf/skills`(讀取 `AGENTS.md`)。 +完整指南:[docs/windsurf-setup.md](docs/windsurf-setup.md)。 +
+ +
Antigravity(Google) + +`./scripts/install.sh antigravity --project` → `.agent/skills`(讀取 `AGENTS.md` / `GEMINI.md`)。 +完整指南:[docs/antigravity-setup.md](docs/antigravity-setup.md)。 +
+ +
pi(earendil-works) + +`./scripts/install.sh pi` → `~/.pi/agent/skills`,或讓 pi 的 `skills` 設定指向一個克隆。 +完整指南:[docs/pi-setup.md](docs/pi-setup.md)。 +
+ +
GitHub Copilot + +`./scripts/install.sh copilot --project` → `.github/skills`(也自動辨識 `.claude/skills`;讀取 +`AGENTS.md`)。完整指南:[docs/copilot-setup.md](docs/copilot-setup.md)。 +
+ +
Kiro(AWS) + +`./scripts/install.sh kiro` → `~/.kiro/skills`(自動註冊 `/brooks-review`;讀取 `AGENTS.md`)。 +完整指南:[docs/kiro-setup.md](docs/kiro-setup.md)。 +
+ +
Factory Droid + +`./scripts/install.sh droid` → `~/.factory/skills`(註冊 `/brooks-review`;讀取 `AGENTS.md`)。 +完整指南:[docs/factory-droid-setup.md](docs/factory-droid-setup.md)。 +
+ +> **🧪 驗證狀態。** Claude Code、Gemini CLI、Codex CLI 已由維護者驗證。上面八個平台依據各工具官方技能規範撰寫, +> 並已在檔案佈局層面驗證(安裝器經過測試),但維護者尚未在每個平台端到端實跑。在某平台試過了——無論成功**還是**失敗? +> 請[提一個 issue](https://github.com/hyhmrright/brooks-lint/issues/new),附上平台、版本和你看到的結果。 +> 用的是其他相容 Agent Skills 的 agent?它幾乎肯定以同樣方式運作——告訴我們,我們會補上。 + +## 斜線命令 + +### Claude Code +| 命令 | 短命令 | 作用 | +|---------|------------|--------| +| `/brooks-lint:brooks-review` | `/brooks-review` | PR 級程式碼審查 | +| `/brooks-lint:brooks-audit` | `/brooks-audit` | 完整架構審查 | +| `/brooks-lint:brooks-debt` | `/brooks-debt` | 技術債評估 | +| `/brooks-lint:brooks-test` | `/brooks-test` | 測試套件健康審查 | +| `/brooks-lint:brooks-health` | `/brooks-health` | 健康儀表板——全部四個維度 | +| `/brooks-lint:brooks-sweep` | `/brooks-sweep` | 全面掃描——分析所有維度並自動修復 | + +> 短命令由 session-start 掛鉤在首次工作階段啟動時自動安裝。 + +### Gemini CLI +| 命令 | 作用 | +|---------|--------| +| `/brooks-review` | PR 級程式碼審查 | +| `/brooks-audit` | 完整架構審查 | +| `/brooks-debt` | 技術債評估 | +| `/brooks-test` | 測試套件健康審查 | +| `/brooks-health` | 健康儀表板——全部四個維度 | +| `/brooks-sweep` | 全面掃描——分析所有維度並自動修復 | + +### Codex CLI + +| 命令 | 作用 | +|---------|--------| +| `$brooks-review` | PR 級程式碼審查 | +| `$brooks-audit` | 完整架構審查 | +| `$brooks-debt` | 技術債評估 | +| `$brooks-test` | 測試套件健康審查 | +| `$brooks-health` | 健康儀表板——全部四個維度 | +| `$brooks-sweep` | 全面掃描——分析所有維度並自動修復 | + +當你討論程式碼品質、架構、可維護性或測試健康時,這些技能也會自動觸發。 + +### OpenCode · Cursor · Antigravity · pi + +這些平台依據每個技能的 `description` 自動呼叫 Agent Skills——直接提問(「審查這個 PR」、「稽核架構」、 +「我們最糟的技術債在哪」)就會執行對應模式。需要顯式呼叫時,使用各平台的技能命令語法(例如 pi 把每個技能註冊為 +`/skill:brooks-review`;Cursor 與 OpenCode 在技能被探索到後暴露 `/brooks-review`)。 + +## 使用 + +### PR 審查 + +``` +/brooks-review # Claude Code(短命令)/ Gemini CLI +/brooks-lint:brooks-review # Claude Code(完整形式) +$brooks-review # Codex CLI +``` + +貼上一段 diff,或讓 AI 指向改動的檔案。它會以 症狀 → 根源 → 後果 → 對策 的格式,逐一診斷六類衰退風險並給出具體診斷。 + +### 架構審查 + +``` +/brooks-audit # Claude Code(短命令)/ Gemini CLI +/brooks-lint:brooks-audit # Claude Code(完整形式) +$brooks-audit # Codex CLI +``` + +描述你的專案結構或分享關鍵檔案。它會梳理模組相依、識別循環相依,並檢查是否符合康威定律。 + +### 技術債評估 + +``` +/brooks-debt # Claude Code(短命令)/ Gemini CLI +/brooks-lint:brooks-debt # Claude Code(完整形式) +$brooks-debt # Codex CLI +``` + +按六類衰退風險對技術債分類,以 痛感 × 擴散面 為每條診斷打優先順序,產出帶 Critical / Scheduled / Monitored 分級的償還路線圖。 + +### 測試品質審查 + +``` +/brooks-test # Claude Code(短命令)/ Gemini CLI +/brooks-lint:brooks-test # Claude Code(完整形式) +$brooks-test # Codex CLI +``` + +對照六類測試空間衰退風險審查你的測試套件——測試晦澀、測試脆弱、測試重複、Mock 濫用、覆蓋率幻覺、架構錯配——出處為 xUnit Test Patterns、The Art of Unit Testing、How Google Tests Software 和 Working Effectively with Legacy Code。PR 審查還會自動包含一個輕量的第 7 步快速測試檢查(對純文件或非生產程式碼 diff 會略過)。 + +### 健康儀表板 + +``` +/brooks-health # Claude Code(短命令)/ Gemini CLI +/brooks-lint:brooks-health # Claude Code(完整形式) +$brooks-health # Codex CLI +``` + +對全部四個品質維度做精簡掃描,產出加權綜合健康分(0–100)。適合發版前、新團隊上手時,或任何你想要一份「我們現在怎麼樣?」全局報告的場景。需要某個維度的深度診斷時,請改用對應的專項技能。 + +### 全面掃描 + +``` +/brooks-sweep # Claude Code(短命令)/ Gemini CLI +/brooks-lint:brooks-sweep # Claude Code(完整形式) +$brooks-sweep # Codex CLI +``` + +一次性掃描全部生產(R1–R6)與測試(T1–T6)衰退風險以及架構,然後施加修復:安全改動立即自動套用,跨檔案或觸及介面的改動需確認,複雜的架構決策則標記為人工處理項。輸出修復記錄、健康分變化和遺留項清單。 + +## 設定 + +在專案根目錄放一個 `.brooks-lint.yaml` 來客製化審查行為: + +```yaml +version: 1 + +strictness: balanced # strict | balanced(預設)| legacy-friendly——對遺留程式碼更寬鬆的評分 + +disable: + - T5 # 略過覆蓋率指標檢查——我們不強制覆蓋率 + +severity: + R1: suggestion # 在該領域下調「認知過載」診斷的嚴重度 + +ignore: + - "**/*.generated.*" + - "**/vendor/**" + +# custom_risks: # 定義專案專屬 Cx 風險碼——見 skills/_shared/custom-risks-guide.md +# suppress: # 按風險碼 + 路徑下調特定診斷(如已接受的遺留債務) +``` + +可複製 [`.brooks-lint.example.yaml`](.brooks-lint.example.yaml) 作為起點。 +所有設定均為選用——完全省略該檔案即使用預設行為。 + +| 設定 | 說明 | +|---------|-------------| +| `strictness` | 評分預設:`strict`、`balanced`(預設)或 `legacy-friendly`(更輕的扣分,並優先列出高槓桿修復項) | +| `disable` | 要略過的風險碼(`R1`–`R6`、`T1`–`T6`) | +| `severity` | 覆寫嚴重度等級(`critical` / `warning` / `suggestion`) | +| `ignore` | 要排除的檔案 glob 模式 | +| `focus` | 只評估這些風險碼(不能與 `disable` 同時使用) | +| `custom_risks` | 定義專案專屬風險碼(`C1`、`C2`……)——見 [`custom-risks-guide.md`](skills/_shared/custom-risks-guide.md) | +| `suppress` | 按風險碼 + 路徑下調特定診斷的嚴重度(可帶 `expires:` 到期日期) | + +--- + +## 為什麼是這些書,為什麼是現在? + +在 AI 輔助編程的時代,我們寫程式碼比以往任何時候都更快、更多。但六十年軟體工程沉澱下來的洞見並沒有改變: + +> *"軟體的複雜性是本質屬性,而非偶然屬性。"* +> —— Frederick Brooks + +AI 能幫你更快地寫程式碼,卻無法告訴你正在建造的是大教堂還是焦油坑。**brooks-lint 彌合了這道鴻溝**——它把十二本經典工程著作中得來不易的智慧,帶進你現代的開發工作流程。 + +這些作者識別出的衰退風險,如今比以往更切題: +- **接入 AI 助手** 並不能修復認知過載或領域模型失真 +- **產生更多程式碼** 會加劇變更擴散和知識重複 +- **跑得更快** 讓偶發複雜度和相依失序更加危險 + +## 專案結構 + +``` +brooks-lint/ +├── .claude-plugin/ # Claude Code 外掛中繼資料 +├── .codex-plugin/ # Codex CLI 外掛中繼資料 +├── skills/ +│ ├── _shared/ # 共享框架檔案 +│ │ ├── common.md # 鐵律、專案設定、報告範本、健康分 +│ │ ├── source-coverage.md # 12 本書涵蓋矩陣、權衡、誤報防護 +│ │ ├── decay-risks.md # 六類衰退風險及症狀與書目出處 +│ │ ├── test-decay-risks.md # 六類測試空間衰退風險及書目出處 +│ │ ├── remedy-guide.md # --fix 模式:可落地的對策強化規則 +│ │ └── custom-risks-guide.md # 專案自訂風險碼範本 +│ ├── brooks-review/ # 模式 1:PR 審查 +│ │ ├── SKILL.md +│ │ └── pr-review-guide.md +│ ├── brooks-audit/ # 模式 2:架構審查 +│ │ ├── SKILL.md +│ │ └── architecture-guide.md +│ ├── brooks-debt/ # 模式 3:技術債評估 +│ │ ├── SKILL.md +│ │ └── debt-guide.md +│ ├── brooks-test/ # 模式 4:測試品質審查 +│ │ ├── SKILL.md +│ │ └── test-guide.md +│ ├── brooks-health/ # 模式 5:健康儀表板 +│ │ ├── SKILL.md +│ │ └── health-guide.md +│ └── brooks-sweep/ # 模式 6:全面掃描與自動修復 +│ ├── SKILL.md +│ └── sweep-guide.md +├── hooks/ # SessionStart 掛鉤 +├── commands/ # 短命令包裝(由掛鉤自動安裝) +├── evals/ # 基準測試案例 +│ └── evals.json +└── assets/ + └── logo.svg +``` + +## CI/CD 整合 + +用 GitHub Action 在每個 PR 上自動執行 brooks-lint: + +```yaml +# .github/workflows/brooks-lint.yml +name: Brooks-Lint PR Review +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + brooks-lint: + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: hyhmrright/brooks-lint/.github/actions/brooks-lint@main + with: + mode: review + anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} + fail-below: 70 +``` + +完整範本見 [`docs/github-action-example.yml`](docs/github-action-example.yml)。 + +該 Action 會把審查結果作為 PR 留言發布,並可在健康分跌破閾值時讓檢查失敗。若儲存庫中提交了 `.brooks-lint-history.json`,留言還會包含趨勢變化(如 "85 → 82(−3),近 3 次執行")。 + +**品質閘門與 Code Scanning。** 除 `fail-below` 外,該 Action 還提供: + +```yaml + with: + mode: review + anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} + fail-on: critical # 出現任何 Critical 即失敗(none | warning | critical) + fail-on-regression: true # 健康分較上次執行下降則失敗 + sarif-file: brooks-lint.sarif # 同時把診斷上傳到 GitHub Code Scanning +``` + +`fail-on-regression` 讀取 `.brooks-lint-history.json`,因此提交該檔案即可強制「無新增回歸」。設定 `sarif-file` 會讓診斷直接顯示在 PR 的 **Files changed** 分頁,並需要 job 具備 `security-events: write` 權限。 + +**成本:** 每次 PR 執行約 $0.05–0.15,取決於 diff 大小和模型。建議僅在 `pull_request` 事件上執行。 + +## 路線圖 + +> **目前狀態(v1.4):** 12 本書地基,6 類生產衰退風險(R1–R6)+ 6 類測試衰退風險(T1–T6),6 個技能——PR 審查、架構審查、技術債、測試品質、健康儀表板、全量掃描——外加 CI 品質閘門、面向 GitHub Code Scanning 的 SARIF 輸出、嚴格度預設,以及一個可復現的 parser 保真度基準。下方較早的條目記錄的是歷史里程碑,而非目前功能集。 + +- [x] **v0.2**:外掛基礎設施(`.claude-plugin/`、掛鉤、斜線命令) +- [x] **v0.3**:八個 Brooks 維度、文件完整度評分 +- [x] **v0.4**:六本書框架、衰退風險維度、診斷鏈、基準套件 +- [x] **v0.5**:測試品質審查(模式 4)——四本測試書、六類測試衰退風險 +- [x] **v0.6**:架構審查中的 Mermaid 相依圖 +- [x] **v0.7**:`.brooks-lint.yaml` 專案設定、模式 2 主動上下文、擴展到 10 本書 +- [x] **v0.8**:帶命名空間命令的獨立技能架構 +- [x] **v0.9**:步驟校驗、自動 diff 範圍、`/brooks-health` 儀表板、趨勢追蹤、分診模式、`--fix` 對策、上手報告、GitHub Action +- [x] **v1.0**:評測自動化(`run-evals-live.mjs`)、自訂風險擴充(`Cx` 碼) +- [x] **v1.1**:全量掃描技能(`brooks-sweep`)——跨維度統一分析 + 自動修復 +- [x] **v1.2**:自主化 sweep 管線、`npm run bump` 版本傳播 +- [x] **v1.3**:Codex 市集中繼資料、多平台一鍵安裝指令碼、雙語 README + 落地頁 +- [x] **v1.4**:SARIF 輸出(GitHub Code Scanning)、CI severity + 回歸閘門、嚴格度預設(strict/balanced/legacy-friendly)、57 情境 eval 套件、可復現的 parser 保真度基準(`npm run benchmark`) + +想出一份力?現在最有價值的貢獻是新的評測案例和更好的衰退風險症狀模式。見 [CONTRIBUTING.md](CONTRIBUTING.md)。 + +## 貢獻 + +如何新增診斷、改進指南或擴充基準套件,見 [CONTRIBUTING.md](CONTRIBUTING.md)。 + +在你自己的 PR 上跑一遍 `/brooks-review`——我們用正在打造的工具來審查貢獻。 + +## 授權條款 + +MIT License——詳見 [LICENSE](LICENSE)。 + +## 致謝 + +本專案站在十二位巨人的肩膀上: + +**生產程式碼框架** +- Frederick P. Brooks Jr. — *The Mythical Man-Month*(1975,紀念版 1995) +- Steve McConnell — *Code Complete*(1993,第 2 版 2004) +- Martin Fowler — *Refactoring*(1999,第 2 版 2018) +- Robert C. Martin — *Clean Architecture*(2017) +- Andrew Hunt & David Thomas — *The Pragmatic Programmer*(1999,20 週年版 2019) +- Eric Evans — *Domain-Driven Design*(2003) +- John Ousterhout — *A Philosophy of Software Design*(2018) +- Titus Winters、Tom Manshreck、Hyrum Wright — *Software Engineering at Google*(2020) + +**測試品質框架** +- Gerard Meszaros — *xUnit Test Patterns*(2007) +- Roy Osherove — *The Art of Unit Testing*(2009,第 3 版 2023) +- Google Engineering — *How Google Tests Software*(2012) +- Michael Feathers — *Working Effectively with Legacy Code*(2004) + +本工具中編碼的衰退風險,是我們對他們思想的綜合,並應用於現代程式碼品質評估。 + +--- + +## Star 歷史 + +[![Star History Chart](https://api.star-history.com/svg?repos=hyhmrright/brooks-lint&type=Date)](https://star-history.com/#hyhmrright/brooks-lint&Date) + +--- + +

+ ⭐ 如果這個工具讓你以不同的眼光看待自己的程式碼庫,請給它點個 star! +

diff --git a/brooks-lint/SOURCE.md b/brooks-lint/SOURCE.md index 11779274..cd532654 100644 --- a/brooks-lint/SOURCE.md +++ b/brooks-lint/SOURCE.md @@ -1,8 +1,8 @@ # Source - Repo: https://github.com/hyhmrright/brooks-lint -- Ref: c77dcc655d7a39f2cf7134e7255434b9e07f5716 +- Ref: f4af0b27315ca3bdcdcdefb5ee547d1ea8b40ad9 - Remove-Paths: -- Snapshot: 2026-06-21 +- Snapshot: 2026-06-27 - Sync-Mode: copy_skill_dirs - Notes: vendored into playbook branch thirdparty/skill diff --git a/brooks-lint/assets/banner-en.svg b/brooks-lint/assets/banner-en.svg new file mode 100644 index 00000000..a0281a80 --- /dev/null +++ b/brooks-lint/assets/banner-en.svg @@ -0,0 +1,54 @@ + + + + + + Your code + PR or whole repo + + + + + + 12 classics + Brooks · Fowler · Martin + + + + + + 12 decay risks + R1–R6 · T1–T6 + + + + + + Cited findings + Symptom → Remedy + + + + + + + + + + + + + + diff --git a/brooks-lint/assets/banner-es.svg b/brooks-lint/assets/banner-es.svg new file mode 100644 index 00000000..9ff82299 --- /dev/null +++ b/brooks-lint/assets/banner-es.svg @@ -0,0 +1,54 @@ + + + + + + Tu código + PR o repo completo + + + + + + 12 clásicos + Brooks · Fowler · Martin + + + + + + 12 riesgos + de deterioro · R1–T6 + + + + + + Hallazgos + Síntoma → Remedio + + + + + + + + + + + + + + diff --git a/brooks-lint/assets/banner-ja.svg b/brooks-lint/assets/banner-ja.svg new file mode 100644 index 00000000..457d9016 --- /dev/null +++ b/brooks-lint/assets/banner-ja.svg @@ -0,0 +1,54 @@ + + + + + + あなたのコード + PR / リポジトリ全体 + + + + + + 古典12冊 + Brooks · Fowler · Martin + + + + + + 12の劣化リスク + R1–R6 · T1–T6 + + + + + + 出典付きの指摘 + 症状 → 対策 + + + + + + + + + + + + + + diff --git a/brooks-lint/assets/banner-ko.svg b/brooks-lint/assets/banner-ko.svg new file mode 100644 index 00000000..ac279409 --- /dev/null +++ b/brooks-lint/assets/banner-ko.svg @@ -0,0 +1,54 @@ + + + + + + 당신의 코드 + PR / 전체 저장소 + + + + + + 고전 12권 + Brooks · Fowler · Martin + + + + + + 12가지 리스크 + R1–R6 · T1–T6 + + + + + + 출처 있는 진단 + 증상 → 처방 + + + + + + + + + + + + + + diff --git a/brooks-lint/assets/banner-zh-CN.svg b/brooks-lint/assets/banner-zh-CN.svg new file mode 100644 index 00000000..2fd6103b --- /dev/null +++ b/brooks-lint/assets/banner-zh-CN.svg @@ -0,0 +1,54 @@ + + + + + + 你的代码 + PR 或整个仓库 + + + + + + 十二本经典 + 布鲁克斯 · 福勒 · 马丁 + + + + + + 十二类衰退风险 + R1–R6 · T1–T6 + + + + + + 带出处的结论 + 症状 → 对策 + + + + + + + + + + + + + + diff --git a/brooks-lint/assets/banner-zh-TW.svg b/brooks-lint/assets/banner-zh-TW.svg new file mode 100644 index 00000000..1b8c5394 --- /dev/null +++ b/brooks-lint/assets/banner-zh-TW.svg @@ -0,0 +1,54 @@ + + + + + + 你的程式碼 + PR 或整個儲存庫 + + + + + + 十二本經典 + 布魯克斯 · 福勒 · 馬丁 + + + + + + 十二類衰退風險 + R1–R6 · T1–T6 + + + + + + 帶出處的結論 + 症狀 → 對策 + + + + + + + + + + + + + + diff --git a/brooks-lint/docs/banner-en.svg b/brooks-lint/docs/banner-en.svg new file mode 100644 index 00000000..a0281a80 --- /dev/null +++ b/brooks-lint/docs/banner-en.svg @@ -0,0 +1,54 @@ + + + + + + Your code + PR or whole repo + + + + + + 12 classics + Brooks · Fowler · Martin + + + + + + 12 decay risks + R1–R6 · T1–T6 + + + + + + Cited findings + Symptom → Remedy + + + + + + + + + + + + + + diff --git a/brooks-lint/docs/banner-es.svg b/brooks-lint/docs/banner-es.svg new file mode 100644 index 00000000..9ff82299 --- /dev/null +++ b/brooks-lint/docs/banner-es.svg @@ -0,0 +1,54 @@ + + + + + + Tu código + PR o repo completo + + + + + + 12 clásicos + Brooks · Fowler · Martin + + + + + + 12 riesgos + de deterioro · R1–T6 + + + + + + Hallazgos + Síntoma → Remedio + + + + + + + + + + + + + + diff --git a/brooks-lint/docs/banner-ja.svg b/brooks-lint/docs/banner-ja.svg new file mode 100644 index 00000000..457d9016 --- /dev/null +++ b/brooks-lint/docs/banner-ja.svg @@ -0,0 +1,54 @@ + + + + + + あなたのコード + PR / リポジトリ全体 + + + + + + 古典12冊 + Brooks · Fowler · Martin + + + + + + 12の劣化リスク + R1–R6 · T1–T6 + + + + + + 出典付きの指摘 + 症状 → 対策 + + + + + + + + + + + + + + diff --git a/brooks-lint/docs/banner-ko.svg b/brooks-lint/docs/banner-ko.svg new file mode 100644 index 00000000..ac279409 --- /dev/null +++ b/brooks-lint/docs/banner-ko.svg @@ -0,0 +1,54 @@ + + + + + + 당신의 코드 + PR / 전체 저장소 + + + + + + 고전 12권 + Brooks · Fowler · Martin + + + + + + 12가지 리스크 + R1–R6 · T1–T6 + + + + + + 출처 있는 진단 + 증상 → 처방 + + + + + + + + + + + + + + diff --git a/brooks-lint/docs/banner-zh-CN.svg b/brooks-lint/docs/banner-zh-CN.svg new file mode 100644 index 00000000..2fd6103b --- /dev/null +++ b/brooks-lint/docs/banner-zh-CN.svg @@ -0,0 +1,54 @@ + + + + + + 你的代码 + PR 或整个仓库 + + + + + + 十二本经典 + 布鲁克斯 · 福勒 · 马丁 + + + + + + 十二类衰退风险 + R1–R6 · T1–T6 + + + + + + 带出处的结论 + 症状 → 对策 + + + + + + + + + + + + + + diff --git a/brooks-lint/docs/banner-zh-TW.svg b/brooks-lint/docs/banner-zh-TW.svg new file mode 100644 index 00000000..1b8c5394 --- /dev/null +++ b/brooks-lint/docs/banner-zh-TW.svg @@ -0,0 +1,54 @@ + + + + + + 你的程式碼 + PR 或整個儲存庫 + + + + + + 十二本經典 + 布魯克斯 · 福勒 · 馬丁 + + + + + + 十二類衰退風險 + R1–R6 · T1–T6 + + + + + + 帶出處的結論 + 症狀 → 對策 + + + + + + + + + + + + + + diff --git a/brooks-lint/docs/gallery.html b/brooks-lint/docs/gallery.html index 8152f7cd..29597b0a 100644 --- a/brooks-lint/docs/gallery.html +++ b/brooks-lint/docs/gallery.html @@ -92,6 +92,9 @@ .foot-links{display:flex;gap:20px;flex-wrap:wrap;} .foot-links a{color:var(--ink-soft);font-size:14px;} .foot-note{font-size:13px;color:var(--ink-soft);} .hidden{display:none !important;} + .lang-toggle{display:inline-flex;border:1px solid var(--rule);border-radius:999px;overflow:hidden;font-size:13px;background:var(--card);} + .lang-toggle button{border:none;background:transparent;padding:5px 11px;cursor:pointer;color:var(--ink-soft);font-family:var(--sans);font-weight:600;font-size:12.5px;} + .lang-toggle button.active{background:var(--ink);color:var(--paper-2);} @@ -100,20 +103,28 @@
-

The Gallery

-

Real diagnostic output from brooks-lint — generated by running the skill, then lightly abridged. Four languages, four review modes, every finding in the Iron Law form.

+

The Gallery

+

Real diagnostic output from brooks-lint — generated by running the skill, then lightly abridged. Four languages, four review modes, every finding in the Iron Law form.

- 8 worked examples - 4 review modes - 4 languages + 8 worked examples + 4 review modes + 4 languages Python · TypeScript · Go · Java
@@ -121,11 +132,11 @@
- - - - - + + + + +
@@ -133,18 +144,18 @@
-

PR Review Mode 1

-

Diagnoses a diff against the six production decay risks (R1–R6).

+

PR Review Mode 1

+

Diagnoses a diff against the six production decay risks (R1–R6).

TypeScript -

Seven-service payment processor

+

Seven-service payment processor

55 / 100
-

A single method orchestrates seven services, creating a structural coupling trap where any change to payment, fraud, inventory, or notification touches the same method.

+

A single method orchestrates seven services, creating a structural coupling trap where any change to payment, fraud, inventory, or notification touches the same method.

- ▸ Input code + ▸ Input code
class PaymentProcessor {
   constructor(
     private db, private stripe, private mailer, private inventory,
@@ -170,43 +181,43 @@
 }
-

🔴 Change Propagation — Seven-service constructor signals a God Class

-
Symptom: One class injects seven dependencies; one method orchestrates all of them.
-
Source: Fowler — Refactoring — Divergent Change; Martin — Clean Architecture — SRP
-
Remedy: Decompose into FraudCheckService, InventoryDeductionService, PaymentNotifier — inject 3, not 7.
+

🔴 Change Propagation — Seven-service constructor signals a God Class

+
Symptom: One class injects seven dependencies; one method orchestrates all of them.
+
Source: Fowler — Refactoring — Divergent Change; Martin — Clean Architecture — SRP
+
Remedy: Decompose into FraudCheckService, InventoryDeductionService, PaymentNotifier — inject 3, not 7.
-

🔴 Change Propagation — Inventory loop embeds warehouse notification policy

-
Symptom: A low-stock check (< 10) fires a warehouse email with hardcoded recipient inside the payment loop.
-
Source: Fowler — Refactoring — Shotgun Surgery; Hunt & Thomas — Orthogonality
-
Remedy: Publish a StockLevelChanged domain event a separate notifier subscribes to.
+

🔴 Change Propagation — Inventory loop embeds warehouse notification policy

+
Symptom: A low-stock check (< 10) fires a warehouse email with hardcoded recipient inside the payment loop.
+
Source: Fowler — Refactoring — Shotgun Surgery; Hunt & Thomas — Orthogonality
+
Remedy: Publish a StockLevelChanged domain event a separate notifier subscribes to.
-

🟡 Knowledge Duplication — order.total + tax computed three times

-
Symptom: The same expression appears on three lines with no shared name.
-
Source: Hunt & Thomas — DRY; Fowler — Refactoring — Duplicate Code
-
Remedy: Expose a computed order.grandTotal.
+

🟡 Knowledge Duplication — order.total + tax computed three times

+
Symptom: The same expression appears on three lines with no shared name.
+
Source: Hunt & Thomas — DRY; Fowler — Refactoring — Duplicate Code
+
Remedy: Expose a computed order.grandTotal.
-

🟡 Domain Model Distortion — Order is a mutable data bag

-
Symptom: order.tax, order.status, order.chargeId are all set externally; the object holds no behaviour.
-
Remedy: Give Order state-transition methods: order.recordPayment(chargeId).
+

🟡 Domain Model Distortion — Order is a mutable data bag

+
Symptom: order.tax, order.status, order.chargeId are all set externally; the object holds no behaviour.
+
Remedy: Give Order state-transition methods: order.recordPayment(chargeId).
-

Architecture Audit Mode 2

-

Maps module dependencies, renders a colour-coded graph, and flags layering and cycle violations.

+

Architecture Audit Mode 2

+

Maps module dependencies, renders a colour-coded graph, and flags layering and cycle violations.

TypeScript -

Dependency Inversion violation

+

Dependency Inversion violation

50 / 100
-

Domain entities import infrastructure directly, and a near-cycle forms between Product and PricingService.

+

Domain entities import infrastructure directly, and a near-cycle forms between Product and PricingService.

graph TD
   subgraph API["API Layer"]
     OrderController; UserController
@@ -237,26 +248,26 @@
   class OrderService,PricingService,UserService warning
   class OrderController,UserController,PostgresClient,RedisCache,StripeClient clean
-

🔴 Dependency Disorder — Domain layer directly imports infrastructure

-
Symptom: Order.ts imports PostgresClient; User.ts imports RedisCache.
-
Source: Martin — Clean Architecture — Dependency Inversion Principle
-
Remedy: Define IOrderRepository/IUserRepository in the domain; move infra refs to infra/.
+

🔴 Dependency Disorder — Domain layer directly imports infrastructure

+
Symptom: Order.ts imports PostgresClient; User.ts imports RedisCache.
+
Source: Martin — Clean Architecture — Dependency Inversion Principle
+
Remedy: Define IOrderRepository/IUserRepository in the domain; move infra refs to infra/.
-

🔴 Dependency Disorder — Product → PricingService (upward dependency)

-
Symptom: Near-cycle PricingService → Product → PricingService.
-
Source: Martin — Clean Architecture — Acyclic Dependencies Principle
-
Remedy: Pass pricing as a value object or define IPricingPolicy in the domain.
+

🔴 Dependency Disorder — Product → PricingService (upward dependency)

+
Symptom: Near-cycle PricingService → Product → PricingService.
+
Source: Martin — Clean Architecture — Acyclic Dependencies Principle
+
Remedy: Pass pricing as a value object or define IPricingPolicy in the domain.
Go -

Circular dependency across packages

+

Circular dependency across packages

45 / 100
-

auth → user → notification → auth forms a strongly connected component — Go refuses to compile it.

+

auth → user → notification → auth forms a strongly connected component — Go refuses to compile it.

graph TD
   subgraph pkg["pkg/"]
     auth["auth"]; user["user"]; notification["notification"]; billing["billing"]
@@ -270,26 +281,26 @@
   class auth,user,notification critical
   class billing warning
-

🔴 Dependency Disorder — Circular dependency auth → user → notification → auth

-
Symptom: Three packages form a cycle; none compile, test, or deploy independently.
-
Source: Martin — Clean Architecture — Acyclic Dependencies Principle
-
Remedy: Extract interfaces into pkg/contracts; each package implements the interface its consumer defines.
+

🔴 Dependency Disorder — Circular dependency auth → user → notification → auth

+
Symptom: Three packages form a cycle; none compile, test, or deploy independently.
+
Source: Martin — Clean Architecture — Acyclic Dependencies Principle
+
Remedy: Extract interfaces into pkg/contracts; each package implements the interface its consumer defines.
-

🟡 Domain Model Distortion — Bounded contexts crossed with no anti-corruption layer

-
Symptom: Identity, profile, and notification contexts import each other with no translation layer.
-
Source: Evans — DDD — Bounded Context; Anti-Corruption Layer
-
Remedy: Define thin adapters at each context boundary.
+

🟡 Domain Model Distortion — Bounded contexts crossed with no anti-corruption layer

+
Symptom: Identity, profile, and notification contexts import each other with no translation layer.
+
Source: Evans — DDD — Bounded Context; Anti-Corruption Layer
+
Remedy: Define thin adapters at each context boundary.
Java -

Textbook Clean Architecture

+

Textbook Clean Architecture

98 / 100
-

Dependencies flow inward, infra implements domain ports, no cycles. brooks-lint reports clean code as clean — and still offers one forward-looking suggestion.

+

Dependencies flow inward, infra implements domain ports, no cycles. brooks-lint reports clean code as clean — and still offers one forward-looking suggestion.

graph TD
   subgraph API["API Layer"]
     OrderController; UserController
@@ -314,71 +325,76 @@
   classDef clean fill:#51cf66,stroke:#2b8a3e,color:#fff
   class OrderController,UserController,OrderService,UserService,OrderModel,UserModel,OrderRepository,UserRepository,JpaOrderRepository,JpaUserRepository clean
-

🟢 Suggestion — Monitor application service growth

-
Symptom: OrderService and UserService are symmetric siblings that may accrue responsibilities without a split policy.
-
Source: Brooks — The Mythical Man-Month — Conceptual Integrity
-
Remedy: Document a "one service per use-case cluster" rule now, before the pattern calcifies.
+

🟢 Suggestion — Monitor application service growth

+
Symptom: OrderService and UserService are symmetric siblings that may accrue responsibilities without a split policy.
+
Source: Brooks — The Mythical Man-Month — Conceptual Integrity
+
Remedy: Document a "one service per use-case cluster" rule now, before the pattern calcifies.
-

Tech Debt Assessment Mode 3

-

Classifies debt across the decay risks and scores each finding by Pain × Spread priority.

+

Tech Debt Assessment Mode 3

+

Classifies debt across the decay risks and scores each finding by Pain × Spread priority.

Java -

Shotgun Surgery across six files

+

Shotgun Surgery across six files

56 / 100
-

Adding a currency means editing six files in six unrelated layers — three Critical findings that share one root cause.

+

Adding a currency means editing six files in six unrelated layers — three Critical findings that share one root cause.

- + + + + + + - - - - + + + +
RiskFindingsAvg PriorityClassification
RiskFindingsAvg PriorityClassification
Change Propagation26.5Mixed (1 Critical + 1 Scheduled)
Knowledge Duplication19.0Critical
Domain Model Distortion19.0Critical
Cognitive Overload16.0Scheduled
Change Propagation26.5Mixed (1 Critical + 1 Scheduled)
Knowledge Duplication19.0Critical
Domain Model Distortion19.0Critical
Cognitive Overload16.0Scheduled
-

🔴 Change Propagation — Shotgun Surgery across six modules Pain × Spread: 9

-
Symptom: Adding EUR requires editing 6 files in 6 distinct layers with no architectural relationship.
-
Source: Fowler — Refactoring — Shotgun Surgery; Hunt & Thomas — Orthogonality
-
Remedy: Introduce a Money value object and a MoneyFormatter service.
+

🔴 Change Propagation — Shotgun Surgery across six modules Pain × Spread: 9

+
Symptom: Adding EUR requires editing 6 files in 6 distinct layers with no architectural relationship.
+
Source: Fowler — Refactoring — Shotgun Surgery; Hunt & Thomas — Orthogonality
+
Remedy: Introduce a Money value object and a MoneyFormatter service.
-

🔴 Knowledge Duplication — $ as a magic literal in five files Pain × Spread: 9

-
Symptom: The string "$" appears in 5 independent locations with no shared constant.
-
Source: Hunt & Thomas — DRY; McConnell — Code Complete — Ch. 12
-
Remedy: Use Currency.getSymbol(Locale) in MoneyFormatter; remove all "$" literals.
+

🔴 Knowledge Duplication — $ as a magic literal in five files Pain × Spread: 9

+
Symptom: The string "$" appears in 5 independent locations with no shared constant.
+
Source: Hunt & Thomas — DRY; McConnell — Code Complete — Ch. 12
+
Remedy: Use Currency.getSymbol(Locale) in MoneyFormatter; remove all "$" literals.
-

🔴 Domain Model Distortion — No Money type exists Pain × Spread: 9

-
Symptom: All price/amount fields are raw double.
-
Source: Evans — DDD — Domain Model; Fowler — Refactoring — Data Class
-
Remedy: Introduce record Money(BigDecimal amount, Currency currency).
+

🔴 Domain Model Distortion — No Money type exists Pain × Spread: 9

+
Symptom: All price/amount fields are raw double.
+
Source: Evans — DDD — Domain Model; Fowler — Refactoring — Data Class
+
Remedy: Introduce record Money(BigDecimal amount, Currency currency).
-
Recommended focus: All three Critical findings share one root cause — the absence of a Money value object. One intervention collapses three findings.
+
Recommended focus: All three Critical findings share one root cause — the absence of a Money value object. One intervention collapses three findings.
-

Test Quality Review Mode 4

-

Audits an existing suite against six test-space decay risks (T1–T6).

+

Test Quality Review Mode 4

+

Audits an existing suite against six test-space decay risks (T1–T6).

TypeScript -

Mock abuse

+

Mock abuse

60 / 100
-

Seven mocks per test, 14 lines of setup vs 6 of assertions — the service is never tested against a real collaborator, and the return value is never checked.

+

Seven mocks per test, 14 lines of setup vs 6 of assertions — the service is never tested against a real collaborator, and the return value is never checked.

- ▸ Input test + ▸ Input test
it('should place an order successfully', () => {
   const mockDb = mock<Database>();
   const mockPayment = mock<PaymentGateway>();
@@ -399,28 +415,28 @@
 });
-

🔴 Mock Abuse — Seven mocks per test; setup dominates logic

-
Symptom: 7 mock objects; 14 lines of setup vs 6 of assertions. No real collaborator is ever exercised.
-
Source: Osherove — The Art of Unit Testing (mock count > 3); Meszaros — xUnit Test Patterns
-
Remedy: Reduce mocks to ≤ 3, use in-memory fakes, assert on result first.
+

🔴 Mock Abuse — Seven mocks per test; setup dominates logic

+
Symptom: 7 mock objects; 14 lines of setup vs 6 of assertions. No real collaborator is ever exercised.
+
Source: Osherove — The Art of Unit Testing (mock count > 3); Meszaros — xUnit Test Patterns
+
Remedy: Reduce mocks to ≤ 3, use in-memory fakes, assert on result first.
-

🔴 Mock Abuse — All six assertions verify mock calls, not behaviour

-
Symptom: Every assertion is toHaveBeenCalledWith; result is captured but never asserted.
-
Consequence: A placeOrder that calls every mock yet returns null or double-charges still passes.
-
Remedy: Assert observable output: expect(result.status).toBe('confirmed').
+

🔴 Mock Abuse — All six assertions verify mock calls, not behaviour

+
Symptom: Every assertion is toHaveBeenCalledWith; result is captured but never asserted.
+
Consequence: A placeOrder that calls every mock yet returns null or double-charges still passes.
+
Remedy: Assert observable output: expect(result.status).toBe('confirmed').
Python -

Inverted test pyramid

+

Inverted test pyramid

55 / 100
-

Only 16% of tests are unit tests; an E2E-heavy suite takes ~9 minutes and blocks fast CI feedback.

+

Only 16% of tests are unit tests; an E2E-heavy suite takes ~9 minutes and blocks fast CI feedback.

- ▸ Suite overview + ▸ Suite overview
tests/
 ├── e2e/           47 tests, avg 8s each   (~6 min)
 ├── integration/   83 tests, avg 2s each   (~3 min)
@@ -431,21 +447,21 @@ Actual  ratio:  Unit 16% : Integration 54% : E2E 30%
 Target  ratio:  Unit 70% : Integration 20% : E2E 10%
-

🔴 Architecture Mismatch — Fully inverted test pyramid

-
Symptom: Only 24 of 154 tests (16%) are unit tests; E2E + integration = 84%.
-
Source: Google — How Google Tests Software — 70:20:10; Meszaros — xUnit Test Patterns
-
Remedy: Target 70% unit; reduce E2E to 5–8 critical smoke tests.
+

🔴 Architecture Mismatch — Fully inverted test pyramid

+
Symptom: Only 24 of 154 tests (16%) are unit tests; E2E + integration = 84%.
+
Source: Google — How Google Tests Software — 70:20:10; Meszaros — xUnit Test Patterns
+
Remedy: Target 70% unit; reduce E2E to 5–8 critical smoke tests.
-

🔴 Architecture Mismatch — 9-minute suite blocks CI fast-feedback

-
Symptom: Full suite ~542s, dominated by 8s E2E tests.
-
Remedy: Split CI: (1) unit only, < 60s, blocks merge; (2) integration + E2E async, non-blocking.
+

🔴 Architecture Mismatch — 9-minute suite blocks CI fast-feedback

+
Symptom: Full suite ~542s, dominated by 8s E2E tests.
+
Remedy: Split CI: (1) unit only, < 60s, blocks merge; (2) integration + E2E async, non-blocking.
-

🟡 Coverage Illusion — Core domain untested at unit level

-
Symptom: tests/unit/ covers only validators and formatters — no checkout, login, order, or payment.
-
Source: Feathers — Working Effectively with Legacy Code
-
Remedy: Start with test_checkout_flow.py and test_payment_api.py.
+

🟡 Coverage Illusion — Core domain untested at unit level

+
Symptom: tests/unit/ covers only validators and formatters — no checkout, login, order, or payment.
+
Source: Feathers — Working Effectively with Legacy Code
+
Remedy: Start with test_checkout_flow.py and test_payment_api.py.
@@ -455,11 +471,11 @@ Target ratio: Unit 70% : Integration 20% : E2E 10% @@ -491,5 +507,37 @@ Target ratio: Unit 70% : Integration 20% : E2E 10% }); })(); + diff --git a/brooks-lint/docs/guide.html b/brooks-lint/docs/guide.html index a34b1459..99fcc6a0 100644 --- a/brooks-lint/docs/guide.html +++ b/brooks-lint/docs/guide.html @@ -71,6 +71,9 @@ .cta a{display:inline-block;margin-top:14px;background:var(--gold);color:#1c160f;font-weight:700;text-decoration:none;padding:10px 22px;border-radius:8px;} footer{margin-top:56px;padding-top:24px;border-top:1px solid var(--rule);font-size:14px;color:var(--ink-soft);text-align:center;} footer a{color:var(--blue);text-decoration:none;} + .lang-toggle{display:inline-flex;border:1px solid var(--rule);border-radius:999px;overflow:hidden;font-size:13px;background:var(--card);vertical-align:middle;} + .lang-toggle button{border:none;background:transparent;padding:4px 9px;cursor:pointer;color:var(--ink-soft);font-family:var(--sans);font-weight:600;font-size:12.5px;} + .lang-toggle button.active{background:var(--ink);color:var(--paper);} @@ -78,142 +81,182 @@
brooks-lint logo brooks-lint - + + + + + + + + +
-

The Six Code Decay Risks

-

A field guide to the ways production code rots — and the classic engineering books that named each one fifty years before your codebase did it again.

-

Most linters count lines and cyclomatic complexity. They measure the surface. Decay happens underneath: in how responsibilities tangle, how knowledge duplicates, how dependencies invert. These six patterns are a synthesis of twelve classic software engineering books, applied to modern code review.

+

The Six Code Decay Risks

+

A field guide to the ways production code rots — and the classic engineering books that named each one fifty years before your codebase did it again.

+

Most linters count lines and cyclomatic complexity. They measure the surface. Decay happens underneath: in how responsibilities tangle, how knowledge duplicates, how dependencies invert. These six patterns are a synthesis of twelve classic software engineering books, applied to modern code review.

-

The six risks

+

The six risks

    -
  1. Cognitive Overload — how hard is this to understand?
  2. -
  3. Change Propagation — what breaks when you touch one thing?
  4. -
  5. Knowledge Duplication — is one decision expressed in many places?
  6. -
  7. Accidental Complexity — is the code harder than the problem?
  8. -
  9. Dependency Disorder — do dependencies flow one way?
  10. -
  11. Domain Model Distortion — does the code mean what the business means?
  12. +
  13. Cognitive Overload — how hard is this to understand?
  14. +
  15. Change Propagation — what breaks when you touch one thing?
  16. +
  17. Knowledge Duplication — is one decision expressed in many places?
  18. +
  19. Accidental Complexity — is the code harder than the problem?
  20. +
  21. Dependency Disorder — do dependencies flow one way?
  22. +
  23. Domain Model Distortion — does the code mean what the business means?
-

Each risk below follows the same shape brooks-lint uses for every finding — the Iron Law: Symptom → Source → Consequence → Remedy. A symptom you can see in the diff, a source you can cite to a book, a consequence that explains why it matters, and a remedy you can actually apply.

+

Each risk below follows the same shape brooks-lint uses for every finding — the Iron Law: Symptom → Source → Consequence → Remedy. A symptom you can see in the diff, a source you can cite to a book, a consequence that explains why it matters, and a remedy you can actually apply.

-

1 · Cognitive Overload R1

+

1 · Cognitive Overload R1

-

Diagnostic question: How much mental effort does a human need to understand this?

-

Working memory holds about four chunks at once. Code that exceeds that budget causes mistakes, invites avoidance, and blocks the very refactoring that would fix it.

-

Signature symptoms

+

Diagnostic question: How much mental effort does a human need to understand this?

+

Working memory holds about four chunks at once. Code that exceeds that budget causes mistakes, invites avoidance, and blocks the very refactoring that would fix it.

+

Signature symptoms

    -
  • Functions that mix multiple levels of abstraction in one body, or run past ~20 lines
  • -
  • Nesting deeper than three levels; boolean conditions with three or more clauses
  • -
  • Long parameter lists, flag arguments, and "train-wreck" chains like a.getB().getC().doD()
  • -
  • Primitive obsession — domain concepts smuggled through as String/int instead of purpose-built types
  • -
  • Shallow modules — an interface as complex as the functionality it hides
  • +
  • Functions that mix multiple levels of abstraction in one body, or run past ~20 lines
  • +
  • Nesting deeper than three levels; boolean conditions with three or more clauses
  • +
  • Long parameter lists, flag arguments, and "train-wreck" chains like a.getB().getC().doD()
  • +
  • Primitive obsession — domain concepts smuggled through as String/int instead of purpose-built types
  • +
  • Shallow modules — an interface as complex as the functionality it hides
-

Sources: Fowler, Refactoring (Long Method, Long Parameter List, Message Chains, Primitive Obsession) · McConnell, Code Complete (high-quality routines, the power of variable names) · Ousterhout, A Philosophy of Software Design (deep modules) · Evans, Domain-Driven Design (ubiquitous language).

-

Remedy

-

Extract methods until each one operates at a single level of abstraction. Replace primitives with value types. Make modules deep: a simple interface over substantial functionality, not a thin wrapper.

+

Sources: Fowler, Refactoring (Long Method, Long Parameter List, Message Chains, Primitive Obsession) · McConnell, Code Complete (high-quality routines, the power of variable names) · Ousterhout, A Philosophy of Software Design (deep modules) · Evans, Domain-Driven Design (ubiquitous language).

+

Remedy

+

Extract methods until each one operates at a single level of abstraction. Replace primitives with value types. Make modules deep: a simple interface over substantial functionality, not a thin wrapper.

-

2 · Change Propagation R2

+

2 · Change Propagation R2

-

Diagnostic question: How many unrelated things break when you change one thing?

-

This is the most expensive decay risk because it compounds: every future edit inherits the blast radius of the last one.

-

Signature symptoms

+

Diagnostic question: How many unrelated things break when you change one thing?

+

This is the most expensive decay risk because it compounds: every future edit inherits the blast radius of the last one.

+

Signature symptoms

    -
  • Modifying one feature forces edits across more than three files in unrelated modules
  • -
  • One class changes for several different business reasons (Single Responsibility violation)
  • -
  • Shotgun surgery: a single conceptual change scattered across many small edits
  • +
  • Modifying one feature forces edits across more than three files in unrelated modules
  • +
  • One class changes for several different business reasons (Single Responsibility violation)
  • +
  • Shotgun surgery: a single conceptual change scattered across many small edits
-

Sources: Fowler, Refactoring (Divergent Change, Shotgun Surgery) · Martin, Clean Architecture (Single Responsibility) · Hunt & Thomas, The Pragmatic Programmer (orthogonality) · Winters et al., Software Engineering at Google.

-

Remedy

-

Separate responsibilities into focused units and let a thin orchestrator call them. Aim for orthogonality — changing the loyalty formula should never risk breaking email notifications.

+

Sources: Fowler, Refactoring (Divergent Change, Shotgun Surgery) · Martin, Clean Architecture (Single Responsibility) · Hunt & Thomas, The Pragmatic Programmer (orthogonality) · Winters et al., Software Engineering at Google.

+

Remedy

+

Separate responsibilities into focused units and let a thin orchestrator call them. Aim for orthogonality — changing the loyalty formula should never risk breaking email notifications.

-

3 · Knowledge Duplication R3

+

3 · Knowledge Duplication R3

-

Diagnostic question: Is the same decision expressed in more than one place?

-

DRY is about knowledge, not text. Two identical-looking blocks that encode different decisions are fine; one decision copied into three files is a latent bug waiting for the day someone updates two of them.

-

Signature symptoms

+

Diagnostic question: Is the same decision expressed in more than one place?

+

DRY is about knowledge, not text. Two identical-looking blocks that encode different decisions are fine; one decision copied into three files is a latent bug waiting for the day someone updates two of them.

+

Signature symptoms

    -
  • The same logic copy-pasted across files or functions
  • -
  • One concept named differently in different parts of the codebase
  • -
  • Business rules (tax rates, validation limits) hard-coded in multiple spots
  • +
  • The same logic copy-pasted across files or functions
  • +
  • One concept named differently in different parts of the codebase
  • +
  • Business rules (tax rates, validation limits) hard-coded in multiple spots
-

Sources: Hunt & Thomas, The Pragmatic Programmer (DRY) · Fowler, Refactoring (Duplicated Code) · Evans, Domain-Driven Design.

-

Remedy

-

Give each decision a single authoritative home. Extract shared logic; unify vocabulary so one concept has one name everywhere.

+

Sources: Hunt & Thomas, The Pragmatic Programmer (DRY) · Fowler, Refactoring (Duplicated Code) · Evans, Domain-Driven Design.

+

Remedy

+

Give each decision a single authoritative home. Extract shared logic; unify vocabulary so one concept has one name everywhere.

-

4 · Accidental Complexity R4

+

4 · Accidental Complexity R4

-

Diagnostic question: Is the code more complex than the problem it solves?

-

Brooks distinguished essential complexity (inherent to the problem) from accidental complexity (introduced by our solution). The second kind is the only kind you can delete.

-

Signature symptoms

+

Diagnostic question: Is the code more complex than the problem it solves?

+

Brooks distinguished essential complexity (inherent to the problem) from accidental complexity (introduced by our solution). The second kind is the only kind you can delete.

+

Signature symptoms

    -
  • Abstractions built "for future use" with no current consumer (speculative generality)
  • -
  • Classes that barely justify their existence — a wrapper around a single call
  • -
  • Configuration, indirection, or patterns out of proportion to the actual requirement
  • +
  • Abstractions built "for future use" with no current consumer (speculative generality)
  • +
  • Classes that barely justify their existence — a wrapper around a single call
  • +
  • Configuration, indirection, or patterns out of proportion to the actual requirement
-

Sources: Brooks, The Mythical Man-Month (essential vs. accidental complexity) · Fowler, Refactoring (Speculative Generality) · Ousterhout, A Philosophy of Software Design.

-

Remedy

-

Delete speculative abstractions until a second real consumer appears. Prefer the simplest design that solves today's problem — you can always add structure when the need is concrete.

+

Sources: Brooks, The Mythical Man-Month (essential vs. accidental complexity) · Fowler, Refactoring (Speculative Generality) · Ousterhout, A Philosophy of Software Design.

+

Remedy

+

Delete speculative abstractions until a second real consumer appears. Prefer the simplest design that solves today's problem — you can always add structure when the need is concrete.

-

5 · Dependency Disorder R5

+

5 · Dependency Disorder R5

-

Diagnostic question: Do dependencies flow in a consistent, predictable direction?

-

Architecture is mostly about the direction of the arrows. When high-level policy depends on low-level detail, the detail starts driving the design.

-

Signature symptoms

+

Diagnostic question: Do dependencies flow in a consistent, predictable direction?

+

Architecture is mostly about the direction of the arrows. When high-level policy depends on low-level detail, the detail starts driving the design.

+

Signature symptoms

    -
  • Circular dependencies between modules or packages
  • -
  • High-level business logic importing directly from low-level infrastructure (DB drivers, HTTP clients)
  • -
  • The domain layer reaching out to frameworks instead of the other way around
  • +
  • Circular dependencies between modules or packages
  • +
  • High-level business logic importing directly from low-level infrastructure (DB drivers, HTTP clients)
  • +
  • The domain layer reaching out to frameworks instead of the other way around
-

Sources: Martin, Clean Architecture (Dependency Inversion, the Dependency Rule) · Brooks, The Mythical Man-Month · Winters et al., Software Engineering at Google.

-

Remedy

-

Invert the dependency: define an interface the high-level code owns, and let infrastructure implement it. Break cycles by extracting the shared abstraction both sides can depend on.

+

Sources: Martin, Clean Architecture (Dependency Inversion, the Dependency Rule) · Brooks, The Mythical Man-Month · Winters et al., Software Engineering at Google.

+

Remedy

+

Invert the dependency: define an interface the high-level code owns, and let infrastructure implement it. Break cycles by extracting the shared abstraction both sides can depend on.

-

6 · Domain Model Distortion R6

+

6 · Domain Model Distortion R6

-

Diagnostic question: Does the code faithfully represent the problem it is solving?

-

When the model drifts from the domain, every reader has to translate in their head — and translation errors become bugs.

-

Signature symptoms

+

Diagnostic question: Does the code faithfully represent the problem it is solving?

+

When the model drifts from the domain, every reader has to translate in their head — and translation errors become bugs.

+

Signature symptoms

    -
  • Anemic models: business logic scattered across services while domain objects hold only getters and setters
  • -
  • Names that don't match what business stakeholders actually call the concept
  • -
  • Logic bugs hiding in code that reads plausibly but doesn't model reality (e.g. comparing a value to itself after overwriting it)
  • +
  • Anemic models: business logic scattered across services while domain objects hold only getters and setters
  • +
  • Names that don't match what business stakeholders actually call the concept
  • +
  • Logic bugs hiding in code that reads plausibly but doesn't model reality (e.g. comparing a value to itself after overwriting it)
-

Sources: Evans, Domain-Driven Design (rich models, ubiquitous language) · Fowler, Refactoring (Anemic Domain Model).

-

Remedy

-

Move behaviour onto the objects that own the data. Align every name with the language the business uses. Make illegal states unrepresentable.

+

Sources: Evans, Domain-Driven Design (rich models, ubiquitous language) · Fowler, Refactoring (Anemic Domain Model).

+

Remedy

+

Move behaviour onto the objects that own the data. Align every name with the language the business uses. Make illegal states unrepresentable.

-

And the test suite decays too

-

brooks-lint applies the same lens to tests, with six parallel risks (T1–T6) drawn from xUnit Test Patterns, The Art of Unit Testing, How Google Tests Software, and Working Effectively with Legacy Code:

+

And the test suite decays too

+

brooks-lint applies the same lens to tests, with six parallel risks (T1–T6) drawn from xUnit Test Patterns, The Art of Unit Testing, How Google Tests Software, and Working Effectively with Legacy Code:

- - - - - - - + + + + + + +
RiskThe question it asks
Test ObscurityCan you tell what a test verifies without reading its implementation?
Test BrittlenessDoes a refactor that preserves behaviour still break the test?
Test DuplicationIs the same setup or assertion copied across many tests?
Mock AbuseDoes the test verify interactions instead of outcomes?
Coverage IllusionDoes high coverage hide tests that assert nothing meaningful?
Architecture MismatchDo the tests fight the code's seams instead of using them?
RiskThe question it asks
Test ObscurityCan you tell what a test verifies without reading its implementation?
Test BrittlenessDoes a refactor that preserves behaviour still break the test?
Test DuplicationIs the same setup or assertion copied across many tests?
Mock AbuseDoes the test verify interactions instead of outcomes?
Coverage IllusionDoes high coverage hide tests that assert nothing meaningful?
Architecture MismatchDo the tests fight the code's seams instead of using them?
-

See it run on your own code

-

brooks-lint is a free, open-source plugin for Claude Code, Gemini CLI, and Codex. Install it and review any file in one command:

-

/plugin marketplace add hyhmrright/brooks-lint
/brooks-review

- ⭐ Get it on GitHub +

See it run on your own code

+

brooks-lint is a free, open-source plugin for Claude Code, Gemini CLI, and Codex. Install it and review any file in one command:

+

/plugin marketplace add hyhmrright/brooks-lint
/brooks-review

+ ⭐ Get it on GitHub
+ diff --git a/brooks-lint/docs/index.html b/brooks-lint/docs/index.html index c193f9b1..3d5bb5e2 100644 --- a/brooks-lint/docs/index.html +++ b/brooks-lint/docs/index.html @@ -28,7 +28,7 @@ "description": "AI code reviews grounded in twelve classic software engineering books. Decay-risk diagnostics with book citations, severity labels, and six analysis modes including full-sweep auto-fix.", "url": "https://hyhmrright.github.io/brooks-lint/", "image": "https://hyhmrright.github.io/brooks-lint/hero.png", - "softwareVersion": "1.3.0", + "softwareVersion": "1.4.0", "license": "https://github.com/hyhmrright/brooks-lint/blob/main/LICENSE", "codeRepository": "https://github.com/hyhmrright/brooks-lint", "keywords": "AI code review, code quality, tech debt, architecture audit, test quality, Claude Code plugin, refactoring, clean architecture", @@ -219,15 +219,19 @@

+

Linters catch syntax. brooks-lint catches architectural drift, knowledge silos, and domain distortion — the slow problems that cost teams months.

⚖️ -

The Iron Law

-

The Iron Law

+

Every finding follows one shape: Symptom → Source → Consequence → Remedy. No vague vibes, ever.

📚 -

Cited to the books

-

Cited to the books

+

Brooks, Fowler, Martin, Ousterhout, Evans, Feathers, Meszaros and more — each finding names the author and principle.

🎯 -

Six focused skills

-

Six focused skills +

PR Review, Architecture Audit, Tech Debt, Test Quality, Health Dashboard, and a Full Sweep that auto-fixes.

🔌 -

Zero config, any language

-

Zero config, any language +

Works in Claude Code, Codex CLI, and Gemini CLI. No plugins to wire up, no language limits.

@@ -312,45 +328,45 @@
-

The Six Production Decay Risks

-

The Six Production Decay Risks +

Synthesized from the twelve books. Six more (T1–T6) cover test-suite decay.

R1 -

🧠 Cognitive Overload

-

How much mental effort does it take to understand this?

+

🧠 Cognitive Overload

+

How much mental effort does it take to understand this?

Code Complete · Refactoring · DDD · Philosophy of SD
R2 -

🔗 Change Propagation

-

How many unrelated things break on one change?

+

🔗 Change Propagation

+

How many unrelated things break on one change?

Refactoring · Clean Architecture · Pragmatic · SE@Google
R3 -

📋 Knowledge Duplication

-

Is the same decision expressed in multiple places?

+

📋 Knowledge Duplication

+

Is the same decision expressed in multiple places?

Pragmatic · Refactoring · DDD
R4 -

🌀 Accidental Complexity

-

Is the code more complex than the problem itself?

+

🌀 Accidental Complexity

+

Is the code more complex than the problem itself?

Refactoring · Code Complete · Brooks · Philosophy of SD
R5 -

🏗️ Dependency Disorder

-

Do dependencies flow in a consistent direction?

+

🏗️ Dependency Disorder

+

Do dependencies flow in a consistent direction?

Clean Architecture · Brooks · Pragmatic · SE@Google
R6 -

🗺️ Domain Model Distortion

-

Does the code faithfully represent the domain?

+

🗺️ Domain Model Distortion

+

Does the code faithfully represent the domain?

DDD · Refactoring
@@ -361,47 +377,47 @@
-

What a finding looks like

-

What a finding looks like +

Same messy method, two of the eight findings brooks-lint produces — each one cited and actionable.

-
Health Score: 28/100
+
Health Score: 28/100
This method concentrates four unrelated business responsibilities, hides a logic bug that silently suppresses email notifications, and is wide open to SQL injection.
-

🔴 R2 — One method changes for four unrelated reasons

-
Symptom: - 🔴 R2 — One method changes for four unrelated reasons +
Symptom: + update_profile does field updates, email notifications, loyalty recalculation, and cache invalidation in one body.
-
Source: - Source: + Fowler — Refactoring — Divergent Change; Hunt & Thomas — Orthogonality
-
Consequence: - Consequence: + A change to the loyalty formula risks breaking email notifications. Every edit carries regression risk across four domains.
-
Remedy: - Remedy: + Extract NotificationService, LoyaltyService, UserCacheInvalidator. update_profile should orchestrate, not implement.
-

🔴 R6 — Silent logic bug: notification never fires

-
Symptom: - 🔴 R6 — Silent logic bug: notification never fires +
Symptom: + user['email'] = email runs before if user['email'] != email — the condition is always False, the code is dead.
-
Source: - Source: + McConnell — Code Complete — Ch. 17: Unusual Control Structures
-
Consequence: - Consequence: + Users are never notified when their email changes. A business rule is silently violated while the system looks fine.
-
Remedy: - Remedy: + Capture old_email before any mutation. Compare against old_email, not the already-overwritten value.
@@ -412,25 +428,25 @@
-

Consistency is the point

-

Consistency is the point +

Tested across PR review, architecture audit, and tech debt scenarios. The gap isn't what Claude can find — it's what it finds every single time, with evidence.

- + - + - - - - - + + + + +
CriterionCriterion brooks-lintClaude aloneClaude alone
Structured Symptom→Source→Consequence→Remedy100%0%
Book citation per finding100%0%
Consistent severity labels 🔴🟡🟢100%0%
Health Score (0–100)100%0%
Overall pass rate94%16%
Structured Symptom→Source→Consequence→Remedy100%0%
Book citation per finding100%0%
Consistent severity labels 🔴🟡🟢100%0%
Health Score (0–100)100%0%
Overall pass rate94%16%
@@ -441,8 +457,8 @@
-

Standing on twelve giants

-

Standing on twelve giants +

The decay risks are our synthesis of their ideas, applied to modern code quality.

@@ -466,8 +482,8 @@
-

Get started in seconds

-

Get started in seconds +

Pick your tool. Then just ask it to review your code, audit your architecture, or assess tech debt.

@@ -487,12 +503,12 @@ # just say this in a Codex session Install the brooks-lint skill from hyhmrright/brooks-lint
-
Then, in any session:
+
Then, in any session:
/brooks-review # or /brooks-audit · /brooks-debt · /brooks-test · /brooks-health · /brooks-sweep
@@ -503,24 +519,29 @@ Install the brooks-lint skill from hyhmrright/brooks-lint
-
MIT License — Built by hyhmrright
+
MIT License — Built by hyhmrright