Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Options:
Change to directory before doing anything. (default ".")
-p value
Parameter to substitute in the prompt. Can be specified multiple times as key=value.
-r Resume mode: skip outputting rules and select task with 'resume: true' in frontmatter.
-s value
Include rules with matching frontmatter. Can be specified multiple times as key=value.
```
Expand Down Expand Up @@ -172,6 +173,57 @@ coding-context-cli -s environment=staging deploy
coding-context-cli -s environment=production deploy
```

### Resume Mode

Resume mode is designed for continuing work on a task where you've already established context. When using the `-r` flag:

1. **Rules are skipped**: All rule files are excluded from output, saving tokens and reducing context size
2. **Resume-specific task prompts are selected**: Automatically adds `-s resume=true` selector to find task files with `resume: true` in their frontmatter

This is particularly useful in agentic workflows where an AI agent has already been primed with rules and is continuing work from a previous session.

**The `-r` flag is shorthand for:**
- Adding `-s resume=true` selector
- Skipping all rules output

**Example usage:**

```bash
# Initial task invocation (includes all rules, uses task with resume: false)
coding-context-cli -s resume=false fix-bug | ai-agent

# Resume the task (skips rules, uses task with resume: true)
coding-context-cli -r fix-bug | ai-agent
```

**Example task files for resume mode:**

Initial task (`.agents/tasks/fix-bug-initial.md`):
```markdown
---
task_name: fix-bug
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot to exclude from resume, "resume: false".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated documentation and examples to show resume: false for initial tasks. Users can now use -s resume=false to explicitly select non-resume tasks. See commit 07213fe.

resume: false
---
# Fix Bug

Analyze the issue and implement a fix.
Follow the coding standards and write tests.
```

Resume task (`.agents/tasks/fix-bug-resume.md`):
```markdown
---
task_name: fix-bug
resume: true
---
# Fix Bug - Continue

Continue working on the bug fix.
Review your previous work and complete remaining tasks.
```

With this approach, you can have multiple task prompts for the same task name, differentiated by the `resume` frontmatter field. Use `-s resume=false` to select the initial task (with rules), or `-r` to select the resume task (without rules).

### Rule Files

Rule files are Markdown (`.md`) or `.mdc` files, optionally with YAML frontmatter for filtering.
Expand Down
45 changes: 45 additions & 0 deletions examples/agents/tasks/fix-bug-resume.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
task_name: fix-bug
resume: true
---

# Bug Fix Task - Resume

You are continuing work on a bug fix from a previous session.

## Context

You've already been provided with the coding standards and project guidelines.
Continue from where you left off.

## Issue Information

- **Issue Number**: #${issue_number}
- **Title**: ${issue_title}
- **URL**: ${issue_url}

## Your Task

Review your previous work and:

1. **Complete Implementation**
- Finish any incomplete code changes
- Address any edge cases identified
- Ensure consistency with existing patterns

2. **Finalize Tests**
- Complete test coverage
- Verify all tests pass
- Add any missing test cases

3. **Code Review Preparation**
- Review your changes for quality
- Update documentation as needed
- Ensure commit messages are clear

## Next Steps

- Complete any outstanding tasks
- Run all tests one final time
- Prepare for code review
- Update the PR description if needed
1 change: 1 addition & 0 deletions examples/agents/tasks/fix-bug.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
task_name: fix-bug
resume: false
---

# Bug Fix Task
Expand Down
3 changes: 3 additions & 0 deletions frontmatter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package main

type frontMatter map[string]any
105 changes: 105 additions & 0 deletions integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -941,3 +941,108 @@ Deploy to the production environment.
t.Errorf("staging task content should not be in stdout when selecting production")
}
}

func TestResumeMode(t *testing.T) {
// Build the binary
binaryPath := filepath.Join(t.TempDir(), "coding-context")
cmd := exec.Command("go", "build", "-o", binaryPath, ".")
if output, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("failed to build binary: %v\n%s", err, output)
}

// Create a temporary directory structure
tmpDir := t.TempDir()
rulesDir := filepath.Join(tmpDir, ".agents", "rules")
tasksDir := filepath.Join(tmpDir, ".agents", "tasks")

if err := os.MkdirAll(rulesDir, 0755); err != nil {
t.Fatalf("failed to create rules dir: %v", err)
}
if err := os.MkdirAll(tasksDir, 0755); err != nil {
t.Fatalf("failed to create tasks dir: %v", err)
}

// Create a rule file that should be included in normal mode
ruleFile := filepath.Join(rulesDir, "coding-standards.md")
ruleContent := `---
---
# Coding Standards

These are the coding standards for the project.
`
if err := os.WriteFile(ruleFile, []byte(ruleContent), 0644); err != nil {
t.Fatalf("failed to write rule file: %v", err)
}

// Create a normal task file (with resume: false)
normalTaskFile := filepath.Join(tasksDir, "fix-bug-initial.md")
normalTaskContent := `---
task_name: fix-bug
resume: false
---
# Fix Bug (Initial)

This is the initial task prompt for fixing a bug.
`
if err := os.WriteFile(normalTaskFile, []byte(normalTaskContent), 0644); err != nil {
t.Fatalf("failed to write normal task file: %v", err)
}

// Create a resume task file (with resume: true)
resumeTaskFile := filepath.Join(tasksDir, "fix-bug-resume.md")
resumeTaskContent := `---
task_name: fix-bug
resume: true
---
# Fix Bug (Resume)

This is the resume task prompt for continuing the bug fix.
`
if err := os.WriteFile(resumeTaskFile, []byte(resumeTaskContent), 0644); err != nil {
t.Fatalf("failed to write resume task file: %v", err)
}

// Test 1: Run in normal mode (with -s resume=false to select non-resume task)
cmd = exec.Command(binaryPath, "-C", tmpDir, "-s", "resume=false", "fix-bug")
output, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("failed to run binary in normal mode: %v\n%s", err, output)
}

outputStr := string(output)

// In normal mode, rules should be included
if !strings.Contains(outputStr, "# Coding Standards") {
t.Errorf("normal mode: rule content not found in stdout")
}

// In normal mode, should use the normal task (not resume task)
if !strings.Contains(outputStr, "# Fix Bug (Initial)") {
t.Errorf("normal mode: normal task content not found in stdout")
}
if strings.Contains(outputStr, "# Fix Bug (Resume)") {
t.Errorf("normal mode: resume task content should not be in stdout")
}

// Test 2: Run in resume mode (with -r flag)
cmd = exec.Command(binaryPath, "-C", tmpDir, "-r", "fix-bug")
output, err = cmd.CombinedOutput()
if err != nil {
t.Fatalf("failed to run binary in resume mode: %v\n%s", err, output)
}

outputStr = string(output)

// In resume mode, rules should NOT be included
if strings.Contains(outputStr, "# Coding Standards") {
t.Errorf("resume mode: rule content should not be in stdout")
}

// In resume mode, should use the resume task
if !strings.Contains(outputStr, "# Fix Bug (Resume)") {
t.Errorf("resume mode: resume task content not found in stdout")
}
if strings.Contains(outputStr, "# Fix Bug (Initial)") {
t.Errorf("resume mode: normal task content should not be in stdout")
}
}
Loading