(root, prompt string, compact bool)
| 106 | } |
| 107 | |
| 108 | func buildContextEnvelope(root, prompt string, compact bool) ContextEnvelope { |
| 109 | projCfg := config.Load(root) |
| 110 | info := getHubInfoNoFallback(root) |
| 111 | |
| 112 | envelope := ContextEnvelope{ |
| 113 | Version: 1, |
| 114 | GeneratedAt: time.Now(), |
| 115 | Project: buildProjectContext(root, info), |
| 116 | Budget: BudgetInfo{Compact: compact}, |
| 117 | } |
| 118 | |
| 119 | // Intent classification (if prompt provided) |
| 120 | if prompt != "" { |
| 121 | topK := projCfg.RoutingTopKOrDefault() |
| 122 | files := extractMentionedFiles(prompt, topK) |
| 123 | intent := classifyIntent(prompt, files, info, projCfg) |
| 124 | envelope.Intent = &intent |
| 125 | |
| 126 | // Match skills against intent |
| 127 | if !compact { |
| 128 | if idx, err := skills.LoadSkills(root); err == nil && idx != nil { |
| 129 | var langs []string |
| 130 | for _, f := range files { |
| 131 | if lang := scanner.DetectLanguage(f); lang != "" { |
| 132 | langs = append(langs, lang) |
| 133 | } |
| 134 | } |
| 135 | matches := idx.MatchSkills(intent.Category, files, langs, 3) |
| 136 | for _, m := range matches { |
| 137 | envelope.Skills = append(envelope.Skills, SkillRef{ |
| 138 | Name: m.Skill.Meta.Name, |
| 139 | Score: m.Score, |
| 140 | Reason: m.Reason, |
| 141 | }) |
| 142 | } |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | // Working set from daemon |
| 148 | if state := watch.ReadState(root); state != nil && state.WorkingSet != nil { |
| 149 | ws := state.WorkingSet |
| 150 | wsCtx := &WorkingSetContext{ |
| 151 | FileCount: ws.Size(), |
| 152 | HubCount: ws.HubCount(), |
| 153 | } |
| 154 | limit := 10 |
| 155 | if compact { |
| 156 | limit = 3 |
| 157 | } |
| 158 | for _, wf := range ws.HotFiles(limit) { |
| 159 | wsCtx.TopFiles = append(wsCtx.TopFiles, WorkingFileContext{ |
| 160 | Path: wf.Path, |
| 161 | EditCount: wf.EditCount, |
| 162 | NetDelta: wf.NetDelta, |
| 163 | IsHub: wf.IsHub, |
| 164 | }) |
| 165 | } |
no test coverage detected