一键导入
rmc-api-surface
Audit a Rust crate's public API.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Audit a Rust crate's public API.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Preview a Rust symbol rename — exact reference set & refactor probe.
Enforce Rust crate-edge rules.
Audit Rust attributes and doc-comments.
Rust fn-level call graphs.
Task-conditioned workspace subgraph — nodes, edges, hierarchy.
Rust complexity hotspots by blast radius.
| name | rmc-api-surface |
| description | Audit a Rust crate's public API. |
| argument-hint | <crate-name> |
| allowed-tools | Read, mcp__rust-code-mcp__* |
Catch over-broad facades, accidental internals exposure, and dead public surface. Scope: single crate.
For workspace-wide imports/exports, use rmc-imports-exports. For
refactor-specific recipes (drop facade, demote pub), use rmc-refactor-plan.
build_hypergraph(directory=<absolute-path>)
get_declared_reexports(directory=..., module=<crate_root>)
get_exports(directory=..., module=<crate_root>, consumer=<external_crate>)
module_tree(directory=..., krate=<crate>) → filter to pub items
dead_pub_in_crate(directory=..., krate=<crate>)
| Source | Meaning |
|---|---|
module_tree (visibility=pub) | What's pub at canonical site |
get_declared_reexports | What's re-exported via pub use at the crate root |
get_exports(consumer=<other>) | What's actually visible from outside (visibility-filtered) |
dead_pub_in_crate | Pub items with no cross-crate consumer |
For each declared re-export, look up canonical-path traffic:
who_imports(directory=..., target=<canonical_path>)
Most importers reaching for the canonical path means the facade isn't being used. Drop it.
Items in get_declared_reexports that the team thought were pub(crate).
These usually slip in via pub use submodule::* patterns.
If a pub use chain can become pub(crate) use, the source can be
pub(crate). dead_pub_in_crate already finds these.
| Empty result | Means |
|---|---|
get_declared_reexports([]) | Crate has no facade — everything at canonical paths. Intentional design. |
dead_pub_in_crate([]) | No dead pubs — disciplined. |
overlaps.common_fn_names([]) | No init / run proliferation — good hygiene. |
| Finding | Action |
|---|---|
Re-export declared at root, target dead in dead_pub_in_crate | Drop pub use, demote source |
Pub item at canonical site, dead in dead_pub_in_crate | Demote to pub(crate) |
Item in get_declared_reexports that looks crate-internal | Probably accidentally exposed; demote |
| Re-export AND canonical declaration of same item | Pick one path; drop the other |
get_exports(consumer=X) smaller than get_declared_reexports | Visibility filter is trimming pub(crate) / pub(in <crate>) items (intentional discipline) |
| Signal | Means |
|---|---|
pub use foo::* at crate root | Likely over-broad facade; audit each item |
Crate's get_declared_reexports ⊆ dead_pub_in_crate | Entire facade is dead — drop wholesale |
get_exports(consumer=X) smaller than get_declared_reexports | Visibility filter trimming pub(crate) / pub(in <crate>) items |
Every facade item has who_imports only on the facade path | Facade is earning its keep |
Every facade item has who_imports only on canonical path | Facade is dead weight |
Crate: <crate>
Declared re-exports: <n>
Effective exports to <consumer>: <m>
Dead pubs: <k>
Dead facade re-exports (intersection): <j>
Recommended:
- Drop pub use for: <list>
- Demote to pub(crate): <list>
- Already healthy: <list of items earning their pub keyword>
Severity-ranked findings:
🔴 High — Crate-internal type accidentally exposed via pub use
🟡 Medium — Dead facade re-export
🟡 Medium — Dead canonical pub
🟢 Low — Over-broad pub use glob (audit each item)
⚪ Info — Healthy facade; intentional no-facade design
tui in coding-agent-bad15 submodules. 7 dead pubs of which 3 are dead re-exports at the crate
root (RunState, InvalidTransition, RunnerWakeError — all
re-exported AND dead). Sensible pub(in tui) discipline for
crate-internal helpers. Cleanup: drop three pub use lines, demote
source types to pub(crate).
get_exports(consumer=X) requires X to be a valid crate name in the
workspace. Pass a non-existent name and you get an empty result, not
an error.pub use submodule::* glob re-exports surface as one row per
re-exported item, not one row per glob — verify by reading source if
the glob is the actual smell.dead_pub_in_crate counts cross-crate consumers only; within-crate
test usage still flags as dead.