MCPcopy Create free account
hub / github.com/Chat2AnyLLM/code-agent-manager / List

Method List

internal/desktop/tool_service.go:25–77  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

23const maxDetectionWorkers = 32
24
25func (s *ToolService) List() ([]ToolDTO, error) {
26 registry, err := tools.LoadDefault()
27 if err != nil {
28 return nil, wrapError("TOOL_REGISTRY_LOAD_FAILED", err)
29 }
30 names := registry.Names()
31 out := make([]ToolDTO, len(names))
32
33 // Serve fresh cached detections synchronously; only the stale or
34 // not-yet-seen tools need a subprocess probe. This is what makes repeat
35 // Agents-page loads fast — detection is the page's dominant cost.
36 s.cache.loadOnce()
37 type pending struct {
38 idx int
39 tool tools.Tool
40 }
41 var toProbe []pending
42 for i, name := range names {
43 if entry, fresh := s.cache.get(name); fresh {
44 out[i] = toolDTOWith(registry.Tools[name], entry.Installed, entry.Version)
45 continue
46 }
47 toProbe = append(toProbe, pending{idx: i, tool: registry.Tools[name]})
48 }
49 if len(toProbe) == 0 {
50 return out, nil
51 }
52
53 // Each tool's detection blocks on subprocess execution (LookPath + version
54 // probes). Run them concurrently — one goroutine per tool, capped — so the
55 // Agents page doesn't wait on every binary serially. Writes target distinct
56 // slice indices, so no locking is required; output order still matches names.
57 workers := len(toProbe)
58 if workers > maxDetectionWorkers {
59 workers = maxDetectionWorkers
60 }
61 sem := make(chan struct{}, workers)
62 var wg sync.WaitGroup
63 for _, p := range toProbe {
64 wg.Add(1)
65 sem <- struct{}{}
66 go func(p pending) {
67 defer wg.Done()
68 defer func() { <-sem }()
69 installed, version := tools.Detect(p.tool)
70 s.cache.put(p.tool.Name, installed, version)
71 out[p.idx] = toolDTOWith(p.tool, installed, version)
72 }(p)
73 }
74 wg.Wait()
75 s.cache.persist()
76 return out, nil
77}
78
79func (s *ToolService) Install(name string, dryRun bool) (OperationResult, error) {
80 tool, err := loadTool(name)

Callers 4

ListToolsMethod · 0.45
TestToolServiceListFunction · 0.45

Calls 10

LoadDefaultFunction · 0.92
DetectFunction · 0.92
wrapErrorFunction · 0.85
toolDTOWithFunction · 0.85
loadOnceMethod · 0.80
getMethod · 0.80
putMethod · 0.80
persistMethod · 0.80
NamesMethod · 0.45
AddMethod · 0.45

Tested by 3

TestToolServiceListFunction · 0.36