Some checks failed
CodeQL / Analyze (${{ matrix.language }}) (go) (pull_request) Successful in 13s
CodeQL / Analyze (${{ matrix.language }}) (python) (pull_request) Successful in 11s
CodeQL / Analyze (${{ matrix.language }}) (javascript-typescript) (pull_request) Successful in 12s
Check merge_group trigger on required workflows / Required workflows have merge_group trigger (pull_request) Successful in 15s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 27s
CI / Detect changes (pull_request) Successful in 20s
Retarget main PRs to staging / Retarget to staging (pull_request) Has been skipped
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 15s
E2E API Smoke Test / detect-changes (pull_request) Successful in 51s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 51s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 39s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 51s
Harness Replays / detect-changes (pull_request) Successful in 53s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 48s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m7s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 31s
Harness Replays / Harness Replays (pull_request) Failing after 1m18s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2m19s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 3m14s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 6m1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 6m47s
CI / Python Lint & Test (pull_request) Successful in 8m16s
CI / Canvas (Next.js) (pull_request) Failing after 9m36s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Successful in 12m18s
Migrates the two Go modules under molecule-core off the dead
github.com/Molecule-AI/molecule-monorepo/... identity onto the vanity
host go.moleculesai.app. Also fixes the historical naming
inconsistency where the Gitea repo is molecule-core but the Go module
path said molecule-monorepo.
Module changes:
- workspace-server/go.mod:
github.com/Molecule-AI/molecule-monorepo/platform
-> go.moleculesai.app/core/platform
- tests/harness/cp-stub/go.mod:
github.com/Molecule-AI/molecule-monorepo/tests/harness/cp-stub
-> go.moleculesai.app/core/tests/harness/cp-stub
Surfaces touched
- 174 *.go files (374 import lines) — every import under
workspace-server/ + tests/harness/cp-stub/
- 2 Dockerfiles (workspace-server/Dockerfile + Dockerfile.tenant) —
-ldflags strings updated in lockstep with the module rename so
buildinfo.GitSHA injection still resolves correctly
- README + docs + scripts + comment URLs to git.moleculesai.app form
- NEW workspace-server/internal/lint/import_path_lint_test.go —
structural lint gate rejecting future github.com/Molecule-AI/ or
Molecule-AI/molecule-monorepo references. Identical template to the
other migration PRs (plugin-gh-identity#3, molecule-cli#2,
molecule-controlplane#32).
Cross-repo dep allowlist (documented in lint gate)
workspace-server requires molecule-ai-plugin-gh-identity, whose own
vanity migration is PR molecule-ai-plugin-gh-identity#3. Until that PR
merges + a tag is cut at go.moleculesai.app/plugin/gh-identity, the
two locations referencing the legacy github.com path
(workspace-server/go.mod require, cmd/server/main.go import) remain
allowlisted. Follow-up PR drops the allowlist + updates both refs in
one shot once gh-identity is fully migrated.
Test plan
- go build ./... clean for both modules
- go test ./... green except two pre-existing failures
(TestStartSweeper_RecordsMetricsOnSuccess flaky-on-suite,
TestLocalResolver_BubblesUpCopyFailure relies on read-only fs perms
but runs as root on operator host) — both reproduce identically on
baseline main pre-migration; NOT regressions of this PR
- Mutation-tested: lint gate fails on canaries in .go + .md;
allowlist correctly suppresses cross-repo dep references in go.mod
while still flagging unrelated additions
Open dependency
- go.moleculesai.app responder must be deployed before fresh-clone
external builds resolve the vanity path. Existing CI / Docker builds
ride pinned go.sum + self-referential module path + responder is
not on critical path for those.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
183 lines
8.2 KiB
Markdown
183 lines
8.2 KiB
Markdown
# Molecule AI plugins and the agentskills.io standard
|
||
|
||
> **TL;DR** — every skill inside a Molecule AI plugin is a spec-compliant
|
||
> [agentskills.io](https://agentskills.io) skill, which means the same
|
||
> skill directory is installable in **Claude Code, Cursor, GitHub Copilot,
|
||
> VS Code, OpenAI Codex, Gemini CLI, Amp, OpenCode, OpenHands, Letta,
|
||
> Goose, Roo Code, Kiro, Factory, Ona, Junie**, and ~20 other agent
|
||
> products that ship the standard today. Molecule AI adds a *plugin*
|
||
> superset on top: a bundle of skills + rules + per-runtime adapters,
|
||
> so the same plugin can orchestrate across a team of agents running on
|
||
> different LLM runtimes.
|
||
|
||
## The two layers
|
||
|
||
```
|
||
plugins/my-plugin/ ← Molecule AI bundle (our layer)
|
||
├── plugin.yaml ← Molecule AI manifest: name, version,
|
||
│ runtimes, adapters, description
|
||
├── rules/*.md ← Molecule AI-only: always-on prose
|
||
│ appended to the runtime memory file
|
||
├── skills/ ← agentskills.io layer starts here
|
||
│ ├── <skill-name-1>/
|
||
│ │ ├── SKILL.md ← agentskills spec: frontmatter + body
|
||
│ │ ├── scripts/ ← optional, executable code
|
||
│ │ ├── references/ ← optional, deep-dive docs
|
||
│ │ └── assets/ ← optional, templates/data
|
||
│ └── <skill-name-2>/
|
||
│ └── SKILL.md
|
||
└── adapters/ ← Molecule AI-only: per-runtime installers
|
||
├── claude_code.py
|
||
└── deepagents.py
|
||
```
|
||
|
||
The boundary is clean:
|
||
|
||
- **Everything under `skills/<name>/`** follows the spec. A skill-aware
|
||
tool that doesn't know what Molecule AI is can consume it as-is.
|
||
- **Everything above `skills/`** is our superset — bundle metadata,
|
||
cross-runtime install logic, always-on rules.
|
||
|
||
## What the spec defines (and what we follow exactly)
|
||
|
||
Per [agentskills.io/specification](https://agentskills.io/specification):
|
||
|
||
| Spec requirement | How Molecule AI enforces it |
|
||
|---|---|
|
||
| Skill is a directory with `SKILL.md` at the root | `skills/<name>/SKILL.md` |
|
||
| Directory name matches frontmatter `name` | Enforced by `molecule_plugin validate` |
|
||
| `name`: 1–64 chars, lowercase + hyphens, no consecutive or edge hyphens | Regex-validated |
|
||
| `description`: 1–1024 chars, covers what+when | Length-validated |
|
||
| `license`, `compatibility`, `metadata`, `allowed-tools` optional | Passed through unchanged |
|
||
| `scripts/`, `references/`, `assets/` optional dirs | Skill loader reads all three |
|
||
| Progressive disclosure (metadata → body → sub-files) | Claude Code reads it natively; other runtimes load via plugin adaptor |
|
||
|
||
## Where we extend the spec (bundle layer)
|
||
|
||
The spec doesn't address bundling, cross-runtime installation, or
|
||
always-on rules. That's what `plugin.yaml` adds:
|
||
|
||
```yaml
|
||
# plugins/my-plugin/plugin.yaml
|
||
name: my-plugin
|
||
version: 1.0.0
|
||
description: Bundle of related skills + rules for <use case>.
|
||
author: your-name
|
||
tags: [example]
|
||
|
||
# Declared supported workspace runtimes — each must have a matching
|
||
# adapters/<runtime>.py file, or the install falls through to raw-drop.
|
||
runtimes:
|
||
- claude_code
|
||
- deepagents
|
||
|
||
# Optional — these are document hints, not enforced by the spec.
|
||
# The skills list is informational; the skill loader discovers everything
|
||
# under skills/ regardless.
|
||
skills:
|
||
- my-skill-a
|
||
- my-skill-b
|
||
|
||
# Optional — always-on markdown files appended to the runtime memory file
|
||
# (CLAUDE.md on Claude Code and DeepAgents). The spec has no always-on tier.
|
||
rules:
|
||
- rules/conventions.md
|
||
```
|
||
|
||
### Rules vs skills
|
||
|
||
- **A skill** is activated on demand — the agent reads its `name` and
|
||
`description` at startup, then loads the body when the task matches.
|
||
- **A rule** is always-on — its text is appended to the runtime's
|
||
memory file (CLAUDE.md) so the agent sees it on every turn.
|
||
|
||
Rules are a Molecule AI-specific extension. If we ever need to represent a
|
||
rule as a spec-compliant skill (e.g. for distribution to a non-Molecule AI
|
||
tool), write it as a skill whose `description` explicitly says "apply
|
||
continuously in this codebase" — the tool will decide whether to honor it.
|
||
|
||
### Per-runtime adapters
|
||
|
||
The spec leaves install semantics to the host tool. Molecule AI's plugin
|
||
adapters (`plugins/<name>/adapters/<runtime>.py`) bridge the gap for
|
||
runtimes that don't read `SKILL.md` natively. For most plugins the
|
||
built-in `AgentskillsAdaptor` covers the common shape (copy skills to
|
||
`/configs/skills/`, append rules to CLAUDE.md). See
|
||
[plugins_registry](../../workspace/plugins_registry/__init__.py)
|
||
for the resolution order.
|
||
|
||
## Validator
|
||
|
||
Run before publishing a plugin:
|
||
|
||
```bash
|
||
python -m molecule_plugin validate plugins/my-plugin
|
||
```
|
||
|
||
Checks:
|
||
|
||
1. `plugin.yaml` parses and declares known runtimes.
|
||
2. Every `skills/<name>/SKILL.md`:
|
||
- has valid frontmatter
|
||
- `name` matches the directory name
|
||
- `name` matches the spec regex (lowercase, hyphens, length)
|
||
- `description` is 1–1024 chars
|
||
- optional fields (`license`, `compatibility`, `metadata`,
|
||
`allowed-tools`) conform to spec types
|
||
|
||
CI runs this against every first-party plugin on every PR, so spec drift
|
||
is caught before merge.
|
||
|
||
## Publishing a skill to agentskills-compatible tools
|
||
|
||
Any `skills/<name>/` directory from a Molecule AI plugin is a valid standalone
|
||
skill. To publish it for Cursor / Codex / Goose / etc. users:
|
||
|
||
1. Copy `plugins/my-plugin/skills/<name>/` into a new repo.
|
||
2. Validate: `python -m molecule_plugin validate .` (or `skills-ref validate`
|
||
from the upstream [agentskills/agentskills](https://github.com/agentskills/agentskills) repo).
|
||
3. Publish the repo; users install according to their tool's docs.
|
||
|
||
The skill will use default activation semantics in each tool. Molecule AI's
|
||
plugin bundle (runtimes, adapters, rules) is not needed — it only matters
|
||
if the skill is installed inside Molecule AI.
|
||
|
||
## Hermes runtime compatibility (issue #852)
|
||
|
||
As of 2026-04-18, `hermes` has been added to the `runtimes:` field in
|
||
the five SKILL.md-only first-party plugins. agentskills.io v0.8.0
|
||
confirmed that SKILL.md-only plugins are natively hermes-compatible via
|
||
**raw-drop** (no adapter file required). Hook-based plugins remain
|
||
`claude_code`-only — they rely on harness-level hooks that hermes does
|
||
not expose.
|
||
|
||
| Plugin | Before | After |
|
||
|---|---|---|
|
||
| `ecc` | `[claude_code, deepagents]` | `[claude_code, deepagents, hermes]` |
|
||
| `superpowers` | `[claude_code, deepagents]` | `[claude_code, deepagents, hermes]` |
|
||
| `molecule-dev` | `[claude_code, deepagents]` | `[claude_code, deepagents, hermes]` |
|
||
| `molecule-skill-cron-learnings` | `[claude_code]` | `[claude_code, hermes]` |
|
||
| `molecule-skill-update-docs` | `[claude_code]` | `[claude_code, hermes]` |
|
||
|
||
Companion PRs:
|
||
- [molecule-ai-plugin-ecc#2](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-ecc/pull/2)
|
||
- [molecule-ai-plugin-superpowers#2](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-superpowers/pull/2)
|
||
- [molecule-ai-plugin-molecule-dev#2](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-molecule-dev/pull/2)
|
||
- [molecule-ai-plugin-molecule-skill-cron-learnings#2](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-molecule-skill-cron-learnings/pull/2)
|
||
- [molecule-ai-plugin-molecule-skill-update-docs#2](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-molecule-skill-update-docs/pull/2)
|
||
|
||
Security note: Security Auditor was offline at time of change. Self-assessed
|
||
as non-security-impacting — adding `hermes` to a string list in `plugin.yaml`
|
||
creates no new tool surface or execution path.
|
||
|
||
## Why this matters strategically
|
||
|
||
- **Zero-cost distribution.** Every skill we ship to Molecule AI users is
|
||
automatically installable in ~35 other agent products, no rewrite.
|
||
- **We're visible in the spec ecosystem.** Our plugin directory becomes
|
||
discoverable alongside Anthropic's own example skills. If the spec
|
||
adds new fields, we inherit them for free.
|
||
- **Our moat stays intact.** Multi-agent orchestration, A2A, per-runtime
|
||
adapters, and the visual canvas — none of this is in scope for the
|
||
spec and is unlikely to be. That's where Molecule AI differentiates.
|