Skip to content

Commit 4c030f9

Browse files
CopilotalexecCopilot
authored
Add standard frontmatter fields with typed generic Markdown (metadata-only) (#122)
* Initial plan * Add standard frontmatter fields for tasks and rules - Implemented agent field as default selector (filters rules) - Implemented language field as default selector (supports string or array) - Added model, single_shot, timeout, mcp_servers as metadata fields - Added comprehensive tests for all new functionality - Updated documentation with detailed examples - Added example files demonstrating standard fields Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> * Improve agent field handling consistency Use type switching for agent field similar to language field for better consistency and code clarity Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> * Fix language casing, timeout format, agent behavior, and add types - Changed all language examples from uppercase (Go, Python, JavaScript) to lowercase (go, python, javascript) - Updated timeout field to use time.Duration format (e.g., "10m") instead of numeric seconds - Fixed agent field behavior: now excludes agent's own directories (like -a flag) instead of acting as selector - Added types.go with TaskFrontMatter and RuleFrontMatter struct definitions - Updated all tests to reflect new behavior - Updated documentation to correctly describe agent field behavior Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> * Add warning log for invalid agent names Log a warning when an invalid agent name is found in task frontmatter to help users identify configuration issues Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> * Refactor FrontMatter to struct and split types into separate files - Changed FrontMatter from type alias to struct with Content field - Made TaskFrontMatter and RuleFrontMatter extend FrontMatter - Split types into separate files (frontmatter.go, task_frontmatter.go, rule_frontmatter.go) - Added MCP server config types in pkg/config package - Updated all code and tests to work with new FrontMatter structure - All tests passing Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> * Move MCP types from pkg/config to pkg/codingcontext Moved all MCP server configuration types to pkg/codingcontext package as requested Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> * Make Markdown generic and update frontmatter types per review - Made Markdown generic: Markdown[T any] with TaskMarkdown and RuleMarkdown type aliases - Added NewFrontMatter() and NewTaskFrontMatter() constructor functions - Deleted Config type from mcp_config.go as requested - Removed ParseFrontmatter method (noop per review comment) - Changed TaskFrontMatter.Language to Languages []string with yaml tag languages - Changed RuleFrontMatter.TaskName to TaskNames []string with yaml tag task_names - Changed RuleFrontMatter.Language to Languages []string with yaml tag languages - Changed MCPServers to []MCPServerConfig in both frontmatter types - Updated all tests to reflect new field names and types - Updated example_test.go to work without ParseFrontmatter method Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> * Update docs/reference/file-formats.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Changes before error encountered Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> * Remove -a flag and add UnmarshalJSON for frontmatter types - Removed -a flag from CLI as requested - Added custom UnmarshalJSON methods to TaskFrontMatter and RuleFrontMatter - Renamed FrontMatter to BaseFrontMatter (base struct) - Updated all references throughout codebase - Fixed test files to use correct field names - All code compiles successfully Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> * Remove SyncToContent functions per review feedback - Removed SyncToContent() methods from TaskFrontMatter and RuleFrontMatter - Removed all calls to SyncToContent() in context.go - Removed unused yaml imports from frontmatter files - UnmarshalJSON already populates both typed fields and Content map, making sync functions unnecessary Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> * Remove automatic language filtering per review feedback - Removed automatic filtering loop for languages field (lines 470-474) - Languages field is now metadata only, does not filter rules - Only the explicit selectors field filters rules - Updated comments to clarify languages is metadata-only Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> * Refactor per review feedback: remove Path field, simplify agent handling, constrain Markdown generic - Removed Path field from Markdown struct (unreachable/unused) - Removed BootstrapPath() method (unreachable code) - Changed Markdown[T any] to Markdown[T FrontMatter] for type constraint - Removed agent default behavior check - agent field now always sets target agent when present - Removed unused filepath and strings imports from result.go Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> * Refactor: task matching and resume handling - Task names now based on filename instead of task_name frontmatter field - Removed resume flag (-r), resume is now a selector (-s resume=true) - Tasks no longer have bootstrap scripts (only rules do) - Language field is metadata only, not automatically added as selector - Updated all tests to reflect these changes * Reinstate -r flag and add WithResume option - Reinstated -r flag in main.go that was removed - Added WithResume option to codingcontext package - Updated findExecuteRuleFiles to check cc.resume directly - Added comprehensive tests for resume mode including bootstrap script verification - Resume mode now properly skips all rule discovery and bootstrap scripts * feat: reinstate -a flag and merge TargetAgent into Agent - Reinstated -a flag for specifying target agent - Merged TargetAgent type into Agent type - Renamed targetAgent field to agent throughout codebase - Agent type now handles both agent identification and exclusion logic - Task frontmatter agent field overrides -a flag when set - Excludes agent-specific paths and rules with matching agent field * feat: add MCPServers method to Result - Added Result.MCPServers() method to collect all MCP servers - Collects servers from both task and all included rules - Task servers included first, followed by rule servers - Added comprehensive tests for various scenarios --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> Co-authored-by: Alex Collins <alexec@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Alex Collins <alex_collins@intuit.com>
1 parent 668c728 commit 4c030f9

24 files changed

Lines changed: 1792 additions & 683 deletions

docs/reference/file-formats.md

Lines changed: 253 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,158 @@ task_name: fix-bug
4545
coding-context fix-bug
4646
```
4747

48+
#### `language` (optional, standard field)
49+
50+
**Type:** String or Array
51+
**Purpose:** Specifies the programming language(s) and automatically filters rules with matching language selector
52+
53+
The `language` field is a **standard frontmatter field** that acts as a default selector. When a task specifies a language, only rules with that same language value (or no language field) will be included in the context.
54+
55+
**Example (single language):**
56+
```yaml
57+
---
58+
task_name: implement-feature
59+
language: go
60+
---
61+
```
62+
63+
**Example (multiple languages with OR logic):**
64+
```yaml
65+
---
66+
task_name: polyglot-task
67+
language:
68+
- go
69+
- python
70+
- javascript
71+
---
72+
```
73+
74+
**Behavior:**
75+
- Rules with `language: go` are included (when task has `language: go`)
76+
- Rules without a `language` field are included (generic rules)
77+
- Rules with different language values are excluded
78+
- When multiple languages are specified, rules matching ANY of them are included (OR logic)
79+
80+
**Equivalent command-line usage:**
81+
```bash
82+
# These are equivalent:
83+
coding-context implement-feature # (task has language: go)
84+
coding-context -s language=go implement-feature
85+
```
86+
87+
#### `single_shot` (optional, standard field)
88+
89+
**Type:** Boolean
90+
**Purpose:** Indicates whether the task should be run once or many times; stored in frontmatter output but does not filter rules
91+
92+
The `single_shot` field is a **standard frontmatter field** that provides metadata about task execution. It does not act as a selector.
93+
94+
**Example:**
95+
```yaml
96+
---
97+
task_name: deploy
98+
single_shot: true
99+
---
100+
```
101+
102+
**Common values:**
103+
- `true` - Task runs once
104+
- `false` - Task can run multiple times
105+
106+
#### `timeout` (optional, standard field)
107+
108+
**Type:** String (time.Duration format)
109+
**Purpose:** Specifies the timeout duration for the task using Go's time.Duration format; stored in frontmatter output but does not filter rules
110+
111+
The `timeout` field is a **standard frontmatter field** that provides metadata about task execution limits. It does not act as a selector.
112+
113+
**Example:**
114+
```yaml
115+
---
116+
task_name: long-running-analysis
117+
timeout: 10m
118+
---
119+
```
120+
121+
**Common time.Duration formats:**
122+
- `30s` - 30 seconds
123+
- `5m` - 5 minutes
124+
- `1h` - 1 hour
125+
- `1h30m` - 1 hour 30 minutes
126+
127+
#### `mcp_servers` (optional, standard field)
128+
129+
**Type:** Array
130+
**Purpose:** Specifies the list of MCP (Model Context Protocol) servers that the task should use; stored in frontmatter output but does not filter rules
131+
132+
The `mcp_servers` field is a **standard frontmatter field** following the industry standard for MCP server definition. It does not act as a selector.
133+
134+
**Example:**
135+
```yaml
136+
---
137+
task_name: file-operations
138+
mcp_servers:
139+
- filesystem
140+
- git
141+
- database
142+
---
143+
```
144+
145+
**Note:** The format follows the MCP specification for server identification.
146+
147+
#### `agent` (optional, standard field)
148+
149+
**Type:** String
150+
**Purpose:** Specifies the target agent and automatically filters rules with matching agent selector
151+
152+
The `agent` field is a **standard frontmatter field** that acts as a default selector. When a task specifies an agent, only rules with that same agent value (or no agent field) will be included in the context.
153+
154+
**Example:**
155+
```yaml
156+
---
157+
task_name: implement-feature
158+
agent: cursor
159+
---
160+
```
161+
162+
**Supported agents:** `cursor`, `copilot`, `claude`, `gemini`, `opencode`, `augment`, `windsurf`, `codex`
163+
164+
**Behavior:**
165+
- Rules with `agent: cursor` are included
166+
- Rules without an `agent` field are included (generic rules)
167+
- Rules with different agent values (e.g., `agent: copilot`) are excluded
168+
169+
**Equivalent command-line usage:**
170+
```bash
171+
# These are equivalent:
172+
coding-context implement-feature # (task has agent: cursor)
173+
coding-context -a cursor implement-feature
174+
```
175+
176+
#### `model` (optional, standard field)
177+
178+
**Type:** String
179+
**Purpose:** Specifies the AI model to use; stored in frontmatter output but does not filter rules
180+
181+
The `model` field is a **standard frontmatter field** that provides metadata about which AI model should be used for the task. Unlike the `agent` field, the `model` field does not act as a selector and does not filter rules.
182+
183+
**Example:**
184+
```yaml
185+
---
186+
task_name: code-review
187+
agent: copilot
188+
model: anthropic.claude-sonnet-4-20250514-v1-0
189+
---
190+
```
191+
192+
**Common model values:**
193+
- `anthropic.claude-sonnet-4-20250514-v1-0`
194+
- `gpt-4`
195+
- `gpt-4-turbo`
196+
- `gemini-pro`
197+
198+
**Note:** The model field is purely informational and appears in the task frontmatter output for the AI agent to use as configuration.
199+
48200
#### Custom Fields (optional)
49201

50202
Any additional YAML fields can be used for selector-based filtering.
@@ -75,20 +227,20 @@ The `selectors` field allows a task to specify which rules should be included wh
75227
---
76228
task_name: implement-feature
77229
selectors:
78-
language: Go
230+
language: go
79231
stage: implementation
80232
---
81233
```
82234

83235
**Usage:**
84236
```bash
85-
# Automatically includes rules with language=Go AND stage=implementation
237+
# Automatically includes rules with language=go AND stage=implementation
86238
coding-context implement-feature
87239
```
88240

89241
This is equivalent to:
90242
```bash
91-
coding-context -s language=Go -s stage=implementation implement-feature
243+
coding-context -s language=go -s stage=implementation implement-feature
92244
```
93245

94246
**OR Logic with Arrays:**
@@ -104,7 +256,7 @@ selectors:
104256
---
105257
```
106258

107-
This matches rules where `(language=Go OR language=Python OR language=JavaScript) AND stage=testing`.
259+
This matches rules where `(language=go OR language=python OR language=javascript) AND stage=testing`.
108260

109261
**Combining with Command-Line Selectors:**
110262

@@ -113,7 +265,7 @@ Selectors from the task frontmatter and command-line `-s` flags are combined (ad
113265
```bash
114266
# Task frontmatter has: selectors.language = Go
115267
# Command line adds: -s priority=high
116-
# Result: Rules must match language=Go AND priority=high
268+
# Result: Rules must match language=go AND priority=high
117269
coding-context -s priority=high implement-feature
118270
```
119271

@@ -186,14 +338,101 @@ Guidelines, standards, or context for AI agents.
186338

187339
All frontmatter fields are optional and used for filtering.
188340

189-
**Common fields:**
341+
**Standard fields for rules:**
342+
343+
#### `task_name` (rule selector)
344+
345+
Specifies which task(s) this rule applies to. Can be a string or array.
346+
190347
```yaml
191348
---
192-
language: Go
349+
task_name: fix-bug
350+
---
351+
# This rule only applies to the 'fix-bug' task
352+
```
353+
354+
**Multiple tasks (OR logic):**
355+
```yaml
356+
---
357+
task_name:
358+
- fix-bug
359+
- implement-feature
360+
- refactor
361+
---
362+
# This rule applies to any of these three tasks
363+
```
364+
365+
**Behavior:**
366+
- When a task is run, rules with matching `task_name` are included
367+
- Rules without `task_name` are included for all tasks (generic rules)
368+
- The task's own `task_name` is automatically added as a selector
369+
370+
#### `language` (rule selector)
371+
372+
Specifies which programming language(s) this rule applies to. Can be a string or array.
373+
374+
```yaml
375+
---
376+
language: go
377+
---
378+
# This rule only applies when language=go is selected
379+
```
380+
381+
**Multiple languages (OR logic):**
382+
```yaml
383+
---
384+
language:
385+
- Go
386+
- Python
387+
- JavaScript
388+
---
389+
# This rule applies to any of these languages
390+
```
391+
392+
**Behavior:**
393+
- When a task has `language: go`, rules with `language: go` are included
394+
- Rules without `language` are included (generic rules)
395+
- Can also be filtered via `-s language=go` command-line flag
396+
397+
#### `agent` (rule selector)
398+
399+
Specifies which AI agent this rule is intended for.
400+
401+
```yaml
402+
---
403+
agent: cursor
404+
---
405+
# Rule specific to Cursor AI agent
406+
```
407+
408+
**Behavior:**
409+
- If task/CLI specifies `agent: cursor`, only rules with `agent: cursor` or no agent field are included
410+
- Rules without an agent field are considered generic and always included (unless other selectors exclude them)
411+
412+
#### `mcp_servers` (rule metadata)
413+
414+
Specifies MCP servers that need to be running for this rule. Does not filter rules.
415+
416+
```yaml
417+
---
418+
mcp_servers:
419+
- filesystem
420+
- database
421+
---
422+
# Metadata indicating required MCP servers
423+
```
424+
425+
**Note:** This field is informational and does not affect rule selection.
426+
427+
**Other common fields:**
428+
```yaml
429+
---
430+
language: go
193431
stage: implementation
194432
priority: high
195433
team: backend
196-
source: jira
434+
agent: cursor
435+
task_name: implement-feature
197436
---
198437
```
199438

@@ -282,25 +521,25 @@ boolean_key: true
282521
```yaml
283522
# ✅ Supported
284523
---
285-
language: Go
524+
language: go
286525
stage: testing
287526
---
288527

289528
# ❌ Not supported (nested fields)
290529
---
291530
metadata:
292-
language: Go
531+
language: go
293532
stage: testing
294533
---
295534
```
296535

297536
**Selectors match top-level only:**
298537
```bash
299538
# Works with top-level fields
300-
coding-context -s language=Go fix-bug
539+
coding-context -s language=go fix-bug
301540

302541
# Doesn't work with nested fields
303-
coding-context -s metadata.language=Go fix-bug # Won't match
542+
coding-context -s metadata.language=go fix-bug # Won't match
304543
```
305544

306545
### Data Types
@@ -311,15 +550,15 @@ Frontmatter values are treated as strings for matching:
311550
---
312551
priority: 1
313552
enabled: true
314-
language: Go
553+
language: go
315554
---
316555
```
317556

318557
```bash
319558
# All values are matched as strings
320559
coding-context -s priority=1 task # Matches priority: 1
321560
coding-context -s enabled=true task # Matches enabled: true
322-
coding-context -s language=Go task # Matches language: Go
561+
coding-context -s language=go task # Matches language: go
323562
```
324563

325564
## Special Behaviors
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
task_name: implement-feature
3+
language: go
4+
agent: cursor
5+
---
6+
7+
# Go Implementation Standards for Feature Development
8+
9+
This rule demonstrates standard frontmatter fields for rules:
10+
11+
- **task_name**: `implement-feature` - This rule only applies to the `implement-feature` task
12+
- **language**: `go` - This rule only applies when the language is go
13+
- **agent**: `cursor` - This rule is optimized for the Cursor AI agent
14+
15+
## When This Rule Is Included
16+
17+
This rule will be included when:
18+
1. The task being run is `implement-feature` (or has `task_name: implement-feature` selector)
19+
2. AND the task has `language: go` (or `-s language=go` is specified)
20+
3. AND the task has `agent: cursor` (or `-a cursor` is specified)
21+
22+
## Go-Specific Implementation Guidelines
23+
24+
When implementing features in Go:
25+
- Follow Go idioms and conventions
26+
- Use table-driven tests
27+
- Handle errors explicitly
28+
- Keep functions small and focused
29+
- Use interfaces for abstraction

0 commit comments

Comments
 (0)