# Empryo Cells — task map for agents > A Cell is one JSON file (.empryo/morphs/.json) that extends the Empryo desktop app: panels, status chips, toolbar buttons, /commands, key chords, live feeds, triggers, and an agent layer (rules, lookups, guards, state). A cell can also BE the workspace: a canvas board takes the window in place of the chat, its lanes and columns filled from an API, a folder of the checkout (files://specs/*.md), a live socket (wss://) or the engine itself, and its cards start real agent runs. Each section link below returns JSON containing the exact reference text and citation URLs. Validate a file against the JSON Schema: https://empryo.com/morphs.schema.json · full page: https://empryo.com/docs/tools/morphs.md · search: https://empryo.com/api/docs/search?q=&scope=morphs ## Retrieval prompt Fetch https://empryo.com/docs/tools/morphs/llms.txt, pick the sections for the task, fetch each sectionUrl (fragments are citation anchors, not HTTP section selectors), then write the cell and check it against https://empryo.com/morphs.schema.json. Cite sections by their .md#anchor URL. ## Create a cell - [Work it directly](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=work-it-directly): A morph's panel is something you use directly. It is not just a row of buttons that write prompts. For each control, the author picks what it does: (~533 tokens) - [The agent layer › Example: a morph the agent works inside](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=example-a-morph-the-agent-works-inside): With this morph on: (~342 tokens) - [Shapes](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=shapes): What you build is up to you. These are examples of what people have made, not a fixed menu: (~272 tokens) - [Example: the one-page work hub](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=example-the-one-page-work-hub): Tickets, pull requests and docs in one panel, so the agent can work on a ticket without you switching apps. (~658 tokens) - [Manage](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=manage): **Cells & Morphs** lists every morph with what it adds, its status (live, off, or broken with the reason) and an on/off switch. You can search, filter by status or by morph, and delete with a two-step confirmation. **Share** copies a… (~120 tokens) ## Surfaces (panels, chips, buttons, commands) - [The UI layer](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=the-ui-layer): An action can have `layout`: a **Focus** button that rearranges the window when clicked. It takes one true/false value per pane: `sidebar` (the file tree), `context`, `map`, `terminal`, `browser`, `cells`, `canvas`, `graph`, `plan`,… (~1243 tokens) - [Toolbar](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=toolbar): Up to six buttons. `label` is the tooltip. `glyph` is one of `sparkles zap bug rocket book git list bell chart globe shield wrench clock flag star terminal`, or any Lucide icon name. An unknown glyph shows the morph's icon. Each button… (~74 tokens) - [Icons](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=icons): You can use any [Lucide](https://lucide.dev/icons) icon by its kebab-case name: `music`, `git-pull-request`, `circle-check`, `triangle-alert`. (~236 tokens) - [Helper](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=helper): A morph that needs something from your computer (Spotify's current track through AppleScript, a build's status, a sensor) can declare a program that provides it: (~454 tokens) ## A board instead of the chat: canvas, grid, lanes, runs, slots - [The agent layer › Grid, putting things where you want them](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=grid-putting-things-where-you-want-them): Every other block says *what* to show. `grid` says *where*: (~238 tokens) - [The agent layer › How a board arranges itself](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=how-a-board-arranges-itself): `layout` decides the shape. The default is usually the right choice: (~276 tokens) - [The agent layer › The canvas, a board instead of the chat](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=the-canvas-a-board-instead-of-the-chat): `"place": "canvas"` gives a morph the whole window. The chat is not closed. It moves aside, and every tab keeps working behind the board. Press **Chat** (or run `/canvas` again) to switch back. (~401 tokens) - [The agent layer › A pipeline, not just a list](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=a-pipeline-not-just-a-list): A board can have a second direction. Give it `lanes` and each lane becomes a row of cards across the columns. The lane is the thing that moves (a spec, a ticket, a release) and the column is the stage it is in. (~293 tokens) - [The agent layer › Motion, when the movement is the point](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=motion-when-the-movement-is-the-point): A morph's own code (a `view` block) gets the app's animation library, [anime.js](https://animejs.com), already loaded. There is nothing to install: (~297 tokens) ## Sources: a folder of files, a live socket, the engine - [The agent layer › A folder of files as the data](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=a-folder-of-files-as-the-data): A feed's `url` can be `files://specs/*.md`: files in the project you have open. No network and no keys are needed. (~419 tokens) - [The agent layer › Live sources, the feed pushes, you don't poll](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=live-sources-the-feed-pushes-you-dont-poll): A feed's `url` can be `wss://…` (or `ws://127.0.0.1:…` for something running on your own machine). The app keeps the connection open while the morph is on, and each message from the server becomes rows right away. There is no interval and… (~403 tokens) - [The agent layer › The engine as a source, and buttons that act](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=the-engine-as-a-source-and-buttons-that-act): A pulse's `url` can read data from Empryo itself: (~489 tokens) - [The agent layer › Naming the facts a row carries](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=naming-the-facts-a-row-carries): Some `map` keys fill a part of the card: `text`, `detail`, `badge`, `group`, `tone`, `href`, `id`, `desk`, `tab`, `image`, `attach`, `icon`, `prompt`. **Any other key is a named fact on the row.** You can use it as `{{owner}}` in a run's… (~236 tokens) ## Blocks and backdrops - [The agent layer › Extensions, blocks in the app's own places](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=extensions-blocks-in-the-apps-own-places): There are three ways a morph can appear in the app: (~1192 tokens) - [Blocks](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=blocks): `stats`, `progress`, `badges`, `divider`, and the blocks below. (~1097 tokens) - [Blocks › Views, the free mode](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=views-the-free-mode): The morph format is kept small on purpose. A `view` block is for anything it cannot express. The morph includes a JavaScript module, and the app loads it and shows the component it returns **inside the panel**. It uses the same page, the… (~1218 tokens) - [Blocks › Views, the free mode › The host: live context and engine features](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=the-host-live-context-and-engine-features): `host.version === 1`. (~1068 tokens) - [Blocks › Views, the free mode › Try the piano composer](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=try-the-piano-composer): The Piano composer example replaces the composer with a piano you can type with. (~213 tokens) - [Blocks › Views, the free mode › Intents, hands for views](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=intents-hands-for-views): An intent is an action declared once, by name, at the top of the file (up to 16). It can use the same actions a button has: `call`, `run`, `desk`, `open`, `state`, `prompt`/`send`, `href`, `copy`. Its `label` defaults to its name. (~745 tokens) - [Blocks › Nothing is enforced](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=nothing-is-enforced): Every part of the frame around a panel is optional: (~171 tokens) - [Blocks › Backdrops](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=backdrops): `surface.backdrop` is an image (https, or `http://127.0.0.1`), or a template that resolves to one: `"{{pulses.np.rows.0.image}}"`. The app shows it blurred and dimmed behind the panel, slowly drifting, and fades to the next picture when… (~128 tokens) ## Settings, vars, where a cell lives - [Settings, conditions, and where a morph lives](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=settings-conditions-and-where-a-morph-lives): **Settings.** A morph can declare `vars`, its settings. `{{var:HOST}}` works anywhere in the file: a URL, a header, a prompt, a row template. You fill in your values once in Cells & Morphs, and they are stored outside the file, so one… (~808 tokens) - [The agent layer › Which sessions morphs reach](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=which-sessions-morphs-reach): By default, a morph only reaches the agent **in morph mode**, the dedicated tab where the Cellwright (the agent that builds morphs) works. A normal coding session has no `cells` tool, no morph instructions and no board context: the morph… (~119 tokens) - [The agent layer › Signed morphs](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=signed-morphs): A morph can carry an Ed25519 `signature` over its content (everything except `signature`, `source`, `enabled` and `state`). The Cells & Morphs panel shows: (~114 tokens) - [The agent layer › Reach](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=reach): Before you turn a morph on, it shows its **reach**: everything it can touch. Reach is worked out from the file itself, so a morph cannot under-report it. It lists the hosts the morph talks to, whether it gives the agent rules, how many… (~107 tokens) ## Pulses (live feeds) and templates - [Pulses](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=pulses): A pulse (a live feed) is a URL, how often to fetch it, where the list is in the response, and how to turn each item into a row. (~400 tokens) - [Templates](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=templates): These fields can contain `{{holes}}`: `status.text`, `surface.body`, stats `value` and `hint`, progress `hint`, `text` blocks, `kv` values. (~99 tokens) ## Triggers (events) - [Triggers](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=triggers): Available values: `{{name}}` and `{{tab}}` always. `{{cost}}`, `{{duration}}`, `{{files}}`, `{{tools}}`, `{{steps}}` on `turn.done`. `{{error}}` on `turn.failed`, `turn.stopped` and `error`. `{{tool}}`, `{{ok}}`, `{{summary}}` on… (~916 tokens) ## The agent layer: instructions, lookups, guards, state - [The agent layer](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=the-agent-layer): This is not the same as a hook. A [hook](/docs/tools/hooks) is a shell command that watches or blocks the agent. A morph gives the agent abilities and a shared workspace you can both see. Guards are the only overlap, and they are plain… (~296 tokens) - [The agent layer › The agent layer needs its own yes](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=the-agent-layer-needs-its-own-yes): Turning a morph on turns on its UI. Its agent layer (instructions, lookups, guards) stays **held** until you approve it in Cells & Morphs, where you can read exactly what it declares. (~260 tokens) - [The agent layer › Hidden from the agent](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=hidden-from-the-agent): You can hide any morph from the agent on its card in Cells & Morphs: **Agent access → hidden**. A hidden morph still works on screen (its board, chip, buttons and popups), but the agent cannot see it at all. It is not in `cells list`, and… (~288 tokens) - [The agent layer › Desks, one click from a board row to its own tab](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=desks-one-click-from-a-board-row-to-its-own-tab): Switching between tasks costs time and attention, and a short note about where you left off makes it easier to come back. Desks give each piece of work its own place to return to. (~275 tokens) - [The agent layer › Credentials](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=credentials): A pulse or lookup can send headers: `"headers": { "authorization": "Bearer {{secret:JIRA_TOKEN}}" }`. `{{secret:NAME}}` reads Empryo's key store (`/keys`) and `{{env:NAME}}` reads an environment variable. The app fills in the values just… (~501 tokens) - [The agent layer › Instructions, per mode](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=instructions-per-mode): `instructions` is usually one line the agent always reads. You can also write it per mode, `{ "plan": "…", "architect": "…", "*": "…" }`, so the morph says one thing while you plan and another while code is written. `*` applies to every… (~86 tokens) - [The agent layer › Organisation policy](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=organisation-policy): Organisations can set rules for morphs in the **global** config (`~/.empryo/config.json`, never in a repository): (~196 tokens) - [The agent layer › What the agent is holding](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=what-the-agent-is-holding): When you ask for a morph, the agent that answers is the **Cellwright**. It is a dedicated agent for building morphs, separate from the coding agent. These are all its tools, so you know what it can and cannot do while it builds: (~371 tokens) - [The agent layer › Build your own picker](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=build-your-own-picker): When the control you want is an app menu a morph cannot reach, build your own picker instead. You need three parts: (~209 tokens) - [The agent layer › The agent drives its own work](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=the-agent-drives-its-own-work): Besides reading (`debug`) and looking (`shot`), the agent can use a live morph the way you would: (~236 tokens) - [The agent layer › The agent looks at its own work](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=the-agent-looks-at-its-own-work): Two questions, two tools. `cells debug ` says what the morph **is**: its checked structure, what was dropped, which feed is empty. `cells shot ` says what it **looks like**: the app draws the morph and gives the agent the picture. (~202 tokens) - [The agent layer › The agent checks its own work](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=the-agent-checks-its-own-work): `cells list` names what a morph restyles (`decorates composer:pulse`). `cells debug` prints the resolved `decorate` map and every `{{lane.*}}` hole it left for the chat to fill. That way "the style I asked for was dropped" and "this strip… (~198 tokens) - [The agent layer › The agent opens desks too](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=the-agent-opens-desks-too): `cells` has a `desk` action. When you say "let's work on PROJ-142", the agent opens (or goes back to) that row's tab for you. `engine://desks` lists every tab tied to a row (title, busy or idle, tab), so a "where was I" morph needs only… (~62 tokens) - [The agent layer › Runs, cards that do the work](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=runs-cards-that-do-the-work): Any action, row action or kanban `onMove` can have a **run**: (~857 tokens) - [The agent layer › The engine pushes too](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=the-engine-pushes-too): An `engine://` pulse does not wait for its next scheduled fetch. As soon as the engine reports something a feed depends on, the feed updates. For example: (~344 tokens) - [The agent layer › Slots, a morph instead of part of the app](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=slots-a-morph-instead-of-part-of-the-app): `place` puts a morph where the app has left room for one. A **slot** goes further: the morph *replaces* that part of the window, and the app does not draw its own version. (~257 tokens) - [The agent layer › Side by side](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=side-by-side): The app can show two chats next to each other, stack them, and group panes that no longer fit into one shared column. A morph works in all of these layouts without any extra setup. (~296 tokens) - [The agent layer › Facts about one chat: `{{lane.*}}`](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=facts-about-one-chat-lane): Most holes are filled once, before anything is drawn, so every copy shows the same value. Chat facts are different. When two chats are side by side, the same morph is drawn twice, so these holes are filled separately for each pane's own… (~251 tokens) - [The agent layer › Decorate](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=decorate): `pigment` can do more than change colors. It can restyle one of the app's own parts while the morph is on. (~210 tokens) - [The agent layer › Popups](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=popups): A popup is a second place to put blocks. Give it an id, and any control opens it with `"open": ""`. (~188 tokens) - [The agent layer › Every host](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=every-host): Only the desktop app draws a morph's panels. The agent layer (the `cells` tool, the morph's instructions, lookups and guards) works the same in the terminal UI and in `--headless` runs. (~115 tokens) - [The agent layer › Where morphs live, and sharing](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=where-morphs-live-and-sharing): A new morph is **yours in every repository by default**: it is saved in `~/.empryo/morphs/*.json`, and the panel shows "every project" next to it. A morph about one repository (its board, its tests, its deploys) belongs in that… (~343 tokens) - [The agent layer › What reaches the model](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=what-reaches-the-model): Pulse rows are built from `map` templates, so only the fields the morph names are sent. Lookups work the same way with `map`, or with `pick`, a list of dot paths that are the only fields sent. If neither is set, the raw JSON is sent, cut… (~108 tokens) ## Limits - [Limits](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=limits): When a morph goes over a limit, the app shortens long text (with an ellipsis) and drops extra items. A single broken block, row, action or pulse is dropped too. The rest of the morph still works. (~624 tokens) ## Everything else - [Try it in five minutes](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=try-it-in-five-minutes) (~162 tokens) - [Template holes and filters](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=template-holes-and-filters) (~350 tokens) - [How morphs compare](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=how-morphs-compare) (~791 tokens) - [What a morph cannot do](https://empryo.com/api/docs/section?page=tools%2Fmorphs&anchor=what-a-morph-cannot-do) (~203 tokens) ## Examples - [Blog: Morphs and Cells](https://empryo.com/blog/morphs-and-cells.md): the why, with screenshots - Starter cells: the public directory in the Empryo repo (Start from… → Directory in the app)