mirror of
https://github.com/obra/superpowers.git
synced 2026-06-26 04:29:04 +08:00
Compare commits
4 Commits
v6.0.3
...
prune-harn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1eebca388e | ||
|
|
321c8cd24c | ||
|
|
bfa3e4137a | ||
|
|
a17aaaef3a |
20
.agents/plugins/marketplace.json
Normal file
20
.agents/plugins/marketplace.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "superpowers-dev",
|
||||||
|
"interface": {
|
||||||
|
"displayName": "Superpowers Dev"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "superpowers",
|
||||||
|
"source": {
|
||||||
|
"source": "url",
|
||||||
|
"url": "./"
|
||||||
|
},
|
||||||
|
"policy": {
|
||||||
|
"installation": "AVAILABLE",
|
||||||
|
"authentication": "ON_INSTALL"
|
||||||
|
},
|
||||||
|
"category": "Developer Tools"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"hooks": {
|
"hooks": {
|
||||||
"SessionStart": [
|
"SessionStart": [
|
||||||
{
|
{
|
||||||
"matcher": "startup|resume|clear",
|
"matcher": "startup|clear|compact",
|
||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
|
|||||||
@@ -4,85 +4,12 @@ Skills speak in actions ("dispatch a subagent", "create a todo", "read a file").
|
|||||||
|
|
||||||
| Action skills request | Antigravity CLI equivalent |
|
| Action skills request | Antigravity CLI equivalent |
|
||||||
|----------------------|----------------------|
|
|----------------------|----------------------|
|
||||||
| Read a file | `view_file` |
|
|
||||||
| Create a new file | `write_to_file` |
|
|
||||||
| Edit a file | `replace_file_content` |
|
|
||||||
| Edit a file in several places at once | `multi_replace_file_content` |
|
|
||||||
| Run a shell command | `run_command` |
|
|
||||||
| Search file contents | `grep_search` |
|
|
||||||
| Find files by name / list a directory | `list_dir` (no dedicated glob tool — combine `list_dir` with `grep_search`) |
|
|
||||||
| Fetch a URL | `read_url_content` |
|
|
||||||
| Search the web | `search_web` |
|
|
||||||
| Pose a structured question to your human partner | `ask_question` |
|
|
||||||
| Dispatch a subagent (`Subagent (general-purpose):` template) | `invoke_subagent` with a built-in `TypeName` — `self` for full-capability work, `research` for read-only (see [Subagent support](#subagent-support)) |
|
| Dispatch a subagent (`Subagent (general-purpose):` template) | `invoke_subagent` with a built-in `TypeName` — `self` for full-capability work, `research` for read-only (see [Subagent support](#subagent-support)) |
|
||||||
| Multiple parallel dispatches | Multiple entries in one `invoke_subagent` call's `Subagents` array |
|
|
||||||
| Task tracking ("create a todo", "mark complete") | a **task artifact** — `write_to_file` with `IsArtifact: true` and `ArtifactType: "task"` (see [Task tracking](#task-tracking)). **Not** `manage_task`, which manages background processes. |
|
| Task tracking ("create a todo", "mark complete") | a **task artifact** — `write_to_file` with `IsArtifact: true` and `ArtifactType: "task"` (see [Task tracking](#task-tracking)). **Not** `manage_task`, which manages background processes. |
|
||||||
|
|
||||||
## Invoking a skill — read its `SKILL.md`
|
|
||||||
|
|
||||||
Antigravity surfaces every installed skill's `name` + `description` to you at the
|
|
||||||
start of each session, but it has **no `Skill`/`activate_skill` tool**. To load a
|
|
||||||
skill, **read its `SKILL.md` with `view_file`, setting `IsSkillFile: true`** when
|
|
||||||
the skill applies — e.g. `view_file` on
|
|
||||||
`.../plugins/superpowers/skills/<skill-name>/SKILL.md` with `IsSkillFile: true`.
|
|
||||||
(`IsSkillFile` is agy's own signal that you're reading a file to *execute its
|
|
||||||
instructions*, not to edit or preview it — set it whenever you load a skill.)
|
|
||||||
|
|
||||||
This is the blessed skill-loading mechanism on this harness. The general rule
|
|
||||||
"never read skill files manually" means "don't bypass your platform's
|
|
||||||
skill-loading mechanism" — and on Antigravity, reading `SKILL.md` *is* that
|
|
||||||
mechanism. Reading it honors the rule rather than breaking it.
|
|
||||||
|
|
||||||
You already know which skills exist and what they're for: their names and
|
|
||||||
descriptions are in front of you at session start. When a description matches
|
|
||||||
what you're about to do, read that skill's `SKILL.md` before acting.
|
|
||||||
|
|
||||||
## Subagent support
|
|
||||||
|
|
||||||
Antigravity dispatches subagents with `invoke_subagent`, passing each one a
|
|
||||||
`TypeName` in the `Subagents` array. Two `TypeName`s are **built in** — use them
|
|
||||||
directly, no `define_subagent` needed:
|
|
||||||
|
|
||||||
- **`self`** — a full clone of you, with every tool you have (including
|
|
||||||
`write_to_file`/`replace_file_content`/`run_command`). The safe default for
|
|
||||||
general-purpose work: implementing, fixing, anything that edits files or runs
|
|
||||||
commands.
|
|
||||||
- **`research`** — read-only (file reading, `grep_search`, web/URL fetch; no write
|
|
||||||
or command access). Use it when you specifically want a subagent that can't make
|
|
||||||
changes — investigation and read-only review.
|
|
||||||
|
|
||||||
Call `define_subagent` only for a custom system prompt or capability mix: set
|
|
||||||
`enable_write_tools: true` to grant file edits **and** `run_command`,
|
|
||||||
`enable_subagent_tools` for nested dispatch, `enable_mcp_tools` for MCP. Then
|
|
||||||
invoke it by the name you gave it. (`manage_subagents` lists/kills running
|
|
||||||
subagents.)
|
|
||||||
|
|
||||||
Skills dispatch with `Subagent (general-purpose):` and either reference a
|
|
||||||
prompt-template file (e.g. `superpowers:subagent-driven-development`'s
|
|
||||||
`./implementer-prompt.md`) or supply an inline prompt. On Antigravity:
|
|
||||||
|
|
||||||
| Skill dispatch form | Antigravity equivalent |
|
|
||||||
|---------------------|----------------------|
|
|
||||||
| An implementer-style `*-prompt.md` template (writes code, runs tests) | Fill the template, then `invoke_subagent` with `TypeName: "self"` and the filled prompt |
|
|
||||||
| A read-only reviewer template (`task-reviewer`, `code-reviewer`, `requesting-code-review`'s `./code-reviewer.md`) | `invoke_subagent` with `TypeName: "research"` and the filled review template |
|
|
||||||
| Inline prompt (no template referenced) | `invoke_subagent` with `TypeName: "self"` (or `"research"` if the task only reads) and your inline prompt |
|
|
||||||
|
|
||||||
### Prompt filling
|
|
||||||
|
|
||||||
Skills provide prompt templates with placeholders like `{WHAT_WAS_IMPLEMENTED}` or
|
|
||||||
`[FULL TEXT of task]`. Fill all placeholders before passing the complete prompt to
|
|
||||||
`invoke_subagent`. The prompt template itself contains the agent's role, review
|
|
||||||
criteria, and expected output format — the subagent will follow it.
|
|
||||||
|
|
||||||
### Parallel dispatch
|
|
||||||
|
|
||||||
Put multiple entries in a single `invoke_subagent` call's `Subagents` array to run
|
|
||||||
independent subagent work in parallel. Keep dependent tasks sequential, but do not
|
|
||||||
serialize independent subagent tasks just to preserve a simpler history.
|
|
||||||
|
|
||||||
## Task tracking
|
## Task tracking
|
||||||
|
|
||||||
Antigravity has **no todo / `TodoWrite` tool** (`manage_task` manages background
|
Antigravity has **no todo tool** (`manage_task` manages background
|
||||||
processes — `list`/`kill`/`status`/`send_input` — it is *not* a checklist). When a
|
processes — `list`/`kill`/`status`/`send_input` — it is *not* a checklist). When a
|
||||||
skill says to create a todo list or track tasks, maintain a **task artifact**: a
|
skill says to create a todo list or track tasks, maintain a **task artifact**: a
|
||||||
markdown checklist saved with `write_to_file` (`IsArtifact: true`,
|
markdown checklist saved with `write_to_file` (`IsArtifact: true`,
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
# Claude Code Tool Mapping
|
|
||||||
|
|
||||||
Skills speak in actions ("dispatch a subagent", "create a todo", "read a file"). On Claude Code these resolve to the tools below.
|
|
||||||
|
|
||||||
## Tools
|
|
||||||
|
|
||||||
| Action skills request | Claude Code tool |
|
|
||||||
|----------------------|------------------|
|
|
||||||
| Read a file | `Read` |
|
|
||||||
| Create a new file | `Write` |
|
|
||||||
| Edit a file | `Edit` |
|
|
||||||
| Run a shell command | `Bash` |
|
|
||||||
| Search file contents | `Grep` |
|
|
||||||
| Find files by name | `Glob` |
|
|
||||||
| Fetch a URL | `WebFetch` |
|
|
||||||
| Search the web | `WebSearch` |
|
|
||||||
| Invoke a skill | `Skill` |
|
|
||||||
| Dispatch a subagent (`Subagent (general-purpose):` template) | `Agent` (older releases named this `Task`) |
|
|
||||||
| Multiple parallel dispatches | Multiple `Agent` calls in one response |
|
|
||||||
| Task tracking ("create a todo", "mark complete") | `TaskCreate`, `TaskUpdate`, `TaskList`, `TaskGet`; `TodoWrite` in `claude -p` / Agent SDK unless `CLAUDE_CODE_ENABLE_TASKS=1` is set |
|
|
||||||
| Background-process / subagent lifecycle (read output, cancel) | `TaskOutput`, `TaskStop` — these are distinct from the todo tools above and apply to running shells, agents, and remote sessions |
|
|
||||||
|
|
||||||
## Instructions file
|
|
||||||
|
|
||||||
When a skill mentions "your instructions file", on Claude Code this is **`CLAUDE.md`**. Claude Code walks up the directory tree from the current working directory and concatenates every `CLAUDE.md` and `CLAUDE.local.md` it finds along the way. Standard locations:
|
|
||||||
|
|
||||||
| Scope | Location |
|
|
||||||
|-------|----------|
|
|
||||||
| Project (team-shared) | `./CLAUDE.md` or `./.claude/CLAUDE.md` |
|
|
||||||
| User global | `~/.claude/CLAUDE.md` |
|
|
||||||
| Local-private (gitignored) | `./CLAUDE.local.md` |
|
|
||||||
| Managed policy (org-wide) | `/Library/Application Support/ClaudeCode/CLAUDE.md` (macOS), `/etc/claude-code/CLAUDE.md` (Linux/WSL), `C:\Program Files\ClaudeCode\CLAUDE.md` (Windows) |
|
|
||||||
|
|
||||||
CLAUDE.md files can pull in additional content with `@path/to/file` imports (relative or absolute, max five hops deep). Subdirectory `CLAUDE.md` files are also discovered automatically and loaded on-demand when Claude Code reads files in those subdirectories.
|
|
||||||
|
|
||||||
Claude Code does **not** read `AGENTS.md` directly. If a project already maintains `AGENTS.md` for other agents, import it from `CLAUDE.md` so both runtimes share the same instructions:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
@AGENTS.md
|
|
||||||
|
|
||||||
## Claude Code
|
|
||||||
|
|
||||||
(Claude-Code-specific instructions go here.)
|
|
||||||
```
|
|
||||||
|
|
||||||
For path-scoped rules and larger-project organization, see `.claude/rules/` (rules can be scoped to specific files via `paths` frontmatter and load on demand).
|
|
||||||
|
|
||||||
## Personal skills directory
|
|
||||||
|
|
||||||
User-level skills live at **`~/.claude/skills/`**. Each skill is a subdirectory containing a `SKILL.md` (with `name` and `description` frontmatter) plus any supporting files. Claude Code does not currently recognize the cross-runtime `~/.agents/skills/` path that Codex, Copilot CLI, and Gemini CLI read; if you're relying on cross-runtime support in the future, verify against the [official skills docs](https://code.claude.com/docs/en/skills).
|
|
||||||
@@ -1,31 +1,3 @@
|
|||||||
# Codex Tool Mapping
|
|
||||||
|
|
||||||
Skills speak in actions ("dispatch a subagent", "create a todo", "read a file"). On Codex these resolve to the tools below.
|
|
||||||
|
|
||||||
| Action skills request | Codex equivalent |
|
|
||||||
|----------------------|------------------|
|
|
||||||
| Read a file | `shell` (e.g., `cat`, `head`, `tail`) — Codex reads files via shell |
|
|
||||||
| Create / edit / delete a file | `apply_patch` (structured diff for create, update, delete) |
|
|
||||||
| Run a shell command | `shell` |
|
|
||||||
| Search file contents | `shell` (e.g., `grep`, `rg`) |
|
|
||||||
| Find files by name | `shell` (e.g., `find`, `ls`) |
|
|
||||||
| Fetch a URL | `shell` with `curl` / `wget` — Codex has no native fetch tool |
|
|
||||||
| Search the web | `web_search` (enabled by default; configurable in `config.toml` via the top-level `web_search` setting — `live`, `cached`, or `disabled`) |
|
|
||||||
| Invoke a skill | Skills load natively — just follow the instructions |
|
|
||||||
| Dispatch a subagent (`Subagent (general-purpose):` template) | `spawn_agent` (see [Subagent dispatch requires multi-agent support](#subagent-dispatch-requires-multi-agent-support)) |
|
|
||||||
| Multiple parallel dispatches | Multiple `spawn_agent` calls in one response |
|
|
||||||
| Wait for subagent result | `wait_agent` |
|
|
||||||
| Free up subagent slot when done | `close_agent` |
|
|
||||||
| Task tracking ("create a todo", "mark complete") | `update_plan` |
|
|
||||||
|
|
||||||
## Instructions file
|
|
||||||
|
|
||||||
When a skill mentions "your instructions file", on Codex this is **`AGENTS.md`** at the project root. Codex also reads `~/.codex/AGENTS.md` for global context, and an `AGENTS.override.md` (in the project tree or `~/.codex/`) takes precedence when present. Codex walks from the project root down to the current working directory, concatenating `AGENTS.md` files it finds along the way, up to `project_doc_max_bytes` (32 KiB by default).
|
|
||||||
|
|
||||||
## Personal skills directory
|
|
||||||
|
|
||||||
User-level skills live at **`$CODEX_HOME/skills/`** (default `~/.codex/skills/`). Codex also reads the cross-runtime path **`~/.agents/skills/`** (shared with Copilot CLI and Gemini CLI). When both directories exist at the same scope, Codex loads them both as separate skill catalogs — Codex's docs don't currently document a precedence between them. Each skill is a subdirectory containing a `SKILL.md` (with `name` and `description` frontmatter).
|
|
||||||
|
|
||||||
## Subagent dispatch requires multi-agent support
|
## Subagent dispatch requires multi-agent support
|
||||||
|
|
||||||
Add to your Codex config (`~/.codex/config.toml`):
|
Add to your Codex config (`~/.codex/config.toml`):
|
||||||
@@ -35,12 +7,7 @@ Add to your Codex config (`~/.codex/config.toml`):
|
|||||||
multi_agent = true
|
multi_agent = true
|
||||||
```
|
```
|
||||||
|
|
||||||
This enables `spawn_agent`, `wait_agent`, and `close_agent` for skills like `dispatching-parallel-agents` and `subagent-driven-development`.
|
This enables `spawn_agent`, `wait_agent`, and `close_agent` for skills like `dispatching-parallel-agents` and `subagent-driven-development`. When using subagent-driven-development, you should always close implementer and reviewer subagents when they have finished all their work.
|
||||||
|
|
||||||
Legacy note: Codex builds before `rust-v0.115.0` exposed spawned-agent
|
|
||||||
waiting as `wait`. Current Codex uses `wait_agent` for spawned agents. The
|
|
||||||
`wait` name now belongs to code-mode `exec/wait`, which resumes a yielded exec
|
|
||||||
cell by `cell_id`; it is not the spawned-agent result tool.
|
|
||||||
|
|
||||||
## Environment Detection
|
## Environment Detection
|
||||||
|
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
# Copilot CLI Tool Mapping
|
|
||||||
|
|
||||||
Skills speak in actions ("dispatch a subagent", "create a todo", "read a file"). On Copilot CLI these resolve to the tools below.
|
|
||||||
|
|
||||||
| Action skills request | Copilot CLI equivalent |
|
|
||||||
|----------------------|----------------------|
|
|
||||||
| Read a file | `view` |
|
|
||||||
| Create / edit / delete a file | `apply_patch` (Copilot CLI has no separate create/edit/write tools) |
|
|
||||||
| Run a shell command | `bash` |
|
|
||||||
| Search file contents | `rg` (ripgrep; Copilot CLI does not expose a `grep` tool) |
|
|
||||||
| Find files by name | `glob` |
|
|
||||||
| Fetch a URL | `web_fetch` |
|
|
||||||
| Search the web | `web_search` |
|
|
||||||
| Invoke a skill | `skill` |
|
|
||||||
| Dispatch a subagent (`Subagent (general-purpose):` template) | `task` with `agent_type: "general-purpose"` (other accepted types: `explore`, `task`, `code-review`, `research`, `configure-copilot`) |
|
|
||||||
| Multiple parallel dispatches | Multiple `task` calls in one response |
|
|
||||||
| Subagent status/output/control | `read_agent`, `list_agents`, `write_agent` |
|
|
||||||
| Task tracking ("create a todo", "mark complete") | `update_todo` |
|
|
||||||
| Enter / exit plan mode | No equivalent — stay in the main session |
|
|
||||||
|
|
||||||
## Instructions file
|
|
||||||
|
|
||||||
When a skill mentions "your instructions file", on Copilot CLI this is **`AGENTS.md`** at the repository root. If both `AGENTS.md` and `.github/copilot-instructions.md` are present, Copilot reads both.
|
|
||||||
|
|
||||||
## Personal skills directory
|
|
||||||
|
|
||||||
User-level skills live at **`~/.copilot/skills/`**. Copilot CLI also recognizes the cross-runtime alias **`~/.agents/skills/`**, which is shared with Codex and Gemini CLI. Each skill is a subdirectory containing a `SKILL.md` (with `name` and `description` frontmatter).
|
|
||||||
|
|
||||||
## Async shell sessions
|
|
||||||
|
|
||||||
Copilot CLI supports persistent async shell sessions:
|
|
||||||
|
|
||||||
| Tool | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| `bash` with `mode: "async"` (and optionally `detach: true`) | Start a long-running command in the background; returns a `shellId` |
|
|
||||||
| `write_bash` | Send input to a running async session |
|
|
||||||
| `read_bash` | Read output from an async session |
|
|
||||||
| `stop_bash` | Terminate an async session |
|
|
||||||
| `list_bash` | List all active shell sessions |
|
|
||||||
|
|
||||||
## Additional Copilot CLI tools
|
|
||||||
|
|
||||||
| Tool | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| `store_memory` | Persist facts about the codebase for future sessions |
|
|
||||||
| `report_intent` | Update the UI status line with current intent |
|
|
||||||
| `sql` | Query the session's SQLite database (todos, metadata) |
|
|
||||||
| `fetch_copilot_cli_documentation` | Look up Copilot CLI documentation |
|
|
||||||
| GitHub MCP tools (`github-mcp-server-*`) | Native GitHub API access (issues, PRs, code search) |
|
|
||||||
@@ -4,21 +4,9 @@ Skills speak in actions ("dispatch a subagent", "create a todo", "read a file").
|
|||||||
|
|
||||||
| Action skills request | Pi equivalent |
|
| Action skills request | Pi equivalent |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| Invoke a skill | Pi native skills: load the relevant `SKILL.md` with `read`, or let the human use `/skill:name` |
|
|
||||||
| Read a file | `read` |
|
|
||||||
| Create a file | `write` |
|
|
||||||
| Edit a file | `edit` |
|
|
||||||
| Run a shell command | `bash` |
|
|
||||||
| Search file contents | `grep` when active; otherwise `bash` with `rg`/`grep` |
|
|
||||||
| Find files by name | `find` or `bash` with shell globs |
|
|
||||||
| List files and subdirectories | `ls` when active; otherwise `bash` with `ls` |
|
|
||||||
| Dispatch a subagent (`Subagent (general-purpose):` template) | Use an installed subagent tool such as `subagent` from `pi-subagents` if available |
|
| Dispatch a subagent (`Subagent (general-purpose):` template) | Use an installed subagent tool such as `subagent` from `pi-subagents` if available |
|
||||||
| Task tracking ("create a todo", "mark complete") | Use an installed todo/task tool if available, otherwise track tasks in the plan or `TODO.md` |
|
| Task tracking ("create a todo", "mark complete") | Use an installed todo/task tool if available, otherwise track tasks in the plan or `TODO.md` |
|
||||||
|
|
||||||
## Skills
|
|
||||||
|
|
||||||
Pi discovers skills from configured skill directories and installed Pi packages. A Superpowers Pi package should expose `skills/` through its `pi.skills` manifest entry. Pi does not expose Claude Code's `Skill` tool, but the agent should still follow the Superpowers rule: when a skill applies, load and follow it before responding.
|
|
||||||
|
|
||||||
## Subagents
|
## Subagents
|
||||||
|
|
||||||
Pi core does not ship a standard subagent tool. The `pi-subagents` package is a strong optional companion and provides a `subagent` tool with single-agent, chain, parallel, async, forked-context, and resume/status workflows. If no subagent tool is available, do not fabricate `Task` calls; execute sequentially in the current session or explain that the optional subagent capability is not installed.
|
Pi core does not ship a standard subagent tool. The `pi-subagents` package is a strong optional companion and provides a `subagent` tool with single-agent, chain, parallel, async, forked-context, and resume/status workflows. If no subagent tool is available, do not fabricate `Task` calls; execute sequentially in the current session or explain that the optional subagent capability is not installed.
|
||||||
|
|||||||
61
tests/codex/test-marketplace-manifest.sh
Executable file
61
tests/codex/test-marketplace-manifest.sh
Executable file
@@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
MARKETPLACE="$REPO_ROOT/.agents/plugins/marketplace.json"
|
||||||
|
|
||||||
|
python3 - "$MARKETPLACE" "$REPO_ROOT" <<'PY'
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
marketplace_path = Path(sys.argv[1])
|
||||||
|
repo_root = Path(sys.argv[2])
|
||||||
|
|
||||||
|
if not marketplace_path.exists():
|
||||||
|
raise AssertionError(".agents/plugins/marketplace.json must exist")
|
||||||
|
|
||||||
|
marketplace = json.loads(marketplace_path.read_text(encoding="utf-8"))
|
||||||
|
|
||||||
|
def assert_equal(actual, expected, label):
|
||||||
|
if actual != expected:
|
||||||
|
raise AssertionError(f"{label}: expected {expected!r}, got {actual!r}")
|
||||||
|
|
||||||
|
assert_equal(marketplace.get("name"), "superpowers-dev", "marketplace name")
|
||||||
|
assert_equal(
|
||||||
|
marketplace.get("interface", {}).get("displayName"),
|
||||||
|
"Superpowers Dev",
|
||||||
|
"marketplace display name",
|
||||||
|
)
|
||||||
|
|
||||||
|
plugins = marketplace.get("plugins")
|
||||||
|
if not isinstance(plugins, list):
|
||||||
|
raise AssertionError("plugins must be a list")
|
||||||
|
|
||||||
|
matching_plugins = [plugin for plugin in plugins if plugin.get("name") == "superpowers"]
|
||||||
|
assert_equal(len(matching_plugins), 1, "superpowers plugin entry count")
|
||||||
|
|
||||||
|
plugin = matching_plugins[0]
|
||||||
|
assert_equal(plugin.get("source"), {"source": "url", "url": "./"}, "plugin source")
|
||||||
|
assert_equal(
|
||||||
|
plugin.get("policy"),
|
||||||
|
{"installation": "AVAILABLE", "authentication": "ON_INSTALL"},
|
||||||
|
"plugin policy",
|
||||||
|
)
|
||||||
|
assert_equal(plugin.get("category"), "Developer Tools", "plugin category")
|
||||||
|
|
||||||
|
plugin_manifest = repo_root / ".codex-plugin" / "plugin.json"
|
||||||
|
if not plugin_manifest.exists():
|
||||||
|
raise AssertionError(".codex-plugin/plugin.json must exist")
|
||||||
|
|
||||||
|
manifest = json.loads(plugin_manifest.read_text(encoding="utf-8"))
|
||||||
|
assert_equal(manifest.get("name"), plugin.get("name"), "plugin manifest name")
|
||||||
|
assert_equal(
|
||||||
|
manifest.get("hooks"),
|
||||||
|
"./hooks/hooks-codex.json",
|
||||||
|
"Codex hooks manifest",
|
||||||
|
)
|
||||||
|
|
||||||
|
print("Codex marketplace manifest looks good")
|
||||||
|
PY
|
||||||
Reference in New Issue
Block a user