Skip to content

Commit 4e76fdf

Browse files
Copilotalexec
andcommitted
Automatically set rule ID to filename if not in frontmatter
- Modified rule loading to auto-set ID from filename (without extension) - Simplified MCPServers() since ID is now always set - Updated tests to reflect auto-generated IDs - Added integration test to verify ID auto-generation behavior Co-authored-by: alexec <1142830+alexec@users.noreply.github.com>
1 parent e388f80 commit 4e76fdf

File tree

4 files changed

+61
-17
lines changed

4 files changed

+61
-17
lines changed

pkg/codingcontext/context.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,13 @@ func (cc *Context) findExecuteRuleFiles(ctx context.Context, homeDir string) err
516516
return fmt.Errorf("failed to parse markdown file %s: %w", path, err)
517517
}
518518

519+
// Automatically set ID to filename (without extension) if not set in frontmatter
520+
if frontmatter.ID == "" {
521+
baseName := filepath.Base(path)
522+
ext := filepath.Ext(baseName)
523+
frontmatter.ID = strings.TrimSuffix(baseName, ext)
524+
}
525+
519526
// Expand parameters only if expand is not explicitly set to false
520527
var processedContent string
521528
if shouldExpandParams(frontmatter.ExpandParams) {

pkg/codingcontext/context_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,46 @@ func TestContext_Run_Rules(t *testing.T) {
699699
}
700700
},
701701
},
702+
{
703+
name: "rule IDs automatically set from filename",
704+
setup: func(t *testing.T, dir string) {
705+
createTask(t, dir, "id-task", "", "Task")
706+
createRule(t, dir, ".agents/rules/my-rule.md", "", "Rule without ID in frontmatter")
707+
createRule(t, dir, ".agents/rules/another-rule.md", "id: explicit-id", "Rule with explicit ID")
708+
},
709+
taskName: "id-task",
710+
wantErr: false,
711+
check: func(t *testing.T, result *Result) {
712+
if len(result.Rules) != 2 {
713+
t.Fatalf("expected 2 rules, got %d", len(result.Rules))
714+
}
715+
716+
// Check that one rule has auto-generated ID from filename
717+
foundMyRule := false
718+
foundAnotherRule := false
719+
for _, rule := range result.Rules {
720+
if rule.FrontMatter.ID == "my-rule" {
721+
foundMyRule = true
722+
if !strings.Contains(rule.Content, "Rule without ID") {
723+
t.Error("my-rule should contain 'Rule without ID'")
724+
}
725+
}
726+
if rule.FrontMatter.ID == "explicit-id" {
727+
foundAnotherRule = true
728+
if !strings.Contains(rule.Content, "Rule with explicit ID") {
729+
t.Error("explicit-id should contain 'Rule with explicit ID'")
730+
}
731+
}
732+
}
733+
734+
if !foundMyRule {
735+
t.Error("expected to find rule with auto-generated ID 'my-rule'")
736+
}
737+
if !foundAnotherRule {
738+
t.Error("expected to find rule with explicit ID 'explicit-id'")
739+
}
740+
},
741+
},
702742
}
703743

