iii / worker
$worker

iii-directory

v0.5.1

Engine introspection (functions / triggers / workers), workers registry proxy, and filesystem-backed skill + prompt reader.

  • macOS: arm64 · x64
  • Linux: arm64 · armv7 · x64
  • Windows: arm64 · x64 · x86
agent-ready brief for v0.5.1
install + config + dependencies + readme + api reference, all in one place. fetch as agent-context.md for an llm to consume.
the same content rendered as discrete blocks below is exposed as a single markdown document at /workers/iii-directory.md?version=0.5.1. paste it into an llm prompt or pipe it through curl from a worker.

install

install
$iii worker add iii-directory@0.5.1

configuration

iii-config.yaml
- download_timeout_ms: 60000
  registry_url: https://api.workers.iii.dev
  skills_folder: ./skills
  system_prompt_skills:
    - skills/iii/*.md
    - skills/directory/*.md

dependencies

no dependencies for v0.5.1

readme

README.md

iii-directory

Engine introspection, workers registry proxy, and filesystem-backed skill + prompt reader for the iii engine. Every public function sits under a single directory::* namespace, split into four sub-namespaces (all MCP-agnostic):

Surface What clients see When to use it
Skills (directory::skills::*) Enriched listing via directory::skills::list ({ id, title, description, bytes, modified_at } per row) and a single-skill reader directory::skills::get { id } returning { id, title, description, body, modified_at } Orientation: "when and why to use my worker's tools"
Prompts (directory::prompts::*) Static prompt templates listed by directory::prompts::list and read by directory::prompts::get Parametric command templates the user invokes
Engine (directory::engine::*) Read-side enrichment over engine::functions::list, engine::workers::list, engine::trigger-types::list, engine::triggers::list "What's connected to the engine right now?"
Registry (directory::registry::*) HTTP proxy over api.workers.iii.dev with the same workers::{list,info} shape as directory::engine::workers::* "What's published in the public registry?"

Skills and prompts are sourced from a single configured folder on disk (skills_folder). The only write path is the directory::skills::download function, which pulls markdown into skills_folder from either the workers registry or a GitHub repo. Once downloaded, files belong to the developer — edit them however you want.

directory::engine::workers::* and directory::registry::workers::* share the same envelope shape so callers can switch between the local engine view and the published-registry view without re-learning the API.

Table of contents

  1. Install
  2. Configuration
  3. Quickstart: download some skills
  4. On-disk layout
  5. Skill ids
  6. Functions
  7. Custom trigger types
  8. Local development & testing
  9. Migration from skills v0.2.x

Install

iii worker add iii-directory

iii worker add fetches the binary, writes a config block into ~/.iii/config.yaml, and the engine starts the worker on the next iii start.


Configuration

# Folder that backs every read (`directory::skills::list`,
# `directory::skills::get`, `directory::prompts::*`) and every write
# from `directory::skills::download`. Relative paths are resolved
# against the process current working directory; absolute paths are
# used as-is.
skills_folder: ./skills

# Workers registry base URL — used by `directory::skills::download`
# and the `directory::registry::*` proxies when a `worker=` source is
# specified. Override for self-hosted deployments.
registry_url: https://api.workers.iii.dev

# Timeout for a single download (`git clone` or HTTP request) in ms.
download_timeout_ms: 60000

The folder is created on first download if it doesn't exist.


Quickstart: download some skills

# Pull a specific worker's skills + prompts at a fixed semver from
# the registry. Files land under `<skills_folder>/agent-memory/`.
iii trigger --function-id=directory::skills::download \
  --payload='{"worker": "agent-memory", "version": "1.2.3"}'

# Same, but always fetch whatever's tagged `latest` (also the default
# when neither version nor tag is given).
iii trigger --function-id=directory::skills::download \
  --payload='{"worker": "agent-memory"}'

# Pull a single subfolder out of a public GitHub repo via
# `git clone --depth 1 --branch main`. Files land under
# `<skills_folder>/frontend-design/`. The `branch` field defaults to
# `main`; pass `"master"` for older repos that haven't migrated.
iii trigger --function-id=directory::skills::download \
  --payload='{
    "repo": "https://github.com/anthropics/skills",
    "skill": "frontend-design"
  }'

The response is { namespace, skills_written, prompts_written, source } where skills_written and prompts_written are arrays of relative paths / prompt names that were materialised in this run.

After every successful download the worker fires the directory::skills::on-change and/or directory::prompts::on-change trigger types so that subscribers like the mcp worker can forward MCP notifications/list_changed to their clients.


On-disk layout

The worker assumes a fixed layout under skills_folder:

skills_folder/
  <namespace>/                 # one folder per `directory::skills::download` namespace
    index.md                   # → iii://<namespace>/index
    contacts.md                # → iii://<namespace>/contacts
    emails/send-email.md       # → iii://<namespace>/emails/send-email
    prompts/                   # ← magic marker for prompts
      send-email.md            # ← MCP slash-command (needs YAML frontmatter)
      triage.md

A few rules:

  • Skill ids are the relative path under skills_folder with .md stripped. Each segment must satisfy [a-z0-9_-]{1,64}.
  • Prompts live under any */prompts/*.md path. They must start with a YAML frontmatter block declaring at least description; name is optional and overrides the file-stem default.
  • Files anywhere else (i.e. not in a prompts/ segment) are skills.

The download function namespaces by source:

Source Destination
repo=URL skill=NAME branch?=main //...
worker=NAME version=… //...
worker=NAME tag=… (default tag=latest) //...

Re-pulling the same source overwrites files file-by-file — existing siblings outside the response set are preserved (so hand-edited additions survive a re-pull).


Skill ids

Skills are addressed by their relative path under skills_folder with .md stripped — e.g. /agent-memory/observe.md → id "agent-memory/observe". The same string is what directory::skills::list returns and what directory::skills::get expects in { "id": ... }. The legacy iii://{id} link form is still accepted on get (the prefix is auto-stripped), but the worker no longer parses any other iii:// URI shape — bodies are read solely by id, and the auto-rendered tree-shaped index that previous releases served at iii://directory/skills is gone. Consumers that want a tree-shaped picker iterate list rows themselves and indent by id.matches('/').count().


Functions

Fifteen functions, all under directory::*. All registrations are namespace-clean; this worker is intentionally agnostic to MCP and any other adapter.

directory::skills::* (filesystem reader)

Function ID Description
directory::skills::download Pull markdown into skills_folder. Either {repo, skill, branch?} (defaults branch=main) or `{worker, version?
directory::skills::list Enriched listing of every fs-backed skill: { id, title, description, bytes, modified_at } per row. Title and description are extracted from each body's H1 + first paragraph so consumers can render a picker without a follow-up get per row.
directory::skills::get Fetch one skill by id. Returns { id, title, description, body, modified_at } — same flat shape as directory::prompts::get. Accepts a bare id or the same id prefixed with iii://.

directory::prompts::* (filesystem reader)

Function ID Description
directory::prompts::list Metadata-only listing of every fs-backed prompt.
directory::prompts::get Fetch one prompt's body + {name, description, modified_at}. Plain shape, no envelope.

directory::engine::* (engine introspection)

Function ID Description
directory::engine::functions::list List functions registered with the engine; filter by search/prefix/worker.
directory::engine::functions::info Single-function detail: schemas, owning worker, registered triggers, bundled how-to.
directory::engine::triggers::list List trigger TYPES registered with the engine; filter by search/prefix/worker.
directory::engine::triggers::info Single trigger-type detail: configuration schema, return schema, instance count.
directory::engine::registered-triggers::list List registered trigger INSTANCES (subscriber rows).
directory::engine::registered-triggers::info Composite: instance + trigger-type detail + function detail.
directory::engine::workers::list List workers connected to the engine; same row shape as directory::registry::workers::list.
directory::engine::workers::info One worker's worker envelope + functions + trigger types + registered triggers.

directory::registry::* (workers registry HTTP proxy)

Function ID Description
directory::registry::workers::list Search published workers in api.workers.iii.dev. Same row shape as directory::engine::workers::list.
directory::registry::workers::info Full registry detail for one worker: worker envelope (matching directory::engine::workers::info.worker) plus readme, api_reference, skills_tree.

Both directory::registry::* responses are cached in-process for registry_cache_ttl_ms (default 60s).

There is no directory::skills::register / directory::prompts::register — see Migration below.


Custom trigger types

Trigger type Fires when Payload to subscribers
directory::skills::on-change After a directory::skills::download that wrote at least one skill markdown file { "op": "download", "namespace": "", "source": "repo" | "registry" }
directory::prompts::on-change After a directory::skills::download that wrote at least one prompt markdown file { "op": "download", "namespace": "", "source": "repo" | "registry" }

Dispatches are fire-and-forget (Void), so the download path doesn't block on downstream latency.


Local development & testing

Run from source

cargo run --release -- --url ws://127.0.0.1:49134 --config ./config.yaml

Tests

# Fast, offline — exercises the pure helpers (markdown / id validators
# / fs source) without needing an iii engine.
cargo test --lib

# Full BDD suite — requires an iii engine on ws://127.0.0.1:49134
# (or III_ENGINE_WS_URL). The git-backed download scenarios spin up
# a local fixture repo via `git init`; the registry-backed scenarios
# point a wiremock server at the worker's `registry_url` config.
cargo test

# One feature group at a time. Available tags:
#   @engine  @read  @prompts  @download  @download_repo  @download_registry
cargo test --test bdd -- --tags @download

The BDD harness lives under tests/. Feature files mirror the modules in src/functions/. Step definitions under tests/steps/ drive each feature through the same iii.trigger path the production binary uses.

api reference (json)

agent-api-reference.json
{
  "functions": [
    {
      "description": "Fetch one filesystem-backed skill by id. Returns the raw markdown body plus id, title, description, and modified_at — same flat shape as directory::prompts::get. Accepts a bare id (e.g. \"directory/skills/list\") or the same id prefixed with iii://.",
      "metadata": {
        "tool": {
          "label": "Get skill"
        }
      },
      "name": "directory::skills::get",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "id": {
            "description": "Skill id (the same string returned by `directory::skills::list`, e.g. `\"directory/skills/list\"`). The legacy `iii://{id}` form is also accepted for ergonomics; the prefix is stripped before validation. Other URI schemes are rejected.",
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "title": "SkillGetInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "body": {
            "description": "Raw markdown body (post-frontmatter) from disk.",
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "modified_at": {
            "description": "File mtime as RFC 3339.",
            "type": "string"
          },
          "title": {
            "type": "string"
          }
        },
        "required": [
          "body",
          "description",
          "id",
          "modified_at",
          "title"
        ],
        "title": "SkillGetOutput",
        "type": "object"
      }
    },
    {
      "description": "List registered trigger instances (the link rows between trigger types and target functions). Filter by trigger_type, function_id, worker, or free-text search.",
      "metadata": {},
      "name": "directory::engine::registered-triggers::list",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "function_id": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "search": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "trigger_type": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "worker": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "RegisteredTriggerListInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "RegisteredTriggerListEntry": {
            "properties": {
              "config_summary": {
                "description": "Truncated (~80 chars) JSON preview of `config` so listings stay scannable. Use `directory::registered-trigger-info` for the full payload.",
                "type": "string"
              },
              "function_id": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "trigger_type": {
                "type": "string"
              },
              "worker_name": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "config_summary",
              "function_id",
              "id",
              "trigger_type"
            ],
            "type": "object"
          }
        },
        "properties": {
          "registered_triggers": {
            "items": {
              "$ref": "#/definitions/RegisteredTriggerListEntry"
            },
            "type": "array"
          }
        },
        "required": [
          "registered_triggers"
        ],
        "title": "RegisteredTriggerListOutput",
        "type": "object"
      }
    },
    {
      "description": "List every worker currently connected to the engine. Filter by name substring, runtime, or status. Same row shape as directory::registry::workers::list so callers learn one envelope.",
      "metadata": {},
      "name": "directory::engine::workers::list",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "runtime": {
            "default": null,
            "description": "Exact runtime match (e.g. `\"rust\"`, `\"node\"`).",
            "type": [
              "string",
              "null"
            ]
          },
          "search": {
            "default": null,
            "description": "Case-insensitive substring match against `name`.",
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "default": null,
            "description": "Exact status match (e.g. `\"connected\"`).",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "WorkerListInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "Worker": {
            "description": "Shared worker envelope used by both `directory::worker-list` rows and the `worker` field of `directory::worker-info`. Field names line up with `registry::Worker` (see [`crate::functions::registry::Worker`]) so callers learn one shape across local + registry surfaces.",
            "properties": {
              "active_invocations": {
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "connected_at_ms": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "description": {
                "description": "Engine-side workers carry no description; field present for shape parity with `registry::Worker.description`. Always `None`.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "function_count": {
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "id": {
                "description": "Engine-assigned connection id (directory-specific).",
                "type": "string"
              },
              "ip_address": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "isolation": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "description": "Worker name as registered with the engine.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "os": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "runtime": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "status": {
                "description": "Connection state (e.g. `\"connected\"`, `\"disconnected\"`).",
                "type": "string"
              },
              "version": {
                "description": "Worker version string from the worker's published manifest.",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "active_invocations",
              "connected_at_ms",
              "function_count",
              "id",
              "status"
            ],
            "type": "object"
          }
        },
        "properties": {
          "workers": {
            "items": {
              "$ref": "#/definitions/Worker"
            },
            "type": "array"
          }
        },
        "required": [
          "workers"
        ],
        "title": "WorkerListOutput",
        "type": "object"
      }
    },
    {
      "description": "List every trigger TYPE registered with the engine. Filter by search, prefix, worker. (For registered trigger instances, use directory::engine::registered-triggers::list.)",
      "metadata": {},
      "name": "directory::engine::triggers::list",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "prefix": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "search": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "worker": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "TriggerListInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "TriggerListEntry": {
            "properties": {
              "description": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "worker_name": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "description",
              "id"
            ],
            "type": "object"
          }
        },
        "properties": {
          "triggers": {
            "items": {
              "$ref": "#/definitions/TriggerListEntry"
            },
            "type": "array"
          }
        },
        "required": [
          "triggers"
        ],
        "title": "TriggerListOutput",
        "type": "object"
      }
    },
    {
      "description": "List filesystem-backed skills (id, title, description, bytes, modified_at) from skills_folder. Each row carries the H1 title and first-paragraph description so consumers can render a picker or indented index without one get per row.",
      "metadata": {},
      "name": "directory::skills::list",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "title": "ListSkillsInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "SkillEntry": {
            "properties": {
              "bytes": {
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "description": {
                "description": "First paragraph of the body, empty when the file has only headings.",
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "modified_at": {
                "description": "File mtime as RFC 3339 (best effort; empty if unavailable).",
                "type": "string"
              },
              "title": {
                "description": "First `# H1` line in the body, falling back to `id` when absent.",
                "type": "string"
              }
            },
            "required": [
              "bytes",
              "description",
              "id",
              "modified_at",
              "title"
            ],
            "type": "object"
          }
        },
        "properties": {
          "skills": {
            "items": {
              "$ref": "#/definitions/SkillEntry"
            },
            "type": "array"
          }
        },
        "required": [
          "skills"
        ],
        "title": "ListSkillsOutput",
        "type": "object"
      }
    },
    {
      "description": "List workers from the public registry (api.workers.iii.dev) matching the free-text term `search`. Same row shape as directory::engine::workers::list so callers learn one envelope. Results are cached for `registry_cache_ttl_ms` (default 60s).",
      "metadata": {},
      "name": "directory::registry::workers::list",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "`directory::registry::workers::list` input. Mirrors [`crate::functions::directory::WorkerListInput.search`] so callers can switch between local and registry surfaces without re-learning the API. Adds `limit` for paging because the registry is paged.",
        "properties": {
          "limit": {
            "default": null,
            "description": "Max results to return. Defaults to 20; capped at 100.",
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "search": {
            "default": null,
            "description": "Free-text query forwarded to the registry as `?q=…`. Required — the public registry doesn't support an unscoped browse endpoint.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "WorkerListInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "RegistryAuthor": {
            "properties": {
              "is_verified": {
                "default": false,
                "type": "boolean"
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "profile_picture": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "type": "object"
          },
          "Worker": {
            "description": "Shared worker envelope used by both `directory::registry::workers::list` rows and the `worker` field of `directory::registry::workers::info`. Same field names as [`crate::functions::directory::Worker`] so callers learn one shape across local + registry surfaces.",
            "properties": {
              "author": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/RegistryAuthor"
                  },
                  {
                    "type": "null"
                  }
                ],
                "default": null
              },
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "type": "string"
              },
              "repo": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "version": {
                "description": "Latest published version (worker-list) or the resolved version (worker-info, when called with `version` / `tag`).",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "name"
            ],
            "type": "object"
          }
        },
        "properties": {
          "workers": {
            "items": {
              "$ref": "#/definitions/Worker"
            },
            "type": "array"
          }
        },
        "required": [
          "workers"
        ],
        "title": "WorkerListOutput",
        "type": "object"
      }
    },
    {
      "description": "Fetch one filesystem-backed prompt by name. Returns the raw markdown body plus name, description, and modified_at — no envelope, no templating.",
      "metadata": {},
      "name": "directory::prompts::get",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "name": {
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "title": "PromptGetInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "body": {
            "description": "Raw markdown body (post-frontmatter) from disk.",
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "modified_at": {
            "description": "File mtime as RFC 3339.",
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "body",
          "description",
          "modified_at",
          "name"
        ],
        "title": "PromptGetOutput",
        "type": "object"
      }
    },
    {
      "description": "Full detail for one trigger type: configuration schema, return schema, owning worker, and current instance count.",
      "metadata": {},
      "name": "directory::engine::triggers::info",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "title": "TriggerInfoInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "configuration_schema": {
            "description": "SDK 0.11.3 surfaces a single `trigger_request_format` that doubles as the per-instance configuration shape; expose it explicitly so callers don't have to know the alias."
          },
          "description": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "instance_count": {
            "format": "uint",
            "minimum": 0,
            "type": "integer"
          },
          "return_schema": true,
          "worker_name": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "description",
          "id",
          "instance_count"
        ],
        "title": "TriggerInfoOutput",
        "type": "object"
      }
    },
    {
      "description": "Download skills + prompts into skills_folder. Pass {repo, skill, branch?} to clone a single skill folder from a GitHub repo (git clone --depth 1 --branch <branch>; branch defaults to \"main\"), or {worker, version?|tag?} to pull from the workers registry (defaults to tag=\"latest\" when neither version nor tag is given). Files in the destination namespace are overwritten file-by-file.",
      "metadata": {
        "tool": {
          "label": "Download skills"
        }
      },
      "name": "directory::skills::download",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "branch": {
            "default": null,
            "description": "Source A: branch to clone. Defaults to `\"main\"`. Pass `\"master\"` (or any other branch name) for repos whose default branch is not `main`.",
            "type": [
              "string",
              "null"
            ]
          },
          "repo": {
            "default": null,
            "description": "Source A: GitHub repo URL. Pair with `skill`.",
            "type": [
              "string",
              "null"
            ]
          },
          "skill": {
            "default": null,
            "description": "Source A: subfolder under `skills/` inside the repo. Doubles as the destination namespace inside `skills_folder`.",
            "type": [
              "string",
              "null"
            ]
          },
          "tag": {
            "default": null,
            "description": "Source B: registry tag to pull (e.g. `latest`). Mutually exclusive with `version`. Defaults to `\"latest\"` when neither `version` nor `tag` is provided.",
            "type": [
              "string",
              "null"
            ]
          },
          "version": {
            "default": null,
            "description": "Source B: explicit semver to pull. Mutually exclusive with `tag`.",
            "type": [
              "string",
              "null"
            ]
          },
          "worker": {
            "default": null,
            "description": "Source B: workers registry name. Pair with exactly one of `version` / `tag`.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "DownloadInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "namespace": {
            "type": "string"
          },
          "prompts_written": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "skills_written": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "source": true
        },
        "required": [
          "namespace",
          "prompts_written",
          "skills_written",
          "source"
        ],
        "title": "DownloadOutput",
        "type": "object"
      }
    },
    {
      "description": "List every function registered with the engine. Filter by free-text search, namespace prefix, and/or worker name.",
      "metadata": {},
      "name": "directory::engine::functions::list",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "prefix": {
            "default": null,
            "description": "Exact prefix match on `function_id` (e.g. `\"mem::\"`).",
            "type": [
              "string",
              "null"
            ]
          },
          "search": {
            "default": null,
            "description": "Case-insensitive substring match against `function_id` and `description`.",
            "type": [
              "string",
              "null"
            ]
          },
          "worker": {
            "default": null,
            "description": "Exact worker-name match (the worker that registered the function).",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "FunctionListInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "FunctionListEntry": {
            "properties": {
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "function_id": {
                "type": "string"
              },
              "worker_name": {
                "description": "Worker that registered it (resolved via `WorkerInfo.functions[]`), or the first `::` segment of `function_id` as fallback.",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "function_id"
            ],
            "type": "object"
          }
        },
        "properties": {
          "functions": {
            "items": {
              "$ref": "#/definitions/FunctionListEntry"
            },
            "type": "array"
          }
        },
        "required": [
          "functions"
        ],
        "title": "FunctionListOutput",
        "type": "object"
      }
    },
    {
      "description": "List filesystem-backed prompts (name, description, modified_at) from skills_folder.",
      "metadata": {},
      "name": "directory::prompts::list",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "title": "ListPromptsInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "PromptEntry": {
            "properties": {
              "description": {
                "type": "string"
              },
              "modified_at": {
                "description": "File mtime as RFC 3339.",
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "description",
              "modified_at",
              "name"
            ],
            "type": "object"
          }
        },
        "properties": {
          "prompts": {
            "items": {
              "$ref": "#/definitions/PromptEntry"
            },
            "type": "array"
          }
        },
        "required": [
          "prompts"
        ],
        "title": "ListPromptsOutput",
        "type": "object"
      }
    },
    {
      "description": "Full detail for one function: schemas, owning worker, registered triggers that target it, and any matching how-to skill from skills_folder.",
      "metadata": {},
      "name": "directory::engine::functions::info",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "function_id": {
            "type": "string"
          }
        },
        "required": [
          "function_id"
        ],
        "title": "FunctionInfoInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "HowGuide": {
            "description": "Primary how-to skill that documents this function. Kept tiny so `function-info` stays cheap to render; deeper related skills come back via [`FunctionInfoOutput::related_skills`] as title-only refs that callers can pull on demand through `directory::skills::get`.",
            "properties": {
              "body": {
                "type": "string"
              },
              "skill_id": {
                "type": "string"
              },
              "title": {
                "type": "string"
              }
            },
            "required": [
              "body",
              "skill_id",
              "title"
            ],
            "type": "object"
          },
          "RegisteredTriggerSummary": {
            "properties": {
              "config": true,
              "id": {
                "type": "string"
              },
              "trigger_type": {
                "type": "string"
              }
            },
            "required": [
              "config",
              "id",
              "trigger_type"
            ],
            "type": "object"
          },
          "RelatedSkillRef": {
            "description": "Title-only reference to another skill that mentions a function. Bodies are intentionally omitted; callers fetch on demand via `directory::skills::get { id: \"<skill_id>\" }`.",
            "properties": {
              "skill_id": {
                "type": "string"
              },
              "title": {
                "type": "string"
              }
            },
            "required": [
              "skill_id",
              "title"
            ],
            "type": "object"
          }
        },
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "function_id": {
            "type": "string"
          },
          "how_guide": {
            "anyOf": [
              {
                "$ref": "#/definitions/HowGuide"
              },
              {
                "type": "null"
              }
            ]
          },
          "metadata": true,
          "registered_triggers": {
            "items": {
              "$ref": "#/definitions/RegisteredTriggerSummary"
            },
            "type": "array"
          },
          "related_skills": {
            "description": "Other skills (any `type`) that mention this function via either the literal `function_id` or the `iii://fn/<dotted/path>` URI. Body content is omitted; fetch on demand via `directory::skills::get`.",
            "items": {
              "$ref": "#/definitions/RelatedSkillRef"
            },
            "type": "array"
          },
          "request_schema": true,
          "response_schema": true,
          "worker_name": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "function_id",
          "registered_triggers",
          "related_skills"
        ],
        "title": "FunctionInfoOutput",
        "type": "object"
      }
    },
    {
      "description": "Worker envelope plus the lists of functions, trigger types, and registered triggers it owns. The `worker` field has the same shape as directory::registry::workers::info so callers can switch between local + registry surfaces with the same parser.",
      "metadata": {},
      "name": "directory::engine::workers::info",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "name": {
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "title": "WorkerInfoInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "Worker": {
            "description": "Shared worker envelope used by both `directory::worker-list` rows and the `worker` field of `directory::worker-info`. Field names line up with `registry::Worker` (see [`crate::functions::registry::Worker`]) so callers learn one shape across local + registry surfaces.",
            "properties": {
              "active_invocations": {
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "connected_at_ms": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "description": {
                "description": "Engine-side workers carry no description; field present for shape parity with `registry::Worker.description`. Always `None`.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "function_count": {
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "id": {
                "description": "Engine-assigned connection id (directory-specific).",
                "type": "string"
              },
              "ip_address": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "isolation": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "description": "Worker name as registered with the engine.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "os": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "runtime": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "status": {
                "description": "Connection state (e.g. `\"connected\"`, `\"disconnected\"`).",
                "type": "string"
              },
              "version": {
                "description": "Worker version string from the worker's published manifest.",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "active_invocations",
              "connected_at_ms",
              "function_count",
              "id",
              "status"
            ],
            "type": "object"
          },
          "WorkerFunctionEntry": {
            "properties": {
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "function_id": {
                "type": "string"
              }
            },
            "required": [
              "function_id"
            ],
            "type": "object"
          },
          "WorkerRegisteredTriggerEntry": {
            "properties": {
              "function_id": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "trigger_type": {
                "type": "string"
              }
            },
            "required": [
              "function_id",
              "id",
              "trigger_type"
            ],
            "type": "object"
          },
          "WorkerTriggerTypeEntry": {
            "properties": {
              "description": {
                "type": "string"
              },
              "id": {
                "type": "string"
              }
            },
            "required": [
              "description",
              "id"
            ],
            "type": "object"
          }
        },
        "properties": {
          "functions": {
            "items": {
              "$ref": "#/definitions/WorkerFunctionEntry"
            },
            "type": "array"
          },
          "registered_triggers": {
            "items": {
              "$ref": "#/definitions/WorkerRegisteredTriggerEntry"
            },
            "type": "array"
          },
          "trigger_types": {
            "items": {
              "$ref": "#/definitions/WorkerTriggerTypeEntry"
            },
            "type": "array"
          },
          "worker": {
            "allOf": [
              {
                "$ref": "#/definitions/Worker"
              }
            ],
            "description": "Same shape as `worker-list` rows (and `registry::worker-info.worker`)."
          }
        },
        "required": [
          "functions",
          "registered_triggers",
          "trigger_types",
          "worker"
        ],
        "title": "WorkerInfoOutput",
        "type": "object"
      }
    },
    {
      "description": "Full denormalized detail for one registered trigger: instance config + trigger-type detail + function detail.",
      "metadata": {},
      "name": "directory::engine::registered-triggers::info",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "title": "RegisteredTriggerInfoInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "FunctionInfoOutput": {
            "properties": {
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "function_id": {
                "type": "string"
              },
              "how_guide": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/HowGuide"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "metadata": true,
              "registered_triggers": {
                "items": {
                  "$ref": "#/definitions/RegisteredTriggerSummary"
                },
                "type": "array"
              },
              "related_skills": {
                "description": "Other skills (any `type`) that mention this function via either the literal `function_id` or the `iii://fn/<dotted/path>` URI. Body content is omitted; fetch on demand via `directory::skills::get`.",
                "items": {
                  "$ref": "#/definitions/RelatedSkillRef"
                },
                "type": "array"
              },
              "request_schema": true,
              "response_schema": true,
              "worker_name": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "function_id",
              "registered_triggers",
              "related_skills"
            ],
            "type": "object"
          },
          "HowGuide": {
            "description": "Primary how-to skill that documents this function. Kept tiny so `function-info` stays cheap to render; deeper related skills come back via [`FunctionInfoOutput::related_skills`] as title-only refs that callers can pull on demand through `directory::skills::get`.",
            "properties": {
              "body": {
                "type": "string"
              },
              "skill_id": {
                "type": "string"
              },
              "title": {
                "type": "string"
              }
            },
            "required": [
              "body",
              "skill_id",
              "title"
            ],
            "type": "object"
          },
          "RegisteredTriggerSummary": {
            "properties": {
              "config": true,
              "id": {
                "type": "string"
              },
              "trigger_type": {
                "type": "string"
              }
            },
            "required": [
              "config",
              "id",
              "trigger_type"
            ],
            "type": "object"
          },
          "RelatedSkillRef": {
            "description": "Title-only reference to another skill that mentions a function. Bodies are intentionally omitted; callers fetch on demand via `directory::skills::get { id: \"<skill_id>\" }`.",
            "properties": {
              "skill_id": {
                "type": "string"
              },
              "title": {
                "type": "string"
              }
            },
            "required": [
              "skill_id",
              "title"
            ],
            "type": "object"
          },
          "TriggerInfoOutput": {
            "properties": {
              "configuration_schema": {
                "description": "SDK 0.11.3 surfaces a single `trigger_request_format` that doubles as the per-instance configuration shape; expose it explicitly so callers don't have to know the alias."
              },
              "description": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "instance_count": {
                "format": "uint",
                "minimum": 0,
                "type": "integer"
              },
              "return_schema": true,
              "worker_name": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "description",
              "id",
              "instance_count"
            ],
            "type": "object"
          }
        },
        "properties": {
          "config": true,
          "function": {
            "anyOf": [
              {
                "$ref": "#/definitions/FunctionInfoOutput"
              },
              {
                "type": "null"
              }
            ],
            "description": "Full function detail for `function_id`. `None` if the function has been unregistered between calls."
          },
          "function_id": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "metadata": true,
          "trigger": {
            "anyOf": [
              {
                "$ref": "#/definitions/TriggerInfoOutput"
              },
              {
                "type": "null"
              }
            ],
            "description": "Full trigger-type detail for `trigger_type`. `None` if the type has been unregistered between calls."
          },
          "trigger_type": {
            "type": "string"
          },
          "worker_name": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "config",
          "function_id",
          "id",
          "trigger_type"
        ],
        "title": "RegisteredTriggerInfoOutput",
        "type": "object"
      }
    },
    {
      "description": "Fetch full registry metadata for one worker: worker envelope (same shape as directory::registry::workers::list rows and directory::engine::workers::info), readme, full API reference (functions + triggers schemas), and tree of skill/prompt file paths. Pass either `version` or `tag` (defaults to tag=\"latest\"). Results are cached for `registry_cache_ttl_ms`.",
      "metadata": {},
      "name": "directory::registry::workers::info",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "`directory::registry::workers::info` input. Pass either `version` or `tag`; if neither is provided we fall back to `tag: \"latest\"`.",
        "properties": {
          "name": {
            "description": "Worker name in the registry (e.g. `\"resend\"`).",
            "type": "string"
          },
          "tag": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "version": {
            "default": null,
            "description": "Mutually exclusive with `tag`. If neither is provided we fall back to `tag: \"latest\"`.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "name"
        ],
        "title": "WorkerInfoInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "ApiReference": {
            "properties": {
              "functions": {
                "default": [],
                "items": {
                  "$ref": "#/definitions/ApiReferenceFunction"
                },
                "type": "array"
              },
              "triggers": {
                "default": [],
                "items": {
                  "$ref": "#/definitions/ApiReferenceTrigger"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "ApiReferenceFunction": {
            "properties": {
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "metadata": true,
              "name": {
                "type": "string"
              },
              "request_schema": true,
              "response_schema": true
            },
            "required": [
              "name"
            ],
            "type": "object"
          },
          "ApiReferenceTrigger": {
            "properties": {
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "invocation_schema": true,
              "metadata": true,
              "name": {
                "type": "string"
              },
              "return_schema": true
            },
            "required": [
              "name"
            ],
            "type": "object"
          },
          "RegistryAuthor": {
            "properties": {
              "is_verified": {
                "default": false,
                "type": "boolean"
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "profile_picture": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "type": "object"
          },
          "SkillsTree": {
            "properties": {
              "prompts": {
                "default": [],
                "items": {
                  "$ref": "#/definitions/SkillsTreePrompt"
                },
                "type": "array"
              },
              "skills": {
                "default": [],
                "items": {
                  "$ref": "#/definitions/SkillsTreeSkill"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "SkillsTreePrompt": {
            "properties": {
              "description": {
                "default": null,
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "name"
            ],
            "type": "object"
          },
          "SkillsTreeSkill": {
            "properties": {
              "path": {
                "type": "string"
              }
            },
            "required": [
              "path"
            ],
            "type": "object"
          },
          "Worker": {
            "description": "Shared worker envelope used by both `directory::registry::workers::list` rows and the `worker` field of `directory::registry::workers::info`. Same field names as [`crate::functions::directory::Worker`] so callers learn one shape across local + registry surfaces.",
            "properties": {
              "author": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/RegistryAuthor"
                  },
                  {
                    "type": "null"
                  }
                ],
                "default": null
              },
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "type": "string"
              },
              "repo": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "version": {
                "description": "Latest published version (worker-list) or the resolved version (worker-info, when called with `version` / `tag`).",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "name"
            ],
            "type": "object"
          }
        },
        "properties": {
          "api_reference": {
            "$ref": "#/definitions/ApiReference"
          },
          "readme": {
            "type": [
              "string",
              "null"
            ]
          },
          "skills_tree": {
            "$ref": "#/definitions/SkillsTree"
          },
          "worker": {
            "allOf": [
              {
                "$ref": "#/definitions/Worker"
              }
            ],
            "description": "Same shape as `directory::registry::workers::list` rows (and `directory::engine::workers::info.worker`)."
          }
        },
        "required": [
          "api_reference",
          "skills_tree",
          "worker"
        ],
        "title": "WorkerInfoOutput",
        "type": "object"
      }
    }
  ],
  "triggers": [
    {
      "description": "Fires after every successful directory::skills::download that wrote at least one prompt markdown file.",
      "invocation_schema": {},
      "metadata": {},
      "name": "directory::prompts::on-change",
      "return_schema": {}
    },
    {
      "description": "Fires after every successful directory::skills::download that wrote at least one skill markdown file.",
      "invocation_schema": {},
      "metadata": {},
      "name": "directory::skills::on-change",
      "return_schema": {}
    }
  ]
}