-
Notifications
You must be signed in to change notification settings - Fork 0
feat(mcp): add SSE transport, tools command, and multi-client install support #102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
776da67
feat(entity): add hidden _id column to wrapped entities
moshloop f44c71c
feat(api): add stack trace parsing and rendering with source resolution
moshloop 1b9788d
feat(examples): Add syntax highlighting and stack trace rendering sup…
moshloop 7db2f25
feat(mcp): Add fluent Builder API and discover-tools MCP tool
moshloop 4fece21
feat(mcp): add SSE transport, tools command, and multi-client install…
moshloop a0e00b6
chore(deps): clean up unused dependencies in go.sum
moshloop 37cc4d7
feat(api,flags): add unified diff rendering and grouped flag help output
moshloop f68560c
build(makefile): add git commit and build date to binary via ldflags
moshloop dfebb7d
refactor(api,mcp,rpc): extract helper functions and improve code orga…
moshloop 275d813
feat(entity): add WithOptionalID for actions with flag-supplied targets
moshloop 8065786
feat(rpc,cobra): Support rich error rendering and configurable conver…
moshloop b7f8c4a
fix(task): treat StatusWarning as terminal state to freeze endTime
moshloop 4dcafc7
chore(deps): update dependencies to latest versions
moshloop b9f1a94
chore(deps): update dependencies to latest versions
moshloop 6986348
docs(readme): simplify and restructure README for clarity and brevity
moshloop 419452b
chore(deps): update Go dependencies in examples module
moshloop File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package clicky | ||
|
|
||
| import ( | ||
| "errors" | ||
| "fmt" | ||
| "testing" | ||
|
|
||
| "github.com/flanksource/clicky/api" | ||
| ) | ||
|
|
||
| // prettyErr is a test error that carries a clicky rendering interface — | ||
| // the shape renderableError must detect so the command runner renders it | ||
| // through the format pipeline instead of collapsing it to Error(). | ||
| type prettyErr struct{ msg string } | ||
|
|
||
| func (e *prettyErr) Error() string { return e.msg } | ||
| func (e *prettyErr) Pretty() api.Text { return api.Text{Content: "rendered: " + e.msg} } | ||
|
|
||
| func TestRenderableError_DetectsErrorImplementingPretty(t *testing.T) { | ||
| rich, ok := renderableError(&prettyErr{msg: "boom"}) | ||
| if !ok { | ||
| t.Fatalf("renderableError must detect an error implementing Pretty()") | ||
| } | ||
| if api.TryTypedValue(rich) == nil { | ||
| t.Fatalf("the returned value must be renderable by the format pipeline") | ||
| } | ||
| } | ||
|
|
||
| func TestRenderableError_WalksWrappedChain(t *testing.T) { | ||
| // A fmt-wrapped rich error must still be detected — clicky walks the | ||
| // Unwrap chain so a renderable cause survives an outer fmt.Errorf. | ||
| wrapped := fmt.Errorf("dispatching: %w", &prettyErr{msg: "boom"}) | ||
| rich, ok := renderableError(wrapped) | ||
| if !ok { | ||
| t.Fatalf("renderableError must walk the Unwrap chain to find a renderable cause") | ||
| } | ||
| if _, isPretty := rich.(*prettyErr); !isPretty { | ||
| t.Fatalf("renderableError must return the matched *prettyErr, got %T", rich) | ||
| } | ||
| } | ||
|
|
||
| func TestRenderableError_PlainErrorIsNotRenderable(t *testing.T) { | ||
| // A plain error carries no rendering interface — the command runner | ||
| // must fall back to logging Error(), not the render pipeline. | ||
| if _, ok := renderableError(errors.New("plain failure")); ok { | ||
| t.Fatalf("a plain error must not be reported as renderable") | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
In Go (1.20+), does errors.Unwrap traverse errors that implement Unwrap() []error (e.g., errors.Join or fmt.Errorf with multiple %w), or only Unwrap() error?💡 Result:
In Go (1.20+), the errors.Unwrap function only traverses errors that implement the Unwrap error method [1][2]. It does not traverse errors that implement Unwrap []error (such as those created by errors.Join) [1][3]. If you call errors.Unwrap on an error that implements only Unwrap []error, it will return nil [1][2]. While the errors.Is and errors.As functions are designed to handle both Unwrap error and Unwrap []error (performing a depth-first search through the error tree for the latter) [4][2][5], the errors.Unwrap function remains restricted to the standard linked-list style of unwrapping [1][3]. If you need to access multiple errors joined together, you must perform a type assertion to the interface that provides the Unwrap []error method [6]: if uw, ok:= err.(interface{ Unwrap []error }); ok { errs:= uw.Unwrap // process the slice of errors }
Citations:
Handle joined/multi-error unwrapping in
renderableErrorrenderableErrorwalks onlyerrors.Unwrap(e)(singleUnwrap() errorchain), so it will miss renderable causes reachable viaUnwrap() []error(e.g.,errors.Join(...)orfmt.Errorfwith multiple%w). Switch to anerrors.As-based approach forapi.TryTypedValue’s target type, or explicitly traverseinterface{ Unwrap() []error }in addition toUnwrap() errorto keep rich error formatting consistent.🤖 Prompt for AI Agents