# Port Master

> >-

- **Type:** Skill
- **Install:** `agentstack add skill-sequenzia-agent-alchemy-port-master`
- **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-master
- **Website:** https://sequenzia.github.io/agent-alchemy

## Install

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

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

## About

# Port Master

Extract the platform-agnostic intent from Claude Code plugins, producing clean markdown files that any agent harness developer can read and adapt. The output preserves the *what* and *why* of each skill, agent, and hook while removing implementation details tied to Claude Code.

The goal is portability through clarity — a developer familiar with any agent framework should be able to read the output and integrate it into their system without needing to understand Claude Code's internals.

Three output modes are supported:
- **Full mode** (default): Produces skills, agents, and hooks — preserves the original component structure in generic format. Supports two output layouts:
  - **Per-group** (default): Each plugin group gets its own subdirectory with separate manifest and integration guide.
  - **Unified** (`--unified`): All groups merged into a single directory — one manifest, one integration guide, components organized by type. Cross-group dependencies become internal. Only meaningful when converting multiple groups.
- **Flatten mode** (`--flatten`): Produces skills only — agents are converted to skills, hooks are absorbed into a `lifecycle-hooks` skill. Use this for agent harnesses that only support skills and not agents or hooks.
- **Nested mode** (`--nested`): Agents become pure markdown instruction files nested within their parent skill's `agents/` directory. Hooks are absorbed into a `lifecycle-hooks` skill. Use this for harnesses that support sub-agent delegation but use skills as the primary organizational unit.

Complete ALL 5 phases. After completing each phase, immediately proceed to the next without waiting for user prompts.

## Critical Rules

### AskUserQuestion is MANDATORY

Use the `AskUserQuestion` tool for ALL questions to the user. Never ask questions through regular text output.

- Selection questions → AskUserQuestion
- Confirmation questions → AskUserQuestion
- Clarifying questions → AskUserQuestion

Text output is only for status updates, summaries, and informational context.

### AskUserQuestion Option Limits

Each question in `AskUserQuestion` supports **2-4 options maximum** (plus a built-in "Other" for free-text input). Never create questions with more than 4 options — use presets, categories, or follow-up questions to stay within limits. When users need to pick from a large set, list all available items in the question text and let users specify via "Other".

### Plan Mode Behavior

This skill performs an interactive conversion workflow. When invoked during plan mode:

- Proceed with the full wizard and conversion workflow immediately
- Write converted files to the output directory as normal
- Do NOT create an implementation plan or defer work to an "execution phase"

## Phase Overview

1. **Configuration Wizard & Component Selection** — Parse arguments, upfront wizard, load registry, interactive selection
2. **Dependency Analysis** — Build dependency graph, classify dependencies, plan smart resolution
3. **Conversion** — Transform each component using rules from `references/conversion-rules.md`
4. **Output Generation** — Write files, manifest, and integration guide
5. **Summary** — Present results and next steps

---

## Phase 1: Configuration Wizard & Component Selection

**Goal:** Gather all configuration (plugins, output directory, output mode) upfront, then select components.

### Step 1: Parse Arguments

Parse `$ARGUMENTS` for:
- Plugin group name(s) — positional arguments
- `--all` — Convert all plugin groups
- `--output ` — Output directory (default: `./ported/`)
- `--flatten` — Skills-only output mode (agents converted to skills, hooks absorbed)
- `--nested` — Nested output mode (agents nested as pure markdown within parent skills, hooks absorbed)
- `--unified` — Unified output layout (all groups merged into a single directory tree; full mode only)

If both `--flatten` and `--nested` are provided, report an error: these flags are mutually exclusive. Ask the user to choose one.

If `--unified` is provided together with `--flatten` or `--nested`, report an error: `--unified` only applies to full mode.

If `--unified` is provided with only one group (not `--all`), ignore it silently — unified and per-group produce identical output for a single group.

### Step 2: Load Marketplace Registry

Read the plugin registry to enumerate available plugin groups:

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

Parse the `plugins` array. Each entry has `name`, `version`, `description`, and `source` (relative path like `./core-tools`). Extract the short group name from the source path.

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

For each group, scan its directory to count components:
- Skills: `Glob claude/{group}/skills/*/SKILL.md`
- Agents: `Glob claude/{group}/agents/*.md`
- Hooks: check for `claude/{group}/hooks/hooks.json`

### Step 3: Configuration Wizard

Present configuration options via `AskUserQuestion`. Build the questions array dynamically — include only questions that still need user input (skip questions fully answered by arguments).

**If ALL arguments were provided** (valid plugin names or `--all`, plus `--output` and `--flatten` or `--nested`), skip this step entirely and proceed to Step 4.

Otherwise, build the questions array from the following, including only the ones needed. Combine applicable questions into a single `AskUserQuestion` call (max 4 questions per call).

