<!-- Version: 0.5.0 | Status: COMPLETE | Updated: 2026-04-09 -->
Scanned 9/6/2026
Install to Claude Code
npx -y skills add shrwnsan/vibekit-claude-plugins --skill plans --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Plans?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/shrwnsan-plans)More formats (shields.io, HTML) on the badges page.
# PRD: Extract Meta-Search into a Standalone Portable Skill
<!-- Version: 0.5.0 | Status: COMPLETE | Updated: 2026-04-09 -->
## Overview
Extract the `meta-search` skill from the `search-plus` plugin into a self-contained, portable skill with bundled scripts. The skill orchestrates multi-service error recovery (Tavily, Jina.ai, free services) via three tiers: automated hook, skill-driven script execution, and manual fallback strategies.
## Goals
- Make `meta-search` fully portable — self-contained skill directory with bundled scripts per the [Agent Skills](https://agentskills.io/specification) open standard.
- Three-tier error recovery: hook (automatic), skill (orchestrated scripts), manual (built-in tools).
- Maintain full compatibility when `meta-search` and `search-plus` are installed together.
- Remove the `/search-plus` command in favor of skill-based invocation per [Claude Code skills docs](https://code.claude.com/docs/en/skills).
## Non-Goals
- Creating a separate plugin for meta-search (it stays inside `plugins/search-plus/skills/`).
- Building a shared library between plugins.
- Refactoring the existing `search-plus` agent or adding new search providers.
## Problem Statement
The `meta-search` skill lived at `plugins/search-plus/skills/meta-searching/SKILL.md` with several issues:
1. **Naming**: Skill directory was `meta-searching` but referenced as `meta-search` — inconsistent.
2. **Dead scripts**: 13 scripts (~6,383 lines) at `plugins/search-plus/scripts/` had no CLI entry points — the `PostToolUse` hook fired `node handle-web-search.mjs` which exited silently.
3. **Command redundancy**: `commands/search-plus.md` was a thin wrapper — commands and skills are unified per Claude Code.
4. **Portability claim**: SKILL.md disclaimed that "search-plus agent delegation provides the most reliable results" — contradicting standalone use.
5. **SKILL.md was marketing copy**: Claimed capabilities ("Combines Tavily with Jina.ai fallback") without actionable instructions for Claude to follow.
## Key Outcomes and Success Metrics
- **Portability**: `meta-search` skill directory contains SKILL.md + scripts — fully self-contained per Agent Skills spec.
- **Three-tier recovery**: Hook handles errors automatically, skill orchestrates bundled scripts, manual strategies cover edge cases.
- **Composition**: `search-plus` agent loads `meta-search` skill via `skills: meta-search`.
- **Parity**: Test results unchanged — 32/35 pass, same scenarios as baseline.
- **Accuracy**: ARCHITECTURE.md and SKILL.md reflect actual runtime behavior.
- **Distribution**: Skill auto-syncs to `shrwnsan/agents` hub via CI pipeline.
## Discovery: Scripts Are Dead Code (v0.2)
> **Added in v0.2** — Critical finding that reshaped the entire PRD scope.
During implementation analysis, we traced the actual data flow and found:
- `handle-web-search.mjs` only exports `handleWebSearch()` — no `process.stdin`, `process.argv`, or top-level code.
- None of the 13 scripts in `scripts/` had a CLI entry point.
- The hook command `node handle-web-search.mjs` ran Node, which imported modules, found nothing to execute, and exited silently.
- Error recovery worked through Claude reading SKILL.md instructions and reasoning with built-in tools.
### Resolution (v0.4)
Instead of the originally recommended Option 2 (remove scripts, keep instruction-only), we implemented a hybrid that wires up the scripts:
- **`hook-entry.mjs`** — CLI entry point for `PostToolUse` hook. Reads stdin JSON, detects errors, delegates to `handleWebSearch()`, outputs `additionalContext`.
- **`search.mjs`** — CLI wrapper for skill invocation. Takes query/URL as args, outputs recovered content.
- **Scripts moved** from `plugins/search-plus/scripts/` into `skills/meta-search/scripts/` per Agent Skills spec.
- **5 dead scripts removed** (~1,986 lines): `architecture-improvements`, `missing-features`, `optimized-transforms`, `production-improvements`, `response-validator`.
## User Stories
- As a developer, I want the meta-search skill to recover from search failures automatically via the hook, and manually via `/search-plus:meta-search` when needed.
- As a search-plus user, I want the skill and agent to compose cleanly with no redundancy.
- As a plugin author, I want accurate documentation that reflects the three-tier architecture.
## Implemented Structure
```
plugins/search-plus/
├── .claude-plugin/
│ └── plugin.json # v2.11.0
├── agents/
│ └── search-plus.md # skills: meta-search
├── docs/
│ ├── ARCHITECTURE.md # Updated — three-tier, hook runtime
│ ├── CONFIGURATION.md
│ ├── PERFORMANCE.md
│ └── STANDARD_RESPONSE_FORMAT.md
├── hooks/
│ └── hooks.json # PostToolUse → skills/meta-search/scripts/hook-entry.mjs
├── skills/
│ └── meta-search/ # Self-contained skill (Agent Skills spec)
│ ├── SKILL.md # Orchestrates scripts, then manual fallback
│ └── scripts/
│ ├── search.mjs # CLI wrapper for skill invocation
│ ├── hook-entry.mjs # CLI entry point for PostToolUse hook
│ ├── handle-web-search.mjs
│ ├── content-extractor.mjs
│ ├── handle-search-error.mjs
│ ├── handle-rate-limit.mjs
│ ├── github-service.mjs
│ ├── response-transformer.mjs
│ ├── search-response.mjs
│ └── security-utils.mjs
├── CHANGELOG.md
└── README.md
```
### Three-tier architecture
| Tier | Trigger | Component | How it works |
|------|---------|-----------|--------------|
| **Hook** | Automatic on `PostToolUse` error | `hook-entry.mjs` | Reads stdin JSON, detects 403/429/422/451/ECONNREFUSED/empty, runs `handleWebSearch()`, injects `additionalContext` |
| **Skill** | Claude auto-loads or user invokes `/search-plus:meta-search` | `SKILL.md` → `search.mjs` | Runs `node ${CLAUDE_SKILL_DIR}/scripts/search.mjs <query>`, falls back to manual strategies |
| **Manual** | Skill Step 2 | Built-in `web_search`/`web_fetch` | Error-specific strategies (cache URLs, query reformulation, domain exclusion) |
## Acceptance Criteria
- [x] **AC1**: `meta-search` skill renamed from `meta-searching`, SKILL.md updated with portable description.
- [x] **AC2**: `search-plus` agent references `skills: meta-search`.
- [x] **AC3**: `commands/search-plus.md` removed.
- [x] **AC4**: ARCHITECTURE.md rewritten with three-tier model and PostToolUseFailure callout.
- [x] **AC5**: Hook wired up with CLI entry point (`hook-entry.mjs`), tested with real PostToolUse JSON.
- [x] **AC6**: Scripts moved into skill directory per Agent Skills spec.
- [x] **AC7**: `search.mjs` CLI wrapper tested — Tavily recovery verified.
- [x] **AC8**: SKILL.md follows best practices: third-person description (182 chars), `Bash(node *)` in `allowed-tools`, orchestrates bundled scripts.
- [x] **AC9**: Test parity — 32/35 pass, matching baseline.
- [x] **AC10**: README, CHANGELOG updated. Version bumped to 2.11.0.
- [x] **AC11**: PERFORMANCE.md and STANDARD_RESPONSE_FORMAT.md updated for new script paths.
- [x] **AC12**: `marketplace.json` version synced to 2.11.0.
- [x] **AC13**: Skill synced to `shrwnsan/agents` hub via CI pipeline ([PR #76](https://github.com/shrwnsan/vibekit-claude-plugins/pull/76)).
## Risks and Mitigations
| Risk | Severity | Mitigation |
|------|----------|------------|
| **Breaking `/search-plus` for existing users** | Medium | Command removed; same functionality via skill auto-invocation or `/search-plus:meta-search`. Migration notes in CHANGELOG. |
| **Hook + skill double-processing** | Low | Hook fires on `PostToolUse` (post-execution); skill fires on Claude's decision. Different triggers — no conflict. |
| **Scripts depend on external APIs** | Low | Free services (SearXNG, DuckDuckGo, Startpage) work without API keys. Tavily/Jina are optional enhancements. |
| **`PostToolUseFailure` not covered** | Low | Hook only covers `PostToolUse` (successful tool call with error in response). Tool-level exceptions not intercepted. Documented in ARCHITECTURE.md and SKILL.md. |
## Open Questions (Resolved)
| Question | Resolution |
|----------|------------|
| Keep `scripts/` as reference or remove? | Moved 9 core scripts into skill; removed 5 dead scripts. |
| Remove hook or leave as-is? | Wired up with `hook-entry.mjs` — now functional. |
| Pursue Option 1 (CLI entry point)? | Yes — implemented as `hook-entry.mjs` + `search.mjs`. |
| Version bump: 2.11.0 or 3.0.0? | 2.11.0 — breaking changes are to interfaces that were dead code or platform-deprecated. No external API contract violated. |
## Implementation Phases
### Phase 1: Rename and Update ✅
- Renamed `skills/meta-searching/` → `skills/meta-search/`.
- Updated agent skill reference.
- Removed `commands/search-plus.md`.
### Phase 2: Wire Up Scripts ✅
- Added `hook-entry.mjs` CLI entry point for PostToolUse hook.
- Added `search.mjs` CLI wrapper for skill invocation.
- Moved 9 core scripts into `skills/meta-search/scripts/`.
- Removed 5 dead scripts (~1,986 lines).
- Updated `hooks.json` to point to skill-local scripts.
### Phase 3: Documentation ✅
- Rewrote ARCHITECTURE.md — three-tier model, PostToolUseFailure callout.
- Rewrote SKILL.md — orchestrates scripts, best-practice compliant.
- Updated README — natural language prompts, removed `/search-plus` command refs.
- Added CHANGELOG v2.11.0 entry.
- Updated PERFORMANCE.md and STANDARD_RESPONSE_FORMAT.md for new script paths.
- Fixed stale import paths (deleted `response-validator.mjs` → `search-response.mjs`).
- Updated test import paths in 4 test scripts.
### Phase 4: Pre-Push Cleanup ✅
- Synced `marketplace.json` version to 2.11.0.
- Fixed stale `/search-plus` references in CONFIGURATION.md.
- Removed broken `search-plus-standardization-test.mjs`.
- Squashed to 10 clean conventional commits.
- Merged via [PR #76](https://github.com/shrwnsan/vibekit-claude-plugins/pull/76) (squash merge).
### Phase 5: CI/CD Pipeline ✅
- Fixed `sync-skills.yml` — creates PR instead of direct push to `shrwnsan/agents` ([PR #77](https://github.com/shrwnsan/vibekit-claude-plugins/pull/77)).
- Added re-run safety: `--force-with-lease` push, duplicate PR check ([PR #79](https://github.com/shrwnsan/vibekit-claude-plugins/pull/79)).
- Added `auto-merge-sync.yml` to `shrwnsan/agents` — gates on branch pattern + author ([PR #3](https://github.com/shrwnsan/agents/pull/3)).
- Updated `AGENTS_HUB_PAT` with `pull_requests: write` scope.
- E2E verified: skill change → sync PR → auto-merge → `meta-search` landed in agents hub ([PR #4](https://github.com/shrwnsan/agents/pull/4)).
- Cleaned up stale `skills/meta-searching/` from agents, updated README ([PR #5](https://github.com/shrwnsan/agents/pull/5)).
## Retrospective
### What went well
- **Dead code discovery (v0.2)** was the pivotal moment — tracing `handle-web-search.mjs` data flow revealed the scripts were never executed. This prevented us from doing unnecessary bundling work and led to a better architecture (wiring up CLI entry points instead).
- **Three-tier architecture** exceeded the original scope in a good way. The PRD recommended Option 2 (instruction-only), but implementing Option 1 (CLI entry points) was straightforward and gives real automated recovery via the hook.
- **Test parity** — 32/35 baseline held throughout. No regressions introduced despite moving 9 scripts and deleting 5.
- **Git worktree isolation** kept the work separate from main until ready. Multiple squash rounds kept the commit history clean (10 commits from many more iterations).
- **PRD as living document** — iterating from v0.1 (wrong assumptions) through v0.5 (complete) kept scope clear and decisions traceable.
### What could improve
- **CI pipeline was an afterthought** — the `sync-skills.yml` workflow existed before this PRD but had never been tested end-to-end. Branch protection on `shrwnsan/agents` blocked direct push, PAT lacked `pull_requests` scope, and `--auto` merge required a repo setting that wasn't enabled. Three iterations of workflow fixes (#77, #79, re-runs) could have been one if we'd tested the pipeline before merging #76.
- **Version bump debate** — the 2.11.0 vs 3.0.0 discussion happened late (during pre-push review). This should have been decided during planning. The answer was clear once we cataloged what actually broke — nothing a real consumer would hit — but the analysis took time.
- **Stale references scattered across docs** — PERFORMANCE.md, STANDARD_RESPONSE_FORMAT.md, CONFIGURATION.md all had stale paths or import references. A grep for old paths early in Phase 3 would have caught them all at once instead of in a follow-up batch.
- **Re-runs of GitHub Actions use the old workflow file** from the triggering commit, not the latest on main. This tripped us up when the fixed workflow was on main but the re-run still used the old code. Worth remembering for future CI work.
### Decisions worth revisiting
- **Hook-driven recovery vs instruction-only** — the hook now fires on every `WebSearch|WebFetch` call and exits silently on success. Need real-world data on whether the 30s timeout and Node startup overhead causes perceptible latency.
- **Scripts in skill directory** — bundling ~4,400 lines of `.mjs` into the skill makes it self-contained but large. If the skill is installed standalone (outside the plugin), those scripts need Node.js available. Not an issue today but worth noting.
## Future Considerations
- **Real-world hook validation** — install the updated plugin in Claude Code and test the three tiers with actual search failures. Verify hook `additionalContext` injection works as expected.
- **PostToolUseFailure coverage** — if tool-level exceptions (network timeouts before tool returns) are common, consider adding a `PostToolUseFailure` hook entry point.
- **`sync-upstream.yml` on agents repo** also pushes directly to main (line 114). Same branch protection issue — should be converted to PR-based flow for consistency.
---
## Changelog
### v0.5.0 (2026-04-09)
All phases complete, CI/CD pipeline verified end-to-end.
**Phase 5 (CI/CD)**:
- Fixed `sync-skills.yml`: PR-based flow instead of direct push, re-run safety, immediate merge.
- Added `auto-merge-sync.yml` to `shrwnsan/agents`: gates on `sync/vibekit-skills-*` branch pattern + `shrwnsan`/`nano-ade` author.
- Updated `AGENTS_HUB_PAT` with `pull_requests: write` scope.
- E2E pipeline verified: skill change → PR #4 auto-merged → `meta-search` landed in agents hub.
- Cleaned up stale `meta-searching` from agents repo, updated README.
**Acceptance criteria**: All 13 ACs now complete. PRD status → COMPLETE.
### v0.4.0 (2026-04-06)
Implementation complete — exceeded original scope.
**Outcome**:
- Implemented three-tier architecture (hook + skill + manual) instead of originally recommended Option 2 (instruction-only).
- Wired up dead scripts with CLI entry points: `hook-entry.mjs` (PostToolUse stdin/stdout) and `search.mjs` (CLI args).
- Moved 9 core scripts into `skills/meta-search/scripts/` per Agent Skills spec. Removed 5 dead scripts (~1,986 lines).
- SKILL.md rewritten to orchestrate bundled scripts, then fall back to manual strategies. Best-practice compliant (third-person, 182 chars, under 250 truncation limit).
- Test parity confirmed: 32/35 pass, matching pre-change baseline.
**Open questions resolved**:
- Scripts: moved into skill (not removed or kept as reference).
- Hook: wired up (not removed or left inert).
- Option 1: implemented as part of this PRD (not deferred).
### v0.3.0 (2026-04-05)
Review pass — factual corrections and versioning formalization.
**Corrections**:
- Fixed dead code line count: ~4,399 → ~6,383 lines across 13 scripts (verified via `wc -l`).
- Removed inaccurate "7 dependencies" claim — actual: 5 direct imports.
- ARCHITECTURE.md version drift noted (2.9.0 vs 2.10.1 in plugin.json).
**Structural**:
- Added semver version header to document frontmatter.
- Formalized changelog with semver.
### v0.2.0 (2026-04-05)
Critical scope revision based on data flow analysis.
**Findings**:
- Scripts (~6,383 lines across 13 files) have no CLI entry point — hook fires silently.
- Error recovery works through Claude reading SKILL.md, not through scripted runtime.
- ARCHITECTURE.md documented an aspirational system.
- Commands merged into skills per Claude Code docs.
### v0.1.0 (2026-04-02)
Initial draft. Assumed scripts were active runtime with hook-driven execution. Proposed separate plugin with bundled scripts and hook deduplication strategy.
---
**Status**: COMPLETE (v0.5.0)
**Created**: 2026-04-02
**Last Updated**: 2026-04-09
**Issue Type**: Architecture and Portability
**Impact**: Three-tier error recovery — standalone meta-search skill with bundled Tavily/Jina scripts, auto-synced to agents hub
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!