---
title: "Toolbox (asset type)"
description: "A toolbox is a namespace folder that groups related .tool/ children plus shared helpers. Toolboxes are the addressing layer for tools — every tool's identity is <toolbox>.<name>, so the toolbox name…"
section: "Types"
slug: "types-toolbox"
canonical: "https://origozero.ai/docs/types-toolbox"
updated: "2026-09-05T16:41:47.518538631+00:00"
tags: ["asset-type", "reference"]
---

# Toolbox (asset type)

## When to use one

- You have two or more related tools that belong together (an `anim`
  toolbox with `play` / `stop` / `list`; an `assets` toolbox with
  `compose` / `validate`).
- You need a shared helper module exclusively used by a tool set.
- You want a clean dot-namespaced identity for your tools
  (`my_tools.foo`, `my_tools.bar`).

If you only have one tool and no shared helpers, you still need a
toolbox — it's the required parent.

## Where it lives

- Source: `/zero/source/.../<Name>.toolbox/`
- Identity: `<Name>` (the `.toolbox` suffix strips).
- Folder shape (container-style — open child set):
  - `README.md` — instance documentation. **Required.**
  - `.metadata` — agent-editable tags + free-form fields. **Required.**
  - `shared.module/` — optional shared helper module
    (`init.luau` + `README.md`).
  - `<x>.tool/` — any number of `.tool/` children.

The validator permits unlisted children (`allow_unlisted: true`) so
tool subfolders don't need to be declared per-name.

## How to create one

```luau
tools.createToolbox({ name = "<Name>", description = "..." })
-- or the generic scaffold:
asset.create("toolbox", "<Name>")
-- Creates: /zero/source/<Name>.toolbox/
--   README.md            (instance README template)
--   shared.module/       (ok / fail result-envelope constructors)

-- `folder` places it in a subfolder of /source; `into` nests it in a
-- resolved `.package`:
asset.create("toolbox", "<Name>", { folder = "tools" })
```

Then add tools under it:

```luau
local box = asset.resolve("<Name>.toolbox")
asset.create("tool", "<toolName>", { into = box })
```

## How it operates

1. **Registration.** Writing into a `.toolbox/` folder indexes the
   toolbox. It becomes the parent namespace for any `.tool/`
   children.
2. **Tool identity composition.** Each child `.tool/`'s identity is
   `<toolbox>.<tool>`. Listing the toolbox's tools enumerates the
   children.
3. **Shared helpers.** Tools inside the toolbox pull
   `shared.module/` in via `require(".shared")` (relative require
   from the tool's `init.luau`).
4. **Hot reload.** Editing `shared.module/init.luau` reloads every
   tool in the toolbox (they all `require` it). Editing the toolbox
   folder structure (adding / removing tools) reflects in
   `tools.list` immediately.

## Discovery

- `asset.list("toolbox")` — every registered toolbox.
- `asset.inspect("<name>")` — child tools, source, this type
  README.
- `cat /zero/source/<Name>.toolbox` — same summary.
- `tools.list()` — every tool across every toolbox.

## Authoring conventions

- **Per-tool implementation lives in each `<x>.tool/init.luau`.**
  The tool's full function body — argument validation, the call
  into engine APIs, the return value — goes in `init.luau` with
  `--!desc` / `--!arg` / `--!return` / `--!example` annotations
  above the function. **Every exported function is declared
  `typed function`** — the keyword compiles to the runtime argument
  check, so a plain `function` accepts any input and reports success
  on garbage. Do NOT make `init.luau` a one-line forwarder onto a
  function defined in `shared.module/`.
- Keep `shared.module/` thin: result envelope constructors
  (`shared.ok(value, formatted)`, `shared.fail(message, exitCode)`),
  argument validators, common formatters — anything genuinely used
  by more than one tool. Per-tool logic does NOT belong here.
- Group by domain, not by surface — `assets` toolbox holds asset
  operations, `entity` toolbox holds entity operations. Tools that
  feel unrelated probably want different toolboxes.
- Document the toolbox's surface in `README.md` — what problem space
  it covers, who calls into it, any shared invariants.

## Common pitfalls

- **Missing parent toolbox.** Tools cannot exist outside a toolbox.
  Always scaffold the toolbox first.
- **Cross-toolbox shared.** Each toolbox has its own
  `shared.module/`. Don't try to share helpers across toolboxes; if
  you need cross-toolbox helpers, factor them into a standalone
  `.module`.
- **Toolbox identity.** Strip the `.toolbox` suffix in identity
  references (`my_tools`, not `my_tools.toolbox`).

## Related types

- `.tool` — the required child(ren) of a toolbox.
- `.module` — for cross-toolbox utilities.
