Compare commits

..

1 Commits

Author SHA1 Message Date
Drew Ritter
68040f2cde test(opencode): modernize integration tests 2026-04-27 12:34:52 -07:00
6 changed files with 8 additions and 158 deletions

View File

@@ -36,9 +36,6 @@
"I've got an idea for something I'd like to build.", "I've got an idea for something I'd like to build.",
"Let's add a feature to this project." "Let's add a feature to this project."
], ],
"websiteURL": "https://github.com/obra/superpowers",
"privacyPolicyURL": "https://docs.github.com/en/site-policy/privacy-policies/github-general-privacy-statement",
"termsOfServiceURL": "https://docs.github.com/en/site-policy/github-terms/github-terms-of-service",
"brandColor": "#F59E0B", "brandColor": "#F59E0B",
"composerIcon": "./assets/superpowers-small.svg", "composerIcon": "./assets/superpowers-small.svg",
"logo": "./assets/app-icon.png", "logo": "./assets/app-icon.png",

View File

@@ -14,14 +14,10 @@ Add superpowers to the `plugin` array in your `opencode.json` (global or project
} }
``` ```
Restart OpenCode. The plugin installs through OpenCode's plugin manager and Restart OpenCode. That's it — the plugin auto-installs and registers all skills.
registers all skills.
Verify by asking: "Tell me about your superpowers" Verify by asking: "Tell me about your superpowers"
OpenCode uses its own plugin install. If you also use Claude Code, Codex, or
another harness, install Superpowers separately for each one.
## Migrating from the old symlink-based install ## Migrating from the old symlink-based install
If you previously installed superpowers using `git clone` and symlinks, remove the old setup: If you previously installed superpowers using `git clone` and symlinks, remove the old setup:
@@ -50,10 +46,7 @@ use skill tool to load superpowers/brainstorming
## Updating ## Updating
OpenCode installs Superpowers through a git-backed package spec. Some OpenCode Superpowers updates automatically when you restart OpenCode.
and Bun versions pin that resolved git dependency in a lockfile or cache, so a
restart may not pick up the newest Superpowers commit. If updates do not appear,
clear OpenCode's package cache or reinstall the plugin.
To pin a specific version: To pin a specific version:
@@ -71,26 +64,6 @@ To pin a specific version:
2. Verify the plugin line in your `opencode.json` 2. Verify the plugin line in your `opencode.json`
3. Make sure you're running a recent version of OpenCode 3. Make sure you're running a recent version of OpenCode
### Windows install issues
Some Windows OpenCode builds have upstream installer issues with git-backed
plugin specs, including cache paths for `git+https` URLs and Bun not finding
`git.exe` even when it works in a normal terminal. If OpenCode cannot install
the plugin, try installing with system npm and pointing OpenCode at the local
package:
```powershell
npm install superpowers@git+https://github.com/obra/superpowers.git --prefix "$HOME\.config\opencode"
```
Then use the installed package path in `opencode.json`:
```json
{
"plugin": ["~/.config/opencode/node_modules/superpowers"]
}
```
### Skills not found ### Skills not found
1. Use `skill` tool to list what's discovered 1. Use `skill` tool to list what's discovered

View File

@@ -89,9 +89,6 @@ or search for "superpowers" in the plugin marketplace.
### OpenCode ### OpenCode
OpenCode uses its own plugin install; install Superpowers separately even if you
already use it in another harness.
Tell OpenCode: Tell OpenCode:
``` ```
@@ -119,20 +116,6 @@ To update:
gemini extensions update superpowers gemini extensions update superpowers
``` ```
### Factory Droid
In Droid, register the marketplace:
```bash
droid plugin marketplace add https://github.com/obra/superpowers
```
Then install:
```bash
droid plugin install superpowers@superpowers
```
## The Basic Workflow ## The Basic Workflow
1. **brainstorming** - Activates before writing code. Refines rough ideas through questions, explores alternatives, presents design in sections for validation. Saves design document. 1. **brainstorming** - Activates before writing code. Refines rough ideas through questions, explores alternatives, presents design in sections for validation. Saves design document.

View File

