# Port Plugin

> Converts Agent Alchemy plugins into formats compatible with other AI coding platforms

- **Type:** Skill
- **Install:** `agentstack add skill-sequenzia-agent-alchemy-port-plugin`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [sequenzia](https://agentstack.voostack.com/s/sequenzia)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [sequenzia](https://github.com/sequenzia)
- **Source:** https://github.com/sequenzia/agent-alchemy/tree/main/claude/plugin-tools/skills/port-plugin
- **Website:** https://sequenzia.github.io/agent-alchemy

## Install

```sh
agentstack add skill-sequenzia-agent-alchemy-port-plugin
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Plugin Porter

Convert Agent Alchemy plugins (skills, agents, hooks, references, MCP configs) into formats compatible with other AI coding platforms using an extensible markdown-based adapter framework, live platform research, and interactive conversion workflows.

**CRITICAL: Complete ALL 7 phases.** The workflow is not complete until Phase 7: Summary is finished. After completing each phase, immediately proceed to the next phase without waiting for user prompts.

## Critical Rules

### AskUserQuestion is MANDATORY

**IMPORTANT**: You MUST use the `AskUserQuestion` tool for ALL questions to the user. Never ask questions through regular text output.

- Every wizard question -> AskUserQuestion
- Selection questions -> AskUserQuestion
- Confirmation questions -> AskUserQuestion
- Yes/no consent questions -> AskUserQuestion
- Clarifying questions -> AskUserQuestion

Text output should only be used for:
- Summarizing selections and findings
- Presenting information and status updates
- Explaining context or conversion details

If you need the user to make a choice or provide input, use AskUserQuestion.

**NEVER do this** (asking via text output):
```
Which plugin groups would you like to port?
1. core-tools
2. dev-tools
3. sdd-tools
```

**ALWAYS do this** (using AskUserQuestion tool):
```yaml
AskUserQuestion:
  questions:
    - header: "Plugin Groups"
      question: "Which plugin groups would you like to port?"
      options:
        - label: "core-tools"
          description: "3 skills, 2 agents — Deep analysis, codebase analysis, language patterns"
        - label: "dev-tools"
          description: "6 skills, 4 agents — Feature dev, code review, docs, changelog"
        - label: "sdd-tools"
          description: "6 skills, 3 agents — Spec creation, task management, execution"
      multiSelect: true
```

### Plan Mode Behavior

**CRITICAL**: This skill performs an interactive conversion workflow, NOT an implementation plan. When invoked during Claude Code's plan mode:

- **DO NOT** create an implementation plan for how to build the porting feature
- **DO NOT** defer conversion to an "execution phase"
- **DO** proceed with the full wizard and conversion workflow immediately
- **DO** write converted files to the output directory as normal

## Phase Overview

Execute these phases in order, completing ALL of them:

1. **Settings & Arguments** - Load configuration and parse arguments
2. **Plugin Selection Wizard** - Interactive selection of plugin groups and components
3. **Dependency Validation** - Build dependency graph and detect missing references
4. **Platform Research** - Spawn research agent to investigate target platform
4.5. **Dry-Run Preview** - Optional preview of expected output before conversion
5. **Wave-Based Conversion** - Convert components via parallel agent team with incompatibility resolution
6. **Output & Reporting** - Write converted files, migration guide, and gap report
7. **Summary** - Present results and next steps

---

## Phase 1: Settings & Arguments

**Goal:** Load configuration, parse arguments, and determine the target platform.

### Step 1: Parse Arguments

Parse `$ARGUMENTS` for:
- `--target ` — Target platform slug (default: `opencode`)
- `--dry-run` — Preview mode; show expected output without writing files

Set `TARGET_PLATFORM` from `--target` value (default: `opencode`).
Set `DRY_RUN` from `--dry-run` flag (default: `false`).

### Step 2: Load Settings

Check if `.claude/agent-alchemy.local.md` exists and read for any `plugin-tools` section with settings:

```markdown
- **plugin-tools**:
  - **default-target**: opencode
  - **default-output-dir**: ported/
  - **auto-research**: true
```

If settings exist, apply them as defaults (CLI arguments override settings file values).

### Step 3: Validate Adapter

Check that an adapter file exists for the target platform:

1. Use `Glob` to check `${CLAUDE_PLUGIN_ROOT}/references/adapters/{TARGET_PLATFORM}.md`
2. If the adapter file exists, read it and store as `ADAPTER`
3. If no adapter file exists:
   - Inform the user: "No adapter file found for '{TARGET_PLATFORM}'. The research agent will investigate the platform from scratch, and a new adapter file can be created from the findings."
   - Set `ADAPTER = null`
   - Continue — the research phase will gather platform information

### Step 4: Load Marketplace Registry

Read the marketplace registry to enumerate available plugin groups:

```
Read: ${CLAUDE_PLUGIN_ROOT}/../../.claude-plugin/marketplace.json
```

Parse the `plugins` array. Each entry has:
- `name` — Full plugin name (e.g., `agent-alchemy-core-tools`)
- `version` — Current version
- `description` — Brief description
- `source` — Relative path to plugin directory (e.g., `./core-tools`)

Build a list of available plugin groups, extracting the short group name from the source path (e.g., `core-tools` from `./core-tools`).

**Exclude `plugin-tools` from the selection list** — the porter should not attempt to port itself.

---

## Phase 2: Plugin Selection Wizard

**Goal:** Guide the user through selecting which plugin groups and individual components to port.

### Step 1: Target Platform Confirmation

Inform the user of the target platform and configuration:

```
Target platform: {TARGET_PLATFORM}
Adapter: {adapter file path or "None — research agent will investigate"}
Dry-run: {DRY_RUN}
```

### Step 2: Group-Level Selection

Present all available plugin groups for selection using `AskUserQuestion` with `multiSelect: true`.

For each plugin group, scan its directory to count components:

1. Use `Glob` to count skills: `claude/{group}/skills/*/SKILL.md`
2. Use `Glob` to count agents: `claude/{group}/agents/*.md`
3. Use `Glob` to check for hooks: `claude/{group}/hooks/hooks.json`
4. Use `Glob` to count reference dirs: `claude/{group}/skills/*/references/`
5. Use `Glob` to check for MCP config: `claude/{group}/.mcp.json`

Build the selection options:

```yaml
AskUserQuestion:
  questions:
    - header: "Plugin Group Selection"
      question: "Which plugin groups would you like to port to {TARGET_PLATFORM}?"
      options:
        - label: "{group-name} (v{version})"
          description: "{skill_count} skills, {agent_count} agents{, hooks}{, MCP config} — {marketplace description}"
      multiSelect: true
```

**Edge case — Empty plugin group:** If a scanned group has zero skills, zero agents, no hooks, and no MCP config, skip it from the selection list and note: "Skipped {group}: no portable components found."

Store the selected groups as `SELECTED_GROUPS`.

If no groups are selected (user cancels or selects nothing), use `AskUserQuestion` to confirm:
```yaml
AskUserQuestion:
  questions:
    - header: "No Selection"
      question: "No plugin groups were selected. Would you like to start over or cancel?"
      options:
        - label: "Start over"
          description: "Return to group selection"
        - label: "Cancel"
          description: "Exit the porter"
      multiSelect: false
```

If "Start over", repeat Step 2. If "Cancel", end the workflow gracefully.

### Step 3: Component-Level Selection

For each selected group, scan and enumerate all individual components, then present for selection.

**Component scanning per group:**

1. **Skills**: For each `claude/{group}/skills/*/SKILL.md`:
   - Read the frontmatter to extract `name` and `description`
   - Check for `references/` subdirectory and count reference files
   - Format: `skill:{group}/{skill-name}` with description

2. **Agents**: For each `claude/{group}/agents/*.md`:
   - Read the frontmatter to extract `name`, `description`, and `model`
   - Format: `agent:{group}/{agent-name}` with description and model tier

3. **Hooks**: If `claude/{group}/hooks/hooks.json` exists:
   - Read the file and count hook entries
   - Format: `hooks:{group}` with hook count and event types

4. **MCP Config**: If `claude/{group}/.mcp.json` exists:
   - Read the file and list configured servers
   - Format: `mcp:{group}` with server names

Present components for each group using `AskUserQuestion`:

```yaml
AskUserQuestion:
  questions:
    - header: "{group-name} Components"
      question: "Select components to port from {group-name}:"
      options:
        - label: "All components"
          description: "Port everything in {group-name} ({total_count} components)"
        - label: "skill: {skill-name}"
          description: "{skill description} ({ref_count} references)"
        - label: "agent: {agent-name}"
          description: "{agent description} (model: {model})"
        - label: "hooks: {group}"
          description: "{hook_count} hooks ({event types})"
        - label: "mcp: {group}"
          description: "MCP config ({server names})"
      multiSelect: true
```

**Edge case — "All components" selected:** If the user selects "All components", include every component from that group in the selection. Do not present further sub-selection.

Build the final component list as `SELECTED_COMPONENTS`, a flat list of component identifiers with their types:

```
[
  { type: "skill", group: "core-tools", name: "deep-analysis", path: "claude/core-tools/skills/deep-analysis/SKILL.md" },
  { type: "agent", group: "core-tools", name: "code-explorer", path: "claude/core-tools/agents/code-explorer.md" },
  { type: "hooks", group: "core-tools", name: "hooks", path: "claude/core-tools/hooks/hooks.json" },
  ...
]
```

### Step 4: Selection Summary

Present a summary of the selection to the user:

```
## Selection Summary

**Target platform:** {TARGET_PLATFORM}
**Plugin groups:** {count} selected
**Total components:** {count}

| Group | Skills | Agents | Hooks | MCP | References |
|-------|--------|--------|-------|-----|------------|
| {group} | {n} | {n} | {yes/no} | {yes/no} | {n} files |

Components:
- {component list with types}
```

Use `AskUserQuestion` to confirm:

```yaml
AskUserQuestion:
  questions:
    - header: "Confirm Selection"
      question: "Proceed with this selection?"
      options:
        - label: "Proceed"
          description: "Continue to dependency validation"
        - label: "Modify selection"
          description: "Go back and change component selection"
        - label: "Cancel"
          description: "Exit the porter"
      multiSelect: false
```

If "Modify selection", return to Step 2.
If "Cancel", end the workflow gracefully.

---

## Phase 3: Dependency Validation

**Goal:** Build a full dependency graph from selected components, detect all five dependency types, flag missing references and external dependencies, and produce a dependency-sorted conversion order for Phase 5.

This phase consumes `SELECTED_COMPONENTS` and `SELECTED_GROUPS` from Phase 2 and produces `DEPENDENCY_GRAPH` (including `CONVERSION_ORDER`) for Phase 5.

### Step 1: Parse Dependencies

For each component in `SELECTED_COMPONENTS`, read its source file and extract all dependency references. Initialize a flat dependency list:

```
DEPENDENCIES = []   // each entry: { source, target_type, target_ref, dep_type, raw_pattern, transitive }
```

Process each component type using the sub-steps below. Apply these error handling rules during scanning:

**Error: Unreadable file.** If a component file cannot be read (permission error, file missing, I/O error), log a warning and continue scanning the remaining components:
```
WARNING: Could not read {component.path} -- skipping dependency scan for this component.
```

**Error: Malformed YAML frontmatter.** If a component's YAML frontmatter cannot be parsed (invalid YAML between `---` delimiters), log a parsing error and fall back to body-only scanning for that component:
```
WARNING: Malformed YAML frontmatter in {component.path} -- scanning body text only for dependencies.
```

#### 1a: Skill Dependencies

For each skill component (`type: "skill"`), read its `SKILL.md` and scan for all five dependency types:

**Dependency Type 1 -- Skill-to-skill references:**

Scan the skill body for patterns that load another skill from the same plugin group:
```
Read ${CLAUDE_PLUGIN_ROOT}/skills/{skill-name}/SKILL.md
```

For each match, extract `{skill-name}` and record:
```
{ source: this_component, target_type: "skill", target_ref: "{this_group}/{skill-name}", dep_type: "skill-to-skill", raw_pattern: "{matched line}", transitive: false }
```

**Dependency Type 2 -- Cross-plugin references:**

Scan the body for patterns that reference a different plugin group:
```
${CLAUDE_PLUGIN_ROOT}/../{source-dir-name}/skills/{skill-name}/SKILL.md
${CLAUDE_PLUGIN_ROOT}/../{source-dir-name}/agents/{agent-name}.md
${CLAUDE_PLUGIN_ROOT}/../{source-dir-name}/
```

For each match, extract `{source-dir-name}` and the component name, and record:
```
{ source: this_component, target_type: "skill" or "agent", target_ref: "{source-dir-name}/{name}", dep_type: "cross-plugin", raw_pattern: "{matched line}", transitive: false }
```

**Dependency Type 3 -- Reference file includes:**

Scan the body for patterns that load reference files:
```
Read ${CLAUDE_PLUGIN_ROOT}/skills/{skill-name}/references/{filename}
${CLAUDE_PLUGIN_ROOT}/skills/{skill-name}/references/{filename}
```

For each match, determine if the reference belongs to this skill or another skill:
- References to this skill's own `references/` directory are internal by definition and do not create a dependency edge
- References to another skill's `references/` directory create a dependency:
```
{ source: this_component, target_type: "reference", target_ref: "{group}/{skill-name}/references/{filename}", dep_type: "reference-include", raw_pattern: "{matched line}", transitive: false }
```

**Dependency Type 4 -- Agent/subagent references:**

Scan the body for Task tool invocations that spawn agents:
```
subagent_type: "{agent-name}"
```

For each match, record:
```
{ source: this_component, target_type: "agent", target_ref: "{group}/{agent-name}", dep_type: "skill-to-skill", raw_pattern: "{matched line}", transitive: false }
```

**External dependencies (non-component):**

Scan for system-level dependencies that cannot be ported as components:
- MCP server tool references: patterns like `mcp__{server}__{tool}` or the `mcp__` prefix in the body or `allowed-tools` list
- Bash script invocations: references to specific script files (paths ending in `.sh`, `.py`, `.js`)

For each external dependency found:
```
{ source: this_component, target_type: "external", target_ref: "{description}", dep_type: "external", raw_pattern: "{matched line}", transitive: false }
```

#### 1b: Agent Dependencies

For each agent component (`type: "agent"`), read its `.md` file:

**Dependency Type 5 -- Agent-to-skill references:**

Parse the YAML frontmatter and extract the `skills:` field (array of skill identifiers). For each skill listed:
```
{ source: this_component, target_type: "skill", target_ref: "{resolved skill reference}", dep_type: "agent-to-skill", raw_pattern: "skills: [{skill}]", transitive: false }
```

Also scan the agent's markdown body for `Read ${CLAUDE_PLUGIN_ROOT}` and `${CLAUDE_PLUGIN_ROOT}/../` patterns, applying the same Type 1, Type 2, and Type 3 scans from Step 1a.

**Tool dependencies (informational only):**

Parse the `tools:` field from frontmatter. These are Claude Code platform tools classified as `System` dependencies. They do not create dependency edges but are tracked for the gap report.

#### 1c: Hook Dependencies

For each hooks component (`type: "hooks"`), read the `hooks.json` file and parse the JSON:

**Dependency Type 4 -- Hook-to-script references:**

For each hook entry, extract the `command` field and scan for:
- Script file paths: any path in the command string (e.g., `${CLAUDE_PLUGIN_ROOT}/hooks/scripts/auto-approve.sh`)
- Direct script references: paths ending in `.sh`, `.py`, `.js`, or other executable extensions

For each script reference:
```
{ source: this_component, target_type: "script", target_ref: "{script path}", dep_type: "hook-to-script", raw_pattern: "{command v

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [sequenzia](https://github.com/sequenzia)
- **Source:** [sequenzia/agent-alchemy](https://github.com/sequenzia/agent-alchemy)
- **License:** MIT
- **Homepage:** https://sequenzia.github.io/agent-alchemy

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-sequenzia-agent-alchemy-port-plugin
- Seller: https://agentstack.voostack.com/s/sequenzia
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
