diff --git a/AGENTS.md b/AGENTS.md index 63585fa..9a20d68 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -25,7 +25,14 @@ The general-purpose skills that do exist are narrow output-format helpers (`docx ## Layout +The repository root is an [Agent Plugins](https://agent-plugins.org/) 1.0.0 package: `plugin.json` +plus the portable `skills/` tree. Keep `plugin.json` valid against the Agent Plugins manifest +schema, and keep its `version` identical to `pyproject.toml` `[project].version`. Do not add +non-portable top-level fields to `plugin.json` (no inline MCP, hooks, or client-only keys — use +`mcp.json` or a reverse-domain `extensions` namespace if those are ever needed). + ```text +plugin.json # Agent Plugins manifest (repo root) skills// ├── SKILL.md # required ├── references/ # optional: long documentation, loaded only when needed @@ -33,8 +40,8 @@ skills// └── assets/ # optional: templates and static resources ``` -Only `SKILL.md` is required. Reference other files with relative paths from the skill root, kept -one level deep. +Only `SKILL.md` is required inside each skill. Reference other files with relative paths from the +skill root, kept one level deep. **Tests never live under `skills/`.** A skill directory ships only what an agent loads. Checks for a skill's scripts and structure go in the repository-level suite instead: @@ -367,9 +374,10 @@ hand-tuning one skill's prompt, so the set stays visually consistent. - `metadata.version` exists, is quoted, and is bumped if you changed an existing skill. - `metadata` is a block mapping; `openclaw` / `hermes` blocks are nested mappings. - `uv run skills-ref validate skills/` passes. +- If the collection version changes, `plugin.json` `version` matches `pyproject.toml`. - `uv run --with pytest python -m pytest tests/_meta -q` passes — this is what CI blocks on, and it - catches a missing suite, a missing `skill-requirements.toml` entry, a broken local link, and a - leaked local path. + catches a missing suite, a missing `skill-requirements.toml` entry, a broken local link, a + leaked local path, and a drifted Agent Plugins manifest. - If the skill ships `scripts/`: a suite exists at `tests//`, a `[skills.]` entry exists in `tests/skill-requirements.toml`, and `python tests/run_all.py --isolated ` passes. - `docs/images/.png` exists, and was regenerated if the change altered what the skill does. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5c64554..af14db7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,9 +14,13 @@ Participation in this project is governed by our [Code of Conduct](CODE_OF_CONDU ## Skill Location -All repository skills live under `skills/`: +All repository skills live under `skills/`. The repository root is also an +[Agent Plugins](https://agent-plugins.org/) package: keep root `plugin.json` schema-valid, do not +add non-portable top-level fields, and keep its `version` in sync with `pyproject.toml` whenever +you bump the collection version. ```text +plugin.json skills/ └── skill-name/ ├── SKILL.md @@ -345,6 +349,7 @@ Before submitting a pull request, confirm: - If the skill needs credentials, they are named in `compatibility` and declared in `metadata.openclaw.envVars`. - `metadata.version` exists and is quoted. - Existing skills have a version bump when changed. +- If the collection version changes, `plugin.json` `version` matches `pyproject.toml`. - The `description` clearly says what the skill does and when to use it. - `uv run --with pytest python -m pytest tests/_meta -q` passes. This is what CI blocks on, and it catches a missing suite, a missing `skill-requirements.toml` entry, a broken local link, a leaked local path, and a `SKILL.md` over 500 lines. - If the skill ships `scripts/`: a suite exists at `tests//`, a `[skills.]` entry exists in `tests/skill-requirements.toml`, and `python tests/run_all.py --isolated ` passes. diff --git a/README.md b/README.md index 0724f84..b43effb 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@ # Scientific Agent Skills [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE.md) -[![Version](https://img.shields.io/badge/Version-2.62.0-blue.svg)](pyproject.toml) +[![Version](https://img.shields.io/badge/Version-2.63.0-blue.svg)](pyproject.toml) [![Skills](https://img.shields.io/badge/Skills-161-brightgreen.svg)](#-whats-included) [![Databases](https://img.shields.io/badge/Databases-100%2B-orange.svg)](#-whats-included) [![Agent Skills](https://img.shields.io/badge/Standard-Agent_Skills-blueviolet.svg)](https://agentskills.io/) +[![Agent Plugins](https://img.shields.io/badge/Standard-Agent_Plugins-0A7A72.svg)](https://agent-plugins.org/) [![Security Scan](https://github.com/K-Dense-AI/scientific-agent-skills/actions/workflows/security-scan.yml/badge.svg)](https://github.com/K-Dense-AI/scientific-agent-skills/actions/workflows/security-scan.yml) [![Skill Tests](https://github.com/K-Dense-AI/scientific-agent-skills/actions/workflows/skill-tests.yml/badge.svg)](https://github.com/K-Dense-AI/scientific-agent-skills/actions/workflows/skill-tests.yml) [![Works with](https://img.shields.io/badge/Works_with-Cursor_|_Claude_Code_|_Codex_|_Google_Antigravity-blue.svg)](#-getting-started) @@ -18,7 +19,7 @@ > **Stay up to date:** Follow K-Dense on [X](https://x.com/k_dense_ai), [LinkedIn](https://www.linkedin.com/company/k-dense-inc), and [YouTube](https://www.youtube.com/@K-Dense-Inc) for new skills, release announcements, walkthroughs, research workflow demos, and examples you can use with your own AI agent. -A comprehensive collection of **161 ready-to-use scientific and research skills** (covering cancer genomics, individual-level 1000 Genomes queries, hosted regulatory-sequence prediction, live pathogen-variant surveillance, analytical method validation, PK/PD modelling and dose selection, full-text biomedical and regulatory literature retrieval, drug-target binding, bounded biomedical knowledge graph search, molecular dynamics, RNA velocity, geospatial science, time series forecasting, scientific ML resource discovery via Hugging Science, 78+ scientific databases, and more) for any AI agent that supports the open [Agent Skills](https://agentskills.io/) standard, created by [K-Dense](https://k-dense.ai). Works with **Cursor, Claude Code, Codex, Google Antigravity, and more**. Transform your AI agent into a research assistant capable of executing complex multi-step scientific workflows across biology, chemistry, medicine, and beyond. +A comprehensive collection of **161 ready-to-use scientific and research skills** (covering cancer genomics, individual-level 1000 Genomes queries, hosted regulatory-sequence prediction, live pathogen-variant surveillance, analytical method validation, PK/PD modelling and dose selection, full-text biomedical and regulatory literature retrieval, drug-target binding, bounded biomedical knowledge graph search, molecular dynamics, RNA velocity, geospatial science, time series forecasting, scientific ML resource discovery via Hugging Science, 78+ scientific databases, and more) for any AI agent that supports the open [Agent Skills](https://agentskills.io/) standard, created by [K-Dense](https://k-dense.ai). The repository is also a portable [Agent Plugins](https://agent-plugins.org/) package (`plugin.json` + `skills/`), so plugin-capable clients can load the whole collection as one plugin. Works with **Cursor, Claude Code, Codex, Google Antigravity, and more**. Transform your AI agent into a research assistant capable of executing complex multi-step scientific workflows across biology, chemistry, medicine, and beyond. > ⭐ **Help make AI for science easier to discover:** If Scientific Agent Skills saves you time, teaches your agent a workflow, or helps your lab move faster, please [star this repository](https://github.com/K-Dense-AI/scientific-agent-skills). A star is a public signal that these open, reusable research skills are worth maintaining: it helps scientists, engineers, and open-source contributors find the project, shows which agent-skill standards are gaining real adoption, and gives us a clear reason to keep expanding the collection for the community. @@ -155,7 +156,7 @@ Pin to a specific release tag or commit SHA for reproducible installs: ```bash # Pin to a release tag -gh skill install K-Dense-AI/scientific-agent-skills --pin v2.62.0 +gh skill install K-Dense-AI/scientific-agent-skills --pin v2.63.0 # Pin to a commit SHA gh skill install K-Dense-AI/scientific-agent-skills --pin abc123def @@ -171,6 +172,27 @@ gh skill update gh skill update --all ``` +### Option 3: Agent Plugins (Cursor, Codex, and other plugin clients) + +This repository is a valid [Agent Plugins](https://agent-plugins.org/) 1.0.0 package: root [`plugin.json`](plugin.json) plus Agent Skills under `skills/`. Clients that support the standard discover every immediate child of `skills/` that contains a `SKILL.md`. + +**Cursor** — symlink or copy the repo into the local plugins directory, then reload: + +```bash +mkdir -p ~/.cursor/plugins/local +ln -s "$(pwd)" ~/.cursor/plugins/local/scientific-agent-skills +``` + +Restart Cursor or run **Developer: Reload Window**, then confirm the plugin and its skills appear under **Customize**. See [Cursor plugins](https://cursor.com/docs/plugins). + +**Codex** — install from a local checkout (confirm the current CLI flag names in Codex docs): + +```bash +codex plugins install . +``` + +Compatible clients (Cursor, Codex, GitHub Copilot, VS Code, Kiro, and others listed at [agent-plugins.org](https://agent-plugins.org/compatible-clients)) share the same package layout; installation UX stays client-specific. + ### Other Agent Skills hosts (OpenClaw, NemoClaw, Pi, Hermes, …) Agent hosts differ in install paths, discovery settings, and support for optional frontmatter fields. `npx skills add` (Option 1) commonly installs into the `~/.agents/skills/` convention, with project-scoped installs under `.agents/skills/`; confirm both paths against your host's current documentation. To install manually on a host configured to scan one of those locations: diff --git a/plugin.json b/plugin.json new file mode 100644 index 0000000..b5d6598 --- /dev/null +++ b/plugin.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", + "name": "scientific-agent-skills", + "version": "2.63.0", + "description": "Ready-to-use scientific and research Agent Skills for biology, chemistry, medicine, and related workflows.", + "author": { + "name": "K-Dense Inc.", + "url": "https://k-dense.ai" + }, + "homepage": "https://github.com/K-Dense-AI/scientific-agent-skills", + "repository": "https://github.com/K-Dense-AI/scientific-agent-skills", + "license": "MIT", + "keywords": [ + "agent-skills", + "science", + "research", + "bioinformatics", + "cheminformatics", + "biology", + "chemistry", + "medicine" + ] +} diff --git a/pyproject.toml b/pyproject.toml index 36b9048..8b23589 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "scientific-agent-skills" -version = "2.62.0" +version = "2.63.0" description = "A set of ready to use Agent Skills for research, science, engineering, analysis, finance and writing." readme = "README.md" requires-python = ">=3.13" diff --git a/tests/_meta/test_repo_contract.py b/tests/_meta/test_repo_contract.py index 367efb8..c70584d 100644 --- a/tests/_meta/test_repo_contract.py +++ b/tests/_meta/test_repo_contract.py @@ -14,6 +14,8 @@ run it on every pull request in seconds. from __future__ import annotations +import json +import re import tomllib import unittest from pathlib import Path @@ -24,6 +26,26 @@ REPO_ROOT = Path(__file__).resolve().parents[2] SKILLS_DIR = REPO_ROOT / "skills" TESTS_DIR = REPO_ROOT / "tests" REQUIREMENTS = TESTS_DIR / "skill-requirements.toml" +PLUGIN_MANIFEST = REPO_ROOT / "plugin.json" +PYPROJECT = REPO_ROOT / "pyproject.toml" + +PLUGIN_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json" +PLUGIN_NAME = "scientific-agent-skills" +ALLOWED_PLUGIN_KEYS = frozenset( + { + "$schema", + "name", + "version", + "description", + "author", + "homepage", + "repository", + "license", + "keywords", + "extensions", + } +) +PLUGIN_NAME_RE = re.compile(r"^(?!.*(?:--|\.\.))[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?$") structure = skill_contract.structure office = skill_contract.office @@ -122,5 +144,40 @@ class SharedCopyTests(unittest.TestCase): self.assertEqual(office.shared_file_problems(SKILLS_DIR), []) +class AgentPluginTests(unittest.TestCase): + """Root plugin.json keeps the repo a valid Agent Plugins 1.0.0 package.""" + + maxDiff = None + + def test_plugin_manifest_conforms(self) -> None: + self.assertTrue(PLUGIN_MANIFEST.is_file(), "plugin.json must exist at the repo root") + manifest = json.loads(PLUGIN_MANIFEST.read_text(encoding="utf-8")) + self.assertIsInstance(manifest, dict) + + unknown = sorted(set(manifest) - ALLOWED_PLUGIN_KEYS) + self.assertEqual(unknown, [], "plugin.json has closed top-level schema") + + self.assertEqual(manifest.get("$schema"), PLUGIN_SCHEMA) + self.assertEqual(manifest.get("name"), PLUGIN_NAME) + self.assertRegex(manifest["name"], PLUGIN_NAME_RE) + + project = tomllib.loads(PYPROJECT.read_text(encoding="utf-8"))["project"] + self.assertEqual( + manifest.get("version"), + project["version"], + "plugin.json version must match pyproject.toml [project].version", + ) + + def test_skills_component_is_discoverable(self) -> None: + """Agent Plugins discovers only immediate children of skills/ with SKILL.md.""" + self.assertTrue(SKILLS_DIR.is_dir()) + self.assertTrue(KNOWN_SKILLS, "no discoverable skills under skills/") + for name in sorted(KNOWN_SKILLS): + with self.subTest(skill=name): + skill_md = SKILLS_DIR / name / "SKILL.md" + self.assertTrue(skill_md.is_file()) + self.assertEqual(skill_md.parent.parent, SKILLS_DIR) + + if __name__ == "__main__": unittest.main()