Drive more traffic, capture more leads, and grow your business.
The TypeStack Magic prompt field is more than a text box. Under the hood it can trigger tools, write files, and even create new pages – as long as you give it clear, structured instructions.
There are three main ways to talk to the Agent:
TEST and FILE-TEST.aOperations (the real power).For quick checks you can use two built-in commands without JSON:
TEST – end-to-end health check. Returns a JSON response with sMode = "test" and confirms that the AJAX and JSON pipeline is working. FILE-TEST – filesystem selftest. Writes a small test file in data/agent/fs-test.txt using the AgentToolFileSystem tool, and returns detailed debug info. If these two work, your Agent stack (routing + JSON + filesystem) is good to go.
aOperations For real work, the Agent expects a JSON object in the prompt. The root object contains an array called aOperations. Each entry in that array is one operation with:
sTool – which tool to call (for example "fs", "page", "env").sMode – what that tool should do.aArgs, sBase, sPath, sContent, …) depending on the tool. The Agent will execute each operation in order and return a JSON response with both the requested operations and an aOpResults block with detailed results and debug lines.
Currently the Agent supports three tools:
fs – filesystem helper (read, write, append, replace) in safe, sandboxed paths. page – creates new pages in the CMS (structure item, translation, page record, grid, content). env – reads basic environment info from the current TypeStack session or responds to a simple ping. More tools can be added over time by implementing new AgentTool* classes and wiring them into AgentPrompt::HandlePrompt().
sTool = "fs") This example appends a line to data/agent/agent-selftest.log in the application layer:
{ "aOperations": [ { "sTool": "fs", "sMode": "append", "sBase": "app", "sPath": "data/agent/agent-selftest.log", "sContent": "Selftest from TypeStack Magic\\n" } ]
} sBase = "app" → use the application root from the session.sPath is relative to that base.sMode = "append" → the content is added to the end of the file. If the file does not exist, it is treated as empty and created. \\n are converted to real newlines before writing, so you can safely generate multi-line code from a JSON prompt. sTool = "page") This example creates a new page under structure_id = 7 (for example the homepage), using template 1, and writes an initial HTML block into the first slide of that template:
{ "aOperations": [ { "sTool": "page", "sMode": "create-page", "aArgs": { "sTitle": "TypeStack Magic – Agent documentation", "sSubtitle": "How the Agent reads, writes and builds pages", "sDescription": "Internal documentation page generated by the Agent.", "sCase": "typestack-magic-agent-docs", "iParentStructureID": 7, "iTemplateID": 1, "sContentHTML": "<h1>TypeStack Magic</h1>\n<p>This page was created by AgentToolPage.</p>" } } ]
} Internally, the Agent will:
cms_structure row under iParentStructureID.cms_structure_translations row with sTitle and sCase.cms_pages row for the current substance with page_template_id = iTemplateID.cms_template_grid into cms_page_grid and attach the page. cms_content row for that slide with content_html = sContentHTML in the current language. The JSON response will include the new iStructureID, iPageID, iContentID and a detailed aDebug trail with every step.
sTool = "env")You can also query basic environment details from the current TypeStack session:
{ "aOperations": [ { "sTool": "env", "sMode": "info", "aArgs": {} } ]
} This returns an aEnv block with values like: sApplicationRoot, sCoreRoot, iInstanceID, sDomain and sDeviceType, plus debug lines showing what was read.
Using "sMode": "ping" will simply echo back a message and confirm connectivity.
Every call to AgentPrompt::HandlePrompt() returns a JSON response:
bSuccess – global success flag.sMode – how the prompt was interpreted ("test", "file-test", "operations", "echo", …).sMessage – human-readable status.sQuestion – the original prompt text.aDebug – logbook with all debug lines for this run.aOperations: aOperations (what you asked) and aOpResults (what happened per operation). This makes it easy to let an external AI (or a human developer) inspect the logbook, learn from it, and send better prompts next time.
TypeStack Magic sends a single field (sQuestion) to the backend. The AgentPrompt class interprets this field in different modes:
All responses are JSON and include a high level status plus detailed debug information for each operation, so you can see exactly what happened on the server.
File operations are always performed relative to a logical base path, controlled by sBase:
$_SESSION['TypeStack']['sApplicationRoot']).$_SERVER['DOCUMENT_ROOT'] where possible, or falls back to public_html / private_html under the application root.$_SESSION['TypeStack']['sCoreRoot']). You select the base per operation via "sBase": "app", "sBase": "web" or "sBase": "core".
The behaviour of TypeStack Magic depends on the content of sQuestion:
TEST or PING, the agent enters the test mode (no filesystem access).FILE-TEST, the agent performs a simple write operation in the app sandbox.{, the agent tries to decode it as JSON and looks for aOperations.To verify that the AJAX chain and JSON parsing work, type:
TEST
or:
PING
Typical response:
{ "bSuccess": true, "sMode": "test", "sMessage": "AgentPrompt test route OK.", "sQuestion": "TEST", "aDebug": [ "Mode: test", "Time: 2025-12-04 23:59:59", "Note: this route never touches the filesystem." ]
} This route never touches the filesystem and is designed to always work as long as the backend can execute PHP and return JSON.
To test whether the agent can write to disk in the app base, type:
FILE-TEST
The agent will:
data/agent/fs-test.txt under sBase: "app".overwrite with a timestamped string.ProcessFileOperation() which internally uses AgentToolFileSystem::ReadFile() and AgentToolFileSystem::WriteFile(). The response includes a single entry in aOpResults:
{ "bSuccess": true, "sMode": "file-test", "sMessage": "FILE-TEST completed.", "aOperations": [ { "sBase": "app", "sPath": "data/agent/fs-test.txt", "sMode": "overwrite", "sContent": "FILE-TEST from AgentPrompt at ..." } ], "aOpResults": [ { "iIndex": 0, "aOp": { ... }, "aResult": { "bSuccess": true, "sMessage": "File operation completed.", "iNewLength": 48, "aWrite": { "bSuccess": true, "sMessage": "File written successfully.", "sBase": "app", "sPath": "data/agent/fs-test.txt", "iSize": 48, "aDebug": [ "WriteFile: sBase = app", "WriteFile: sPath = data/agent/fs-test.txt", ... ] }, "aDebug": [ ... ] } } ]
} On disk, the file appears under the application root, for example:
/home/typest19/domains/typestack.com/data/agent/fs-test.txt
aOperations When the prompt starts with {, the agent attempts to decode it as JSON. If the JSON contains aOperations as an array, each entry represents one file operation. All operations are processed in order, and each one produces a separate result in aOpResults.
Basic structure:
{ "aOperations": [ { "sBase": "app|web|core", "sPath": "data/test.txt", "sMode": "overwrite|append|replace|read", "sContent": "...", // for overwrite/append "sSearch": "...", // for replace "sReplace": "..." // for replace } ]
} Supported modes:
sContent.sContent.str_replace(sSearch, sReplace, oldContent) to the existing content.sContent in the result without calling WriteFile().data/test.txt (app base) To overwrite data/test.txt under the application root:
{ "aOperations": [ { "sBase": "app", "sPath": "data/test.txt", "sMode": "overwrite", "sContent": "Hello from TypeStack Magic after update" } ]
} The agent will read the existing file (if present), then write the new content via WriteFile(). The final length is reported as iNewLength in the result.
To keep a lightweight log in the app base, you can append to data/agent/agent-selftest.log:
{ "aOperations": [ { "sBase": "app", "sPath": "data/agent/agent-selftest.log", "sMode": "append", "sContent": "[SELFTEST] App layer OK at 2025-12-04 23:59:59\n" } ]
} If the file does not yet exist, it is treated as empty and created automatically.
To write a test file under the current web root (DirectAdmin-aware), use sBase: "web":
{ "aOperations": [ { "sBase": "web", "sPath": "data/agent/agent-web-selftest.txt", "sMode": "overwrite", "sContent": "Hello from TypeStack Magic on web base" } ]
} The agent will resolve the web base using DOCUMENT_ROOT or public_html/private_html under the application root. The resulting file is typically available via HTTP.
You can chain multiple operations in a single JSON prompt. For example:
{ "aOperations": [ { "sBase": "app", "sPath": "data/agent/agent-selftest.log", "sMode": "append", "sContent": "[SELFTEST] Combined operation started\n" }, { "sBase": "app", "sPath": "data/agent/fs-selftest-app.txt", "sMode": "overwrite", "sContent": "App base OK" }, { "sBase": "web", "sPath": "data/agent/fs-selftest-web.txt", "sMode": "overwrite", "sContent": "Web base OK" }, { "sBase": "app", "sPath": "data/agent/agent-selftest.log", "sMode": "append", "sContent": "[SELFTEST] Combined operation finished\n" } ]
} The response will contain four entries in aOpResults, one for each operation, each with its own bSuccess flag and debug output.
data/test.txt If data/test.txt currently contains Hoi Open AI :), you can replace that text via:
{ "aOperations": [ { "sBase": "app", "sPath": "data/test.txt", "sMode": "replace", "sSearch": "Hoi Open AI :)", "sReplace": "Hello from TypeStack Magic after replace" } ]
} Internally this becomes:
str_replace("Hoi Open AI :)", "Hello from TypeStack Magic after replace", oldContent); The modified content is written back using WriteFile(), and the new length is reported in iNewLength.
sMode = "read") In addition to overwrite, append and replace, the agent supports a pure read-only mode using sMode: "read". This is useful when the agent needs to inspect a file before deciding how to modify it.
Example prompt to read data/test.txt under the application base:
{ "aOperations": [ { "sBase": "app", "sPath": "data/test.txt", "sMode": "read" } ]
} The response will include an entry similar to:
"aOpResults": [ { "iIndex": 0, "aOp": { "sBase": "app", "sPath": "data/test.txt", "sMode": "read" }, "aResult": { "bSuccess": true, "sMessage": "Read operation completed.", "sMode": "read", "sBase": "app", "sPath": "data/test.txt", "sFullPath": "/home/typest19/domains/typestack.com/data/test.txt", "sContent": "The current file content...", "aDebug": [ "ProcessFileOperation called.", "sBase = app", "sPath = data/test.txt", "sMode = read", "ReadFile succeeded in read mode.", "ReadFile: content length = 123" ] } }
] Read mode respects the same base rules as other operations: sBase: "app" reads from the application root, sBase: "web" reads from the current web root (DirectAdmin-aware), and sBase: "core" reads from the core path (read-only).
When writing .php or .class.php files via TypeStack Magic, you should not include the <?php opening tag in sContent.
The agent will automatically prepend a PHP opening tag on the server side for these files. This avoids issues with security filters that may block PHP code in HTTP request bodies, while still ensuring that the resulting file is a valid PHP file on disk.
In other words: send only the class body, and let the backend handle the <?php tag.
If the prompt does not match TEST, PING, FILE-TEST and does not start with {, the agent enters echo mode:
{ "bSuccess": true, "sMode": "echo", "sMessage": "AgentPrompt echo mode – no JSON detected, no file operations executed.", "sQuestion": "your original prompt..."
} Echo mode is useful as a simple debug tool: you see exactly what the server received, without any side effects on the filesystem.