Use when the user wants to create or manage a Specialist agent or create, revise, publish, or delete a Skill through the conversational `/Customize` entry. Routes Skill work to the internal skill-creator and handles Specialist work through the JavaScript host.agents SDK.
66
83%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
This Skill routes conversational customization to one of two native composers. It is not a security boundary: it helps the user draft, review, confirm, and report changes, while the application decides whether a destructive or identity-affecting operation actually takes effect.
Important: this is a framework Skill, not hard isolation. Do not claim that this Skill provides hard security isolation; it is workflow guidance only.
host.skills.read('skill-creator') and follow that internal Skill completely. Do not duplicate its
authoring workflow here.Do not create a plan record for Specialist or Skill CRUD. Ask only about choices that materially change behavior, access, or safety. Skills and Specialists are application-managed resources, not Artifacts.
The Skill runs in the JavaScript control-plane REPL only. It uses JavaScript exclusively. Do not
use Python or R here, and do not look for host.agents or host.skills in a data kernel — they are
absent there. Specialist mutation happens through host.agents.*; Skill lifecycle work is delegated
to the internal Skill Creator above.
The Skill never uses the following, and you must not invent them:
host.agents through host.mcp().host.agents SDK surfaceThe SDK is name-first and lives in the trusted calling session. JavaScript methods, inputs, and returned records all use camelCase. Methods:
host.agents.list() — custom Specialist summaries for discovery and selection only.host.agents.get(name) — one existing Specialist's complete current state by immutable name
(returns stable id and revision, but you do not show those to the user).host.agents.create(input) — object form (see below).host.agents.update(name, patch) — name selects the Specialist and is immutable; use
patch.displayName to change its presentation label.host.agents.switch(nameOrNull) — switches the current conversation only; null returns to Main
Agent. Does not accept a caller-supplied session id.host.agents.delete(name, { revision }).host.agents.attachSkill(name, skillRef, { revision }) / host.agents.detachSkill(...).host.agents.attachConnector(name, connectorRef, { revision }) /
host.agents.detachConnector(...).host.agents.listSkills(nameOrId?) — complete Skill catalog, including Main-disabled Skills.host.agents.listConnectors(nameOrId?) — public Connector information; never credentials, headers,
environment values, Connector arguments, or tokens.create takes an object:
host.agents.create({
name,
displayName,
description,
systemPrompt,
iconKey,
colorKey,
enabled,
unrestricted,
skillNames,
connectorNames
})Skill/Connector references resolve an exact stable catalog id first, otherwise a unique immutable name. An
ambiguous name is rejected — tell the user to use the stable id from listSkills/listConnectors.
Errors are sanitized and prefixed host.agents.<method>:; they never contain system instructions,
credentials, headers, environment values, Connector arguments, or the RPC token.
Treat systemPrompt as the Specialist's identity override while the application's safety, tool, and
workflow rules remain in force. Lead with You are {displayName}., replacing {displayName} with
the proposed display name. State the Specialist's one focused job, what it handles, and what the
Specialist does not do. Keep the identity concise; the heavy how-to lives in Skills, not in the system
prompt. Reuse or create Skills for recurring procedures instead of copying those procedures into the
identity.
After a newly created Specialist exists and its state has been read back, offer to switch this
conversation to it with host.agents.switch(name). Do not switch unless the user accepts the offer and
the application approves the privileged operation.
Follow this order for every mutation. Do not snapshot catalog contents into a profile or session (resolution is always live):
list for discovery and selection. For an existing Specialist, call get(name)
to read its complete current state. Also call listSkills/listConnectors to read the catalogs
before proposing anything.
Resolve persisted Custom Connector UUIDs through the live Connector catalog and use each
Connector's immutable name in drafts, reviews, and mutation inputs. Never show a Connector UUID
in ordinary prose. Bundled Connector IDs already equal their names; do not invent suffixes.get(name). After delete, verify absence
with list or an expected not-found result from get(name). For switch, use binding read-back.When the user has not specified Full versus Selected, you must ask. Do not silently use the SDK's omitted-fields Full default — never assume Full access. Full is selected only after an explicit request such as "full access" or "same capabilities as Main."
Capability semantics:
create with neither skillNames nor connectorNames → Full access. But only use this after the
user explicitly chose Full.create → Selected; an omitted other array becomes empty.update({ unrestricted: true }) → Full, preserving the stored Selected configuration.skillNames or connectorNames to update exactly replaces the supplied collection and
switches to Selected; an omitted collection is preserved.attachSkill/detachSkill and attachConnector/detachConnector mutate the current mode without
changing it (Selected: add/remove an inclusion;
Full: remove/add an exclusion).For create and non-name update, show the complete target state and wait for the user's explicit confirmation before executing. The review must show:
For an update, also identify the changed fields.
For multi-field capability edits, prefer one atomic update over a loop of attach/detach calls
that could partially succeed. Use attachSkill/detachSkill or
attachConnector/detachConnector only for a single incremental collection move.
/customize
entry and the composer prefill are not confirmation. name is immutable; displayName is an
ordinary update field. The whole patch is applied atomically, and a stale revision fails without
merge or retry.When you describe one of these privileged actions, explain:
Carry the reviewed revision into update, delete, and the attach/detach methods. A stale revision
fails without merge or retry. When it fails, re-read, rebuild the complete draft, and ask for
confirmation again. A changed draft also invalidates the user's earlier confirmation — re-review after
the user edits the draft. Do not automatically retry declined or stale privileged operations.
A declined operation is a normal result, for example { status: "declined", operation: "switch" }.
Report it as a user decision and stop. Do not retry it.
get(name) and report the actual state. Never assume
success from the call alone.switch, report that approval lets the current control tool finish, then automatically
continues the same task under the approved target. A decline leaves the current Agent unchanged.
The binding survives app restart.delete, report that existing conversations bound to the deleted Specialist become
unavailable — they are not switched to Main Agent; the user must explicitly choose another
Specialist or Main Agent. Verify deletion with list or an expected not-found get(name) result.Returned records include stable id and revision, but do not show them to the user unless needed to
resolve ambiguity (for example, an ambiguous catalog name where you must ask for the stable id) or to
explain a revision conflict. Ordinary reporting uses names and the reviewed state only.
Respond naturally in the conversation's language. This document and the fixed user-facing review/card copy remain English.
bf35648
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.