skip to content
$worker

iii-directory

v1.2.20

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,916 installs25 in 7d1 today
install
$iii trigger compose::add worker=iii-directory@1.2.20
  • macOS: arm64
  • Linux: arm64 · armv7 · x64
  • Windows: arm64 · x64

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>, preloaded <code class="readme-inline-code">skills</code> and <code class="readme-inline-code">functions</code> (bodies and contracts the harness freezes into every session's prompt), 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> <p>For container settings, fetch <code class="readme-inline-code">compose::schema { function_id: "compose::add" }</code> and use its <code class="readme-inline-code">workers</code> list. For example, after registering the completion wake described below:</p> <pre class="shiki vitesse-light" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span style="color:#999999">{</span></span> <span class="line"><span style="color:#99841877"> "</span><span style="color:#998418">operation_id</span><span style="color:#99841877">"</span><span style="color:#999999">:</span><span style="color:#B5695977"> "</span><span style="color:#B56959"><operation-id></span><span style="color:#B5695977">"</span><span style="color:#999999">,</span></span> <span class="line"><span style="color:#99841877"> "</span><span style="color:#998418">workers</span><span style="color:#99841877">"</span><span style="color:#999999">:</span><span style="color:#999999"> [</span></span> <span class="line"><span style="color:#B5695977"> "</span><span style="color:#B56959">state</span><span style="color:#B5695977">"</span><span style="color:#999999">,</span></span> <span class="line"><span style="color:#999999"> {</span></span> <span class="line"><span style="color:#99841877"> "</span><span style="color:#998418">worker</span><span style="color:#99841877">"</span><span style="color:#999999">:</span><span style="color:#B5695977"> "</span><span style="color:#B56959">iii-directory</span><span style="color:#B5695977">"</span><span style="color:#999999">,</span></span> <span class="line"><span style="color:#99841877"> "</span><span style="color:#998418">start_after</span><span style="color:#99841877">"</span><span style="color:#999999">:</span><span style="color:#999999"> [</span><span style="color:#B5695977">"</span><span style="color:#B56959">state</span><span style="color:#B5695977">"</span><span style="color:#999999">],</span></span> <span class="line"><span style="color:#99841877"> "</span><span style="color:#998418">config_override</span><span style="color:#99841877">"</span><span style="color:#999999">:</span><span style="color:#999999"> {</span><span style="color:#99841877"> "</span><span style="color:#998418">registry_search</span><span style="color:#99841877">"</span><span style="color:#999999">:</span><span style="color:#1E754F"> true</span><span style="color:#999999"> }</span></span> <span class="line"><span style="color:#999999"> }</span></span> <span class="line"><span style="color:#999999"> ]</span></span> <span class="line"><span style="color:#999999">}</span></span></code></pre><p>The list can mix worker names and objects. Each object accepts <code class="readme-inline-code">scripts</code>, <code class="readme-inline-code">config_name</code>, <code class="readme-inline-code">config_override</code>, <code class="readme-inline-code">working_dir</code>, <code class="readme-inline-code">environment</code>, <code class="readme-inline-code">env_file</code>, <code class="readme-inline-code">startup_timeout</code>, and package <code class="readme-inline-code">version</code> as well as <code class="readme-inline-code">worker</code> and <code class="readme-inline-code">start_after</code>. <code class="readme-inline-code">scripts.run</code> is for local workers only. Supplied maps replace the whole field; omitted settings are retained.</p> <p>The returned <code class="readme-inline-code">install.payload</code> from function search is a minimal shorthand. If the worker needs settings, replace its singular <code class="readme-inline-code">worker</code> with an object in <code class="readme-inline-code">workers</code>. Register a one-shot <code class="readme-inline-code">compose-operation</code> wake before calling <code class="readme-inline-code">compose::add</code>, use the same <code class="readme-inline-code">operation_id</code> in both calls, and wait for terminal success before using the new functions. An acceptance response does not mean the worker is ready. See the <a href="https://github.com/iii-hq/workers/blob/main/harness/README.md#adding-workers-with-container-settings">container settings example and completion flow</a> for field behavior, path resolution, and recovery.</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 style="color:#A0ADA0"># function_search_model_path: ~/.cache/iii/all-MiniLM-L6-v2-<revision> # pinned Hybrid bundle; null disables it</span></span> <span class="line"><span style="color:#998418">function_search_model_download</span><span style="color:#999999">:</span><span style="color:#1E754F"> true</span><span style="color:#A0ADA0"> # download the pinned bundle at boot in Hybrid mode</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> <span class="line"><span style="color:#998418">function_search_mode</span><span style="color:#999999">:</span><span style="color:#B56959"> hybrid</span><span style="color:#A0ADA0"> # lexical | hybrid (default) | jev</span></span> <span class="line"><span style="color:#998418">function_search_jev_api_key</span><span style="color:#999999">:</span><span style="color:#AB5959"> null</span><span style="color:#A0ADA0"> # optional override; null/blank uses TYPESAFE_API_KEY</span></span> <span class="line"><span style="color:#998418">function_search_jev_model</span><span style="color:#999999">:</span><span style="color:#B56959"> jev-1.13.0</span><span style="color:#A0ADA0"> # non-empty TypeSafe model name</span></span> <span class="line"><span style="color:#998418">function_search_jev_timeout_ms</span><span style="color:#999999">:</span><span style="color:#2F798A"> 3000</span><span style="color:#A0ADA0"> # integer 1..30000; shared Jev deadline per public search</span></span> <span class="line"><span style="color:#998418">function_search_jev_min_relevance</span><span style="color:#999999">:</span><span style="color:#2F798A"> 0.5</span><span style="color:#A0ADA0"> # finite 0..1 inclusive; initial calibration value</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> / <code class="readme-inline-code">function_search_model_path</code> / <code class="readme-inline-code">function_search_model_download</code>) are refused with a "restart required" log; the previous configuration is kept until the worker restarts.</p> <p><code class="readme-inline-code">function_search_mode</code> and all <code class="readme-inline-code">function_search_jev_*</code> options hot-reload, including <code class="readme-inline-code">function_search_jev_api_key</code>. A configured key takes precedence over <code class="readme-inline-code">TYPESAFE_API_KEY</code> captured from the <strong>iii-directory worker process environment at boot</strong>. Missing, null or blank keys restore that environment fallback. Changes apply to new searches; searches in progress keep their original key. Changing the environment variable itself still requires restarting the worker.</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 declare preloaded functions.</strong> <code class="readme-inline-code">functions:</code> lists engine function ids (<code class="readme-inline-code">coder::tree</code>, <code class="readme-inline-code">coder::search</code>, …) the profile uses routinely. The harness resolves their contracts once, when a session starts as this profile, and freezes them into the system prompt as a <code class="readme-inline-code"><preloaded_functions></code> block (id, description, compacted request schema), so the model calls them on the first step instead of spending a <code class="readme-inline-code">directory::search_functions</code> + <code class="readme-inline-code">engine::functions::info</code> round-trip per session; everything else still goes through discovery. Ids are stored verbatim (non-empty, no whitespace; duplicates collapse, order kept); <code class="readme-inline-code">get</code> reports ids the engine does not currently know in <code class="readme-inline-code">unknown_functions</code> (a warning — the harness renders them as unavailable), <code class="readme-inline-code">list</code> carries <code class="readme-inline-code">function_count</code>. <code class="readme-inline-code">directory::agents::functions::add</code> / <code class="readme-inline-code">::remove { id, functions }</code> edit only that frontmatter field — the rest of the file stays byte-identical — and fan out <code class="readme-inline-code">on-change</code> as an update. The console's profile editor picks them from the live registry with the same keyboard-first search + Selected/Available lists as skills.</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">model</code> and <code class="readme-inline-code">reasoning_effort</code> fall back to the nearest ancestor that sets them when omitted, while <code class="readme-inline-code">skills</code> and <code class="readme-inline-code">functions</code> inherit ADDITIVELY (the union of the chain's lists, root first, no duplicates — a child adds to what its parents allow / preload, it cannot remove); <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> <tr> <td><code class="readme-inline-code">directory::agents::functions::add</code></td> <td><code class="readme-inline-code">{ id, functions: ["coder::tree", …] }</code> — append engine function ids to one EXISTING profile's OWN <code class="readme-inline-code">functions:</code> list (its <em>preloaded</em> functions: the contracts the harness pre-loads into the system prompt of every new session running as the profile). Ids already present are kept once; only that frontmatter field is rewritten (block style), every other byte of the file is untouched; writes atomically, copy-on-writes a bundled profile's shadow, fans out <code class="readme-inline-code">on-change</code> with <code class="readme-inline-code">op: "update"</code>. Returns <code class="readme-inline-code">{ id, functions, added, unchanged?, bytes, modified_at }</code> — <code class="readme-inline-code">unchanged: true</code> means nothing was written. <code class="readme-inline-code">D416</code> for a request with no valid ids (entries must be non-empty and whitespace-free).</td> </tr> <tr> <td><code class="readme-inline-code">directory::agents::functions::remove</code></td> <td><code class="readme-inline-code">{ id, functions }</code> — drop ids from one EXISTING profile's OWN <code class="readme-inline-code">functions:</code> list (absent ids are ignored; the field disappears when the list empties). Same write semantics and <code class="readme-inline-code">D416</code>; returns <code class="readme-inline-code">{ id, functions, removed, unchanged?, bytes, modified_at }</code>. Neither verb touches ids inherited through <code class="readme-inline-code">extends</code> — those stay in the resolved union and are removed on the parent that declares them.</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>Pre-install card 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, api_reference, skills_tree, readme? }</code>. The card keeps public function/trigger names and descriptions only: request/response schemas, metadata, internal and search-excluded functions are dropped (browser's schemas alone ran 65 KB; the contract is <code class="readme-inline-code">engine::functions::info</code> after installing), and <code class="readme-inline-code">readme</code> (10–25 KB) is included only with <code class="readme-inline-code">readme: true</code>. The full record stays cached in-process for <code class="readme-inline-code">directory::search_functions</code>. 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 function search over the live engine catalog (hybrid by default: BM25 fused with the local MiniLM model, reranked). Set <code class="readme-inline-code">function_search_mode: lexical</code> for BM25 only, or <code class="readme-inline-code">jev</code> for remote relevance evaluation through TypeSafe with Hybrid, then Lexical fallback. 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>: rank with the configured mode over the live engine catalog in batches of six capabilities (12 candidates per batch across at most max(6, 2 × capabilities) workers, up to 3 batches) 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 non-empty unmet external capability searches (one to six is the norm); entries past the 18th are not searched and are named in <code class="readme-inline-code">guidance</code>. 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>Lexical/Hybrid 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 private workers registry in-process with the same capability queries plus informative-term retries (all concurrent; every listed worker is a candidate — the registry is team-authored). Candidates merge round-robin across search variants; their API references are pooled and ranked per capability with the configured mode. Hybrid fuses BM25 with the MiniLM dense lane (same 0.30 admission floor as the installed catalog), so a capability sharing no vocabulary with a contract ("retrieve web news articles" → <code class="readme-inline-code">web::fetch</code>) still surfaces. Returns up to 2 workers / 6 candidates per batch of six capabilities (so up to 6 workers / 18 candidates across three batches; a worker two batches both surface keeps one entry with its functions merged) 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> <h3 id="jev-mode" class="scroll-mt-20">Jev mode</h3> <p>Enter your TypeSafe key in <strong>Jev API key</strong> in the console's Function search settings, or set <code class="readme-inline-code">function_search_jev_api_key</code> in the <code class="readme-inline-code">iii-directory</code> configuration. The console masks this field; its value is persisted by the configuration service and omitted from the worker's configuration debug output.</p> <p>Alternatively, leave the field unset and provide <code class="readme-inline-code">TYPESAFE_API_KEY</code> through the worker service or container environment before starting <code class="readme-inline-code">iii-directory</code>. The configured key takes precedence. Clearing it (or setting null/blank) restores the environment key without a restart. If neither is available, search falls back to Hybrid, then Lexical if the local model is unavailable. A rejected configured key uses the same fallback chain; it does not retry with the environment credential.</p> <p>Select <strong>Jev</strong> in the console's Function search settings, or set:</p> <pre class="shiki vitesse-light" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span style="color:#998418">function_search_mode</span><span style="color:#999999">:</span><span style="color:#B56959"> jev</span></span> <span class="line"><span style="color:#998418">function_search_jev_api_key</span><span style="color:#999999">:</span><span style="color:#AB5959"> null</span><span style="color:#A0ADA0"> # set your key here or in the masked console field</span></span> <span class="line"><span style="color:#998418">function_search_jev_model</span><span style="color:#999999">:</span><span style="color:#B56959"> jev-1.13.0</span></span> <span class="line"><span style="color:#998418">function_search_jev_timeout_ms</span><span style="color:#999999">:</span><span style="color:#2F798A"> 3000</span></span> <span class="line"><span style="color:#998418">function_search_jev_min_relevance</span><span style="color:#999999">:</span><span style="color:#2F798A"> 0.5</span></span></code></pre><p>These fields apply without a restart. The model must be a non-empty string, the timeout an integer from 1 to 30000 ms, and relevance a finite number from 0 to 1 inclusive. YAML seeds and JSON configuration updates use the same validation. The relevance default is a starting point for calibration, not a measured quality guarantee.</p> <p>Jev evaluates eligible installed functions across the catalog, without a BM25 shortlist or a MiniLM dependency. It sends normalized capabilities, function IDs, short descriptions and parameter names to TypeSafe; it does not send conversation history or function argument values. Exact eligible IDs, internal-function exclusions, session deduplication and result limits remain enforced locally. <code class="readme-inline-code">function_search_model_path: null</code> is valid in Jev mode and disables the Hybrid fallback. With a configured path, Jev prepares an installed MiniLM bundle and keeps its catalog index current in the background so Hybrid can take over on failure. Successful Jev responses do not run local query inference. Jev does not download a missing bundle; automatic boot-time downloads remain tied to Hybrid mode.</p> <p>Registry discovery still starts with the registry API's lexical search. Jev evaluates the returned contract pool and <strong>cannot recover workers that upstream search did not return</strong>. Installable results remain suggestions until installation.</p> <p>A valid response with no functions at or above the relevance threshold stays empty. Missing credentials, timeouts, HTTP failures and invalid/incomplete service responses instead trigger <strong>Jev → Hybrid → Lexical</strong> fallback for the affected batch or registry pool. Hybrid uses the existing local ranking policy; if the model is disabled, missing, not yet indexed for the current catalog, or fails, Lexical serves the results. A registry HTTP failure still omits the installable section.</p> <p>The Jev deadline is shared across all batches in one public search, including waiting for a request slot and reading responses. Local Hybrid fallback and registry HTTP requests run outside this budget, so total search latency may exceed the Jev deadline. Requests use up to 16 functions × 6 capabilities per block and at most four concurrent requests per client; payloads are split at the local byte limits (48 KiB total JSON and 16 KiB for state plus the largest question). These byte guards are not token counts. Cost and latency grow with catalog size and capability count. Use the <a href="examples/benchmark_jev_search.rs">opt-in benchmark</a> and returned token-usage telemetry to measure your workload; this configuration change supplies no measured remote quality, latency or cost result.</p> <p>Switch back to <code class="readme-inline-code">lexical</code> at any time to use BM25 only. Switching from <code class="readme-inline-code">lexical</code> to <code class="readme-inline-code">hybrid</code> or <code class="readme-inline-code">jev</code> prepares the local index from the current catalog. If the MiniLM bundle is missing, Hybrid uses lexical fallback; its boot-time download and changes to the local model path require a worker restart. Only Hybrid shows the local-model warning.</p> <h3 id="pre-generate-hint" class="scroll-mt-20">Pre-generate hint</h3> <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> <p>On targets with a pinned static ONNX Runtime (Linux glibc x86_64/aarch64, Apple Silicon macOS, Windows MSVC) every build links it and MiniLM retrieval and reranking are compiled in. With no <code class="readme-inline-code">ORT_LIB_PATH</code>, <code class="readme-inline-code">ort-sys</code> downloads the runtime for the build target at build time (SHA-256-verified). For offline or cached x86_64 Linux builds, provision it once and export the path it prints:</p> <pre class="shiki vitesse-light" style="background-color:#ffffff;color:#393a34" tabindex="0"><code><span class="line"><span style="color:#AB5959">export</span><span style="color:#B07D48"> ORT_LIB_PATH</span><span style="color:#999999">=</span><span style="color:#B5695977">"</span><span style="color:#999999">$(</span><span style="color:#59873A">scripts/provision-onnxruntime.sh</span><span style="color:#999999">)</span><span style="color:#B5695977">"</span><span style="color:#A0ADA0"> # idempotent, SHA-256 verified</span></span> <span class="line"><span style="color:#AB5959">export</span><span style="color:#B07D48"> ORT_PREFER_DYNAMIC_LINK</span><span style="color:#999999">=</span><span style="color:#2F798A">0</span></span></code></pre><p>Other targets (musl, armv7, Intel macOS) build the BM25-only worker and need nothing extra.</p> <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.20</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">31</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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#fn-directory::agents::functions::add">directory::agents::functions::add</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&version=1.2.20#fn-directory::agents::functions::remove">directory::agents::functions::remove</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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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&version=1.2.20#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,790 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.8k</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_9t6FPAnCmMznQGkwHNaKPyukAiRA" 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_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\"],\"SiteHeader\"]\n5:I[90280,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\"],\"default\"]\n6:I[69616,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\"],\"default\"]\n7:I[46610,[\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0.o_9ma339h6h.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\"],\"\"]\ne:I[50609,[\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/02eqejg_b4k2y.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\"],\"default\"]\n11:I[41074,[\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0.o_9ma339h6h.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\"],\"default\"]\n13:I[51557,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\"],\"OutletBoundary\"]\n14:\"$Sreact.suspense\"\n17:I[51557,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\"],\"ViewportBoundary\"]\n19:I[51557,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\"],\"MetadataBoundary\"]\n:HL[\"/_next/static/chunks/10tws~ys5_0-j.css?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"style\"]\n:HL[\"/_next/static/media/387ee14c0e0fe675-s.p.16njqniuj6huf.woff2?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"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?version=1.2.20\"],\"q\":\"?version=1.2.20\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"workers\",{\"children\":[[\"slug\",\"iii-directory\",\"d\",null],{\"children\":[\"__PAGE__?{\\\"version\\\":\\\"1.2.20\\\"}\",{}]}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/10tws~ys5_0-j.css?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"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]\"}]]}]}],\"$undefined\",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_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"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/10tws~ys5_0-j.css?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"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,"1b:I[18418,[\"/_next/static/chunks/04ylibgf-0e6d.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0.vqct1a~k736.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\"],\"IconMark\"]\n4:[\"$\",\"a\",null,{\"href\":\"https://github.com/iii-hq/iii\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"aria-label\":\"iii-hq/iii on GitHub — 18,790 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.8k\"}]]}]\n10:[\"$\",\"a\",null,{\"href\":\"https://github.com/iii-hq/iii\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"aria-label\":\"iii-hq/iii on GitHub — 18,790 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.8k\"}]]}]\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_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0.o_9ma339h6h.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\"],\"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.20\\\",\\\"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\"}],\"$undefined\",[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] uppercase tracking-[0.06em] text-ink-ghost tabular-nums\",\"children\":\"v1.2.20\"}]]}],[\"$\",\"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,916\"}],\" installs\"]}],[[\"$\",\"span\",null,{\"aria-hidden\":true,\"className\":\"text-rule\",\"children\":\"/\"}],[\"$\",\"span\",null,{\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink\",\"children\":\"25\"}],\" in 7d\"]}]],[[\"$\",\"span\",null,{\"aria-hidden\":true,\"className\":\"text-rule\",\"children\":\"/\"}],[\"$\",\"span\",null,{\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ink\",\"children\":\"1\"}],\" \",\"today\"]}]]]}]]}],[\"$\",\"$L1c\",null,{\"workerName\":\"iii-directory\",\"version\":\"1.2.20\"}],[\"$\",\"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_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0.o_9ma339h6h.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\"],\"Image\"]\n28:I[84938,[\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0.o_9ma339h6h.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\"],\"PageTabs\"]\n2a:I[42794,[\"/_next/static/chunks/0ksmnd8nff8...js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0c0r_-py6v_70.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\",\"/_next/static/chunks/0.o_9ma339h6h.js?dpl=dpl_9t6FPAnCmMznQGkwHNaKPyukAiRA\"],\"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\",\"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\"}]]}],[\"$\",\"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\",\"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\"}]]}]]}]\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?version=1.2.20\u0026tab=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\":\"31\"}],[\"$\",\"span\",null,{\"className\":\"uppercase tracking-[0.06em] text-[11px]\",\"children\":\"functions\"}]]}],[\"$\",\"$L7\",null,{\"href\":\"/workers/iii-directory?version=1.2.20\u0026tab=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?version=1.2.20\u0026tab=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\":\"5\"}],[\"$\",\"span\",null,{\"className\":\"uppercase tracking-[0.06em] text-[11px]\",\"children\":\"skills\"}]]}],[\"$\",\"$L7\",null,{\"href\":\"/workers/iii-directory?version=1.2.20\u0026tab=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?version=1.2.20\u0026tab=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.20\"}],[\"$\",\"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\":\"1.2.20\"}],[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?version=1.2.20\",\"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.20\"}]]}],[\"$\",\"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\"}]]}],null,[\"$\",\"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\":\"1.2.20\",\"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::functions::add\",\"anchor\":\"fn-directory::agents::functions::add\"},{\"name\":\"directory::agents::functions::remove\",\"anchor\":\"fn-directory::agents::functions::remove\"},{\"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:T154e5,"])</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, preloaded \u003ccode class=\"readme-inline-code\"\u003eskills\u003c/code\u003e and \u003ccode class=\"readme-inline-code\"\u003efunctions\u003c/code\u003e (bodies and contracts the harness freezes into every session\u0026#39;s prompt), 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\u003cp\u003eFor container settings, fetch \u003ccode class=\"readme-inline-code\"\u003ecompose::schema { function_id: \"compose::add\" }\u003c/code\u003e and use\nits \u003ccode class=\"readme-inline-code\"\u003eworkers\u003c/code\u003e list. For example, after registering the completion wake described below:\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:#999999\"\u003e{\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#99841877\"\u003e \"\u003c/span\u003e\u003cspan style=\"color:#998418\"\u003eoperation_id\u003c/span\u003e\u003cspan style=\"color:#99841877\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e \"\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e\u0026#x3C;operation-id\u003e\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#99841877\"\u003e \"\u003c/span\u003e\u003cspan style=\"color:#998418\"\u003eworkers\u003c/span\u003e\u003cspan style=\"color:#99841877\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e [\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#B5695977\"\u003e \"\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003estate\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#999999\"\u003e {\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#99841877\"\u003e \"\u003c/span\u003e\u003cspan style=\"color:#998418\"\u003eworker\u003c/span\u003e\u003cspan style=\"color:#99841877\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e \"\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003eiii-directory\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e,\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#99841877\"\u003e \"\u003c/span\u003e\u003cspan style=\"color:#998418\"\u003estart_after\u003c/span\u003e\u003cspan style=\"color:#99841877\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e [\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003estate\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e],\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#99841877\"\u003e \"\u003c/span\u003e\u003cspan style=\"color:#998418\"\u003econfig_override\u003c/span\u003e\u003cspan style=\"color:#99841877\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e {\u003c/span\u003e\u003cspan style=\"color:#99841877\"\u003e \"\u003c/span\u003e\u003cspan style=\"color:#998418\"\u003eregistry_search\u003c/span\u003e\u003cspan style=\"color:#99841877\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#1E754F\"\u003e true\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e }\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#999999\"\u003e }\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#999999\"\u003e ]\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#999999\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThe list can mix worker names and objects. Each object accepts \u003ccode class=\"readme-inline-code\"\u003escripts\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003econfig_name\u003c/code\u003e,\n\u003ccode class=\"readme-inline-code\"\u003econfig_override\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003eworking_dir\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003eenvironment\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003eenv_file\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003estartup_timeout\u003c/code\u003e, and\npackage \u003ccode class=\"readme-inline-code\"\u003eversion\u003c/code\u003e as well as \u003ccode class=\"readme-inline-code\"\u003eworker\u003c/code\u003e and \u003ccode class=\"readme-inline-code\"\u003estart_after\u003c/code\u003e. \u003ccode class=\"readme-inline-code\"\u003escripts.run\u003c/code\u003e is for local\nworkers only. Supplied maps replace the whole field; omitted settings are retained.\u003c/p\u003e\n\u003cp\u003eThe returned \u003ccode class=\"readme-inline-code\"\u003einstall.payload\u003c/code\u003e from function search is a minimal shorthand. If the worker\nneeds settings, replace its singular \u003ccode class=\"readme-inline-code\"\u003eworker\u003c/code\u003e with an object in \u003ccode class=\"readme-inline-code\"\u003eworkers\u003c/code\u003e.\nRegister a one-shot \u003ccode class=\"readme-inline-code\"\u003ecompose-operation\u003c/code\u003e wake before calling \u003ccode class=\"readme-inline-code\"\u003ecompose::add\u003c/code\u003e, use the same\n\u003ccode class=\"readme-inline-code\"\u003eoperation_id\u003c/code\u003e in both calls, and wait for terminal success before using the new functions.\nAn acceptance response does not mean the worker is ready. See the\n\u003ca href=\"https://github.com/iii-hq/workers/blob/main/harness/README.md#adding-workers-with-container-settings\"\u003econtainer settings example and completion flow\u003c/a\u003e\nfor field behavior, path resolution, and recovery.\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\u003cspan style=\"color:#A0ADA0\"\u003e# function_search_model_path: ~/.cache/iii/all-MiniLM-L6-v2-\u0026#x3C;revision\u003e # pinned Hybrid bundle; null disables it\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003efunction_search_model_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 # download the pinned bundle at boot in Hybrid mode\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\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003efunction_search_mode\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e hybrid\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # lexical | hybrid (default) | jev\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003efunction_search_jev_api_key\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#AB5959\"\u003e null\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # optional override; null/blank uses TYPESAFE_API_KEY\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003efunction_search_jev_model\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e jev-1.13.0\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # non-empty TypeSafe model name\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003efunction_search_jev_timeout_ms\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#2F798A\"\u003e 3000\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # integer 1..30000; shared Jev deadline per public search\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003efunction_search_jev_min_relevance\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#2F798A\"\u003e 0.5\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # finite 0..1 inclusive; initial calibration value\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 /\n\u003ccode class=\"readme-inline-code\"\u003efunction_search_model_path\u003c/code\u003e / \u003ccode class=\"readme-inline-code\"\u003efunction_search_model_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\u003e\u003ccode class=\"readme-inline-code\"\u003efunction_search_mode\u003c/code\u003e and all \u003ccode class=\"readme-inline-code\"\u003efunction_search_jev_*\u003c/code\u003e options hot-reload,\nincluding \u003ccode class=\"readme-inline-code\"\u003efunction_search_jev_api_key\u003c/code\u003e. A configured key takes precedence over\n\u003ccode class=\"readme-inline-code\"\u003eTYPESAFE_API_KEY\u003c/code\u003e captured from the \u003cstrong\u003eiii-directory worker process environment\nat boot\u003c/strong\u003e. Missing, null or blank keys restore that environment fallback.\nChanges apply to new searches; searches in progress keep their original key.\nChanging the environment variable itself still requires restarting the worker.\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 declare preloaded functions.\u003c/strong\u003e \u003ccode class=\"readme-inline-code\"\u003efunctions:\u003c/code\u003e lists engine\nfunction ids (\u003ccode class=\"readme-inline-code\"\u003ecoder::tree\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003ecoder::search\u003c/code\u003e, …) the profile uses\nroutinely. The harness resolves their contracts once, when a session\nstarts as this profile, and freezes them into the system prompt as a\n\u003ccode class=\"readme-inline-code\"\u003e\u003cpreloaded_functions\u003e\u003c/code\u003e block (id, description, compacted request schema), so\nthe model calls them on the first step instead of spending a\n\u003ccode class=\"readme-inline-code\"\u003edirectory::search_functions\u003c/code\u003e + \u003ccode class=\"readme-inline-code\"\u003eengine::functions::info\u003c/code\u003e round-trip per\nsession; everything else still goes through discovery. Ids are stored\nverbatim (non-empty, no whitespace; duplicates collapse, order kept);\n\u003ccode class=\"readme-inline-code\"\u003eget\u003c/code\u003e reports ids the engine does not currently know in\n\u003ccode class=\"readme-inline-code\"\u003eunknown_functions\u003c/code\u003e (a warning — the harness renders them as unavailable),\n\u003ccode class=\"readme-inline-code\"\u003elist\u003c/code\u003e carries \u003ccode class=\"readme-inline-code\"\u003efunction_count\u003c/code\u003e. \u003ccode class=\"readme-inline-code\"\u003edirectory::agents::functions::add\u003c/code\u003e /\n\u003ccode class=\"readme-inline-code\"\u003e::remove { id, functions }\u003c/code\u003e edit only that frontmatter field — the rest\nof the file stays byte-identical — and fan out \u003ccode class=\"readme-inline-code\"\u003eon-change\u003c/code\u003e as an update.\nThe console\u0026#39;s profile editor picks them from the live registry with the\nsame keyboard-first search + Selected/Available lists as skills.\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\"\u003emodel\u003c/code\u003e and\n\u003ccode class=\"readme-inline-code\"\u003ereasoning_effort\u003c/code\u003e fall back to the nearest ancestor that sets them when\nomitted, while \u003ccode class=\"readme-inline-code\"\u003eskills\u003c/code\u003e and \u003ccode class=\"readme-inline-code\"\u003efunctions\u003c/code\u003e inherit ADDITIVELY (the union of\nthe chain\u0026#39;s lists, root first, no duplicates — a child adds to what its\nparents allow / preload, it cannot remove); \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,\n\u003ccode class=\"readme-inline-code\"\u003eicon\u003c/code\u003e and \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\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::agents::functions::add\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003e{ id, functions: [\"coder::tree\", …] }\u003c/code\u003e — append engine function ids to one EXISTING profile\u0026#39;s OWN \u003ccode class=\"readme-inline-code\"\u003efunctions:\u003c/code\u003e list (its \u003cem\u003epreloaded\u003c/em\u003e functions: the contracts the harness pre-loads into the system prompt of every new session running as the profile). Ids already present are kept once; only that frontmatter field is rewritten (block style), every other byte of the file is untouched; writes atomically, copy-on-writes a bundled profile\u0026#39;s shadow, fans out \u003ccode class=\"readme-inline-code\"\u003eon-change\u003c/code\u003e with \u003ccode class=\"readme-inline-code\"\u003eop: \"update\"\u003c/code\u003e. Returns \u003ccode class=\"readme-inline-code\"\u003e{ id, functions, added, unchanged?, bytes, modified_at }\u003c/code\u003e — \u003ccode class=\"readme-inline-code\"\u003eunchanged: true\u003c/code\u003e means nothing was written. \u003ccode class=\"readme-inline-code\"\u003eD416\u003c/code\u003e for a request with no valid ids (entries must be non-empty and whitespace-free).\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003edirectory::agents::functions::remove\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"readme-inline-code\"\u003e{ id, functions }\u003c/code\u003e — drop ids from one EXISTING profile\u0026#39;s OWN \u003ccode class=\"readme-inline-code\"\u003efunctions:\u003c/code\u003e list (absent ids are ignored; the field disappears when the list empties). Same write semantics and \u003ccode class=\"readme-inline-code\"\u003eD416\u003c/code\u003e; returns \u003ccode class=\"readme-inline-code\"\u003e{ id, functions, removed, unchanged?, bytes, modified_at }\u003c/code\u003e. Neither verb touches ids inherited through \u003ccode class=\"readme-inline-code\"\u003eextends\u003c/code\u003e — those stay in the resolved union and are removed on the parent that declares them.\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\u003ePre-install card 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, api_reference, skills_tree, readme? }\u003c/code\u003e. The card keeps public function/trigger names and descriptions only: request/response schemas, metadata, internal and search-excluded functions are dropped (browser\u0026#39;s schemas alone ran 65 KB; the contract is \u003ccode class=\"readme-inline-code\"\u003eengine::functions::info\u003c/code\u003e after installing), and \u003ccode class=\"readme-inline-code\"\u003ereadme\u003c/code\u003e (10–25 KB) is included only with \u003ccode class=\"readme-inline-code\"\u003ereadme: true\u003c/code\u003e. The full record stays cached in-process for \u003ccode class=\"readme-inline-code\"\u003edirectory::search_functions\u003c/code\u003e. 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 function search over the live engine catalog (hybrid by default:\nBM25 fused with the local MiniLM model, reranked). Set \u003ccode class=\"readme-inline-code\"\u003efunction_search_mode: lexical\u003c/code\u003e for BM25 only, or \u003ccode class=\"readme-inline-code\"\u003ejev\u003c/code\u003e for remote relevance evaluation through\nTypeSafe with Hybrid, then Lexical fallback. Absorbed from the former \u003ccode class=\"readme-inline-code\"\u003ediscovery\u003c/code\u003e worker,\nit 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: rank with the configured mode over the live engine catalog in batches of six capabilities (12 candidates per batch across at most max(6, 2 × capabilities) workers, up to 3 batches) 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 non-empty unmet external capability searches (one to six is the norm); entries past the 18th are not searched and are named in \u003ccode class=\"readme-inline-code\"\u003eguidance\u003c/code\u003e. 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\u003eLexical/Hybrid ranking 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 private workers registry in-process with the same capability\nqueries plus informative-term retries (all concurrent; every listed worker\nis a candidate — the registry is team-authored). Candidates merge\nround-robin across search variants; their API references are pooled and\nranked per capability with the configured mode. Hybrid fuses BM25 with the\nMiniLM dense lane (same 0.30 admission floor as the installed catalog), so a capability sharing no\nvocabulary with a contract (\u0026quot;retrieve web news articles\u0026quot; → \u003ccode class=\"readme-inline-code\"\u003eweb::fetch\u003c/code\u003e)\nstill surfaces. Returns up to 2 workers / 6 candidates per batch of six\ncapabilities (so up to 6 workers / 18 candidates across three batches; a\nworker two batches both surface keeps one entry with its functions merged)\nthat WOULD match if installed, with \u003ccode class=\"readme-inline-code\"\u003ecompose::add\u003c/code\u003e guidance.\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\u003ch3 id=\"jev-mode\" class=\"scroll-mt-20\"\u003eJev mode\u003c/h3\u003e\n\u003cp\u003eEnter your TypeSafe key in \u003cstrong\u003eJev API key\u003c/strong\u003e in the console\u0026#39;s Function search\nsettings, or set \u003ccode class=\"readme-inline-code\"\u003efunction_search_jev_api_key\u003c/code\u003e in the \u003ccode class=\"readme-inline-code\"\u003eiii-directory\u003c/code\u003e\nconfiguration. The console masks this field; its value is persisted by the\nconfiguration service and omitted from the worker\u0026#39;s configuration debug output.\u003c/p\u003e\n\u003cp\u003eAlternatively, leave the field unset and provide \u003ccode class=\"readme-inline-code\"\u003eTYPESAFE_API_KEY\u003c/code\u003e through the\nworker service or container environment before starting \u003ccode class=\"readme-inline-code\"\u003eiii-directory\u003c/code\u003e.\nThe configured key takes precedence. Clearing it (or setting null/blank) restores\nthe environment key without a restart. If neither is available, search falls back\nto Hybrid, then Lexical if the local model is unavailable. A rejected configured\nkey uses the same fallback chain; it does not retry with the environment credential.\u003c/p\u003e\n\u003cp\u003eSelect \u003cstrong\u003eJev\u003c/strong\u003e in the console\u0026#39;s Function search settings, or set:\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:#998418\"\u003efunction_search_mode\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e jev\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003efunction_search_jev_api_key\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#AB5959\"\u003e null\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # set your key here or in the masked console field\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003efunction_search_jev_model\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#B56959\"\u003e jev-1.13.0\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003efunction_search_jev_timeout_ms\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#2F798A\"\u003e 3000\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#998418\"\u003efunction_search_jev_min_relevance\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e:\u003c/span\u003e\u003cspan style=\"color:#2F798A\"\u003e 0.5\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThese fields apply without a restart. The model must be a non-empty string,\nthe timeout an integer from 1 to 30000 ms, and relevance a finite number from 0\nto 1 inclusive. YAML seeds and JSON configuration updates use the same validation.\nThe relevance default is a starting point for calibration, not a measured quality\nguarantee.\u003c/p\u003e\n\u003cp\u003eJev evaluates eligible installed functions across the catalog, without a BM25\nshortlist or a MiniLM dependency. It sends normalized capabilities, function IDs,\nshort descriptions and parameter names to TypeSafe; it does not send conversation\nhistory or function argument values. Exact eligible IDs, internal-function\nexclusions, session deduplication and result limits remain enforced locally.\n\u003ccode class=\"readme-inline-code\"\u003efunction_search_model_path: null\u003c/code\u003e is valid in Jev mode and disables the Hybrid\nfallback. With a configured path, Jev prepares an installed MiniLM bundle and\nkeeps its catalog index current in the background so Hybrid can take over on\nfailure. Successful Jev responses do not run local query inference. Jev does not\ndownload a missing bundle; automatic boot-time downloads remain tied to Hybrid mode.\u003c/p\u003e\n\u003cp\u003eRegistry discovery still starts with the registry API\u0026#39;s lexical search. Jev\nevaluates the returned contract pool and \u003cstrong\u003ecannot recover workers that upstream\nsearch did not return\u003c/strong\u003e. Installable results remain suggestions until installation.\u003c/p\u003e\n\u003cp\u003eA valid response with no functions at or above the relevance threshold stays\nempty. Missing credentials, timeouts, HTTP failures and invalid/incomplete service\nresponses instead trigger \u003cstrong\u003eJev → Hybrid → Lexical\u003c/strong\u003e fallback for the affected\nbatch or registry pool. Hybrid uses the existing local ranking policy; if the\nmodel is disabled, missing, not yet indexed for the current catalog, or fails,\nLexical serves the results. A registry HTTP failure still omits the installable section.\u003c/p\u003e\n\u003cp\u003eThe Jev deadline is shared across all batches in one public search, including\nwaiting for a request slot and reading responses. Local Hybrid fallback and\nregistry HTTP requests run outside this budget, so total search latency may\nexceed the Jev deadline. Requests use up to\n16 functions × 6 capabilities per block and at most four concurrent requests per\nclient; payloads are split at the local byte limits (48 KiB total JSON and 16 KiB\nfor state plus the largest question). These byte guards are not token counts.\nCost and latency grow with catalog size and capability count. Use the\n\u003ca href=\"examples/benchmark_jev_search.rs\"\u003eopt-in benchmark\u003c/a\u003e and returned token-usage\ntelemetry to measure your workload; this\nconfiguration change supplies no measured remote quality, latency or cost result.\u003c/p\u003e\n\u003cp\u003eSwitch back to \u003ccode class=\"readme-inline-code\"\u003elexical\u003c/code\u003e at any time to use BM25 only. Switching from \u003ccode class=\"readme-inline-code\"\u003elexical\u003c/code\u003e\nto \u003ccode class=\"readme-inline-code\"\u003ehybrid\u003c/code\u003e or \u003ccode class=\"readme-inline-code\"\u003ejev\u003c/code\u003e prepares the local index from the current catalog. If the MiniLM bundle is\nmissing, Hybrid uses lexical fallback; its boot-time download and changes to the\nlocal model path require a worker restart. Only Hybrid shows the local-model warning.\u003c/p\u003e\n\u003ch3 id=\"pre-generate-hint\" class=\"scroll-mt-20\"\u003ePre-generate hint\u003c/h3\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\u003cp\u003eOn targets with a pinned static ONNX Runtime (Linux glibc x86_64/aarch64,\nApple Silicon macOS, Windows MSVC) every build links it and MiniLM retrieval\nand reranking are compiled in. With no \u003ccode class=\"readme-inline-code\"\u003eORT_LIB_PATH\u003c/code\u003e, \u003ccode class=\"readme-inline-code\"\u003eort-sys\u003c/code\u003e downloads the\nruntime for the build target at build time (SHA-256-verified). For offline or\ncached x86_64 Linux builds, provision it once and export the path it prints:\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:#AB5959\"\u003eexport\u003c/span\u003e\u003cspan style=\"color:#B07D48\"\u003e ORT_LIB_PATH\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e$(\u003c/span\u003e\u003cspan style=\"color:#59873A\"\u003escripts/provision-onnxruntime.sh\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e)\u003c/span\u003e\u003cspan style=\"color:#B5695977\"\u003e\"\u003c/span\u003e\u003cspan style=\"color:#A0ADA0\"\u003e # idempotent, SHA-256 verified\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"line\"\u003e\u003cspan style=\"color:#AB5959\"\u003eexport\u003c/span\u003e\u003cspan style=\"color:#B07D48\"\u003e ORT_PREFER_DYNAMIC_LINK\u003c/span\u003e\u003cspan style=\"color:#999999\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#2F798A\"\u003e0\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eOther targets (musl, armv7, Intel macOS) build the BM25-only worker and need\nnothing extra.\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:#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>