@@ -12,14 +12,10 @@ Add superpowers to the `plugin` array in your `opencode.json` (global or project
} }
``` ```
Restart OpenCode. The plugin installs through OpenCode's plugin manager and Restart OpenCode. The plugin auto-installs via Bun and registers all skills automatically.
registers all skills.
Verify by asking: "Tell me about your superpowers" Verify by asking: "Tell me about your superpowers"
OpenCode uses its own plugin install. If you also use Claude Code, Codex, or
another harness, install Superpowers separately for each one.
### Migrating from the old symlink-based install ### Migrating from the old symlink-based install
If you previously installed superpowers using `git clone` and symlinks, remove the old setup: If you previously installed superpowers using `git clone` and symlinks, remove the old setup:
@@ -82,10 +78,7 @@ Create project-specific skills in `.opencode/skills/` within your project.
## Updating ## Updating
OpenCode installs Superpowers through a git-backed package spec. Some OpenCode Superpowers updates automatically when you restart OpenCode. The plugin is re-installed from the git repository on each launch.
and Bun versions pin that resolved git dependency in a lockfile or cache, so a
restart may not pick up the newest Superpowers commit. If updates do not appear,
clear OpenCode's package cache or reinstall the plugin.
To pin a specific version, use a branch or tag: To pin a specific version, use a branch or tag:
@@ -119,26 +112,6 @@ Skills written for Claude Code are automatically adapted for OpenCode:
2. Verify the plugin line in your `opencode.json` is correct 2. Verify the plugin line in your `opencode.json` is correct
3. Make sure you're running a recent version of OpenCode 3. Make sure you're running a recent version of OpenCode
### Windows install issues
Some Windows OpenCode builds have upstream installer issues with git-backed
plugin specs, including cache paths for `git+https` URLs and Bun not finding
`git.exe` even when it works in a normal terminal. If OpenCode cannot install
the plugin, try installing with system npm and pointing OpenCode at the local
package:
```powershell
npm install superpowers@git+https://github.com/obra/superpowers.git --prefix "$HOME\.config\opencode"
```
Then use the installed package path in `opencode.json`:
```json
{
"plugin": ["~/.config/opencode/node_modules/superpowers"]
}
```
### Skills not found ### Skills not found
1. Use OpenCode's `skill` tool to list available skills 1. Use OpenCode's `skill` tool to list available skills

View File

