Release Notes 2026-08-06

Release Notes 2026-08-06

Version Information

OpenEdge Release

Version Information

OpenEdge Release

Version Information

11.7.21, 12.2.19, 12.8.9, 12.8.11, 13.0.0

Release 11.7 #89416@2026-08-06

Retirement of OpenEdge 11.7

OpenEdge 11.7 has been retired by Progress Software on April 1st 2025. In consequence we urge all customers still using OpenEdge 11 to upgrade to OpenEdge 12.2 or 12.8 as soon as possible.

We are intending to drop the official support of the SmartComponent Library for OpenEdge 11.7 during the second half of the year 2025. We will then no longer ensure that new features of the framework will be usable with OpenEdge 11.7

Customers that are concerned by this intention, should reach out to us as soon as possible, so that we can discuss about a solution.

OpenEdge 13.0 support!

We are pleased to announce that we are not aware of any issues using the SmartComponent Library on OpenEdge 13.0. We hereby declare OpenEdge 13.0 fully supported for the SmartComponent Library as of the release of February 15th 2026.

OpenEdge 12.8 support!

We are pleased to announce that we are not aware of any issues using the SmartComponent Library on OpenEdge 12.8. We hereby declare OpenEdge 12.8 fully supported for the SmartComponent Library as of the release of January 15th 2024.

OpenEdge 12.2 support!

We are pleased to announce that we are not aware of any issues using the SmartComponent Library on OpenEdge 12.2. We hereby declare OpenEdge 12.2 fully supported for the SmartComponent Library as of the release of April 09th 2020.

PASOE / OEMANAGER VS Code Extension

Our first VS Code extension is available in the VS Code marketplace: https://marketplace.visualstudio.com/items?itemName=ConsultingwerkApplicationModernizationSolutionsLtd.oemanager

The extension supports developers with PASOE related routine tasks during development:

  • checking agent or session status

  • trimming the PASOE agents

  • restarting a new agent vai the ping request

Introducing the SmartComponent Library developer forum

Got questions about using the SmartComponent Library? Wish to discuss feature requests with other users of the SmartComponent Library? To facilitate networking in the growing number of SmartComponent Library users and developers, we've added a developer forum on our new home-page. The developer forum can be found at: https://www.consultingwerk.com/support/forum

A login is required to participate in the forum. Don't be shy - create your account today!

Release Notes

Following the release of the OpenEdge 11.7 Release we have completed our testing of the SmartComponent Library on this release of Progress and are proud to announce formal support for the SmartComponent Library on OpenEdge 11.7 with the 2017-04-24 release of the SmartComponent Library. Generally we recommend customers on OpenEdge 11 to upgrade to OpenEdge 11.7 quickly. Starting the 2017-07-14 release we are supporting OpenEdge 11.7 Service Pack 1 (11.7.1).

Starting the 2015-10-09 release the Business Entity Designer will feature a start page with links to most recent release note articles on this site.

With SCL-751 we have adopted native Enums for OpenEdge 11.6. To activate this feature customers must add a definition to products.i. SCL-751 provides details for this.

With SCL-1113 we have modified the templates for SmartWindowForms and SmartTabFolderPages generated from the Business Entity Designer. We have removed the initialization of the viewer controls SmartTableIOState property (value was set to "NoDataSource" within the InitializeComponent method). Customers using their own set of templates should adopt the same fix to their templates.

New Versions of Proparse .NET Assemblies (30 December 2018)

