From test-engineering
Performs the C# half of RPC discovery. The goal is to find all C# RPC library wrapper methods. Note that the output of some files may be large, so keep that in mind when issuing tool calls.
npx claudepluginhub issacchaos/local-marketplace --plugin test-engineeringThis skill uses the workspace's default tool permissions.
Performs the C# half of RPC discovery. The goal is to find all C# RPC library wrapper methods. Note that the output of some files may be large, so keep that in mind when issuing tool calls.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Performs the C# half of RPC discovery. The goal is to find all C# RPC library wrapper methods. Note that the output of some files may be large, so keep that in mind when issuing tool calls.
RPC wrapper methods live in C# library files. Each file has a name like SampleRpcLibrary.cs or AutomationRpcLibrary.cs. Use the pattern *RpcLibrary*.cs to find them, as different projects may have different naming standards.
Each library file contains public static methods that wrap RPC calls. They look something like the following example. The method name is the canonical RPC name (strip trailing Async if present). Inside each method body, CallRpc is invoked with the actual RPC name string, which may differ from the method name.
// Sync method — return type is simple (void/bool)
public static void LoginUser(AutomationRpcClient client, string username, string password)
{
client.CallRpc(client, "LoginUser", new Dictionary<string, object>
{
{ "username", username },
{ "password", password }
});
}
// Async method — return type is structured (Task<T>)
public static async Task<PlayerStatusResponse> GetPlayerStatusAsync(AutomationRpcClient client, string playerId)
{
return await client.CallRpc<PlayerStatusResponse>(client, "GetPlayerStatus", new Dictionary<string, object>
{
{ "playerId", playerId }
});
}
// Method name may differ from the RPC name string
public static void TeleportToPosition(AutomationRpcClient client, float x, float y, float z)
{
client.CallRpc(client, "BotTeleport", new Dictionary<string, object>
{
{ "x", x }, { "y", y }, { "z", z }
});
}
CRITICAL: ALL file discovery and content searches (that do not target a specific file) MUST follow this protocol. Searches that do not apply exclude patterns WILL cause tool timeouts and failures in Unreal Engine projects due to large generated/cached directories (Content, Intermediate, ThirdParty, etc.).
Use Bash with rg (ripgrep) for ALL recursive file and content searches. Do NOT use the Glob tool or Grep tool for recursive codebase searches, because:
Glob tool has no exclude support — it will scan into ThirdParty, Intermediate, Content, etc. and time out.Grep tool only accepts a single glob pattern — it cannot combine an include pattern with multiple exclude patterns.exclude_args:
- "ThirdParty/"
- "Intermediate/"
- "Content/"
- "Saved/"
- "DerivedDataCache/"
- "Binaries/"
- "Engine/"
- ".git/"
- "node_modules/"
File discovery (finding files by name pattern):
rg --files --iglob "{include_pattern}" {exclude_args} {targetPath}
Content search (finding text within files):
rg "{regex_pattern}" --iglob "{include_pattern}" {exclude_args} -n [-A N] {targetPath}
The agent receives a prompt from the orchestrator (spawned via Task tool) containing:
targetPath: {string}
excludePatterns: {JSON array of glob strings}
findingsDir: {string} # e.g., ".rpc/discovery/" or ".rpc/discovery/{project}/"
In a large project, the output may be a large number of RPCs. With that in mind, if necessary, write the output to a file so that the caller may read it given there is limited context.
The output should be a JSON object with the following structure:
{
"files_scanned": 6,
"rpcs": {
"LoginUser": [
{"file": "path/to/SampleRpcLibrary.cs", "line": 115, "method_name": "LoginUser", "async": false}
],
"GetPlayerStatus": [
{"file": "path/to/SampleRpcLibrary.cs", "line": 181, "method_name": "GetPlayerStatus", "async": false},
{"file": "path/to/SampleAsyncRpcLibrary.cs", "line": 42, "method_name": "GetPlayerStatusAsync", "async": true}
]
},
"notes": []
}
Fields:
files_scanned: Count of unique .cs files examined (library files + test case files combined).rpcs: Map of canonical RPC name → array of callsite objects. Each callsite has file, line, method_name, and async flag.notes: Informational messages (duplicates, unrecognized patterns, etc.).If no C# files are found, return:
{"files_scanned": 0, "rpcs": {}, "notes": ["No *RpcLibrary*.cs files found in {targetPath}"]}
IMPORTANT: The final line of the response MUST be the JSON object (or a markdown code block containing only the JSON object). The orchestrator parses the last JSON-parseable block from the response.
The findings cache preserves project-specific patterns discovered during scanning so that subsequent runs can benefit from prior knowledge. The cache is a markdown file at {findingsDir}csharp-findings.md.
Before starting the search, attempt to read {findingsDir}csharp-findings.md.
*RpcLibrary*.cs, CallRpc).After completing discovery and assembling the output JSON, write (or overwrite) {findingsDir}csharp-findings.md with the patterns you discovered during this scan. Use your judgment about what is useful to record. Include any information you might be able to use to do this scan again. Good candidates include:
SampleRpcLibrary.cs, FortRpcLibrary.cs)CallRpc is invoked (e.g., client.CallRpc(client, "Name", ...) vs other calling conventions)MethodNameAsync)Task<T> with specific T types)Keep the file concise and factual. Write what you observed, not general documentation about C# patterns. Example structure:
# C# RPC Discovery Findings
## File Patterns
- Library files: `SampleRpcLibrary.cs`, `SampleAsyncRpcLibrary.cs`
- Located in: `rpc-scaffold/test_fixtures/`
## Method Patterns
- Sync: `public static void MethodName(AutomationRpcClient client, ...)`
- Async: `public static async Task<T> MethodNameAsync(AutomationRpcClient client, ...)`
- Client type: `AutomationRpcClient`
## RPC Invocation
- Sync: `client.CallRpc(client, "RpcName", new Dictionary<string, object> { ... })`
- Async: `await client.CallRpc<T>(client, "RpcName", new Dictionary<string, object> { ... })`
## Notes
- Both sync and async variants exist for some RPCs
- Method names sometimes differ from RPC name strings (e.g., TeleportToPosition → BotTeleport)
- 6 library files found
Error handling: If the Write fails, log a warning and continue — the findings cache is not critical to the scan results.