feat: enhance response of querying convention #58
Merged
Conversation
Contributor
sehwan505
commented
Dec 14, 2025
- convention 반환할 때 명령 추가해서 반환
- category input 여러개 입력 가능
There was a problem hiding this comment.
Pull request overview
This PR enhances the convention querying functionality by allowing multiple category filters and improving the response format. The changes make the API more flexible by accepting an array of categories instead of a single category string, and restructure the output to be more suitable for AI coding assistants.
Key Changes:
- Parameter renamed from singular
categoryto pluralcategories, now accepting an array of strings - Response format enhanced with a structured, prompt-style output that groups conventions by category and includes clear instructions
- New helper functions
normalizeCategories()andmatchesCategories()implement the multi-category filtering logic
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| internal/mcp/server.go | Implements multiple category filtering with new helper functions, updates struct definitions, and adds buildConventionPrompt() for enhanced response formatting |
| internal/mcp/server_test.go | Updates all test cases to use categories array parameter instead of singular category string |
Comments suppressed due to low confidence (1)
internal/mcp/server_test.go:219
- The test suite doesn't include a test case for querying multiple categories simultaneously (e.g., categories: ["security", "documentation"]). While single category queries are tested, the new capability to filter by multiple categories at once should have test coverage to ensure the OR logic works correctly.
t.Run("query all categories for javascript", func(t *testing.T) {
params := map[string]interface{}{
"categories": []interface{}{"all"},
"languages": []interface{}{"javascript"},
}
result, rpcErr := server.handleListConvention(params)
require.Nil(t, rpcErr)
require.NotNil(t, result)
resultMap := result.(map[string]interface{})
content := resultMap["content"].([]map[string]interface{})
text := content[0]["text"].(string)
t.Logf("Result: %s", text)
// Should find conventions
assert.NotContains(t, text, "No conventions found")
assert.Contains(t, text, "DOC-001")
assert.Contains(t, text, "SEC-001")
assert.Contains(t, text, "STYLE-001")
})
t.Run("query documentation category for javascript", func(t *testing.T) {
params := map[string]interface{}{
"categories": []interface{}{"documentation"},
"languages": []interface{}{"javascript"},
}
result, rpcErr := server.handleListConvention(params)
require.Nil(t, rpcErr)
require.NotNil(t, result)
resultMap := result.(map[string]interface{})
content := resultMap["content"].([]map[string]interface{})
text := content[0]["text"].(string)
t.Logf("Result: %s", text)
// Should find only documentation conventions
assert.Contains(t, text, "DOC-001")
assert.NotContains(t, text, "SEC-001")
assert.NotContains(t, text, "STYLE-001")
})
t.Run("query security category for typescript", func(t *testing.T) {
params := map[string]interface{}{
"categories": []interface{}{"security"},
"languages": []interface{}{"typescript"},
}
result, rpcErr := server.handleListConvention(params)
require.Nil(t, rpcErr)
require.NotNil(t, result)
resultMap := result.(map[string]interface{})
content := resultMap["content"].([]map[string]interface{})
text := content[0]["text"].(string)
t.Logf("Result: %s", text)
// Should find SEC-001 (supports typescript)
assert.Contains(t, text, "SEC-001")
assert.NotContains(t, text, "DOC-001") // javascript only
})
t.Run("query with unsupported language", func(t *testing.T) {
params := map[string]interface{}{
"categories": []interface{}{"all"},
"languages": []interface{}{"python"},
}
result, rpcErr := server.handleListConvention(params)
require.Nil(t, rpcErr)
require.NotNil(t, result)
resultMap := result.(map[string]interface{})
content := resultMap["content"].([]map[string]interface{})
text := content[0]["text"].(string)
t.Logf("Result: %s", text)
// Should return no conventions
assert.Contains(t, text, "No conventions found")
})
t.Run("rule without severity uses defaults", func(t *testing.T) {
params := map[string]interface{}{
"categories": []interface{}{"style"},
"languages": []interface{}{"javascript"},
}
result, rpcErr := server.handleListConvention(params)
require.Nil(t, rpcErr)
require.NotNil(t, result)
resultMap := result.(map[string]interface{})
content := resultMap["content"].([]map[string]interface{})
text := content[0]["text"].(string)
t.Logf("Result: %s", text)
// STYLE-001 doesn't have explicit severity, should use default "error"
assert.Contains(t, text, "STYLE-001")
assert.Contains(t, text, "[error]") // Should use default from policy
})
t.Run("empty parameters returns all conventions", func(t *testing.T) {
params := map[string]interface{}{}
result, rpcErr := server.handleListConvention(params)
require.Nil(t, rpcErr)
require.NotNil(t, result)
resultMap := result.(map[string]interface{})
content := resultMap["content"].([]map[string]interface{})
text := content[0]["text"].(string)
t.Logf("Result: %s", text)
// Should return all conventions when no filters specified
assert.Contains(t, text, "DOC-001")
assert.Contains(t, text, "SEC-001")
assert.Contains(t, text, "STYLE-001")
})
t.Run("only category specified", func(t *testing.T) {
params := map[string]interface{}{
"categories": []interface{}{"security"},
}
result, rpcErr := server.handleListConvention(params)
require.Nil(t, rpcErr)
require.NotNil(t, result)
resultMap := result.(map[string]interface{})
content := resultMap["content"].([]map[string]interface{})
text := content[0]["text"].(string)
t.Logf("Result: %s", text)
// Should return only security conventions
assert.Contains(t, text, "SEC-001")
assert.NotContains(t, text, "DOC-001")
})
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Instructions section | ||
| sb.WriteString("---\n\n") | ||
| sb.WriteString("## Instructions\n\n") | ||
| sb.WriteString("1. Apply all conventions above when writing code(without configuration files)\n") |
There was a problem hiding this comment.
Missing space before the opening parenthesis in "code(without configuration files)". Should be "code (without configuration files)".
Suggested change
| sb.WriteString("1. Apply all conventions above when writing code(without configuration files)\n") | |
| sb.WriteString("1. Apply all conventions above when writing code (without configuration files)\n") |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.