multica/server/internal/daemon/execenv/context.go
Naiyuan Qing a500001093 refactor: remove acceptance_criteria and context_refs from issues
These fields were unused in practice. Removed from frontend types,
issue detail UI, backend handlers, daemon prompt/context, protocol
messages, SQL queries, and tests. DB columns retained with defaults.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 19:24:34 +08:00

111 lines
3 KiB
Go

package execenv
import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
)
// writeContextFiles renders and writes .agent_context/issue_context.md and skills into workDir.
func writeContextFiles(workDir string, ctx TaskContextForEnv) error {
contextDir := filepath.Join(workDir, ".agent_context")
if err := os.MkdirAll(contextDir, 0o755); err != nil {
return fmt.Errorf("create .agent_context dir: %w", err)
}
content := renderIssueContext(ctx)
path := filepath.Join(contextDir, "issue_context.md")
if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
return fmt.Errorf("write issue_context.md: %w", err)
}
if len(ctx.AgentSkills) > 0 {
if err := writeSkillFiles(contextDir, ctx.AgentSkills); err != nil {
return fmt.Errorf("write skill files: %w", err)
}
}
return nil
}
var nonAlphaNum = regexp.MustCompile(`[^a-z0-9]+`)
// sanitizeSkillName converts a skill name to a safe directory name.
func sanitizeSkillName(name string) string {
s := strings.ToLower(strings.TrimSpace(name))
s = nonAlphaNum.ReplaceAllString(s, "-")
s = strings.Trim(s, "-")
if s == "" {
s = "skill"
}
return s
}
// writeSkillFiles creates a skills/ directory with one subdirectory per skill.
func writeSkillFiles(contextDir string, skills []SkillContextForEnv) error {
skillsDir := filepath.Join(contextDir, "skills")
if err := os.MkdirAll(skillsDir, 0o755); err != nil {
return fmt.Errorf("create skills dir: %w", err)
}
for _, skill := range skills {
dir := filepath.Join(skillsDir, sanitizeSkillName(skill.Name))
if err := os.MkdirAll(dir, 0o755); err != nil {
return err
}
// Write main SKILL.md
if err := os.WriteFile(filepath.Join(dir, "SKILL.md"), []byte(skill.Content), 0o644); err != nil {
return err
}
// Write supporting files
for _, f := range skill.Files {
fpath := filepath.Join(dir, f.Path)
if err := os.MkdirAll(filepath.Dir(fpath), 0o755); err != nil {
return err
}
if err := os.WriteFile(fpath, []byte(f.Content), 0o644); err != nil {
return err
}
}
}
return nil
}
// renderIssueContext builds the markdown content for issue_context.md.
// Sections with empty content are omitted.
func renderIssueContext(ctx TaskContextForEnv) string {
var b strings.Builder
if ctx.IssueTitle != "" {
fmt.Fprintf(&b, "# Issue: %s\n\n", ctx.IssueTitle)
}
if ctx.IssueDescription != "" {
b.WriteString("## Description\n\n")
b.WriteString(ctx.IssueDescription)
b.WriteString("\n\n")
}
if ctx.WorkspaceContext != "" {
b.WriteString("## Workspace Context\n\n")
b.WriteString(ctx.WorkspaceContext)
b.WriteString("\n\n")
}
if len(ctx.AgentSkills) > 0 {
b.WriteString("## Agent Skills\n\n")
b.WriteString("Detailed skill instructions are in `.agent_context/skills/`.\n")
b.WriteString("Each subdirectory contains a `SKILL.md` with instructions and any supporting files.\n\n")
for _, skill := range ctx.AgentSkills {
fmt.Fprintf(&b, "- **%s**\n", skill.Name)
}
b.WriteString("\n")
}
return b.String()
}