| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "strings" |
| 5 | |
| 6 | "reasonix/desktop/internal/workspacestate" |
| 7 | "reasonix/internal/config" |
| 8 | "reasonix/internal/control" |
| 9 | "reasonix/internal/plugin" |
| 10 | ) |
| 11 | |
| 12 | type sessionOpenEnvironment struct { |
| 13 | snapshot tabRuntimeSnapshot |
| 14 | config *config.Config |
| 15 | host *plugin.Host |
| 16 | oldHost string |
| 17 | acquiredHost bool |
| 18 | workspaceChanged bool |
| 19 | preserveSource bool |
| 20 | releaseAdmission func() |
| 21 | } |
| 22 | |
| 23 | func (a *App) prepareSessionOpenEnvironment(tab *WorkspaceTab, workspace workspacestate.Workspace) (*sessionOpenEnvironment, error) { |
| 24 | snap := a.tabRuntimeSnapshot(tab) |
| 25 | prepared := &sessionOpenEnvironment{snapshot: snap, oldHost: snap.sharedHostKey, workspaceChanged: canonicalWorkspaceChanged(snap, workspace)} |
| 26 | prepared.preserveSource = controllerHasActiveRuntimeWork(snap.ctrl) |
| 27 | prepared.snapshot.sink = &tabEventSink{tabID: tab.ID, app: a} |
| 28 | prepared.snapshot.scope, prepared.snapshot.workspaceRoot = canonicalWorkspaceScope(workspace), workspace.Root |
| 29 | release, err := a.beginProjectRuntimeAdmission(prepared.snapshot.scope, workspace.Root) |
| 30 | if err != nil { |
| 31 | return nil, err |
| 32 | } |
| 33 | prepared.releaseAdmission = release |
| 34 | prepared.config, err = config.LoadForRoot(workspace.Root) |
| 35 | if err != nil { |
| 36 | release() |
| 37 | return nil, err |
| 38 | } |
| 39 | prepared.host = a.lookupSharedHost(snap.sharedHostKey) |
| 40 | if prepared.workspaceChanged || snap.ctrl == nil || prepared.preserveSource { |
| 41 | prepared.snapshot.sharedHostKey = workspace.Root |
| 42 | prepared.host = a.acquireSharedHost(workspace.Root) |
| 43 | prepared.acquiredHost = true |
| 44 | } |
| 45 | return prepared, nil |
| 46 | } |
| 47 | |
| 48 | func (a *App) finishSessionOpenEnvironment(prepared *sessionOpenEnvironment, committed bool) { |
| 49 | prepared.releaseAdmission() |
| 50 | if !prepared.acquiredHost { |
| 51 | return |
| 52 | } |
| 53 | if !committed { |
| 54 | a.releaseSharedHost(prepared.snapshot.sharedHostKey) |
| 55 | } else if prepared.oldHost != "" && !prepared.preserveSource { |
| 56 | a.releaseSharedHost(prepared.oldHost) |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | func prepareCanonicalControllerRuntime(candidate control.SessionAPI, snap tabRuntimeSnapshot) normalizedTabRuntime { |
| 61 | candidate.EnableInteractiveApproval() |
| 62 | runtime := snap.normalizedRuntime() |
| 63 | applyTabToolApprovalModeToController(candidate, runtime.toolApprovalMode) |
| 64 | applyTabQualityFloorToController(candidate, runtime.qualityFloor) |
| 65 | runtime.collaborationMode, runtime.legacyGoal = "normal", "" |
| 66 | if candidate.PlanMode() { |
| 67 | runtime.collaborationMode = "plan" |
| 68 | } |
| 69 | if candidate.GoalStatus() == control.GoalStatusRunning && strings.TrimSpace(candidate.Goal()) != "" && !candidate.PlanMode() { |
| 70 | runtime.collaborationMode, runtime.legacyGoal = "goal", strings.TrimSpace(candidate.Goal()) |
| 71 | } |
| 72 | return runtime |
| 73 | } |
| 74 |