Minimal working Bricklayer code-runner examples: inspecting Magento at runtime safely

Just enough examples to let Your AI agent run PHP inside Magento without breaking anything.

Sometimes the fastest way to answer a question about a store is to just ask Magento. What does this repository return for that SKU? Which class does the ObjectManager give me in the frontend area? We all have a test.php in the root for exactly that. code-runner is the same idea, but built for agents and with guard rails.

code-runner(code, area="", allow_write=false, timeout=30, mode="execute")
Parameter Default Description
code required PHP code, without <?php tags
area "" frontend, adminhtml, webapi_rest, graphql, crontab, global
allow_write false when false, DB changes are rolled back
timeout 30 max execution time in seconds
mode execute execute runs code; define saves reusable functions for the session

The safety model in short:

  • every call runs inside a DB transaction that is always rolled back unless allow_write=true, so You will see read_only: true even for code that writes nothing
  • code is checked against 9 dangerous patterns: shell execution, file writes, superglobals, cURL, eval, header manipulation, global handler registration, long sleeps
  • no network access for executed code
  • disabled in production deploy mode, no way around it
  • runs through PsySH when available (it ships as a dependency), eval as a fallback; bricklayer verify tells You which one

Helpers and examples

Inside the executed code You get:

  • $get(ClassName::class) - singleton from the DI container
  • $create(ClassName::class, ['arg' => val]) - new instance
  • $repo(RepositoryInterface::class) - alias for $get(), reads nicer for repositories
  • $config('section/group/field') - system config value
  • query('SELECT ...', $binds) - read-only SELECT, returns rows
  • runLog($value, 'label') - capture values into the response log key

Full guide with variables, areas and examples is one call away: code-runner-help.

  • Read a product through the service layer:
code-runner(code="return $repo(\Magento\Catalog\Api\ProductRepositoryInterface::class)->get('24-MB01')->getName();")
  • Which implementation does the frontend area actually get?
code-runner(area="frontend", code="return get_class($get(\Magento\Checkout\Model\Session::class));")
  • Config value and a quick query, both captured:
code-runner(code="runLog($config('web/secure/base_url'), 'base_url'); runLog(query('SELECT COUNT(*) AS c FROM catalog_product_entity'), 'products');")
  • Reusable functions for the session (mode=define, max 20, cleared on reinitialize):
code-runner(mode="define", code="function getProductBySku($sku) { return get(\Magento\Catalog\Api\ProductRepositoryInterface::class)->get($sku); }")
code-runner(code="$p = getProductBySku('24-MB01'); return $p->getName();")

Every response includes metrics: execution time, memory delta, peak memory and number of queries. Handy for a quick “how expensive is this load” check.

Writes and limits

Want the change to stick? Check both places:

  • tools.code-runner.allow_write in .bricklayer.json must allow it (developer default is false)
  • the call itself must pass allow_write=true
vendor/bin/bricklayer config:set tools.code-runner.allow_write true

My advice: leave writes off. If the agent needs to change data, the catalog, order and customer tools go through Magento’s service layer and each one can be switched on or off separately. code-runner is for looking.

  • tools.code-runner.max_timeout caps the timeout parameter (default 60)
  • in production code-runner is hard-blocked, the config file can not enable it
  • functions defined with mode=define live until the session ends or reinitialize runs

Start coding!

Source: GitHub