Install
$ agentstack add skill-totvs-engpro-advpl-tlpp-skills-advpl-to-tlpp-migration ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
AdvPL-to-TLPP Migration
Overview
Migrate legacy AdvPL source files (.prw, .prx) to modern TLPP (.tlpp) incrementally and safely. TLPP is an evolution of AdvPL that introduces modern language features while maintaining full backward compatibility with existing AdvPL constructs. This skill provides a structured migration path that can be applied gradually — no forced rewrite is required.
When to Use
Use this skill when:
- Modernizing legacy AdvPL code to TLPP
- Converting
.prwfiles to.tlpp - Adopting TLPP-exclusive features (typing, try-catch, namespace, etc.)
- Replacing prohibited constructs (e.g.,
StaticCall) in TLPP sources - Preparing code for TLPP REST migration from WsRESTful
- Onboarding developers transitioning from AdvPL to TLPP
Feature Comparison: AdvPL vs. TLPP
For the complete feature-by-feature comparison table (19 features covering scoping, control structures, typing, namespaces, Try-Catch, JSON inline, class modifiers, REST, and StaticCall status), see [advpl-tlpp-feature-comparison.md](references/advpl-tlpp-feature-comparison.md).
Migration Process
> MANDATORY RULE — File Extension: Any source file that includes #include "tlpp-core.th" or uses TLPP-exclusive features must use the .tlpp extension. If a .prw or .prx file is being migrated or modified to adopt TLPP constructs, rename it to .tlpp as part of the same change. The AdvPL compiler silently ignores TLPP directives in .prw/.prx files, which leads to hard-to-diagnose failures. Always change the extension first.
The migration involves 15 steps, each addressing a specific AdvPL → TLPP transformation:
- File Extension and Includes —
.prw→.tlpp, add#include "tlpp-core.th" - Add Namespace — Organize code with
Namespace company.module.feature - Add Type Annotations — Variables, parameters, return values (
as Type) - Replace ErrorBlock with Try-Catch — Modern exception handling
- Replace StaticCall — Use
FWLoadMenuDef,FWLoadModel, namespace calls - Use Long Identifier Names — TLPP removes the 10-char limit
- Use Named Parameters — Improve readability at call sites
- Use JSON Inline — Replace
JsonObject():New()chains - Add Class Access Modifiers —
Private,Protected,Public - Migrate WsRESTful to TLPP REST — Annotation-based
@Get,@Post, etc. - Fix Incorrect Inheritance —
LongNameClass(notLongClassName) - Remove ISAM Driver Usage — Migrate to
FWTemporaryTable - Migrate Console APIs to FWLogMsg — Replace
ConOut,OutErr,? - Remove IIF Usage — Replace with
If/Else/EndIf - Migrate FormCommit Override to FWModelEvent — Use
FWFormCommit(oModel)
For complete before/after diff examples for all 15 steps, see [tlpp-migration-patterns.md](references/tlpp-migration-patterns.md).
Migration Checklist
Pre-Migration
- [ ] Source file is under version control with a clean commit
- [ ] Existing tests pass (or tests exist for the code)
- [ ] Dependencies on the file are identified (callers, includes)
- [ ] Team is aware of the migration (naming changes affect callers)
File Transformation
- [ ] File extension changed from
.prwto.tlpp - [ ]
#include "tlpp-core.th"added as the first include - [ ]
Namespacedeclaration added - [ ] All
StaticCall()replaced with direct calls orFWLoad*functions - [ ] User Function return types added (
as Type) - [ ] Parameter types added (
as Type) - [ ] Variable types added (
as Type)
Modernization (Incremental)
- [ ]
ErrorBlockpatterns replaced withTry-Catchwhere appropriate - [ ] Short identifier names expanded to descriptive names
- [ ]
Privatevariable scope replaced withLocalwhere possible - [ ] Class access modifiers added (
Private,Protected,Public) - [ ] Named parameters used for functions with 3+ parameters
- [ ] JSON inline syntax used for JSON object construction
- [ ] WsRESTful services migrated to TLPP REST annotations
- [ ]
LongNameClassused for inheritance (notLongClassName) - [ ] ISAM drivers (
MSCREATE,DBCREATE,CRIATRAB) replaced withFWTemporaryTable - [ ]
ConOut()/OutErr()/?replaced withFWLogMsg() - [ ]
IIF()replaced withIf/Else/EndIfblocks - [ ]
FormCommitoverrides migrated toFWModelEvent/FWFormCommit(oModel)pattern
> Refer to [references/sonarqube-rules-reference.md](../references/sonarqube-rules-reference.md) for the complete SonarQube rules reference.
Post-Migration
- [ ] Source compiles without errors
- [ ] All unit/integration tests pass
- [ ] Callers updated if function signatures changed
- [ ] RPO recompiled and tested in development environment
- [ ] No regression in existing functionality
Common Migration Pitfalls
| Pitfall | Symptom | Resolution | | ------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------ | | Using #include "tlpp-core.th" in a .prw/.prx file | TLPP features silently ignored; unexpected runtime behavior | Rename the file to .tlpp before adding TLPP includes or features | | Using long identifiers in .prw files | Silent truncation, wrong function calls | Only use long names in .tlpp files | | StaticCall in .tlpp file | Compilation error | Replace with FWLoadMenuDef, FWLoadModel, or namespace call | | Missing #include "tlpp-core.th" | TLPP features not recognized | Add as the first include | | Default access modifier changed | Class members inaccessible from outside | Explicitly add Public to members that need external access | | Try-Catch around non-TLPP calls | ErrorBlock still needed for pure AdvPL error flows | Use Try-Catch regardless — it captures AdvPL throws too | | JSON inline without line continuations | Compilation error | Use ; at end of each line in JSON inline blocks | | Access modifiers or static in method implementation | Compilation error or unexpected behavior | Method implementations use bare method — NEVER public method, static method, etc. Modifiers are ONLY in the class declaration |
Incremental Migration Strategy
Migration does not need to be all-or-nothing. Follow this priority order:
- Mandatory for TLPP: File extension +
tlpp-core.thinclude + removeStaticCall - High value: Add
Namespace+ type annotations (catches bugs at compile time) - Medium value: Replace
ErrorBlockwithTry-Catch, add class access modifiers, fixLongNameClassinheritance - SonarQube compliance: Remove
IIF,ConOut→FWLogMsg, ISAM →FWTemporaryTable,FormCommit→FWModelEvent - Nice to have: Long identifiers, named parameters, JSON inline
> AdvPL and TLPP coexist. A .tlpp file can call AdvPL functions and vice versa. You don't need to migrate everything at once.
Troubleshooting
StaticCallnot compiling in TLPP:StaticCallis prohibited in TLPP. ReplaceStaticCall(TClass, Method, params)withTClass():Method(params).- Include conflicts after renaming to
.tlpp: Replace#include "protheus.ch"with#include "tlpp-core.th". Add#include "totvs.ch"if the source uses Protheus framework functions. Do not keepprotheus.ch— usetotvs.chinstead. - Namespace resolution errors: Ensure the
Namespacedeclaration matches the directory structure and that callers use the fully qualified name or aUsingdirective. - Functions not found after migration: AdvPL and TLPP can coexist. If a
.tlppfile calls an AdvPL function, the AdvPL source must still be compiled in the RPO. - Type mismatch at compile time: TLPP type annotations are strict. Ensure parameter types and return types match exactly — implicit conversions allowed in AdvPL may fail in TLPP.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: totvs
- Source: totvs/engpro-advpl-tlpp-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.