**Q1: Plugin Groups** — include unless `--all` was specified or all positional args are valid group names.

List all available groups (with component counts) in the question text so users can reference them when choosing "Other". Use preset-based options to stay within the 4-option limit:

```yaml
- header: "Plugin Groups"
  question: "Which plugin groups would you like to convert? Available: {group1} ({N} skills, {M} agents), {group2} (...), ..."
  options:
    - label: "All groups"
      description: "Convert all {count} available plugin groups"
    - label: "Core stack"
      description: "core-tools + dev-tools + claude-tools"
    - label: "SDD pipeline"
      description: "sdd-tools + tdd-tools + claude-tools"
  multiSelect: false
```

Build the preset options dynamically from the available groups — create 2-3 logical groupings based on the plugin descriptions. The user can always type specific group names via the built-in "Other" option.

If positional arguments named specific plugins but any name is invalid, note the invalid name in the question text: "'{invalid-name}' was not found."

**Q2: Output Directory** — include unless `--output` was provided:

```yaml
- header: "Output"
  question: "Where should the converted files be written?"
  options:
    - label: "./ported/ (Recommended)"
      description: "Standard ported output location — timestamped subdirectory created automatically"
    - label: "Custom path"
      description: "Specify a different output directory"
  multiSelect: false
```

**Q3: Output Mode** — include unless `--flatten` or `--nested` was provided:

```yaml
- header: "Output Mode"
  question: "What output format should be used?"
  options:
    - label: "Full (skills, agents, hooks)"
      description: "Preserves original component structure in generic format"
    - label: "Skills only (flatten)"
      description: "Converts agents to skills, absorbs hooks — for harnesses that only support skills"
    - label: "Nested (skills with embedded agents)"
      description: "Agents nested as pure markdown in parent skills, hooks absorbed — for harnesses using skills as primary unit"
  multiSelect: false
```

**Q4: Output Layout** — include only when ALL of these conditions are met:
- Output mode is "Full" (not flatten or nested) — determined by arguments or Q3 answer
- Multiple groups are selected or `--all` was specified — determined by arguments or Q1 answer
- `--unified` was NOT already provided as an argument

```yaml
- header: "Output Layout"
  question: "How should the output be organized?"
  options:
    - label: "Per-group (Recommended)"
      description: "Each group in its own subdirectory with separate manifest and integration guide"
    - label: "Unified"
      description: "All groups merged into one directory — single manifest, single integration guide, components organized by type"
  multiSelect: false
```

Store results as:
- `SELECTED_GROUPS` — plugin groups to convert (parse from preset or "Other" text)
- `OUTPUT_DIR` — base output directory (before timestamp)
- `FLATTEN_MODE` — boolean, true if "Skills only" selected or `--flatten` provided
- `NESTED_MODE` — boolean, true if "Nested" selected or `--nested` provided
- `UNIFIED_LAYOUT` — boolean, true if "Unified" selected or `--unified` provided. Always false in flatten/nested mode or when only one group is selected

### Step 4: Component-Level Selection

For each selected group, enumerate components by reading frontmatter from each file to extract `name` and `description`. Count skills, agents, and hooks.

Present a simplified selection per group using preset options (stays within 4-option limit). List all component names in the question text so users know what's available:

```yaml
AskUserQuestion:
  questions:
    - header: "{group-name}"
      question: "Select components from {group-name} ({total} total — Skills: {skill_names}; Agents: {agent_names}; Hooks: {yes/no}):"
      options:
        - label: "All components (Recommended)"
          description: "Convert all {total} components"
        - label: "Skills only"
          description: "Convert {skill_count} skills, skip agents and hooks"
        - label: "Custom selection"
          description: "Specify which components to include via text"
      multiSelect: false
```

If multiple groups are selected, you can ask about all groups in a single `AskUserQuestion` call (one question per group, max 4 questions per call). For more than 4 groups, use multiple sequential calls.

If the user selects "Custom selection" or types specific names via "Other", parse their response to build the component list.

In **flatten mode**, add context to the question text:
- Note that agents will be converted to skills and hooks will be absorbed into a lifecycle-hooks skill

In **nested mode**, add context to the question text:
- Note that agents will be nested as pure markdown instruction files within their parent skill's `agents/` directory
- Note that hooks will be absorbed into a lifecycle-hooks skill (same as flatten)

Build `SELECTED_COMPONENTS` — a flat list:
```
[{ type: "skill"|"agent"|"hooks", group: "{group}", name: "{name}", path: "{file path}" }]
```

### Step 5: Confirm Selection

Present a summary table showing selected components, output mode, and output directory. Confirm with the user:

