Use the `untaped ansible` command to map Ansible role and project dependencies across GitHub repositories (what a role depends on, what depends on it, which projects reach a repo, and dependency graphs). Use when the user mentions Ansible roles, requirements.yml, meta/main.yml dependencies, impact or blast-radius analysis, who uses a role, or a dependency graph.
Resources
1Install
npx skillscat add alexisbeaulieu97/untaped/untaped-ansible Install via the SkillsCat registry.
SKILL.md
Untaped Ansible
Use this skill when the user wants an agent to operate the untaped ansible CLI for Ansible dependency graphing and impact analysis.
Details that do not fit here ship next to this file:
| File | Read it when |
|---|---|
| references/sources.md | managing saved sources, source aliases, refresh backends, partial or resumable refreshes, the SQLite cache |
| references/graphs.md | ref and repo resolution, unpinned dependencies, local targets, tree and JSON graph output, skipped dependency files |
Setup
- The command is
untaped ansible. It ships with the unifieduntapedCLI (no separate install). - Settings live under
profiles.<name>.ansible; source aliases and sources areansiblestate in~/.untaped/state.yml. untaped ansibleanalyzes Ansible project roots and roles. Collections in requirements files are not traversed;source refresh,--refreshon the graph commands, and local targets print one warning line listing the ignored collections (live GitHub reads do not).- GitHub API access belongs to
untaped github; do not duplicate GitHub client behavior inside Ansible workflows.
Command Patterns
- Pick the command by question:
deps ROLE(what ROLE depends on, downstream),impact ROLE(what depends on ROLE, upstream; needs a source),find REPO --root ROOTor--stdin(which roots contain REPO downstream). They print rows (--format table|json|yaml|pipe|raw,--columns) and default to--depth unlimited.graph TARGETrenders the whole graph astree(default),mermaidorjson(--out FILE), both directions by default (--upstream/--downstream/--both), default--depth 3. depsrows (ansible.dependency) andimpactrows (ansible.dependent) carryrepo,ref,unresolved(declared name of a dependency with no GitHub repo),declared_ref/declared_in(verbatim, from the edge that reached it),depth, the shortestpathin dependency order (from ROLE fordeps, towards ROLE forimpact) androot_ref; one row per repo per root, and a ref-less ROLE is walked from each of its refs (root_reftells them apart). Warnings go to stderr.ansible.default_sourcenames the saved sourcedeps,impact,findandgraphuse whenever neither--sourcenor inline selectors are given; an unknown name fails naming the setting.impactwithout any source fails;graphwithout one omits upstream with a warning. Setting it switchesdeps/find/graphdownstream reads from live GitHub to the source cache (roles outside it warn "not cached" and give no rows; before the first refresh they fail with the refresh command);--livereads GitHub anyway.- Saved sources are selected with repeatable
--source NAME; repeated sources are additive. - Inline selectors such as
--org,--team,--repo,--path,--ref-kind,--ref-pattern, and--ref-scan-defaultare also additive where accepted. --liveis the explicit opt-in for live GitHub downstream reads when a source is selected; it works even before the source's first refresh (withgraph --both, upstream is then omitted with a warning).impacthas no--live. Without any source, downstream reads are always live, for remote and local targets alike; a local target with no GitHub token stays offline and warns that transitive dependencies were not expanded.--refresh,--cached, and--liveare mutually exclusive, as are--upstream,--downstream, and--both; conflicting flags are usage errors (exit 2).--refreshalso requires--source, inline source boundary selectors (--org,--team, or--repo), oransible.default_source; modifiers such as--path,--ref-kind,--ref-pattern, and--ref-scan-defaultdo not count by themselves.--teamaccepts ORG/SLUG; a bare SLUG is allowed when exactly one--orgis given and normalizes to ORG/SLUG.- Repeating the identical command with inline source selectors reuses the cached scan.
find REPO...(owner/repo, URL, or source alias; several to find any) searches downstream from roots given with repeatable--root owner/repo[@ref]or read with--stdin(bareowner/repo@reflines, or pipe records withscm_url/repo_url/repo/full_nameandeffective_scm_ref/ref, e.g.awx job-templates list --with-scm --format pipe). It prints oneansible.dependency_matchrow per matched node (root_repo,root_ref,repo,declared_refverbatim,declared_in, shortestpath, plus the input record'sinput_kind/input_id/input_name,nullfor--rootand bare lines), and nothing for roots that never reach it. Every input record gets its own rows even when records share a root, so results join back to the inputs (for example to the job templates to test). Searches the full graph unless--depth Nis given (then an empty result sayswithin --depth N); honors--sourceand the refresh flags.- Row-style commands (
deps,impact,find,source-alias list,source list,source get,source status) accept--format pipefor typed NDJSON:untaped ansible source list --format pipeemits one{"untaped":"1","kind":"ansible.source","record":{...}}line per row (kinds:ansible.dependency,ansible.dependent,ansible.dependency_match,ansible.source_alias,ansible.source,ansible.source_status).graphhas no pipe output.
Agent Guidance
- Prefer
deps/impact/findrows as JSON or pipe for machine reasoning,graphtree output for human impact reports, and Mermaid only when the user wants a diagram. - Do not collapse refs. A dependency at
repo@v1is distinct fromrepo@main. - Treat graph cycle reports as depth-bounded evidence, not proof that no longer cycle exists outside the emitted traversal horizon.
impactrequires refreshed source data; if unavailable, prompt the user to refresh or configure sources.- Save a source with
untaped ansible source set platform --org acmeand index it withuntaped ansible source refresh platform; see references/sources.md for everything else about sources. - Exit codes: 0 success, 1 failure (including a refresh with failed repos, whose successes are saved), 2 usage error, 4 fix the environment (
ansible.*orgithub.*settings, a rejected GitHub token, git missing), 5 temporary (a timeout, network error or rate limit, including a paused refresh; retry later), 130 interrupted. With--format jsonstderr is JSON Lines with each error'scategory,systemandhint.