Pacific Blue Software Logo

Using an AI Coding Assistant with TMS WEB Core

Using an AI Coding Assistant with TMS WEB Core

TMS WEB Core compiles Delphi code to JavaScript with pas2js. An AI coding assistant knows a great deal about Delphi and a great deal about JavaScript, but very little about the narrow space between them. Asked to do something in the browser, it reaches for what it knows best: an asm block full of JavaScript.

That code works, but it is code the Pascal compiler cannot check, the IDE cannot navigate, and the next person to read the project has to understand in two languages. The aim of this article is to keep the assistant writing Pascal, and to give it the WEB Core and XData knowledge it lacks.

For setting up Claude Code on a Delphi project in general, see Using Claude Code on a Delphi Project; this article covers what is different for the web.


Pascal Instead of asm Blocks

Most of what an assistant puts in an asm block can be written in Pascal. The browser's objects are available as Pascal classes in the WEB and JS units, so this:

asm
  document.getElementById('status').innerHTML = 'Saved';
end;

is simply:

document.getElementById('status').innerHTML := 'Saved';

with WEB in the uses clause. The Pascal version is checked by the compiler, found by Find References, and survives a rename. Better still, bind the element to a WEB Core control through its ElementID and set the control's properties.

Say it plainly in CLAUDE.md: no asm blocks unless there is no Pascal way, and if there is not, ask first. Assistants follow that rule well once it is written down.


Styling Belongs in HTML and CSS

The other habit to break is setting colours, sizes and visibility in code. An assistant asked to "make the error message red" will set a style property from Pascal - or, worse, from JavaScript. In a web project the right place is a CSS class in the stylesheet, and the code only switches classes:

Error_Label.ElementClassName := 'error_text';

This keeps the look of the application in one place, where a designer - or you, later - can change it without recompiling. HTML and CSS are also where an assistant is at its strongest, so let it work on the form's .html template and the stylesheet freely.


What It Does Not Know About pas2js

pas2js accepts most of modern Delphi, but not all of it, and an assistant will write desktop Delphi unless told otherwise. The common failures:

Each of these is one line in CLAUDE.md, and each line saves a round of "that does not compile in the browser".


What It Does Not Know About XData

The quirk that causes most confusion: when XData sends an object as JSON, fields whose names start with F lose the F. A class with a field FCustomer_Id arrives in the browser as Customer_Id. An assistant writing the client side will look for FCustomer_Id, find nothing, and - without an error - carry on with an empty value. When it builds JSON to send, it may add the F and have the server ignore the field.

It also does not know your service contracts unless it can read them. Give it the folder with the server's interface units, even if they belong to a different project, and say in CLAUDE.md where they are. Whether a service operation is called with GET or POST changes how the client calls it - covered in GET or POST for TMS XData Service Operations.


A CLAUDE.md for a WEB Core Project

# Customer Portal - TMS WEB Core client, XData server

## Language
- This is pas2js, not desktop Delphi. Code must compile with pas2js.
- No asm blocks. Use the WEB and JS units for browser objects. If
  something cannot be done in Pascal, stop and say so before writing JS.
- No AnsiChar, AnsiString, ShortString, PChar, Variant or SizeOf.
- Int64 is exact only to 2^53. IDs from the server arrive as strings.
- Do not pass nested procedures as callbacks to overloaded TMS methods;
  use a form method or a component event.
- Forms load asynchronously: only use a form's controls once it has loaded.

## Styling
- All styling in CSS (css\portal.css). Code only sets ElementClassName.
- Form layout is in each form's .html template.

## XData
- Server interfaces: ..\Server\Services\*.pas (read only).
- JSON drops the leading F from field names: FCustomer_Id is Customer_Id.

## Build
- I build in the IDE and paste errors. Say which files you changed.

Checking Its Work


Summary


Keeping the AI Writing Pascal in the Browser


Back to Articles for Developers
Back to Articles on AI
Back to Articles on Delphi
Sharing Units Between VCL and TMS WEB Core