```yaml
AskUserQuestion:
  questions:
    - header: "Confirm"
      question: "Proceed with converting {count} components? Output: {output_mode}{layout_suffix}, Directory: {OUTPUT_DIR}"
      options:
        - label: "Proceed"
          description: "Continue to dependency analysis"
        - label: "Modify"
          description: "Change configuration"
        - label: "Cancel"
          description: "Exit"
      multiSelect: false
```

Where `{output_mode}` is "Full", "Flatten (skills only)", or "Nested (skills with embedded agents)". `{layout_suffix}` is ` (unified layout)` when `UNIFIED_LAYOUT` is true, empty string otherwise.

---

## Phase 2: Dependency Analysis & Resolution Planning

**Goal:** Map all dependencies between selected components and plan how to resolve them in the generic output.

### Step 1: Parse Dependencies

For each component in `SELECTED_COMPONENTS`, read its source file and scan for dependency patterns.

**Six dependency patterns to detect:**

| Pattern | Example | Type |
|---------|---------|------|
| Same-plugin skill load | `Read ${CLAUDE_PLUGIN_ROOT}/skills/{name}/SKILL.md` | skill-to-skill |
| Cross-plugin load | `${CLAUDE_PLUGIN_ROOT}/../{group}/skills/{name}/SKILL.md` | cross-plugin |
| Reference file include | `${CLAUDE_PLUGIN_ROOT}/skills/{name}/references/{file}` | reference |
| Agent spawn | `subagent_type: "{name}"` or `subagent_type: "{plugin}:{name}"` | agent-ref |
| Agent skill preload | `skills:` array in agent frontmatter | agent-to-skill |
| Agent-to-agent reference | Agent body mentions another agent by name in spawning context | agent-to-agent |

Also detect external dependencies (MCP servers, shell scripts) for informational tracking.

### Step 2: Classify Dependencies

For each dependency found, classify it:

| Classification | Meaning | Action |
|----------------|---------|--------|
| **Internal** | Target is in `SELECTED_COMPONENTS` | Will be converted; reference by name |
| **External-available** | Target exists on disk but wasn't selected | Reference by name in manifest |
| **External-missing** | Target doesn't exist locally | Note as unresolved in manifest |
| **Reference file** | Points to a `references/*.md` file | Smart resolution (see Step 3) |

**Unified layout adjustment:** When `UNIFIED_LAYOUT` is active, dependencies that would be classified as **External-available** between selected groups are reclassified as **Internal**. A component from group A that depends on a component from group B (both selected) is internal in unified mode because both exist in the same output directory. Only dependencies pointing to groups NOT in `SELECTED_GROUPS` remain external.

### Step 3: Smart Resolution Planning

For each reference file dependency, determine how to handle it based on line count, consumer count, and consumer type.

1. Count lines in the referenced file using `Bash: wc -l < {path}`
2. Determine the **primary owner** — the skill whose source directory originally contained the reference file (from the source path `skills/{owner}/references/{file}`). If the primary owner was not selected for conversion, assign ownership to the first selected consumer
3. Identify all consumers — which skills and agents use this reference

**Decision logic for skill-consumed references:**

- **Under 250 lines AND single consumer** → mark for **inline** (content will be embedded directly in the consuming skill's SKILL.md)
- **250+ lines AND single consumer** → mark as **separate** in the consuming skill's `references/` directory
- **Multiple skill consumers** → mark as **separate** in the **primary owner** skill's `references/` directory; other consumers reference via relative path `../{owner-skill}/references/{file}`

**Decision logic for agent-consumed references (full mode):**

- **Under 250 lines** → mark for **inline** into the agent's body
- **250+ lines** → mark as **promote_to_skill** — the reference becomes a new skill at `skills/{ref-name}/SKILL.md` with its content as the body. The agent's converted text will reference it as a dependency. If the name collides with an existing skill, prefix with the agent name: `{agent-name}-{ref-name}`

**Decision logic for agent-consumed references (flatten mode):**

When `FLATTEN_MODE` is active, agents are converted to skills. Use skill-consumed rules instead of promote_to_skill:

- **Under 250 lines AND single consumer** → mark for **inline** into the agent-as-skill's body
- **250+ lines AND single consumer** → mark as **separate** in the agent-as-skill's `references/` directory
- **Multiple consumers** → mark as **separate** in the **primary owner** skill's `references/` directory

This avoids creating promoted skills when the agent itself is already becoming a skill — the reference can live directly in the agent-as-skill's own `references/` directory.

**Decision logic for agent-consumed references (nested mode):**

When `NESTED_MODE` is active, agents are nested within their parent skill's directory. Use skill-consumed rules (same as flatten), but the "owning skill" for a nested agent's references is the **parent skill** from `AGENT_PARENT_MAP`:

- **Under 250 lines AND

…

## 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-master
- 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%.
