mirror of
https://github.com/obra/superpowers.git
synced 2026-06-25 03:59:05 +08:00
Compare commits
10 Commits
fix/render
...
codex/issu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc20cdaa55 | ||
|
|
bfa3e4137a | ||
|
|
a17aaaef3a | ||
|
|
896224c4b1 | ||
|
|
549dee6f64 | ||
|
|
4f9bd3131e | ||
|
|
caf14aac66 | ||
|
|
667b2c4a2e | ||
|
|
93b8444b51 | ||
|
|
207a12b203 |
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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
{
|
{
|
||||||
"name": "superpowers",
|
"name": "superpowers",
|
||||||
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
|
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
|
||||||
"version": "6.0.2",
|
"version": "6.0.3",
|
||||||
"source": "./",
|
"source": "./",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Jesse Vincent",
|
"name": "Jesse Vincent",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "superpowers",
|
"name": "superpowers",
|
||||||
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
|
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
|
||||||
"version": "6.0.2",
|
"version": "6.0.3",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Jesse Vincent",
|
"name": "Jesse Vincent",
|
||||||
"email": "jesse@fsck.com"
|
"email": "jesse@fsck.com"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "superpowers",
|
"name": "superpowers",
|
||||||
"version": "6.0.2",
|
"version": "6.0.3",
|
||||||
"description": "An agentic skills framework & software development methodology that works: planning, TDD, debugging, and collaboration workflows.",
|
"description": "An agentic skills framework & software development methodology that works: planning, TDD, debugging, and collaboration workflows.",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Jesse Vincent",
|
"name": "Jesse Vincent",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "superpowers",
|
"name": "superpowers",
|
||||||
"displayName": "Superpowers",
|
"displayName": "Superpowers",
|
||||||
"description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques",
|
"description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques",
|
||||||
"version": "6.0.2",
|
"version": "6.0.3",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Jesse Vincent",
|
"name": "Jesse Vincent",
|
||||||
"email": "jesse@fsck.com"
|
"email": "jesse@fsck.com"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "superpowers",
|
"name": "superpowers",
|
||||||
"version": "6.0.2",
|
"version": "6.0.3",
|
||||||
"description": "An agentic skills framework and software development methodology.",
|
"description": "An agentic skills framework and software development methodology.",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Jesse Vincent",
|
"name": "Jesse Vincent",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "superpowers",
|
"name": "superpowers",
|
||||||
"description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques",
|
"description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques",
|
||||||
"version": "6.0.2",
|
"version": "6.0.3",
|
||||||
"contextFileName": "GEMINI.md"
|
"contextFileName": "GEMINI.md"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "\"${PLUGIN_ROOT}/hooks/run-hook.cmd\" session-start-codex",
|
"command": "\"${PLUGIN_ROOT}/hooks/run-hook.cmd\" session-start-codex",
|
||||||
|
"commandWindows": "& \"${PLUGIN_ROOT}/hooks/run-hook.cmd\" session-start-codex",
|
||||||
"async": false
|
"async": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "superpowers",
|
"name": "superpowers",
|
||||||
"version": "6.0.2",
|
"version": "6.0.3",
|
||||||
"description": "Superpowers skills and runtime bootstrap for coding agents",
|
"description": "Superpowers skills and runtime bootstrap for coding agents",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": ".opencode/plugins/superpowers.js",
|
"main": ".opencode/plugins/superpowers.js",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { execFileSync } = require('child_process');
|
const { execSync } = require('child_process');
|
||||||
|
|
||||||
function extractDotBlocks(markdown) {
|
function extractDotBlocks(markdown) {
|
||||||
const blocks = [];
|
const blocks = [];
|
||||||
@@ -69,7 +69,7 @@ ${bodies.join('\n\n')}
|
|||||||
|
|
||||||
function renderToSvg(dotContent) {
|
function renderToSvg(dotContent) {
|
||||||
try {
|
try {
|
||||||
return execFileSync('dot', ['-Tsvg'], {
|
return execSync('dot -Tsvg', {
|
||||||
input: dotContent,
|
input: dotContent,
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
maxBuffer: 10 * 1024 * 1024
|
maxBuffer: 10 * 1024 * 1024
|
||||||
@@ -107,10 +107,9 @@ function main() {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if dot is available. Run the binary directly rather than probing
|
// Check if dot is available
|
||||||
// with `which`, which is not a command on Windows.
|
|
||||||
try {
|
try {
|
||||||
execFileSync('dot', ['-V'], { stdio: 'ignore' });
|
execSync('which dot', { encoding: 'utf-8' });
|
||||||
} catch {
|
} catch {
|
||||||
console.error('Error: graphviz (dot) not found. Install with:');
|
console.error('Error: graphviz (dot) not found. Install with:');
|
||||||
console.error(' brew install graphviz # macOS');
|
console.error(' brew install graphviz # macOS');
|
||||||
|
|||||||
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