• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stacklok / toolhive-studio / 29571051485

17 Jul 2026 09:44AM UTC coverage: 71.713% (+0.5%) from 71.204%
29571051485

Pull #2475

github

samuv
fix(chat): harden Effect runtime adapters after external review

Make readiness and runtime retrieval atomic, type adapter programs against
ChatServices, and tighten domain-error narrowing plus agent/settings edge cases.

Co-authored-by: Cursor <cursoragent@cursor.com>
Pull Request #2475: refactor(chat): migrate main-process chat to Effect domain services

5476 of 8187 branches covered (66.89%)

871 of 1363 new or added lines in 42 files covered. (63.9%)

1 existing line in 1 file now uncovered.

8153 of 11369 relevant lines covered (71.71%)

137.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

6.25
/main/src/chat/settings-storage.ts
1
import { Effect } from 'effect'
2
import { runChatSyncOr, runChatPromiseOr, runChatToResultSync } from './runtime'
3
import { SettingsService } from './settings/settings-service'
4
import type {
5
  ChatSettingsProvider,
6
  ChatSettingsSelectedModel,
7
} from './settings/settings-service'
8
import {
9
  CHAT_PROVIDER_INFO,
10
  LOCAL_PROVIDER_IDS,
11
  type LocalProviderId,
12
} from './constants'
13

14
type ProviderId = (typeof CHAT_PROVIDER_INFO)[number]['id']
15

16
function isLocalProvider(
17
  providerId: ProviderId
18
): providerId is LocalProviderId {
NEW
19
  return LOCAL_PROVIDER_IDS.includes(providerId as LocalProviderId)
×
20
}
21

22
function defaultChatSettings(providerId: ProviderId): ChatSettingsProvider {
UNCOV
23
  if (isLocalProvider(providerId)) {
×
NEW
24
    return { providerId, endpointURL: '', enabledTools: [] }
×
25
  }
NEW
26
  return {
×
27
    providerId,
28
    apiKey: '',
29
    enabledTools: [],
30
  }
31
}
32

33
const EMPTY_SELECTED_MODEL: ChatSettingsSelectedModel = {
12✔
34
  provider: '',
35
  model: '',
36
}
37

38
export function getChatSettings(providerId: ProviderId): ChatSettingsProvider {
NEW
39
  return runChatSyncOr(
×
40
    SettingsService.getChatSettings(providerId),
41
    defaultChatSettings(providerId)
42
  )
43
}
44

45
export function clearChatSettings(providerId?: ProviderId): {
46
  success: boolean
47
  error?: string
48
} {
NEW
49
  return runChatToResultSync(
×
50
    SettingsService.clearChatSettings(providerId).pipe(Effect.as({}))
51
  )
52
}
53

54
export function getSelectedModel(): ChatSettingsSelectedModel {
NEW
55
  return runChatSyncOr(SettingsService.getSelectedModel(), EMPTY_SELECTED_MODEL)
×
56
}
57

58
export function saveSelectedModel(
59
  provider: string,
60
  model: string
61
): { success: boolean; error?: string } {
NEW
62
  return runChatToResultSync(
×
63
    SettingsService.saveSelectedModel(provider, model).pipe(Effect.as({}))
64
  )
65
}
66

67
export function saveEnabledMcpTools(
68
  serverName: string,
69
  toolNames: string[]
70
): { success: boolean; error?: string } {
NEW
71
  return runChatToResultSync(
×
72
    SettingsService.saveEnabledMcpTools(serverName, toolNames).pipe(
73
      Effect.as({})
74
    )
75
  )
76
}
77

78
export async function getEnabledMcpTools(): Promise<Record<string, string[]>> {
NEW
79
  return runChatPromiseOr(SettingsService.getEnabledMcpTools(), {})
×
80
}
81

82
export async function getEnabledMcpServersFromTools(): Promise<string[]> {
NEW
83
  return runChatPromiseOr(SettingsService.getEnabledMcpServersFromTools(), [])
×
84
}
85

86
export function getEnabledSkills(): string[] {
NEW
87
  return runChatSyncOr(SettingsService.getEnabledSkills(), [])
×
88
}
89

90
export function setSkillEnabled(
91
  name: string,
92
  enabled: boolean
93
): { success: boolean; error?: string } {
NEW
94
  return runChatToResultSync(
×
95
    SettingsService.setSkillEnabled(name, enabled).pipe(Effect.as({}))
96
  )
97
}
98

99
export function pruneEnabledSkillsTo(
100
  installedNames: readonly string[]
101
): number {
NEW
102
  return runChatSyncOr(SettingsService.pruneEnabledSkillsTo(installedNames), 0)
×
103
}
104

105
export function handleSaveSettings(
106
  providerId: string,
107
  settings:
108
    | { apiKey: string; enabledTools: string[] }
109
    | { endpointURL: string; enabledTools: string[] }
110
): { success: boolean; error?: string } {
NEW
111
  return runChatToResultSync(
×
112
    SettingsService.handleSaveSettings(providerId, settings).pipe(Effect.as({}))
113
  )
114
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc