feat: add rich signatures, schema expansion, and examples#4
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4fffeed. Configure here.
| if (nullable) | ||
| return "null"; | ||
|
|
||
| var normalized = NormalizeType(type); |
There was a problem hiding this comment.
Collection examples show element value instead of array
High Severity
CreateExampleLiteral calls NormalizeType which unwraps collection types (e.g. List<string> → string, int[] → int) before the simple-type checks run. The collection check on lines 466–475 uses the original type, but execution never reaches it because the normalized element type already matched a simple-type branch. For example, List<int> returns "123" and List<string> returns "\"example\"" instead of "[]". This visibly affects the sample ChatHub.JoinRoom roles parameter and ChatMessagePayload.Tags property.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 4fffeed. Configure here.
| return $"{FormatType(type.GetElementType()!)}[]"; | ||
|
|
||
| if (TryGetKeywordAlias(type, out var alias)) | ||
| return alias; |
There was a problem hiding this comment.
Nullable keyword-aliased types missing question mark suffix
Medium Severity
FormatTypeWithNullability returns the keyword alias immediately when TryGetKeywordAlias matches, without considering the nullableReference flag. For nullable reference types with keyword aliases (e.g. string?, object?), the output is "string" instead of "string?". The nullability suffix logic on lines 257–258 and 268–269 is only reachable for types that don't have a keyword alias.
Reviewed by Cursor Bugbot for commit 4fffeed. Configure here.
|
|
||
| public static class Extensions | ||
| { | ||
| private static readonly NullabilityInfoContext NullabilityContext = new(); |
There was a problem hiding this comment.
Static NullabilityInfoContext is not thread-safe
Medium Severity
NullabilityInfoContext is stored as a private static readonly field and accessed from the /hubdocs/hubdocs.json HTTP endpoint handler, which can serve concurrent requests. NullabilityInfoContext is not thread-safe — its internal dictionary cache can throw InvalidOperationException or ArgumentException when accessed concurrently. Creating a new instance per invocation avoids this.
Reviewed by Cursor Bugbot for commit 4fffeed. Configure here.


Note
Medium Risk
Changes the shape and contents of
hubdocs.json(new fields for signatures/parameters/schemas/examples) and adds reflection-based schema generation, which could break existing consumers or produce unexpected output for complex types/nullability.Overview
HubDocs metadata output is expanded: hub and client methods now include full
Signature, typedParameters(with nullability), and example invocations/return examples, and hubs expose a newSchemassection describing discovered DTO/enums used by method parameters/returns.Reflection/type formatting was upgraded to use C# keyword aliases (e.g.
int,string), handleTask/Task<T>return signatures, and derive nullable reference info viaNullabilityInfoContext; unit tests were updated accordingly.The UI (
hubdocs.html) now renders signatures, examples, pre-fills Try It inputs from examples, and shows the new schema browser. The sampleChatHubadds a rich-message payload + enum and newSendRichMessage/ReceiveRichMessagemethods to exercise the schema output.Reviewed by Cursor Bugbot for commit 4fffeed. Bugbot is set up for automated code reviews on this repo. Configure here.