返回 DeepSeek-Reasonix
topic_state_catalog.go
根目录 / desktop / topic_state_catalog.go
1 package main
2
3 import (
4 "strings"
5
6 "reasonix/internal/sessioncatalog"
7 )
8
9 // ListProjectTopics surfaces topic-state failures instead of hiding them as empty pages.
10 func (a *App) ListProjectTopics(req ProjectTopicPageRequest) (ProjectTopicPage, error) {
11 if catalog := a.sessionCatalog.Load(); catalog != nil {
12 catalog.PrioritizeWorkspace(req.Scope, req.WorkspaceRoot)
13 }
14 // Remote roots come from Serve and must never map to local metadata paths.
15 if strings.HasPrefix(strings.TrimSpace(req.WorkspaceRoot), "remote-project:") {
16 return ProjectTopicPage{Items: []ProjectNode{}}, nil
17 }
18 if err := topicStateReadable(topicTitleRoot(req.Scope, req.WorkspaceRoot)); err != nil {
19 return ProjectTopicPage{Items: []ProjectNode{}}, err
20 }
21 return a.unifiedProjectTopics(req)
22 }
23
24 func (a *App) GetTopicSummary(key ProjectTopicKey) (ProjectNode, error) {
25 scope, workspaceRoot := normalizeDesktopTopicScope(key.Scope, key.WorkspaceRoot)
26 topicID := strings.TrimSpace(key.TopicID)
27 if topicID == "" {
28 return ProjectNode{Children: []ProjectNode{}}, nil
29 }
30 allowMetadataFallback := true
31 if catalog := a.sessionCatalog.Load(); catalog != nil {
32 availability := a.catalogWorkspaceAvailability(catalog, scope, workspaceRoot)
33 allowMetadataFallback = !availability.complete
34 if !availability.usable {
35 return a.metadataTopicSummary(scope, workspaceRoot, topicID), nil
36 }
37 ctx, cancel := a.catalogReadContext()
38 defer cancel()
39 topic, ok, err := catalog.GetTopic(ctx, sessioncatalog.TopicKey{
40 Scope: scope, WorkspaceRoot: workspaceRoot, TopicID: topicID,
41 })
42 if err != nil {
43 return ProjectNode{Children: []ProjectNode{}}, err
44 }
45 if ok {
46 topicOverlays, sessionOverlays := a.catalogRuntimeOverlays()
47 preferred, prefErr := catalog.PreferredOrdinarySessionPaths(ctx, scope, workspaceRoot)
48 if prefErr != nil {
49 preferred = nil
50 }
51 if node, visible := a.projectNodeFromCatalogTopic(topic, topicOverlays, sessionOverlays, preferred); visible {
52 return node, nil
53 }
54 }
55 }
56 if !allowMetadataFallback {
57 return ProjectNode{Children: []ProjectNode{}}, nil
58 }
59 return a.metadataTopicSummary(scope, workspaceRoot, topicID), nil
60 }
61
62 func (a *App) metadataTopicSummary(scope, workspaceRoot, topicID string) ProjectNode {
63 for _, node := range a.metadataProjectTopics(scope, workspaceRoot) {
64 if node.TopicID == topicID {
65 return node
66 }
67 }
68 return ProjectNode{Children: []ProjectNode{}}
69 }
70
70 lines GO