mirror of
https://github.com/pulumi/agent-skills.git
synced 2026-09-14 20:16:47 +08:00
Add combined pulumi plugin for one-install marketplace distribution (#50)
* Add combined pulumi plugin for one-install marketplace distribution The Claude marketplace 'pulumi' entry now points at a combined plugin defined at the repo root, whose skills field bundles the authoring, migration, and delegation skill groups. A single '/plugin install pulumi' covers all 14 end-user skills; granular plugins remain for subset installs. Also adds the official square logo asset for marketplace listings, raises pulumi-delegation to three Codex starter prompts, and updates the install docs. * Review fixes: version 2.0.0 + displayName, doc counts, missing skill listing Bump the combined plugin to 2.0.0 since it replaces the granular 'pulumi' plugin (also 1.0.0) with different contents, and add a displayName. Fix the README wording that implied pulumi-package- maintenance is part of the combined plugin. Correct stale skill counts (migration 4 to 5, pulumi 7 to 8) and list pulumi-debug-failed-operation in both docs; it was missing from README and AGENTS.md. * Reword combined plugin description to say what Pulumi is * Add HCL to the combined plugin language list * Extend the combined pulumi plugin to Codex with a root .codex-plugin manifest The Codex catalog still pointed the pulumi entry at ./pulumi (8 skills) while the Claude marketplace pointed it at ./ (14 skills), so the same plugin name installed different contents per ecosystem. Add a root .codex-plugin/plugin.json mirroring the combined Claude manifest and point the catalog at ./. Verified with codex-cli 0.146.0: the skills array registers all 14 skills under the pulumi namespace (checked via codex debug prompt-input). Manifest tests now cover the root manifests and accept both string and array skills fields.
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
"name": "pulumi",
|
||||
"source": {
|
||||
"source": "local",
|
||||
"path": "./pulumi"
|
||||
"path": "./"
|
||||
},
|
||||
"policy": {
|
||||
"installation": "AVAILABLE"
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
},
|
||||
{
|
||||
"name": "pulumi",
|
||||
"source": "./pulumi",
|
||||
"description": "Entry-point and specialized skills for writing and operating Pulumi infrastructure",
|
||||
"source": "./",
|
||||
"description": "Teach your agent Pulumi: infrastructure as code in TypeScript, Python, Go, C#, Java, YAML, or HCL. Skills for writing and operating cloud infrastructure, migrating from Terraform, CloudFormation, CDK, and ARM, and delegating work to Pulumi Neo, Pulumi's AI platform engineer.",
|
||||
"category": "development"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "pulumi",
|
||||
"displayName": "Pulumi",
|
||||
"version": "2.0.0",
|
||||
"description": "Teach your agent Pulumi: infrastructure as code in TypeScript, Python, Go, C#, Java, YAML, or HCL. Skills for writing and operating cloud infrastructure, migrating from Terraform, CloudFormation, CDK, and ARM, and delegating work to Pulumi Neo, Pulumi's AI platform engineer.",
|
||||
"author": {
|
||||
"name": "Pulumi",
|
||||
"url": "https://github.com/pulumi"
|
||||
},
|
||||
"homepage": "https://www.pulumi.com/docs/",
|
||||
"repository": "https://github.com/pulumi/agent-skills",
|
||||
"license": "Apache-2.0",
|
||||
"keywords": [
|
||||
"pulumi",
|
||||
"infrastructure",
|
||||
"iac",
|
||||
"terraform",
|
||||
"cloudformation",
|
||||
"cdk",
|
||||
"arm",
|
||||
"bicep",
|
||||
"migration",
|
||||
"esc",
|
||||
"secrets",
|
||||
"automation-api",
|
||||
"neo"
|
||||
],
|
||||
"skills": [
|
||||
"./pulumi/skills",
|
||||
"./migration/skills",
|
||||
"./delegation/skills"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "pulumi",
|
||||
"version": "2.0.0",
|
||||
"description": "Teach your agent Pulumi: infrastructure as code in TypeScript, Python, Go, C#, Java, YAML, or HCL. Skills for writing and operating cloud infrastructure, migrating from Terraform, CloudFormation, CDK, and ARM, and delegating work to Pulumi Neo, Pulumi's AI platform engineer.",
|
||||
"skills": [
|
||||
"./pulumi/skills",
|
||||
"./migration/skills",
|
||||
"./delegation/skills"
|
||||
],
|
||||
"author": {
|
||||
"name": "Pulumi",
|
||||
"url": "https://github.com/pulumi"
|
||||
},
|
||||
"homepage": "https://www.pulumi.com/docs/",
|
||||
"repository": "https://github.com/pulumi/agent-skills",
|
||||
"license": "Apache-2.0",
|
||||
"keywords": [
|
||||
"pulumi",
|
||||
"infrastructure",
|
||||
"iac",
|
||||
"terraform",
|
||||
"cloudformation",
|
||||
"cdk",
|
||||
"arm",
|
||||
"bicep",
|
||||
"migration",
|
||||
"esc",
|
||||
"secrets",
|
||||
"automation-api",
|
||||
"neo"
|
||||
],
|
||||
"interface": {
|
||||
"displayName": "Pulumi",
|
||||
"shortDescription": "Write, migrate, and operate Pulumi infrastructure",
|
||||
"developerName": "Pulumi",
|
||||
"category": "Coding",
|
||||
"websiteURL": "https://www.pulumi.com/docs/",
|
||||
"defaultPrompt": [
|
||||
"Use $pulumi-overview to set up an S3 bucket and a Cloudflare DNS record",
|
||||
"Use $pulumi-overview to provision a database for this app",
|
||||
"Use $pulumi-best-practices to review this Pulumi code",
|
||||
"Use $pulumi-terraform-to-pulumi to convert this Terraform module",
|
||||
"Use $pulumi-neo-handoff to hand off this Pulumi program to Neo to preview and deploy"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ Entry-point and specialized skills for writing and operating Pulumi infrastructu
|
||||
- **pulumi-component**: Guide for authoring ComponentResource classes
|
||||
- **pulumi-automation-api**: Best practices for using Pulumi Automation API
|
||||
- **pulumi-esc**: Guidance for working with Pulumi ESC (Environments, Secrets, and Configuration)
|
||||
- **pulumi-debug-failed-operation**: Debug a failed `pulumi up` or `pulumi preview` from the failure Pulumi already recorded
|
||||
- **provider-upgrade**: Safe workflows for upgrading Pulumi providers without unintended infrastructure changes
|
||||
- **package-usage**: Track which stacks across an organization use a package and at what versions
|
||||
|
||||
@@ -47,10 +48,15 @@ Skills for handing off in-progress work from coding agents to Pulumi Neo for del
|
||||
|
||||
```bash
|
||||
/plugin marketplace add pulumi/agent-skills
|
||||
/plugin install pulumi-migration
|
||||
/plugin install pulumi
|
||||
/plugin install pulumi-delegation
|
||||
/plugin install pulumi-package-maintenance
|
||||
/plugin install pulumi # all end-user skills (authoring + migration + Neo handoff)
|
||||
```
|
||||
|
||||
The `pulumi` plugin is the combined plugin defined at the repo root: `.claude-plugin/plugin.json` and `.codex-plugin/plugin.json` list `pulumi/skills/`, `migration/skills/`, and `delegation/skills/` in their `skills` fields. Granular alternatives (do not combine with `pulumi`, which already includes the first two):
|
||||
|
||||
```bash
|
||||
/plugin install pulumi-migration # migration skills only
|
||||
/plugin install pulumi-delegation # Neo handoff skill only
|
||||
/plugin install pulumi-package-maintenance # provider-repo maintenance skills
|
||||
```
|
||||
|
||||
### OpenAI Codex
|
||||
@@ -59,7 +65,7 @@ Skills for handing off in-progress work from coding agents to Pulumi Neo for del
|
||||
codex plugin marketplace add pulumi/agent-skills
|
||||
```
|
||||
|
||||
After the marketplace registers, install plugins from the Codex TUI: run `codex`, open the plugin marketplace with `/plugins`, and pick `pulumi-migration`, `pulumi`, `pulumi-delegation`, or `pulumi-package-maintenance`.
|
||||
After the marketplace registers, install plugins from the Codex TUI: run `codex`, open the plugin marketplace with `/plugins`, and pick `pulumi-migration`, `pulumi`, `pulumi-delegation`, or `pulumi-package-maintenance`. As in Claude Code, `pulumi` is the combined plugin with all end-user skills; do not combine it with `pulumi-migration` or `pulumi-delegation`.
|
||||
|
||||
### Universal (all agents)
|
||||
|
||||
@@ -72,8 +78,8 @@ npx skills add pulumi/agent-skills --skill '*'
|
||||
Or install individual plugin groups:
|
||||
|
||||
```bash
|
||||
npx skills add pulumi/agent-skills/migration --skill '*' # 4 migration skills
|
||||
npx skills add pulumi/agent-skills/pulumi --skill '*' # 7 pulumi skills (overview + specialized)
|
||||
npx skills add pulumi/agent-skills/migration --skill '*' # 5 migration skills
|
||||
npx skills add pulumi/agent-skills/pulumi --skill '*' # 8 pulumi skills (overview + specialized)
|
||||
npx skills add pulumi/agent-skills/delegation --skill '*' # 1 delegation skill
|
||||
npx skills add pulumi/agent-skills/package-maintenance --skill '*' # 2 package-maintenance skills
|
||||
```
|
||||
@@ -145,7 +151,7 @@ The test loads every `use_cases.yaml` across the tree and asserts that each quer
|
||||
|
||||
### Skill quality review (`test_skill_quality.py`)
|
||||
|
||||
An LLM judge reads each `SKILL.md` and checks it against a quality rubric (description clarity and trigger precision, lean body, explains WHY not just what, progressive disclosure). The test fails on HIGH-severity findings and prints all issues — including medium and low — for visibility.
|
||||
An LLM judge reads each `SKILL.md` and checks it against a quality rubric (description clarity and trigger precision, lean body, explains WHY not just what, progressive disclosure). The test fails on HIGH-severity findings and prints all issues (including medium and low) for visibility.
|
||||
|
||||
### Running locally
|
||||
|
||||
@@ -176,7 +182,7 @@ uv run pytest tests/ -v
|
||||
4. Add `use_cases.yaml` with representative trigger queries (see [Testing](#testing) above)
|
||||
5. Update this AGENTS.md file to list the new skill in the appropriate plugin section
|
||||
6. Update [README.md](README.md) to add the skill to the skills table
|
||||
7. Bump the containing plugin's patch version in both `<plugin>/.claude-plugin/plugin.json` and `<plugin>/.codex-plugin/plugin.json`
|
||||
7. Bump the containing plugin's patch version in both `<plugin>/.claude-plugin/plugin.json` and `<plugin>/.codex-plugin/plugin.json`. For skills in an end-user group (`pulumi/`, `migration/`, `delegation/`), also bump the root combined manifests `.claude-plugin/plugin.json` and `.codex-plugin/plugin.json`, which ship the same skill
|
||||
8. Submit a pull request
|
||||
|
||||
The skill will automatically be included in its plugin group, but installed plugin users need a plugin version bump to receive changed plugin contents. Any change under an existing plugin directory that affects shipped skills, references, agents, hooks, MCP config, or install-surface metadata must bump that plugin's version in both ecosystem manifests. Use a patch bump for skill-content and routing changes unless the change is intentionally breaking or feature-sized.
|
||||
@@ -191,6 +197,8 @@ Examples:
|
||||
|
||||
Each plugin group ships a manifest for both Claude Code and OpenAI Codex. The skill content is shared; only the per-ecosystem manifest files differ.
|
||||
|
||||
If the new group is end-user facing (not maintainer tooling), also add its `skills/` directory to the `skills` lists in both root combined plugin manifests, [.claude-plugin/plugin.json](.claude-plugin/plugin.json) and [.codex-plugin/plugin.json](.codex-plugin/plugin.json), so installing `pulumi` picks it up in both ecosystems.
|
||||
|
||||
1. Create the plugin directory structure:
|
||||
```
|
||||
<plugin-name>/
|
||||
|
||||
@@ -49,6 +49,7 @@ Entry-point and specialized skills for writing and operating Pulumi infrastructu
|
||||
| [pulumi-component](pulumi/skills/pulumi-component) | Guide for authoring ComponentResource classes |
|
||||
| [pulumi-automation-api](pulumi/skills/pulumi-automation-api) | Best practices for using Pulumi Automation API |
|
||||
| [pulumi-esc](pulumi/skills/pulumi-esc) | Guidance for working with Pulumi ESC (Environments, Secrets, and Configuration) |
|
||||
| [pulumi-debug-failed-operation](pulumi/skills/pulumi-debug-failed-operation) | Debug a failed `pulumi up` or `pulumi preview` from the failure Pulumi already recorded |
|
||||
| [provider-upgrade](pulumi/skills/provider-upgrade) | Safe workflows for upgrading Pulumi providers without unintended infrastructure changes |
|
||||
| [package-usage](pulumi/skills/package-usage) | Track which stacks across an organization use a package and at what versions |
|
||||
|
||||
@@ -75,15 +76,20 @@ Hand off in-progress work from coding agents to Pulumi Neo:
|
||||
|
||||
```bash
|
||||
/plugin marketplace add pulumi/agent-skills
|
||||
/plugin install pulumi-migration # Install migration skills
|
||||
/plugin install pulumi # Install Pulumi skills (overview + specialized)
|
||||
/plugin install pulumi-delegation # Install delegation skills (Neo handoff)
|
||||
/plugin install pulumi-package-maintenance # Install provider-repo maintenance skills
|
||||
/plugin install pulumi # All end-user skills: authoring, migration, and Neo handoff
|
||||
```
|
||||
|
||||
The `pulumi` plugin bundles the authoring, migration, and delegation skill groups in one install. Prefer a subset? Install `pulumi-migration` or `pulumi-delegation` instead (not alongside `pulumi`, which already includes both). `pulumi-package-maintenance` is separate: it targets provider authors and combines fine with any of the others.
|
||||
|
||||
```bash
|
||||
/plugin install pulumi-migration # Migration skills only
|
||||
/plugin install pulumi-delegation # Neo handoff skill only
|
||||
/plugin install pulumi-package-maintenance # Provider-repo maintenance skills (for provider authors)
|
||||
```
|
||||
|
||||
#### Declarative install via `settings.json`
|
||||
|
||||
To register the marketplace and enable plugins automatically (for a team or CI), add this to `.claude/settings.json`. The marketplace key **must** be `pulumi-agent-skills` — it has to match the `name` field in this repo's [`.claude-plugin/marketplace.json`](.claude-plugin/marketplace.json), and the same name is used as the `@<marketplace>` suffix in `enabledPlugins`:
|
||||
To register the marketplace and enable plugins automatically (for a team or CI), add this to `.claude/settings.json`. The marketplace key **must** be `pulumi-agent-skills`: it has to match the `name` field in this repo's [`.claude-plugin/marketplace.json`](.claude-plugin/marketplace.json), and the same name is used as the `@<marketplace>` suffix in `enabledPlugins`:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -93,14 +99,13 @@ To register the marketplace and enable plugins automatically (for a team or CI),
|
||||
}
|
||||
},
|
||||
"enabledPlugins": {
|
||||
"pulumi-migration@pulumi-agent-skills": true,
|
||||
"pulumi@pulumi-agent-skills": true,
|
||||
"pulumi-delegation@pulumi-agent-skills": true,
|
||||
"pulumi-package-maintenance@pulumi-agent-skills": true
|
||||
"pulumi@pulumi-agent-skills": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `pulumi` plugin covers authoring, migration, and delegation. Swap in `pulumi-migration` or `pulumi-delegation` for a subset, or add `pulumi-package-maintenance` for provider-repo maintenance.
|
||||
|
||||
If you name the marketplace anything else (e.g. `pulumi-skills`), the plugins fail to resolve with `Plugin '…' not found in marketplace '…'`.
|
||||
|
||||
### OpenAI Codex
|
||||
@@ -109,7 +114,7 @@ If you name the marketplace anything else (e.g. `pulumi-skills`), the plugins fa
|
||||
codex plugin marketplace add pulumi/agent-skills
|
||||
```
|
||||
|
||||
Once the marketplace is registered, install plugins from the Codex TUI: run `codex`, open the plugin marketplace with `/plugins`, and pick `pulumi-migration`, `pulumi`, `pulumi-delegation`, or `pulumi-package-maintenance`.
|
||||
Once the marketplace is registered, install plugins from the Codex TUI: run `codex`, open the plugin marketplace with `/plugins`, and pick `pulumi-migration`, `pulumi`, `pulumi-delegation`, or `pulumi-package-maintenance`. As in Claude Code, `pulumi` is the combined plugin with all end-user skills; do not combine it with `pulumi-migration` or `pulumi-delegation`.
|
||||
|
||||
### Universal (all agents)
|
||||
|
||||
@@ -123,7 +128,7 @@ Or install individual plugin groups:
|
||||
|
||||
```bash
|
||||
npx skills add pulumi/agent-skills/migration --skill '*' # 5 migration skills
|
||||
npx skills add pulumi/agent-skills/pulumi --skill '*' # 7 pulumi skills (overview + specialized)
|
||||
npx skills add pulumi/agent-skills/pulumi --skill '*' # 8 pulumi skills (overview + specialized)
|
||||
npx skills add pulumi/agent-skills/delegation --skill '*' # 1 delegation skill
|
||||
npx skills add pulumi/agent-skills/package-maintenance --skill '*' # 2 package-maintenance skills
|
||||
```
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
@@ -25,7 +25,9 @@
|
||||
"category": "Coding",
|
||||
"websiteURL": "https://www.pulumi.com/docs/",
|
||||
"defaultPrompt": [
|
||||
"Use $pulumi-neo-handoff to package the current conversation and launch a Pulumi Neo task"
|
||||
"Use $pulumi-neo-handoff to package the current conversation and launch a Pulumi Neo task",
|
||||
"Use $pulumi-neo-handoff to hand off this Pulumi program to Neo to preview and deploy",
|
||||
"Use $pulumi-neo-handoff to continue this infrastructure debugging in Pulumi Neo"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
+12
-6
@@ -20,11 +20,15 @@ CLAUDE_REQUIRED_FIELDS = ("name", "version", "description")
|
||||
|
||||
|
||||
def _codex_manifests() -> list[Path]:
|
||||
return sorted(REPO_ROOT.glob("*/.codex-plugin/plugin.json"))
|
||||
return sorted(REPO_ROOT.glob(".codex-plugin/plugin.json")) + sorted(
|
||||
REPO_ROOT.glob("*/.codex-plugin/plugin.json")
|
||||
)
|
||||
|
||||
|
||||
def _claude_manifests() -> list[Path]:
|
||||
return sorted(REPO_ROOT.glob("*/.claude-plugin/plugin.json"))
|
||||
return sorted(REPO_ROOT.glob(".claude-plugin/plugin.json")) + sorted(
|
||||
REPO_ROOT.glob("*/.claude-plugin/plugin.json")
|
||||
)
|
||||
|
||||
|
||||
def _rel(path: Path) -> str:
|
||||
@@ -36,10 +40,12 @@ def test_codex_plugin_manifest(manifest: Path) -> None:
|
||||
data = json.loads(manifest.read_text())
|
||||
for field in CODEX_REQUIRED_FIELDS:
|
||||
assert field in data, f"{_rel(manifest)}: missing field `{field}`"
|
||||
skills_path = (manifest.parent.parent / data["skills"].lstrip("./")).resolve()
|
||||
assert skills_path.is_dir(), (
|
||||
f"{_rel(manifest)}: skills path `{data['skills']}` does not resolve to a directory"
|
||||
)
|
||||
skills = data["skills"]
|
||||
for skills_entry in skills if isinstance(skills, list) else [skills]:
|
||||
skills_path = (manifest.parent.parent / skills_entry.lstrip("./")).resolve()
|
||||
assert skills_path.is_dir(), (
|
||||
f"{_rel(manifest)}: skills path `{skills_entry}` does not resolve to a directory"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("manifest", _claude_manifests(), ids=_rel)
|
||||
|
||||
Reference in New Issue
Block a user