From nyxid
Builds an Aevatar agent team and its members via REST API. Creates teams, adds workflow/script/gagent members, binds implementations, and sets entry point. Requires prior workflow YAML authoring.
How this skill is triggered — by the user, by Claude, or both
Slash command
/nyxid:aevatar-team-builderThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You create a **team**, fill it with **members** (each backed by a workflow, script, or
You create a team, fill it with members (each backed by a workflow, script, or
gagent), bind their implementations, and set the team's entry member — all via REST. The
output is an invocable team. Publishing it as a NyxID service is a separate step
(aevatar-service-publisher); scheduling is another (aevatar-scheduler).
# Drive aevatar THROUGH the NyxID broker: it injects your scope_id claim AND auto-refreshes your
# token. A raw curl to the aevatar backend with ~/.nyxid/access_token resolves NO scope
# (scopeResolved:false) and the stored token expires — it is not a usable path.
# Prerequisite once: the `aevatar` service must be connected — `nyxid service add aevatar`.
# NOTE: the aevatar backend requires `Content-Type: application/json` on writes (POST/PUT) —
# omit it and every write returns HTTP 415 Unsupported Media Type. The helper sets it on
# every call (harmless on bodyless GETs), so the POST/PUT examples below work as written.
aev() { nyxid proxy request aevatar "$@" -H 'Content-Type: application/json'; } # aev "<path>" [-m POST|PUT|DELETE] [-d '<json>'] [--stream]
scopeId=$(aev "api/studio/context" | jq -r .scopeId)
jqis only for convenience — any JSON reader works (replace| jq -r .scopeIdwith| python3 -c 'import sys,json;print(json.load(sys.stdin)["scopeId"])'). All calls go through the NyxID broker (nyxid proxy request aevatar), which injects yourscope_idclaim and auto-refreshes the token. And because the create/bind calls are async and can occasionally return a transient empty body, always read the response status/JSON back — retry once on an empty body — rather than assuming success.
Member implementation kinds are the lowercase strings workflow, script,
gagent.
teamId=$(aev "api/scopes/$scopeId/teams" -m POST \
-d '{"displayName":"My Team","description":"what it does"}' | jq -r '.teamId // .id')
CreateStudioTeamRequest: displayName (required), description?, teamId? (omit to
let the server mint one). Read the returned id back — do not invent it.
Create the member as a shell. Do not pass implementationRef here — the concrete
implementation (the workflow + its YAML) is attached in Step 3. Passing a forward
workflowId that does not exist yet returns HTTP 500.
wfId="my-workflow" # the id you will bind in Step 3 (pick a stable kebab-case id)
memberId=$(aev "api/scopes/$scopeId/members" -m POST -d "{
\"displayName\": \"My Workflow Member\",
\"implementationKind\": \"workflow\",
\"teamId\": \"$teamId\"
}" | jq -r '.memberId')
CreateStudioMemberRequest: displayName + implementationKind (required,
workflow|script|gagent); description?, memberId?, teamId? (attach now, or add
later via PATCH). The new member returns at lifecycleStage:"created" and is already
assigned a publishedServiceId; its implementationRef stays null until Step 3 fills
it in. (Verified: omitting implementationRef returns 201; sending it with a not-yet-bound
workflowId returns 500.)
implementationKind
to "script" or "gagent". Discover valid gagent kinds with GET /api/scopes/gagent-types.
The concrete scriptId / agentKind is supplied in the Step 3 binding, not here.This is where the real implementation lands. It starts an async binding run.
# Author the YAML first with aevatar-workflow-authoring; pass it inline.
runId=$(aev "api/scopes/$scopeId/members/$memberId/binding" -m PUT -d "{
\"workflow\": { \"workflowId\": \"$wfId\", \"workflowYamls\": [ $(jq -Rs . < workflow.yaml) ] }
}" | jq -r '.bindingRunId') # returns {status:"accepted", bindingRunId:"bind-...", ...}
UpdateStudioMemberBindingRequest carries exactly one of:
workflow: {workflowId, workflowYamls:[<yaml strings>]}script: {scriptId, scriptRevision?}gAgent: {agentKind, endpoints?}(jq -Rs . safely JSON-encodes the YAML file as a string.)
Poll the binding run by its id until status is succeeded:
aev "api/scopes/$scopeId/members/$memberId/binding-runs/$runId" \
| jq '{status, failure}'
Status progresses accepted → admission_pending → admitted → platform_binding_pending → … → succeeded (or failed/rejected). It commonly sits at platform_binding_pending
for a minute or two before flipping to succeeded — keep polling (e.g. every 5s, up to
~3 min). On succeeded the response carries result.publishedServiceId +
result.revisionId, and the member reaches lifecycleStage:"bind_ready":
aev "api/scopes/$scopeId/members/$memberId" \
| jq '{stage:.summary.lifecycleStage, svc:.summary.publishedServiceId, ref:.implementationRef}'
Do not report success on the 2xx from the PUT alone — that is only accepted; wait for the
run to reach succeeded.
The entry member is the team's front door (what callers hit by default).
aev "api/scopes/$scopeId/teams/$teamId/entry-member" -m PUT \
-d "{\"memberId\":\"$memberId\"}"
Add more members by repeating Steps 2–3 with the same teamId. List the roster:
GET /api/scopes/$scopeId/teams/$teamId/members.
aev "api/scopes/$scopeId/teams/$teamId" | jq .
aev "api/scopes/$scopeId/teams/$teamId/members" | jq .
Confirm the team exists, the roster contains your member(s), and the entry member is set.
PATCH /api/scopes/{scopeId}/teams/{teamId} and PATCH …/members/{memberId}.PATCH …/members/{memberId} with {teamId}.POST …/teams/{teamId}/archive.aevatar-service-publisher.aevatar-scheduler.aevatar-platform-map for the full panorama.If you genuinely cannot complete a step server-side, hand the original request back to your caller rather than fabricating — see the fallback skill in this family.
npx claudepluginhub chronoaiproject/nyxid --plugin nyxidPublishes Aevatar members/teams/workflows as invocable services via NyxID registration, with REST API lifecycle management, verification, and invocation.
Creates a multi-agent team composition file with purpose definition, member selection, coordination patterns, and registry integration. Use when formalizing recurring collaborative workflows.