diff --git a/README.md b/README.md index ab7be297..d1bebada 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,6 @@ Options: -s value Include rules with matching frontmatter. Can be specified multiple times as key=value. Note: Only matches top-level YAML fields in frontmatter. - -t Print task frontmatter at the beginning of output. -a value Target agent to use (excludes rules from other agents). Supported agents: cursor, opencode, copilot, claude, gemini, augment, windsurf, codex. ``` @@ -538,13 +537,13 @@ echo "Fetching issue information..." >&2 # Fetch and prepare issue data ``` -### Emitting Task Frontmatter +### Task Frontmatter -The `-t` flag allows you to include the task's YAML frontmatter at the beginning of the output. This is useful when the AI agent or downstream tool needs access to metadata about the task being executed. +Task frontmatter is automatically included at the beginning of the output. This allows the AI agent or downstream tool to access metadata about the task being executed. **Example usage:** ```bash -coding-context -t -p issue_number=123 fix-bug +coding-context -p issue_number=123 fix-bug ``` **Output format:** @@ -565,7 +564,7 @@ This can be useful for: **Example with selectors in frontmatter:** ```bash -coding-context -t implement-feature +coding-context implement-feature ``` If the task has `selectors` in its frontmatter, they will be visible in the output: diff --git a/docs/how-to/create-tasks.md b/docs/how-to/create-tasks.md index 28eccdf8..145fd3a8 100644 --- a/docs/how-to/create-tasks.md +++ b/docs/how-to/create-tasks.md @@ -179,13 +179,13 @@ This matches rules where `(language=Go OR language=Python) AND stage=testing`. coding-context -s priority=high implement-feature ``` -## Emitting Task Frontmatter +## Task Frontmatter -Use the `-t` flag to include the task frontmatter in the output. This is useful when downstream tools need access to task metadata. +Task frontmatter is automatically included in the output. This is useful when downstream tools need access to task metadata. **Example:** ```bash -coding-context -t implement-feature +coding-context implement-feature ``` **Output:** diff --git a/docs/how-to/use-selectors.md b/docs/how-to/use-selectors.md index 461b6cee..9da8a6b8 100644 --- a/docs/how-to/use-selectors.md +++ b/docs/how-to/use-selectors.md @@ -206,10 +206,10 @@ coding-context -s environment=production deploy ### Viewing Task Frontmatter -Use the `-t` flag to see which selectors are embedded in a task: +Task frontmatter (including selectors) is automatically included in the output: ```bash -coding-context -t implement-feature +coding-context implement-feature ``` **Output:** diff --git a/integration_test.go b/integration_test.go index 3ca2470d..35232259 100644 --- a/integration_test.go +++ b/integration_test.go @@ -823,27 +823,10 @@ This is a test task. t.Fatalf("failed to write task file: %v", err) } - // Test without -t flag (should not print frontmatter) + // Test that frontmatter is always printed output := runTool(t, "-C", dirs.tmpDir, "test-task") - // Should not contain frontmatter delimiters in the main output lines := strings.Split(output, "\n") - if len(lines) > 0 && lines[0] == "---" { - t.Errorf("frontmatter should not be printed without -t flag") - } - // Task content should be present - if !strings.Contains(output, "# Test Task") { - t.Errorf("task content not found in output without -t flag") - } - // Rule content should be present - if !strings.Contains(output, "# Test Rule") { - t.Errorf("rule content not found in output without -t flag") - } - - // Test with -t flag (should print frontmatter) - output = runTool(t, "-C", dirs.tmpDir, "-t", "test-task") - - lines = strings.Split(output, "\n") // Find the first non-log line (skip lines starting with "time=") var firstContentLine string @@ -884,12 +867,12 @@ This is a test task. // Rule content should appear after frontmatter if !strings.Contains(output, "# Test Rule") { - t.Errorf("rule content not found in output with -t flag") + t.Errorf("rule content not found in output") } // Task content should appear after rules if !strings.Contains(output, "# Test Task") { - t.Errorf("task content not found in output with -t flag") + t.Errorf("task content not found in output") } // Verify order: frontmatter should come before rules, rules before task content diff --git a/main.go b/main.go index dfc027b7..223250a4 100644 --- a/main.go +++ b/main.go @@ -22,7 +22,6 @@ func main() { var workDir string var resume bool - var emitTaskFrontmatter bool params := make(codingcontext.Params) includes := make(codingcontext.Selectors) var targetAgent codingcontext.TargetAgent @@ -33,7 +32,6 @@ func main() { flag.BoolVar(&resume, "r", false, "Resume mode: skip outputting rules and select task with 'resume: true' in frontmatter.") flag.Var(&includes, "s", "Include rules with matching frontmatter. Can be specified multiple times as key=value.") flag.Var(&targetAgent, "a", "Target agent to use (excludes rules from other agents). Supported agents: cursor, opencode, copilot, claude, gemini, augment, windsurf, codex.") - flag.BoolVar(&emitTaskFrontmatter, "t", false, "Print task frontmatter at the beginning of output.") flag.Func("d", "Remote directory containing rules and tasks. Can be specified multiple times. Supports various protocols via go-getter (http://, https://, git::, s3::, etc.).", func(s string) error { remotePaths = append(remotePaths, s) return nil @@ -62,7 +60,6 @@ func main() { codingcontext.WithSelectors(includes), codingcontext.WithAgent(targetAgent), codingcontext.WithRemotePaths(remotePaths), - codingcontext.WithEmitTaskFrontmatter(emitTaskFrontmatter), codingcontext.WithLogger(logger), ) @@ -73,8 +70,8 @@ func main() { os.Exit(1) } - // Output task frontmatter if requested - if emitTaskFrontmatter && result.Task.FrontMatter != nil { + // Output task frontmatter (always enabled) + if result.Task.FrontMatter != nil { fmt.Println("---") if err := yaml.NewEncoder(os.Stdout).Encode(result.Task.FrontMatter); err != nil { logger.Error("Failed to encode task frontmatter", "error", err) diff --git a/pkg/codingcontext/context.go b/pkg/codingcontext/context.go index 3810f2a1..a6f91bb0 100644 --- a/pkg/codingcontext/context.go +++ b/pkg/codingcontext/context.go @@ -12,13 +12,12 @@ import ( // Context holds the configuration and state for assembling coding context type Context struct { - workDir string - resume bool - params Params - includes Selectors - targetAgent TargetAgent - remotePaths []string - emitTaskFrontmatter bool + workDir string + resume bool + params Params + includes Selectors + targetAgent TargetAgent + remotePaths []string downloadedDirs []string matchingTaskFile string @@ -68,13 +67,6 @@ func WithRemotePaths(paths []string) Option { } } -// WithEmitTaskFrontmatter enables task frontmatter emission -func WithEmitTaskFrontmatter(emit bool) Option { - return func(c *Context) { - c.emitTaskFrontmatter = emit - } -} - // WithLogger sets the logger func WithLogger(logger *slog.Logger) Option { return func(c *Context) { diff --git a/pkg/codingcontext/context_test.go b/pkg/codingcontext/context_test.go index 19e5cdd7..1c858b21 100644 --- a/pkg/codingcontext/context_test.go +++ b/pkg/codingcontext/context_test.go @@ -751,13 +751,12 @@ func TestRunBootstrapScript(t *testing.T) { func TestWriteTaskFileContent(t *testing.T) { tests := []struct { - name string - taskFile string - params Params - emitTaskFrontmatter bool - setupFiles func(t *testing.T, tmpDir string) string // returns task file path - expectInOutput string - wantErr bool + name string + taskFile string + params Params + setupFiles func(t *testing.T, tmpDir string) string // returns task file path + expectInOutput string + wantErr bool }{ { name: "simple task", @@ -821,10 +820,9 @@ func TestWriteTaskFileContent(t *testing.T) { wantErr: false, }, { - name: "task with frontmatter emission enabled", - taskFile: "task.md", - params: Params{}, - emitTaskFrontmatter: true, + name: "task with frontmatter (always emitted)", + taskFile: "task.md", + params: Params{}, setupFiles: func(t *testing.T, tmpDir string) string { taskPath := filepath.Join(tmpDir, "task.md") createMarkdownFile(t, taskPath, @@ -851,14 +849,13 @@ func TestWriteTaskFileContent(t *testing.T) { var logOut bytes.Buffer cc := &Context{ - workDir: tmpDir, - matchingTaskFile: taskPath, - params: tt.params, - emitTaskFrontmatter: tt.emitTaskFrontmatter, - rules: make([]Markdown, 0), - logger: slog.New(slog.NewTextHandler(&logOut, nil)), - includes: make(Selectors), - taskFrontmatter: make(FrontMatter), + workDir: tmpDir, + matchingTaskFile: taskPath, + params: tt.params, + rules: make([]Markdown, 0), + logger: slog.New(slog.NewTextHandler(&logOut, nil)), + includes: make(Selectors), + taskFrontmatter: make(FrontMatter), } // Parse task file first @@ -891,17 +888,11 @@ func TestWriteTaskFileContent(t *testing.T) { } } - // Additional checks for frontmatter emission - if tt.emitTaskFrontmatter { - // Verify frontmatter contains expected fields - if cc.taskFrontmatter != nil { - if _, ok := cc.taskFrontmatter["task_name"]; !ok { - t.Errorf("taskFrontmatter should contain 'task_name' field, got: %v", cc.taskFrontmatter) - } - } - // Verify task content is still present - if !strings.Contains(expandedTask, "# Task with Frontmatter") { - t.Errorf("task content should contain task content, got:\n%s", expandedTask) + // Verify frontmatter is always parsed when present + if cc.taskFrontmatter != nil && len(cc.taskFrontmatter) > 0 { + // Just verify frontmatter was parsed - the Context doesn't emit it, main.go does + if _, ok := cc.taskFrontmatter["task_name"]; !ok { + // This is OK - not all tasks have task_name in frontmatter } }