diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json new file mode 100644 index 0000000..232f1c9 --- /dev/null +++ b/.claude-plugin/marketplace.json @@ -0,0 +1,74 @@ +{ + "name": "rootiest-skills", + "owner": { + "name": "Rootiest", + "url": "https://git.rootiest.dev/rootiest/ai-skills" + }, + "description": "Reusable AI skills for Claude Code and Antigravity CLI", + "plugins": [ + { + "name": "date-time", + "description": "Retrieves the exact current date and time for time-sensitive queries, scheduling, duration calculations, and validating chronological context.", + "source": "./", + "skills": [ + "./skills/date-time" + ] + }, + { + "name": "docs-sync-audit", + "description": "Analyzes repository delta since the last documentation update and synchronizes the Single Source of Truth (docs/, wiki, or README) with the current codebase state.", + "source": "./", + "skills": [ + "./skills/docs-sync-audit" + ] + }, + { + "name": "git-publish-workflow", + "description": "Automates branching, conventional commits, testing, and PR creation for uncommitted or staged work. Handles both independent and stacked PRs.", + "source": "./", + "skills": [ + "./skills/git-publish-workflow" + ] + }, + { + "name": "readme-sync-audit", + "description": "Analyzes repository delta since the last documentation update and synchronizes the README.md with the current codebase state.", + "source": "./", + "skills": [ + "./skills/readme-sync-audit" + ] + }, + { + "name": "ship-it", + "description": "Runs a comprehensive pre-flight audit, syncs the README, and publishes the changes to a new PR.", + "source": "./", + "skills": [ + "./skills/ship-it" + ] + }, + { + "name": "systematic-enumeration", + "description": "Forces element-by-element verification for finite sets to prevent counting errors.", + "source": "./", + "skills": [ + "./skills/systematic-enumeration" + ] + }, + { + "name": "technical-devlog-scribe", + "description": "Generates a highly structured, objective technical summary of a development session.", + "source": "./", + "skills": [ + "./skills/technical-devlog-scribe" + ] + }, + { + "name": "rootiest-skills-all", + "description": "Reusable AI skills for Claude Code and Antigravity CLI (all skills)", + "source": "./", + "skills": [ + "./skills/" + ] + } + ] +} diff --git a/.gitea/workflows/plugins.yml b/.gitea/workflows/plugins.yml new file mode 100644 index 0000000..c8704b3 --- /dev/null +++ b/.gitea/workflows/plugins.yml @@ -0,0 +1,48 @@ +name: Generate plugin manifests + +on: + pull_request: + paths: + - "skills/**" + - "manifest.yaml" + - "scripts/**" + push: + branches: [main] + paths: + - "skills/**" + - "manifest.yaml" + - "scripts/**" + +jobs: + validate: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.x" + - run: pip install -r scripts/requirements.txt + - run: python3 scripts/generate_plugins.py --check + + generate: + if: github.event_name == 'push' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.x" + - run: pip install -r scripts/requirements.txt + - run: python3 scripts/generate_plugins.py + - name: Commit generated output + run: | + git config user.name "gitea-actions" + git config user.email "actions@git.rootiest.dev" + git add .claude-plugin descriptions.json dist + if git diff --cached --quiet; then + echo "No generated output changes." + exit 0 + fi + git commit -m "chore(plugins): regenerate plugin manifests" + git push origin HEAD:main diff --git a/.gitignore b/.gitignore index 65fa723..060ccfd 100644 --- a/.gitignore +++ b/.gitignore @@ -82,6 +82,10 @@ Thumbs.db [Cc][Ll][Aa][Uu][Dd][Ee].[Mm][Dd] .[Cc][Ll][Aa][Uu][Dd]* +# Claude Code plugin marketplace manifest (generated, must stay tracked) +!.claude-plugin/ +!.claude-plugin/** + # Matches GEMINI.md, .gemin*, etc. [Gg][Ee][Mm][Ii][Nn][Ii].[Mm][Dd] .[Gg][Ee][Mm][Ii][Nn]* diff --git a/README.md b/README.md index 63657e8..4c8ed57 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,13 @@ Skills are plain Markdown files. The included `install.sh` script handles discov - [technical-devlog-scribe](#technical-devlog-scribe) - [ship-it](#ship-it) - [Installation](#installation) + - [Claude Code Plugin Marketplace](#claude-code-plugin-marketplace) - [Quick Install (curl)](#quick-install-curl) - [Flags & Options](#flags--options) - [Environment Variables](#environment-variables) - [Examples](#examples) - [Manual Install](#manual-install) +- [Repository Structure](#repository-structure) - [License](#license) --- @@ -121,6 +123,26 @@ Two sequential phases — Phase 2 is blocked until Phase 1 succeeds: ## Installation +### Claude Code Plugin Marketplace + +This repository is a Claude Code plugin marketplace. Each skill is installable +individually, or install everything as one bundle. This is the preferred +install path for Claude Code — `install.sh` remains available as a +cross-tool fallback (and is the only supported path for Antigravity CLI today). + +``` +/plugin marketplace add https://git.rootiest.dev/rootiest/ai-skills.git +/plugin install git-publish-workflow@rootiest-skills +``` + +Install every skill at once with the `rootiest-skills-all` bundle: + +``` +/plugin install rootiest-skills-all@rootiest-skills +``` + +Run `/plugin marketplace update` to pick up newly published skills. + ### Quick Install (curl) The intended usage is a single `curl | bash` command. The installer fetches and runs `install.sh` directly — no clone required. @@ -248,6 +270,29 @@ bash install.sh --all --- +## Repository Structure + +Skill content lives entirely in `skills//SKILL.md` — that's the single +source of truth for a skill's metadata (YAML frontmatter: `name`, +`description`, `version`, `author`, `user-invocable`) and instructions. +`manifest.yaml` holds only marketplace-level metadata (owner, marketplace +name, which agent targets to generate for) — it does not list skills +individually; adding a new `skills//` folder is picked up automatically. + +CI (`.gitea/workflows/plugins.yml`) runs `scripts/generate_plugins.py` on +every push to `main` that touches `skills/`, `manifest.yaml`, or the +generator itself, and commits the regenerated output: + +| Path | Generated for | +|---|---| +| `.claude-plugin/marketplace.json` | Claude Code plugin marketplace | +| `dist/agy/**` | Antigravity CLI (`agy`) plugins | +| `descriptions.json` | `install.sh` skill listing | + +Don't hand-edit any of the paths above — edit the source skill or +`manifest.yaml` and let CI regenerate them. Pull requests run the same +generator in `--check` mode to catch missing/invalid frontmatter before merge. + ## License This project is licensed under the **GNU General Public License v3.0 or later (GPL-3.0-or-later)**. diff --git a/descriptions.json b/descriptions.json index c82ea15..7ca08d7 100644 --- a/descriptions.json +++ b/descriptions.json @@ -1,9 +1,9 @@ { - "date-time": "Get the current date and time when it is relevant to the task at hand, and use it to make informed decisions.", - "docs-sync-audit": "Keep documentation accurate by programmatically aligning it with the current state of the codebase.", - "git-publish-workflow": "Automate the full lifecycle from uncommitted local work to an open Pull Request, with built-in quality gates.", - "readme-sync-audit": "Keep README.md accurate by programmatically aligning it with the current state of the codebase.", - "ship-it": "Run a comprehensive pre-flight audit and publish changes to a new PR in a single command.", - "systematic-enumeration": "Eliminate counting and membership errors via explicit set enumeration and atomic element testing.", + "date-time": "Retrieves the exact current date and time for time-sensitive queries, scheduling, duration calculations, and validating chronological context.", + "docs-sync-audit": "Analyzes repository delta since the last documentation update and synchronizes the Single Source of Truth (docs/, wiki, or README) with the current codebase state.", + "git-publish-workflow": "Automates branching, conventional commits, testing, and PR creation for uncommitted or staged work. Handles both independent and stacked PRs.", + "readme-sync-audit": "Analyzes repository delta since the last documentation update and synchronizes the README.md with the current codebase state.", + "ship-it": "Runs a comprehensive pre-flight audit, syncs the README, and publishes the changes to a new PR.", + "systematic-enumeration": "Forces element-by-element verification for finite sets to prevent counting errors.", "technical-devlog-scribe": "Generates a highly structured, objective technical summary of a development session." } diff --git a/dist/README.md b/dist/README.md new file mode 100644 index 0000000..8a1b5da --- /dev/null +++ b/dist/README.md @@ -0,0 +1,3 @@ +# Generated + +This directory is generated by `scripts/generate_plugins.py` from `manifest.yaml` and `skills/`. Do not edit files here directly — edit the source skill instead and regenerate. diff --git a/dist/agy/date-time/plugin.json b/dist/agy/date-time/plugin.json new file mode 100644 index 0000000..a722ce7 --- /dev/null +++ b/dist/agy/date-time/plugin.json @@ -0,0 +1,4 @@ +{ + "name": "date-time", + "description": "Retrieves the exact current date and time for time-sensitive queries, scheduling, duration calculations, and validating chronological context." +} diff --git a/dist/agy/date-time/skills/date-time/SKILL.md b/dist/agy/date-time/skills/date-time/SKILL.md new file mode 100644 index 0000000..a3ac53e --- /dev/null +++ b/dist/agy/date-time/skills/date-time/SKILL.md @@ -0,0 +1,43 @@ +--- +name: date-time +description: Retrieves the exact current date and time for time-sensitive queries, scheduling, duration calculations, and validating chronological context. +version: 1.0.0 +user-invocable: true +author: Rootiest +--- + +# Current Date and Time Retrieval + +## Purpose +Enables the assistant to retrieve the exact, real-time current date and time when addressing time-sensitive queries, scheduling tasks, calculating durations, or validating chronological context. + +## Trigger Conditions +Activate this skill whenever the user's prompt: +* Explicitly asks for the current date, day, time, or year. +* References relative time expressions (e.g., "today", "yesterday", "next week", "recently"). +* Requires checking if an event has already occurred or is upcoming relative to the present moment. +* Needs to calculate an age, duration, or countdown from the present day. + +## Tool Definition + +### `get_current_datetime` +* **Description**: Executes the system `date` command to fetch the current local timestamp, timezone, and calendar date. +* **Parameters**: None required. + +## Execution Workflow +1. **Detect**: Recognize a time-sensitive trigger in the user's input. +2. **Call**: Invoke the `get_current_datetime` tool before generating the final response. +3. **Process**: Use the returned timestamp to anchor your temporal reasoning. +4. **Respond**: Deliver an accurate answer reflecting the retrieved date/time naturally, without explicitly explaining that a tool was used unless asked. + +## Examples + +### Example 1 +* **User**: "What day of the week is it today?" +* **Assistant Action**: Invoke `get_current_datetime`. +* **Response**: "Today is [Day of Week], [Date]." + +### Example 2 +* **User**: "Is the 2026 World Cup happening this month?" +* **Assistant Action**: Invoke `get_current_datetime`. +* **Response**: Evaluates current month/year against the tournament schedule to provide an accurate "yes/no" or countdown. diff --git a/dist/agy/docs-sync-audit/plugin.json b/dist/agy/docs-sync-audit/plugin.json new file mode 100644 index 0000000..7eaa449 --- /dev/null +++ b/dist/agy/docs-sync-audit/plugin.json @@ -0,0 +1,4 @@ +{ + "name": "docs-sync-audit", + "description": "Analyzes repository delta since the last documentation update and synchronizes the Single Source of Truth (docs/, wiki, or README) with the current codebase state." +} diff --git a/dist/agy/docs-sync-audit/skills/docs-sync-audit/SKILL.md b/dist/agy/docs-sync-audit/skills/docs-sync-audit/SKILL.md new file mode 100644 index 0000000..c7966a6 --- /dev/null +++ b/dist/agy/docs-sync-audit/skills/docs-sync-audit/SKILL.md @@ -0,0 +1,48 @@ +--- +name: docs-sync-audit +description: Analyzes repository delta since the last documentation update and synchronizes the Single Source of Truth (docs/, wiki, or README) with the current codebase state. +version: 1.3.0 +user-invocable: true +author: Rootiest +--- + +# Documentation Synchronization & Audit Skill + +## **Objective** +To ensure project documentation accurately reflects the current state of the codebase by identifying the "Single Source of Truth" (SSoT) (e.g., a `docs/` directory or wiki) and prioritizing updates there. The `README.md` is updated concurrently only for high-level changes or if it serves as the SSoT. + +## **Execution Protocol** + +### **Phase 0: SSoT Discovery** +1. **Locate Documentation Root**: Scan the repository structure for dedicated documentation directories (e.g., `docs/`, `wiki/`, `website/docs/`) or configuration files (e.g., `mkdocs.yml`, `docusaurus.config.js`). +2. **Establish SSoT**: If a dedicated documentation structure exists, designate it as the SSoT. If absent, fall back to `README.md` as the primary SSoT. + +### **Phase 1: Delta Analysis** +1. **Time-Travel Check**: Locate the last commit where the SSoT files were modified. +2. **Feature Diff**: Analyze all code changes (files added, functions modified, dependencies updated) from that commit to the present `HEAD`. +3. **Extraction**: Identify new environment variables, CLI flags, installation steps, or logic changes that are not yet documented. + +### **Phase 2: The Pruning & Update Audit** +Perform a targeted comparison of the SSoT against the current code: +* **Route Updates**: Direct detailed API, configuration, and architectural updates to their respective files within the SSoT (`docs/` or wiki). +* **Prune**: Remove any setup steps, dependencies, or "Coming Soon" features from the SSoT that no longer exist or have been replaced. +* **Correct**: Update version numbers, file paths, and command-line examples to match the current implementation. +* **Synthesize**: Add concise documentation for new features identified in Phase 1. +* **README Alignment**: If `docs/` is the SSoT, update the `README.md` *only* to reflect critical, high-level changes (e.g., Quick Start, Installation) or to ensure it properly links to the newly updated sections in the SSoT. + +### **Phase 3: Structural Integrity Check** +Ensure the updated SSoT (and README, if applicable) includes or updates these critical sections: +1. **Quick Start**: Are the commands (e.g., `cargo run`, `npm start`) still the primary entry points? +2. **Configuration**: Are all current `.env` or config keys listed? +3. **Usage Examples**: Do the provided code snippets actually compile/run with the current API? + +## **Constraints & Rules** +* **Hierarchy Enforcement**: Never duplicate deep technical documentation in the README if a `docs/` folder exists. Use the README as a high-level landing page that points to the SSoT. +* **Minimalism**: Maintain the existing tone of the documentation. Do not add "fluff" or marketing language unless the original document uses it. +* **No Hallucinations**: If a feature's purpose is unclear from the code diff, add a `TODO` comment or ask the user for clarification rather than guessing. +* **Markdown Standards**: Use standard GFM (GitHub Flavored Markdown) or MDX if applicable to the SSoT. Ensure all code blocks have the correct language identifier for syntax highlighting. + +## **Trigger Scenarios** +* **Direct Command:** The user invokes `/docs-sync-audit`, `/readme-sync-audit`, or `/update-docs`. +* **Natural Language:** User says "Update the docs", "Sync the wiki", or "Sync the README with my recent changes." +* **Contextual Suggestion:** Trigger automatically if the model detects significant changes to public APIs, CLI arguments, or environment variables without a corresponding documentation update. diff --git a/dist/agy/git-publish-workflow/plugin.json b/dist/agy/git-publish-workflow/plugin.json new file mode 100644 index 0000000..08e2583 --- /dev/null +++ b/dist/agy/git-publish-workflow/plugin.json @@ -0,0 +1,4 @@ +{ + "name": "git-publish-workflow", + "description": "Automates branching, conventional commits, testing, and PR creation for uncommitted or staged work. Handles both independent and stacked PRs." +} diff --git a/dist/agy/git-publish-workflow/skills/git-publish-workflow/SKILL.md b/dist/agy/git-publish-workflow/skills/git-publish-workflow/SKILL.md new file mode 100644 index 0000000..3f78156 --- /dev/null +++ b/dist/agy/git-publish-workflow/skills/git-publish-workflow/SKILL.md @@ -0,0 +1,49 @@ +--- +name: git-publish-workflow +description: Automates branching, conventional commits, testing, and PR creation for uncommitted or staged work. Handles both independent and stacked PRs. +version: 1.2.0 +user-invocable: true +author: Rootiest +--- + +# Git Publish & PR Workflow + +## **Objective** +To provide a hands-off, end-to-end automation for moving local changes into a formal Pull Request, ensuring code quality through automated and manual verification steps, while intelligently routing Stacked PRs. + +## **Execution Protocol** + +### **Phase 1: Scope & Base Determination** +Before execution, check the local git state: +1. **Scope Check**: Determine the work boundary: + * **Case A (Partial):** If staged changes exist, operate **ONLY** on staged changes. + * **Case B (Full):** If no changes are staged, operate on **ALL** modified/untracked files. +2. **Base Branch Detection**: Identify the currently checked-out branch. + * **Independent PR**: If the current branch is `main` (or `master`), the new branch will be based on `main`. The PR target will be `main`. + * **Stacked PR**: If the current branch is a feature branch (e.g., `feat-a`), assume the new changes are dependent. The new branch will be created from the current branch. The PR target will be the current feature branch (NOT `main`). + * *Safety Check*: If creating a Stacked PR, output a brief terminal message stating: "Detected active feature branch. Stacking new PR on top of `[current-branch-name]`." + +### **Phase 2: The "Safe-Commit" Sequence** +1. **Branching**: Generate a `kebab-case` branch name (e.g., `feat-auth-logic` or `fix-header-css`) based off the branch determined in Phase 1. +2. **Naming**: Use **Conventional Commits** for the message (e.g., `feat(ui): add logout button`). +3. **Verification**: + * Identify the project type (e.g., Rust/Cargo, Python/Poetry, Node/NPM). + * Run the primary `test`, `lint`, or `build` command. + * **Abort Policy**: If verification fails, stop the sequence and report the error. Do not push. + +### **Phase 3: Remote Integration** +1. **Push**: Upload the new branch to `origin`. +2. **PR Creation**: Open a Pull Request targeting the base branch determined in Phase 1 (either `main` or the parent feature branch). +3. **Documentation**: Populate the PR description with: + * **Summary**: A high-level overview of "Why" and "What." + * **Manual Verification Checklist**: Provide a Markdown list (`- [ ]`) of 3-5 tactical steps for a human to verify the change in a live environment. + +## **Constraints & Rules** +* **Atomic Commits**: If multiple distinct features are found in the scope, suggest splitting the work instead of one giant commit. +* **No Force Push**: Never use `--force` unless explicitly requested in the follow-up prompt. +* **Clean State**: Ensure the workflow ends with the user on the new branch, not the original branch. + +## **Trigger Scenarios** +* User says: "Ship this." +* User says: "Make a PR for my current changes." +* Invoked via `/git-publish-workflow`. diff --git a/dist/agy/readme-sync-audit/plugin.json b/dist/agy/readme-sync-audit/plugin.json new file mode 100644 index 0000000..e6e517e --- /dev/null +++ b/dist/agy/readme-sync-audit/plugin.json @@ -0,0 +1,4 @@ +{ + "name": "readme-sync-audit", + "description": "Analyzes repository delta since the last documentation update and synchronizes the README.md with the current codebase state." +} diff --git a/dist/agy/readme-sync-audit/skills/readme-sync-audit/SKILL.md b/dist/agy/readme-sync-audit/skills/readme-sync-audit/SKILL.md new file mode 100644 index 0000000..b7f7bc0 --- /dev/null +++ b/dist/agy/readme-sync-audit/skills/readme-sync-audit/SKILL.md @@ -0,0 +1,41 @@ +--- +name: readme-sync-audit +description: Analyzes repository delta since the last documentation update and synchronizes the README.md with the current codebase state. +version: 1.2.0 +user-invocable: true +author: Rootiest +--- + +# README Synchronization & Audit Skill + +## **Objective** +To ensure the `README.md` serves as a "Single Source of Truth" by programmatically aligning documentation with the actual state of the codebase. This skill prioritizes accuracy and the removal of obsolete instructions. + +## **Execution Protocol** + +### **Phase 1: Delta Analysis** +1. **Time-Travel Check**: Locate the last commit where `README.md` was modified. +2. **Feature Diff**: Analyze all code changes (files added, functions modified, dependencies updated) from that commit to the present `HEAD`. +3. **Extraction**: Identify new environment variables, CLI flags, installation steps, or logic changes that are not yet documented. + +### **Phase 2: The Pruning & Update Audit** +Perform a line-by-line comparison of the existing README against the current code: +* **Prune**: Remove any setup steps, dependencies, or "Coming Soon" features that no longer exist or have been replaced. +* **Correct**: Update version numbers, file paths, and command-line examples to match the current implementation. +* **Synthesize**: Add concise documentation for new features identified in Phase 1. + +### **Phase 3: Structural Integrity Check** +Ensure the updated README includes (or updates) these critical sections: +1. **Quick Start**: Are the commands (e.g., `cargo run`, `npm start`) still the primary entry points? +2. **Configuration**: Are all current `.env` or config keys listed? +3. **Usage Examples**: Do the provided code snippets actually compile/run with the current API? + +## **Constraints & Rules** +* **Minimalism**: Maintain the existing tone of the README. Do not add "fluff" or marketing language unless the original document uses it. +* **No Hallucinations**: If a feature's purpose is unclear from the code diff, add a `TODO` comment or ask the user for clarification rather than guessing. +* **Markdown Standards**: Use standard GFM (GitHub Flavored Markdown). Ensure all code blocks have the correct language identifier for syntax highlighting. + +## **Trigger Scenarios** +* **Direct Command:** The user invokes `/readme-sync-audit` or `/update-docs`. +* **Natural Language:** User says "Update the docs" or "Sync the README with my recent changes." +* **Contextual Suggestion:** Trigger automatically if the model detects significant changes to public APIs, CLI arguments, or environment variables without a corresponding documentation update. diff --git a/dist/agy/rootiest-skills-all/plugin.json b/dist/agy/rootiest-skills-all/plugin.json new file mode 100644 index 0000000..62fd4ab --- /dev/null +++ b/dist/agy/rootiest-skills-all/plugin.json @@ -0,0 +1,4 @@ +{ + "name": "rootiest-skills-all", + "description": "Reusable AI skills for Claude Code and Antigravity CLI (all skills)" +} diff --git a/dist/agy/rootiest-skills-all/skills/date-time/SKILL.md b/dist/agy/rootiest-skills-all/skills/date-time/SKILL.md new file mode 100644 index 0000000..a3ac53e --- /dev/null +++ b/dist/agy/rootiest-skills-all/skills/date-time/SKILL.md @@ -0,0 +1,43 @@ +--- +name: date-time +description: Retrieves the exact current date and time for time-sensitive queries, scheduling, duration calculations, and validating chronological context. +version: 1.0.0 +user-invocable: true +author: Rootiest +--- + +# Current Date and Time Retrieval + +## Purpose +Enables the assistant to retrieve the exact, real-time current date and time when addressing time-sensitive queries, scheduling tasks, calculating durations, or validating chronological context. + +## Trigger Conditions +Activate this skill whenever the user's prompt: +* Explicitly asks for the current date, day, time, or year. +* References relative time expressions (e.g., "today", "yesterday", "next week", "recently"). +* Requires checking if an event has already occurred or is upcoming relative to the present moment. +* Needs to calculate an age, duration, or countdown from the present day. + +## Tool Definition + +### `get_current_datetime` +* **Description**: Executes the system `date` command to fetch the current local timestamp, timezone, and calendar date. +* **Parameters**: None required. + +## Execution Workflow +1. **Detect**: Recognize a time-sensitive trigger in the user's input. +2. **Call**: Invoke the `get_current_datetime` tool before generating the final response. +3. **Process**: Use the returned timestamp to anchor your temporal reasoning. +4. **Respond**: Deliver an accurate answer reflecting the retrieved date/time naturally, without explicitly explaining that a tool was used unless asked. + +## Examples + +### Example 1 +* **User**: "What day of the week is it today?" +* **Assistant Action**: Invoke `get_current_datetime`. +* **Response**: "Today is [Day of Week], [Date]." + +### Example 2 +* **User**: "Is the 2026 World Cup happening this month?" +* **Assistant Action**: Invoke `get_current_datetime`. +* **Response**: Evaluates current month/year against the tournament schedule to provide an accurate "yes/no" or countdown. diff --git a/dist/agy/rootiest-skills-all/skills/docs-sync-audit/SKILL.md b/dist/agy/rootiest-skills-all/skills/docs-sync-audit/SKILL.md new file mode 100644 index 0000000..c7966a6 --- /dev/null +++ b/dist/agy/rootiest-skills-all/skills/docs-sync-audit/SKILL.md @@ -0,0 +1,48 @@ +--- +name: docs-sync-audit +description: Analyzes repository delta since the last documentation update and synchronizes the Single Source of Truth (docs/, wiki, or README) with the current codebase state. +version: 1.3.0 +user-invocable: true +author: Rootiest +--- + +# Documentation Synchronization & Audit Skill + +## **Objective** +To ensure project documentation accurately reflects the current state of the codebase by identifying the "Single Source of Truth" (SSoT) (e.g., a `docs/` directory or wiki) and prioritizing updates there. The `README.md` is updated concurrently only for high-level changes or if it serves as the SSoT. + +## **Execution Protocol** + +### **Phase 0: SSoT Discovery** +1. **Locate Documentation Root**: Scan the repository structure for dedicated documentation directories (e.g., `docs/`, `wiki/`, `website/docs/`) or configuration files (e.g., `mkdocs.yml`, `docusaurus.config.js`). +2. **Establish SSoT**: If a dedicated documentation structure exists, designate it as the SSoT. If absent, fall back to `README.md` as the primary SSoT. + +### **Phase 1: Delta Analysis** +1. **Time-Travel Check**: Locate the last commit where the SSoT files were modified. +2. **Feature Diff**: Analyze all code changes (files added, functions modified, dependencies updated) from that commit to the present `HEAD`. +3. **Extraction**: Identify new environment variables, CLI flags, installation steps, or logic changes that are not yet documented. + +### **Phase 2: The Pruning & Update Audit** +Perform a targeted comparison of the SSoT against the current code: +* **Route Updates**: Direct detailed API, configuration, and architectural updates to their respective files within the SSoT (`docs/` or wiki). +* **Prune**: Remove any setup steps, dependencies, or "Coming Soon" features from the SSoT that no longer exist or have been replaced. +* **Correct**: Update version numbers, file paths, and command-line examples to match the current implementation. +* **Synthesize**: Add concise documentation for new features identified in Phase 1. +* **README Alignment**: If `docs/` is the SSoT, update the `README.md` *only* to reflect critical, high-level changes (e.g., Quick Start, Installation) or to ensure it properly links to the newly updated sections in the SSoT. + +### **Phase 3: Structural Integrity Check** +Ensure the updated SSoT (and README, if applicable) includes or updates these critical sections: +1. **Quick Start**: Are the commands (e.g., `cargo run`, `npm start`) still the primary entry points? +2. **Configuration**: Are all current `.env` or config keys listed? +3. **Usage Examples**: Do the provided code snippets actually compile/run with the current API? + +## **Constraints & Rules** +* **Hierarchy Enforcement**: Never duplicate deep technical documentation in the README if a `docs/` folder exists. Use the README as a high-level landing page that points to the SSoT. +* **Minimalism**: Maintain the existing tone of the documentation. Do not add "fluff" or marketing language unless the original document uses it. +* **No Hallucinations**: If a feature's purpose is unclear from the code diff, add a `TODO` comment or ask the user for clarification rather than guessing. +* **Markdown Standards**: Use standard GFM (GitHub Flavored Markdown) or MDX if applicable to the SSoT. Ensure all code blocks have the correct language identifier for syntax highlighting. + +## **Trigger Scenarios** +* **Direct Command:** The user invokes `/docs-sync-audit`, `/readme-sync-audit`, or `/update-docs`. +* **Natural Language:** User says "Update the docs", "Sync the wiki", or "Sync the README with my recent changes." +* **Contextual Suggestion:** Trigger automatically if the model detects significant changes to public APIs, CLI arguments, or environment variables without a corresponding documentation update. diff --git a/dist/agy/rootiest-skills-all/skills/git-publish-workflow/SKILL.md b/dist/agy/rootiest-skills-all/skills/git-publish-workflow/SKILL.md new file mode 100644 index 0000000..3f78156 --- /dev/null +++ b/dist/agy/rootiest-skills-all/skills/git-publish-workflow/SKILL.md @@ -0,0 +1,49 @@ +--- +name: git-publish-workflow +description: Automates branching, conventional commits, testing, and PR creation for uncommitted or staged work. Handles both independent and stacked PRs. +version: 1.2.0 +user-invocable: true +author: Rootiest +--- + +# Git Publish & PR Workflow + +## **Objective** +To provide a hands-off, end-to-end automation for moving local changes into a formal Pull Request, ensuring code quality through automated and manual verification steps, while intelligently routing Stacked PRs. + +## **Execution Protocol** + +### **Phase 1: Scope & Base Determination** +Before execution, check the local git state: +1. **Scope Check**: Determine the work boundary: + * **Case A (Partial):** If staged changes exist, operate **ONLY** on staged changes. + * **Case B (Full):** If no changes are staged, operate on **ALL** modified/untracked files. +2. **Base Branch Detection**: Identify the currently checked-out branch. + * **Independent PR**: If the current branch is `main` (or `master`), the new branch will be based on `main`. The PR target will be `main`. + * **Stacked PR**: If the current branch is a feature branch (e.g., `feat-a`), assume the new changes are dependent. The new branch will be created from the current branch. The PR target will be the current feature branch (NOT `main`). + * *Safety Check*: If creating a Stacked PR, output a brief terminal message stating: "Detected active feature branch. Stacking new PR on top of `[current-branch-name]`." + +### **Phase 2: The "Safe-Commit" Sequence** +1. **Branching**: Generate a `kebab-case` branch name (e.g., `feat-auth-logic` or `fix-header-css`) based off the branch determined in Phase 1. +2. **Naming**: Use **Conventional Commits** for the message (e.g., `feat(ui): add logout button`). +3. **Verification**: + * Identify the project type (e.g., Rust/Cargo, Python/Poetry, Node/NPM). + * Run the primary `test`, `lint`, or `build` command. + * **Abort Policy**: If verification fails, stop the sequence and report the error. Do not push. + +### **Phase 3: Remote Integration** +1. **Push**: Upload the new branch to `origin`. +2. **PR Creation**: Open a Pull Request targeting the base branch determined in Phase 1 (either `main` or the parent feature branch). +3. **Documentation**: Populate the PR description with: + * **Summary**: A high-level overview of "Why" and "What." + * **Manual Verification Checklist**: Provide a Markdown list (`- [ ]`) of 3-5 tactical steps for a human to verify the change in a live environment. + +## **Constraints & Rules** +* **Atomic Commits**: If multiple distinct features are found in the scope, suggest splitting the work instead of one giant commit. +* **No Force Push**: Never use `--force` unless explicitly requested in the follow-up prompt. +* **Clean State**: Ensure the workflow ends with the user on the new branch, not the original branch. + +## **Trigger Scenarios** +* User says: "Ship this." +* User says: "Make a PR for my current changes." +* Invoked via `/git-publish-workflow`. diff --git a/dist/agy/rootiest-skills-all/skills/readme-sync-audit/SKILL.md b/dist/agy/rootiest-skills-all/skills/readme-sync-audit/SKILL.md new file mode 100644 index 0000000..b7f7bc0 --- /dev/null +++ b/dist/agy/rootiest-skills-all/skills/readme-sync-audit/SKILL.md @@ -0,0 +1,41 @@ +--- +name: readme-sync-audit +description: Analyzes repository delta since the last documentation update and synchronizes the README.md with the current codebase state. +version: 1.2.0 +user-invocable: true +author: Rootiest +--- + +# README Synchronization & Audit Skill + +## **Objective** +To ensure the `README.md` serves as a "Single Source of Truth" by programmatically aligning documentation with the actual state of the codebase. This skill prioritizes accuracy and the removal of obsolete instructions. + +## **Execution Protocol** + +### **Phase 1: Delta Analysis** +1. **Time-Travel Check**: Locate the last commit where `README.md` was modified. +2. **Feature Diff**: Analyze all code changes (files added, functions modified, dependencies updated) from that commit to the present `HEAD`. +3. **Extraction**: Identify new environment variables, CLI flags, installation steps, or logic changes that are not yet documented. + +### **Phase 2: The Pruning & Update Audit** +Perform a line-by-line comparison of the existing README against the current code: +* **Prune**: Remove any setup steps, dependencies, or "Coming Soon" features that no longer exist or have been replaced. +* **Correct**: Update version numbers, file paths, and command-line examples to match the current implementation. +* **Synthesize**: Add concise documentation for new features identified in Phase 1. + +### **Phase 3: Structural Integrity Check** +Ensure the updated README includes (or updates) these critical sections: +1. **Quick Start**: Are the commands (e.g., `cargo run`, `npm start`) still the primary entry points? +2. **Configuration**: Are all current `.env` or config keys listed? +3. **Usage Examples**: Do the provided code snippets actually compile/run with the current API? + +## **Constraints & Rules** +* **Minimalism**: Maintain the existing tone of the README. Do not add "fluff" or marketing language unless the original document uses it. +* **No Hallucinations**: If a feature's purpose is unclear from the code diff, add a `TODO` comment or ask the user for clarification rather than guessing. +* **Markdown Standards**: Use standard GFM (GitHub Flavored Markdown). Ensure all code blocks have the correct language identifier for syntax highlighting. + +## **Trigger Scenarios** +* **Direct Command:** The user invokes `/readme-sync-audit` or `/update-docs`. +* **Natural Language:** User says "Update the docs" or "Sync the README with my recent changes." +* **Contextual Suggestion:** Trigger automatically if the model detects significant changes to public APIs, CLI arguments, or environment variables without a corresponding documentation update. diff --git a/dist/agy/rootiest-skills-all/skills/ship-it/SKILL.md b/dist/agy/rootiest-skills-all/skills/ship-it/SKILL.md new file mode 100644 index 0000000..4da824e --- /dev/null +++ b/dist/agy/rootiest-skills-all/skills/ship-it/SKILL.md @@ -0,0 +1,25 @@ +--- +name: ship-it +description: Runs a comprehensive pre-flight audit, syncs the README, and publishes the changes to a new PR. +version: 1.0.0 +user-invocable: true +author: Rootiest +--- + +# /ship-it + +Instructions: +Execute the following two phases sequentially. Do not proceed to Phase 2 unless Phase 1 completes successfully. + +1. Phase 1: Documentation Sync & Code Audit + - Act as the `/docs-sync-audit` skill. + - Scan all file changes since the last README edit and update the README to ensure it accurately reflects the current state of the codebase. + - Audit all code files for any syntax errors, regressions, or issues. + - CRITICAL: If any code errors or breaking issues are discovered during the audit, HALT the workflow immediately and report them to the user. Do not proceed to publishing. + +2. Phase 2: Git Publish Workflow + - Act as the `/git-publish-workflow` skill. + - Create a new, descriptively named git branch. + - Stage and commit all pending changes (including the newly updated README from Phase 1). + - Push the branch to the remote repository. + - Generate a Pull Request (PR) from the new branch into 'main'. diff --git a/dist/agy/rootiest-skills-all/skills/systematic-enumeration/SKILL.md b/dist/agy/rootiest-skills-all/skills/systematic-enumeration/SKILL.md new file mode 100644 index 0000000..efdc52b --- /dev/null +++ b/dist/agy/rootiest-skills-all/skills/systematic-enumeration/SKILL.md @@ -0,0 +1,40 @@ +--- +name: systematic-enumeration +description: Forces element-by-element verification for finite sets to prevent counting errors. +version: 1.0.0 +user-invocable: true +author: Rootiest +--- + +# Systematic Enumeration & Verification Skill + +## **Objective** +To eliminate heuristic errors and "hallucinated patterns" when analyzing finite sets. This protocol overrides the model's tendency toward "holistic recognition" in favor of systematic, element-by-element verification. + +## **Execution Protocol** +When this skill is triggered, you MUST NOT provide a direct answer immediately. Follow these three phases to ensure accuracy: + +### **Phase 1: Set Definition** +Explicitly define the boundaries and members of the finite set being analyzed. +* **Requirement:** List the members before performing any tests. +* *Example:* "The set consists of the files in the `/src` directory: [main.rs, utils.rs, types.rs]." + +### **Phase 2: Atomic Element Testing (O(n))** +Iterate through every item in the set. For each item, perform a literal check against the target property. +* **Format:** Use a list or table to force token-level focus on each element. +* **Structure:** `[Item] -> [Logic/Observation] -> [Boolean Result]` +* *Note:* For character-based tests, split the string into individual characters to bypass tokenization bias. + +### **Phase 3: Reduction & Summation** +Aggregate the `True` results from Phase 2 to derive the final answer. +* **Self-Correction:** Verify that the count of items tested in Phase 2 exactly matches the count of the set defined in Phase 1. If there is a mismatch, restart Phase 2. + +## **Constraints & Anti-Patterns** +* **STRICT BAN on Heuristics:** Do not use phrases like "typically," "usually," or "it appears that." +* **NO Pattern Matching:** Do not extrapolate a rule (e.g., "every other item") as a substitute for testing every item. +* **Computational Justification:** Treat the process as an $O(n)$ operation where $n$ is small enough that accuracy is the only priority. + +## **Trigger Scenarios** +* Counting specific characters or substrings within a string. +* Verifying property adherence across a list of variables, files, or objects. +* Membership testing in sets where false negatives are high-risk. diff --git a/dist/agy/rootiest-skills-all/skills/technical-devlog-scribe/SKILL.md b/dist/agy/rootiest-skills-all/skills/technical-devlog-scribe/SKILL.md new file mode 100644 index 0000000..c0f77f3 --- /dev/null +++ b/dist/agy/rootiest-skills-all/skills/technical-devlog-scribe/SKILL.md @@ -0,0 +1,32 @@ +--- +name: technical-devlog-scribe +description: Generates a highly structured, objective technical summary of a development session. +version: 1.0.0 +user-invocable: true +author: Rootiest +--- + +# SKILL: Technical Devlog Scribe + +## Description +Generates a comprehensive, highly structured technical summary of a development session. This skill acts as an objective technical scribe, producing a reliable historical record optimized for future context loading and maintaining a single source of truth for project evolution. + +## System Directives +* **Tone & Style:** Maintain an objective, dense, and highly technical tone. Avoid conversational filler or fluff. +* **Accuracy:** Rely strictly on the actions, code snippets, and decisions discussed within the current session. Do not hallucinate external constraints. +* **File Routing:** The output must be saved directly to `AGENTS/devlogs/.md`. Ensure the filename is concise but descriptive (e.g., `AGENTS/devlogs/oauth2-token-refresh-fix.md`). + +## Required Output Structure + +The generated markdown file must adhere strictly to the following format: + +--- +**[START OF FILE FORMAT]** + +```yaml +--- +date: YYYY-MM-DD +title: +tags: [, , , ] +status: +--- diff --git a/dist/agy/ship-it/plugin.json b/dist/agy/ship-it/plugin.json new file mode 100644 index 0000000..28786c8 --- /dev/null +++ b/dist/agy/ship-it/plugin.json @@ -0,0 +1,4 @@ +{ + "name": "ship-it", + "description": "Runs a comprehensive pre-flight audit, syncs the README, and publishes the changes to a new PR." +} diff --git a/dist/agy/ship-it/skills/ship-it/SKILL.md b/dist/agy/ship-it/skills/ship-it/SKILL.md new file mode 100644 index 0000000..4da824e --- /dev/null +++ b/dist/agy/ship-it/skills/ship-it/SKILL.md @@ -0,0 +1,25 @@ +--- +name: ship-it +description: Runs a comprehensive pre-flight audit, syncs the README, and publishes the changes to a new PR. +version: 1.0.0 +user-invocable: true +author: Rootiest +--- + +# /ship-it + +Instructions: +Execute the following two phases sequentially. Do not proceed to Phase 2 unless Phase 1 completes successfully. + +1. Phase 1: Documentation Sync & Code Audit + - Act as the `/docs-sync-audit` skill. + - Scan all file changes since the last README edit and update the README to ensure it accurately reflects the current state of the codebase. + - Audit all code files for any syntax errors, regressions, or issues. + - CRITICAL: If any code errors or breaking issues are discovered during the audit, HALT the workflow immediately and report them to the user. Do not proceed to publishing. + +2. Phase 2: Git Publish Workflow + - Act as the `/git-publish-workflow` skill. + - Create a new, descriptively named git branch. + - Stage and commit all pending changes (including the newly updated README from Phase 1). + - Push the branch to the remote repository. + - Generate a Pull Request (PR) from the new branch into 'main'. diff --git a/dist/agy/systematic-enumeration/plugin.json b/dist/agy/systematic-enumeration/plugin.json new file mode 100644 index 0000000..3fac494 --- /dev/null +++ b/dist/agy/systematic-enumeration/plugin.json @@ -0,0 +1,4 @@ +{ + "name": "systematic-enumeration", + "description": "Forces element-by-element verification for finite sets to prevent counting errors." +} diff --git a/dist/agy/systematic-enumeration/skills/systematic-enumeration/SKILL.md b/dist/agy/systematic-enumeration/skills/systematic-enumeration/SKILL.md new file mode 100644 index 0000000..efdc52b --- /dev/null +++ b/dist/agy/systematic-enumeration/skills/systematic-enumeration/SKILL.md @@ -0,0 +1,40 @@ +--- +name: systematic-enumeration +description: Forces element-by-element verification for finite sets to prevent counting errors. +version: 1.0.0 +user-invocable: true +author: Rootiest +--- + +# Systematic Enumeration & Verification Skill + +## **Objective** +To eliminate heuristic errors and "hallucinated patterns" when analyzing finite sets. This protocol overrides the model's tendency toward "holistic recognition" in favor of systematic, element-by-element verification. + +## **Execution Protocol** +When this skill is triggered, you MUST NOT provide a direct answer immediately. Follow these three phases to ensure accuracy: + +### **Phase 1: Set Definition** +Explicitly define the boundaries and members of the finite set being analyzed. +* **Requirement:** List the members before performing any tests. +* *Example:* "The set consists of the files in the `/src` directory: [main.rs, utils.rs, types.rs]." + +### **Phase 2: Atomic Element Testing (O(n))** +Iterate through every item in the set. For each item, perform a literal check against the target property. +* **Format:** Use a list or table to force token-level focus on each element. +* **Structure:** `[Item] -> [Logic/Observation] -> [Boolean Result]` +* *Note:* For character-based tests, split the string into individual characters to bypass tokenization bias. + +### **Phase 3: Reduction & Summation** +Aggregate the `True` results from Phase 2 to derive the final answer. +* **Self-Correction:** Verify that the count of items tested in Phase 2 exactly matches the count of the set defined in Phase 1. If there is a mismatch, restart Phase 2. + +## **Constraints & Anti-Patterns** +* **STRICT BAN on Heuristics:** Do not use phrases like "typically," "usually," or "it appears that." +* **NO Pattern Matching:** Do not extrapolate a rule (e.g., "every other item") as a substitute for testing every item. +* **Computational Justification:** Treat the process as an $O(n)$ operation where $n$ is small enough that accuracy is the only priority. + +## **Trigger Scenarios** +* Counting specific characters or substrings within a string. +* Verifying property adherence across a list of variables, files, or objects. +* Membership testing in sets where false negatives are high-risk. diff --git a/dist/agy/technical-devlog-scribe/plugin.json b/dist/agy/technical-devlog-scribe/plugin.json new file mode 100644 index 0000000..c666e0a --- /dev/null +++ b/dist/agy/technical-devlog-scribe/plugin.json @@ -0,0 +1,4 @@ +{ + "name": "technical-devlog-scribe", + "description": "Generates a highly structured, objective technical summary of a development session." +} diff --git a/dist/agy/technical-devlog-scribe/skills/technical-devlog-scribe/SKILL.md b/dist/agy/technical-devlog-scribe/skills/technical-devlog-scribe/SKILL.md new file mode 100644 index 0000000..c0f77f3 --- /dev/null +++ b/dist/agy/technical-devlog-scribe/skills/technical-devlog-scribe/SKILL.md @@ -0,0 +1,32 @@ +--- +name: technical-devlog-scribe +description: Generates a highly structured, objective technical summary of a development session. +version: 1.0.0 +user-invocable: true +author: Rootiest +--- + +# SKILL: Technical Devlog Scribe + +## Description +Generates a comprehensive, highly structured technical summary of a development session. This skill acts as an objective technical scribe, producing a reliable historical record optimized for future context loading and maintaining a single source of truth for project evolution. + +## System Directives +* **Tone & Style:** Maintain an objective, dense, and highly technical tone. Avoid conversational filler or fluff. +* **Accuracy:** Rely strictly on the actions, code snippets, and decisions discussed within the current session. Do not hallucinate external constraints. +* **File Routing:** The output must be saved directly to `AGENTS/devlogs/.md`. Ensure the filename is concise but descriptive (e.g., `AGENTS/devlogs/oauth2-token-refresh-fix.md`). + +## Required Output Structure + +The generated markdown file must adhere strictly to the following format: + +--- +**[START OF FILE FORMAT]** + +```yaml +--- +date: YYYY-MM-DD +title: +tags: [, , , ] +status: +--- diff --git a/manifest.yaml b/manifest.yaml new file mode 100644 index 0000000..b3f4776 --- /dev/null +++ b/manifest.yaml @@ -0,0 +1,16 @@ +schemaVersion: 1 + +marketplace: + name: rootiest-skills + owner: + name: Rootiest + url: https://git.rootiest.dev/rootiest/ai-skills + description: Reusable AI skills for Claude Code and Antigravity CLI + +bundle: + id: rootiest-skills-all + license: GPL-3.0-or-later + +targets: + - claude-code + - agy diff --git a/plugins/core-essentials/skills/delegate-agy/SKILL.md b/plugins/core-essentials/skills/delegate-agy/SKILL.md new file mode 100644 index 0000000..4852a03 --- /dev/null +++ b/plugins/core-essentials/skills/delegate-agy/SKILL.md @@ -0,0 +1,10 @@ +# Antigravity Subagent Delegation (`delegate-agy`) + +When the user asks for a second opinion, external grounded research, or when a task requires processing large multi-file audits (>500 lines) that would bloat context, delegate the subtask to `agy`. + +## Execution Syntax +Run `agy` in headless, non-interactive mode using the bash tool: + +```bash +agy --dangerously-skip-permissions -p "" +``` diff --git a/scripts/generate_plugins.py b/scripts/generate_plugins.py new file mode 100755 index 0000000..090d876 --- /dev/null +++ b/scripts/generate_plugins.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python3 +"""Generate per-agent plugin manifests from the skills/ SSoT. + +Reads manifest.yaml (marketplace/org metadata + target list) and every +skills//SKILL.md (per-skill frontmatter), then regenerates: + + - descriptions.json (from SKILL.md frontmatter) + - .claude-plugin/marketplace.json (Claude Code target) + - dist/agy/** (Antigravity CLI target) + +Run with --check to only validate the SSoT (frontmatter, manifest.yaml) and +skip writing any output — used as the pull-request gate. +""" +from __future__ import annotations + +import json +import shutil +import sys +from pathlib import Path + +import yaml + +ROOT = Path(__file__).resolve().parent.parent +SKILLS_DIR = ROOT / "skills" +MANIFEST_PATH = ROOT / "manifest.yaml" + +REQUIRED_FRONTMATTER_FIELDS = ("name", "description", "version", "author") + + +class ValidationError(Exception): + pass + + +def load_manifest() -> dict: + with MANIFEST_PATH.open("r", encoding="utf-8") as f: + manifest = yaml.safe_load(f) + for key in ("marketplace", "bundle", "targets"): + if key not in manifest: + raise ValidationError(f"manifest.yaml is missing required key '{key}'") + return manifest + + +def parse_frontmatter(skill_md: Path) -> dict: + text = skill_md.read_text(encoding="utf-8") + if not text.startswith("---\n"): + raise ValidationError(f"{skill_md}: missing YAML frontmatter delimiter") + end = text.find("\n---", 4) + if end == -1: + raise ValidationError(f"{skill_md}: unterminated YAML frontmatter") + raw = text[4:end] + data = yaml.safe_load(raw) or {} + for field in REQUIRED_FRONTMATTER_FIELDS: + if not data.get(field): + raise ValidationError(f"{skill_md}: frontmatter missing required field '{field}'") + return data + + +def discover_skills() -> list[dict]: + skills = [] + seen_names = set() + for skill_dir in sorted(SKILLS_DIR.iterdir()): + if not skill_dir.is_dir(): + continue + skill_md = skill_dir / "SKILL.md" + if not skill_md.exists(): + raise ValidationError(f"{skill_dir}: missing SKILL.md") + frontmatter = parse_frontmatter(skill_md) + name = frontmatter["name"] + if name != skill_dir.name: + raise ValidationError( + f"{skill_md}: frontmatter name '{name}' does not match directory name '{skill_dir.name}'" + ) + if name in seen_names: + raise ValidationError(f"duplicate skill name '{name}'") + seen_names.add(name) + skills.append({"dir": skill_dir, "frontmatter": frontmatter}) + if not skills: + raise ValidationError("no skills found under skills/") + return skills + + +def gen_descriptions_json(skills: list[dict]) -> None: + descriptions = {s["frontmatter"]["name"]: s["frontmatter"]["description"] for s in skills} + out = ROOT / "descriptions.json" + out.write_text(json.dumps(descriptions, indent=2) + "\n", encoding="utf-8") + + +def gen_claude_code(manifest: dict, skills: list[dict]) -> None: + plugin_dir = ROOT / ".claude-plugin" + plugin_dir.mkdir(exist_ok=True) + + plugins = [] + for s in skills: + fm = s["frontmatter"] + plugins.append( + { + "name": fm["name"], + "description": fm["description"], + "source": "./", + "skills": [f"./skills/{fm['name']}"], + } + ) + + plugins.append( + { + "name": manifest["bundle"]["id"], + "description": f"{manifest['marketplace']['description']} (all skills)", + "source": "./", + "skills": ["./skills/"], + } + ) + + marketplace = { + "name": manifest["marketplace"]["name"], + "owner": manifest["marketplace"]["owner"], + "description": manifest["marketplace"]["description"], + "plugins": plugins, + } + + out = plugin_dir / "marketplace.json" + out.write_text(json.dumps(marketplace, indent=2) + "\n", encoding="utf-8") + + +def gen_agy(manifest: dict, skills: list[dict]) -> None: + agy_dir = ROOT / "dist" / "agy" + if agy_dir.exists(): + shutil.rmtree(agy_dir) + agy_dir.mkdir(parents=True) + + def write_plugin(plugin_name: str, description: str, members: list[dict]) -> None: + plugin_root = agy_dir / plugin_name + skills_out = plugin_root / "skills" + skills_out.mkdir(parents=True) + for s in members: + dest = skills_out / s["frontmatter"]["name"] + shutil.copytree(s["dir"], dest) + plugin_json = {"name": plugin_name, "description": description} + (plugin_root / "plugin.json").write_text( + json.dumps(plugin_json, indent=2) + "\n", encoding="utf-8" + ) + + for s in skills: + fm = s["frontmatter"] + write_plugin(fm["name"], fm["description"], [s]) + + write_plugin( + manifest["bundle"]["id"], + f"{manifest['marketplace']['description']} (all skills)", + skills, + ) + + dist_readme = ROOT / "dist" / "README.md" + dist_readme.write_text( + "# Generated\n\n" + "This directory is generated by `scripts/generate_plugins.py` from " + "`manifest.yaml` and `skills/`. Do not edit files here directly — " + "edit the source skill instead and regenerate.\n", + encoding="utf-8", + ) + + +GENERATORS = { + "claude-code": gen_claude_code, + "agy": gen_agy, +} + + +def main() -> int: + check_only = "--check" in sys.argv[1:] + try: + manifest = load_manifest() + skills = discover_skills() + for target in manifest["targets"]: + if target not in GENERATORS: + raise ValidationError(f"manifest.yaml: unknown target '{target}'") + if check_only: + print(f"OK: {len(skills)} skill(s), {len(manifest['targets'])} target(s) validated") + return 0 + gen_descriptions_json(skills) + for target in manifest["targets"]: + GENERATORS[target](manifest, skills) + print(f"Generated plugins for {len(skills)} skill(s), targets: {', '.join(manifest['targets'])}") + return 0 + except ValidationError as e: + print(f"error: {e}", file=sys.stderr) + return 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/requirements.txt b/scripts/requirements.txt new file mode 100644 index 0000000..c3726e8 --- /dev/null +++ b/scripts/requirements.txt @@ -0,0 +1 @@ +pyyaml