From nyxid
Publishes Aevatar members/teams/workflows as invocable services via NyxID registration, with REST API lifecycle management, verification, and invocation.
How this skill is triggered — by the user, by Claude, or both
Slash command
/nyxid:aevatar-service-publisherThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You turn a member / team / workflow into an **invocable service** and verify whether it is
You turn a member / team / workflow into an invocable service and verify whether it is
registered with NyxID as a brokered connector. Build the artifact first
(aevatar-team-builder). Then pick the path that matches what you have.
# 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 your scope_id claim and auto-refreshes the token, so you never touch the aevatar backend or a stored token directly. On the streaming:streaminvoke, the SSEdata:frames interleave lifecycle frames (stepStarted/stepFinished/runFinished/stateSnapshot/usage, keyed by a top-level field) with raw observation frames (custom.name: aevatar.raw.observed) that carry the step output text — there is no flattypefield, so parse for those keys, notobj.type.
Registration to NyxID is automatic but host-gated. When a service deployment becomes active, the platform reconciles it to NyxID — only if the host has external exposure enabled and the service is in scope of that policy. You can drive publish + activation and read the result, but you cannot turn host exposure on from the client. So always verify (below) and report honestly: if no NyxID slug appears, the service is still usable in-scope, it just is not a NyxID-brokered connector.
A bound member already has a published service — binding it was the publish. The
published-service endpoint only returns ids; the real detail (endpoints, readiness,
NyxID exposure) lives in the scope services list:
# minimal: publishedServiceId + key
aev "api/scopes/$scopeId/members/$memberId/published-service" | jq .
# full: identity, endpoints, serving revision, invokeReady, externalExposure
aev "api/scopes/$scopeId/services" \
| jq '.[] | select(.serviceId=="member-'"$memberId"'")
| {serviceId, defaultServingRevisionId, invokeReady, invokeReadinessStatus,
endpoints: [.endpoints[] | {endpointId, requestTypeUrl}], externalExposure}'
A workflow member exposes endpoint chat (type.googleapis.com/aevatar.ai.ChatRequestEvent)
and reports invokeReady:true once serving. Then jump to Verify and Invoke.
The fastest way to expose a single workflow/script/gagent as a service for your scope:
aev "api/scopes/$scopeId/binding" -m PUT -d "{
\"implementationKind\": \"workflow\",
\"displayName\": \"My Service\",
\"serviceId\": \"my-service\",
\"workflow\": { \"workflowId\": \"my-workflow\", \"workflowYamls\": [ $(jq -Rs . < workflow.yaml) ] }
}"
UpsertScopeBindingHttpRequest: implementationKind (required, workflow|script|gagent)
plus the matching typed block (workflow / script / gAgent), displayName?,
serviceId?, appId?, revisionId?. List your scope services and read exposure:
aev "api/scopes/$scopeId/services" | jq '.[] | {serviceId, displayName, externalExposure}'
For a standalone, independently versioned service with staged rollout. Identity is the
4-tuple tenantId / appId / namespace / serviceId (reuse it on every call).
# 1. Create the service shell + its endpoint contract(s)
aev "api/services" -m POST -d '{
"tenantId":"<t>","appId":"<a>","namespace":"<ns>","serviceId":"my-service",
"displayName":"My Service",
"endpoints":[{"endpointId":"invoke","displayName":"Invoke","kind":"unary",
"requestTypeUrl":"<type.googleapis.com/...>","responseTypeUrl":"<...>","description":"..."}]
}'
# 2. Add an implementation revision (one of static / scripting / workflow)
aev "api/services/my-service/revisions" -m POST -d '{
"tenantId":"<t>","appId":"<a>","namespace":"<ns>","revisionId":"r1",
"implementationKind":"workflow",
"workflow":{"workflowName":"my-workflow","workflowYaml":"<yaml>","definitionActorId":null,"inlineWorkflowYamls":null}
}'
# 3. Prepare → publish → deploy
aev "api/services/my-service/revisions/r1:prepare" -m POST
aev "api/services/my-service/revisions/r1:publish" -m POST
aev "api/services/my-service:deploy" -m POST -d '{ ... serving target ... }'
Optional staged rollout: POST …/rollouts then :advance / :pause / :resume /
:rollback; inspect GET …/serving and GET …/traffic. Bindings (connector + secret)
and access policies: POST …/bindings, POST …/policies. The service self-describes at
GET /api/services/{serviceId}/openapi.json.
# Account-level service + its NyxID exposure block
aev "api/services/my-service" | jq '{serviceId, externalExposure}'
# Its own OpenAPI (proves it is serving)
aev "api/services/my-service/openapi.json" | jq '.info, (.paths|keys)'
The externalExposure block is the NyxID-registration truth:
nyxidSlug — the brokered connector slug (empty ⇒ not registered).status — registration status; lastError — why it failed, if it did.desiredSpecHash vs registeredSpecHash — equal ⇒ NyxID is up to date with the current
contract; unequal ⇒ a re-registration is pending/needed.The endpoint contract tells you the path, readiness, and a ready-to-run curl example:
aev "api/scopes/$scopeId/members/$memberId/endpoints/chat/contract" \
| jq '{invokePath, canInvoke:.invocationReadiness.canInvoke, curlExample}'
The reliable smoke test is the streaming path (…/invoke/{endpointId}:stream, SSE),
which accepts the {"prompt":"…"} shorthand and returns workflow-run frames ending in a
runFinished event with the result:
aev "api/scopes/$scopeId/members/$memberId/invoke/chat:stream" -m POST --stream \
-d '{"prompt":"smoke test"}'
# look for: data: {... "runFinished": { "result": { "output": "..." } } }
The non-streaming …/invoke/{endpointId} expects the full typed envelope (it rejects a
bare {prompt} with 400 "payloadTypeUrl is required") — prefer :stream for a quick check.
Teams and account-level services invoke the same way:
POST /api/scopes/{scopeId}/teams/{teamId}/invoke/{endpointId}[:stream],
POST /api/scopes/{scopeId}/services/{serviceId}/invoke/{endpointId}[:stream].
Watch runs: GET /api/scopes/{scopeId}/services/{serviceId}/runs and …/runs/{runId}
(and :resume / :stop / :signal). For a visual timeline use the observatory:
GET /api/workflow/observatory/runs.
aevatar-scheduler — it needs the service identity
(tenantId/appId/namespace/serviceId), an endpointId, and the payload type you found
in the contract above.aevatar-platform-map.If you cannot complete a step server-side after a real attempt, hand the original request back to your caller rather than fabricating — see the fallback skill in this family.
npx claudepluginhub chronoaiproject/nyxid --plugin nyxidEntry point and router for the Aevatar skill family. Teaches object model, auth, and caller modes, then hands off to the right companion skill for building, running, publishing, or scheduling on Aevatar.
Builds a JSON-RPC 2.0 A2A server with task lifecycle management, SSE streaming, push notifications, and Agent Card serving for multi-agent interoperability.
Produces a complete service catalog entry for a microservice or internal platform service, covering identity, purpose, architecture, SLAs, API contracts, data classification, dependencies, and runbooks.