704744
for _, tt := range tests {

pkg/codingcontext/result.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package codingcontext
22

33
import (
4-
"fmt"
5-
64
"github.com/kitproj/coding-context-cli/pkg/codingcontext/markdown"
75
"github.com/kitproj/coding-context-cli/pkg/codingcontext/mcp"
86
"github.com/kitproj/coding-context-cli/pkg/codingcontext/skills"
@@ -22,21 +20,17 @@ type Result struct {
2220
// Each rule can specify one MCP server configuration.
2321
// Returns a map from rule ID to MCP server configuration.
2422
// Empty/zero-value MCP server configurations are filtered out.
25-
// Rules without an ID field are included with a generated key "rule-<index>".
23+
// The rule ID is automatically set to the filename (without extension) if not
24+
// explicitly provided in the frontmatter.
2625
func (r *Result) MCPServers() map[string]mcp.MCPServerConfig {
2726
servers := make(map[string]mcp.MCPServerConfig)
2827

2928
// Add server from each rule, filtering out empty configs
30-
for i, rule := range r.Rules {
29+
for _, rule := range r.Rules {
3130
server := rule.FrontMatter.MCPServer
3231
// Skip empty MCP server configs (no command and no URL means empty)
3332
if server.Command != "" || server.URL != "" {
34-
// Use the rule's ID as the key, or generate one if not present
35-
key := rule.FrontMatter.ID
36-
if key == "" {
37-
key = fmt.Sprintf("rule-%d", i)
38-
}
39-
servers[key] = server
33+
servers[rule.FrontMatter.ID] = server
4034
}
4135
}
4236

pkg/codingcontext/result_test.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,18 @@ func TestResult_MCPServers(t *testing.T) {
111111
},
112112
},
113113
{
114-
name: "MCP servers from rules without IDs",
114+
name: "MCP servers from rules without explicit IDs in frontmatter",
115115
result: Result{
116116
Rules: []markdown.Markdown[markdown.RuleFrontMatter]{
117117
{
118118
FrontMatter: markdown.RuleFrontMatter{
119+
ID: "rule-file-1", // ID is auto-set to filename during loading
119120
MCPServer: mcp.MCPServerConfig{Type: mcp.TransportTypeStdio, Command: "server1"},
120121
},
121122
},
122123
{
123124
FrontMatter: markdown.RuleFrontMatter{
125+
ID: "rule-file-2", // ID is auto-set to filename during loading
124126
MCPServer: mcp.MCPServerConfig{Type: mcp.TransportTypeStdio, Command: "server2"},
125127
},
126128
},
@@ -130,8 +132,8 @@ func TestResult_MCPServers(t *testing.T) {
130132
},
131133
},
132134
want: map[string]mcp.MCPServerConfig{
133-
"rule-0": {Type: mcp.TransportTypeStdio, Command: "server1"},
134-
"rule-1": {Type: mcp.TransportTypeStdio, Command: "server2"},
135+
"rule-file-1": {Type: mcp.TransportTypeStdio, Command: "server1"},
136+
"rule-file-2": {Type: mcp.TransportTypeStdio, Command: "server2"},
135137
},
136138
},
137139
{
@@ -185,23 +187,24 @@ func TestResult_MCPServers(t *testing.T) {
185187
},
186188
},
187189
{
188-
name: "mixed rules with and without IDs",
190+
name: "mixed rules with explicit and auto-generated IDs",
189191
result: Result{
190192
Rules: []markdown.Markdown[markdown.RuleFrontMatter]{
191193
{
192194
FrontMatter: markdown.RuleFrontMatter{
193-
ID: "explicit-id",
195+
ID: "explicit-id", // Explicit ID in frontmatter
194196
MCPServer: mcp.MCPServerConfig{Type: mcp.TransportTypeStdio, Command: "server1"},
195197
},
196198
},
197199
{
198200
FrontMatter: markdown.RuleFrontMatter{
201+
ID: "some-rule", // ID auto-set to filename during loading
199202
MCPServer: mcp.MCPServerConfig{Type: mcp.TransportTypeStdio, Command: "server2"},
200203
},
201204
},
202205
{
203206
FrontMatter: markdown.RuleFrontMatter{
204-
ID: "another-id",
207+
ID: "another-id", // Explicit ID in frontmatter
205208
MCPServer: mcp.MCPServerConfig{Type: mcp.TransportTypeHTTP, URL: "https://example.com"},
206209
},
207210
},
@@ -212,7 +215,7 @@ func TestResult_MCPServers(t *testing.T) {
212215
},
213216
want: map[string]mcp.MCPServerConfig{
214217
"explicit-id": {Type: mcp.TransportTypeStdio, Command: "server1"},
215-
"rule-1": {Type: mcp.TransportTypeStdio, Command: "server2"},
218+
"some-rule": {Type: mcp.TransportTypeStdio, Command: "server2"},
216219
"another-id": {Type: mcp.TransportTypeHTTP, URL: "https://example.com"},
217220
},
218221
},

0 commit comments

Comments
 (0)