$npx -y skills add forcedotcom/sf-skills --skill agentforce-architecture-analyzeDeclared architecture snapshot for one Agentforce agent: planner, topics, actions, flows, Apex, prompt templates, and NGA plugins. Renders a human-readable architecture document and Mermaid invocation graph from design-time metadata (not runtime audit rows). TRIGGER when user ask
| 1 | # agentforce-architecture-analyze — declared architecture snapshot |
| 2 | |
| 3 | Design-time metadata tree for one Agentforce agent: planner → topics → actions → flows → Apex → prompts → NGA plugins. Reads declared metadata only — `BotDefinition`, `GenAiPlanner*`, `GenAiPlugin*`, `GenAiFunction*`, `Flow`, `ApexClass`, `GenAiPromptTemplate`. Does **not** read runtime audit rows. |
| 4 | |
| 5 | **Runtime budget: 30–45s typical, ≤60s hard cap** on reference fixtures. Sequential baseline would be 90–220s; parallel Tooling SOQL fan-out delivers a 3–5× speedup. Large bots with many flows scale approximately linearly — each flow metadata retrieve is one round-trip. |
| 6 | |
| 7 | Runs **inline** — no subagent. Every phase is deterministic file processing. |
| 8 | |
| 9 | ## If the user hasn't given enough to proceed |
| 10 | |
| 11 | When invoked with no `agent_api_name` AND no org alias, print the following block **verbatim** — do not paraphrase, do not pre-run any script. Trigger condition: `$ARGUMENTS` is empty OR names no agent (no `--agent` flag and no known agent API name in the prose) OR names no org (no `--org` flag and no known alias). |
| 12 | |
| 13 | > Which agent should I document, and in which org? |
| 14 | > |
| 15 | > I need: |
| 16 | > - **Agent API name** — the `DeveloperName` of the `BotDefinition` (e.g. `MyAgent`, `MySalesAgent`). Not the label. |
| 17 | > - **Org alias** — for `sf` CLI auth (the alias you configured with `sf org login`) |
| 18 | > |
| 19 | > Optional: |
| 20 | > - **Version** — an `agent_version_api_name` like `v5`. If omitted, I'll resolve the active `BotVersion`. |
| 21 | > - **`--force`** — ignore cached tree; re-fetch everything. |
| 22 | > - **`--reprobe`** — re-run the 7-day channel-probe cache (only needed after a Salesforce release). |
| 23 | > |
| 24 | > I'll run the metadata pipeline inline. Artifacts land under `~/.vibe/data/agentforce-architecture-analyze/<org_id15>/<agent_api_name>__<agent_version>/` (overridable with `--data-dir`). |
| 25 | |
| 26 | ## Pipeline invocation |
| 27 | |
| 28 | When the user has supplied `--org <alias>` + `--agent <api_name>` (plus any optional flags), run this block. One `python3` invocation drives the full pipeline. `main.py` writes `.emit_ctx.json`; `emit_result.py` reads it and prints the final `=== RESULT ===` block last to stdout. |
| 29 | |
| 30 | ```bash |
| 31 | set -euo pipefail |
| 32 | |
| 33 | # zsh arrays are 1-indexed by default; bash arrays are 0-indexed. |
| 34 | # This block uses 0-indexed semantics throughout (_args[$i] starting at i=0), |
| 35 | # so under zsh + `set -u` the very first read of `_args[0]` would trip |
| 36 | # `parameter not set`. KSH_ARRAYS makes zsh treat arrays as 0-indexed, |
| 37 | # matching the bash shebang's expectation. No-op under bash. |
| 38 | [ -n "${ZSH_VERSION:-}" ] && setopt KSH_ARRAYS |
| 39 | |
| 40 | SKILL_ROOT="${SKILL_ROOT:-${PLUGIN_ROOT:-$HOME/.vibe/skills}/agentforce-architecture-analyze}" |
| 41 | |
| 42 | # Argument parser. Accepts both `--org foo` and `--org=foo`. |
| 43 | # `$ARGUMENTS` is the raw user input Claude Code substitutes. |
| 44 | ARG_ORG="" |
| 45 | ARG_AGENT="" |
| 46 | ARG_VERSION="" |
| 47 | ARG_FORCE="" |
| 48 | ARG_REPROBE="" |
| 49 | ARG_PARALLELISM="" |
| 50 | ARG_MAX_MERMAID="" |
| 51 | |
| 52 | # shellcheck disable=SC2206 |
| 53 | _args=($ARGUMENTS) |
| 54 | i=0 |
| 55 | while [ $i -lt ${#_args[@]} ]; do |
| 56 | tok="${_args[$i]}" |
| 57 | case "$tok" in |
| 58 | --org=*) ARG_ORG="${tok#--org=}" ;; |
| 59 | --org) i=$((i+1)); ARG_ORG="${_args[$i]:-}" ;; |
| 60 | --agent=*) ARG_AGENT="${tok#--agent=}" ;; |
| 61 | --agent) i=$((i+1)); ARG_AGENT="${_args[$i]:-}" ;; |
| 62 | --version=*) ARG_VERSION="${tok#--version=}" ;; |
| 63 | --version) i=$((i+1)); ARG_VERSION="${_args[$i]:-}" ;; |
| 64 | --parallelism=*) ARG_PARALLELISM="${tok#--parallelism=}" ;; |
| 65 | --parallelism) i=$((i+1)); ARG_PARALLELISM="${_args[$i]:-}" ;; |
| 66 | --max-mermaid-nodes=*) ARG_MAX_MERMAID="${tok#--max-mermaid-nodes=}" ;; |
| 67 | --max-mermaid-nodes) i=$((i+1)); ARG_MAX_MERMAID="${_args[$i]:-}" ;; |
| 68 | --force) ARG_FORCE="1" ;; |
| 69 | --reprobe) ARG_REPROBE="1" ;; |
| 70 | esac |
| 71 | i=$((i+1)) |
| 72 | done |
| 73 | |
| 74 | # Usage block if required flags missing. Agent reads stderr, |
| 75 | # prints verbatim, and stops — does NOT pre-run main.py. |
| 76 | if [ -z "$ARG_ORG" ] || [ -z "$ARG_AGENT" ]; then |
| 77 | cat >&2 <<'USAGE' |
| 78 | > Which agent should I document, and in which org? |
| 79 | > |
| 80 | > I need: |
| 81 | > - **Agent API name** — the BotDefinition.DeveloperName (e.g. `MyAgent`) |
| 82 | > - **Org alias** — for `sf` CLI auth (the alias you configured with `sf org login`) |
| 83 | > |
| 84 | > Optional flags: |
| 85 | > - `--version v5` — pin a specific BotVersion (default: Active+highest) |
| 86 | > - `--force` — bypass cache |
| 87 | > - `--reprobe` — force channel-probe refresh |
| 88 | > - `--parallel |