skip to content
$worker

iii-directory

v1.2.8

Engine introspection, workers registry proxy, filesystem-backed skills, system prompts, and agent profiles, plus lexical function search with a conditional pre-generate hint.

iiiverified
2,734 installs88 in 7d2 today
install
$iii trigger compose::add worker=iii-directory
  • macOS: arm64 · x64
  • Linux: arm64 · armv7 · x64
  • Windows: arm64 · x64 · x86

exact versions are immutable; binary and bundle artifacts are digest-pinned.

README.md

iii-directory

Workers registry HTTP proxy and filesystem-backed skills, system prompts, and agent profiles for the iii engine. Every public function sits under a single directory::* namespace, split into five surfaces (all MCP-agnostic):

Surface What clients see When to use it
Skills (directory::skills::*) Enriched listing via directory::skills::list ({ id, title, type, function_id, disable_model_invocation, description, bytes, modified_at } per row), a single-skill reader directory::skills::get { id } returning { id, title, type, function_id, disable_model_invocation, path, body, modified_at } (the full body instead of the list teaser), and directory::skills::index which renders a short per-worker overview document (one ## </code> + first paragraph + <code class="readme-inline-code">read more</code> link per <code class="readme-inline-code">type: index</code> skill). Authored by <code class="readme-inline-code">create</code>, edited by <code class="readme-inline-code">update</code>, removed by <code class="readme-inline-code">delete</code>. <code class="readme-inline-code">title</code> prefers the YAML frontmatter <code class="readme-inline-code">title:</code> (then <code class="readme-inline-code">name:</code>) over the body H1; <code class="readme-inline-code">type</code> is lifted from frontmatter <code class="readme-inline-code">type:</code> (e.g. <code class="readme-inline-code">index</code>, <code class="readme-inline-code">how-to</code>, <code class="readme-inline-code">reference</code>) and serialised as <code class="readme-inline-code">null</code> when absent. System-installed agent skills under the read-only <code class="readme-inline-code">agents_skills_folder</code> are served too (see <a href="#on-disk-layout">On-disk layout</a>).</td> <td>Orientation: "when and why to use my worker's tools"</td> </tr> <tr> <td><strong>System prompts</strong> (<code class="readme-inline-code">directory::system-prompts::*</code>)</td> <td>Identity prompts listed by <code class="readme-inline-code">list</code>, read by <code class="readme-inline-code">get</code>, authored by <code class="readme-inline-code">create</code>, edited by <code class="readme-inline-code">update</code>, and removed by <code class="readme-inline-code">delete</code>. The list response keeps its <code class="readme-inline-code">prompts</code> field name. Stored under any <code class="readme-inline-code">system-prompts/</code> path segment; <code class="readme-inline-code">create</code> writes <code class="readme-inline-code"><skills_folder>/system-prompts/<name>.md</code>.</td> <td>What the chat's system-prompt picker offers as an identity prompt (enrich or replace)</td> </tr> <tr> <td><strong>Agent Profiles</strong> (<code class="readme-inline-code">directory::agents::*</code>)</td> <td>Reusable session identities whose file body is the system prompt, with display <code class="readme-inline-code">name</code>, emoji <code class="readme-inline-code">logo</code>, a <code class="readme-inline-code">skills</code> filter, and optional <code class="readme-inline-code">model</code> + <code class="readme-inline-code">reasoning_effort</code> in required frontmatter. <code class="readme-inline-code">list</code> rows carry the display/configuration metadata and <code class="readme-inline-code">get</code> adds <code class="readme-inline-code">system_prompt</code> and <code class="readme-inline-code">unknown_skills</code>. Stored as direct <code class="readme-inline-code"><agents_folder>/<id>.md</code> files. See <a href="../docs/architecture/agent-profile-storage.md">Agent profile storage</a>.</td> <td>A named identity selected with <code class="readme-inline-code">harness::send { options: { agent } }</code></td> </tr> <tr> <td><strong>Search</strong> (<code class="readme-inline-code">directory::search_functions</code>)</td> <td>One to six external capabilities → compact function-id candidates (installed, plus registry workers under <code class="readme-inline-code">installable</code>), with a conditional pre-generate hint pointing agents at it.</td> <td>"Which functions do I call for this task?"</td> </tr> <tr> <td><strong>Registry</strong> (<code class="readme-inline-code">directory::registry::*</code>)</td> <td>HTTP proxy over <code class="readme-inline-code">api.workers.iii.dev</code> with <code class="readme-inline-code">workers::{list,info}</code>. Rows share the core <code class="readme-inline-code">name</code> / <code class="readme-inline-code">description</code> / <code class="readme-inline-code">version</code> fields with the engine's <code class="readme-inline-code">engine::workers::list</code> and add publication metadata (<code class="readme-inline-code">type</code>, <code class="readme-inline-code">config</code>, <code class="readme-inline-code">supported_targets</code>, <code class="readme-inline-code">total_downloads</code>, <code class="readme-inline-code">dependencies</code>, optional <code class="readme-inline-code">image</code>). <code class="readme-inline-code">workers::list</code> is cursor-paginated with a server-authored page size.</td> <td>"What's published in the public registry?"</td> </tr> </tbody></table> <p>Engine introspection (functions / triggers / registered triggers / workers) is served by the engine natively at <code class="readme-inline-code">engine::functions::*</code>, <code class="readme-inline-code">engine::triggers::*</code>, <code class="readme-inline-code">engine::registered-triggers::*</code>, and <code class="readme-inline-code">engine::workers::*</code>. Call the engine ids directly. One wrapper survives for callers that can only reach the <code class="readme-inline-code">directory::</code> namespace: <code class="readme-inline-code">directory::engine::functions::info</code> proxies a single function's schema (see its row below).</p> <p>This worker is where an agent's identity text LIVES. <code class="readme-inline-code">skills/system-prompts/iii-runtime.md</code> ships here and is the one copy of "how to work against a live iii engine" — <code class="readme-inline-code">claude-code</code> and <code class="readme-inline-code">pi</code> fetch it with <code class="readme-inline-code">directory::system-prompts::get name=iii-runtime</code> (plus <code class="readme-inline-code">directory::skills::index</code>) for both their headless turns and their console terminals, rather than compiling a prompt of their own. Edit that file and every agent reads the edit; no worker release involved.</p> <p>Skills and system prompts are sourced from <code class="readme-inline-code">skills_folder</code>; agent profiles use the dedicated <code class="readme-inline-code">agents_folder</code>. Writes are the <strong><code class="readme-inline-code">directory::skills::download*</code></strong> functions, which pull markdown from either the <a href="https://workers.iii.dev">workers registry</a> or a GitHub repo and route each supported family to its configured root, plus the per-kind single-file editors — <code class="readme-inline-code">directory::skills::{create,update,delete}</code>, <code class="readme-inline-code">directory::system-prompts::{create,update,delete}</code> and <code class="readme-inline-code">directory::agents::{create,update,delete}</code>. Once downloaded, files belong to the developer — edit them however you want, in the editor of your choice: a change made directly on disk fires the matching <code class="readme-inline-code">on-change</code> with <code class="readme-inline-code">op: "external"</code> (see <a href="#custom-trigger-types">Custom trigger types</a>).</p> <p><code class="readme-inline-code">directory::registry::workers::*</code> and the engine's <code class="readme-inline-code">engine::workers::*</code> share the core <code class="readme-inline-code">name</code> / <code class="readme-inline-code">description</code> / <code class="readme-inline-code">version</code> fields so a parser that touches only those keys works against either surface; the registry view also surfaces publication metadata (<code class="readme-inline-code">type</code>, <code class="readme-inline-code">config</code>, <code class="readme-inline-code">supported_targets</code>, <code class="readme-inline-code">total_downloads</code>, <code class="readme-inline-code">dependencies</code>, optional <code class="readme-inline-code">image</code>) and the engine view adds runtime / connection state.</p> <h2 id="table-of-contents" class="scroll-mt-20">Table of contents</h2> <ol> <li><a href="#install">Install</a></li> <li><a href="#configuration">Configuration</a></li> <li><a href="#quickstart-download-some-skills">Quickstart: download some skills</a></li> <li><a href="#on-disk-layout">On-disk layout</a></li> <li><a href="#skill-ids">Skill ids</a></li> <li><a href="#functions">Functions</a></li> <li><a href="#function-search--pre-generate-hint">Function search & pre-generate hint</a></li> <li><a href="#custom-trigger-types">Custom trigger types</a></li> <li><a href="#local-development--testing">Local development & testing</a></li> <li><a href="#migration-from-skills-v02x">Migration from skills v0.2.x</a></li> </ol> <hr> <h2 id="install" class="scroll-mt-20">Install</h2> <pre class="shiki vitesse-light" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span style="color:#59873A">iii</span><span style="color:#B56959"> trigger</span><span style="color:#B56959"> compose::add</span><span style="color:#B56959"> worker=iii-directory</span></span></code></pre><p><code class="readme-inline-code">iii trigger compose::add</code> resolves the worker and its dependencies, writes exact declarations to <code class="readme-inline-code">worker-compose.yaml</code>, and reconciles the Compose project.</p> <hr> <h2 id="skills" class="scroll-mt-20">Skills</h2> <p>Install the <code class="readme-inline-code">iii-directory</code> agent skill for Claude Code, Cursor, and 30+ other agents:</p> <pre class="shiki vitesse-light" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span style="color:#59873A">npx</span><span style="color:#B56959"> skills</span><span style="color:#B56959"> add</span><span style="color:#B56959"> iii-hq/workers</span><span style="color:#A65E2B"> --skill</span><span style="color:#B56959"> iii-directory</span></span></code></pre><p>Browse or install every worker skill at once:</p> <pre class="shiki vitesse-light" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span style="color:#59873A">npx</span><span style="color:#B56959"> skills</span><span style="color:#B56959"> add</span><span style="color:#B56959"> iii-hq/workers</span><span style="color:#A65E2B"> --list</span></span> <span class="line"><span style="color:#59873A">npx</span><span style="color:#B56959"> skills</span><span style="color:#B56959"> add</span><span style="color:#B56959"> iii-hq/workers</span><span style="color:#A65E2B"> --all</span></span></code></pre><hr> <h2 id="configuration" class="scroll-mt-20">Configuration</h2> <p>Runtime settings live in the <strong><code class="readme-inline-code">configuration</code> worker</strong> under id <strong><code class="readme-inline-code">iii-directory</code></strong> (the same pattern <code class="readme-inline-code">database</code> and <code class="readme-inline-code">storage</code> use). At boot the worker registers its JSON Schema, reads the live value via <code class="readme-inline-code">configuration::get</code> (the configuration worker env-expands <code class="readme-inline-code">${VAR}</code>), and binds a <code class="readme-inline-code">configuration</code> trigger so it re-fetches on change.</p> <p>Persisted values default to <code class="readme-inline-code">./data/configuration/iii-directory.yaml</code> (fs adapter). Edit that file directly, call <code class="readme-inline-code">configuration::set id=iii-directory</code>, or use the Console's global Settings modal — all three propagate without a redeploy.</p> <h3 id="fields" class="scroll-mt-20">Fields</h3> <pre class="shiki vitesse-light" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span style="color:#A0ADA0"># TOPOLOGY — changing any of these requires a worker restart.</span></span> <span class="line"><span style="color:#998418">skills_folder</span><span style="color:#999999">:</span><span style="color:#B56959"> skills</span><span style="color:#A0ADA0"> # under III_COMPOSE_DIR, or the process cwd standalone</span></span> <span class="line"><span style="color:#998418">local_skills_folder</span><span style="color:#999999">:</span><span style="color:#B56959"> skills/iii</span><span style="color:#A0ADA0"> # project-scoped overrides (whole-namespace local-wins)</span></span> <span class="line"><span style="color:#998418">agents_folder</span><span style="color:#999999">:</span><span style="color:#B56959"> agents</span><span style="color:#A0ADA0"> # direct <id>.md agent profiles</span></span> <span class="line"><span style="color:#998418">agents_skills_folder</span><span style="color:#999999">:</span><span style="color:#B56959"> .agents/skills</span><span style="color:#A0ADA0"> # READ-ONLY agent skills, with the same relative-path base</span></span> <span class="line"><span style="color:#998418">auto_download</span><span style="color:#999999">:</span><span style="color:#1E754F"> true</span><span style="color:#A0ADA0"> # subscribe to worker-add + run the boot reconcile</span></span> <span class="line"></span> <span class="line"><span style="color:#A0ADA0"># TUNABLE — hot-reload live on `configuration:updated`.</span></span> <span class="line"><span style="color:#998418">registry_url</span><span style="color:#999999">:</span><span style="color:#B56959"> https://api.workers.iii.dev</span><span style="color:#A0ADA0"> # workers registry base URL</span></span> <span class="line"><span style="color:#998418">download_timeout_ms</span><span style="color:#999999">:</span><span style="color:#2F798A"> 60000</span><span style="color:#A0ADA0"> # per git-clone / HTTP request timeout (ms)</span></span> <span class="line"><span style="color:#998418">registry_cache_ttl_ms</span><span style="color:#999999">:</span><span style="color:#2F798A"> 60000</span><span style="color:#A0ADA0"> # in-process TTL for registry::workers::* responses</span></span> <span class="line"><span style="color:#998418">filter_unregistered</span><span style="color:#999999">:</span><span style="color:#1E754F"> true</span><span style="color:#A0ADA0"> # hide skills whose namespace isn't an installed worker</span></span> <span class="line"><span style="color:#998418">inject_hint</span><span style="color:#999999">:</span><span style="color:#1E754F"> false</span><span style="color:#A0ADA0"> # bind the directory::pre-generate search-hint hook (off: the harness identity prompt already teaches directory-first discovery)</span></span> <span class="line"><span style="color:#998418">hint_min_workers</span><span style="color:#999999">:</span><span style="color:#2F798A"> 2</span><span style="color:#A0ADA0"> # minimum surface width before the hint fires (0 = always)</span></span> <span class="line"><span style="color:#998418">registry_search</span><span style="color:#999999">:</span><span style="color:#1E754F"> true</span><span style="color:#A0ADA0"> # include installable registry workers in every search</span></span></code></pre><p>The writable <code class="readme-inline-code">skills_folder</code> and <code class="readme-inline-code">agents_folder</code> roots are created when needed.</p> <h3 id="zero-config-default-seed" class="scroll-mt-20">Zero-config default + seed</h3> <p>With no seed and no stored value the worker uses built-in defaults. Relative folder paths use <code class="readme-inline-code">III_COMPOSE_DIR</code> when set and the process current directory otherwise (<code class="readme-inline-code">skills_folder: skills</code>, <code class="readme-inline-code">agents_folder: agents</code>, <code class="readme-inline-code">registry_url: https://api.workers.iii.dev</code>). Pass <code class="readme-inline-code">--config <path></code> to supply a YAML seed: when present and no value is stored yet, its contents become <code class="readme-inline-code">initial_value</code> on <code class="readme-inline-code">configuration::register</code> (see <a href="config.yaml.example"><code class="readme-inline-code">config.yaml.example</code></a>). Engine-managed deployments inline the config under the worker entry; the engine delivers it via <code class="readme-inline-code">--config</code>.</p> <h3 id="hot-reload" class="scroll-mt-20">Hot reload</h3> <p>On <code class="readme-inline-code">configuration::set</code> (or an external edit to the persisted file), the worker re-fetches the authoritative value. Tunable changes apply in place and the registry caches are cleared so a repointed <code class="readme-inline-code">registry_url</code> takes effect immediately. Topology changes (<code class="readme-inline-code">skills_folder</code> / <code class="readme-inline-code">local_skills_folder</code> / <code class="readme-inline-code">agents_folder</code> / <code class="readme-inline-code">agents_skills_folder</code> / <code class="readme-inline-code">auto_download</code>) are refused with a "restart required" log; the previous configuration is kept until the worker restarts.</p> <p>The writable <code class="readme-inline-code">skills_folder</code>, <code class="readme-inline-code">local_skills_folder</code>, and <code class="readme-inline-code">agents_folder</code> are watch roots, and the watcher creates each one at boot if it is missing. Direct <code class="readme-inline-code"><id>.md</code> edits under <code class="readme-inline-code">agents_folder</code> fire <code class="readme-inline-code">directory::agents::on-change</code> with <code class="readme-inline-code">op: "external"</code>; nested files are ignored. <code class="readme-inline-code">agents_skills_folder</code> is a watch root too, but only when it already exists — the worker never creates (or writes) anything under it. Install your first agents skill while the worker is running and that root stays unwatched until the next restart: reads still serve it, since every read re-scans disk, but the live <code class="readme-inline-code">external</code> doorbell is missing until then. <code class="readme-inline-code">local_skills_folder</code> defaults to <code class="readme-inline-code">skills/iii</code> under <code class="readme-inline-code">III_COMPOSE_DIR</code>, or under the process current directory when the worker runs standalone. An empty local root shadows nothing. Because the roots are restart-required, the watch roots are fixed for the process lifetime.</p> <hr> <h2 id="quickstart-download-some-skills" class="scroll-mt-20">Quickstart: download some skills</h2> <pre class="shiki vitesse-light" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span style="color:#A0ADA0"># Pull a specific worker's directory bundle at a fixed semver from</span></span> <span class="line"><span style="color:#A0ADA0"># the registry. Files land under `<skills_folder>/agent-memory/`.</span></span> <span class="line"><span style="color:#59873A">iii</span><span style="color:#B56959"> trigger</span><span style="color:#A65E2B"> --function-id=directory::skills::download</span><span style="color:#A65E2B"> \</span></span> <span class="line"><span style="color:#A65E2B"> --payload=</span><span style="color:#B5695977">'</span><span style="color:#B56959">{"worker": "agent-memory", "version": "1.2.3"}</span><span style="color:#B5695977">'</span></span> <span class="line"></span> <span class="line"><span style="color:#A0ADA0"># Same, but always fetch whatever's tagged `latest` (also the default</span></span> <span class="line"><span style="color:#A0ADA0"># when neither version nor tag is given).</span></span> <span class="line"><span style="color:#59873A">iii</span><span style="color:#B56959"> trigger</span><span style="color:#A65E2B"> --function-id=directory::skills::download</span><span style="color:#A65E2B"> \</span></span> <span class="line"><span style="color:#A65E2B"> --payload=</span><span style="color:#B5695977">'</span><span style="color:#B56959">{"worker": "agent-memory"}</span><span style="color:#B5695977">'</span></span> <span class="line"></span> <span class="line"><span style="color:#A0ADA0"># Pull a single subfolder out of a public GitHub repo via</span></span> <span class="line"><span style="color:#A0ADA0"># `git clone --depth 1 --branch main`. Files land under</span></span> <span class="line"><span style="color:#A0ADA0"># `<skills_folder>/frontend-design/`. The `branch` field defaults to</span></span> <span class="line"><span style="color:#A0ADA0"># `main`; pass `"master"` for older repos that haven't migrated.</span></span> <span class="line"><span style="color:#59873A">iii</span><span style="color:#B56959"> trigger</span><span style="color:#A65E2B"> --function-id=directory::skills::download</span><span style="color:#A65E2B"> \</span></span> <span class="line"><span style="color:#A65E2B"> --payload=</span><span style="color:#B5695977">'</span><span style="color:#B56959">{</span></span> <span class="line"><span style="color:#B56959"> "repo": "https://github.com/anthropics/skills",</span></span> <span class="line"><span style="color:#B56959"> "skill": "frontend-design"</span></span> <span class="line"><span style="color:#B56959"> }</span><span style="color:#B5695977">'</span></span></code></pre><p>The response is <code class="readme-inline-code">{ namespace, skills_written, system_prompts_written, agents_written, source }</code>. The three <code class="readme-inline-code">*_written</code> fields list the files materialised in this run. Registry entries shaped exactly as <code class="readme-inline-code">agents/<id>.md</code> land in <code class="readme-inline-code"><agents_folder>/<id>.md</code>; repo downloads do not install agent profiles.</p> <p>After every successful download the worker fires the <code class="readme-inline-code">directory::skills::on-change</code>, <code class="readme-inline-code">directory::system-prompts::on-change</code>, and/or <code class="readme-inline-code">directory::agents::on-change</code> trigger types so that subscribers like the <a href="https://github.com/iii-hq/workers/tree/main/mcp"><code class="readme-inline-code">mcp</code></a> worker can forward MCP <code class="readme-inline-code">notifications/list_changed</code> to their clients.</p> <hr> <h2 id="on-disk-layout" class="scroll-mt-20">On-disk layout</h2> <p>The worker uses separate roots for directory content and agent profiles:</p> <pre><code>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 system-prompts/ # ← magic marker for system prompts reviewer.md # ← identity prompt (needs YAML frontmatter) system-prompts/ # ← where system-prompts::create writes pirate.md agents_folder/ # ← where agents::create writes release-captain.md # ← agent profile (needs YAML frontmatter) frontend-design.md # ← `extends: iii` builds on the bundled base</code></pre><p>Two base agent profiles ship inside the worker binary: <code class="readme-inline-code">iii</code> (the harness default identity, verbatim) and <code class="readme-inline-code">iii-minimal</code> (the minimal directory-first identity — the same text as the bundled system prompt of that name). Each is always listed (<code class="readme-inline-code">builtin: true</code>), a local <code class="readme-inline-code">agents_folder/<id>.md</code> shadows it, <code class="readme-inline-code">update</code> on it copy-on-writes that local file, and deleting the file falls back to the bundled copy. No file is ever seeded on disk.</p> <p>A second, READ-ONLY root — <code class="readme-inline-code">agents_skills_folder</code> (default <code class="readme-inline-code">.agents/skills</code> under the same Compose or standalone base) — serves agent skills. It is scanned <strong>shallowly</strong>: only <code class="readme-inline-code"><skill-dir>/SKILL.md</code> becomes an entry (id <code class="readme-inline-code"><skill-dir>/index</code>, displayed as <code class="readme-inline-code"><skill-dir></code>); a skill's <code class="readme-inline-code">reference/</code>, <code class="readme-inline-code">scripts/</code>, or other support payload is never listed. A missing directory is silently empty. These skills bypass <code class="readme-inline-code">filter_unregistered</code> (their namespaces are skills, not workers), stay out of <code class="readme-inline-code">directory::skills::index</code> (a per-WORKER surface), and are refused by <code class="readme-inline-code">update</code>/<code class="readme-inline-code">delete</code> — edit them with their owning tool, or copy one into <code class="readme-inline-code">skills_folder</code> on disk to fork it. Precedence is <code class="readme-inline-code">local_skills_folder</code> > <code class="readme-inline-code">skills_folder</code> > <code class="readme-inline-code">agents_skills_folder</code>, namespace-wise: a top-level namespace directory in a higher root shadows the same namespace below.</p> <p>A few rules:</p> <ul> <li><strong>Skill ids</strong> are the relative path under <code class="readme-inline-code">skills_folder</code> with <code class="readme-inline-code">.md</code> stripped. Each segment must satisfy <code class="readme-inline-code">[a-z0-9_-]{1,64}</code>.</li> <li><strong>Skill frontmatter is optional.</strong> When present, the reader recognises <code class="readme-inline-code">title:</code> (preferred title), <code class="readme-inline-code">name:</code> (title fallback), <code class="readme-inline-code">type:</code> (free-form classifier), <code class="readme-inline-code">function_id:</code> (canonical bus function id surfaced by <code class="readme-inline-code">list</code> and <code class="readme-inline-code">get</code>), <code class="readme-inline-code">description:</code> (preferred <code class="readme-inline-code">list</code> teaser), and <code class="readme-inline-code">disable-model-invocation:</code> (boolean, default <code class="readme-inline-code">false</code>, surfaced as <code class="readme-inline-code">disable_model_invocation</code> by both responses). The body H1 and first paragraph are the title and list-description fallbacks, respectively. Disabled skills remain visible to ordinary directory clients; model index consumers decide whether to filter them. Any other YAML keys are ignored.</li> <li><strong>System prompts</strong> live under any <code class="readme-inline-code">*/system-prompts/*.md</code> path, with YAML frontmatter (<code class="readme-inline-code">description</code> required, <code class="readme-inline-code">name</code> optional). A path carrying both a <code class="readme-inline-code">prompts</code> and a <code class="readme-inline-code">system-prompts</code> segment is a system prompt because <code class="readme-inline-code">system-prompts</code> is classified first. Other paths containing a <code class="readme-inline-code">prompts</code> segment are ignored by scans and downloads.</li> <li><strong>What a system prompt can do, by design.</strong> The console's chat picker can send a selected system prompt with <code class="readme-inline-code">system_prompt_strategy: "override"</code>, which replaces the harness's built-in identity prompt with that file's body verbatim. Files reach <code class="readme-inline-code">system-prompts/</code> either by local authoring or via <code class="readme-inline-code">directory::skills::download</code> from a git repo or the registry, so a downloaded bundle can supply one. This is an accepted property, not a hole: it takes a deliberate selection in the UI, the same UI already accepts arbitrary typed text, and the operator owns <code class="readme-inline-code">skills_folder</code>. Worth knowing before you point <code class="readme-inline-code">skills_folder</code> at a directory other people can write to.</li> <li><strong>Agent profiles</strong> are direct <code class="readme-inline-code"><agents_folder>/<id>.md</code> files (unrelated to the read-only <code class="readme-inline-code">agents_skills_folder</code> above, which holds external tools' <em>skills</em>). Nested profiles and the former <code class="readme-inline-code"><skills_folder>/**/agents/*.md</code> layout are ignored. Frontmatter is required and must declare a non-empty <code class="readme-inline-code">name</code> (the display name — the id is always the file stem); <code class="readme-inline-code">description</code> may be empty, <code class="readme-inline-code">logo</code> is emoji-only (≤16 bytes, no path characters), <code class="readme-inline-code">skills:</code> filters the skill index (absent/empty = every skill), and <code class="readme-inline-code">model:</code> names a model id for sessions using this profile (absent = the send decides), and optional <code class="readme-inline-code">reasoning_effort:</code> names its provider-native effort. Both are stored verbatim and resolved against the live model catalog where they are used. The body is the system prompt, verbatim, and may be empty — a profile with no prompt of its own contributes only its parent chain (if any) and its non-prompt settings. Unknown <code class="readme-inline-code">skills</code> ids are warnings surfaced by <code class="readme-inline-code">get</code>, never load failures.</li> <li><strong>Agent profiles inherit.</strong> <code class="readme-inline-code">extends: <id></code> names one parent profile (chains allowed, at most 8 hops). The resolved system prompt served by <code class="readme-inline-code">get</code> is the parent's resolved prompt followed by a blank line and this file's body — a blank body contributes nothing, so a profile with no prompt of its own serves its parent chain unchanged; <code class="readme-inline-code">skills</code>, <code class="readme-inline-code">model</code> and <code class="readme-inline-code">reasoning_effort</code> fall back to the nearest ancestor that sets them when omitted (a non-empty <code class="readme-inline-code">skills</code> list replaces, never unions); <code class="readme-inline-code">name</code>, <code class="readme-inline-code">description</code>, <code class="readme-inline-code">logo</code>, <code class="readme-inline-code">icon</code> and <code class="readme-inline-code">color</code> are always the profile's own. A chain that does not resolve (unknown parent, loop, too deep) is reported by <code class="readme-inline-code">list</code>/<code class="readme-inline-code">get</code> as <code class="readme-inline-code">inheritance_error</code> (<code class="readme-inline-code">D415</code> text) while the profile still serves its own file (so the editor can fix it); the harness refuses to run it.</li> <li>Under a skills root, files outside <code class="readme-inline-code">prompts/</code>, <code class="readme-inline-code">system-prompts/</code>, and reserved <code class="readme-inline-code">agents/</code> segments are skills.</li> </ul> <p>The download function namespaces by source:</p> <table> <thead> <tr> <th>Source</th> <th>Destination</th> </tr> </thead> <tbody><tr> <td><code class="readme-inline-code">repo=URL skill=NAME branch?=main</code></td> <td><code class="readme-inline-code"><skills_folder>/<NAME>/...</code></td> </tr> <tr> <td><code class="readme-inline-code">worker=NAME version=…</code></td> <td>Skills/prompts under <code class="readme-inline-code"><skills_folder>/<NAME>/...</code>; exact <code class="readme-inline-code">agents/<id>.md</code> entries under <code class="readme-inline-code"><agents_folder>/<id>.md</code></td> </tr> <tr> <td><code class="readme-inline-code">worker=NAME tag=…</code> (default <code class="readme-inline-code">tag=latest</code>)</td> <td>Same routing as the version form</td> </tr> </tbody></table> <p>Re-pulling the same source overwrites files <strong>file-by-file</strong> — existing siblings outside the response set are preserved (so hand-edited additions survive a re-pull).</p> <hr> <h2 id="skill-ids" class="scroll-mt-20">Skill ids</h2> <p>Skills are addressed by their relative path under <code class="readme-inline-code">skills_folder</code> with <code class="readme-inline-code">.md</code> stripped — e.g. <code class="readme-inline-code"><skills_folder>/agent-memory/observe.md</code> → id <code class="readme-inline-code">"agent-memory/observe"</code>. The same string is what <code class="readme-inline-code">directory::skills::list</code> returns and what <code class="readme-inline-code">directory::skills::get</code> expects in <code class="readme-inline-code">{ "id": ... }</code>. The legacy <code class="readme-inline-code">iii://{id}</code> link form is still accepted on <code class="readme-inline-code">get</code> (the prefix is auto-stripped), but the worker no longer parses any other <code class="readme-inline-code">iii://</code> URI shape — bodies are read solely by id, and the auto-rendered tree-shaped index that previous releases served at <code class="readme-inline-code">iii://directory/skills</code> is gone. Consumers that want a tree-shaped picker iterate <code class="readme-inline-code">list</code> rows themselves and indent by <code class="readme-inline-code">id.matches('/').count()</code>.</p> <hr> <h2 id="functions" class="scroll-mt-20">Functions</h2> <p>Functions sit under <code class="readme-inline-code">directory::*</code>. All registrations are namespace-clean; this worker is intentionally agnostic to MCP and any other adapter.</p> <h3 id="directoryskills-filesystem-reader-editor" class="scroll-mt-20"><code class="readme-inline-code">directory::skills::*</code> (filesystem reader + editor)</h3> <table> <thead> <tr> <th>Function ID</th> <th>Description</th> </tr> </thead> <tbody><tr> <td><code class="readme-inline-code">directory::skills::download</code></td> <td>Download directory content. Flexible alias accepting either source set: <code class="readme-inline-code">{repo, skill, branch?}</code> (defaults <code class="readme-inline-code">branch=main</code>) or <code class="readme-inline-code">{worker, version?|tag?}</code> (defaults <code class="readme-inline-code">tag=latest</code>). Prefer the two explicit forms below so the source is unambiguous.</td> </tr> <tr> <td><code class="readme-inline-code">directory::skills::download_from_repo</code></td> <td>Repo-only form: <code class="readme-inline-code">{repo, skill, branch?}</code>. Copies one skill folder out of a GitHub repo; paths under <code class="readme-inline-code">prompts/</code> and <code class="readme-inline-code">agents/</code> are ignored.</td> </tr> <tr> <td><code class="readme-inline-code">directory::skills::download_from_registry</code></td> <td>Registry-only form: <code class="readme-inline-code">{worker, version?|tag?}</code>. Installs a published worker's bundle from <code class="readme-inline-code">api.workers.iii.dev</code>, routing exact <code class="readme-inline-code">agents/<id>.md</code> entries to <code class="readme-inline-code">agents_folder</code>.</td> </tr> <tr> <td><code class="readme-inline-code">directory::skills::list</code></td> <td>Enriched listing of every fs-backed skill: <code class="readme-inline-code">{ id, title, type, function_id, disable_model_invocation, description, bytes, modified_at }</code> per row. <code class="readme-inline-code">title</code> prefers the YAML frontmatter <code class="readme-inline-code">title:</code> over the body H1, <code class="readme-inline-code">type</code> is lifted from frontmatter <code class="readme-inline-code">type:</code> (<code class="readme-inline-code">null</code> when absent), <code class="readme-inline-code">function_id</code> identifies the documented bus function when present, and <code class="readme-inline-code">description</code> is the frontmatter description or first body paragraph — so consumers can render a picker without a follow-up <code class="readme-inline-code">get</code> per row.</td> </tr> <tr> <td><code class="readme-inline-code">directory::skills::get</code></td> <td>Fetch one skill by id. Returns <code class="readme-inline-code">{ id, title, type, function_id, disable_model_invocation, path, body, modified_at }</code>. It shares the list row's identity, classification, function, and invocation metadata, but returns the raw markdown <code class="readme-inline-code">body</code> and absolute on-disk <code class="readme-inline-code">path</code> instead of the teaser and byte count; there is no <code class="readme-inline-code">description</code> field. The path's parent directory is the skill's base directory, where payload like <code class="readme-inline-code">scripts/</code> and <code class="readme-inline-code">reference/</code> lives, and is meaningful only to callers on this worker's machine. Accepts a bare id or the same id prefixed with <code class="readme-inline-code">iii://</code>. Pass <code class="readme-inline-code">raw: true</code> to additionally get the FULL on-disk file (frontmatter included) as <code class="readme-inline-code">raw</code> — the round-trip form <code class="readme-inline-code">update</code> takes.</td> </tr> <tr> <td><code class="readme-inline-code">directory::skills::update</code></td> <td>Overwrite one EXISTING skill file with new full-file content: <code class="readme-inline-code">{ id, content }</code> where <code class="readme-inline-code">content</code> is the edited <code class="readme-inline-code">raw</code> from <code class="readme-inline-code">get { raw: true }</code>. Validated against the read invariants (size cap, non-empty body after frontmatter); atomic write; fans out <code class="readme-inline-code">directory::skills::on-change</code> with <code class="readme-inline-code">op: "update"</code>. Never creates files (use <code class="readme-inline-code">create</code>). Refuses read-only system-installed skills under <code class="readme-inline-code">agents_skills_folder</code> (<code class="readme-inline-code">D116</code>).</td> </tr> <tr> <td><code class="readme-inline-code">directory::skills::create</code></td> <td>Create a NEW skill file at <code class="readme-inline-code"><skills_folder>/<id>.md</code> from full-file content: <code class="readme-inline-code">{ id, content }</code>. Frontmatter is optional (same rules as <code class="readme-inline-code">update</code>: size cap, non-empty body). Refuses an <code class="readme-inline-code">id</code> that already resolves in the visible set — including the <code class="readme-inline-code"><id></code> → <code class="readme-inline-code"><id>/index</code> overview alias and system-installed agents skills — or a target path that already exists on disk (<code class="readme-inline-code">D114</code>); an <code class="readme-inline-code">id</code> in a namespace reserved by a system-installed agents skill (<code class="readme-inline-code">D115</code>); and, while <code class="readme-inline-code">filter_unregistered</code> is on, an <code class="readme-inline-code">id</code> the visibility filter would immediately hide (<code class="readme-inline-code">D115</code>). Atomic write; fans out <code class="readme-inline-code">directory::skills::on-change</code> with <code class="readme-inline-code">op: "create"</code>. Returns the same shape as <code class="readme-inline-code">update</code>.</td> </tr> <tr> <td><code class="readme-inline-code">directory::skills::delete</code></td> <td>Permanently remove one EXISTING skill file by <code class="readme-inline-code">{ id }</code> (same id forms as <code class="readme-inline-code">get</code>). Resolves against the same visible set as <code class="readme-inline-code">list</code>/<code class="readme-inline-code">get</code>, refuses read-only system-installed skills under <code class="readme-inline-code">agents_skills_folder</code> (<code class="readme-inline-code">D116</code>), removes the file plus any parent directories left empty (so a deleted namespace can't keep shadowing a lower-precedence root), and fans out <code class="readme-inline-code">directory::skills::on-change</code> with <code class="readme-inline-code">op: "delete"</code>. Returns <code class="readme-inline-code">{ id }</code> (the resolved on-disk id).</td> </tr> <tr> <td><code class="readme-inline-code">directory::skills::index</code></td> <td>Render one short markdown entry per installed worker (skills with frontmatter <code class="readme-inline-code">type: index</code>). Returns <code class="readme-inline-code">{ body, workers_count }</code> where <code class="readme-inline-code">body</code> is a ready-to-paste page: <code class="readme-inline-code"># Skills index</code>, then one <code class="readme-inline-code">## <worker title></code> heading + the worker's first overview paragraph + a <code class="readme-inline-code">Read iii://<ns>/index</code> pointer the agent can follow with <code class="readme-inline-code">directory::skills::get</code>. Token-light by design; use <code class="readme-inline-code">directory::skills::list</code> for per-skill rows.</td> </tr> </tbody></table> <h3 id="directorysystem-prompts-filesystem-reader-editor" class="scroll-mt-20"><code class="readme-inline-code">directory::system-prompts::*</code> (filesystem reader + editor)</h3> <table> <thead> <tr> <th>Function ID</th> <th>Description</th> </tr> </thead> <tbody><tr> <td><code class="readme-inline-code">directory::system-prompts::list</code></td> <td>Metadata-only listing of every fs-backed system prompt.</td> </tr> <tr> <td><code class="readme-inline-code">directory::system-prompts::get</code></td> <td>Fetch one system prompt's body + <code class="readme-inline-code">{name, description, modified_at}</code>. Plain shape, no envelope. Pass <code class="readme-inline-code">raw: true</code> to additionally get the FULL on-disk file (frontmatter included) as <code class="readme-inline-code">raw</code>.</td> </tr> <tr> <td><code class="readme-inline-code">directory::system-prompts::update</code></td> <td>Overwrite one EXISTING system prompt file with new full-file content: <code class="readme-inline-code">{ name, content }</code>. The frontmatter must keep a non-empty <code class="readme-inline-code">description</code> (and a valid <code class="readme-inline-code">name</code> when declared) — the same rules the scanner enforces. Atomic write; fans out <code class="readme-inline-code">directory::system-prompts::on-change</code> with <code class="readme-inline-code">op: "update"</code>. Returns the system prompt's effective name after the write.</td> </tr> <tr> <td><code class="readme-inline-code">directory::system-prompts::create</code></td> <td>Create a NEW system prompt file at <code class="readme-inline-code"><skills_folder>/system-prompts/<name>.md</code> from full-file content: <code class="readme-inline-code">{ name, content }</code>, where <code class="readme-inline-code">content</code> is the FULL file including frontmatter. The frontmatter must carry a non-empty <code class="readme-inline-code">description</code> (and a <code class="readme-inline-code">name</code> matching the request, when declared) — the same rules <code class="readme-inline-code">update</code> enforces. Refuses a <code class="readme-inline-code">name</code> that already exists anywhere in the merged system-prompt scan, and a target path that already exists on disk even if the scanner would skip it. Atomic write; fans out <code class="readme-inline-code">directory::system-prompts::on-change</code> with <code class="readme-inline-code">op: "create"</code>. Returns <code class="readme-inline-code">{ name, description, bytes, modified_at }</code>.</td> </tr> <tr> <td><code class="readme-inline-code">directory::system-prompts::delete</code></td> <td>Permanently remove one EXISTING system prompt file by <code class="readme-inline-code">{ name }</code>. Resolves against the same merged scan as <code class="readme-inline-code">list</code>/<code class="readme-inline-code">get</code>, fans out <code class="readme-inline-code">directory::system-prompts::on-change</code> with <code class="readme-inline-code">op: "delete"</code>, and returns <code class="readme-inline-code">{ name }</code>.</td> </tr> </tbody></table> <h3 id="agent-profiles-directoryagents-filesystem-reader-editor" class="scroll-mt-20">Agent Profiles — <code class="readme-inline-code">directory::agents::*</code> (filesystem reader + editor)</h3> <table> <thead> <tr> <th>Function ID</th> <th>Description</th> </tr> </thead> <tbody><tr> <td><code class="readme-inline-code">directory::agents::list</code></td> <td>Metadata-only listing of every agent profile — fs-backed plus the bundled <code class="readme-inline-code">iii</code> / <code class="readme-inline-code">iii-minimal</code> bases (<code class="readme-inline-code">builtin: true</code> until a local file shadows one): <code class="readme-inline-code">{ id, name, description, logo, skill_count, model, reasoning_effort, icon, color, extends, modified_at }</code> per row, <code class="readme-inline-code">skill_count</code>/<code class="readme-inline-code">model</code>/<code class="readme-inline-code">reasoning_effort</code> resolved through <code class="readme-inline-code">extends</code> (<code class="readme-inline-code">skill_count: null</code> = every skill; <code class="readme-inline-code">model: null</code> = the send decides). A row whose chain does not resolve carries <code class="readme-inline-code">inheritance_error</code>.</td> </tr> <tr> <td><code class="readme-inline-code">directory::agents::get</code></td> <td>Fetch one agent profile by <code class="readme-inline-code">{ id }</code>: the RESOLVED <code class="readme-inline-code">system_prompt</code> (each ancestor's body root-first, then this file's body), <code class="readme-inline-code">skills</code> + <code class="readme-inline-code">unknown_skills</code> (filter entries matching no visible skill — warnings), <code class="readme-inline-code">model</code> (<code class="readme-inline-code">null</code> = the send decides), provider-native <code class="readme-inline-code">reasoning_effort</code>, display <code class="readme-inline-code">icon</code>/<code class="readme-inline-code">color</code>, <code class="readme-inline-code">extends</code>, <code class="readme-inline-code">builtin</code>, <code class="readme-inline-code">modified_at</code>, and <code class="readme-inline-code">inheritance_error</code> when the chain does not resolve (own file served meanwhile). Pass <code class="readme-inline-code">raw: true</code> to additionally get this profile's FULL on-disk file as <code class="readme-inline-code">raw</code>.</td> </tr> <tr> <td><code class="readme-inline-code">directory::agents::update</code></td> <td>Overwrite one EXISTING agent profile file with new full-file content: <code class="readme-inline-code">{ id, content }</code>. Same rules the scanner enforces (required frontmatter with non-empty <code class="readme-inline-code">name</code>, emoji-only <code class="readme-inline-code">logo</code>; the body — the system prompt — may be empty); the id stays the file stem. Updating a bundled profile creates the local file that shadows it. Atomic write; fans out <code class="readme-inline-code">directory::agents::on-change</code> with <code class="readme-inline-code">op: "update"</code>.</td> </tr> <tr> <td><code class="readme-inline-code">directory::agents::create</code></td> <td>Create a NEW agent profile at <code class="readme-inline-code"><agents_folder>/<id>.md</code> from full-file content: <code class="readme-inline-code">{ id, content }</code>. Refuses an <code class="readme-inline-code">id</code> that already exists in the configured agent-profile root, and a target path that already exists on disk even if the scanner would skip it; creating a bundled id shadows the bundled copy. Atomic write; fans out <code class="readme-inline-code">directory::agents::on-change</code> with <code class="readme-inline-code">op: "create"</code>. Returns <code class="readme-inline-code">{ id, name, description, logo, bytes, modified_at }</code>.</td> </tr> <tr> <td><code class="readme-inline-code">directory::agents::delete</code></td> <td>Permanently remove one EXISTING agent profile file by <code class="readme-inline-code">{ id }</code>. Resolves against the same configured root as <code class="readme-inline-code">list</code>/<code class="readme-inline-code">get</code>, fans out <code class="readme-inline-code">directory::agents::on-change</code> with <code class="readme-inline-code">op: "delete"</code>, and returns <code class="readme-inline-code">{ id }</code>. Deleting the local shadow of a bundled profile falls back to the bundled copy; a bundled profile with no local file has nothing to delete (<code class="readme-inline-code">D414</code>). Sessions already using the profile are unaffected; profiles extending it stop resolving until fixed.</td> </tr> </tbody></table> <h3 id="engine-introspection-native-plus-one-wrapper" class="scroll-mt-20">Engine introspection (native, plus one wrapper)</h3> <p>Engine introspection is served natively; call these ids directly — every one takes the same filters (<code class="readme-inline-code">prefix</code>, <code class="readme-inline-code">search</code>, <code class="readme-inline-code">worker</code>, <code class="readme-inline-code">include_internal</code> where applicable). One wrapper is kept for callers whose policy only admits the <code class="readme-inline-code">directory::</code> namespace:</p> <table> <thead> <tr> <th>Function ID</th> <th>Description</th> </tr> </thead> <tbody><tr> <td><code class="readme-inline-code">directory::engine::functions::info</code></td> <td>Thin proxy to <code class="readme-inline-code">engine::functions::info</code> for a single <code class="readme-inline-code">function_id</code>: request/response schemas, metadata, and registered triggers. The one <code class="readme-inline-code">directory::engine::*</code> helper that still exists — reach for it only when you cannot call <code class="readme-inline-code">engine::*</code> directly.</td> </tr> </tbody></table> <p>The native ids:</p> <table> <thead> <tr> <th>Function ID</th> <th>Description</th> </tr> </thead> <tbody><tr> <td><code class="readme-inline-code">engine::functions::list</code></td> <td>List functions registered with the engine.</td> </tr> <tr> <td><code class="readme-inline-code">engine::functions::info</code></td> <td>Single-function detail: schemas, owning worker.</td> </tr> <tr> <td><code class="readme-inline-code">engine::triggers::list</code></td> <td>List trigger TYPES (the providers, e.g. <code class="readme-inline-code">http</code>, <code class="readme-inline-code">cron</code>).</td> </tr> <tr> <td><code class="readme-inline-code">engine::triggers::info</code></td> <td>Single trigger-type detail: configuration schema, return schema.</td> </tr> <tr> <td><code class="readme-inline-code">engine::registered-triggers::list</code></td> <td>List trigger INSTANCES (subscriber rows).</td> </tr> <tr> <td><code class="readme-inline-code">engine::registered-triggers::info</code></td> <td>Single registered-trigger detail.</td> </tr> <tr> <td><code class="readme-inline-code">engine::workers::list</code></td> <td>List workers with an open engine WS connection. Daemon-managed providers (<code class="readme-inline-code">http</code>, <code class="readme-inline-code">cron</code>, <code class="readme-inline-code">state</code>) won't appear — call <code class="readme-inline-code">worker::list</code> from the supervisor to see those.</td> </tr> <tr> <td><code class="readme-inline-code">engine::workers::info</code></td> <td>One worker's detail by <code class="readme-inline-code">name</code>.</td> </tr> </tbody></table> <h3 id="directoryregistry-workers-registry-http-proxy" class="scroll-mt-20"><code class="readme-inline-code">directory::registry::*</code> (workers registry HTTP proxy)</h3> <table> <thead> <tr> <th>Function ID</th> <th>Description</th> </tr> </thead> <tbody><tr> <td><code class="readme-inline-code">directory::registry::workers::list</code></td> <td>Browse / search published workers in <code class="readme-inline-code">api.workers.iii.dev</code>. Optional free-text <code class="readme-inline-code">search</code> (matched fuzzy by <code class="readme-inline-code">pg_trgm</code>) and opaque <code class="readme-inline-code">cursor</code> for pagination; page size is server-authored. Response is <code class="readme-inline-code">{ workers: [...], pagination: { next_cursor, has_more, page_size } }</code>. Shares the core <code class="readme-inline-code">name</code> / <code class="readme-inline-code">description</code> / <code class="readme-inline-code">version</code> fields with the engine's <code class="readme-inline-code">engine::workers::list</code>.</td> </tr> <tr> <td><code class="readme-inline-code">directory::registry::workers::info</code></td> <td>Full registry detail for one worker. Fans out two parallel registry calls — <code class="readme-inline-code">GET /w/{slug}</code> for the worker envelope (publication metadata + readme + functions + triggers) and <code class="readme-inline-code">GET /w/{slug}/skills</code> for the skills tree — and merges them into <code class="readme-inline-code">{ worker, readme, api_reference, skills_tree }</code>. The user-facing input still accepts <code class="readme-inline-code">version:</code> (semver) or <code class="readme-inline-code">tag:</code> (e.g. <code class="readme-inline-code">latest</code>); both go on the wire as <code class="readme-inline-code">?version=…</code>.</td> </tr> </tbody></table> <p>Both <code class="readme-inline-code">directory::registry::*</code> responses are cached in-process for <code class="readme-inline-code">registry_cache_ttl_ms</code> (default 60s).</p> <p>There is <strong>no</strong> <code class="readme-inline-code">directory::skills::register</code> — see <a href="#migration-from-skills-v02x">Migration</a> below.</p> <hr> <h2 id="function-search-pre-generate-hint" class="scroll-mt-20">Function search & pre-generate hint</h2> <p>One-shot lexical function search over the live engine catalog, absorbed from the former <code class="readme-inline-code">discovery</code> worker. It returns only compact <code class="readme-inline-code">{ function_id, description }</code> candidates, grouped by worker in rank order. The model chooses the candidates it needs, then fetches their contracts in one <code class="readme-inline-code">engine::functions::info { function_ids: [...] }</code> call instead of walking the catalog with <code class="readme-inline-code">engine::functions::list</code>.</p> <table> <thead> <tr> <th>Function</th> <th>Kind</th> <th>What it does</th> </tr> </thead> <tbody><tr> <td><code class="readme-inline-code">directory::search_functions</code></td> <td>public</td> <td><code class="readme-inline-code">{ capabilities }</code> → <code class="readme-inline-code">{ guidance, workers[], installable[]?, latency_ms }</code>: BM25 rank over the live engine catalog (at most 6 workers / 12 candidates) plus matching NOT-installed registry workers under <code class="readme-inline-code">installable</code>. <code class="readme-inline-code">capabilities</code> is a required list of one to six non-empty unmet external capability searches. Requests to summarize provided text/content are ignored.</td> </tr> <tr> <td><code class="readme-inline-code">directory::pre-generate</code></td> <td>internal hook</td> <td>Injects the conditional search hint into a harness generation (at most once per turn).</td> </tr> <tr> <td><code class="readme-inline-code">directory::on-functions-change</code></td> <td>internal</td> <td>Refreshes the search catalog on the engine's functions-available push.</td> </tr> <tr> <td><code class="readme-inline-code">directory::hint-preview</code></td> <td>internal</td> <td>The exact hint text per exposure mode, for the configuration UI.</td> </tr> </tbody></table> <p>Ranking pipeline:</p> <ol> <li><strong>Corpus</strong>: the live engine catalog (boot snapshot + push refresh), slimmed to name + first description sentence + argument names. <code class="readme-inline-code">engine::</code> ids, functions published with <code class="readme-inline-code">metadata.internal</code>, and the search itself never participate — the worker's own public <code class="readme-inline-code">directory::*</code> functions are searchable like any other capability.</li> <li><strong>Scoring</strong>: Okapi BM25 (k1 1.2, b 0.75) with the function name indexed at 3× weight, camelCase segmentation (<code class="readme-inline-code">presignUrl</code> → presign + url), a 22-word grammatical stoplist, conservative plural folding, JSON-key stripping from capability text, and a two-distinct-terms minimum match.</li> <li><strong>Capability queries</strong>: each <code class="readme-inline-code">capabilities</code> entry is ranked independently against its own leader and is authoritative. Include every currently unmet external capability once in the same call. Write every capability in English, translating non-English requests while preserving proper names, URLs, and function ids. Requests to summarize provided text or content are ignored. Results merge round-robin so every capability gets a candidate before any gets a rider.</li> <li><strong>Pruning</strong>: coverage-aware function floor (≥50% of the leader AND full term coverage or ≥85% score) drops same-worker family riders; a namespace-level floor (40% of the leader) drops trailing workers.</li> <li><strong>Registry search</strong> (<code class="readme-inline-code">registry_search</code>, default on): every call also consults the public workers registry in-process with the same capability queries plus informative-term retries (all concurrent; verified authors only). Candidates merge round-robin across search variants, returning up to 2 workers / 6 candidates that WOULD match if installed, with <code class="readme-inline-code">compose::add</code> guidance.</li> <li><strong>Session memory</strong> (keyed by caller-supplied OTel baggage, fail-open): repeat queries omit candidates already delivered.</li> </ol> <p>The pre-generate hook appends one <code class="readme-inline-code"><discovery_assist></code> block pointing the model at <code class="readme-inline-code">search_functions</code>, telling it to derive capabilities from the goal and current execution state and to batch selected ids through <code class="readme-inline-code">engine::functions::info</code> — at most once per turn, and only when every gate clears: the function is callable in the surface, no search result is in the current task window yet, the surface spans at least <code class="readme-inline-code">hint_min_workers</code> distinct workers, the current task (from the latest user message) has no real function results yet, and it does not already name a callable function id. Measured on 26 pre-existing e2e scenarios: an unconditional hint <em>induces</em> redundant discovery on guided tasks (up to +110% tokens). The hook ships OFF by default (<code class="readme-inline-code">inject_hint: false</code>): the harness identity prompt already teaches <code class="readme-inline-code">directory::search_functions</code> as the default discovery path, so the hint is for deployments running a custom identity prompt without that doctrine. The hook's transcript annotations (<code class="readme-inline-code">origin.directory</code>) carry only coarse outcome/reason and counts.</p> <p>Knobs (<code class="readme-inline-code">inject_hint</code>, <code class="readme-inline-code">hint_min_workers</code>, <code class="readme-inline-code">registry_search</code>) live in the <code class="readme-inline-code">iii-directory</code> configuration entry and hot-apply — see Configuration.</p> <h2 id="custom-trigger-types" class="scroll-mt-20">Custom trigger types</h2> <table> <thead> <tr> <th>Trigger type</th> <th>Fires when</th> <th>Payload to subscribers</th> </tr> </thead> <tbody><tr> <td><code class="readme-inline-code">directory::skills::on-change</code></td> <td>After a <code class="readme-inline-code">directory::skills::download</code> that wrote at least one skill markdown file, a <code class="readme-inline-code">directory::skills::update</code>, <code class="readme-inline-code">create</code>, or <code class="readme-inline-code">delete</code>, or external (file pasted/edited/deleted directly on disk — including under <code class="readme-inline-code">agents_skills_folder</code>)</td> <td>download: <code class="readme-inline-code">{ "op": "download", "namespace": "<ns>", "source": "repo" | "registry" }</code>; update/create/delete: <code class="readme-inline-code">{ "op": "<operation>", "namespace": "<ns>", "id": "<id>" }</code>; external (file pasted/edited/deleted directly on disk): <code class="readme-inline-code">{ "op": "external" }</code></td> </tr> <tr> <td><code class="readme-inline-code">directory::system-prompts::on-change</code></td> <td>After a <code class="readme-inline-code">directory::skills::download</code> that wrote at least one system prompt markdown file, a <code class="readme-inline-code">directory::system-prompts::update</code>, <code class="readme-inline-code">create</code>, <code class="readme-inline-code">delete</code>, or external file change</td> <td>download: <code class="readme-inline-code">{ "op": "download", "namespace": "<ns>", "source": "repo" | "registry" }</code>; update/create/delete: <code class="readme-inline-code">{ "op": "<operation>", "name": "<name>" }</code>; external: <code class="readme-inline-code">{ "op": "external" }</code></td> </tr> <tr> <td><code class="readme-inline-code">directory::agents::on-change</code></td> <td>After a <code class="readme-inline-code">directory::skills::download</code> that wrote at least one agent profile, a <code class="readme-inline-code">directory::agents::update</code>, <code class="readme-inline-code">create</code>, <code class="readme-inline-code">delete</code>, or external file change</td> <td>download: <code class="readme-inline-code">{ "op": "download", "namespace": "<ns>", "source": "repo" | "registry" }</code>; update/create/delete: <code class="readme-inline-code">{ "op": "<operation>", "name": "<id>" }</code>; external: <code class="readme-inline-code">{ "op": "external" }</code></td> </tr> </tbody></table> <p>Dispatches are fire-and-forget (Void), so the write path doesn't block on downstream latency.</p> <p>The <code class="readme-inline-code">external</code> op comes from a filesystem watch over <code class="readme-inline-code">skills_folder</code>, <code class="readme-inline-code">local_skills_folder</code>, and (when it already exists) the read-only <code class="readme-inline-code">agents_skills_folder</code>. It is a doorbell, not a ledger: every read re-scans disk, so a missed event costs a stale open view until the next call, never data. A burst coalesces into one event per kind, and this worker's own writes are suppressed — a <code class="readme-inline-code">create</code> or <code class="readme-inline-code">update</code> sends its precise op and never an extra <code class="readme-inline-code">external</code>.</p> <p><strong>Loop hazard for subscribers.</strong> Suppression covers writes made <em>through this worker</em>. A subscriber that reacts to <code class="readme-inline-code">{ "op": "external" }</code> by writing <code class="readme-inline-code">.md</code> files under <code class="readme-inline-code">skills_folder</code> by some other route — a shell or coder worker, a script — is not suppressed and will re-trigger itself. Either write through <code class="readme-inline-code">directory::*::update</code> / <code class="readme-inline-code">create</code>, or make the reaction idempotent and gated.</p> <hr> <h2 id="local-development-testing" class="scroll-mt-20">Local development & testing</h2> <h3 id="run-from-source" class="scroll-mt-20">Run from source</h3> <pre class="shiki vitesse-light" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span style="color:#A0ADA0"># --config is an optional YAML seed (see config.yaml.example); omit it to</span></span> <span class="line"><span style="color:#A0ADA0"># rely on the value stored in the `configuration` worker (or built-in defaults).</span></span> <span class="line"><span style="color:#59873A">cargo</span><span style="color:#B56959"> run</span><span style="color:#A65E2B"> --release</span><span style="color:#A65E2B"> --</span><span style="color:#A65E2B"> --url</span><span style="color:#B56959"> ws://127.0.0.1:49134</span><span style="color:#A65E2B"> --config</span><span style="color:#B56959"> ./config.yaml.example</span></span></code></pre><h3 id="tests" class="scroll-mt-20">Tests</h3> <pre class="shiki vitesse-light" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span style="color:#A0ADA0"># Fast, offline — exercises the pure helpers (markdown / id validators</span></span> <span class="line"><span style="color:#A0ADA0"># / fs source) without needing an iii engine.</span></span> <span class="line"><span style="color:#59873A">cargo</span><span style="color:#B56959"> test</span><span style="color:#A65E2B"> --lib</span></span> <span class="line"></span> <span class="line"><span style="color:#A0ADA0"># Full BDD suite — requires an iii engine on ws://127.0.0.1:49134</span></span> <span class="line"><span style="color:#A0ADA0"># (or III_ENGINE_WS_URL). The git-backed download scenarios spin up</span></span> <span class="line"><span style="color:#A0ADA0"># a local fixture repo via `git init`; the registry-backed scenarios</span></span> <span class="line"><span style="color:#A0ADA0"># point a wiremock server at the worker's `registry_url` config.</span></span> <span class="line"><span style="color:#59873A">cargo</span><span style="color:#B56959"> test</span></span> <span class="line"></span> <span class="line"><span style="color:#A0ADA0"># One feature group at a time. Available tags:</span></span> <span class="line"><span style="color:#A0ADA0"># @engine @read @download @download_repo @download_registry</span></span> <span class="line"><span style="color:#59873A">cargo</span><span style="color:#B56959"> test</span><span style="color:#A65E2B"> --test</span><span style="color:#B56959"> bdd</span><span style="color:#A65E2B"> --</span><span style="color:#A65E2B"> --tags</span><span style="color:#B56959"> @download</span></span></code></pre><p>The BDD harness lives under <a href="tests/">tests/</a>. Feature files mirror the modules in <a href="src/functions/">src/functions/</a>. Step definitions under <a href="tests/steps/">tests/steps/</a> drive each feature through the same <code class="readme-inline-code">iii.trigger</code> path the production binary uses.</p> </div></div></section></div><aside class="flex flex-col gap-y-4 @4xl:sticky @4xl:top-4 @4xl:self-start @4xl:max-h-[calc(100dvh-2rem)] @4xl:overflow-y-auto"><div class="border border-rule bg-bg"><div class="bg-panel px-3.5 py-2.5 border-b border-rule"><span class="font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint">details</span></div><div class="p-4 flex flex-col gap-y-2.5"><div class="flex items-baseline justify-between font-mono text-[13px] gap-x-3"><span class="text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]">version</span><span class="text-ink truncate text-right lowercase tabular-nums">v1.2.8</span></div><div class="flex items-baseline justify-between font-mono text-[13px] gap-x-3"><span class="text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]">type</span><span class="text-ink truncate text-right lowercase ">binary</span></div><div class="flex items-baseline justify-between font-mono text-[13px] gap-x-3"><span class="text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]">license</span><span class="text-ink truncate text-right ">Apache-2.0</span></div><div class="flex items-baseline justify-between font-mono text-[13px] gap-x-3 min-w-0"><span class="text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]">repo</span><a href="https://github.com/iii-hq/workers" target="_blank" rel="noreferrer" class="inline-flex items-center gap-x-1 font-mono text-[13px] text-ink lowercase hover:text-accent transition-colors min-w-0 text-right justify-end"><span class="truncate">iii-hq/workers</span><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link size-3 shrink-0" aria-hidden="true"><path d="M15 3h6v6"></path><path d="M10 14 21 3"></path><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path></svg></a></div></div></div><div class="border border-rule bg-bg"><div class="bg-panel px-3.5 py-2.5 border-b border-rule"><span class="font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint">api</span></div><div class="p-4 flex flex-col gap-y-4"><div class="flex flex-col gap-y-1.5"><div class="flex items-baseline justify-between"><span class="font-mono text-[10px] uppercase tracking-[0.18em] text-ink-ghost">functions</span><span class="font-mono text-[10px] text-ink-ghost tabular-nums">29</span></div><ul class="flex flex-col"><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::__on_worker_added">directory::__on_worker_added</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::agents::create">directory::agents::create</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::agents::delete">directory::agents::delete</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::agents::get">directory::agents::get</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::agents::list">directory::agents::list</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::agents::update">directory::agents::update</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::engine::functions::info">directory::engine::functions::info</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::hint-preview">directory::hint-preview</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::on-config-change">directory::on-config-change</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::on-functions-change">directory::on-functions-change</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::pre-generate">directory::pre-generate</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::registry::workers::info">directory::registry::workers::info</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::registry::workers::list">directory::registry::workers::list</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::search_functions">directory::search_functions</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::skills::create">directory::skills::create</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::skills::delete">directory::skills::delete</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::skills::download">directory::skills::download</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::skills::download_from_registry">directory::skills::download_from_registry</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::skills::download_from_repo">directory::skills::download_from_repo</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::skills::get">directory::skills::get</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::skills::index">directory::skills::index</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::skills::list">directory::skills::list</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::skills::update">directory::skills::update</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::system-prompts::create">directory::system-prompts::create</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::system-prompts::delete">directory::system-prompts::delete</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::system-prompts::get">directory::system-prompts::get</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::system-prompts::list">directory::system-prompts::list</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-directory::system-prompts::update">directory::system-prompts::update</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#fn-iii-directory::ui-content">iii-directory::ui-content</a></li></ul></div><div class="flex flex-col gap-y-1.5"><div class="flex items-baseline justify-between"><span class="font-mono text-[10px] uppercase tracking-[0.18em] text-ink-ghost">triggers</span><span class="font-mono text-[10px] text-ink-ghost tabular-nums">3</span></div><ul class="flex flex-col"><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#trigger-directory::agents::on-change">directory::agents::on-change</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#trigger-directory::skills::on-change">directory::skills::on-change</a></li><li><a class="block font-mono text-[12.5px] truncate py-0.5 transition-colors text-ink hover:text-accent" href="/workers/iii-directory?tab=api#trigger-directory::system-prompts::on-change">directory::system-prompts::on-change</a></li></ul></div></div></div><div class="border border-rule bg-bg"><div class="bg-panel px-3.5 py-2.5 border-b border-rule"><span class="font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint">author</span></div><div class="p-4 flex flex-col gap-y-2.5"><div class="flex items-center gap-x-2 font-mono text-[13px]"><img src="https://iii.dev/docs/_mintlify/favicons/motiadev/AFkVbz_UcSL_5jsm/_generated/favicon/apple-touch-icon.png" alt="" class="size-5 object-cover"/><span class="text-ink lowercase">iii</span><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-check size-3.5 text-accent" aria-hidden="true"><path d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z"></path><path d="m9 12 2 2 4-4"></path></svg></div></div></div></aside></div></div></div><!--$--><!--/$--></main><footer class="border-t border-rule bg-bg"><div class="flex items-center justify-between flex-wrap gap-x-6 gap-y-3 px-9 py-4.5"><div class="inline-flex items-center gap-x-4"><a aria-label="iii worker — registry home" class="inline-flex items-center gap-x-2 text-ink" href="/"><svg viewBox="0 0 1075.74 1075.69" aria-hidden="true" focusable="false" class="size-[14px]" fill="currentColor"><rect x="0" y="0.05" width="268.94" height="268.94"></rect><rect x="403.4" y="0.05" width="268.94" height="268.94"></rect><rect x="806.81" y="0.05" width="268.94" height="268.94"></rect><rect x="0" y="403.45" width="268.94" height="672.24"></rect><rect x="403.4" y="403.45" width="268.94" height="672.24"></rect><rect x="806.81" y="403.45" width="268.94" height="672.24"></rect></svg><span class="font-mono text-[13px] font-medium tracking-[-0.02em] lowercase">iii / worker</span></a><a href="https://github.com/iii-hq/iii" target="_blank" rel="noopener noreferrer" aria-label="iii-hq/iii on GitHub — 18,671 stars" class="inline-flex shrink-0 items-center gap-x-2 border border-rule px-2.5 py-1 font-mono text-[13px] text-ink-faint transition-colors hover:text-ink sm:hidden"><svg viewBox="0 0 16 16" aria-hidden="true" focusable="false" class="size-3.5 shrink-0" fill="currentColor"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z"></path></svg><span class="hidden sm:inline lowercase">stars</span><span class="tabular-nums text-ink" aria-hidden="true">18.7k</span></a></div><nav aria-label="footer" class="flex items-center flex-wrap gap-x-6 gap-y-2"><a href="https://iii.dev" target="_blank" rel="noreferrer" class="inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors">iii.dev<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link size-3 shrink-0" aria-hidden="true"><path d="M15 3h6v6"></path><path d="M10 14 21 3"></path><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path></svg></a><a href="https://iii.dev/docs" target="_blank" rel="noreferrer" class="inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors">docs<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link size-3 shrink-0" aria-hidden="true"><path d="M15 3h6v6"></path><path d="M10 14 21 3"></path><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path></svg></a><a class="font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors" href="/collections">collections</a><a class="font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors" href="/leaderboard">leaderboard</a><a class="font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors" href="/publish">publish</a><a class="font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors" href="/badge-preview">badge preview</a><a href="https://discord.gg/iiidev" target="_blank" rel="noreferrer" class="inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors">discord<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link size-3 shrink-0" aria-hidden="true"><path d="M15 3h6v6"></path><path d="M10 14 21 3"></path><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path></svg></a><a href="https://github.com/iii-hq/iii" target="_blank" rel="noreferrer" class="inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors">github<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link size-3 shrink-0" aria-hidden="true"><path d="M15 3h6v6"></path><path d="M10 14 21 3"></path><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path></svg></a></nav></div></footer></div></div><script src="/_next/static/chunks/0b_t-9oq5.7ee.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n3:I[20685,[\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\"],\"SiteHeader\"]\n5:I[90280,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\"],\"default\"]\n6:I[69616,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\"],\"default\"]\n7:I[46610,[\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0.o_9ma339h6h.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\"],\"\"]\ne:I[50609,[\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/02eqejg_b4k2y.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\"],\"default\"]\n11:I[41074,[\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0.o_9ma339h6h.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\"],\"default\"]\n13:I[51557,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\"],\"OutletBoundary\"]\n14:\"$Sreact.suspense\"\n17:I[51557,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\"],\"ViewportBoundary\"]\n19:I[51557,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\"],\"MetadataBoundary\"]\n:HL[\"/_next/static/chunks/0acd84rxu64yw.css?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"style\"]\n:HL[\"/_next/static/media/387ee14c0e0fe675-s.p.16njqniuj6huf.woff2?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:[\"$\",\"iframe\",null,{\"src\":\"https://www.googletagmanager.com/ns.html?id=GTM-N8DCTFB8\",\"height\":\"0\",\"width\":\"0\",\"style\":{\"display\":\"none\",\"visibility\":\"hidden\"},\"title\":\"Google Tag Manager\"}]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"workers\",\"iii-directory\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"workers\",{\"children\":[[\"slug\",\"iii-directory\",\"d\",null],{\"children\":[\"__PAGE__\",{}]}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0acd84rxu64yw.css?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"chivo_mono_90504305-module__244I6q__variable antialiased\",\"data-theme\":\"light\",\"suppressHydrationWarning\":true,\"children\":[\"$\",\"body\",null,{\"className\":\"bg-bg text-ink font-sans min-h-full flex flex-col\",\"children\":[[[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"\\n try {\\n var stored = localStorage.getItem('iii-theme');\\n if (stored === 'dark' || stored === 'light') {\\n document.documentElement.dataset.theme = stored;\\n } else {\\n document.documentElement.dataset.theme = 'light';\\n }\\n } catch (_) {\\n document.documentElement.dataset.theme = 'light';\\n }\\n\"}}],[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"\\n (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':\\n new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],\\n j=d.createElement(s),dl=l!='dataLayer'?'\u0026l='+l:'';j.async=true;j.src=\\n 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);\\n })(window,document,'script','dataLayer','GTM-N8DCTFB8');\\n\"}}]],[\"$\",\"noscript\",null,{\"children\":\"$2\"}],[\"$\",\"div\",null,{\"className\":\"mx-auto w-full max-w-[1200px] @container border-x border-rule min-h-screen bg-bg flex flex-col\",\"children\":[[\"$\",\"a\",null,{\"href\":\"#main-content\",\"className\":\"sr-only focus:not-sr-only focus:absolute focus:left-4 focus:top-4 focus:z-50 focus:bg-ink focus:text-bg focus:px-3 focus:py-2 focus:font-mono focus:text-[13px] lowercase\",\"children\":\"skip to content\"}],[\"$\",\"$L3\",null,{\"githubStars\":\"$L4\"}],[\"$\",\"div\",null,{\"className\":\"flex-1 overflow-x-clip flex flex-col\",\"children\":[[\"$\",\"main\",null,{\"id\":\"main-content\",\"className\":\"flex-1\",\"tabIndex\":-1,\"children\":[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"div\",null,{\"className\":\"page-transition\",\"children\":[\"$\",\"div\",null,{\"className\":\"flex items-end justify-between flex-wrap gap-x-6 gap-y-4 px-9 py-12\",\"children\":[[\"$\",\"div\",null,{\"className\":\"min-w-0\",\"children\":[[\"$\",\"div\",null,{\"className\":\"font-mono text-[11px] uppercase tracking-[0.06em] text-ink-faint mb-3\",\"children\":[\"$\",\"span\",null,{\"className\":\"font-mono text-accent\",\"children\":[\"$$\",[\"$\",\"span\",null,{\"className\":\"text-ink ml-2\",\"children\":\"error\"}]]}]}],[\"$\",\"div\",null,{\"className\":\"flex items-baseline flex-wrap gap-x-3 gap-y-1\",\"children\":[[\"$\",\"h1\",null,{\"className\":\"font-mono text-[28px] font-medium tracking-[-0.01em] text-ink lowercase\",\"children\":[\"$\",\"span\",null,{\"className\":\"inline-flex items-baseline gap-x-2 tabular-nums\",\"children\":[\"404\",[\"$\",\"span\",null,{\"aria-hidden\":true,\"className\":\"blink inline-block w-[6px] h-[13px] bg-ink align-middle translate-y-[1px]\"}]]}]}],null]}],[\"$\",\"p\",null,{\"className\":\"mt-3 font-mono text-[14px] leading-[1.7] text-ink-faint max-w-[60ch] lowercase\",\"children\":\"that worker is not in the registry. it may have been renamed or never published.\"}]]}],[\"$\",\"div\",null,{\"className\":\"flex items-center gap-x-3\",\"children\":[\"$\",\"$L7\",null,{\"href\":\"/\",\"className\":\"inline-flex items-center justify-center gap-x-2 whitespace-nowrap font-mono lowercase rounded-none transition-[background-color,color,border-color,transform] duration-150 ease-out focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-accent disabled:pointer-events-none disabled:opacity-40 select-none active:scale-[0.97] motion-reduce:active:scale-100 bg-ink text-bg border border-ink hover:bg-bg hover:text-ink h-9 px-5 text-[13px]\",\"children\":\"back to registry\"}]}]]}]}],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}],\"$L8\"]}]]}]]}]}]]}],{\"children\":[\"$L9\",{\"children\":[\"$La\",{\"children\":[\"$Lb\",{},null,false,null]},null,false,\"$@c\"]},null,false,\"$@c\"]},null,false,null],\"$Ld\",false]],\"m\":\"$undefined\",\"G\":[\"$e\",[\"$Lf\"]],\"S\":false,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"8:[\"$\",\"footer\",null,{\"className\":\"border-t border-rule bg-bg\",\"children\":[\"$\",\"div\",null,{\"className\":\"flex items-center justify-between flex-wrap gap-x-6 gap-y-3 px-9 py-4.5\",\"children\":[[\"$\",\"div\",null,{\"className\":\"inline-flex items-center gap-x-4\",\"children\":[[\"$\",\"$L7\",null,{\"href\":\"/\",\"aria-label\":\"iii worker — registry home\",\"className\":\"inline-flex items-center gap-x-2 text-ink\",\"children\":[[\"$\",\"svg\",null,{\"viewBox\":\"0 0 1075.74 1075.69\",\"aria-hidden\":\"true\",\"focusable\":\"false\",\"className\":\"size-[14px]\",\"fill\":\"currentColor\",\"children\":[[\"$\",\"rect\",null,{\"x\":\"0\",\"y\":\"0.05\",\"width\":\"268.94\",\"height\":\"268.94\"}],[\"$\",\"rect\",null,{\"x\":\"403.4\",\"y\":\"0.05\",\"width\":\"268.94\",\"height\":\"268.94\"}],[\"$\",\"rect\",null,{\"x\":\"806.81\",\"y\":\"0.05\",\"width\":\"268.94\",\"height\":\"268.94\"}],[\"$\",\"rect\",null,{\"x\":\"0\",\"y\":\"403.45\",\"width\":\"268.94\",\"height\":\"672.24\"}],[\"$\",\"rect\",null,{\"x\":\"403.4\",\"y\":\"403.45\",\"width\":\"268.94\",\"height\":\"672.24\"}],[\"$\",\"rect\",null,{\"x\":\"806.81\",\"y\":\"403.45\",\"width\":\"268.94\",\"height\":\"672.24\"}]]}],[\"$\",\"span\",null,{\"className\":\"font-mono text-[13px] font-medium tracking-[-0.02em] lowercase\",\"children\":\"iii / worker\"}]]}],\"$L10\"]}],[\"$\",\"nav\",null,{\"aria-label\":\"footer\",\"className\":\"flex items-center flex-wrap gap-x-6 gap-y-2\",\"children\":[[\"$\",\"a\",\"https://iii.dev\",{\"href\":\"https://iii.dev\",\"target\":\"_blank\",\"rel\":\"noreferrer\",\"className\":\"inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":[\"iii.dev\",[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":[[\"path\",{\"d\":\"M15 3h6v6\",\"key\":\"1q9fwt\"}],[\"path\",{\"d\":\"M10 14 21 3\",\"key\":\"gplh6r\"}],[\"path\",{\"d\":\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\",\"key\":\"a6xqqp\"}]],\"className\":\"lucide-external-link size-3 shrink-0\",\"aria-hidden\":true}]]}],[\"$\",\"a\",\"https://iii.dev/docs\",{\"href\":\"https://iii.dev/docs\",\"target\":\"_blank\",\"rel\":\"noreferrer\",\"className\":\"inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":[\"docs\",[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":\"$8:props:children:props:children:1:props:children:0:props:children:1:props:iconNode\",\"className\":\"lucide-external-link size-3 shrink-0\",\"aria-hidden\":true}]]}],[\"$\",\"$L7\",\"/collections\",{\"href\":\"/collections\",\"className\":\"font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":\"collections\"}],[\"$\",\"$L7\",\"/leaderboard\",{\"href\":\"/leaderboard\",\"className\":\"font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":\"leaderboard\"}],[\"$\",\"$L7\",\"/publish\",{\"href\":\"/publish\",\"className\":\"font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":\"publish\"}],[\"$\",\"$L7\",\"/badge-preview\",{\"href\":\"/badge-preview\",\"className\":\"font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":\"badge preview\"}],[\"$\",\"a\",\"https://discord.gg/iiidev\",{\"href\":\"https://discord.gg/iiidev\",\"target\":\"_blank\",\"rel\":\"noreferrer\",\"className\":\"inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":[\"discord\",[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":\"$8:props:children:props:children:1:props:children:0:props:children:1:props:iconNode\",\"className\":\"lucide-external-link size-3 shrink-0\",\"aria-hidden\":true}]]}],[\"$\",\"a\",\"https://github.com/iii-hq/iii\",{\"href\":\"https://github.com/iii-hq/iii\",\"target\":\"_blank\",\"rel\":\"noreferrer\",\"className\":\"inline-flex items-center gap-x-1 font-mono text-[13px] text-ink-faint hover:text-ink lowercase transition-colors\",\"children\":[\"github\",[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":\"$8:props:children:props:children:1:props:children:0:props:children:1:props:iconNode\",\"className\":\"lucide-external-link size-3 shrink-0\",\"aria-hidden\":true}]]}]]}]]}]}]\n"])</script><script>self.__next_f.push([1,"9:[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}]\na:[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}]\nb:[\"$\",\"$1\",\"c\",{\"children\":[\"$L12\",[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0.o_9ma339h6h.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L13\",null,{\"children\":[\"$\",\"$14\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@15\"}]}]]}]\n16:[]\nc:\"$W16\"\nd:[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L17\",null,{\"children\":\"$L18\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L19\",null,{\"children\":[\"$\",\"$14\",null,{\"name\":\"Next.Metadata\",\"children\":\"$L1a\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}]\nf:[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0acd84rxu64yw.css?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]\n18:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"4:[\"$\",\"a\",null,{\"href\":\"https://github.com/iii-hq/iii\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"aria-label\":\"iii-hq/iii on GitHub — 18,671 stars\",\"className\":\"shrink-0 items-center gap-x-2 border border-rule px-2.5 py-1 font-mono text-[13px] text-ink-faint transition-colors hover:text-ink hidden sm:inline-flex\",\"children\":[[\"$\",\"svg\",null,{\"viewBox\":\"0 0 16 16\",\"aria-hidden\":\"true\",\"focusable\":\"false\",\"className\":\"size-3.5 shrink-0\",\"fill\":\"currentColor\",\"children\":[\"$\",\"path\",null,{\"d\":\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z\"}]}],[\"$\",\"span\",null,{\"className\":\"hidden sm:inline lowercase\",\"children\":\"stars\"}],[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"aria-hidden\":true,\"children\":\"18.7k\"}]]}]\n10:[\"$\",\"a\",null,{\"href\":\"https://github.com/iii-hq/iii\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"aria-label\":\"iii-hq/iii on GitHub — 18,671 stars\",\"className\":\"inline-flex shrink-0 items-center gap-x-2 border border-rule px-2.5 py-1 font-mono text-[13px] text-ink-faint transition-colors hover:text-ink sm:hidden\",\"children\":[[\"$\",\"svg\",null,{\"viewBox\":\"0 0 16 16\",\"aria-hidden\":\"true\",\"focusable\":\"false\",\"className\":\"size-3.5 shrink-0\",\"fill\":\"currentColor\",\"children\":[\"$\",\"path\",null,{\"d\":\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z\"}]}],[\"$\",\"span\",null,{\"className\":\"hidden sm:inline lowercase\",\"children\":\"stars\"}],[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"aria-hidden\":true,\"children\":\"18.7k\"}]]}]\n"])</script><script>self.__next_f.push([1,"1b:I[18418,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\"],\"IconMark\"]\n15:null\n"])</script><script>self.__next_f.push([1,"1a:[[\"$\",\"title\",\"0\",{\"children\":\"iii-directory - iii worker\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Engine introspection, workers registry proxy, filesystem-backed skills, system prompts, and agent profiles, plus lexical function search with a conditional pre-generate hint.\"}],[\"$\",\"meta\",\"2\",{\"name\":\"robots\",\"content\":\"index, follow\"}],[\"$\",\"link\",\"3\",{\"rel\":\"canonical\",\"href\":\"https://workers.iii.dev/workers/iii-directory\"}],[\"$\",\"meta\",\"4\",{\"property\":\"og:title\",\"content\":\"iii-directory - iii worker\"}],[\"$\",\"meta\",\"5\",{\"property\":\"og:description\",\"content\":\"Engine introspection, workers registry proxy, filesystem-backed skills, system prompts, and agent profiles, plus lexical function search with a conditional pre-generate hint.\"}],[\"$\",\"meta\",\"6\",{\"property\":\"og:url\",\"content\":\"https://workers.iii.dev/workers/iii-directory\"}],[\"$\",\"meta\",\"7\",{\"property\":\"og:image\",\"content\":\"https://workers.iii.dev/workers/iii-directory/opengraph-image?bced171a25d0f70f\"}],[\"$\",\"meta\",\"8\",{\"property\":\"og:image:type\",\"content\":\"image/png\"}],[\"$\",\"meta\",\"9\",{\"property\":\"og:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"10\",{\"property\":\"og:image:height\",\"content\":\"630\"}],[\"$\",\"meta\",\"11\",{\"property\":\"og:image:alt\",\"content\":\"iii worker\"}],[\"$\",\"meta\",\"12\",{\"name\":\"twitter:card\",\"content\":\"summary_large_image\"}],[\"$\",\"meta\",\"13\",{\"name\":\"twitter:title\",\"content\":\"iii-directory - iii worker\"}],[\"$\",\"meta\",\"14\",{\"name\":\"twitter:description\",\"content\":\"Engine introspection, workers registry proxy, filesystem-backed skills, system prompts, and agent profiles, plus lexical function search with a conditional pre-generate hint.\"}],[\"$\",\"meta\",\"15\",{\"name\":\"twitter:image\",\"content\":\"https://workers.iii.dev/workers/iii-directory/opengraph-image?bced171a25d0f70f\"}],[\"$\",\"meta\",\"16\",{\"name\":\"twitter:image:alt\",\"content\":\"iii worker\"}],[\"$\",\"meta\",\"17\",{\"name\":\"twitter:image:type\",\"content\":\"image/png\"}],[\"$\",\"meta\",\"18\",{\"name\":\"twitter:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"19\",{\"name\":\"twitter:image:height\",\"content\":\"630\"}],[\"$\",\"link\",\"20\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0n6vou73am7b3.ico\",\"sizes\":\"48x48\",\"type\":\"image/x-icon\"}],[\"$\",\"$L1b\",\"21\",{}]]\n"])</script><script>self.__next_f.push([1,"1c:I[15957,[\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0.o_9ma339h6h.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\"],\"InstallCommand\"]\n:HL[\"https://iii.dev/docs/_mintlify/favicons/motiadev/AFkVbz_UcSL_5jsm/_generated/favicon/apple-touch-icon.png\",\"image\"]\n"])</script><script>self.__next_f.push([1,"12:[\"$\",\"div\",null,{\"className\":\"page-transition\",\"children\":[[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"SoftwareApplication\\\",\\\"name\\\":\\\"iii-directory\\\",\\\"description\\\":\\\"Engine introspection, workers registry proxy, filesystem-backed skills, system prompts, and agent profiles, plus lexical function search with a conditional pre-generate hint.\\\",\\\"applicationCategory\\\":\\\"DeveloperApplication\\\",\\\"softwareVersion\\\":\\\"1.2.8\\\",\\\"url\\\":\\\"https://workers.iii.dev/workers/iii-directory\\\",\\\"license\\\":\\\"Apache-2.0\\\",\\\"codeRepository\\\":\\\"https://github.com/iii-hq/workers\\\",\\\"author\\\":{\\\"@type\\\":\\\"Person\\\",\\\"name\\\":\\\"iii\\\"}}\"}}],[\"$\",\"div\",null,{\"className\":\"flex items-end justify-between flex-wrap gap-x-6 gap-y-4 px-9 py-12\",\"children\":[[\"$\",\"div\",null,{\"className\":\"min-w-0\",\"children\":[[\"$\",\"div\",null,{\"className\":\"font-mono text-[11px] uppercase tracking-[0.06em] text-ink-faint mb-3\",\"children\":[\"$\",\"span\",null,{\"className\":\"font-mono text-accent\",\"children\":[\"$$\",[\"$\",\"span\",null,{\"className\":\"text-ink ml-2\",\"children\":\"worker\"}]]}]}],[\"$\",\"div\",null,{\"className\":\"flex items-baseline flex-wrap gap-x-3 gap-y-1\",\"children\":[[\"$\",\"h1\",null,{\"className\":\"font-mono text-[28px] font-medium tracking-[-0.01em] text-ink lowercase\",\"children\":\"iii-directory\"}],[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] uppercase tracking-[0.06em] text-ink-ghost tabular-nums\",\"children\":\"v1.2.8\"}]]}],[\"$\",\"p\",null,{\"className\":\"mt-3 font-mono text-[14px] leading-[1.7] text-ink-faint max-w-[60ch] lowercase\",\"children\":\"Engine introspection, workers registry proxy, filesystem-backed skills, system prompts, and agent profiles, plus lexical function search with a conditional pre-generate hint.\"}]]}],null]}],[\"$\",\"div\",null,{\"className\":\"px-9 pb-8 flex flex-col gap-y-6\",\"children\":[null,null,[\"$\",\"div\",null,{\"className\":\"flex flex-col gap-y-5 border border-rule bg-bg p-5 @2xl:p-6\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex flex-wrap items-center gap-x-4 gap-y-2\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex items-center gap-x-2 font-mono text-[13px]\",\"children\":[[\"$\",\"img\",null,{\"src\":\"https://iii.dev/docs/_mintlify/favicons/motiadev/AFkVbz_UcSL_5jsm/_generated/favicon/apple-touch-icon.png\",\"alt\":\"\",\"className\":\"size-5 object-cover\"}],[\"$\",\"span\",null,{\"className\":\"text-ink lowercase\",\"children\":\"iii\"}],[\"$\",\"span\",null,{\"className\":\"inline-flex items-center gap-x-1 text-ink-faint\",\"children\":[[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":[[\"path\",{\"d\":\"M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z\",\"key\":\"3c2336\"}],[\"path\",{\"d\":\"m9 12 2 2 4-4\",\"key\":\"dzmm74\"}]],\"className\":\"lucide-badge-check size-3.5 text-accent\",\"aria-hidden\":true}],[\"$\",\"span\",null,{\"className\":\"text-[11px] uppercase tracking-[0.06em]\",\"children\":\"verified\"}]]}]]}],[\"$\",\"span\",null,{\"className\":\"flex flex-wrap items-center gap-x-3 gap-y-1 font-mono text-[12px] text-ink-ghost tabular-nums\",\"children\":[[\"$\",\"span\",null,{\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink\",\"children\":\"2,734\"}],\" installs\"]}],[[\"$\",\"span\",null,{\"aria-hidden\":true,\"className\":\"text-rule\",\"children\":\"/\"}],[\"$\",\"span\",null,{\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink\",\"children\":\"88\"}],\" in 7d\"]}]],[[\"$\",\"span\",null,{\"aria-hidden\":true,\"className\":\"text-rule\",\"children\":\"/\"}],[\"$\",\"span\",null,{\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink\",\"children\":\"2\"}],\" \",\"today\"]}]]]}]]}],[\"$\",\"$L1c\",null,{\"workerName\":\"iii-directory\",\"version\":\"latest\"}],[\"$\",\"div\",null,{\"className\":\"flex flex-col gap-y-3\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex flex-wrap items-center gap-2 font-mono text-[12px] lowercase\",\"children\":[[\"$\",\"span\",null,{\"className\":\"border border-rule px-2 py-1 text-ink\",\"children\":\"binary\"}],[\"$\",\"span\",null,{\"className\":\"border border-rule px-2 py-1 text-ink normal-case\",\"children\":[\"license: \",\"Apache-2.0\"]}],[[\"$\",\"$L7\",\"agents\",{\"href\":\"/search?tag=agents\",\"className\":\"border border-rule-2 px-2 py-1 text-ink-faint hover:text-ink hover:border-rule transition-colors\",\"children\":\"agents\"}],\"$L1d\",\"$L1e\",\"$L1f\",\"$L20\",\"$L21\",\"$L22\"]]}],\"$L23\",\"$L24\"]}],\"$L25\"]}],false]}],\"$L26\"]}]\n"])</script><script>self.__next_f.push([1,"27:I[33516,[\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0.o_9ma339h6h.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\"],\"Image\"]\n28:I[84938,[\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0.o_9ma339h6h.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\"],\"PageTabs\"]\n2a:I[42794,[\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\",\"/_next/static/chunks/0.o_9ma339h6h.js?dpl=dpl_HM7qx6VtUneCGiqbgwEzNxETS4Rj\"],\"SummaryList\"]\n1d:[\"$\",\"$L7\",\"directory\",{\"href\":\"/search?tag=directory\",\"className\":\"border border-rule-2 px-2 py-1 text-ink-faint hover:text-ink hover:border-rule transition-colors\",\"children\":\"directory\"}]\n1e:[\"$\",\"$L7\",\"functions\",{\"href\":\"/search?tag=functions\",\"className\":\"border border-rule-2 px-2 py-1 text-ink-faint hover:text-ink hover:border-rule transition-colors\",\"children\":\"functions\"}]\n1f:[\"$\",\"$L7\",\"introspect\",{\"href\":\"/search?tag=introspect\",\"className\":\"border border-rule-2 px-2 py-1 text-ink-faint hover:text-ink hover:border-rule transition-colors\",\"children\":\"introspect\"}]\n20:[\"$\",\"$L7\",\"registry\",{\"href\":\"/search?tag=registry\",\"className\":\"border border-rule-2 px-2 py-1 text-ink-faint hover:text-ink hover:border-rule transition-colors\",\"children\":\"registry\"}]\n21:[\"$\",\"$L7\",\"search\",{\"href\":\"/search?tag=search\",\"className\":\"border border-rule-2 px-2 py-1 text-ink-faint hover:text-ink hover:border-rule transition-colors\",\"children\":\"search\"}]\n22:[\"$\",\"$L7\",\"skills\",{\"href\":\"/search?tag=skills\",\"className\":\"border border-rule-2 px-2 py-1 text-ink-faint hover:text-ink hover:border-rule transition-colors\",\"children\":\"skills\"}]\n"])</script><script>self.__next_f.push([1,"23:[\"$\",\"ul\",null,{\"aria-label\":\"Supported platforms\",\"className\":\"flex flex-wrap items-center font-mono text-[12px] gap-x-2 gap-y-1.5 \",\"children\":[[\"$\",\"li\",\"apple\",{\"title\":\"macOS: arm64, x64\",\"className\":\"inline-flex items-center border border-rule bg-bg gap-x-2 px-2 py-1\",\"children\":[[\"$\",\"$L27\",null,{\"src\":\"/icons/apple_dark.svg\",\"alt\":\"\",\"aria-hidden\":true,\"width\":209,\"height\":256,\"className\":\"shrink-0 [filter:brightness(0)] dark:[filter:brightness(0)_invert(1)] h-4 w-auto\"}],[\"$\",\"span\",null,{\"className\":\"sr-only\",\"children\":[\"macOS\",\": \"]}],[\"$\",\"span\",null,{\"className\":\"text-ink tabular-nums\",\"children\":\"arm64 · x64\"}]]}],[\"$\",\"li\",\"linux\",{\"title\":\"Linux: arm64, armv7, x64\",\"className\":\"inline-flex items-center border border-rule bg-bg gap-x-2 px-2 py-1\",\"children\":[[\"$\",\"$L27\",null,{\"src\":\"/icons/linux.svg\",\"alt\":\"\",\"aria-hidden\":true,\"width\":256,\"height\":295,\"className\":\"shrink-0 [filter:brightness(0)] dark:[filter:brightness(0)_invert(1)] h-4 w-auto\"}],[\"$\",\"span\",null,{\"className\":\"sr-only\",\"children\":[\"Linux\",\": \"]}],[\"$\",\"span\",null,{\"className\":\"text-ink tabular-nums\",\"children\":\"arm64 · armv7 · x64\"}]]}],[\"$\",\"li\",\"windows\",{\"title\":\"Windows: arm64, x64, x86\",\"className\":\"inline-flex items-center border border-rule bg-bg gap-x-2 px-2 py-1\",\"children\":[[\"$\",\"$L27\",null,{\"src\":\"/icons/windows.svg\",\"alt\":\"\",\"aria-hidden\":true,\"width\":88,\"height\":88,\"className\":\"shrink-0 [filter:brightness(0)] dark:[filter:brightness(0)_invert(1)] h-4 w-auto\"}],[\"$\",\"span\",null,{\"className\":\"sr-only\",\"children\":[\"Windows\",\": \"]}],[\"$\",\"span\",null,{\"className\":\"text-ink tabular-nums\",\"children\":\"arm64 · x64 · x86\"}]]}]]}]\n"])</script><script>self.__next_f.push([1,"24:[\"$\",\"div\",null,{\"className\":\"flex flex-wrap gap-x-4 gap-y-2 font-mono text-[12px]\",\"children\":[[\"$\",\"$L7\",null,{\"href\":\"/workers/iii-directory?tab=api\",\"className\":\"inline-flex items-baseline gap-x-1.5 text-ink-faint hover:text-ink transition-colors\",\"children\":[[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"children\":\"29\"}],[\"$\",\"span\",null,{\"className\":\"uppercase tracking-[0.06em] text-[11px]\",\"children\":\"functions\"}]]}],[\"$\",\"$L7\",null,{\"href\":\"/workers/iii-directory?tab=api\",\"className\":\"inline-flex items-baseline gap-x-1.5 text-ink-faint hover:text-ink transition-colors\",\"children\":[[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"children\":\"3\"}],[\"$\",\"span\",null,{\"className\":\"uppercase tracking-[0.06em] text-[11px]\",\"children\":\"triggers\"}]]}],[\"$\",\"$L7\",null,{\"href\":\"/workers/iii-directory?tab=skills\",\"className\":\"inline-flex items-baseline gap-x-1.5 text-ink-faint hover:text-ink transition-colors\",\"children\":[[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"children\":\"0\"}],[\"$\",\"span\",null,{\"className\":\"uppercase tracking-[0.06em] text-[11px]\",\"children\":\"skills\"}]]}],[\"$\",\"$L7\",null,{\"href\":\"/workers/iii-directory?tab=deps\",\"className\":\"inline-flex items-baseline gap-x-1.5 text-ink-faint hover:text-ink transition-colors\",\"children\":[[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"children\":\"1\"}],[\"$\",\"span\",null,{\"className\":\"uppercase tracking-[0.06em] text-[11px]\",\"children\":\"deps\"}]]}],[\"$\",\"$L7\",null,{\"href\":\"/workers/iii-directory?tab=versions\",\"className\":\"inline-flex items-baseline gap-x-1.5 text-ink-faint hover:text-ink transition-colors\",\"children\":[[\"$\",\"span\",null,{\"className\":\"tabular-nums text-ink\",\"children\":\"v1.2.8\"}],[\"$\",\"span\",null,{\"className\":\"uppercase tracking-[0.06em] text-[11px]\",\"children\":\"version\"}]]}]]}]\n"])</script><script>self.__next_f.push([1,"25:[\"$\",\"div\",null,{\"className\":\"flex flex-col @2xl:flex-row @2xl:items-center gap-3 border-t border-rule-2 pt-4\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex items-center gap-x-2 min-w-0 font-mono text-[13px]\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-[11px] uppercase tracking-[0.06em] text-ink-faint shrink-0\",\"children\":\"repo\"}],[\"$\",\"a\",null,{\"href\":\"https://github.com/iii-hq/workers\",\"target\":\"_blank\",\"rel\":\"noreferrer\",\"className\":\"inline-flex items-center gap-x-1 font-mono text-[13px] text-ink lowercase hover:text-accent transition-colors min-w-0\",\"children\":[[\"$\",\"span\",null,{\"className\":\"truncate\",\"children\":\"iii-hq/workers\"}],[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":\"$8:props:children:props:children:1:props:children:0:props:children:1:props:iconNode\",\"className\":\"lucide-external-link size-3 shrink-0\",\"aria-hidden\":true}]]}]]}],[\"$\",\"p\",null,{\"className\":\"font-mono text-[12px] leading-[1.5] text-ink-faint @2xl:ml-auto @2xl:max-w-[42ch] @2xl:text-right\",\"children\":\"exact versions are immutable; binary and bundle artifacts are digest-pinned.\"}]]}]\n"])</script><script>self.__next_f.push([1,"26:[\"$\",\"div\",null,{\"className\":\"px-9 pb-12 flex flex-col gap-y-6\",\"children\":[\"$\",\"div\",null,{\"className\":\"grid grid-cols-1 @4xl:grid-cols-[1fr_280px] gap-x-8 gap-y-8\",\"children\":[[\"$\",\"div\",null,{\"className\":\"min-w-0 flex flex-col gap-y-6\",\"children\":[[\"$\",\"$L28\",null,{\"slug\":\"iii-directory\",\"activeTab\":\"readme\",\"version\":\"latest\"}],[false,[\"$\",\"section\",null,{\"children\":[[\"$\",\"div\",null,{\"className\":\"flex items-center justify-between mb-3\",\"children\":[[\"$\",\"h2\",null,{\"className\":\"font-mono text-[12px] font-medium uppercase tracking-[0.18em] text-ink-faint\",\"children\":\"readme\"}],[\"$\",\"a\",null,{\"href\":\"https://api.workers.iii.dev/w/iii-directory/readme\",\"target\":\"_blank\",\"rel\":\"noreferrer\",\"className\":\"inline-flex items-center gap-x-1.5 font-mono text-[11px] uppercase tracking-[0.06em] text-ink-faint hover:text-accent transition-colors\",\"children\":[[\"$\",\"span\",null,{\"children\":\"open as markdown\"}],[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":\"$8:props:children:props:children:1:props:children:0:props:children:1:props:iconNode\",\"className\":\"lucide-external-link w-3 h-3\",\"aria-hidden\":true}]]}]]}],\"$L29\"]}]],false,false,false,false,false,false]}],[\"$\",\"aside\",null,{\"className\":\"flex flex-col gap-y-4 @4xl:sticky @4xl:top-4 @4xl:self-start @4xl:max-h-[calc(100dvh-2rem)] @4xl:overflow-y-auto\",\"children\":[[\"$\",\"div\",null,{\"className\":\"border border-rule bg-bg\",\"children\":[[\"$\",\"div\",null,{\"className\":\"bg-panel px-3.5 py-2.5 border-b border-rule\",\"children\":[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint\",\"children\":\"details\"}]}],[\"$\",\"div\",null,{\"className\":\"p-4 flex flex-col gap-y-2.5\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex items-baseline justify-between font-mono text-[13px] gap-x-3\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]\",\"children\":\"version\"}],[\"$\",\"span\",null,{\"className\":\"text-ink truncate text-right lowercase tabular-nums\",\"children\":\"v1.2.8\"}]]}],[\"$\",\"div\",null,{\"className\":\"flex items-baseline justify-between font-mono text-[13px] gap-x-3\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]\",\"children\":\"type\"}],[\"$\",\"span\",null,{\"className\":\"text-ink truncate text-right lowercase \",\"children\":\"binary\"}]]}],[\"$\",\"div\",null,{\"className\":\"flex items-baseline justify-between font-mono text-[13px] gap-x-3\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]\",\"children\":\"license\"}],[\"$\",\"span\",null,{\"className\":\"text-ink truncate text-right \",\"children\":\"Apache-2.0\"}]]}],[\"$\",\"div\",null,{\"className\":\"flex items-baseline justify-between font-mono text-[13px] gap-x-3 min-w-0\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink-faint shrink-0 uppercase tracking-[0.06em] text-[11px]\",\"children\":\"repo\"}],[\"$\",\"a\",null,{\"href\":\"https://github.com/iii-hq/workers\",\"target\":\"_blank\",\"rel\":\"noreferrer\",\"className\":\"inline-flex items-center gap-x-1 font-mono text-[13px] text-ink lowercase hover:text-accent transition-colors min-w-0 text-right justify-end\",\"children\":[[\"$\",\"span\",null,{\"className\":\"truncate\",\"children\":\"iii-hq/workers\"}],[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":\"$8:props:children:props:children:1:props:children:0:props:children:1:props:iconNode\",\"className\":\"lucide-external-link size-3 shrink-0\",\"aria-hidden\":true}]]}]]}],\"$undefined\"]}]]}],[\"$\",\"div\",null,{\"className\":\"border border-rule bg-bg\",\"children\":[[\"$\",\"div\",null,{\"className\":\"bg-panel px-3.5 py-2.5 border-b border-rule\",\"children\":[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint\",\"children\":\"api\"}]}],[\"$\",\"$L2a\",null,{\"slug\":\"iii-directory\",\"version\":\"latest\",\"functions\":[{\"name\":\"directory::__on_worker_added\",\"anchor\":\"fn-directory::__on_worker_added\"},{\"name\":\"directory::agents::create\",\"anchor\":\"fn-directory::agents::create\"},{\"name\":\"directory::agents::delete\",\"anchor\":\"fn-directory::agents::delete\"},{\"name\":\"directory::agents::get\",\"anchor\":\"fn-directory::agents::get\"},{\"name\":\"directory::agents::list\",\"anchor\":\"fn-directory::agents::list\"},{\"name\":\"directory::agents::update\",\"anchor\":\"fn-directory::agents::update\"},{\"name\":\"directory::engine::functions::info\",\"anchor\":\"fn-directory::engine::functions::info\"},{\"name\":\"directory::hint-preview\",\"anchor\":\"fn-directory::hint-preview\"},{\"name\":\"directory::on-config-change\",\"anchor\":\"fn-directory::on-config-change\"},{\"name\":\"directory::on-functions-change\",\"anchor\":\"fn-directory::on-functions-change\"},{\"name\":\"directory::pre-generate\",\"anchor\":\"fn-directory::pre-generate\"},{\"name\":\"directory::registry::workers::info\",\"anchor\":\"fn-directory::registry::workers::info\"},{\"name\":\"directory::registry::workers::list\",\"anchor\":\"fn-directory::registry::workers::list\"},{\"name\":\"directory::search_functions\",\"anchor\":\"fn-directory::search_functions\"},{\"name\":\"directory::skills::create\",\"anchor\":\"fn-directory::skills::create\"},{\"name\":\"directory::skills::delete\",\"anchor\":\"fn-directory::skills::delete\"},{\"name\":\"directory::skills::download\",\"anchor\":\"fn-directory::skills::download\"},{\"name\":\"directory::skills::download_from_registry\",\"anchor\":\"fn-directory::skills::download_from_registry\"},{\"name\":\"directory::skills::download_from_repo\",\"anchor\":\"fn-directory::skills::download_from_repo\"},{\"name\":\"directory::skills::get\",\"anchor\":\"fn-directory::skills::get\"},{\"name\":\"directory::skills::index\",\"anchor\":\"fn-directory::skills::index\"},{\"name\":\"directory::skills::list\",\"anchor\":\"fn-directory::skills::list\"},{\"name\":\"directory::skills::update\",\"anchor\":\"fn-directory::skills::update\"},{\"name\":\"directory::system-prompts::create\",\"anchor\":\"fn-directory::system-prompts::create\"},{\"name\":\"directory::system-prompts::delete\",\"anchor\":\"fn-directory::system-prompts::delete\"},{\"name\":\"directory::system-prompts::get\",\"anchor\":\"fn-directory::system-prompts::get\"},{\"name\":\"directory::system-prompts::list\",\"anchor\":\"fn-directory::system-prompts::list\"},{\"name\":\"directory::system-prompts::update\",\"anchor\":\"fn-directory::system-prompts::update\"},{\"name\":\"iii-directory::ui-content\",\"anchor\":\"fn-iii-directory::ui-content\"}],\"triggers\":[{\"name\":\"directory::agents::on-change\",\"anchor\":\"trigger-directory::agents::on-change\"},{\"name\":\"directory::skills::on-change\",\"anchor\":\"trigger-directory::skills::on-change\"},{\"name\":\"directory::system-prompts::on-change\",\"anchor\":\"trigger-directory::system-prompts::on-change\"}]}]]}],\"$L2b\"]}]]}]}]\n"])</script><script>self.__next_f.push([1,"2b:[\"$\",\"div\",null,{\"className\":\"border border-rule bg-bg\",\"children\":[[\"$\",\"div\",null,{\"className\":\"bg-panel px-3.5 py-2.5 border-b border-rule\",\"children\":[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint\",\"children\":\"author\"}]}],[\"$\",\"div\",null,{\"className\":\"p-4 flex flex-col gap-y-2.5\",\"children\":[\"$\",\"div\",null,{\"className\":\"flex items-center gap-x-2 font-mono text-[13px]\",\"children\":[[\"$\",\"img\",null,{\"src\":\"https://iii.dev/docs/_mintlify/favicons/motiadev/AFkVbz_UcSL_5jsm/_generated/favicon/apple-touch-icon.png\",\"alt\":\"\",\"className\":\"size-5 object-cover\"}],[\"$\",\"span\",null,{\"className\":\"text-ink lowercase\",\"children\":\"iii\"}],[\"$\",\"$L11\",null,{\"ref\":\"$undefined\",\"iconNode\":\"$12:props:children:2:props:children:2:props:children:0:props:children:0:props:children:2:props:children:0:props:iconNode\",\"className\":\"lucide-badge-check size-3.5 text-accent\"}]]}]}]]}]\n2c:T10b40,"])</script><script>self.__next_f.push([1,"\u003ch1 id=\"iii-directory\" class=\"scroll-mt-20\"\u003eiii-directory\u003c/h1\u003e\n\u003cp\u003eWorkers registry HTTP proxy and filesystem-backed skills, system prompts,\nand agent profiles for the \u003ca href=\"https://github.com/iii-hq/iii\"\u003eiii engine\u003c/a\u003e. Every\npublic function sits under a single \u003ccode class=\"readme-inline-code\"\u003edirectory::*\u003c/code\u003e namespace, split\ninto five surfaces (all MCP-agnostic):\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eSurface\u003c/th\u003e\n\u003cth\u003eWhat clients see\u003c/th\u003e\n\u003cth\u003eWhen to use it\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSkills\u003c/strong\u003e (\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::*\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003eEnriched listing via \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::list\u003c/code\u003e (\u003ccode class=\"readme-inline-code\"\u003e{ id, title, type, function_id, disable_model_invocation, description, bytes, modified_at }\u003c/code\u003e per row), a single-skill reader \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::get { id }\u003c/code\u003e returning \u003ccode class=\"readme-inline-code\"\u003e{ id, title, type, function_id, disable_model_invocation, path, body, modified_at }\u003c/code\u003e (the full body instead of the list teaser), and \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::index\u003c/code\u003e which renders a short per-worker overview document (one \u003ccode class=\"readme-inline-code\"\u003e## \u003ctitle\u003e\u003c/code\u003e + first paragraph + \u003ccode class=\"readme-inline-code\"\u003eread more\u003c/code\u003e link per \u003ccode class=\"readme-inline-code\"\u003etype: index\u003c/code\u003e skill). Authored by \u003ccode class=\"readme-inline-code\"\u003ecreate\u003c/code\u003e, edited by \u003ccode class=\"readme-inline-code\"\u003eupdate\u003c/code\u003e, removed by \u003ccode class=\"readme-inline-code\"\u003edelete\u003c/code\u003e. \u003ccode class=\"readme-inline-code\"\u003etitle\u003c/code\u003e prefers the YAML frontmatter \u003ccode class=\"readme-inline-code\"\u003etitle:\u003c/code\u003e (then \u003ccode class=\"readme-inline-code\"\u003ename:\u003c/code\u003e) over the body H1; \u003ccode class=\"readme-inline-code\"\u003etype\u003c/code\u003e is lifted from frontmatter \u003ccode class=\"readme-inline-code\"\u003etype:\u003c/code\u003e (e.g. \u003ccode class=\"readme-inline-code\"\u003eindex\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003ehow-to\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003ereference\u003c/code\u003e) and serialised as \u003ccode class=\"readme-inline-code\"\u003enull\u003c/code\u003e when absent. System-installed agent skills under the read-only \u003ccode class=\"readme-inline-code\"\u003eagents_skills_folder\u003c/code\u003e are served too (see \u003ca href=\"#on-disk-layout\"\u003eOn-disk layout\u003c/a\u003e).\u003c/td\u003e\n\u003ctd\u003eOrientation: \u0026quot;when and why to use my worker\u0026#39;s tools\u0026quot;\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSystem prompts\u003c/strong\u003e (\u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::*\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003eIdentity prompts listed by \u003ccode class=\"readme-inline-code\"\u003elist\u003c/code\u003e, read by \u003ccode class=\"readme-inline-code\"\u003eget\u003c/code\u003e, authored by \u003ccode class=\"readme-inline-code\"\u003ecreate\u003c/code\u003e, edited by \u003ccode class=\"readme-inline-code\"\u003eupdate\u003c/code\u003e, and removed by \u003ccode class=\"readme-inline-code\"\u003edelete\u003c/code\u003e. The list response keeps its \u003ccode class=\"readme-inline-code\"\u003eprompts\u003c/code\u003e field name. Stored under any \u003ccode class=\"readme-inline-code\"\u003esystem-prompts/\u003c/code\u003e path segment; \u003ccode class=\"readme-inline-code\"\u003ecreate\u003c/code\u003e writes \u003ccode class=\"readme-inline-code\"\u003e\u003cskills_folder\u003e/system-prompts/\u003cname\u003e.md\u003c/code\u003e.\u003c/td\u003e\n\u003ctd\u003eWhat the chat\u0026#39;s system-prompt picker offers as an identity prompt (enrich or replace)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eAgent Profiles\u003c/strong\u003e (\u003ccode class=\"readme-inline-code\"\u003edirectory::agents::*\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003eReusable session identities whose file body is the system prompt, with display \u003ccode class=\"readme-inline-code\"\u003ename\u003c/code\u003e, emoji \u003ccode class=\"readme-inline-code\"\u003elogo\u003c/code\u003e, a \u003ccode class=\"readme-inline-code\"\u003eskills\u003c/code\u003e filter, and optional \u003ccode class=\"readme-inline-code\"\u003emodel\u003c/code\u003e + \u003ccode class=\"readme-inline-code\"\u003ereasoning_effort\u003c/code\u003e in required frontmatter. \u003ccode class=\"readme-inline-code\"\u003elist\u003c/code\u003e rows carry the display/configuration metadata and \u003ccode class=\"readme-inline-code\"\u003eget\u003c/code\u003e adds \u003ccode class=\"readme-inline-code\"\u003esystem_prompt\u003c/code\u003e and \u003ccode class=\"readme-inline-code\"\u003eunknown_skills\u003c/code\u003e. Stored as direct \u003ccode class=\"readme-inline-code\"\u003e\u003cagents_folder\u003e/\u003cid\u003e.md\u003c/code\u003e files. See \u003ca href=\"../docs/architecture/agent-profile-storage.md\"\u003eAgent profile storage\u003c/a\u003e.\u003c/td\u003e\n\u003ctd\u003eA named identity selected with \u003ccode class=\"readme-inline-code\"\u003eharness::send { options: { agent } }\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eSearch\u003c/strong\u003e (\u003ccode class=\"readme-inline-code\"\u003edirectory::search_functions\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003eOne to six external capabilities → compact function-id candidates (installed, plus registry workers under \u003ccode class=\"readme-inline-code\"\u003einstallable\u003c/code\u003e), with a conditional pre-generate hint pointing agents at it.\u003c/td\u003e\n\u003ctd\u003e\u0026quot;Which functions do I call for this task?\u0026quot;\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eRegistry\u003c/strong\u003e (\u003ccode class=\"readme-inline-code\"\u003edirectory::registry::*\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003eHTTP proxy over \u003ccode class=\"readme-inline-code\"\u003eapi.workers.iii.dev\u003c/code\u003e with \u003ccode class=\"readme-inline-code\"\u003eworkers::{list,info}\u003c/code\u003e. Rows share the core \u003ccode class=\"readme-inline-code\"\u003ename\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003edescription\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003eversion\u003c/code\u003e fields with the engine\u0026#39;s \u003ccode class=\"readme-inline-code\"\u003eengine::workers::list\u003c/code\u003e and add publication metadata (\u003ccode class=\"readme-inline-code\"\u003etype\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003econfig\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003esupported_targets\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003etotal_downloads\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003edependencies\u003c/code\u003e, optional \u003ccode class=\"readme-inline-code\"\u003eimage\u003c/code\u003e). \u003ccode class=\"readme-inline-code\"\u003eworkers::list\u003c/code\u003e is cursor-paginated with a server-authored page size.\u003c/td\u003e\n\u003ctd\u003e\u0026quot;What\u0026#39;s published in the public registry?\u0026quot;\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003eEngine introspection (functions / triggers / registered triggers /\nworkers) is served by the engine natively at\n\u003ccode class=\"readme-inline-code\"\u003eengine::functions::*\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003eengine::triggers::*\u003c/code\u003e,\n\u003ccode class=\"readme-inline-code\"\u003eengine::registered-triggers::*\u003c/code\u003e, and \u003ccode class=\"readme-inline-code\"\u003eengine::workers::*\u003c/code\u003e. Call the\nengine ids directly. One wrapper survives for callers that can only\nreach the \u003ccode class=\"readme-inline-code\"\u003edirectory::\u003c/code\u003e namespace: \u003ccode class=\"readme-inline-code\"\u003edirectory::engine::functions::info\u003c/code\u003e\nproxies a single function\u0026#39;s schema (see its row below).\u003c/p\u003e\n\u003cp\u003eThis worker is where an agent\u0026#39;s identity text LIVES. \u003ccode class=\"readme-inline-code\"\u003eskills/system-prompts/iii-runtime.md\u003c/code\u003e\nships here and is the one copy of \u0026quot;how to work against a live iii engine\u0026quot; —\n\u003ccode class=\"readme-inline-code\"\u003eclaude-code\u003c/code\u003e and \u003ccode class=\"readme-inline-code\"\u003epi\u003c/code\u003e fetch it with \u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::get name=iii-runtime\u003c/code\u003e (plus \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::index\u003c/code\u003e) for both their headless\nturns and their console terminals, rather than compiling a prompt of their own.\nEdit that file and every agent reads the edit; no worker release involved.\u003c/p\u003e\n\u003cp\u003eSkills and system prompts are sourced from \u003ccode class=\"readme-inline-code\"\u003eskills_folder\u003c/code\u003e; agent profiles\nuse the dedicated \u003ccode class=\"readme-inline-code\"\u003eagents_folder\u003c/code\u003e. Writes are the\n\u003cstrong\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::download*\u003c/code\u003e\u003c/strong\u003e functions, which pull markdown from either\nthe \u003ca href=\"https://workers.iii.dev\"\u003eworkers registry\u003c/a\u003e or a GitHub repo and route each\nsupported family to its configured root, plus the\nper-kind single-file editors — \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::{create,update,delete}\u003c/code\u003e,\n\u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::{create,update,delete}\u003c/code\u003e and\n\u003ccode class=\"readme-inline-code\"\u003edirectory::agents::{create,update,delete}\u003c/code\u003e. Once downloaded, files\nbelong to the developer — edit them however you want, in the editor of\nyour choice: a change made directly on disk fires the matching\n\u003ccode class=\"readme-inline-code\"\u003eon-change\u003c/code\u003e with \u003ccode class=\"readme-inline-code\"\u003eop: \"external\"\u003c/code\u003e (see \u003ca href=\"#custom-trigger-types\"\u003eCustom trigger\ntypes\u003c/a\u003e).\u003c/p\u003e\n\u003cp\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::registry::workers::*\u003c/code\u003e and the engine\u0026#39;s \u003ccode class=\"readme-inline-code\"\u003eengine::workers::*\u003c/code\u003e\nshare the core \u003ccode class=\"readme-inline-code\"\u003ename\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003edescription\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003eversion\u003c/code\u003e fields so a parser\nthat touches only those keys works against either surface; the\nregistry view also surfaces publication metadata (\u003ccode class=\"readme-inline-code\"\u003etype\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003econfig\u003c/code\u003e,\n\u003ccode class=\"readme-inline-code\"\u003esupported_targets\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003etotal_downloads\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003edependencies\u003c/code\u003e, optional\n\u003ccode class=\"readme-inline-code\"\u003eimage\u003c/code\u003e) and the engine view adds runtime / connection state.\u003c/p\u003e\n\u003ch2 id=\"table-of-contents\" class=\"scroll-mt-20\"\u003eTable of contents\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#install\"\u003eInstall\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#configuration\"\u003eConfiguration\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#quickstart-download-some-skills\"\u003eQuickstart: download some skills\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#on-disk-layout\"\u003eOn-disk layout\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#skill-ids\"\u003eSkill ids\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#functions\"\u003eFunctions\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#function-search--pre-generate-hint\"\u003eFunction search \u0026amp; pre-generate hint\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#custom-trigger-types\"\u003eCustom trigger types\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#local-development--testing\"\u003eLocal development \u0026amp; testing\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#migration-from-skills-v02x\"\u003eMigration from skills v0.2.x\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003chr\u003e\n\u003ch2 id=\"install\" class=\"scroll-mt-20\"\u003eInstall\u003c/h2\u003e\n\u003cpre class=\"shiki vitesse-light\" style=\"background-color:#ffffff;color:#393a34\" tabindex=\"0\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#59873A\"\u003eiii\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e trigger\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e compose::add\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e worker=iii-directory\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e\u003ccode class=\"readme-inline-code\"\u003eiii trigger compose::add\u003c/code\u003e resolves the worker and its dependencies, writes\nexact declarations to \u003ccode class=\"readme-inline-code\"\u003eworker-compose.yaml\u003c/code\u003e, and reconciles the Compose project.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"skills\" class=\"scroll-mt-20\"\u003eSkills\u003c/h2\u003e\n\u003cp\u003eInstall the \u003ccode class=\"readme-inline-code\"\u003eiii-directory\u003c/code\u003e agent skill for Claude Code, Cursor, and 30+ other agents:\u003c/p\u003e\n\u003cpre class=\"shiki vitesse-light\" style=\"background-color:#ffffff;color:#393a34\" tabindex=\"0\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#59873A\"\u003enpx\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e skills\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e add\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e iii-hq/workers\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e --skill\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e iii-directory\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eBrowse or install every worker skill at once:\u003c/p\u003e\n\u003cpre class=\"shiki vitesse-light\" style=\"background-color:#ffffff;color:#393a34\" tabindex=\"0\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#59873A\"\u003enpx\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e skills\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e add\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e iii-hq/workers\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e --list\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#59873A\"\u003enpx\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e skills\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e add\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e iii-hq/workers\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e --all\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003chr\u003e\n\u003ch2 id=\"configuration\" class=\"scroll-mt-20\"\u003eConfiguration\u003c/h2\u003e\n\u003cp\u003eRuntime settings live in the \u003cstrong\u003e\u003ccode class=\"readme-inline-code\"\u003econfiguration\u003c/code\u003e worker\u003c/strong\u003e under id\n\u003cstrong\u003e\u003ccode class=\"readme-inline-code\"\u003eiii-directory\u003c/code\u003e\u003c/strong\u003e (the same pattern \u003ccode class=\"readme-inline-code\"\u003edatabase\u003c/code\u003e and \u003ccode class=\"readme-inline-code\"\u003estorage\u003c/code\u003e use). At boot\nthe worker registers its JSON Schema, reads the live value via\n\u003ccode class=\"readme-inline-code\"\u003econfiguration::get\u003c/code\u003e (the configuration worker env-expands \u003ccode class=\"readme-inline-code\"\u003e${VAR}\u003c/code\u003e), and binds\na \u003ccode class=\"readme-inline-code\"\u003econfiguration\u003c/code\u003e trigger so it re-fetches on change.\u003c/p\u003e\n\u003cp\u003ePersisted values default to \u003ccode class=\"readme-inline-code\"\u003e./data/configuration/iii-directory.yaml\u003c/code\u003e (fs\nadapter). Edit that file directly, call \u003ccode class=\"readme-inline-code\"\u003econfiguration::set id=iii-directory\u003c/code\u003e,\nor use the Console\u0026#39;s global Settings modal — all three propagate without a redeploy.\u003c/p\u003e\n\u003ch3 id=\"fields\" class=\"scroll-mt-20\"\u003eFields\u003c/h3\u003e\n\u003cpre class=\"shiki vitesse-light\" style=\"background-color:#ffffff;color:#393a34\" tabindex=\"0\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# TOPOLOGY — changing any of these requires a worker restart.\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003eskills_folder\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e skills\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # under III_COMPOSE_DIR, or the process cwd standalone\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003elocal_skills_folder\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e skills/iii\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # project-scoped overrides (whole-namespace local-wins)\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003eagents_folder\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e agents\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # direct \u0026#x3C;id\u003e.md agent profiles\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003eagents_skills_folder\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e .agents/skills\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # READ-ONLY agent skills, with the same relative-path base\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003eauto_download\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#1E754F\"\u003e true\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # subscribe to worker-add + run the boot reconcile\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# TUNABLE — hot-reload live on `configuration:updated`.\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003eregistry_url\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e https://api.workers.iii.dev\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # workers registry base URL\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003edownload_timeout_ms\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#2F798A\"\u003e 60000\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # per git-clone / HTTP request timeout (ms)\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003eregistry_cache_ttl_ms\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#2F798A\"\u003e 60000\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # in-process TTL for registry::workers::* responses\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003efilter_unregistered\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#1E754F\"\u003e true\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # hide skills whose namespace isn't an installed worker\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003einject_hint\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#1E754F\"\u003e false\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # bind the directory::pre-generate search-hint hook (off: the harness identity prompt already teaches directory-first discovery)\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003ehint_min_workers\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#2F798A\"\u003e 2\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # minimum surface width before the hint fires (0 = always)\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003eregistry_search\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#1E754F\"\u003e true\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # include installable registry workers in every search\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThe writable \u003ccode class=\"readme-inline-code\"\u003eskills_folder\u003c/code\u003e and \u003ccode class=\"readme-inline-code\"\u003eagents_folder\u003c/code\u003e roots are created when needed.\u003c/p\u003e\n\u003ch3 id=\"zero-config-default-seed\" class=\"scroll-mt-20\"\u003eZero-config default + seed\u003c/h3\u003e\n\u003cp\u003eWith no seed and no stored value the worker uses built-in defaults. Relative\nfolder paths use \u003ccode class=\"readme-inline-code\"\u003eIII_COMPOSE_DIR\u003c/code\u003e when set and the process current directory\notherwise (\u003ccode class=\"readme-inline-code\"\u003eskills_folder: skills\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003eagents_folder: agents\u003c/code\u003e,\n\u003ccode class=\"readme-inline-code\"\u003eregistry_url: https://api.workers.iii.dev\u003c/code\u003e).\nPass \u003ccode class=\"readme-inline-code\"\u003e--config \u003cpath\u003e\u003c/code\u003e to supply a YAML seed: when present and no value is\nstored yet, its contents become \u003ccode class=\"readme-inline-code\"\u003einitial_value\u003c/code\u003e on \u003ccode class=\"readme-inline-code\"\u003econfiguration::register\u003c/code\u003e\n(see \u003ca href=\"config.yaml.example\"\u003e\u003ccode class=\"readme-inline-code\"\u003econfig.yaml.example\u003c/code\u003e\u003c/a\u003e). Engine-managed deployments\ninline the config under the worker entry; the engine delivers it via \u003ccode class=\"readme-inline-code\"\u003e--config\u003c/code\u003e.\u003c/p\u003e\n\u003ch3 id=\"hot-reload\" class=\"scroll-mt-20\"\u003eHot reload\u003c/h3\u003e\n\u003cp\u003eOn \u003ccode class=\"readme-inline-code\"\u003econfiguration::set\u003c/code\u003e (or an external edit to the persisted file), the worker\nre-fetches the authoritative value. Tunable changes apply in place and the\nregistry caches are cleared so a repointed \u003ccode class=\"readme-inline-code\"\u003eregistry_url\u003c/code\u003e takes effect\nimmediately. Topology changes (\u003ccode class=\"readme-inline-code\"\u003eskills_folder\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003elocal_skills_folder\u003c/code\u003e /\n\u003ccode class=\"readme-inline-code\"\u003eagents_folder\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003eagents_skills_folder\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003eauto_download\u003c/code\u003e) are refused with a \u0026quot;restart\nrequired\u0026quot; log; the previous configuration is kept until the worker restarts.\u003c/p\u003e\n\u003cp\u003eThe writable \u003ccode class=\"readme-inline-code\"\u003eskills_folder\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003elocal_skills_folder\u003c/code\u003e, and \u003ccode class=\"readme-inline-code\"\u003eagents_folder\u003c/code\u003e are\nwatch roots, and the watcher creates each one at boot if it is missing.\nDirect \u003ccode class=\"readme-inline-code\"\u003e\u003cid\u003e.md\u003c/code\u003e edits under \u003ccode class=\"readme-inline-code\"\u003eagents_folder\u003c/code\u003e fire\n\u003ccode class=\"readme-inline-code\"\u003edirectory::agents::on-change\u003c/code\u003e with \u003ccode class=\"readme-inline-code\"\u003eop: \"external\"\u003c/code\u003e; nested files are ignored.\n\u003ccode class=\"readme-inline-code\"\u003eagents_skills_folder\u003c/code\u003e is a watch root too,\nbut only when it already exists — the worker never creates (or writes)\nanything under it. Install your first agents skill while the worker is\nrunning and that root stays unwatched until the next restart: reads still\nserve it, since every read re-scans disk, but the live \u003ccode class=\"readme-inline-code\"\u003eexternal\u003c/code\u003e doorbell\nis missing until then. \u003ccode class=\"readme-inline-code\"\u003elocal_skills_folder\u003c/code\u003e defaults to \u003ccode class=\"readme-inline-code\"\u003eskills/iii\u003c/code\u003e under\n\u003ccode class=\"readme-inline-code\"\u003eIII_COMPOSE_DIR\u003c/code\u003e, or under the process current directory when the worker runs\nstandalone. An empty local root shadows nothing. Because the roots are\nrestart-required, the watch\nroots are fixed for the process lifetime.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"quickstart-download-some-skills\" class=\"scroll-mt-20\"\u003eQuickstart: download some skills\u003c/h2\u003e\n\u003cpre class=\"shiki vitesse-light\" style=\"background-color:#ffffff;color:#393a34\" tabindex=\"0\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# Pull a specific worker's directory bundle at a fixed semver from\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# the registry. Files land under `\u0026#x3C;skills_folder\u003e/agent-memory/`.\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#59873A\"\u003eiii\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e trigger\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e --function-id=directory::skills::download\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e \\\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A65E2B\"\u003e --payload=\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e'\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e{\"worker\": \"agent-memory\", \"version\": \"1.2.3\"}\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e'\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# Same, but always fetch whatever's tagged `latest` (also the default\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# when neither version nor tag is given).\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#59873A\"\u003eiii\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e trigger\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e --function-id=directory::skills::download\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e \\\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A65E2B\"\u003e --payload=\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e'\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e{\"worker\": \"agent-memory\"}\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e'\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# Pull a single subfolder out of a public GitHub repo via\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# `git clone --depth 1 --branch main`. Files land under\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# `\u0026#x3C;skills_folder\u003e/frontend-design/`. The `branch` field defaults to\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# `main`; pass `\"master\"` for older repos that haven't migrated.\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#59873A\"\u003eiii\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e trigger\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e --function-id=directory::skills::download\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e \\\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A65E2B\"\u003e --payload=\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e'\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e{\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#B56959\"\u003e \"repo\": \"https://github.com/anthropics/skills\",\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#B56959\"\u003e \"skill\": \"frontend-design\"\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#B56959\"\u003e }\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e'\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThe response is\n\u003ccode class=\"readme-inline-code\"\u003e{ namespace, skills_written, system_prompts_written, agents_written, source }\u003c/code\u003e.\nThe three \u003ccode class=\"readme-inline-code\"\u003e*_written\u003c/code\u003e fields list the files materialised in this run.\nRegistry entries shaped exactly as \u003ccode class=\"readme-inline-code\"\u003eagents/\u003cid\u003e.md\u003c/code\u003e land in\n\u003ccode class=\"readme-inline-code\"\u003e\u003cagents_folder\u003e/\u003cid\u003e.md\u003c/code\u003e; repo downloads do not install agent profiles.\u003c/p\u003e\n\u003cp\u003eAfter every successful download the worker fires the\n\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::on-change\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::on-change\u003c/code\u003e,\nand/or \u003ccode class=\"readme-inline-code\"\u003edirectory::agents::on-change\u003c/code\u003e trigger types so that\nsubscribers like the \u003ca href=\"https://github.com/iii-hq/workers/tree/main/mcp\"\u003e\u003ccode class=\"readme-inline-code\"\u003emcp\u003c/code\u003e\u003c/a\u003e worker can\nforward MCP \u003ccode class=\"readme-inline-code\"\u003enotifications/list_changed\u003c/code\u003e to their clients.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"on-disk-layout\" class=\"scroll-mt-20\"\u003eOn-disk layout\u003c/h2\u003e\n\u003cp\u003eThe worker uses separate roots for directory content and agent profiles:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eskills_folder/\n \u0026lt;namespace\u0026gt;/ # one folder per `directory::skills::download` namespace\n index.md # → iii://\u0026lt;namespace\u0026gt;/index\n contacts.md # → iii://\u0026lt;namespace\u0026gt;/contacts\n emails/send-email.md # → iii://\u0026lt;namespace\u0026gt;/emails/send-email\n system-prompts/ # ← magic marker for system prompts\n reviewer.md # ← identity prompt (needs YAML frontmatter)\n system-prompts/ # ← where system-prompts::create writes\n pirate.md\n\nagents_folder/ # ← where agents::create writes\n release-captain.md # ← agent profile (needs YAML frontmatter)\n frontend-design.md # ← `extends: iii` builds on the bundled base\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eTwo base agent profiles ship inside the worker binary: \u003ccode class=\"readme-inline-code\"\u003eiii\u003c/code\u003e (the harness\ndefault identity, verbatim) and \u003ccode class=\"readme-inline-code\"\u003eiii-minimal\u003c/code\u003e (the minimal directory-first\nidentity — the same text as the bundled system prompt of that name). Each is\nalways listed (\u003ccode class=\"readme-inline-code\"\u003ebuiltin: true\u003c/code\u003e), a local \u003ccode class=\"readme-inline-code\"\u003eagents_folder/\u003cid\u003e.md\u003c/code\u003e shadows it,\n\u003ccode class=\"readme-inline-code\"\u003eupdate\u003c/code\u003e on it copy-on-writes that local file, and deleting the file falls\nback to the bundled copy. No file is ever seeded on disk.\u003c/p\u003e\n\u003cp\u003eA second, READ-ONLY root — \u003ccode class=\"readme-inline-code\"\u003eagents_skills_folder\u003c/code\u003e (default \u003ccode class=\"readme-inline-code\"\u003e.agents/skills\u003c/code\u003e\nunder the same Compose or standalone base) — serves agent skills. It is\nscanned \u003cstrong\u003eshallowly\u003c/strong\u003e: only \u003ccode class=\"readme-inline-code\"\u003e\u003cskill-dir\u003e/SKILL.md\u003c/code\u003e becomes an entry\n(id \u003ccode class=\"readme-inline-code\"\u003e\u003cskill-dir\u003e/index\u003c/code\u003e, displayed as \u003ccode class=\"readme-inline-code\"\u003e\u003cskill-dir\u003e\u003c/code\u003e); a skill\u0026#39;s\n\u003ccode class=\"readme-inline-code\"\u003ereference/\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003escripts/\u003c/code\u003e, or other support payload is never listed. A\nmissing directory is silently empty. These skills bypass\n\u003ccode class=\"readme-inline-code\"\u003efilter_unregistered\u003c/code\u003e (their namespaces are skills, not workers), stay\nout of \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::index\u003c/code\u003e (a per-WORKER surface), and are\nrefused by \u003ccode class=\"readme-inline-code\"\u003eupdate\u003c/code\u003e/\u003ccode class=\"readme-inline-code\"\u003edelete\u003c/code\u003e — edit them with their owning tool, or\ncopy one into \u003ccode class=\"readme-inline-code\"\u003eskills_folder\u003c/code\u003e on disk to fork it. Precedence is\n\u003ccode class=\"readme-inline-code\"\u003elocal_skills_folder\u003c/code\u003e \u0026gt; \u003ccode class=\"readme-inline-code\"\u003eskills_folder\u003c/code\u003e \u0026gt; \u003ccode class=\"readme-inline-code\"\u003eagents_skills_folder\u003c/code\u003e,\nnamespace-wise: a top-level namespace directory in a higher root\nshadows the same namespace below.\u003c/p\u003e\n\u003cp\u003eA few rules:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eSkill ids\u003c/strong\u003e are the relative path under \u003ccode class=\"readme-inline-code\"\u003eskills_folder\u003c/code\u003e with \u003ccode class=\"readme-inline-code\"\u003e.md\u003c/code\u003e\nstripped. Each segment must satisfy \u003ccode class=\"readme-inline-code\"\u003e[a-z0-9_-]{1,64}\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eSkill frontmatter is optional.\u003c/strong\u003e When present, the reader recognises\n\u003ccode class=\"readme-inline-code\"\u003etitle:\u003c/code\u003e (preferred title), \u003ccode class=\"readme-inline-code\"\u003ename:\u003c/code\u003e (title fallback), \u003ccode class=\"readme-inline-code\"\u003etype:\u003c/code\u003e (free-form\nclassifier), \u003ccode class=\"readme-inline-code\"\u003efunction_id:\u003c/code\u003e (canonical bus function id surfaced by \u003ccode class=\"readme-inline-code\"\u003elist\u003c/code\u003e\nand \u003ccode class=\"readme-inline-code\"\u003eget\u003c/code\u003e), \u003ccode class=\"readme-inline-code\"\u003edescription:\u003c/code\u003e (preferred \u003ccode class=\"readme-inline-code\"\u003elist\u003c/code\u003e teaser), and\n\u003ccode class=\"readme-inline-code\"\u003edisable-model-invocation:\u003c/code\u003e (boolean, default \u003ccode class=\"readme-inline-code\"\u003efalse\u003c/code\u003e, surfaced as\n\u003ccode class=\"readme-inline-code\"\u003edisable_model_invocation\u003c/code\u003e by both responses). The body H1 and first\nparagraph are the title and list-description fallbacks, respectively.\nDisabled skills remain visible to ordinary directory clients; model\nindex consumers decide whether to filter them. Any other YAML keys are ignored.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eSystem prompts\u003c/strong\u003e live under any \u003ccode class=\"readme-inline-code\"\u003e*/system-prompts/*.md\u003c/code\u003e path, with\nYAML frontmatter (\u003ccode class=\"readme-inline-code\"\u003edescription\u003c/code\u003e required, \u003ccode class=\"readme-inline-code\"\u003ename\u003c/code\u003e optional). A path carrying\nboth a \u003ccode class=\"readme-inline-code\"\u003eprompts\u003c/code\u003e and a \u003ccode class=\"readme-inline-code\"\u003esystem-prompts\u003c/code\u003e segment is a system prompt because\n\u003ccode class=\"readme-inline-code\"\u003esystem-prompts\u003c/code\u003e is classified first. Other paths containing a \u003ccode class=\"readme-inline-code\"\u003eprompts\u003c/code\u003e\nsegment are ignored by scans and downloads.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eWhat a system prompt can do, by design.\u003c/strong\u003e The console\u0026#39;s chat picker\ncan send a selected system prompt with\n\u003ccode class=\"readme-inline-code\"\u003esystem_prompt_strategy: \"override\"\u003c/code\u003e, which replaces the harness\u0026#39;s\nbuilt-in identity prompt with that file\u0026#39;s body verbatim. Files reach\n\u003ccode class=\"readme-inline-code\"\u003esystem-prompts/\u003c/code\u003e either by local authoring or via\n\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::download\u003c/code\u003e from a git repo or the registry, so a\ndownloaded bundle can supply one. This is an accepted property, not a\nhole: it takes a deliberate selection in the UI, the same UI already\naccepts arbitrary typed text, and the operator owns \u003ccode class=\"readme-inline-code\"\u003eskills_folder\u003c/code\u003e.\nWorth knowing before you point \u003ccode class=\"readme-inline-code\"\u003eskills_folder\u003c/code\u003e at a directory other\npeople can write to.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eAgent profiles\u003c/strong\u003e are direct \u003ccode class=\"readme-inline-code\"\u003e\u003cagents_folder\u003e/\u003cid\u003e.md\u003c/code\u003e files (unrelated to\nthe read-only \u003ccode class=\"readme-inline-code\"\u003eagents_skills_folder\u003c/code\u003e above, which holds external tools\u0026#39;\n\u003cem\u003eskills\u003c/em\u003e). Nested profiles and the former\n\u003ccode class=\"readme-inline-code\"\u003e\u003cskills_folder\u003e/**/agents/*.md\u003c/code\u003e layout are ignored. Frontmatter is required\nand must declare a non-empty \u003ccode class=\"readme-inline-code\"\u003ename\u003c/code\u003e\n(the display name — the id is always the file stem); \u003ccode class=\"readme-inline-code\"\u003edescription\u003c/code\u003e may\nbe empty, \u003ccode class=\"readme-inline-code\"\u003elogo\u003c/code\u003e is emoji-only (≤16 bytes, no path characters),\n\u003ccode class=\"readme-inline-code\"\u003eskills:\u003c/code\u003e filters the skill index (absent/empty = every skill), and\n\u003ccode class=\"readme-inline-code\"\u003emodel:\u003c/code\u003e names a model id for sessions using this profile (absent = the\nsend decides), and optional \u003ccode class=\"readme-inline-code\"\u003ereasoning_effort:\u003c/code\u003e names its provider-native\neffort. Both are stored verbatim and resolved against the live model\ncatalog where they are used. The body is the\nsystem prompt, verbatim, and may be empty — a profile with no prompt of\nits own contributes only its parent chain (if any) and its non-prompt\nsettings. Unknown \u003ccode class=\"readme-inline-code\"\u003eskills\u003c/code\u003e ids are\nwarnings surfaced by \u003ccode class=\"readme-inline-code\"\u003eget\u003c/code\u003e, never load failures.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eAgent profiles inherit.\u003c/strong\u003e \u003ccode class=\"readme-inline-code\"\u003eextends: \u003cid\u003e\u003c/code\u003e names one parent profile\n(chains allowed, at most 8 hops). The resolved system prompt served by\n\u003ccode class=\"readme-inline-code\"\u003eget\u003c/code\u003e is the parent\u0026#39;s resolved prompt followed by a blank line and this\nfile\u0026#39;s body — a blank body contributes nothing, so a profile with no\nprompt of its own serves its parent chain unchanged; \u003ccode class=\"readme-inline-code\"\u003eskills\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003emodel\u003c/code\u003e and \u003ccode class=\"readme-inline-code\"\u003ereasoning_effort\u003c/code\u003e fall back to the\nnearest ancestor that sets them when omitted (a non-empty \u003ccode class=\"readme-inline-code\"\u003eskills\u003c/code\u003e list\nreplaces, never unions); \u003ccode class=\"readme-inline-code\"\u003ename\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003edescription\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003elogo\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003eicon\u003c/code\u003e and\n\u003ccode class=\"readme-inline-code\"\u003ecolor\u003c/code\u003e are always the profile\u0026#39;s own. A chain that does not resolve\n(unknown parent, loop, too deep) is reported by \u003ccode class=\"readme-inline-code\"\u003elist\u003c/code\u003e/\u003ccode class=\"readme-inline-code\"\u003eget\u003c/code\u003e as\n\u003ccode class=\"readme-inline-code\"\u003einheritance_error\u003c/code\u003e (\u003ccode class=\"readme-inline-code\"\u003eD415\u003c/code\u003e text) while the profile still serves its own\nfile (so the editor can fix it); the harness refuses to run it.\u003c/li\u003e\n\u003cli\u003eUnder a skills root, files outside \u003ccode class=\"readme-inline-code\"\u003eprompts/\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003esystem-prompts/\u003c/code\u003e, and\nreserved \u003ccode class=\"readme-inline-code\"\u003eagents/\u003c/code\u003e segments are skills.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe download function namespaces by source:\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eSource\u003c/th\u003e\n\u003cth\u003eDestination\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003erepo=URL skill=NAME branch?=main\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003e\u003cskills_folder\u003e/\u003cNAME\u003e/...\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003eworker=NAME version=…\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSkills/prompts under \u003ccode class=\"readme-inline-code\"\u003e\u003cskills_folder\u003e/\u003cNAME\u003e/...\u003c/code\u003e; exact \u003ccode class=\"readme-inline-code\"\u003eagents/\u003cid\u003e.md\u003c/code\u003e entries under \u003ccode class=\"readme-inline-code\"\u003e\u003cagents_folder\u003e/\u003cid\u003e.md\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003eworker=NAME tag=…\u003c/code\u003e (default \u003ccode class=\"readme-inline-code\"\u003etag=latest\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003eSame routing as the version form\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003eRe-pulling the same source overwrites files \u003cstrong\u003efile-by-file\u003c/strong\u003e —\nexisting siblings outside the response set are preserved (so\nhand-edited additions survive a re-pull).\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"skill-ids\" class=\"scroll-mt-20\"\u003eSkill ids\u003c/h2\u003e\n\u003cp\u003eSkills are addressed by their relative path under \u003ccode class=\"readme-inline-code\"\u003eskills_folder\u003c/code\u003e with\n\u003ccode class=\"readme-inline-code\"\u003e.md\u003c/code\u003e stripped — e.g. \u003ccode class=\"readme-inline-code\"\u003e\u003cskills_folder\u003e/agent-memory/observe.md\u003c/code\u003e →\nid \u003ccode class=\"readme-inline-code\"\u003e\"agent-memory/observe\"\u003c/code\u003e. The same string is what\n\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::list\u003c/code\u003e returns and what \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::get\u003c/code\u003e\nexpects in \u003ccode class=\"readme-inline-code\"\u003e{ \"id\": ... }\u003c/code\u003e. The legacy \u003ccode class=\"readme-inline-code\"\u003eiii://{id}\u003c/code\u003e link form is still\naccepted on \u003ccode class=\"readme-inline-code\"\u003eget\u003c/code\u003e (the prefix is auto-stripped), but the worker no\nlonger parses any other \u003ccode class=\"readme-inline-code\"\u003eiii://\u003c/code\u003e URI shape — bodies are read solely by\nid, and the auto-rendered tree-shaped index that previous releases\nserved at \u003ccode class=\"readme-inline-code\"\u003eiii://directory/skills\u003c/code\u003e is gone. Consumers that want a\ntree-shaped picker iterate \u003ccode class=\"readme-inline-code\"\u003elist\u003c/code\u003e rows themselves and indent by\n\u003ccode class=\"readme-inline-code\"\u003eid.matches('/').count()\u003c/code\u003e.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"functions\" class=\"scroll-mt-20\"\u003eFunctions\u003c/h2\u003e\n\u003cp\u003eFunctions sit under \u003ccode class=\"readme-inline-code\"\u003edirectory::*\u003c/code\u003e. All registrations are\nnamespace-clean; this worker is intentionally agnostic to MCP and any\nother adapter.\u003c/p\u003e\n\u003ch3 id=\"directoryskills-filesystem-reader-editor\" class=\"scroll-mt-20\"\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::*\u003c/code\u003e (filesystem reader + editor)\u003c/h3\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eFunction ID\u003c/th\u003e\n\u003cth\u003eDescription\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::download\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eDownload directory content. Flexible alias accepting either source set: \u003ccode class=\"readme-inline-code\"\u003e{repo, skill, branch?}\u003c/code\u003e (defaults \u003ccode class=\"readme-inline-code\"\u003ebranch=main\u003c/code\u003e) or \u003ccode class=\"readme-inline-code\"\u003e{worker, version?|tag?}\u003c/code\u003e (defaults \u003ccode class=\"readme-inline-code\"\u003etag=latest\u003c/code\u003e). Prefer the two explicit forms below so the source is unambiguous.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::download_from_repo\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eRepo-only form: \u003ccode class=\"readme-inline-code\"\u003e{repo, skill, branch?}\u003c/code\u003e. Copies one skill folder out of a GitHub repo; paths under \u003ccode class=\"readme-inline-code\"\u003eprompts/\u003c/code\u003e and \u003ccode class=\"readme-inline-code\"\u003eagents/\u003c/code\u003e are ignored.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::download_from_registry\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eRegistry-only form: \u003ccode class=\"readme-inline-code\"\u003e{worker, version?|tag?}\u003c/code\u003e. Installs a published worker\u0026#39;s bundle from \u003ccode class=\"readme-inline-code\"\u003eapi.workers.iii.dev\u003c/code\u003e, routing exact \u003ccode class=\"readme-inline-code\"\u003eagents/\u003cid\u003e.md\u003c/code\u003e entries to \u003ccode class=\"readme-inline-code\"\u003eagents_folder\u003c/code\u003e.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::list\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eEnriched listing of every fs-backed skill: \u003ccode class=\"readme-inline-code\"\u003e{ id, title, type, function_id, disable_model_invocation, description, bytes, modified_at }\u003c/code\u003e per row. \u003ccode class=\"readme-inline-code\"\u003etitle\u003c/code\u003e prefers the YAML frontmatter \u003ccode class=\"readme-inline-code\"\u003etitle:\u003c/code\u003e over the body H1, \u003ccode class=\"readme-inline-code\"\u003etype\u003c/code\u003e is lifted from frontmatter \u003ccode class=\"readme-inline-code\"\u003etype:\u003c/code\u003e (\u003ccode class=\"readme-inline-code\"\u003enull\u003c/code\u003e when absent), \u003ccode class=\"readme-inline-code\"\u003efunction_id\u003c/code\u003e identifies the documented bus function when present, and \u003ccode class=\"readme-inline-code\"\u003edescription\u003c/code\u003e is the frontmatter description or first body paragraph — so consumers can render a picker without a follow-up \u003ccode class=\"readme-inline-code\"\u003eget\u003c/code\u003e per row.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::get\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eFetch one skill by id. Returns \u003ccode class=\"readme-inline-code\"\u003e{ id, title, type, function_id, disable_model_invocation, path, body, modified_at }\u003c/code\u003e. It shares the list row\u0026#39;s identity, classification, function, and invocation metadata, but returns the raw markdown \u003ccode class=\"readme-inline-code\"\u003ebody\u003c/code\u003e and absolute on-disk \u003ccode class=\"readme-inline-code\"\u003epath\u003c/code\u003e instead of the teaser and byte count; there is no \u003ccode class=\"readme-inline-code\"\u003edescription\u003c/code\u003e field. The path\u0026#39;s parent directory is the skill\u0026#39;s base directory, where payload like \u003ccode class=\"readme-inline-code\"\u003escripts/\u003c/code\u003e and \u003ccode class=\"readme-inline-code\"\u003ereference/\u003c/code\u003e lives, and is meaningful only to callers on this worker\u0026#39;s machine. Accepts a bare id or the same id prefixed with \u003ccode class=\"readme-inline-code\"\u003eiii://\u003c/code\u003e. Pass \u003ccode class=\"readme-inline-code\"\u003eraw: true\u003c/code\u003e to additionally get the FULL on-disk file (frontmatter included) as \u003ccode class=\"readme-inline-code\"\u003eraw\u003c/code\u003e — the round-trip form \u003ccode class=\"readme-inline-code\"\u003eupdate\u003c/code\u003e takes.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::update\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eOverwrite one EXISTING skill file with new full-file content: \u003ccode class=\"readme-inline-code\"\u003e{ id, content }\u003c/code\u003e where \u003ccode class=\"readme-inline-code\"\u003econtent\u003c/code\u003e is the edited \u003ccode class=\"readme-inline-code\"\u003eraw\u003c/code\u003e from \u003ccode class=\"readme-inline-code\"\u003eget { raw: true }\u003c/code\u003e. Validated against the read invariants (size cap, non-empty body after frontmatter); atomic write; fans out \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::on-change\u003c/code\u003e with \u003ccode class=\"readme-inline-code\"\u003eop: \"update\"\u003c/code\u003e. Never creates files (use \u003ccode class=\"readme-inline-code\"\u003ecreate\u003c/code\u003e). Refuses read-only system-installed skills under \u003ccode class=\"readme-inline-code\"\u003eagents_skills_folder\u003c/code\u003e (\u003ccode class=\"readme-inline-code\"\u003eD116\u003c/code\u003e).\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::create\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCreate a NEW skill file at \u003ccode class=\"readme-inline-code\"\u003e\u003cskills_folder\u003e/\u003cid\u003e.md\u003c/code\u003e from full-file content: \u003ccode class=\"readme-inline-code\"\u003e{ id, content }\u003c/code\u003e. Frontmatter is optional (same rules as \u003ccode class=\"readme-inline-code\"\u003eupdate\u003c/code\u003e: size cap, non-empty body). Refuses an \u003ccode class=\"readme-inline-code\"\u003eid\u003c/code\u003e that already resolves in the visible set — including the \u003ccode class=\"readme-inline-code\"\u003e\u003cid\u003e\u003c/code\u003e → \u003ccode class=\"readme-inline-code\"\u003e\u003cid\u003e/index\u003c/code\u003e overview alias and system-installed agents skills — or a target path that already exists on disk (\u003ccode class=\"readme-inline-code\"\u003eD114\u003c/code\u003e); an \u003ccode class=\"readme-inline-code\"\u003eid\u003c/code\u003e in a namespace reserved by a system-installed agents skill (\u003ccode class=\"readme-inline-code\"\u003eD115\u003c/code\u003e); and, while \u003ccode class=\"readme-inline-code\"\u003efilter_unregistered\u003c/code\u003e is on, an \u003ccode class=\"readme-inline-code\"\u003eid\u003c/code\u003e the visibility filter would immediately hide (\u003ccode class=\"readme-inline-code\"\u003eD115\u003c/code\u003e). Atomic write; fans out \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::on-change\u003c/code\u003e with \u003ccode class=\"readme-inline-code\"\u003eop: \"create\"\u003c/code\u003e. Returns the same shape as \u003ccode class=\"readme-inline-code\"\u003eupdate\u003c/code\u003e.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::delete\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePermanently remove one EXISTING skill file by \u003ccode class=\"readme-inline-code\"\u003e{ id }\u003c/code\u003e (same id forms as \u003ccode class=\"readme-inline-code\"\u003eget\u003c/code\u003e). Resolves against the same visible set as \u003ccode class=\"readme-inline-code\"\u003elist\u003c/code\u003e/\u003ccode class=\"readme-inline-code\"\u003eget\u003c/code\u003e, refuses read-only system-installed skills under \u003ccode class=\"readme-inline-code\"\u003eagents_skills_folder\u003c/code\u003e (\u003ccode class=\"readme-inline-code\"\u003eD116\u003c/code\u003e), removes the file plus any parent directories left empty (so a deleted namespace can\u0026#39;t keep shadowing a lower-precedence root), and fans out \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::on-change\u003c/code\u003e with \u003ccode class=\"readme-inline-code\"\u003eop: \"delete\"\u003c/code\u003e. Returns \u003ccode class=\"readme-inline-code\"\u003e{ id }\u003c/code\u003e (the resolved on-disk id).\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::index\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eRender one short markdown entry per installed worker (skills with frontmatter \u003ccode class=\"readme-inline-code\"\u003etype: index\u003c/code\u003e). Returns \u003ccode class=\"readme-inline-code\"\u003e{ body, workers_count }\u003c/code\u003e where \u003ccode class=\"readme-inline-code\"\u003ebody\u003c/code\u003e is a ready-to-paste page: \u003ccode class=\"readme-inline-code\"\u003e# Skills index\u003c/code\u003e, then one \u003ccode class=\"readme-inline-code\"\u003e## \u003cworker title\u003e\u003c/code\u003e heading + the worker\u0026#39;s first overview paragraph + a \u003ccode class=\"readme-inline-code\"\u003eRead iii://\u003cns\u003e/index\u003c/code\u003e pointer the agent can follow with \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::get\u003c/code\u003e. Token-light by design; use \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::list\u003c/code\u003e for per-skill rows.\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003ch3 id=\"directorysystem-prompts-filesystem-reader-editor\" class=\"scroll-mt-20\"\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::*\u003c/code\u003e (filesystem reader + editor)\u003c/h3\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eFunction ID\u003c/th\u003e\n\u003cth\u003eDescription\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::list\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eMetadata-only listing of every fs-backed system prompt.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::get\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eFetch one system prompt\u0026#39;s body + \u003ccode class=\"readme-inline-code\"\u003e{name, description, modified_at}\u003c/code\u003e. Plain shape, no envelope. Pass \u003ccode class=\"readme-inline-code\"\u003eraw: true\u003c/code\u003e to additionally get the FULL on-disk file (frontmatter included) as \u003ccode class=\"readme-inline-code\"\u003eraw\u003c/code\u003e.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::update\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eOverwrite one EXISTING system prompt file with new full-file content: \u003ccode class=\"readme-inline-code\"\u003e{ name, content }\u003c/code\u003e. The frontmatter must keep a non-empty \u003ccode class=\"readme-inline-code\"\u003edescription\u003c/code\u003e (and a valid \u003ccode class=\"readme-inline-code\"\u003ename\u003c/code\u003e when declared) — the same rules the scanner enforces. Atomic write; fans out \u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::on-change\u003c/code\u003e with \u003ccode class=\"readme-inline-code\"\u003eop: \"update\"\u003c/code\u003e. Returns the system prompt\u0026#39;s effective name after the write.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::create\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCreate a NEW system prompt file at \u003ccode class=\"readme-inline-code\"\u003e\u003cskills_folder\u003e/system-prompts/\u003cname\u003e.md\u003c/code\u003e from full-file content: \u003ccode class=\"readme-inline-code\"\u003e{ name, content }\u003c/code\u003e, where \u003ccode class=\"readme-inline-code\"\u003econtent\u003c/code\u003e is the FULL file including frontmatter. The frontmatter must carry a non-empty \u003ccode class=\"readme-inline-code\"\u003edescription\u003c/code\u003e (and a \u003ccode class=\"readme-inline-code\"\u003ename\u003c/code\u003e matching the request, when declared) — the same rules \u003ccode class=\"readme-inline-code\"\u003eupdate\u003c/code\u003e enforces. Refuses a \u003ccode class=\"readme-inline-code\"\u003ename\u003c/code\u003e that already exists anywhere in the merged system-prompt scan, and a target path that already exists on disk even if the scanner would skip it. Atomic write; fans out \u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::on-change\u003c/code\u003e with \u003ccode class=\"readme-inline-code\"\u003eop: \"create\"\u003c/code\u003e. Returns \u003ccode class=\"readme-inline-code\"\u003e{ name, description, bytes, modified_at }\u003c/code\u003e.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::delete\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePermanently remove one EXISTING system prompt file by \u003ccode class=\"readme-inline-code\"\u003e{ name }\u003c/code\u003e. Resolves against the same merged scan as \u003ccode class=\"readme-inline-code\"\u003elist\u003c/code\u003e/\u003ccode class=\"readme-inline-code\"\u003eget\u003c/code\u003e, fans out \u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::on-change\u003c/code\u003e with \u003ccode class=\"readme-inline-code\"\u003eop: \"delete\"\u003c/code\u003e, and returns \u003ccode class=\"readme-inline-code\"\u003e{ name }\u003c/code\u003e.\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003ch3 id=\"agent-profiles-directoryagents-filesystem-reader-editor\" class=\"scroll-mt-20\"\u003eAgent Profiles — \u003ccode class=\"readme-inline-code\"\u003edirectory::agents::*\u003c/code\u003e (filesystem reader + editor)\u003c/h3\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eFunction ID\u003c/th\u003e\n\u003cth\u003eDescription\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::agents::list\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eMetadata-only listing of every agent profile — fs-backed plus the bundled \u003ccode class=\"readme-inline-code\"\u003eiii\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003eiii-minimal\u003c/code\u003e bases (\u003ccode class=\"readme-inline-code\"\u003ebuiltin: true\u003c/code\u003e until a local file shadows one): \u003ccode class=\"readme-inline-code\"\u003e{ id, name, description, logo, skill_count, model, reasoning_effort, icon, color, extends, modified_at }\u003c/code\u003e per row, \u003ccode class=\"readme-inline-code\"\u003eskill_count\u003c/code\u003e/\u003ccode class=\"readme-inline-code\"\u003emodel\u003c/code\u003e/\u003ccode class=\"readme-inline-code\"\u003ereasoning_effort\u003c/code\u003e resolved through \u003ccode class=\"readme-inline-code\"\u003eextends\u003c/code\u003e (\u003ccode class=\"readme-inline-code\"\u003eskill_count: null\u003c/code\u003e = every skill; \u003ccode class=\"readme-inline-code\"\u003emodel: null\u003c/code\u003e = the send decides). A row whose chain does not resolve carries \u003ccode class=\"readme-inline-code\"\u003einheritance_error\u003c/code\u003e.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::agents::get\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eFetch one agent profile by \u003ccode class=\"readme-inline-code\"\u003e{ id }\u003c/code\u003e: the RESOLVED \u003ccode class=\"readme-inline-code\"\u003esystem_prompt\u003c/code\u003e (each ancestor\u0026#39;s body root-first, then this file\u0026#39;s body), \u003ccode class=\"readme-inline-code\"\u003eskills\u003c/code\u003e + \u003ccode class=\"readme-inline-code\"\u003eunknown_skills\u003c/code\u003e (filter entries matching no visible skill — warnings), \u003ccode class=\"readme-inline-code\"\u003emodel\u003c/code\u003e (\u003ccode class=\"readme-inline-code\"\u003enull\u003c/code\u003e = the send decides), provider-native \u003ccode class=\"readme-inline-code\"\u003ereasoning_effort\u003c/code\u003e, display \u003ccode class=\"readme-inline-code\"\u003eicon\u003c/code\u003e/\u003ccode class=\"readme-inline-code\"\u003ecolor\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003eextends\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003ebuiltin\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003emodified_at\u003c/code\u003e, and \u003ccode class=\"readme-inline-code\"\u003einheritance_error\u003c/code\u003e when the chain does not resolve (own file served meanwhile). Pass \u003ccode class=\"readme-inline-code\"\u003eraw: true\u003c/code\u003e to additionally get this profile\u0026#39;s FULL on-disk file as \u003ccode class=\"readme-inline-code\"\u003eraw\u003c/code\u003e.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::agents::update\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eOverwrite one EXISTING agent profile file with new full-file content: \u003ccode class=\"readme-inline-code\"\u003e{ id, content }\u003c/code\u003e. Same rules the scanner enforces (required frontmatter with non-empty \u003ccode class=\"readme-inline-code\"\u003ename\u003c/code\u003e, emoji-only \u003ccode class=\"readme-inline-code\"\u003elogo\u003c/code\u003e; the body — the system prompt — may be empty); the id stays the file stem. Updating a bundled profile creates the local file that shadows it. Atomic write; fans out \u003ccode class=\"readme-inline-code\"\u003edirectory::agents::on-change\u003c/code\u003e with \u003ccode class=\"readme-inline-code\"\u003eop: \"update\"\u003c/code\u003e.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::agents::create\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCreate a NEW agent profile at \u003ccode class=\"readme-inline-code\"\u003e\u003cagents_folder\u003e/\u003cid\u003e.md\u003c/code\u003e from full-file content: \u003ccode class=\"readme-inline-code\"\u003e{ id, content }\u003c/code\u003e. Refuses an \u003ccode class=\"readme-inline-code\"\u003eid\u003c/code\u003e that already exists in the configured agent-profile root, and a target path that already exists on disk even if the scanner would skip it; creating a bundled id shadows the bundled copy. Atomic write; fans out \u003ccode class=\"readme-inline-code\"\u003edirectory::agents::on-change\u003c/code\u003e with \u003ccode class=\"readme-inline-code\"\u003eop: \"create\"\u003c/code\u003e. Returns \u003ccode class=\"readme-inline-code\"\u003e{ id, name, description, logo, bytes, modified_at }\u003c/code\u003e.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::agents::delete\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003ePermanently remove one EXISTING agent profile file by \u003ccode class=\"readme-inline-code\"\u003e{ id }\u003c/code\u003e. Resolves against the same configured root as \u003ccode class=\"readme-inline-code\"\u003elist\u003c/code\u003e/\u003ccode class=\"readme-inline-code\"\u003eget\u003c/code\u003e, fans out \u003ccode class=\"readme-inline-code\"\u003edirectory::agents::on-change\u003c/code\u003e with \u003ccode class=\"readme-inline-code\"\u003eop: \"delete\"\u003c/code\u003e, and returns \u003ccode class=\"readme-inline-code\"\u003e{ id }\u003c/code\u003e. Deleting the local shadow of a bundled profile falls back to the bundled copy; a bundled profile with no local file has nothing to delete (\u003ccode class=\"readme-inline-code\"\u003eD414\u003c/code\u003e). Sessions already using the profile are unaffected; profiles extending it stop resolving until fixed.\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003ch3 id=\"engine-introspection-native-plus-one-wrapper\" class=\"scroll-mt-20\"\u003eEngine introspection (native, plus one wrapper)\u003c/h3\u003e\n\u003cp\u003eEngine introspection is served natively; call these ids directly — every\none takes the same filters (\u003ccode class=\"readme-inline-code\"\u003eprefix\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003esearch\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003eworker\u003c/code\u003e,\n\u003ccode class=\"readme-inline-code\"\u003einclude_internal\u003c/code\u003e where applicable). One wrapper is kept for callers\nwhose policy only admits the \u003ccode class=\"readme-inline-code\"\u003edirectory::\u003c/code\u003e namespace:\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eFunction ID\u003c/th\u003e\n\u003cth\u003eDescription\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::engine::functions::info\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eThin proxy to \u003ccode class=\"readme-inline-code\"\u003eengine::functions::info\u003c/code\u003e for a single \u003ccode class=\"readme-inline-code\"\u003efunction_id\u003c/code\u003e: request/response schemas, metadata, and registered triggers. The one \u003ccode class=\"readme-inline-code\"\u003edirectory::engine::*\u003c/code\u003e helper that still exists — reach for it only when you cannot call \u003ccode class=\"readme-inline-code\"\u003eengine::*\u003c/code\u003e directly.\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003eThe native ids:\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eFunction ID\u003c/th\u003e\n\u003cth\u003eDescription\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003eengine::functions::list\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eList functions registered with the engine.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003eengine::functions::info\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSingle-function detail: schemas, owning worker.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003eengine::triggers::list\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eList trigger TYPES (the providers, e.g. \u003ccode class=\"readme-inline-code\"\u003ehttp\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003ecron\u003c/code\u003e).\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003eengine::triggers::info\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSingle trigger-type detail: configuration schema, return schema.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003eengine::registered-triggers::list\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eList trigger INSTANCES (subscriber rows).\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003eengine::registered-triggers::info\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eSingle registered-trigger detail.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003eengine::workers::list\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eList workers with an open engine WS connection. Daemon-managed providers (\u003ccode class=\"readme-inline-code\"\u003ehttp\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003ecron\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003estate\u003c/code\u003e) won\u0026#39;t appear — call \u003ccode class=\"readme-inline-code\"\u003eworker::list\u003c/code\u003e from the supervisor to see those.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003eengine::workers::info\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eOne worker\u0026#39;s detail by \u003ccode class=\"readme-inline-code\"\u003ename\u003c/code\u003e.\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003ch3 id=\"directoryregistry-workers-registry-http-proxy\" class=\"scroll-mt-20\"\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::registry::*\u003c/code\u003e (workers registry HTTP proxy)\u003c/h3\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eFunction ID\u003c/th\u003e\n\u003cth\u003eDescription\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::registry::workers::list\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eBrowse / search published workers in \u003ccode class=\"readme-inline-code\"\u003eapi.workers.iii.dev\u003c/code\u003e. Optional free-text \u003ccode class=\"readme-inline-code\"\u003esearch\u003c/code\u003e (matched fuzzy by \u003ccode class=\"readme-inline-code\"\u003epg_trgm\u003c/code\u003e) and opaque \u003ccode class=\"readme-inline-code\"\u003ecursor\u003c/code\u003e for pagination; page size is server-authored. Response is \u003ccode class=\"readme-inline-code\"\u003e{ workers: [...], pagination: { next_cursor, has_more, page_size } }\u003c/code\u003e. Shares the core \u003ccode class=\"readme-inline-code\"\u003ename\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003edescription\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003eversion\u003c/code\u003e fields with the engine\u0026#39;s \u003ccode class=\"readme-inline-code\"\u003eengine::workers::list\u003c/code\u003e.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::registry::workers::info\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eFull registry detail for one worker. Fans out two parallel registry calls — \u003ccode class=\"readme-inline-code\"\u003eGET /w/{slug}\u003c/code\u003e for the worker envelope (publication metadata + readme + functions + triggers) and \u003ccode class=\"readme-inline-code\"\u003eGET /w/{slug}/skills\u003c/code\u003e for the skills tree — and merges them into \u003ccode class=\"readme-inline-code\"\u003e{ worker, readme, api_reference, skills_tree }\u003c/code\u003e. The user-facing input still accepts \u003ccode class=\"readme-inline-code\"\u003eversion:\u003c/code\u003e (semver) or \u003ccode class=\"readme-inline-code\"\u003etag:\u003c/code\u003e (e.g. \u003ccode class=\"readme-inline-code\"\u003elatest\u003c/code\u003e); both go on the wire as \u003ccode class=\"readme-inline-code\"\u003e?version=…\u003c/code\u003e.\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003eBoth \u003ccode class=\"readme-inline-code\"\u003edirectory::registry::*\u003c/code\u003e responses are cached in-process for\n\u003ccode class=\"readme-inline-code\"\u003eregistry_cache_ttl_ms\u003c/code\u003e (default 60s).\u003c/p\u003e\n\u003cp\u003eThere is \u003cstrong\u003eno\u003c/strong\u003e \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::register\u003c/code\u003e — see\n\u003ca href=\"#migration-from-skills-v02x\"\u003eMigration\u003c/a\u003e below.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"function-search-pre-generate-hint\" class=\"scroll-mt-20\"\u003eFunction search \u0026amp; pre-generate hint\u003c/h2\u003e\n\u003cp\u003eOne-shot lexical function search over the live engine catalog, absorbed from\nthe former \u003ccode class=\"readme-inline-code\"\u003ediscovery\u003c/code\u003e worker. It returns only compact \u003ccode class=\"readme-inline-code\"\u003e{ function_id, description }\u003c/code\u003e candidates, grouped by worker in rank order. The model chooses\nthe candidates it needs, then fetches their contracts in one\n\u003ccode class=\"readme-inline-code\"\u003eengine::functions::info { function_ids: [...] }\u003c/code\u003e call instead of walking the\ncatalog with \u003ccode class=\"readme-inline-code\"\u003eengine::functions::list\u003c/code\u003e.\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eFunction\u003c/th\u003e\n\u003cth\u003eKind\u003c/th\u003e\n\u003cth\u003eWhat it does\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::search_functions\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003epublic\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003e{ capabilities }\u003c/code\u003e → \u003ccode class=\"readme-inline-code\"\u003e{ guidance, workers[], installable[]?, latency_ms }\u003c/code\u003e: BM25 rank over the live engine catalog (at most 6 workers / 12 candidates) plus matching NOT-installed registry workers under \u003ccode class=\"readme-inline-code\"\u003einstallable\u003c/code\u003e. \u003ccode class=\"readme-inline-code\"\u003ecapabilities\u003c/code\u003e is a required list of one to six non-empty unmet external capability searches. Requests to summarize provided text/content are ignored.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::pre-generate\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003einternal hook\u003c/td\u003e\n\u003ctd\u003eInjects the conditional search hint into a harness generation (at most once per turn).\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::on-functions-change\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003einternal\u003c/td\u003e\n\u003ctd\u003eRefreshes the search catalog on the engine\u0026#39;s functions-available push.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::hint-preview\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003einternal\u003c/td\u003e\n\u003ctd\u003eThe exact hint text per exposure mode, for the configuration UI.\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003eRanking pipeline:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003eCorpus\u003c/strong\u003e: the live engine catalog (boot snapshot + push refresh),\nslimmed to name + first description sentence + argument names. \u003ccode class=\"readme-inline-code\"\u003eengine::\u003c/code\u003e\nids, functions published with \u003ccode class=\"readme-inline-code\"\u003emetadata.internal\u003c/code\u003e, and the search itself\nnever participate — the worker\u0026#39;s own public \u003ccode class=\"readme-inline-code\"\u003edirectory::*\u003c/code\u003e functions are\nsearchable like any other capability.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eScoring\u003c/strong\u003e: Okapi BM25 (k1 1.2, b 0.75) with the function name indexed at\n3× weight, camelCase segmentation (\u003ccode class=\"readme-inline-code\"\u003epresignUrl\u003c/code\u003e → presign + url), a\n22-word grammatical stoplist, conservative plural folding, JSON-key\nstripping from capability text, and a two-distinct-terms minimum match.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eCapability queries\u003c/strong\u003e: each \u003ccode class=\"readme-inline-code\"\u003ecapabilities\u003c/code\u003e entry is ranked independently\nagainst its own leader and is authoritative. Include every currently unmet\nexternal capability once in the same call. Write every capability in\nEnglish, translating non-English requests while preserving proper names,\nURLs, and function ids. Requests to summarize provided text or content are\nignored. Results merge round-robin so every capability gets a candidate\nbefore any gets a rider.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ePruning\u003c/strong\u003e: coverage-aware function floor (≥50% of the leader AND full\nterm coverage or ≥85% score) drops same-worker family riders; a\nnamespace-level floor (40% of the leader) drops trailing workers.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eRegistry search\u003c/strong\u003e (\u003ccode class=\"readme-inline-code\"\u003eregistry_search\u003c/code\u003e, default on): every call also\nconsults the public workers registry in-process with the same capability\nqueries plus informative-term retries (all concurrent; verified authors\nonly). Candidates merge round-robin across search variants, returning up to\n2 workers / 6 candidates that WOULD match if installed, with \u003ccode class=\"readme-inline-code\"\u003ecompose::add\u003c/code\u003e\nguidance.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eSession memory\u003c/strong\u003e (keyed by caller-supplied OTel baggage, fail-open):\nrepeat queries omit candidates already delivered.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eThe pre-generate hook appends one \u003ccode class=\"readme-inline-code\"\u003e\u003cdiscovery_assist\u003e\u003c/code\u003e block pointing the\nmodel at \u003ccode class=\"readme-inline-code\"\u003esearch_functions\u003c/code\u003e, telling it to derive capabilities from the goal\nand current execution state and to batch selected ids through\n\u003ccode class=\"readme-inline-code\"\u003eengine::functions::info\u003c/code\u003e — at most once per turn, and only when every gate\nclears: the function is callable in the surface, no search result is in the\ncurrent task window yet, the surface spans at least \u003ccode class=\"readme-inline-code\"\u003ehint_min_workers\u003c/code\u003e distinct\nworkers, the current task (from the latest user message) has no real function\nresults yet, and it does not already name a callable function id. Measured on\n26 pre-existing e2e scenarios: an unconditional hint \u003cem\u003einduces\u003c/em\u003e redundant\ndiscovery on guided tasks (up to +110% tokens). The hook ships OFF by default\n(\u003ccode class=\"readme-inline-code\"\u003einject_hint: false\u003c/code\u003e): the harness identity prompt already teaches\n\u003ccode class=\"readme-inline-code\"\u003edirectory::search_functions\u003c/code\u003e as the default discovery path, so the hint is\nfor deployments running a custom identity prompt without that doctrine. The\nhook\u0026#39;s transcript annotations (\u003ccode class=\"readme-inline-code\"\u003eorigin.directory\u003c/code\u003e) carry only coarse\noutcome/reason and counts.\u003c/p\u003e\n\u003cp\u003eKnobs (\u003ccode class=\"readme-inline-code\"\u003einject_hint\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003ehint_min_workers\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003eregistry_search\u003c/code\u003e) live in the\n\u003ccode class=\"readme-inline-code\"\u003eiii-directory\u003c/code\u003e configuration entry and hot-apply — see Configuration.\u003c/p\u003e\n\u003ch2 id=\"custom-trigger-types\" class=\"scroll-mt-20\"\u003eCustom trigger types\u003c/h2\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eTrigger type\u003c/th\u003e\n\u003cth\u003eFires when\u003c/th\u003e\n\u003cth\u003ePayload to subscribers\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::skills::on-change\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eAfter a \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::download\u003c/code\u003e that wrote at least one skill markdown file, a \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::update\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003ecreate\u003c/code\u003e, or \u003ccode class=\"readme-inline-code\"\u003edelete\u003c/code\u003e, or external (file pasted/edited/deleted directly on disk — including under \u003ccode class=\"readme-inline-code\"\u003eagents_skills_folder\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003edownload: \u003ccode class=\"readme-inline-code\"\u003e{ \"op\": \"download\", \"namespace\": \"\u003cns\u003e\", \"source\": \"repo\" | \"registry\" }\u003c/code\u003e; update/create/delete: \u003ccode class=\"readme-inline-code\"\u003e{ \"op\": \"\u003coperation\u003e\", \"namespace\": \"\u003cns\u003e\", \"id\": \"\u003cid\u003e\" }\u003c/code\u003e; external (file pasted/edited/deleted directly on disk): \u003ccode class=\"readme-inline-code\"\u003e{ \"op\": \"external\" }\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::on-change\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eAfter a \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::download\u003c/code\u003e that wrote at least one system prompt markdown file, a \u003ccode class=\"readme-inline-code\"\u003edirectory::system-prompts::update\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003ecreate\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003edelete\u003c/code\u003e, or external file change\u003c/td\u003e\n\u003ctd\u003edownload: \u003ccode class=\"readme-inline-code\"\u003e{ \"op\": \"download\", \"namespace\": \"\u003cns\u003e\", \"source\": \"repo\" | \"registry\" }\u003c/code\u003e; update/create/delete: \u003ccode class=\"readme-inline-code\"\u003e{ \"op\": \"\u003coperation\u003e\", \"name\": \"\u003cname\u003e\" }\u003c/code\u003e; external: \u003ccode class=\"readme-inline-code\"\u003e{ \"op\": \"external\" }\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::agents::on-change\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eAfter a \u003ccode class=\"readme-inline-code\"\u003edirectory::skills::download\u003c/code\u003e that wrote at least one agent profile, a \u003ccode class=\"readme-inline-code\"\u003edirectory::agents::update\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003ecreate\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003edelete\u003c/code\u003e, or external file change\u003c/td\u003e\n\u003ctd\u003edownload: \u003ccode class=\"readme-inline-code\"\u003e{ \"op\": \"download\", \"namespace\": \"\u003cns\u003e\", \"source\": \"repo\" | \"registry\" }\u003c/code\u003e; update/create/delete: \u003ccode class=\"readme-inline-code\"\u003e{ \"op\": \"\u003coperation\u003e\", \"name\": \"\u003cid\u003e\" }\u003c/code\u003e; external: \u003ccode class=\"readme-inline-code\"\u003e{ \"op\": \"external\" }\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003eDispatches are fire-and-forget (Void), so the write path doesn\u0026#39;t\nblock on downstream latency.\u003c/p\u003e\n\u003cp\u003eThe \u003ccode class=\"readme-inline-code\"\u003eexternal\u003c/code\u003e op comes from a filesystem watch over \u003ccode class=\"readme-inline-code\"\u003eskills_folder\u003c/code\u003e,\n\u003ccode class=\"readme-inline-code\"\u003elocal_skills_folder\u003c/code\u003e, and (when it already exists) the read-only\n\u003ccode class=\"readme-inline-code\"\u003eagents_skills_folder\u003c/code\u003e. It is a doorbell, not a ledger: every read re-scans\ndisk, so a missed event costs a stale open view until the next call, never\ndata. A burst coalesces into one event per kind, and this worker\u0026#39;s own writes\nare suppressed — a \u003ccode class=\"readme-inline-code\"\u003ecreate\u003c/code\u003e or \u003ccode class=\"readme-inline-code\"\u003eupdate\u003c/code\u003e sends its precise op and never an\nextra \u003ccode class=\"readme-inline-code\"\u003eexternal\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eLoop hazard for subscribers.\u003c/strong\u003e Suppression covers writes made \u003cem\u003ethrough this\nworker\u003c/em\u003e. A subscriber that reacts to \u003ccode class=\"readme-inline-code\"\u003e{ \"op\": \"external\" }\u003c/code\u003e by writing \u003ccode class=\"readme-inline-code\"\u003e.md\u003c/code\u003e\nfiles under \u003ccode class=\"readme-inline-code\"\u003eskills_folder\u003c/code\u003e by some other route — a shell or coder worker, a\nscript — is not suppressed and will re-trigger itself. Either write through\n\u003ccode class=\"readme-inline-code\"\u003edirectory::*::update\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003ecreate\u003c/code\u003e, or make the reaction idempotent and gated.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"local-development-testing\" class=\"scroll-mt-20\"\u003eLocal development \u0026amp; testing\u003c/h2\u003e\n\u003ch3 id=\"run-from-source\" class=\"scroll-mt-20\"\u003eRun from source\u003c/h3\u003e\n\u003cpre class=\"shiki vitesse-light\" style=\"background-color:#ffffff;color:#393a34\" tabindex=\"0\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# --config is an optional YAML seed (see config.yaml.example); omit it to\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# rely on the value stored in the `configuration` worker (or built-in defaults).\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#59873A\"\u003ecargo\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e run\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e --release\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e --\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e --url\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e ws://127.0.0.1:49134\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e --config\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e ./config.yaml.example\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"tests\" class=\"scroll-mt-20\"\u003eTests\u003c/h3\u003e\n\u003cpre class=\"shiki vitesse-light\" style=\"background-color:#ffffff;color:#393a34\" tabindex=\"0\"\u003e\u003ccode\u003e\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# Fast, offline — exercises the pure helpers (markdown / id validators\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# / fs source) without needing an iii engine.\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#59873A\"\u003ecargo\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e test\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e --lib\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# Full BDD suite — requires an iii engine on ws://127.0.0.1:49134\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# (or III_ENGINE_WS_URL). The git-backed download scenarios spin up\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# a local fixture repo via `git init`; the registry-backed scenarios\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# point a wiremock server at the worker's `registry_url` config.\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#59873A\"\u003ecargo\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e test\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# One feature group at a time. Available tags:\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#A0ADA0\"\u003e# @engine @read @download @download_repo @download_registry\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#59873A\"\u003ecargo\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e test\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e --test\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e bdd\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e --\u003c/span\u003e\u003cspan style=\"color:#A65E2B\"\u003e --tags\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e @download\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThe BDD harness lives under \u003ca href=\"tests/\"\u003etests/\u003c/a\u003e. Feature files mirror the\nmodules in \u003ca href=\"src/functions/\"\u003esrc/functions/\u003c/a\u003e. Step definitions under\n\u003ca href=\"tests/steps/\"\u003etests/steps/\u003c/a\u003e drive each feature through the same\n\u003ccode class=\"readme-inline-code\"\u003eiii.trigger\u003c/code\u003e path the production binary uses.\u003c/p\u003e\n"])</script><script>self.__next_f.push([1,"29:[\"$\",\"div\",null,{\"className\":\"border border-rule bg-bg\",\"children\":[[\"$\",\"div\",null,{\"className\":\"bg-panel px-3.5 py-2.5 border-b border-rule flex flex-col gap-y-1\",\"children\":[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] font-medium uppercase tracking-[0.18em] text-ink-faint\",\"children\":\"README.md\"}]}],[\"$\",\"div\",null,{\"className\":\"px-7 py-6 readme-prose font-mono\",\"dangerouslySetInnerHTML\":{\"__html\":\"$2c\"}}]]}]\n"])</script></body></html>