We have updated proparse with further enhancements in this release (see https://github.com/consultingwerk/proparse/releases/tag/4.0.1.1177). Please download the .NET Assemblies ZIP file from our ESD and replace the proparse.net.dll in your environment with the latest one. The new assembly reference is:

<assembly name="proparse.net, Version=4.0.1.1177, Culture=neutral, PublicKeyToken=cda1b098b1034b24"/>

As proparse is used by our Business Entity Generator, this new version of the proparse.net Assembly is also relevant for customers not doing GUI for .NET development and require support for parsing new ABL language constructs.

This version of proparse provides additional debug information when errors are thrown from proparse.net.dll.

New Version of the Consultingwerk.SmartComponents Assemly (09 January 2019)

To support the new SmartFilterControl and the "Filter" link between the SmartFilterControl/SmartDynamciFilterControl and a SmartBusinessEntityAdapter or SmartDatasetChildAdapter we have updated the Consultingwerk.SmartComponents.dll. The new Assembly reference is:

<assembly name="Consultingwerk.SmartComponents, Version=2.2.0.49856, Culture=neutral, PublicKeyToken=10603cb31df311b3"/>

Customers need to update this Assembly in order to compile the latest releases of the SmartComponent Library.

Hybrid Realm now using IAuthenticationService

We've updated the SmartHybridRealm class used for http authentication to leverage the IAuthenticationService. It is therefor required that for AppServers requiring http Authentication (e.g. REST or Web) the correct IAuthenticationService implementation is registered (using service.xml files).

Customers relying on the previous behavior should ensure that the Consultingwerk.SmartFramework.Authentication.AuthenticationService is regsitered as the IAuthenticationService. This implementation will auhtenticate users against the password stored in the SmartUser database table.

When users with no Login Company set should be able to login using the SmartHybridRealm, it's required to set the Login Company Tennant Domain (similar to the field in the Login Company Maintenance) in the .restapplicationsettings / .applicationsettings, e.g.:

 

"DefaultAuthenticationDomain": "consultingwerk"

This is required as the Hydrid Realm Interface from Progress does not provide the domain name to the authentication method.

Web Handler overview

This is an overview of the web handlers supported by this release

defaultHandler=OpenEdge.Web.CompatibilityHandler handler1=Consultingwerk.OERA.JsdoGenericService.WebHandler.CatalogWebHandler: /Catalog/{EntityName} handler2=Consultingwerk.OERA.JsdoGenericService.WebHandler.CatalogsWebHandler: /Catalogs/{PackageName} handler3=Consultingwerk.OERA.JsdoGenericService.WebHandler.CountWebHandler: /Resource/{EntityName}/count handler4=Consultingwerk.OERA.JsdoGenericService.WebHandler.ResourceSubmitWebHandler: /Resource/{EntityName}/SubmitData handler5=Consultingwerk.OERA.JsdoGenericService.WebHandler.InvokeMethodWebHandler: /Resource/{EntityName}/{MethodName} handler6=Consultingwerk.OERA.JsdoGenericService.WebHandler.ResourceWebHandler: /Resource/{EntityName} handler7=Consultingwerk.OERA.JsdoGenericService.WebHandler.BusinessServicesWebHandler: /BusinessServices/{OutputFormat}/{PackageName} handler8=Consultingwerk.Web2.WebHandler.SmartMenuWebHandler: /SmartMenu/{MenuStructureId} handler9=Consultingwerk.Web2.WebHandler.SmartMenuStructureWebHandler: /SmartMenuStructure handler10=Consultingwerk.Web2.WebHandler.SmartRoutesWebHandler: /SmartRoutes handler11=Consultingwerk.Web2.Services.SmartViewsHandler.SmartGridWebHandler: /SmartViews/Grid/{EntityName}/{ViewName}/{DetailTemplate} handler12=Consultingwerk.Web2.Services.SmartViewsHandler.SmartGridWebHandler: /SmartViews/Grid/{EntityName}/{ViewName} handler13=Consultingwerk.Web2.Services.SmartViewsHandler.SmartGridWebHandler: /SmartViews/Grid/{CustomViewName} handler14=Consultingwerk.Web2.Services.SmartViewsHandler.SmartViewerWebHandler: /SmartViewer/Viewer/{EntityName}/{ViewName} handler15=Consultingwerk.Web2.Services.SmartViewsHandler.SmartViewerWebHandler: /SmartViewer/Viewer/{ObjectName} handler16=Consultingwerk.Web2.Services.SmartViewsHandler.SmartFormWebHandler: /SmartForm/{FormTemplate}/{EntityName}/{ViewName} handler17=Consultingwerk.Web2.Services.SmartViewsHandler.SmartFormWebHandler: /SmartForm/{FormTemplate}/{ObjectName} handler18=Consultingwerk.Web2.WebHandler.SmartMessageWebHandler: /SmartMessage/{MessageGroup}/{MessageNumber} handler19=Consultingwerk.Web2.WebHandler.GetImageWebHandler: /Image/{FileName} handler20=Consultingwerk.Web2.WebHandler.SmartValueListWebHandler: /ValueList/{ValueList} handler21=Consultingwerk.Web2.WebHandler.SmartAttachmentsWebHandler: /Attachments/{Table}/{KeyValues} handler22=Consultingwerk.Web2.WebHandler.SmartAttachmentWebHandler: /Attachment/{Guid} handler23=Consultingwerk.Web2.WebHandler.SessionContextWebHandler: /SessionContext handler24=Consultingwerk.Web2.WebHandler.ContextPropertiesWebHandler: /ContextProperties/{PropertyName} handler25=Consultingwerk.Web2.WebHandler.ContextPropertiesWebHandler: /ContextProperties handler26=Consultingwerk.Web2.WebHandler.SessionInfoWebHandler: /SessionInfo handler27=Consultingwerk.Web2.WebHandler.FileSearchWebHandler: /FileSearch/{FileName} handler28=Consultingwerk.Web2.WebHandler.ExecuteAblWebHandler: /ExecuteAbl handler29=Consultingwerk.Web2.WebHandler.SmartLanguagesWebHandler: /Languages handler30=Consultingwerk.OERA.RestResource.RestEntitiesWebHandler: /Entities handler31=Consultingwerk.OERA.Swagger.SwaggerWebHandler: /Swagger/{EntityName} handler32=Consultingwerk.OERA.Swagger.SwaggerRestEntitiesWebHandler: /SwaggerEntities/{OutputType} handler33=Consultingwerk.Web2.WebHandler.SmartTokenSecurityCheckWebHandler: /TokenSecurityCheck/{ObjectName} handler34=Consultingwerk.Web2.WebHandler.SmartTokenSecurityCheckWebHandler: /TokenSecurityCheck handler35=Consultingwerk.Web2.WebHandler.SmartEntityTableMappingHandler: /EntityTableMapping/{EntityName}/{TableName}/{UiTypeCodes} handler36=Consultingwerk.Web2.WebHandler.SmartTreeRootNodeWebHandler: /SmartViews/TreeRootNode/{rootnodeid} handler37=Consultingwerk.Web2.WebHandler.SmartTreeChildNodesWebHandler: /SmartViews/TreeChildNodes/{parentnodeid} handler38=Consultingwerk.Web2.WebHandler.SmartSecurityCheckWebHandler: /IsRestricted/{SecurityRealmCode}/{SecurityItemGuid} handler39=Consultingwerk.Web2.WebHandler.SmartFieldSecurityCheckWebHandler: /RestrictedFields/{TableName} handler40=Consultingwerk.Web2.WebHandler.GetImageNamesHandler: /ImageNames handler41=Consultingwerk.Web2.WebHandler.ExecuteQueryWebHandler: /ExecuteQuery handler42=Consultingwerk.Web2.WebHandler.TranslationProviderWebHandler: /GetTranslation

UTF-8 based deployments available

Starting August 14th 2016 we ship our source code also as UTF-8 encoded. The ZIP files ending with _utf8.zip contain the source code encoded with that code page. The source code in the remaining archives is still encoded in ISO8859-1. Also on Github there is a new branch containing the OpenEdge 11 based source code in UTF-8.

Related article (Progress K-Base): How to get Progress Developer Studio to save in UTF-8 encoding

New Feature Documentation

Download Link

http://esd.consultingwerkcloud.com/

https://github.com/consultingwerk/SmartComponentLibrary

Overview of included tickets

Setup now removes obsolete Object Type attribute value records during repository data load

The setup process (setup.xml) gained a fix routine that runs after the LoadRepositoryData step and cleans up obsolete type-level attribute value records. It processes only the Object Types shipped in smartobjecttype.xml and deletes their type-level attribute value records - those with no ObjectMasterGuid and no ObjectInstanceGuid - that are no longer contained in the shipped smartattributevalue.xml. Object Types maintained by the customer are never touched, so customer extensions and customizations remain intact. This closes the gap where attribute values removed from an Object Type previously stayed in the customer repository forever.

THIRD-PARTY-NOTICES file added to the SmartComponent Library deployment

A THIRD-PARTY-NOTICES file is now included in the SmartComponent Library deployment packages. It lists every bundled open source component (such as CefSharp/CEF/Chromium, ZeroMQ, Newtonsoft.Json, Proparse, IKVM/OpenJDK and others) with its name, version, copyright notice and full license text, and is referenced from the SmartComponent Library license terms. This ensures compliance with the attribution requirements of the bundled components. No action is required from customer developers.

URL field rendering in Viewers and link column rendering in Grids added to the repository

Repository rendering support has been added so MetaViewer and MetaGrid instances emit the new URL settings consumed by the SmartComponents NG front end. A MetaViewer data field configured as a URL field now renders with inputSettings.inputType = "url" and, when set, inputSettings.urlTemplate; a MetaGrid column configured as a link column renders with type = "link" and, when set, urlTemplate. The urlTemplate string (SUBSTITUTE-style positional placeholders) is passed through verbatim — substitution, URL-encoding and scheme safety are handled by the front end. When the attributes are not set the rendered JSON is unchanged, so no empty urlTemplate noise is emitted. Developers configure these through the new url input type / link column type and UrlTemplate attributes on the repository viewer data field and grid column.

SmartLock administration screen added for managing framework locks

A new repository-based screen for administering SmartLocks has been added, rendering identically on Desktop (GUI for .NET) and Angular/Web from the same repository definition. The read-only grid lists lock information, and toolbar buttons allow expiring or deleting the selected lock, and expiring or deleting all locks of a chosen user (with a user lookup, defaulting to the current user). The toolbar functions are implemented as a single server-side event handler Business Task (Consultingwerk.SmartFramework.Lock.LockPresentationService), and the four lock operations were added to SmartLockService / ISmartLockService. A new SmartLockAdmin security token is verified server-side before any operation runs. Developers with the token can launch the SmartLock form to manage locks across both front ends.

AblFrameMigrationPreProcessor implementations are now configurable dynamically via AblFrameMigrationSettings

The set of AblFrameMigrationPreProcessor implementations used during GUI-for-.NET frame migration can now be configured dynamically. A new IAblFrameMigrationPreProcessor setting (a multi-line editor field, one full class name per line) has been added to AblFrameMigrationSettings, the .AblFrameMigrationSettings.xml file and the AblFrameMigrationSettingsForm. The AblFrameMigrationPreProcessor dispatcher was rewritten to load and call through to the configured implementations based on this setting, accessed via the static AblFrameMigrationSettings class. Developers can add or remove pre-processors by editing the setting; an error is raised if a configured class cannot be loaded, and various line-ending styles (CRLF, LF, CR) are supported.

New DetectLiteralLabelsFrameMigrationPreProcessor detects literals used as field labels

A new IAblFrameMigrationPreProcessor implementation, DetectLiteralLabelsFrameMigrationPreProcessor, has been added. It detects literals used as labels for fields defined with no-label by analysing widget positions: for each selected field it looks for a literal to the left of the field, and when a matching literal is found it marks the literal as unselected and uses its unquoted value (via the StringHelper API) as the field's label, stripping a trailing colon if present. The new class is registered in the IAblFrameMigrationPreProcessor setting of .AblFrameMigrationSettings.xml so it is loaded by the AblFrameMigrationPreProcessor dispatcher, and it is covered by unit tests.

REST URL resolution and parameter object population performance optimized

The REST request handling has been optimized to reduce the per-request cost of URL resolution (RestResourceService:ResolveAddressForRequest) and parameter object population (RestEntitiesWebHandler). Registered address templates are now pre-tokenized at registration time, the request URI and Accept header are parsed once per request instead of per candidate, and candidates are indexed by segment count to skip non-matching endpoints. Parameter property assignment from path and query string now iterates the small values list with a cached name-to-property lookup, avoiding the previous double linear scan. Applications with many Business Entities and Business Tasks and long URLs with multiple path and query string parameters benefit on every request; no changes required in customer code.

SmartUnit test progress log messages are now highlighted with a light green background in the Jenkins console

The SmartUnit test progress log message written by TestRunner:LogProcessedTestMethodCount is now color-coded with a light green background so it stands out in the Jenkins console log. This is achieved using ANSI escape sequences (ESC[102m to set the background and ESC[0m to reset it). Rendering requires the Jenkins AnsiColor plugin with the xterm color map. No changes required in customer code.

Pure-ABL Proparse implementation delivered as a staged full port behind the IProparseApi contract

A full pure-ABL implementation of Proparse was delivered in stages behind the existing IProparseApi contract, removing the IKVM/.NET dependency so Proparse can run anywhere ABL runs, including PASOE on Linux. It reimplements the lexer, preprocessor, parser, record-based node tree, schema model, and tree parser (symbol resolution) using an indexed temp-table AST with lazily materialized INode wrappers. Developers can select the ABL engine as a swappable IProparseApi service alongside the ProparseDotNet and ProparseWeb implementations.

Proparse ABL Stage 0 completed: foundation folder structure with production lexer and preprocessor

The pure-ABL Proparse engine's foundation is in place, with the target folder structure and a production-quality lexer and preprocessor built on a record-based token store and a MEMPTR/GET-BYTE block-scanner that folds preprocessing into the fast path. It provides full preprocessing fidelity (include stacking, macro references, scoped/global defines, conditional directives, escapes, name-dot) and passes the ported Java lexer/preprocessor tests without allocating an object per token on the hot path.

Proparse ABL Stage 1 completed: record-based AST node model with lazy INode wrappers

The pure-ABL Proparse engine now represents the AST as a single self-referencing, highly indexed temp-table owned by a NodeStore, with INode and node-subtype wrappers materialized lazily only when a caller navigates to them. The model implements the existing INode contract and subtypes (IBlockNode, IFieldRefNode, IProgramRootNode, IRecordNameNode, IProparseDirectiveNode) with navigation, Query, and hidden-token attachment, avoiding object-per-node allocation on build.

Proparse ABL Stage 2 completed: hand-written recursive-descent parser producing the record AST

The pure-ABL Proparse engine now includes a hand-written recursive-descent parser for the ABL grammar that reproduces the Java ProParser without an ANTLR runtime, implementing LL(k) lookahead, backtracking, and semantic predicates over the token store. It parses statements, blocks, definitions, and expressions into the record AST with schema-aware record/field/variable disambiguation, validated by parity and regression tests against the SCLxxxx fixtures.

Proparse ABL Stage 3 completed: schema model with live-database meta-schema loader

The pure-ABL Proparse engine now builds its schema model directly from the meta-schema of all connected databases, reading tables, fields, indexes, and aliases from the VSTs and dropping the Java flat-file schema dump entirely. Lookups are indexed and cached as a session singleton for use in the parser's disambiguation predicates, and parsing degrades gracefully with no or partial database connections.

Proparse ABL Stage 4 completed: tree parser with scoping and symbol resolution

The pure-ABL Proparse engine now includes a tree-parser pass over the record AST that builds scopes and resolves buffers, fields, variables, and frames against the schema model, attaching Symbol, FieldContainer, and Call links to nodes. The symbol model implements the existing ISymbol, ISymbolScope, ITableBuffer, IFieldBuffer, IVariable, IFrame, ICall, IBlock, and IBufferScope interfaces, validated by symbol/scope resolution unit tests and parity checks against the reference engine.

Proparse ABL Stage 5 completed: IProparseApi facade with parity, conformance, and performance suites

The pure-ABL Proparse engine's ProparseAblApi facade now implements the IProparseApi contract end-to-end and is registered as a swappable service, so consumers can select the ABL, ProparseDotNet, or ProparseWeb implementation. A parity harness against ProparseDotNet, the SCLxxxx conformance fixtures, and an end-to-end performance suite validate the engine, with documented remaining gaps and a go/no-go recommendation on defaulting consumers to the ABL engine.

Mandatory temp-table columns are now emitted as required fields in the generated OpenAPI schema

Temp-table columns marked as mandatory via the BusinessEntityDescriptor are now added to the required array of the table's schema in the generated OpenAPI documents, in addition to the existing vendor-specific x-mandatory property. This makes the OpenAPI/Swagger viewer correctly mark those fields as mandatory. No changes required in customer code.

Proparse TreeView (API) added: IProparseApi-based variants of the tree view form and control in Proparse2

New IProparseApi-based variants of the ProparseTreeViewForm and ProparseTreeViewControl were added in the Consultingwerk.Studio.Proparse2 package, decoupling the tooling UI from the Proparse implementation so it can also run against the ProparseWeb implementation. The variants use the IProparseApi service and ProparseHelper2 instead of direct Proparse access, and a new "Proparse TreeView (API)" desktop entry launches the form. The contract was extended with an ISymbol:Scope property and ITableBuffer now inheriting ISymbol to support node selection highlighting.

Extension/customizer mechanism added to the IProparseApi-based Proparse2 TreeView variants

A new customizer mechanism was added for the Proparse2 TreeView variants, mirroring the existing Proparse mechanism but based on the IProparseApi contract instead of direct Proparse access. The new contracts Consultingwerk.Studio.Proparse2.IProparseTreeViewCustomizer and IProparseTreeViewCustomizerFactory, together with a default ProparseTreeViewCustomizerFactory, allow developers to register custom TreeView extensions through a dedicated ProparseTreeViewCustomizerFactory2 setting in the .applicationsettings file, leaving the classic TreeView setting untouched. The Proparse2 ProparseTreeViewForm now initializes these extensions on load and calls HandleFileParsed after parsing.

UpdateEditing Proparse tree view extension ported to the IProparseApi-based Proparse2 tree view

The UpdateEditingProparseTreeViewExtension, which interfaces the UPDATE-EDITING migration routines, was ported to the Consultingwerk.Studio.Proparse2 package using INode / IParseUnit / ProparseHelper2 instead of direct JPNode, ParseUnit, and NodeTypes access. The ported extension is registered in the Proparse2 ProparseTreeViewCustomizerFactory.

LeaveTrigger Proparse tree view extension ported to the IProparseApi-based Proparse2 tree view

The LeaveTriggerProparseTreeViewExtension, which drives the LEAVE trigger migration routines, was ported to the Consultingwerk.Studio.Proparse2 package using INode / IParseUnit / ProparseHelper2 instead of direct JPNode and ParseUnit access. The ported extension is registered in the Proparse2 ProparseTreeViewCustomizerFactory.

DataMember Proparse tree view extension ported to the IProparseApi-based Proparse2 tree view

The DataMemberProparseTreeViewExtension was ported to the new Consultingwerk.Studio.Proparse2 package, replacing direct Proparse (JPNode) access with INode / ProparseHelper2 and adding INode-based variants of the supporting DataMemberReport classes. The ported extension is registered in the Proparse2 ProparseTreeViewCustomizerFactory, decoupling it from the underlying Proparse implementation.

ReplaceFieldAndTableReferences TreeView extension ported to the Proparse2 IProparseApi TreeView

The ReplaceFieldAndTableReferencesExtension, used for example during Business Entity migration to replace table and field references in a parse tree, was ported to Consultingwerk.Studio.Proparse2.Extensions and now implements the new IProparseTreeViewCustomizer contract. Direct Proparse access was replaced with the INode, IParseUnit and ProparseHelper2 abstractions, the tree manipulation now builds on ProparseNodeWalker and IProparseNodeAction with an INode-based replace action, and the ported extension is registered in the Proparse2 ProparseTreeViewCustomizerFactory.

ExplainThisCode TreeView extension ported to the Proparse2 IProparseApi TreeView

The ExplainThisCodeProparseTreeViewExtension, which opens ChatGPT with a prompt to explain the code selected in the embedded procedure editor, was ported to Consultingwerk.Studio.Proparse2.Extensions and now implements the new IProparseTreeViewCustomizer contract. The remaining org.prorefactor assembly references were removed, and the ported extension is registered in the Proparse2 ProparseTreeViewCustomizerFactory so it is available in the IProparseApi-based TreeView variants.

ProcedureConverter TreeView extension ported to the Proparse2 IProparseApi TreeView

The ProcedureConverterProparseTreeViewExtension, which adds a ribbon button to launch the ProcedureConverterWizard, was ported to Consultingwerk.Studio.Proparse2.Extensions and now implements the new IProparseTreeViewCustomizer contract. Direct Proparse access was replaced with the INode, IParseUnit and ProparseHelper2 abstractions, and the ported extension is registered in the Proparse2 ProparseTreeViewCustomizerFactory so it is available in the IProparseApi-based TreeView variants.

Pure-ABL Proparse implements the ISymbol:Scope and ITableBuffer-inherits-ISymbol contract extensions

The pure-ABL Proparse implementation now implements the IProparseApi contract extensions introduced with SCL-5450: the ISymbol:Scope property that exposes the owning symbol scope, and the full ISymbol member set on the ABL TableBuffer symbol so it satisfies the extended ITableBuffer interface. The new members are covered by the Stage 5 parity and conformance suite against the ProparseDotNet implementation.

Proparse ABL statement grammar wires the ExpressionParser into the framer with in-statement field/record resolution

The pure-ABL Proparse parser now wires the ExpressionParser into the statement framer at all expression positions (assignments, form items, WHERE clauses, IF/CASE conditions) and brings control-flow and class/procedure framing to full Proparse AST shape. The tree parser resolves fields, records, and variables inside arbitrary statements, including qualified buffer.field references, and the Stage 5 parity suite was extended below statement-head level.

Proparse ABL lexer now normalizes unreserved-keyword-colliding identifiers to ID in identifier positions

The pure-ABL Proparse implementation now normalizes identifiers that collide with unreserved ABL keywords to the ID token type in identifier positions, matching the .NET/Java Proparse engine. This prevents keyword-typed tokens from mis-shaping identifier productions in DEFINE, expression, and Field_ref positions, and is covered by token-parity and parser tests.

IProparseApi contract extended with AST manipulation members for node creation and child/sibling mutation

The IProparseApi contract now exposes AST manipulation members, including a CreateNode factory method for creating synthetic nodes and setters for INode:FirstChild and INode:NextSibling that accept the unknown value to remove all children or truncate the sibling list. Both the ProparseDotNet and ProparseWeb implementations were extended accordingly. This unblocks the INode-based node actions used by the LegacyGuiMigration tooling.

IFrame now exposes ISymbol members (Name, FullName, ProgressType, Scope) in the IProparseApi contract

IWidget (and therefore IFrame) now inherits ISymbol, mirroring the Proparse object model where widget symbols such as Frame extend Symbol. The additional members were implemented in both the ProparseDotNet and ProparseWeb implementations. This lets the tree view tooling report frames as data-member symbols with their name, Progress type, and defining scope.

Fixed: Release notes RSS feed retrieval restored after Atlassian WAF bot challenge broke the direct download

The release notes RSS feed could no longer be downloaded directly because the Atlassian endpoint began answering with an AWS WAF bot challenge instead of the feed content. A new retrieval mechanism replaces the direct createrssfeed.action download in download-rss.p, and a new unit test verifies the feed can actually be downloaded through the new mechanism. No changes required in customer code.

ProparseHelper2 now exposes the full navigation, name-resolution and mutation helper API of ProparseHelper

The INode / IProparseApi-based ProparseHelper2 class was extended to close the public API gap with the JPNode-based ProparseHelper. It now offers the full set of read-only navigation and convenience helpers (ExistsChildNodeByPath, HasChildNodeOfNodeType, FindRoutineParent, child enumeration, name resolution and trigger helpers) as well as mutation and parsing helpers (RemoveNode, ReplaceIndividualNode and a ParseString overload returning an IParseUnit). Developers porting the larger JPNode-based consumers to the INode API can now use these members directly instead of working around the missing methods. Unit test coverage was added for the new members; no changes required in customer code.

Fixed: Links without a source property no longer cause an infinite loop in RenderingHelper

A repository link without a SourcePropertyName (such as FormActionTarget) previously caused an infinite loop in RenderingHelper:ProcessLinks because the query cursor was not advanced in that branch. The loop now advances the query correctly and skips such links. No changes required in customer code.

Release Notes control and Git branches overview on the Start Page are now resizable via a SplitContainer

A SplitContainer (Consultingwerk.Windows.Framework.Repository.Rendering.SplitContainer.SplitContainer) has been added between the Release Notes control and the Git branches overview on the Business Entity Designer Start Page, so developers can freely resize the two areas instead of the Git branches being fixed at 320 pixels. The Release Notes control is placed in the resizing panel and the Git branches overview in the fixed panel, so the Git branches keep their width when the Start Page pane is resized. The existing behaviour is retained: the Start Page is only created when the Display Release Notes At Start setting is enabled, and the drag and drop support of the Release Notes control stays intact.

Delete Branch button added to the Git branches overview control

A Delete Branch button has been added to the toolbar of the Git branches overview control (Consultingwerk.Studio.Git.GitBranchesControl), next to the Refresh button. It is only enabled when the selected branch is neither the current branch nor a protected branch (develop, main, master), asks for confirmation via the framework message dialog before deleting, and offers a force delete when git reports the branch is not fully merged. The capability is provided by a new DeleteBranch(pcBranchName, plForce) method on the Consultingwerk.Studio.Git.IGitBranchesProvider service, which enforces the protection rules through its new ProtectedBranches property and throws a Consultingwerk.Exceptions.Exception carrying the git error when a delete is refused. The branch overview reloads after a successful delete.

Fixed: Keyword case conversion no longer corrupts source when a keyword comes from a preprocessor macro expansion

The KeywordCaseProcessor now reads the source text at the resolved offset before rewriting and skips the node unless it already matches the keyword case-insensitively. Keywords produced by a preprocessor macro expansion (such as {&CLASS} expanding to ENUM) are therefore left untouched instead of overrunning the macro call and corrupting the file, while the remaining literal keywords are still corrected. No changes required in customer code.

Fixed: Keyword case conversion now lowercases ABL HANDLE attributes and methods consistently

The keyword case processor now lowercases attribute and method names of ABL HANDLE references (such as FILE-INFORMATION:FULL-PATHNAME) together with the handle, instead of leaving the part after the colon uppercase. Members of class object references keep their PascalCase, so only ABL system handles and references resolved to a HANDLE are corrected. No changes required in customer code.

Fixed: Keyword case conversion no longer lowercases PascalCase class members that are reserved ABL keywords

The keyword case processor now preserves the casing of class object members (such as oEnum:Label or THIS-OBJECT:Label) even when the member name collides with a reserved ABL keyword. Only attributes and methods of ABL system handles are corrected, so PascalCase property references are no longer silently down-cased. No changes required in customer code; files converted before this fix may contain down-cased properties and should be reviewed.

Fixed: KeywordCaseProcessor now lowercases methods of temp-table, buffer, dataset and query handle references

The KeywordCaseProcessor previously left method and attribute names uppercase for temp-table, buffer, dataset and query handle references, because the allow-list only matched the node immediately to the left of the object colon (the table or buffer name). The processor now also lowercases the attributes and methods of these handle references, while preserving the PascalCase spelling of members on ABL class object references. No changes required in customer code.

Fixed: Keyword case conversion now lowercases attributes and methods of plain HANDLE variables and parameters

The KeywordCaseProcessor now performs a two-pass walk that first collects every name declared AS HANDLE (covering DEFINE VARIABLE, DEFINE PARAMETER, DEFINE PROPERTY, method signature parameters and include files) and then lowercases their attributes and methods, e.g. hQuery:IS-OPEN and hQuery:QUERY-PREPARE. The keyword-all guard on the member name is kept, so PascalCase class members such as oEnum:Label remain protected. No changes required in customer code.

Fixed: convert-lowercase no longer fails when a {&_proparse_} directive follows THEN before a statement

The affected sources were fixed where a {&_proparse_} directive placed between THEN and the statement it guards caused Proparse to consume the directive as the THEN branch, orphaning the following ELSE and aborting keyword case conversion (six sites across SmartRepositoryService, MenuTranslationMaintenanceService and DataTypeHelper). The directives were moved above the IF so the sources convert cleanly while still compiling as before. No changes required in customer code.

Fixed: convert-lowercase now processes classes whose parse chain references a database table

The convert-lowercase tool now adds the project's database connections to its PCTRun task, so Proparse's tree parser can resolve database table references. Classes whose parse chain touches a database table — such as the SmartFramework DataAccess classes that inherit SmartDataAccess and reference the SmartDB SmartTable table — can now be converted to lowercase keywords instead of aborting. The connection is optional so the tool still works standalone for non-database sources. No changes required in customer code.

Database-dependent legacy sources converted to lowercase ABL keywords

The 207 database-dependent legacy sources (179 classes and 28 procedures, mainly in SmartFramework, Studio, Windows and SmartComponentsDemo) that were previously unconvertible have now been swept with convert-lowercase.cmd. Each file now carries lowercase keywords and the @lowercase. annotation, verified against its pre-conversion baseline so that only keyword case changed, non-ASCII content stayed byte-identical, and every down-cased token was confirmed a genuine ABL keyword. This depends on the SCL-5508 converter fix that added the database connection needed to parse these sources.

Fixed: Keyword case conversion now lowercases the no-argument GUID function

The KeywordCaseProcessor now corrects the case of the built-in GUID function when it is used without an argument, which Proparse types as a plain identifier rather than a keyword node. Member references (oObject:Guid) and qualified field references (eTable.GUID) remain unaffected. Affected @lowercase. sources still containing a bare uppercase GUID were also corrected. No changes required in customer code.

Fixed: Dedicated Business Entity by-reference FetchData now works through the ServiceInterface

Fixed a bug in DatasetModelPerformer where a dedicated Business Entity fetch through the ServiceInterface passed the internal chr(1)+GUID entity key to ClassNameToClass. The lookup failed silently, always forcing the by-value path (full dataset deep copy) instead of an output dataset-handle by-reference, and wrote a spurious ignored error to the log on every fetch. The real class name (EntityName) is now used for the class lookup, while the entity key is still used for the dedicated-instance routing. No changes required in customer code.

Fixed: Keyword case conversion now lowercases attributes on chained handle expressions and dataset-buffer (::) references

The KeywordCaseProcessor now resolves the owner of a member reference recursively to the root of the expression chain, so attributes and methods on chained handle expressions (e.g. hDataset:get-buffer-handle(1):BUFFER-FIELD(...):BUFFER-VALUE) and dataset-buffer double-colon references (hDataset::eSmartAttachment:AVAILABLE) are now correctly lowercased during keyword case conversion. Object reference chains keep their PascalCase members. No changes required in customer code.

Static Names Generator (scl-sng) now honors the KeywordCasing setting

The Static Names Generator (scl-sng) now applies the configured keyword case preference to the generated static name Services classes instead of always emitting uppercase keywords. After each class is written, scl-sng-generator.p runs Consultingwerk.Studio.SourceCode.KeywordCaseProcessor:CorrectKeywordCase, driven by the BusinessEntityDesignerSettings:KeywordCasing setting (LOWER / UPPER), and adds the matching @lowercase. or @uppercase. annotation when it is missing. When the setting is not configured, the generated file is left unchanged. This applies both to standalone scl-sng runs and to the StaticNamesGeneratorPlugin path in the Business Entity Designer.

Fixed: KeywordCaseProcessor now corrects the case of the DYNAMIC-PROPERTY built-in function

The KeywordCaseProcessor previously left the DYNAMIC-PROPERTY built-in function uppercase, because Proparse does not know the keyword and types it as a local method reference. The processor now maintains a list of built-in function keywords unknown to Proparse and corrects the case of a LOCAL_METHOD_REF node whose text matches that list; user-defined methods can never collide because these names contain a hyphen. No changes required in customer code.

ProparseAbl now roots the RUN … IN handle expression below the IN_KW node for reference-engine parity

The ProparseAbl statement framer (AblParser RUN statement handling) was updated so that the IN phrase of a RUN statement nests the handle expression below the IN_KW node, matching the reference parse engines. TreeParser:ProcessRun continues to detect the IN option correctly with the new nested shape, and a cross-engine parity test was added covering RUN ... IN THIS-PROCEDURE and RUN ... IN handle. No changes required in customer code.

Added initial full-table data upload to Elasticsearch via the new SmartIndex assembly

This task implements uploading full database tables to Elasticsearch through the new Consultingwerk.SmartIndex assembly. A new command line utility (upload-data.cmd) and ABL procedure (upload-data.p) fetch data from a given Business Entity into a dynamic ProDataset and hand it to the ElasticSearchUploader class, which wraps the .NET SmartIndexer. Developers can configure the index name, key columns, keyword and phonetic fields, and the phonetic encoder; the Elasticsearch endpoint and credentials are read from the elasticsearch section of .applicationsettings. No changes are required in existing customer code.

Added Elasticsearch query capabilities to the SmartComponent Library

This task adds the query side of the Elasticsearch integration, providing a standardized way for applications built on the SmartComponent Library to run searches against the Elasticsearch indices. It defines a query API surface through ABL classes and Business Entity integration and returns search results to callers, supporting full-text search, filtering, paging, sorting, relevance scoring and faceting. Developers can now run searches against Elasticsearch indices directly from Business Entity based application code. This work resurrects and reuses the earlier SmartIndex query effort (SCL-3331).

Added server-side event handling and repository rendering support for the BeforeRetrieveData event of the SmartBusinessEntityAdapter

This improvement adds repository rendering and server-side event handling support for the BeforeRetrieveData event of the SmartBusinessEntityAdapter (MetaDataSource). The server-side event handler payload allows changing the current QueryString and QuerySort and supports a Cancel flag, and is exposed through a dedicated interface. Web rendering of the event handler is implemented in DataSourceWebRendering, with payload mapping added to the EventDispatcherService. Developers can now adjust or cancel a query before data is retrieved - for example to inject a required filter value from the user's session context.

Elasticsearch Data Uploader now supports file-based configuration via -configFile (.elasticupload)

The Elasticsearch Data Uploader now accepts a new -configFile command line argument pointing to a JSON .elasticupload file that can supply all uploader arguments as properties, replacing long and hard-to-quote command lines with a versionable upload definition. The configuration is resolved inside upload-data.p; individual command line arguments override the corresponding file properties, so a stored definition can be reused with a different index name or query string. Unknown or unparseable properties raise a clear error. Existing command lines keep working unchanged, as the new argument is purely additive; a sample .elasticupload file for the Sports2000 Customer upload ships with the framework.

Fixed: QueryEntryTranslator now compiles on OpenEdge 12.2 (extent() syntax compatibility)

The ValueCount method of QueryEntryTranslator now assigns each array holder's Value into a local indeterminate extent variable before calling extent(), so the class compiles on OpenEdge 12.2, where extent() only accepts an array variable rather than a property expression. This is purely a syntax-compatibility refactoring with no behaviour change, and the OpenEdge 12.8 build remains unaffected. No changes required in customer code.

Legacy NativeEnums conditional compilation removed from SmartComponent Library enum definitions

About 120 enum classes across the Consultingwerk packages that relied on the NativeEnums preprocessor switch have been flattened into plain ABL enums, removing the dead legacy branches and preprocessor directives. Explicit numeric member values are preserved where they differ from the ABL defaults. The NativeEnums define in products.i is intentionally kept unchanged so customer code that relies on the switch continues to work. No changes required in customer code.

Fixed: SmartIndex tests no longer hang on OpenEdge releases before 12.7 due to TLS 1.3

The SmartHttpClientLibrary constructor now defaults connections to TLS 1.2 on OpenEdge releases before 12.7, working around a pre-12.7 ABL HttpClient hang that occurs when the server negotiates TLS 1.3 (Progress KB 000258731). ElasticSearchTestHelper registers the SmartHttpClientService so its requests run through the SmartHttpClient stack, which resolves the hanging SmartIndex unit tests. From OpenEdge 12.7 on the behaviour is unchanged, and no changes are required in customer code unless the TLS protocols were set explicitly.

Consultingwerk.iOSAdapter package removed from the SmartComponent Library

The obsolete Consultingwerk.iOSAdapter package (a 2011 iOS demo web service adapter exposing SmartComponentsDemo Business Entities through generated WSDL proxies) has been removed, together with its Business Entity Designer plugin, the build file references and the disabled plugin registration. No changes are required in customer code unless it directly referenced the iOSAdapter package.

Removed dead NoStaticsInHybrids conditional compilation from consuming code

The NoStaticsInHybrids fallback branches, which only applied to OpenEdge 11.2 and 11.3, were removed from roughly 29 sites in consuming code, including SmartDataBrowser and SmartBusinessEntityAdapter; statics in hybrid classes are now used unconditionally. The switch definition in products.i and its variants is kept. No changes required in customer code.

Removed dead PacificAppServer / PacificWebSpeed conditional compilation from consuming code

The classic AppServer and WebSpeed fallback branches, which only applied to OpenEdge releases before 11.5 and 11.6, were removed from roughly 27 sites across the JsdoGenericService, REST resource and web handler layers; the PASOE code path is now used unconditionally. The switch definitions in products.i are kept. No changes required in customer code.

Removed dead AblReflection / NoAblReflection conditional compilation from consuming code

The NoAblReflection fallback branches, which only applied to OpenEdge releases before 11.6, were removed from roughly 26 consuming source files, including central OERA and framework classes such as DataAccess, ServiceInterface and Factory; the reflection-based code path is now used unconditionally. The switch definition in products.i is kept. No changes required in customer code.

Fixed: UserTableStats now correctly reports delete-only index activity

The change-detection guard in the index statistics loop (GetTableIndexStats) of UserTableStats used an inverted comparison for the delete counter, causing delete-only index activity to be skipped and a stale delta to be re-reported on a later snapshot. The guard has been corrected so that index delete activity is reported once per interval, consistent with the table statistics loop. This mainly affects consumers that snapshot repeatedly, such as RequestUserTableStatsMonitor. No changes required in customer code.

Fixed: Cold-start resolution of ISmartRepositoryService no longer throws ServiceAlreadyRegisteredException

An issue where the first resolution of ISmartRepositoryService in a cold session (with no services.xml preregistration) could fail with a ServiceAlreadyRegisteredException has been fixed. The cause was a nested, recursive service registration triggered when SmartRepositoryService filled its object type cache during construction, which caused ServiceNameMappingService.AutoMapFromRepository to register a second instance before the outer registration completed. The framework now resolves and registers the repository service without this hidden side effect. No changes required in customer code.

Fixed: OpenEdge 11.7 compiler crash on Proparse lexer classes caused by a method named Defined

The Defined methods in four ProparseAbl lexer classes (Preprocessor, FoldedPreprocessor, Postlexer and FoldedLexer), together with their call sites, were renamed to EvaluateDefined to work around an OpenEdge 11.7 compiler access violation that occurred when a class declared a method named Defined alongside an &IF DEFINED preprocessor block. This unblocks the OpenEdge 11.7 and Customer builds; the change is behaviour-neutral on OpenEdge 12.8 and 13.0. No changes required in customer code.

UnsupportedAttributesReport no longer crashes on partially-assigned SmartAttributeValue records

The UnsupportedAttributesReport scan filter was extended to skip SmartAttributeValue records with an empty ObjectTypeGuid, which a concurrent no-lock reader could otherwise observe in a partially assigned state and which caused GetObjectTypeName to throw. The report can now run safely while other sessions write repository data such as deployments, imports or designer activity. No changes required in customer code.

Fixed: Release notes proxy now retrieves entries via the ReleaseNotesDownloader instead of the blocked RSS feed

The ReleaseNotesProxyBusinessTask backend endpoint that serves release notes to the web frontend now retrieves data through the ReleaseNotesDownloader and ReleaseNotesParser mechanism instead of the direct Confluence RSS download, which had been blocked by the Atlassian WAF bot challenge and caused the frontend to always receive an empty response. Retrieval failures are no longer forwarded as a successful empty result, so the frontend can distinguish "no release notes" from a broken retrieval. No changes required in customer code.

Fixed: Repository lookup properties now resolved server-side so web input prompt lookups render correctly

The backend now resolves the full inline lookup definition (entity name, table and key field) from the repository before returning the input prompt response to the web frontend, so input prompts configured with only a lookup name now render as proper lookups instead of plain text fields. The GUI for .NET client keeps resolving lookup names on its own side and is unaffected. No changes required in customer code.

Editor buttons now support per-button enabled states in the repository and web rendering

Four new CHARACTER attributes (EditorButtonEnabledForUpdate, EditorButtonEnabledForAdd, EditorButtonEnabledOnCopy and EditorButtonAlwaysEnabled) were added to the MetaField object type and are inherited by all its descendants such as text boxes, combos and lookups. They are editable in the Repository Designer and drive an optional enabledState member rendered per button into inputSettings.EditorButtons, so an editor button can be kept enabled even while its host field is read only or the viewer is not in update mode. Editor buttons on fields that do not use the new attributes render exactly as before.

Smart File Picker now supports the returnRelativePath option in JSON rendering

The JSON rendering of the Smart File Picker input now supports the returnRelativePath property inside filePickerOptions. When set to true, the file picker returns the selected path relative to the configured folder scope instead of an absolute path. Developers enable this by adding returnRelativePath to the filePickerOptions of a filepicker input definition, alongside options such as selectionMode, folderScope and allowCreateFolder.

Session Info dialog now shows Windows Display Version, Current Build and UBR

The Process page of the Session Info dialog (SessionInfoForm:PopulateProcess) now displays three additional Windows values - Windows Display Version, Windows Current Build and Windows UBR - alongside the existing Windows Product Name and Windows Build. The values are read from the registry via Consultingwerk.Framework.Registry:GetRegistryValue, so no additional process is spawned. This lets developers read the exact Windows patch level (including the cumulative update revision) directly from the dialog, which is useful when diagnosing machine-specific issues. Windows only.

Fixed: attribute value search no longer fails when a referenced repository object is deleted concurrently

The attribute value search (AttributeValueSearchBusinessTask) no longer fails with an InvalidParameterValueException when a repository object referenced by a matching attribute value is deleted or rolled back concurrently. The name-resolution loops now tolerate GUIDs that no longer resolve and drop the affected result rows from the search result instead of failing the whole request. No changes required in customer code.

Fixed: MetaBusinessEntityBusinessEntity:ValidateData now resolves relation InstanceName from the correct buffer

In ValidateData, the relation InstanceName was resolved from the wrong buffer (eMetaEntityTable instead of eMetaDataRelation) and could invoke a method on an uninitialized repository service reference, leading to runtime errors such as "no eMetaEntityTable record available". The fix now resolves the relation's own object master GUID, applies the same lazy repository service initialization as the surrounding blocks, and uses the non-throwing GetObjectMasterName overload. No changes required in customer code.

SplitContainer control moved to Consultingwerk.Windows.Controls to remove SmartFramework dependency

The SplitContainer control and the SplitContainerPanelEnum were moved from the Consultingwerk.Windows.Framework.Repository.Rendering.SplitContainer package to the always-shipped Consultingwerk.Windows.Controls package. This removes the dependency of the Business Entity Designer on the SmartFramework packages, so it now compiles in deployments that do not use them. The repository-specific SplitContainerRenderer class remains in its original package and now references the moved control. This is a breaking change: code referencing the old fully qualified class names (including the SplitContainerPanelEnum) must update its using statements to Consultingwerk.Windows.Controls.

Fixed: QuickSearch web rendering now emits helpText and helpUrl attributes in the JSON layout

The QuickSearchWebRendering class did not include the shared render-help include, so the helpText and helpUrl attributes were never emitted into the component's settings JSON and the Angular QuickSearch component could not display help text. The include was added, following the pattern of the other form component renderings, and the settings object is now also created when only HelpText or HelpUrl is set. When neither attribute is set, the rendered JSON is unchanged. No changes required in customer code.

Fixed: BusinessEntityDesignerServices now compiles in deployments without SmartFramework (Mcp package excluded)

The generated BusinessEntityDesignerServices class referenced the excluded McpServices type unconditionally, which caused a compile error in deployments where the Mcp package is excluded. The Mcp property is now guarded by an &if defined (SmartFramework) preprocessor block, with the required products.i include added to the generated file, and a unit test verifies that the guard and include are preserved when the services file is regenerated. No changes required in customer code.