
service-itsm-agentic-setup-fulfiller-agent-configure
Create and activate the IT Service Fulfiller agent as a Next-Gen Authoring (NGA) native agent from the shipped ITSM Fulfiller template's Agent Script, using the Salesforce CLI (sf): read the template, check idempotency, create the NGA bundle then publish and activate it, then verify it is live. Idempotent per developer name. The Fulfiller agent is the IT-technician-facing assistant for incident triage, case summarization, field updates, and related-record automations. Use when asked to create the Fulfiller agent, set up the IT Service Fulfiller agent, provision the fulfiller assistant, or activate the Fulfiller agent. Triggers: create fulfiller agent, set up fulfiller agent, provision fulfiller agent, activate fulfiller agent. DO NOT TRIGGER: checking org prerequisites (service-itsm-agentic-setup-agentforce-studio-validate), or CMDB CRUD.
- Installs
- 1.2K
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/forcedotcom/sf-skills --skill service-itsm-agentic-setup-fulfiller-agent-configure- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads service-itsm-agentic-setup-fulfiller-agent-configure automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Create the IT Service Fulfiller Agent
Create and activate the IT Service Fulfiller Agent as a Next-Gen Authoring (NGA) native agent — Agent-Script-based (AiAuthoringBundleDefVer/bundle), appearing natively in Agentforce Studio's Agents list with no external-link icon — entirely through the Salesforce CLI (sf). This skill does not call the legacy /connect/service-itsm/createAgent; instead it reuses the shipped ITSM Fulfiller template's agentScript and feeds it into the NGA bundle pipeline:
POST /nextgen-authoring/bundles(createBundleWithVersion) — creates the bundle + first version from the template's Agent Script.POST /nextgen-authoring/bundle-versions/{id}/publish— publishes the version (creates the underlyingBotDefinition/BotVersion).POST /nextgen-authoring/bundle-versions/{id}/activate— activates it.
Commands: sf api request rest for Connect API GET/POST; sf data query for the SOQL idempotency + verify reads.
Helper scripts (invoked via Bash) hold every JSON-parsing / decision rule so the model never eyeballs a response body (A9): classify-preflight.mjs (Studio-access + template-provisioning verdict), classify-agent-existence.mjs (idempotency + reactivation-need from the BotDefinition SOQL), build-create-body.mjs (HTML-decodes the template's agentScript, normalizes it for the org's enabled features via strip-release-management.mjs, substitutes config.developer_name/config.agent_label, writes the bundle-create body to a JSON file so large content and free-text quotes never hit an inline shell string), render-report.mjs (deterministic report renderer — single source of report text for chat-turn and harness file).
The Fulfiller agent is the IT-technician-facing assistant — incident triage, case summarization, field updates, related-record automations. The employee self-service surface is service-itsm-agentic-setup-employee-agent-configure.
Scope
- In scope: Reading
agent-templates; extracting the Fulfiller template's Agent Script (svc_itsm_intelligence__ITSrvcMgmtFulfiller); creating the Fulfiller agent as an NGA-native agent viacreateBundleWithVersion→publish→activate; SOQL-verifying live; idempotent skip on duplicate developer name; normalizing the created Agent Script so it activates cleanly on any Agentforce-for-IT-Service org (internal step, never surfaced to the user — see below) — all viasf. - Out of scope: The Employee agent — broad or ~47 specializations under
svc_emp_intelligence__(service-itsm-agentic-setup-employee-agent-configure); enabling org-level feature toggles (validated byservice-itsm-agentic-setup-agentforce-studio-validate); low-level topic/action authoring; perm-set assignment; content-bundle deployment; CMDB CRUD; Discovery / Service Graph; the legacycreateAgentroute.
Preconditions
If any of these are unmet, sf surfaces an auth error or a 401/403/404; surface the raw error verbatim and stop — do not fabricate state.
sfCLI authenticated to the target org (sf org display -o <alias>shows Connected). All calls use--target-org <alias>; never extract the access token by hand.- API v67.0+ — pinned in the URL path; do not hand-edit below the minimum.
- ITSM features + Fulfiller template provisioned (
svc_itsm_intelligence__ITSrvcMgmtFulfiller). Ifagent-templatesreturns nothing or the routes 404, runservice-itsm-agentic-setup-agentforce-studio-validate. node≥ 18 on PATH.
Operations at a glance
| Concern | Command | Notes |
|---|---|---|
| Studio access (precondition read) | sf api request rest "/services/data/v67.0/agentforce-studio/access/Agents" --method GET -o <alias> | hasAccess=false ⇒ prerequisite hand-off |
| List agent templates + Agent Script (read) | sf api request rest "/services/data/v67.0/connect/service-itsm/agent-templates?agentType=AgentforceEmployeeAgent" --method GET -o <alias> | agentType=AgentforceEmployeeAgent required; confirms Fulfiller template + non-empty agentScript |
| Enumerate the existing agent + latest version status (read) | sf data query -q "SELECT Id,DeveloperName,MasterLabel,AgentTemplate,(SELECT Id,Status FROM BotVersions ORDER BY VersionNumber DESC LIMIT 1) FROM BotDefinition WHERE Id='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'" -o <alias> --json | Keyed PRIMARILY on the template's botDefinitionId (Phase-1 row); OR AgentTemplate= is a defensive fallback that would catch a live agent instantiated from the OOTB source template (svc_itsm_intelligence__ITSrvcMgmtFulfiller = Phase-1 template.id) regardless of its DeveloperName; OR DeveloperName= is the real guard here — the normal Fulfiller case (never pre-provisioned; null AgentTemplate) and the guard for a dangling Id link (deleted target). Classified by scripts/classify-agent-existence.mjs; Active latest ⇒ ALREADY-CREATED; Inactive latest ⇒ offer reactivation |
| Create the NGA bundle (write) | sf api request rest "/services/data/v67.0/nextgen-authoring/bundles" --method POST --body @<body-file> -o <alias> | Body built by scripts/build-create-body.mjs; response id = the bundle version Id |
| Publish the bundle version (write) | sf api request rest "/services/data/v67.0/nextgen-authoring/bundle-versions/<bundleVersionId>/publish" --method POST --body '{}' -o <alias> | Returns publishedBotId/publishedBotVersionId — creates the underlying BotDefinition/BotVersion |
| Activate the bundle version (write) | sf api request rest "/services/data/v67.0/nextgen-authoring/bundle-versions/<bundleVersionId>/activate" --method POST --body '{}' -o <alias> | Empty response on success; agent is now live and NGA-native |
| Activate an existing inactive version (write) | sf api request rest "/services/data/v67.0/connect/bot-versions/<latestVersionId>/activation" --method POST --body '{"status":"Active"}' -o <alias> | Reactivation path only (Phase 2b) — skips create/publish |
| Verify agent is live (read) | sf data query -q "SELECT ... FROM BotDefinition WHERE Id='<verifyId>'" -o <alias> --json | <verifyId> = create path's publishedBotId (Phase-5) or the Phase-2 classifier's returned live matched Id (its botDefinitionId/agentId) on ALREADY-CREATED / reactivation — not the null Phase-1 template botDefinitionId, never the collected developerName; confirm BotDefinition present + latest version Active |
Full command shapes and the ITSM Connect API reference live in references/cli-invocation.md; the reactivation-path call + idempotency verdict table live in references/reactivation.md; the response-body error codes and recurring gotchas live in references/error-taxonomy.md.
Never extract the access token. Use
sf api request rest/sf data querydirectly — they use the CLI's stored session for the target org. Do not pull theaccessTokenout ofsf org displayand hand-build an HTTP request with it; that bypasses the CLI session and leaks a bearer token into shell context.
--jsonrule.sf data querytakes--json(results come back in a.result.records[]envelope — that's what the classifier expects).sf api request restdoes not — omit--jsonthere; its raw stdout body is already JSON.
Shipped ITSM Fulfiller agent template
| Template identifier | Default developer name |
|---|---|
svc_itsm_intelligence__ITSrvcMgmtFulfiller (masterLabel "IT Service Fulfiller") | IT_Service_Fulfiller_Agent |
The
agentScriptfield is the source of truth for the NGA create — notid.scripts/build-create-body.mjsmatches onmasterLabel, HTML-decodesagentScript, and substitutes the collected<developerName>/<label>intoconfig.developer_name/config.agent_labelbefore it becomes the bundle'sresourceContent. The Employee-facing agent is handled byservice-itsm-agentic-setup-employee-agent-configure.
Internal template normalization — never surfaced to the user. Before the decoded script becomes
resourceContent,scripts/strip-release-management.mjsremoves thetopic ReleaseManagement:block — plus itsgo_to_ReleaseManagement:selector transition and routing bullet. That topic's only action,svc_itsm_intelligence__SummarizeRelease, is gated behind an org preference (ReleaseManagementPref) and is not surfaced by/actions/custom/generatePromptResponseon an org that has not enabled it; shipping it would makeactivatereturn HTTP 200 with a{success:false, "... does not exist"}silent-failure body.classify-action-availability.mjsapplies the identical transform so Phase 2c scans the same normalized script — the two callers must stay in lock-step. The transform is a no-op if the block is absent (safe against future template revisions). This normalization is an implementation detail: do NOT mention it, the removed subagent, or Release Management in chat narration, the confirm-to-write step, or the report — the admin only ever sees that the agent was created and activated.
Architecture — Creation stages
| Stage | What happens | Tool used |
|---|---|---|
| Preflight | Confirm Studio access (agentforce-studio/access/Agents) and that the template's agentScript is present | Bash (sf api request rest) |
| Enumerate | Read the Fulfiller template (agent-templates) and existing agents + latest version status (SOQL on BotDefinition/BotVersions); classify idempotency and reactivation-need via script | Bash (sf, node) |
| Confirm-to-write | Present the exact developerName + label (the NGA create target), OR — if the existing agent is inactive — present the reactivation option instead, and require explicit "yes" either way | AskUserQuestion |
| Create (create path only) | POST createBundleWithVersion (builds the NGA bundle + first version from the decoded, substituted template Agent Script) | Bash (sf api request rest, node) |
| Publish (create path only) | POST .../bundle-versions/<id>/publish (creates the underlying BotDefinition/BotVersion) | Bash (sf api request rest) |
| Activate | POST .../bundle-versions/<id>/activate (create path) OR POST .../connect/bot-versions/<latestVersionId>/activation with {"status":"Active"} (reactivation path — skips create/publish) | Bash (sf api request rest) |
| Verify | SOQL-read BotDefinition/BotVersions and confirm the agent exists with an Active latest version | Bash (sf data query) |
Idempotency: keyed PRIMARILY on the template's botDefinitionId (Phase-1 agent-templates row — the platform's authoritative template→BotDefinition link), FALLING BACK first to the BotDefinition's AgentTemplate (the OOTB namespaced source template = Phase-1 template.id) and then to the collected <developerName>. The Phase-2 read is BotDefinition WHERE Id='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>' (the OR AgentTemplate= half is a defensive key that would catch a live agent instantiated from the source template regardless of its DeveloperName; the OR DeveloperName= half is both the null-botDefinitionId fallback — the normal Fulfiller case — AND the guard for a dangling Id link whose target BotDefinition was deleted), + latest BotVersion.Status (classified by the helper script). Outcomes: no match on any key ⇒ exists:false ⇒ create; latestVersionStatus:"Active" ⇒ ALREADY-CREATED (skip the write, fall through to Phase 7 verification); needsActivation:true (latest version Inactive) ⇒ offer to activate the existing version instead of creating a new agent (Phase 2b) rather than silently skipping or duplicating. Why the fallbacks matter: the Fulfiller is never pre-provisioned and this skill's create path never stamps templateName, so BOTH the template's botDefinitionId AND the agent's AgentTemplate are always null — the <developerName>-keyed fallback is the guard that actually catches a repeat run; short-circuiting straight to create on a null botDefinitionId would re-create and collide with DUPLICATE_VALUE. The server does reject a duplicate DeveloperName at publish (unique-constraint → bundle cleanup), but only this Phase-2 read turns a repeat into a graceful skip instead of that hard error.
Clarifying Questions
Collect from the user (ask only what is not already in conversation context):
| Field | Description | Default |
|---|---|---|
| Target org | The sf org alias to create the agent in | Default org (sf config get target-org) |
| Developer name | Unique DeveloperName for the agent | IT_Service_Fulfiller_Agent |
| Label | User-facing label for the agent | IT Service Fulfiller Agent |
| Confirm the write | Explicit confirmation before the create/publish/activate sequence | REQUIRED — present the developerName + label and require "yes" via AskUserQuestion |
The idempotency read keys PRIMARILY on the template's botDefinitionId (Phase-1 row) and FALLS BACK to the BotDefinition's AgentTemplate (defensive — null on the never-pre-provisioned Fulfiller) and then to the collected <developerName>, the guard that actually catches a repeat here, when that is null; the verify read keys on the publish response's publishedBotId (create path) or the template's botDefinitionId (ALREADY-CREATED / reactivation). The collected <developerName> and <label> (defaults IT_Service_Fulfiller_Agent / IT Service Fulfiller Agent) also thread through the createBundleWithVersion body — both the outer apiName/label AND the substituted config.developer_name/config.agent_label inside the Agent Script. Never hardcode the name in one call and collect it in another — a mismatch between the bundle's outer apiName and the script's internal developer_name causes the platform to diverge the two. Creating an agent provisions a live, activated agent on the org; the user must explicitly approve the write.
Workflow
Substitute <alias> with the collected target org and <developerName> / <label> with the collected values. Full command shapes + per-phase verdict-branch handling live in references/workflow-detail.md — the phase summary below names each step and its load-bearing rule; the reference file holds the exact sf / node invocations to copy.
- Phase 0 — Establish
${SCRATCH_DIR}. Invoke the deterministic helper (path is skill-root-qualified so it resolves regardless of the shell's CWD):SCRATCH_DIR="$(node "<skill_dir>/scripts/create-scratch-dir.mjs" "${outputDir:-}")". Helper picks the base dir (${TMPDIR}, else/tmp, else the harness${outputDir}last-resort — scratch stays OUT of the scored${outputDir}tree) and emits the created dir on stdout. All transient JSON lands under${SCRATCH_DIR}; the durable${outputDir}/report.mdstays under the harness dir. - Phase 1 — Preflight. Capture the Studio-access read into
${SCRATCH_DIR}/studio-access.jsonand theagent-templatesread (with the requiredagentType=AgentforceEmployeeAgentquery param) into${SCRATCH_DIR}/agent-templates.json, then classify by passing both file paths, then the label (that arg order):node "<skill_dir>/scripts/classify-preflight.mjs" ${SCRATCH_DIR}/studio-access.json ${SCRATCH_DIR}/agent-templates.json "IT Service Fulfiller". The classifier emitstemplate.botDefinitionId,template.id, andtemplate.masterLabelfrom the matched row — capture all three;botDefinitionIdis the primary Phase-2 idempotency key,template.id(the BotDefinition'sAgentTemplate) the first fallback, and<developerName>the last fallback;masterLabelis the report's display label, not a key. Branch onverdict:READY⇒ Phase 2;NOT-READY⇒ prerequisite hand-off viaAskUserQuestion(delegate toservice-itsm-agentic-setup-agentforce-studio-validateon "yes");ERROR⇒ surface + stop;studio.signal="CANNOT-CONFIRM"(confirmed 404) does not block. - Phase 2 — Idempotency (primary key
botDefinitionId, fallbacksAgentTemplatethen<developerName>). Taketemplate.botDefinitionIdandtemplate.idfrom Phase 1. PresentbotDefinitionId⇒ SOQLBotDefinition WHERE Id='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'with theBotVersionssubquery (subquery is required — otherwiseneedsActivationis permanently false; theORclauses make a dangling Id link — deleted target — fall back to the live agent instead of a falseexists:false→ duplicate create). Empty/nullbotDefinitionId(the normal Fulfiller case — the template row is never back-filled) ⇒ do NOT skip to create; readBotDefinition WHERE AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'(a self-created agent from a prior run carries a nullAgentTemplate, soDeveloperNameis what recovers it;AgentTemplatewould catch a hypothetical instantiated-from-template agent under any DeveloperName).<agentTemplate>is Phase-1template.id. Either way classify vianode "<skill_dir>/scripts/classify-agent-existence.mjs" ${SCRATCH_DIR}/bot-existing.json "<botDefinitionId-or-empty>" "<developerName>" "<agentTemplate>". Branch:exists:false⇒ Phase 2c (action-availability gate, then create);exists:true+needsActivation:false⇒ ALREADY-CREATED (skip straight to Phase 7 — no action-availability gate; a live active agent's actions are already wired);exists:true+needsActivation:true⇒ Phase 2b. Non-zero exit ⇒ surface CLI error; never assume absent. Why the fallbacks: the Fulfiller is never pre-provisioned, sobotDefinitionIdandAgentTemplateare always null — a missing developerName check would re-create and hitDUPLICATE_VALUE. - Phase 2b — Reactivation offer.
AskUserQuestion: "Fulfiller agent<developerName>exists but latest version is Inactive. Activate it?". On Yes:POST /connect/bot-versions/<latestVersionId>/activationwith{"status":"Active"}captured to${SCRATCH_DIR}/activate-response.json, thennode "<skill_dir>/scripts/classify-activate-result.mjs" ${SCRATCH_DIR}/activate-response.json—PASS⇒ Phase 7 (verdict ACTIVATED);FAIL⇒ surfacemessages[]verbatim, offer the Phase 2c permset hand-off if a message names a missing invocable action, do NOT report ACTIVATED;CANNOT-CONFIRM⇒ fall through to Phase 7 SOQL verify. On No: stop, no writes. - Phase 2c — Action-availability preflight (create path only; reached only from Phase 2
exists:false). Capturesf api request rest "/services/data/v67.0/actions/custom/generatePromptResponse" --method GETto${SCRATCH_DIR}/generate-prompt-response.json, thennode "<skill_dir>/scripts/classify-action-availability.mjs" ${SCRATCH_DIR}/agent-templates.json "IT Service Fulfiller" ${SCRATCH_DIR}/generate-prompt-response.json(scans the normalized Agent Script — the same internal transform the create step applies — so a subagent whose backing action is gated behind an org preference is never flagged missing and never blocks activation). Branch onverdict:READY⇒ Phase 3;NOT-READY⇒ present the result under an "Attention" heading (never label it "Blocker") and raise anAskUserQuestionoffering hand-off toservice-itsm-agentic-setup-itsm-agentforce-permset-assign(surfacemissing[]verbatim — do NOT proceed to write; the activate call would return HTTP 200 with a{success:false}silent-failure body);CANNOT-CONFIRM⇒ surface reasons and proceed with caution (Phase 6 activate-result classifier catches the silent-failure body). Full contract inreferences/action-availability.md. - Phase 3 — Confirm-to-Write (REQUIRED, create path only). If
${outputDir}was provided, first render the checkpoint file viarender-report.mjswithverdict:"PENDING CONFIRMATION"(skip for interactive runs). THEN raise theAskUserQuestiongate presenting developerName + label + "NGA-native from the Fulfiller template's Agent Script". Proceed only on explicit "yes"; on "no", re-render withverdict:"DECLINED". - Phase 4 — Create.
scripts/build-create-body.mjs ${SCRATCH_DIR}/agent-templates.json "IT Service Fulfiller" "<developerName>" "<label>" ${SCRATCH_DIR}/create-bundle-body.json(helper re-reads Phase-1 templates JSON, HTML-decodes the matchedagentScript, normalizes it — same internal transform as Phase 2c — substitutes internalconfig.developer_name/config.agent_label, writes body to file), thenPOST /nextgen-authoring/bundles --body @${SCRATCH_DIR}/create-bundle-body.json. Capture responseid— that is thebundleVersionIdfor Phases 5–6, notbundleId.403 FUNCTIONALITY_NOT_ENABLED/404⇒ trigger the Phase-1 hand-off; build-script exit 3 ⇒ surface stderr. - Phase 5 — Publish.
POST /nextgen-authoring/bundle-versions/<bundleVersionId>/publish --body '{}'(empty body required). Success:{ lastPublishedOn, publishedBotId, publishedBotVersionId }— this call creates the underlyingBotDefinition/BotVersion. Any error ⇒ surface verbatim; never activate an unpublished version. - Phase 6 — Activate.
POST /nextgen-authoring/bundle-versions/<bundleVersionId>/activate --body '{}'captured to${SCRATCH_DIR}/activate-response.json, thennode "<skill_dir>/scripts/classify-activate-result.mjs" ${SCRATCH_DIR}/activate-response.json— activate can return HTTP 200 with a{success:false}silent-failure body when a referenced invocable action isn't surfaced; the classifier catches that.PASS⇒ Phase 7;FAIL⇒ surfacemessages[], offer Phase 2c permset hand-off if a message names a missing action, do NOT report CREATED;CANNOT-CONFIRM⇒ fall through to Phase 7 SOQL verify. - Phase 7 — Verify. SOQL
BotDefinition WHERE Id='<id>'(+BotVersionssubquery) and classify —<id>is the create path'spublishedBotId(captured from Phase 5) or, on the ALREADY-CREATED / reactivation path, the live matched Id the Phase-2 classifier returned (itsbotDefinitionId/agentIdoutput — the actualBotDefinition.Idof the matched record), not the Phase-1 templatebotDefinitionId(which is always null for the Fulfiller, so on any existing-agent hit the verify would runWHERE Id=''and falsely report failure after a successful skip/activation). Confirmexists:true, count:1, latestVersionStatus:"Active". Any discrepancy ⇒ report verbatim, do not fabricate success. - Phase 8 — Aggregate verdict. Emit CREATED / ALREADY-CREATED / ACTIVATED / FAILED (ACTIVATED on the Phase-2b path) by re-invoking
render-report.mjs— the single source of report text. Never surface internal record IDs — the bundle versionid,publishedBotId/BotDefinition, orBotVersion— in the verdict, chat narration, or the report; they are captured only to drive the publish/activate/verify calls and mean nothing to the admin. Report by status/name only ("created and activated"), never "Bundle created (version id …)" / "Published (BotDefinition …)". If${outputDir}was provided, overwrite${outputDir}/report.md; otherwise emit stdout as the turn-side report. - Phase 9 — Runtime-access hand-off (REQUIRED on a live-agent verdict). When the Phase-8 verdict is
CREATED,ALREADY-CREATED, orACTIVATED(a live agent now exists), raise anAskUserQuestion— the same enforced hand-off pattern as the Phase-1 prerequisite and Phase-2c permset offers — asking whether to set up the agent's runtime access now: "The agent is live, but its actions call platform features (Prompt Templates, Data Cloud, Unified Catalog) a user can't run until access is granted, so it fails when opened. Set up runtime access now?". On Yes, delegate toservice-itsm-agentic-setup-agent-runtime-access-assign(it runs its own target-user selection + confirm-to-write gate). On No, stop — the report's "set up access" next-step line stands as the record. Do NOT raise this onPENDING CONFIRMATION,DECLINED, orFAILED(no live agent to grant access to). This is an enforcedAskUserQuestion, not report prose —render-report.mjsstill emits its plain-language "set up access" line unchanged; the question is what guarantees the offer is actually made every time.
Rules / Constraints
| Constraint | Rationale |
|---|---|
All calls go through sf api request rest / sf data query; never extract the access token | Leaks a bearer token into shell context; the CLI's stored session is the correct surface |
Idempotency read keys PRIMARILY on the template's botDefinitionId (Phase-1 row), falling back to the collected <developerName> when null; the verify read keys on the publish publishedBotId / botDefinitionId; that same <developerName>/<label> also thread through the create body (outer apiName/label AND the substituted config.developer_name/config.agent_label) | The Fulfiller is never pre-provisioned and the create path omits templateName, so its template botDefinitionId is always null — the <developerName> fallback is the guard that catches a repeat run (a name-only miss → DUPLICATE_VALUE). A create-body hardcode/collect mismatch diverges the bundle's outer identity from the script's internal identity |
Preflight, idempotency, bundle-body construction, and report rendering all live in scripts/*.mjs, not prose (A9) | JSON parsing + masterLabel matching + hasAccess reads + verdict emission are deterministic; the ~70KB Agent Script and free-text apostrophes cannot be safely interpolated into a shell string — JSON.stringify in the helper escapes them |
The created Agent Script is normalized before it ships (strip-release-management.mjs); classify-action-availability.mjs applies the identical transform. This normalization is internal — never surface it, the removed subagent, or Release Management in user-facing output (chat, confirm-to-write, or report) | The removed subagent's only action svc_itsm_intelligence__SummarizeRelease is gated behind ReleaseManagementPref; shipping it makes activate return a {success:false} silent-failure body on any org without that preference. Removing it (vs. forcing the pref on) lets the Fulfiller activate cleanly on any Agentforce-for-IT-Service org; both callers stay in lock-step or Phase 2c would false-flag the removed action as missing |
Three-call sequence: createBundleWithVersion → publish → activate, in that order, on the SAME captured bundleVersionId (response id, not bundleId) | Platform enforces DRAFT → published → active; response-body / empty-body / --json / agentType / HTML-decode gotchas live in references/error-taxonomy.md |
Enumerate BotDefinition with the BotVersions subquery; skip create when Active; offer Phase-2b reactivation when Inactive — never silent skip, never duplicate create | Subquery is what distinguishes Active/Inactive; the server rejects a duplicate DeveloperName at publish (unique-constraint → bundle cleanup), so this read is what turns a repeat into a graceful skip instead of that hard error |
| REQUIRED confirm-to-write checkpoint before create sequence or reactivation call | Both change live org state — explicit user approval required |
On hasAccess=false / 403 FUNCTIONALITY_NOT_ENABLED, offer the readiness hand-off — never enable features here; never call legacy /connect/service-itsm/createAgent | Enablement is a Setup-UI/admin action; createAgent produces a Setup-page bot with an external-link icon (wrong kind of agent for this skill) |
Never surface internal record IDs — the bundle version id (1bZ…), publishedBotId/BotDefinition (0Xx…), BotVersion (0Xv…) — in chat narration, the confirm-to-write step, or the report; report progress and verdict by status/name only | These IDs are captured solely to drive the publish → activate → verify → verify-read calls; they are meaningless to an admin going through setup and only add noise. render-report.mjs renders status-only rows and defensively scrubs any ID; the model must likewise not echo them (never "Bundle created (version id 1bZ…)" / "Published (BotDefinition 0Xx…)") |
| Report exact CLI response text on any error | Enables support to diagnose failures — this is the one place a raw ID may appear, inside a verbatim error the user must relay to support |
Verification Checklist
- Preflight classified by
classify-preflight.mjs(PASS or documented CANNOT-CONFIRM); hand-off offered on FAIL; raw error surfaced on ERROR. - Idempotency keyed on the template's
botDefinitionId(Phase-1 row) with the BotDefinition'sAgentTemplate(Phase-1template.id) as a defensive first fallback and the collected developerName as the real guard;BotDefinition WHERE Id='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'(theORs cover a null/danglingbotDefinitionIdand — for the never-pre-provisioned Fulfiller with a nullAgentTemplate— a self-created repeat by DeveloperName) + latestBotVersion.Status(subquery present) read + classified before any write. - If
needsActivation:true, Phase-2b reactivation offer presented — no silent skip, no duplicate create. - Explicit user confirmation at Phase 3 (create) or Phase 2b (reactivation) before any write.
- Bundle body built by
build-create-body.mjs, POSTed via--body @<file>with the collecteddeveloperName/label; or write correctly skipped. - Same
bundleVersionId(responseid) used for publish + activate; reactivation usedPOST /connect/bot-versions/<id>/activation; legacycreateAgentnever called. - Phase-7 verify confirmed
BotDefinitionpresent + latest version Active. - On a live-agent verdict (CREATED / ALREADY-CREATED / ACTIVATED), the Phase-9 runtime-access hand-off was raised as an
AskUserQuestion(delegating toservice-itsm-agentic-setup-agent-runtime-access-assignon "yes"); NOT raised on PENDING CONFIRMATION / DECLINED / FAILED. - Access token never extracted; final verdict reported with no internal record IDs (bundle version
id,publishedBotId/BotDefinition,BotVersion) surfaced in chat, the confirm-to-write step, or the report — status/name only (raw IDs allowed only inside a verbatim error).
Output Format
The report layout is generated deterministically by scripts/render-report.mjs — the single source of report text for both the chat turn and the harness's ${outputDir}/report.md. Never hand-compose the layout in prose (A9); always shell out to the helper. Full rendered shape, report-state JSON schema, and checkpoint-write rules live in references/report-format.md.
Terminal verdicts: CREATED | ALREADY-CREATED | ACTIVATED | PENDING CONFIRMATION | DECLINED | FAILED. When ${outputDir} is set, write at Phase 3, Phase 6 (or Phase 2b), and Phase 8 — each write overwrites the same file. Skip these writes in interactive/chat surfaces. The Phase-9 runtime-access hand-off fires after the Phase-8 report on a live-agent verdict; it does not change the verdict or re-render the report.
Reference File Index
| File | When to read |
|---|---|
references/workflow-detail.md | Full per-phase verdict-branch narrative that the SKILL body summarizes (Phase-1 ERROR/NOT-READY/CANNOT-CONFIRM, Phase-2 classifier output, Phase-4 create response, error branches) |
references/report-format.md | Every render-report.mjs call — the rendered shape and the three-checkpoint write policy for ${outputDir}/report.md |
references/cli-invocation.md | Every phase — exact sf call shapes, the never-extract-token rule, ITSM Connect API reference, three helper-script contracts |
references/action-availability.md | Phase 2c (action-availability preflight, create path) + Phase 2b/6 (activate-result classifier) — silent-failure body catches, permset hand-off wording |
references/reactivation.md | Reactivation path (needsActivation:true) — the direct POST /connect/bot-versions/{id}/activation call + full idempotency verdict table |
references/error-taxonomy.md | Any non-2xx response, unexpected empty body, or script non-zero exit — response-body error codes and recurring foot-guns |
scripts/render-report.mjs | Every checkpoint that writes ${outputDir}/report.md (Phase-3 gate, Phase-6 create-succeeded, Phase-8 final) — deterministic renderer from a phase-state JSON |
scripts/strip-release-management.mjs | The internal Agent Script normalization — imported by build-create-body.mjs (create body) and classify-action-availability.mjs (Phase 2c scan); both must call it or the two diverge |
FAQ
What does the service-itsm-agentic-setup-fulfiller-agent-configure skill do?
Create and activate the IT Service Fulfiller agent as a Next-Gen Authoring (NGA) native agent from the shipped ITSM Fulfiller template's Agent Script, using the Salesforce CLI (sf): read the template, check idempotency, create the NGA bundle then publish and activate it, then verify it is live. Idempotent per developer name. The Fulfiller agent is the IT-technician-facing assistant for incident triage, case summarization, field updates, and related-record automations. Use when asked to create the Fulfiller agent, set up the IT Service Fulfiller agent, provision the fulfiller assistant, or activate the Fulfiller agent. Triggers: create fulfiller agent, set up fulfiller agent, provision fulfiller agent, activate fulfiller agent. DO NOT TRIGGER: checking org prerequisites (service-itsm-agentic-setup-agentforce-studio-validate), or CMDB CRUD.
How do I install service-itsm-agentic-setup-fulfiller-agent-configure?
Run npx skills add https://github.com/forcedotcom/sf-skills --skill service-itsm-agentic-setup-fulfiller-agent-configure in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/service-itsm-agentic-setup-fulfiller-agent-configure/ (personal) or .claude/skills/service-itsm-agentic-setup-fulfiller-agent-configure/ (project).
Which AI agents can use service-itsm-agentic-setup-fulfiller-agent-configure?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is service-itsm-agentic-setup-fulfiller-agent-configure safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains service-itsm-agentic-setup-fulfiller-agent-configure?
It is published by forcedotcom in forcedotcom/sf-skills. It has 1,202 recorded installs.
More from forcedotcom/sf-skills
platform-apex-generate
forcedotcom/sf-skills
Primary Apex authoring skill for class generation, refactoring, and review. ALWAYS ACTIVATE when the user mentions Apex, .cls, triggers, or asks to create/refactor a class (service, selector, domain, batch, queueable, schedulable, invocable, DTO, utility, interface, abstract, exception, REST resource). Use this skill for requests involving SObject CRUD, mapping collections, fetching related records, scheduled jobs, batch jobs, trigger design, @AuraEnabled controllers, @RestResource endpoints, custom REST APIs, or code review of existing Apex.
platform-apex-test-generate
forcedotcom/sf-skills
Use to generate and validate Apex test classes with TestDataFactory patterns, bulk testing (251+ records), mocking, assertions, and disciplined test-fix loops. Use when creating Apex test classes (for triggers, services, controllers, batch jobs, queueables, and callouts), improving coverage, debugging or fixing failing Apex tests, or running test/coverage analysis. Triggers on Test.cls files, sf apex run test, coverage reports. Do NOT trigger for production Apex (use platform-apex-generate) or Jest/LWC tests.
platform-apex-test-run
forcedotcom/sf-skills
Apex test execution, coverage analysis, and test-fix loops with 120-point scoring. Use when the user runs Apex tests, checks code coverage, fixes failing tests, or touches Test.cls / Test.cls files. DO NOT TRIGGER when writing Apex production code (use platform-apex-generate), Agentforce agent testing (use agentforce-test), or Jest/LWC tests (use experience-lwc-generate).
platform-apex-logs-debug
forcedotcom/sf-skills
Salesforce debug log analysis and troubleshooting with 100-point scoring. TRIGGER when: user analyzes debug logs, hits governor limits, reads stack traces, or touches .log files from Salesforce orgs. DO NOT TRIGGER when: running Apex tests (use platform-apex-test-run), generating or fixing Apex code (use platform-apex-generate), or Agentforce session tracing (use agentforce-observe).
platform-soql-query
forcedotcom/sf-skills
Use when the user needs SOQL/SOSL authoring or optimization: natural-language-to-query generation, relationship queries, aggregates, query-plan/selectivity analysis, and performance or safety improvements. TRIGGER when the user writes, optimizes, or debugs SOQL/SOSL, touches .soql files, or asks about relationship queries, aggregates, or query performance. DO NOT TRIGGER for bulk data operations (use platform-data-manage), Apex DML logic (use platform-apex-generate), or report/dashboard queries.
platform-metadata-deploy
forcedotcom/sf-skills
Salesforce DevOps automation using sf CLI v2. TRIGGER when: user deploys metadata, validates a deploy or does a dry-run, deploys to a Production org, quick-deploys a validated job ID, ships/promotes to prod, creates/manages scratch orgs or sandboxes, sets up CI/CD pipelines, or troubleshoots deployment errors with sf project deploy. DO NOT TRIGGER when: writing Apex code, building LWC components (use experience-lwc-generate), creating metadata definitions (use platform-custom-object-generate), deleting metadata from an org (use platform-destructive-deploy), or querying org data (use platform-data-manage).
Popular ai & agents skills
google-agents-cli-publish
google/agents-cli
This skill should be used when the user wants to "publish an agent", "publish my ADK agent", "register an agent with Gemini", "publish to Gemini" (formerly Gemini Enterprise), or needs guidance on the agents-cli publish gemini command. Also use when the user wants to "manage agents in Agent Registry", "list/update/delete registered agents", or "register an MCP server". Covers ADK vs A2A registration modes, programmatic and interactive usage, flag reference, auto-detection from deployment metadata, Agent Registry fleet management, and troubleshooting. Part of the agents-cli skills suite. Do NOT use for deployment (use google-agents-cli-deploy).
google-agents-cli-eval
google/agents-cli
This skill should be used when the user wants to "run an evaluation", "evaluate my agent", "evaluate my ADK agent", "write an eval dataset", "analyze eval failures", "compare eval results", "optimize agent", or needs guidance on the Gemini platform eval methodology and the Quality Flywheel. Covers eval metrics, dataset schema, LLM-as-judge scoring, and common failure causes. Applies to any agents-cli project, whatever framework the agent is written in. Do NOT use for agent API code patterns (ADK: use google-agents-cli-adk-code), deployment (use google-agents-cli-deploy), or project scaffolding (use google-agents-cli-scaffold).
skill-creator
anthropics/skills
Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.
codex-pet
prime-skills/runcomfy-agent-skills
Codex Pet generator on RunComfy. Build a Codex-compatible Codex Pet spritesheet.webp + pet.json from a single reference image, drop it into ${CODEXHOME:-$HOME/.codex}/pets/ / and Codex picks it up as a custom Codex Pet next to the 8 built-ins. This skill produces the exact Codex Pet atlas Codex expects (1536x1872 PNG/WebP, 8 cols x 9 rows, 192x208 cells, 9 animation states — idle, running-right, running-left, waving, jumping, failed, waiting, running, review). Calls OpenAI GPT Image 2 edit ONCE via the local RunComfy CLI as runcomfy run openai/gpt-image-2/edit to produce a canonical Codex Pet pose, then assembles all 9 animation rows programmatically with ImageMagick micro-transforms — no Codex Pro, no $imagegen, no OPENAIAPIKEY required, only RUNCOMFYTOKEN. Triggers on "codex pet", "create codex pet", "make codex pet", "hatch codex pet", "/hatch image", "desktop pet codex", "codex pets", "spritesheet.webp", or any explicit ask to build a custom pet for OpenAI Codex.
full-output-enforcement
leonxlnx/taste-skill
Overrides default LLM truncation behavior. Enforces complete code generation, bans placeholder patterns, and handles token-limit splits cleanly. Apply to any task requiring exhaustive, unabridged output.
executing-plans
obra/superpowers
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available