From port-application
Port, translate, or migrate source code from one programming language to another using a structured pipeline: inventory → translate → evaluate → fix, looping until 100% accuracy. Supports any language pair (C→C#, Python→Rust, Java→Kotlin, JavaScript→TypeScript, etc.). Use this skill whenever the user wants to port, migrate, translate, convert, or rewrite code from one language to another — even if they don't say "port" explicitly. Phrases like "rewrite this in Rust", "convert to TypeScript", "migrate from Java to Kotlin", "translate this C code to C#" should all trigger this skill.
How this skill is triggered — by the user, by Claude, or both
Slash command
/port-application:port-applicationThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are orchestrating a multi-phase porting pipeline that translates source code from
You are orchestrating a multi-phase porting pipeline that translates source code from one programming language to another. The pipeline runs: Port → Evaluate → Fix → Loop until every file scores 100%.
The methodology prioritizes accuracy over elegance — an ugly-but-faithful port beats a clean-but-wrong one. The original source code is always the single source of truth.
This pipeline runs autonomously to completion. After Phase 0 (user interview), the pipeline is a single uninterruptible operation. You MUST NOT stop, pause, present results, or ask the user anything until every file scores 100% and final reports are generated.
The full sequence is one continuous execution:
Before generating ANY text output after a phase completes, ask yourself:
"Am I about to end my turn, ask a question, or present a summary as if the work is done?" If YES → STOP. Do not output that text. Instead, immediately begin the next phase.
Phase completions are transitions, not conclusions. Print a one-line status and immediately spawn the next subagent. Never print a summary table or completion message that treats a phase as a stopping point.
The following is an example of exactly the wrong behavior that has occurred in past runs. Do NOT produce output like this:
❌ WRONG — This is what you must NEVER do:
Phase 1 (Port) Complete!
[big summary table]
Would you like me to proceed to Phase 2 (Evaluate)?
This is wrong because it treats Phase 1 completion as a stopping point. The correct behavior is:
✅ CORRECT — This is what you must do:
Phase 1 complete — 32 files ported. Starting Phase 2 (Evaluate), launching auditor for Group 1...
[immediately spawn auditor subagent — no pause, no question, no waiting]
After Phase 0, your next message to the user may ONLY be the final report. Between phases, you may print brief one-line transition status updates, but you must NEVER:
The pipeline is complete ONLY when ALL of these are true:
If ANY of these are false, you are NOT done. Do not generate a final report, do not present results, do not mention "remaining work." Instead, keep iterating.
A final report that contains a "Remaining Work" section means you stopped too early. There is no such thing as "remaining work" in a completed port — everything is done or you are still in the pipeline.
There is no retry limit. Not 10, not 5, not any number. Keep iterating Evaluate→Fix until the score reaches 100 and the build passes. If you find yourself thinking "I've tried enough times" or "this is good enough at 95%" — that thought is wrong. Continue.
The only valid reason to stop iterating on a file is: auditor score = 100 AND build passes.
Do NOT lower the acceptance threshold. Do NOT accept files below 100 using your own judgment. The rubric already accounts for inherent language differences — platform replacements are noted but not heavily penalized. A faithful port CAN and MUST reach 100. If the auditor keeps scoring below 100 for things you believe are correct translations, fix the auditor's concerns anyway — the auditor is the authority, not your intuition.
$ARGUMENTSport-results/ directory for existing folders. Determine the next project
number (start at 001 if none exist).<NNN>-<short-kebab-name> (e.g., 001-wolf3d-csharp-port).port-results/<slug>/Before any porting, gather configuration. Auto-detect as much as possible, then confirm with the user via AskUserQuestion.
.c/.h → C, .py → Python, .java → Java, .js → JavaScript, .rs → Rust, etc..NET 8Cargo / Rust 2024 editionJDK 21Kotlin 2.0 / JVMNode.js 22 / ESMGo 1.22Python 3.12Use AskUserQuestion with up to 4 questions per round. Every question must include a "Use auto-detected default" option so the user can skip.
Round 1 — Core Settings:
| Question | Auto-Detect | Fallback |
|---|---|---|
| Source language | From file extensions | Ask user |
| Target language | From $ARGUMENTS if mentioned | Ask user |
| Source path | From $ARGUMENTS | Ask user |
| Target output path | <source-dir>-<target-lang>/ | Ask user |
Round 2 — Project Details (if needed):
| Question | Auto-Detect | Fallback |
|---|---|---|
| Original project name | Directory name | Ask user |
| Port project name | <project>.<TargetLang> | Ask user |
| Target framework | From target language table above | Ask user |
| Platform abstraction layer | None if not applicable | Ask user |
Stop interviewing as soon as the user selects "Skip" or all values are known.
Write port-results/<slug>/request.md:
# Port Request
## Configuration
- **Source Language**: {SOURCE_LANG}
- **Target Language**: {TARGET_LANG}
- **Original Project**: {ORIGINAL_PROJECT_NAME}
- **Source Path**: {SOURCE_PATH}
- **Port Project**: {PORT_PROJECT_NAME}
- **Port Path**: {PORT_PATH}
- **Target Framework**: {TARGET_FRAMEWORK}
- **Platform Layer**: {PLATFORM_LAYER}
- **Build Command**: {BUILD_COMMAND}
- **Run Command**: {RUN_COMMAND or "N/A"}
## Source Files
{FILE_LIST with file sizes}
## File Groups
{Groups of 2-3 related files that will be ported together}
## Original Request
{$ARGUMENTS}
Group source files into batches of 2-3 related files:
.h + .c).java interface + impl)List the groups and total count before proceeding.
For each file group, spawn a pa-porter subagent:
Role: Source code porter ({SOURCE_LANG} → {TARGET_LANG})
Original project: {ORIGINAL_PROJECT_NAME} Source path: {SOURCE_PATH} Port project: {PORT_PROJECT_NAME} Port path: {PORT_PATH} Target framework: {TARGET_FRAMEWORK} Platform layer: {PLATFORM_LAYER}
Source files to port: {List of files in this group with their full contents}
Type mapping rules: {Language-specific type mapping — see references/porting-phases.md}
Instructions: Read
references/porting-phases.mdPhase 1 — Porter section. Follow those instructions exactly. Write the ported files to {PORT_PATH}. Also write the inventory checklist toport-results/<slug>/inventories/{filename}-inventory.md.Working directory: {cwd}
After the porter finishes — immediately start Phase 2 (this is not optional):
You must arrive here directly from Phase 1 in the same turn. If you are reading this after completing Phase 1, you should already be spawning the auditor — not asking the user.
Spawn a pa-auditor subagent:
Role: Code port auditor ({SOURCE_LANG} → {TARGET_LANG})
Original project: {ORIGINAL_PROJECT_NAME} Source path: {SOURCE_PATH} Port project: {PORT_PROJECT_NAME} Port path: {PORT_PATH}
Files to evaluate: {List of original files AND their corresponding ported files — include full contents of both}
Instructions: Read
references/porting-phases.mdPhase 2 — Auditor section. Follow those instructions exactly. Score each file 0-100 using the weighted rubric. Run two independent scoring passes and average them.Output: Write the evaluation to BOTH:
port-results/<slug>/evaluations/{filename}-eval-{iteration}.json(structured)port-results/<slug>/evaluations/{filename}-eval-{iteration}.md(human-readable)Working directory: {cwd}
After the auditor finishes — immediately apply Build Verification and Decision Gate (do not stop):
After the auditor scores are in, attempt to build and run the ported project. This is a hard requirement — code that doesn't compile cannot score 100%, regardless of the auditor's assessment.
Before the first build attempt, set up the project scaffolding if it doesn't exist:
.csproj, Cargo.toml, build.gradle, tsconfig.json, etc.)This scaffolding is part of the port — do not skip it.
Before running ANY build command, verify the toolchain is available:
# Check what's available — try the preferred tool first, fall back to alternatives
# Examples:
dotnet --version # .NET
rustc --version # Rust
javac --version # Java
If the preferred build tool is blocked by the sandbox or not installed, immediately try alternatives rather than reporting failure:
| Target | Preferred | Fallback 1 | Fallback 2 |
|---|---|---|---|
| .NET / C# | dotnet build | mcs (Mono) | csc |
| C / C++ | gcc/g++ | cl.exe (MSVC via vcvarsall) | clang |
| Rust | cargo build | rustc directly | — |
| Java | gradle | mvn compile | javac directly |
| TypeScript | npx tsc | node --check (syntax only) | — |
| Go | go build | — | — |
Record which build tool was selected in request.md under Build Command.
Run the build command. Capture the full compiler output (stdout AND stderr).
| Target Framework | Build Command |
|---|---|
| .NET / C# | dotnet build {PORT_PATH} |
| Rust / Cargo | cargo build --manifest-path {PORT_PATH}/Cargo.toml |
| Java / Gradle | gradle -p {PORT_PATH} compileJava |
| Java / Maven | mvn -f {PORT_PATH}/pom.xml compile |
| TypeScript | cd {PORT_PATH} && npx tsc --noEmit |
| Go | cd {PORT_PATH} && go build ./... |
| Python | python -m py_compile on each file |
| C / C++ (MSVC) | cl.exe /c /EHsc *.cpp /I{INCLUDE_PATHS} then link |
| C / C++ (GCC) | g++ -c *.cpp -I{INCLUDE_PATHS} then link |
Capture Results:
build_status: "pass" in the evaluationbuild_status: "fail" with build_errors: [...] in the evaluationIf the project has a main entry point or executable target:
run_status: "pass" | "fail" | "n/a")run_status: "n/a"Build and run results are written to the evaluation JSON alongside auditor scores.
These patterns come up repeatedly in ports. When you encounter them, fix them inline rather than deferring to the fixer:
| Issue | Cause | Fix |
|---|---|---|
| Type redefinition (C2011) | Same type defined in multiple headers | Add include guards or #pragma once |
| Missing forward declarations | Target language is stricter about declaration order | Add forward declarations at top of file |
| Implicit conversion errors | Target language requires explicit casts | Add explicit casts matching original intent |
| Wrong include paths | Package manager puts headers in different locations | Check actual installed path, update #include |
| Unresolved symbols (binary data) | Original linked binary blobs (e.g., GAMEPAL.OBJ) | Extract data from original source, embed as arrays |
| 64-bit pointer truncation | Original used pointer-as-integer tricks on 32-bit | Rewrite to use index-based lookup instead of pointer casts |
| Uninitialized memory/values | Original relied on DOS memory layout | Explicitly initialize (e.g., set mainmem = 4*1024*1024L) |
| Name collisions | Port introduced names that conflict with stdlib/framework | Rename the port's symbol (add suffix _t, prefix, etc.) |
When encountering build errors, fix them yourself in the orchestrator if they are scaffolding/configuration issues (wrong paths, missing project refs, include guards). Only send code-level issues to the pa-fixer subagent.
For each file in the group, apply these rules mechanically (no user input, no judgment calls, no "good enough" exceptions):
| Condition | Action |
|---|---|
| Auditor score = 100 AND build passes | ACCEPT — file is done, move to next group |
| Auditor score < 100 OR build fails | Immediately proceed to Phase 3 (Fix) |
There is no retry limit. A score of 99 is not accepted. A score of 88 is not "close enough." Only 100 AND build passes. Period.
A file group cannot be accepted while the project has build errors, even if the auditor gave it 100%. Build errors are treated as P0 issues.
Do NOT use your own judgment to override this gate. Do NOT accept files because you think the remaining issues are "inherent language differences." The auditor rubric already accounts for language differences. If the auditor says it's not 100, fix it.
When every group is accepted (score = 100, build passes, run passes/n/a), THEN and ONLY THEN proceed to Final Report generation. Not before. Not with "remaining work."
Proceed immediately when the decision gate routes here. Do not pause.
Spawn a pa-fixer subagent:
Role: Code port corrector ({SOURCE_LANG} → {TARGET_LANG})
Original project: {ORIGINAL_PROJECT_NAME} Source path: {SOURCE_PATH} Port project: {PORT_PROJECT_NAME} Port path: {PORT_PATH}
Input A — Original source files: {Full contents of original files}
Input B — Current ported files: {Full contents of current ported files}
Input C — Evaluation report: {Full contents of the evaluation JSON/markdown}
Input D — Build/Run errors (if any): {Full compiler error output and/or runtime crash output. If build passed, state "Build: PASS"}
Instructions: Read
references/porting-phases.mdPhase 3 — Fixer section. Follow those instructions exactly. Fix every issue, P0 first. Build errors are P0 — fix compilation failures before anything else. Overwrite the ported files in {PORT_PATH} with the corrected versions. Write the changelog toport-results/<slug>/changelogs/{filename}-changelog-{iteration}.md.Working directory: {cwd}
After the fixer finishes — immediately loop back to Phase 2 (do not stop):
Maintain a running state table. Update after every phase:
| File | Iteration | Phase | Score | P0s | Build | Status |
|----------------|-----------|----------|-------|-----|-------|--------------|
| main.c | 1 | PORT | — | — | — | In Progress |
| main.c | 1 | EVALUATE | 72 | 1 | FAIL | Below Target |
| main.c | 1 | FIX | 72→85 | 0 | FAIL | Below Target |
| main.c | 2 | EVALUATE | 89 | 0 | PASS | Below Target |
| ... | ... | ... | ... | ... | ... | ... |
| main.c | 5 | EVALUATE | 100 | 0 | PASS | Accepted |
Print the state table after each phase completes.
If the same issue appears in two consecutive evaluations with no improvement:
Subagents may fail due to rate limits, token limits, tool errors, or sandbox restrictions. When this happens:
| Failure | Recovery |
|---|---|
| Rate limit / throttle | Wait briefly, then retry the same task |
| Token limit (file too large) | Split the file group — send fewer files per subagent |
| Tool blocked by sandbox | Try an alternative tool/approach (e.g., different compiler) |
| Subagent returns incomplete output | Re-read the partial output, then spawn a new subagent to finish |
| Subagent crashes / no output | Retry once, then attempt the task directly in the orchestrator |
Never treat a subagent failure as a reason to stop the pipeline. Recover and continue.
After every iteration (each pass through Evaluate or Fix), generate reports.
Write port-results/<slug>/iteration-results-{NN}.md (zero-padded: 01, 02, ...):
# Iteration {N} Results
**Date**: {timestamp}
**Phase**: {PORT|EVALUATE|FIX}
## Files Processed
{Table of files with scores, changes, issues}
## Score Trajectory
{For each file: previous score → current score}
## Issues Found / Fixed
{Numbered list of issues with severity}
## Function Inventory
{Table of original functions → ported methods with confidence}
## Changelog (if fix phase)
{Table of changes made}
## Remaining Issues
{Any issues not yet resolved}
## State Table
{Current state of all files}
Read references/html-templates.md for the HTML templates. Generate:
port-results/<slug>/index.html — Main dashboard. Regenerate after every iteration
with latest totals, scorecard, and links to iteration reports.
port-results/<slug>/iteration-results-{NN}.html — Per-iteration detail page.
Generate once per iteration. Include navigation links (prev/next/dashboard).
Build the HTML by reading the templates from references/html-templates.md and replacing
the placeholder tokens with actual data. Use the color coding scheme from the templates.
When there are multiple file groups, process them efficiently:
Sequential (default for ≤ 3 groups): Process each group through the full Port→Evaluate→Fix loop before starting the next. Simpler, uses less context.
Parallel (for > 3 groups): Spawn porter subagents for multiple groups simultaneously using the Agent tool. Then evaluate results as they come in. This is faster for large projects.
For parallel execution, spawn up to 3 porter subagents at once. As each finishes, immediately spawn its auditor. This keeps the pipeline flowing.
GATE CHECK — Do NOT proceed past this line unless ALL of these are true:
If any box is unchecked, go back to the pipeline. Do not generate this report.
After all files are accepted and verified, write port-results/<slug>/final-report.md:
# Final Port Report: {PORT_PROJECT_NAME}
## Summary
- **Source**: {ORIGINAL_PROJECT_NAME} ({SOURCE_LANG})
- **Target**: {PORT_PROJECT_NAME} ({TARGET_LANG})
- **Framework**: {TARGET_FRAMEWORK}
- **Date**: {timestamp}
## Build & Run Status
- **Build**: {PASS/FAIL} — {build command used}
- **Run**: {PASS/FAIL/N/A} — {run command used, if applicable}
- **Build errors resolved**: {count of build errors fixed during iteration}
## Scorecard
| File | Final Score | Band | Iterations | Status |
|------|-------------|------|------------|--------|
## Score Trajectories
{For each file: iteration-by-iteration score progression}
## Critical Issues Resolved
{Most impactful bugs caught and fixed, including build/runtime errors}
## Cross-File Dependencies
{Any stubs or // DEPENDENCY comments that need wiring up}
## Statistics
- Files ported: {X}
- Average final score: {X}
- Files accepted (100%): {X}
- Files accepted first pass: {X}
- Files requiring iteration: {X}
- Total iterations: {X}
- Build errors fixed: {X}
- Final build status: {PASS/FAIL}
Also regenerate index.html with final statistics.
For each language pair, generate appropriate type mappings. Common pairs are documented
in references/porting-phases.md under "Language-Specific Type Mapping Examples".
For uncommon pairs, generate the mapping by:
port-results/<slug>/.references/porting-phases.md: Detailed instructions for each phase (Porter,
Auditor, Fixer). Subagents should read the relevant section. Contains language-specific
type mappings.references/html-templates.md: HTML templates for generating the dashboard
(index.html) and per-iteration reports (iteration-results-NN.html).npx claudepluginhub etdofresh/claude-marketplace --plugin port-applicationGenerates migration plans, automated scripts, risk assessments, testing strategies, and rollback procedures for transitioning codebases between frameworks, languages, versions, or platforms.
Clones, ports, or converts features from any GitHub repo into your project with 4 modes: port (rewrite), compare (analysis), copy (transplant), improve (copy + optimize). Enforces license and fit checks before adoption.
Provides structured workflow packs for 7 common Claude Code tasks: codebase exploration, bug fixing, safe refactoring, TDD, repo review before merge, CLAUDE.md generation, and migration planning.