@@ -4,8 +4,7 @@
# #
# Sync this superpowers checkout → prime-radiant-inc/openai-codex-plugins. # Sync this superpowers checkout → prime-radiant-inc/openai-codex-plugins.
# Clones the fork fresh into a temp dir, rsyncs tracked upstream plugin content # Clones the fork fresh into a temp dir, rsyncs tracked upstream plugin content
# (including committed Codex files under .codex-plugin/ and assets/), preserves # (including committed Codex files under .codex-plugin/ and assets/), commits,
# OpenAI-owned marketplace metadata already in the destination plugin, commits,
# pushes a sync branch, and opens a PR. # pushes a sync branch, and opens a PR.
# Path/user agnostic — auto-detects upstream from script location. # Path/user agnostic — auto-detects upstream from script location.
# #
@@ -224,7 +223,6 @@ fi
DEST="$DEST_REPO/$DEST_REL" DEST="$DEST_REPO/$DEST_REL"
PREVIEW_REPO="$DEST_REPO" PREVIEW_REPO="$DEST_REPO"
PREVIEW_DEST="$DEST" PREVIEW_DEST="$DEST"
SYNC_SOURCE=""
overlay_destination_paths() { overlay_destination_paths() {
local repo="$1" local repo="$1"
@@ -293,7 +291,7 @@ apply_to_preview_checkout() {
mkdir -p "$PREVIEW_DEST" mkdir -p "$PREVIEW_DEST"
fi fi
rsync "${RSYNC_ARGS[@]}" "$SYNC_SOURCE/" "$PREVIEW_DEST/" rsync "${RSYNC_ARGS[@]}" "$UPSTREAM/" "$PREVIEW_DEST/"
} }
preview_checkout_has_changes() { preview_checkout_has_changes() {
@@ -318,36 +316,6 @@ for pat in "${EXCLUDES[@]}"; do RSYNC_ARGS+=(--exclude="$pat"); done
append_git_ignored_directory_excludes append_git_ignored_directory_excludes
append_git_ignored_file_excludes append_git_ignored_file_excludes
copy_preserved_destination_metadata() {
local destination="$1"
local source="$2"
local path
local rel
[[ -d "$destination/skills" ]] || return 0
while IFS= read -r -d '' path; do
rel="${path#"$destination"/}"
mkdir -p "$source/$(dirname "$rel")"
cp -p "$path" "$source/$rel"
done < <(find "$destination/skills" -path '*/agents/openai.yaml' -type f -print0)
}
prepare_sync_source() {
local destination="$1"
[[ -n "$CLEANUP_DIR" ]] || CLEANUP_DIR="$(mktemp -d)"
SYNC_SOURCE="$CLEANUP_DIR/source-overlay"
rm -rf "$SYNC_SOURCE"
mkdir -p "$SYNC_SOURCE"
rsync "${RSYNC_ARGS[@]}" "$UPSTREAM/" "$SYNC_SOURCE/" >/dev/null
copy_preserved_destination_metadata "$destination" "$SYNC_SOURCE"
}
prepare_sync_source "$PREVIEW_DEST"
# ============================================================================= # =============================================================================
# Dry run preview (always shown) # Dry run preview (always shown)
# ============================================================================= # =============================================================================
@@ -363,7 +331,7 @@ if [[ $BOOTSTRAP -eq 1 ]]; then
fi fi
echo "" echo ""
echo "=== Preview (rsync --dry-run) ===" echo "=== Preview (rsync --dry-run) ==="
rsync "${RSYNC_ARGS[@]}" --dry-run --itemize-changes "$SYNC_SOURCE/" "$PREVIEW_DEST/" rsync "${RSYNC_ARGS[@]}" --dry-run --itemize-changes "$UPSTREAM/" "$PREVIEW_DEST/"
echo "=== End preview ===" echo "=== End preview ==="
echo "" echo ""
@@ -400,7 +368,7 @@ echo "Syncing upstream content..."
if [[ $BOOTSTRAP -eq 1 ]]; then if [[ $BOOTSTRAP -eq 1 ]]; then
mkdir -p "$DEST" mkdir -p "$DEST"
fi fi
rsync "${RSYNC_ARGS[@]}" "$SYNC_SOURCE/" "$DEST/" rsync "${RSYNC_ARGS[@]}" "$UPSTREAM/" "$DEST/"
# Bail early if nothing actually changed # Bail early if nothing actually changed
cd "$DEST_REPO" cd "$DEST_REPO"

View File

@@ -73,19 +73,6 @@ assert_matches() {
fi fi
} }
assert_not_matches() {
local haystack="$1"
local pattern="$2"
local description="$3"
if printf '%s' "$haystack" | grep -Eq -- "$pattern"; then
fail "$description"
echo " did not expect to match: $pattern"
else
pass "$description"
fi
}
assert_path_absent() { assert_path_absent() {
local path="$1" local path="$1"
local description="$2" local description="$2"
@@ -257,22 +244,6 @@ EOF
commit_fixture "$repo" "Initial destination fixture" commit_fixture "$repo" "Initial destination fixture"
} }
add_openai_agent_metadata_fixture() {
local repo="$1"
mkdir -p "$repo/plugins/superpowers/skills/example/agents"
cat > "$repo/plugins/superpowers/skills/example/agents/openai.yaml" <<'EOF'
interface:
display_name: "Example"
short_description: "Destination-owned OpenAI metadata"
EOF
git -C "$repo" add plugins/superpowers/skills/example/agents/openai.yaml
commit_fixture "$repo" "Add OpenAI agent metadata fixture"
}
dirty_tracked_destination_skill() { dirty_tracked_destination_skill() {
local repo="$1" local repo="$1"
@@ -290,7 +261,6 @@ write_synced_destination_fixture() {
"$repo/plugins/superpowers/.codex-plugin" \ "$repo/plugins/superpowers/.codex-plugin" \
"$repo/plugins/superpowers/.private-journal" \ "$repo/plugins/superpowers/.private-journal" \
"$repo/plugins/superpowers/assets" \ "$repo/plugins/superpowers/assets" \
"$repo/plugins/superpowers/skills/example/agents" \
"$repo/plugins/superpowers/skills/example" "$repo/plugins/superpowers/skills/example"
cat > "$repo/plugins/superpowers/.codex-plugin/plugin.json" <<EOF cat > "$repo/plugins/superpowers/.codex-plugin/plugin.json" <<EOF
@@ -312,19 +282,12 @@ EOF
Fixture content. Fixture content.
EOF EOF
cat > "$repo/plugins/superpowers/skills/example/agents/openai.yaml" <<'EOF'
interface:
display_name: "Example"
short_description: "Destination-owned OpenAI metadata"
EOF
printf 'tracked keep\n' > "$repo/plugins/superpowers/.private-journal/keep.txt" printf 'tracked keep\n' > "$repo/plugins/superpowers/.private-journal/keep.txt"
git -C "$repo" add \ git -C "$repo" add \
plugins/superpowers/.codex-plugin/plugin.json \ plugins/superpowers/.codex-plugin/plugin.json \
plugins/superpowers/assets/app-icon.png \ plugins/superpowers/assets/app-icon.png \
plugins/superpowers/assets/superpowers-small.svg \ plugins/superpowers/assets/superpowers-small.svg \
plugins/superpowers/skills/example/agents/openai.yaml \
plugins/superpowers/skills/example/SKILL.md \ plugins/superpowers/skills/example/SKILL.md \
plugins/superpowers/.private-journal/keep.txt plugins/superpowers/.private-journal/keep.txt
@@ -452,7 +415,6 @@ main() {
local help_output local help_output
local script_source local script_source
local dirty_skill_path local dirty_skill_path
local noop_openai_metadata_path
echo "=== Test: sync-to-codex-plugin dry-run regression ===" echo "=== Test: sync-to-codex-plugin dry-run regression ==="
@@ -481,7 +443,6 @@ main() {
init_repo "$dest" init_repo "$dest"
write_destination_fixture "$dest" write_destination_fixture "$dest"
add_openai_agent_metadata_fixture "$dest"
checkout_fixture_branch "$dest" "$dest_branch" checkout_fixture_branch "$dest" "$dest_branch"
dirty_tracked_destination_skill "$dest" dirty_tracked_destination_skill "$dest"
@@ -529,7 +490,6 @@ main() {
preview_section="$(printf '%s\n' "$preview_output" | sed -n '/^=== Preview (rsync --dry-run) ===$/,/^=== End preview ===$/p')" preview_section="$(printf '%s\n' "$preview_output" | sed -n '/^=== Preview (rsync --dry-run) ===$/,/^=== End preview ===$/p')"
stale_preview_section="$(printf '%s\n' "$stale_preview_output" | sed -n '/^=== Preview (rsync --dry-run) ===$/,/^=== End preview ===$/p')" stale_preview_section="$(printf '%s\n' "$stale_preview_output" | sed -n '/^=== Preview (rsync --dry-run) ===$/,/^=== End preview ===$/p')"
dirty_skill_path="$dirty_apply_dest/plugins/superpowers/skills/example/SKILL.md" dirty_skill_path="$dirty_apply_dest/plugins/superpowers/skills/example/SKILL.md"
noop_openai_metadata_path="$noop_apply_dest/plugins/superpowers/skills/example/agents/openai.yaml"
echo "" echo ""
echo "Preview assertions..." echo "Preview assertions..."
@@ -545,7 +505,6 @@ main() {
assert_not_contains "$preview_output" "Overlay file (.codex-plugin/plugin.json) will be regenerated" "Preview omits overlay regeneration note" assert_not_contains "$preview_output" "Overlay file (.codex-plugin/plugin.json) will be regenerated" "Preview omits overlay regeneration note"
assert_not_contains "$preview_output" "Assets (superpowers-small.svg, app-icon.png) will be seeded from" "Preview omits assets seeding note" assert_not_contains "$preview_output" "Assets (superpowers-small.svg, app-icon.png) will be seeded from" "Preview omits assets seeding note"
assert_contains "$preview_section" "skills/example/SKILL.md" "Preview reflects dirty tracked destination file" assert_contains "$preview_section" "skills/example/SKILL.md" "Preview reflects dirty tracked destination file"
assert_not_matches "$preview_section" "\\*deleting +skills/example/agents/openai\\.yaml" "Preview preserves destination-owned OpenAI agent metadata"
assert_current_branch "$dest" "$dest_branch" "Preview leaves destination checkout on its original branch" assert_current_branch "$dest" "$dest_branch" "Preview leaves destination checkout on its original branch"
assert_branch_absent "$dest" "sync/superpowers-*" "Preview does not create sync branch in destination checkout" assert_branch_absent "$dest" "sync/superpowers-*" "Preview does not create sync branch in destination checkout"
@@ -583,9 +542,6 @@ Locally modified fixture content." "Dirty local apply preserves tracked working-
assert_contains "$noop_apply_output" "No changes — embedded plugin was already in sync with upstream" "Clean no-op local apply reports no changes" assert_contains "$noop_apply_output" "No changes — embedded plugin was already in sync with upstream" "Clean no-op local apply reports no changes"
assert_current_branch "$noop_apply_dest" "$noop_apply_dest_branch" "Clean no-op local apply leaves destination checkout on its original branch" assert_current_branch "$noop_apply_dest" "$noop_apply_dest_branch" "Clean no-op local apply leaves destination checkout on its original branch"
assert_branch_absent "$noop_apply_dest" "sync/superpowers-*" "Clean no-op local apply does not create sync branch in destination checkout" assert_branch_absent "$noop_apply_dest" "sync/superpowers-*" "Clean no-op local apply does not create sync branch in destination checkout"
assert_file_equals "$noop_openai_metadata_path" "interface:
display_name: \"Example\"
short_description: \"Destination-owned OpenAI metadata\"" "Clean no-op local apply preserves OpenAI agent metadata"
echo "" echo ""
echo "Missing manifest assertions..." echo "Missing manifest assertions..."