extension purpose

Extensions are Lua programs loaded by zi. They let users shape the agent without rebuilding the Zig core. The concrete host functions are listed in extension api: zi table, and handler context is documented in context object.

Use extensions for things like:

Extensions describe what should happen. zi decides how to schedule work, update the terminal UI, store session data, call providers, and render transcript output.

extension discovery

An extension root is a directory-like container. zi discovers extensions from the extensions/ folder:

<root>/
├─ extensions/
│  ├─ foo.lua
│  └─ bar/
│     └─ init.lua
├─ lua/
├─ prompts/
├─ skills/
├─ themes/
├─ agents/
└─ after/

Supported extension shapes:

extensions/<id>.lua
A flat single-file extension.
extensions/<id>/init.lua
A bundled extension with extension-local modules next to init.lua.

When multiple roots provide the same kind of capability, zi resolves precedence in this order:

explicit > user > project > builtin

Within a root, discovery is lexical and deterministic. Most duplicate registrations use first claimant wins. Commands are different: duplicate command names stay callable through resolved invocation names in commands.

extension loading

The host installs a global zi table into the extension Lua state. Extensions may either register directly at top level or return a function that receives zi:

return function(zi)
  zi.register_tool({
    name = "greet",
    description = "Generate a greeting.",
    parameters = {
      type = "object",
      properties = {
        name = { type = "string", description = "Name to greet" },
      },
    },
    execute = function(params, ctx)
      local name = params.name or "world"
      return {
        content = { { type = "text", text = "hello, " .. name } },
      }
    end,
  })
end

Load/register is non-suspending. Do not perform long work while the extension loads. Register capabilities, initialize cheap local state, and defer work to commands, tools, events, jobs, or host-owned prompts.

extension lifecycle

An extension has two kinds of work:

Important rules:

Common lifecycle events are session_start, session_shutdown, session_before_switch, and session_before_fork.