@lattices/cli 0.4.2 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/app/Info.plist +2 -2
- package/app/Lattices.app/Contents/Info.plist +2 -2
- package/app/Lattices.app/Contents/MacOS/Lattices +0 -0
- package/app/Package.swift +6 -0
- package/app/Sources/AppShell/App.swift +20 -0
- package/app/Sources/{AppDelegate.swift → AppShell/AppDelegate.swift} +94 -34
- package/app/Sources/{AppShellView.swift → AppShell/AppShellView.swift} +12 -1
- package/app/Sources/AppShell/AppUpdater.swift +92 -0
- package/app/Sources/AppShell/CliActionLauncher.swift +50 -0
- package/app/Sources/{HomeDashboardView.swift → AppShell/HomeDashboardView.swift} +18 -10
- package/app/Sources/AppShell/LatticesRuntime.swift +61 -0
- package/app/Sources/{MainView.swift → AppShell/MainView.swift} +351 -191
- package/app/Sources/{OnboardingView.swift → AppShell/OnboardingView.swift} +30 -16
- package/app/Sources/{Preferences.swift → AppShell/Preferences.swift} +78 -0
- package/app/Sources/{SettingsView.swift → AppShell/SettingsView.swift} +869 -152
- package/app/Sources/{HotkeyStore.swift → Core/Actions/HotkeyStore.swift} +9 -5
- package/app/Sources/{IntentEngine.swift → Core/Actions/IntentEngine.swift} +51 -27
- package/app/Sources/Core/Actions/IntentSchema.swift +94 -0
- package/app/Sources/{Intents → Core/Actions/Intents}/LatticeIntent.swift +0 -25
- package/app/Sources/{PaletteCommand.swift → Core/Actions/PaletteCommand.swift} +26 -6
- package/app/Sources/{VoiceIntentResolver.swift → Core/Actions/VoiceIntentResolver.swift} +46 -4
- package/app/Sources/Core/Companion/CompanionActivityLog.swift +70 -0
- package/app/Sources/Core/Companion/CompanionKeyboardController.swift +141 -0
- package/app/Sources/Core/Companion/LatticesCompanionBridgeServer.swift +438 -0
- package/app/Sources/Core/Companion/LatticesCompanionCockpit.swift +555 -0
- package/app/Sources/Core/Companion/LatticesCompanionSecurityCoordinator.swift +594 -0
- package/app/Sources/Core/Companion/LatticesCompanionTrackpadController.swift +204 -0
- package/app/Sources/Core/Companion/LatticesDeckHost.swift +1463 -0
- package/app/Sources/{LatticesApi.swift → Core/Daemon/LatticesApi.swift} +125 -4
- package/app/Sources/{AppTypeClassifier.swift → Core/Desktop/AppTypeClassifier.swift} +36 -0
- package/app/Sources/{DesktopModel.swift → Core/Desktop/DesktopModel.swift} +6 -8
- package/app/Sources/Core/Desktop/MouseFinder.swift +527 -0
- package/app/Sources/Core/Desktop/SessionWindowLocator.swift +139 -0
- package/app/Sources/Core/Desktop/WindowDragSnapController.swift +628 -0
- package/app/Sources/Core/Desktop/WindowPreviewCard.swift +100 -0
- package/app/Sources/Core/Desktop/WindowPreviewStore.swift +113 -0
- package/app/Sources/Core/Desktop/WindowSelectionStore.swift +76 -0
- package/app/Sources/{WindowTiler.swift → Core/Desktop/WindowTiler.swift} +351 -172
- package/app/Sources/Core/Input/MouseGestureConfig.swift +364 -0
- package/app/Sources/Core/Input/MouseGestureController.swift +1203 -0
- package/app/Sources/Core/Input/MouseInputDeviceStore.swift +98 -0
- package/app/Sources/Core/Input/MouseInputEventViewer.swift +272 -0
- package/app/Sources/Core/Input/MouseShortcutStore.swift +107 -0
- package/app/Sources/{CommandModeState.swift → Core/Overlays/CommandMode/CommandModeState.swift} +127 -24
- package/app/Sources/{CommandModeView.swift → Core/Overlays/CommandMode/CommandModeView.swift} +492 -79
- package/app/Sources/Core/Overlays/CommandPalette/CommandPaletteWindow.swift +67 -0
- package/app/Sources/{CheatSheetHUD.swift → Core/Overlays/HUD/CheatSheetHUD.swift} +1 -0
- package/app/Sources/{HUDRightBar.swift → Core/Overlays/HUD/HUDRightBar.swift} +23 -201
- package/app/Sources/{LauncherHUD.swift → Core/Overlays/HUD/LauncherHUD.swift} +12 -26
- package/app/Sources/{OmniSearchView.swift → Core/Overlays/OmniSearch/OmniSearchView.swift} +136 -2
- package/app/Sources/{OmniSearchWindow.swift → Core/Overlays/OmniSearch/OmniSearchWindow.swift} +21 -32
- package/app/Sources/Core/Overlays/OverlayPanelShell.swift +241 -0
- package/app/Sources/{ScreenMapState.swift → Core/Overlays/ScreenMap/ScreenMapState.swift} +116 -32
- package/app/Sources/{ScreenMapView.swift → Core/Overlays/ScreenMap/ScreenMapView.swift} +510 -524
- package/app/Sources/{ScreenMapWindowController.swift → Core/Overlays/ScreenMap/ScreenMapWindowController.swift} +12 -4
- package/app/Sources/{VoiceCommandWindow.swift → Core/Overlays/Voice/VoiceCommandWindow.swift} +46 -53
- package/app/Sources/Core/Pi/PiAuthNextStepCard.swift +148 -0
- package/app/Sources/Core/Pi/PiAuthPromptCard.swift +90 -0
- package/app/Sources/{PiChatDock.swift → Core/Pi/PiChatDock.swift} +137 -74
- package/app/Sources/{PiChatSession.swift → Core/Pi/PiChatSession.swift} +608 -108
- package/app/Sources/Core/Pi/PiInstallCallout.swift +86 -0
- package/app/Sources/Core/Pi/PiProviderSetupCallout.swift +99 -0
- package/app/Sources/{PiWorkspaceView.swift → Core/Pi/PiWorkspaceView.swift} +174 -77
- package/app/Sources/{PermissionChecker.swift → Core/System/PermissionChecker.swift} +76 -2
- package/app/Sources/Core/System/SystemTelemetryMonitor.swift +273 -0
- package/app/Sources/{HandsOffSession.swift → Core/Voice/HandsOffSession.swift} +15 -4
- package/app/Sources/{WorkspaceManager.swift → Core/Workspace/WorkspaceManager.swift} +288 -0
- package/bin/assistant-intelligence.ts +874 -0
- package/bin/handsoff-infer.ts +16 -209
- package/bin/handsoff-worker.ts +45 -258
- package/bin/lattices-app.ts +62 -0
- package/bin/lattices-dev +4 -0
- package/bin/lattices.ts +125 -14
- package/docs/agents.md +14 -0
- package/docs/api.md +55 -0
- package/docs/app.md +3 -0
- package/docs/companion-deck.md +180 -0
- package/docs/component-extraction-roadmap.md +392 -0
- package/docs/config.md +25 -0
- package/docs/tiling-reference.md +55 -0
- package/docs/voice-error-model.md +73 -0
- package/package.json +4 -1
- package/app/Sources/App.swift +0 -10
- package/app/Sources/CommandPaletteWindow.swift +0 -134
- package/app/Sources/MouseFinder.swift +0 -222
- /package/app/Sources/{KeyRecorderView.swift → AppShell/KeyRecorderView.swift} +0 -0
- /package/app/Sources/{MainWindow.swift → AppShell/MainWindow.swift} +0 -0
- /package/app/Sources/{SettingsWindow.swift → AppShell/SettingsWindow.swift} +0 -0
- /package/app/Sources/{HotkeyManager.swift → Core/Actions/HotkeyManager.swift} +0 -0
- /package/app/Sources/{Intents → Core/Actions/Intents}/CreateLayerIntent.swift +0 -0
- /package/app/Sources/{Intents → Core/Actions/Intents}/DistributeIntent.swift +0 -0
- /package/app/Sources/{Intents → Core/Actions/Intents}/FocusIntent.swift +0 -0
- /package/app/Sources/{Intents → Core/Actions/Intents}/HelpIntent.swift +0 -0
- /package/app/Sources/{Intents → Core/Actions/Intents}/KillIntent.swift +0 -0
- /package/app/Sources/{Intents → Core/Actions/Intents}/LaunchIntent.swift +0 -0
- /package/app/Sources/{Intents → Core/Actions/Intents}/ListSessionsIntent.swift +0 -0
- /package/app/Sources/{Intents → Core/Actions/Intents}/ListWindowsIntent.swift +0 -0
- /package/app/Sources/{Intents → Core/Actions/Intents}/ScanIntent.swift +0 -0
- /package/app/Sources/{Intents → Core/Actions/Intents}/SearchIntent.swift +0 -0
- /package/app/Sources/{Intents → Core/Actions/Intents}/SwitchLayerIntent.swift +0 -0
- /package/app/Sources/{Intents → Core/Actions/Intents}/TileIntent.swift +0 -0
- /package/app/Sources/{DaemonProtocol.swift → Core/Daemon/DaemonProtocol.swift} +0 -0
- /package/app/Sources/{DaemonServer.swift → Core/Daemon/DaemonServer.swift} +0 -0
- /package/app/Sources/{AccessibilityTextExtractor.swift → Core/Desktop/AccessibilityTextExtractor.swift} +0 -0
- /package/app/Sources/{DesktopModelTypes.swift → Core/Desktop/DesktopModelTypes.swift} +0 -0
- /package/app/Sources/{InventoryManager.swift → Core/Desktop/InventoryManager.swift} +0 -0
- /package/app/Sources/{InventoryPath.swift → Core/Desktop/InventoryPath.swift} +0 -0
- /package/app/Sources/{OcrModel.swift → Core/Desktop/OcrModel.swift} +0 -0
- /package/app/Sources/{OcrStore.swift → Core/Desktop/OcrStore.swift} +0 -0
- /package/app/Sources/{PlacementSpec.swift → Core/Desktop/PlacementSpec.swift} +0 -0
- /package/app/Sources/{TilePickerView.swift → Core/Desktop/TilePickerView.swift} +0 -0
- /package/app/Sources/{AppWindowShell.swift → Core/Overlays/AppWindowShell.swift} +0 -0
- /package/app/Sources/{CommandModeWindow.swift → Core/Overlays/CommandMode/CommandModeWindow.swift} +0 -0
- /package/app/Sources/{CommandPaletteView.swift → Core/Overlays/CommandPalette/CommandPaletteView.swift} +0 -0
- /package/app/Sources/{HUDBottomBar.swift → Core/Overlays/HUD/HUDBottomBar.swift} +0 -0
- /package/app/Sources/{HUDController.swift → Core/Overlays/HUD/HUDController.swift} +0 -0
- /package/app/Sources/{HUDLeftBar.swift → Core/Overlays/HUD/HUDLeftBar.swift} +0 -0
- /package/app/Sources/{HUDMinimap.swift → Core/Overlays/HUD/HUDMinimap.swift} +0 -0
- /package/app/Sources/{HUDState.swift → Core/Overlays/HUD/HUDState.swift} +0 -0
- /package/app/Sources/{HUDTopBar.swift → Core/Overlays/HUD/HUDTopBar.swift} +0 -0
- /package/app/Sources/{LayerBezel.swift → Core/Overlays/HUD/LayerBezel.swift} +0 -0
- /package/app/Sources/{OmniSearchState.swift → Core/Overlays/OmniSearch/OmniSearchState.swift} +0 -0
- /package/app/Sources/{DiagnosticLog.swift → Core/System/DiagnosticLog.swift} +0 -0
- /package/app/Sources/{EventBus.swift → Core/System/EventBus.swift} +0 -0
- /package/app/Sources/{ProcessModel.swift → Core/System/ProcessModel.swift} +0 -0
- /package/app/Sources/{ProcessQuery.swift → Core/System/ProcessQuery.swift} +0 -0
- /package/app/Sources/{AdvisorLearningStore.swift → Core/Voice/AdvisorLearningStore.swift} +0 -0
- /package/app/Sources/{AgentSession.swift → Core/Voice/AgentSession.swift} +0 -0
- /package/app/Sources/{AudioProvider.swift → Core/Voice/AudioProvider.swift} +0 -0
- /package/app/Sources/{VoiceChatView.swift → Core/Voice/VoiceChatView.swift} +0 -0
- /package/app/Sources/{VoxClient.swift → Core/Voice/VoxClient.swift} +0 -0
- /package/app/Sources/{Project.swift → Core/Workspace/Project.swift} +0 -0
- /package/app/Sources/{ProjectScanner.swift → Core/Workspace/ProjectScanner.swift} +0 -0
- /package/app/Sources/{SessionLayerStore.swift → Core/Workspace/SessionLayerStore.swift} +0 -0
- /package/app/Sources/{SessionManager.swift → Core/Workspace/SessionManager.swift} +0 -0
- /package/app/Sources/{Terminal.swift → Core/Workspace/Terminal/Terminal.swift} +0 -0
- /package/app/Sources/{TerminalQuery.swift → Core/Workspace/Terminal/TerminalQuery.swift} +0 -0
- /package/app/Sources/{TerminalSynthesizer.swift → Core/Workspace/Terminal/TerminalSynthesizer.swift} +0 -0
- /package/app/Sources/{TmuxModel.swift → Core/Workspace/Tmux/TmuxModel.swift} +0 -0
- /package/app/Sources/{TmuxQuery.swift → Core/Workspace/Tmux/TmuxQuery.swift} +0 -0
- /package/app/Sources/{ActionRow.swift → UI/ActionRow.swift} +0 -0
- /package/app/Sources/{OrphanRow.swift → UI/OrphanRow.swift} +0 -0
- /package/app/Sources/{ProjectRow.swift → UI/ProjectRow.swift} +0 -0
- /package/app/Sources/{TabGroupRow.swift → UI/TabGroupRow.swift} +0 -0
- /package/app/Sources/{Theme.swift → UI/Theme.swift} +0 -0
|
@@ -16,7 +16,7 @@ struct PiChatDock: View {
|
|
|
16
16
|
VStack(spacing: 0) {
|
|
17
17
|
topHandle
|
|
18
18
|
|
|
19
|
-
if session.isAuthPanelVisible {
|
|
19
|
+
if session.hasPiBinary && session.isAuthPanelVisible {
|
|
20
20
|
Rectangle()
|
|
21
21
|
.fill(Palette.border)
|
|
22
22
|
.frame(height: 0.5)
|
|
@@ -34,7 +34,23 @@ struct PiChatDock: View {
|
|
|
34
34
|
.fill(Palette.border)
|
|
35
35
|
.frame(height: 0.5)
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
if session.hasPiBinary && !session.needsProviderSetup {
|
|
38
|
+
composer
|
|
39
|
+
} else if session.needsProviderSetup {
|
|
40
|
+
if session.isAuthPanelVisible {
|
|
41
|
+
setupLockedBar
|
|
42
|
+
} else {
|
|
43
|
+
PiProviderSetupCallout(session: session, compact: true)
|
|
44
|
+
.padding(.horizontal, 10)
|
|
45
|
+
.padding(.vertical, 10)
|
|
46
|
+
.background(Color.black.opacity(0.62))
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
PiInstallCallout(session: session, compact: true)
|
|
50
|
+
.padding(.horizontal, 10)
|
|
51
|
+
.padding(.vertical, 10)
|
|
52
|
+
.background(Color.black.opacity(0.62))
|
|
53
|
+
}
|
|
38
54
|
|
|
39
55
|
Rectangle()
|
|
40
56
|
.fill(Palette.border)
|
|
@@ -59,8 +75,11 @@ struct PiChatDock: View {
|
|
|
59
75
|
.strokeBorder(Palette.border, lineWidth: 0.5)
|
|
60
76
|
)
|
|
61
77
|
.onAppear {
|
|
62
|
-
|
|
63
|
-
|
|
78
|
+
session.prepareForDisplay()
|
|
79
|
+
if session.hasPiBinary && !session.needsProviderSetup {
|
|
80
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
|
81
|
+
composerFocused = true
|
|
82
|
+
}
|
|
64
83
|
}
|
|
65
84
|
}
|
|
66
85
|
}
|
|
@@ -113,99 +132,113 @@ struct PiChatDock: View {
|
|
|
113
132
|
|
|
114
133
|
private var authPanel: some View {
|
|
115
134
|
VStack(alignment: .leading, spacing: 10) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
135
|
+
if session.isAuthenticating {
|
|
136
|
+
VStack(alignment: .leading, spacing: 4) {
|
|
137
|
+
Text("Finish Setup")
|
|
138
|
+
.font(Typo.geistMonoBold(10))
|
|
139
|
+
.foregroundColor(Palette.text)
|
|
120
140
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
141
|
+
Text("Ignore the rest for a second and just do the next step below.")
|
|
142
|
+
.font(Typo.mono(9))
|
|
143
|
+
.foregroundColor(Palette.textDim)
|
|
144
|
+
.fixedSize(horizontal: false, vertical: true)
|
|
125
145
|
}
|
|
126
|
-
.labelsHidden()
|
|
127
|
-
.pickerStyle(.menu)
|
|
128
|
-
.font(Typo.mono(10))
|
|
129
|
-
|
|
130
|
-
Spacer()
|
|
131
|
-
|
|
132
|
-
capsuleLabel(
|
|
133
|
-
session.currentProvider.authMode == .oauth ? "OAUTH" : "TOKEN",
|
|
134
|
-
tint: session.currentProvider.authMode == .oauth ? Palette.detach : Palette.running
|
|
135
|
-
)
|
|
136
|
-
}
|
|
137
146
|
|
|
138
|
-
Text(session.currentProvider.helpText)
|
|
139
|
-
.font(Typo.mono(10))
|
|
140
|
-
.foregroundColor(Palette.textDim)
|
|
141
|
-
.fixedSize(horizontal: false, vertical: true)
|
|
142
|
-
|
|
143
|
-
if session.currentProvider.authMode == .apiKey {
|
|
144
147
|
HStack(spacing: 8) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
.focused($authFieldFocused)
|
|
150
|
-
.onSubmit {
|
|
151
|
-
session.saveSelectedToken()
|
|
152
|
-
}
|
|
148
|
+
capsuleLabel(session.currentProvider.name.uppercased(), tint: Palette.text)
|
|
149
|
+
capsuleLabel("IN PROGRESS", tint: Palette.detach)
|
|
150
|
+
Spacer()
|
|
151
|
+
}
|
|
153
152
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
153
|
+
if let prompt = session.pendingAuthPrompt {
|
|
154
|
+
PiAuthPromptCard(session: session, prompt: prompt, compact: true, focus: $authFieldFocused)
|
|
155
|
+
} else {
|
|
156
|
+
PiAuthNextStepCard(session: session, compact: true)
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
if session.needsProviderSetup {
|
|
160
|
+
VStack(alignment: .leading, spacing: 4) {
|
|
161
|
+
Text("Set Up Your AI")
|
|
162
|
+
.font(Typo.geistMonoBold(10))
|
|
163
|
+
.foregroundColor(Palette.text)
|
|
157
164
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
165
|
+
Text("Choose a provider, connect it once, and the chat box unlocks automatically.")
|
|
166
|
+
.font(Typo.mono(9))
|
|
167
|
+
.foregroundColor(Palette.textDim)
|
|
168
|
+
.fixedSize(horizontal: false, vertical: true)
|
|
162
169
|
}
|
|
163
170
|
}
|
|
164
|
-
|
|
165
|
-
.padding(.vertical, 8)
|
|
166
|
-
.background(authCardBackground(tint: Palette.running))
|
|
167
|
-
} else {
|
|
171
|
+
|
|
168
172
|
HStack(spacing: 8) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
} else {
|
|
173
|
-
session.startSelectedAuthFlow()
|
|
174
|
-
}
|
|
175
|
-
}
|
|
173
|
+
Text(session.needsProviderSetup ? "choose provider" : "provider")
|
|
174
|
+
.font(Typo.geistMonoBold(9))
|
|
175
|
+
.foregroundColor(Palette.textMuted)
|
|
176
176
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
177
|
+
Picker("Provider", selection: $session.authProviderID) {
|
|
178
|
+
ForEach(session.providerOptions) { provider in
|
|
179
|
+
Text(provider.name).tag(provider.id)
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
+
.labelsHidden()
|
|
183
|
+
.pickerStyle(.menu)
|
|
184
|
+
.font(Typo.mono(10))
|
|
185
|
+
|
|
186
|
+
Spacer()
|
|
187
|
+
|
|
188
|
+
capsuleLabel(
|
|
189
|
+
session.currentProvider.authMode == .oauth ? "OAUTH" : "TOKEN",
|
|
190
|
+
tint: session.currentProvider.authMode == .oauth ? Palette.detach : Palette.running
|
|
191
|
+
)
|
|
182
192
|
}
|
|
183
|
-
.padding(.horizontal, 10)
|
|
184
|
-
.padding(.vertical, 8)
|
|
185
|
-
.background(authCardBackground(tint: session.isAuthenticating ? Palette.detach : Palette.running))
|
|
186
193
|
|
|
187
|
-
|
|
194
|
+
Text(session.currentProvider.helpText)
|
|
195
|
+
.font(Typo.mono(10))
|
|
196
|
+
.foregroundColor(Palette.textDim)
|
|
197
|
+
.fixedSize(horizontal: false, vertical: true)
|
|
198
|
+
|
|
199
|
+
if session.currentProvider.authMode == .apiKey {
|
|
188
200
|
HStack(spacing: 8) {
|
|
189
|
-
|
|
201
|
+
SecureField(session.currentProvider.tokenPlaceholder, text: $session.authToken)
|
|
190
202
|
.textFieldStyle(.plain)
|
|
191
203
|
.font(Typo.mono(11))
|
|
192
204
|
.foregroundColor(Palette.text)
|
|
193
205
|
.focused($authFieldFocused)
|
|
194
206
|
.onSubmit {
|
|
195
|
-
session.
|
|
207
|
+
session.saveSelectedToken()
|
|
196
208
|
}
|
|
197
209
|
|
|
198
|
-
footerButton("
|
|
199
|
-
session.
|
|
210
|
+
footerButton("save key") {
|
|
211
|
+
session.saveSelectedToken()
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if session.hasSelectedCredential {
|
|
215
|
+
footerButton("clear") {
|
|
216
|
+
session.removeSelectedCredential()
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
.padding(.horizontal, 10)
|
|
221
|
+
.padding(.vertical, 8)
|
|
222
|
+
.background(authCardBackground(tint: Palette.running))
|
|
223
|
+
} else {
|
|
224
|
+
HStack(spacing: 8) {
|
|
225
|
+
footerButton("connect") {
|
|
226
|
+
session.startSelectedAuthFlow()
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if session.hasSelectedCredential {
|
|
230
|
+
footerButton("clear") {
|
|
231
|
+
session.removeSelectedCredential()
|
|
232
|
+
}
|
|
200
233
|
}
|
|
201
234
|
}
|
|
202
235
|
.padding(.horizontal, 10)
|
|
203
236
|
.padding(.vertical, 8)
|
|
204
|
-
.background(authCardBackground(tint: Palette.
|
|
237
|
+
.background(authCardBackground(tint: Palette.running))
|
|
205
238
|
}
|
|
206
239
|
}
|
|
207
240
|
|
|
208
|
-
if let notice = session.authNoticeText, !notice.isEmpty {
|
|
241
|
+
if !session.isAuthenticating, let notice = session.authNoticeText, !notice.isEmpty {
|
|
209
242
|
Text(notice)
|
|
210
243
|
.font(Typo.mono(9))
|
|
211
244
|
.foregroundColor(Palette.textDim)
|
|
@@ -362,8 +395,10 @@ struct PiChatDock: View {
|
|
|
362
395
|
|
|
363
396
|
Spacer()
|
|
364
397
|
|
|
365
|
-
|
|
366
|
-
session.
|
|
398
|
+
if session.hasPiBinary && !session.needsProviderSetup {
|
|
399
|
+
footerButton(session.isAuthPanelVisible ? "auth -" : "auth +") {
|
|
400
|
+
session.toggleAuthPanel()
|
|
401
|
+
}
|
|
367
402
|
}
|
|
368
403
|
|
|
369
404
|
footerButton("reset") {
|
|
@@ -376,8 +411,8 @@ struct PiChatDock: View {
|
|
|
376
411
|
}
|
|
377
412
|
|
|
378
413
|
private var footerStatusText: String {
|
|
379
|
-
if session.statusText == "idle" {
|
|
380
|
-
return session.
|
|
414
|
+
if session.statusText == "idle" || session.needsProviderSetup || session.isAuthenticating || !session.hasPiBinary {
|
|
415
|
+
return session.setupStatusSummary
|
|
381
416
|
}
|
|
382
417
|
return "\(session.currentProvider.name) · \(session.statusText)"
|
|
383
418
|
}
|
|
@@ -390,6 +425,32 @@ struct PiChatDock: View {
|
|
|
390
425
|
}
|
|
391
426
|
}
|
|
392
427
|
|
|
428
|
+
private var setupLockedBar: some View {
|
|
429
|
+
HStack(alignment: .center, spacing: 8) {
|
|
430
|
+
Circle()
|
|
431
|
+
.fill(Palette.detach)
|
|
432
|
+
.frame(width: 6, height: 6)
|
|
433
|
+
|
|
434
|
+
VStack(alignment: .leading, spacing: 2) {
|
|
435
|
+
Text("SETUP IN PROGRESS")
|
|
436
|
+
.font(Typo.geistMonoBold(9))
|
|
437
|
+
.foregroundColor(Palette.text)
|
|
438
|
+
|
|
439
|
+
Text(session.isAuthenticating
|
|
440
|
+
? "Stay with the setup panel above for now. The chat box unlocks as soon as you finish that step."
|
|
441
|
+
: "Finish the setup panel above to unlock the chat box.")
|
|
442
|
+
.font(Typo.mono(9))
|
|
443
|
+
.foregroundColor(Palette.textDim)
|
|
444
|
+
.fixedSize(horizontal: false, vertical: true)
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
Spacer()
|
|
448
|
+
}
|
|
449
|
+
.padding(.horizontal, 10)
|
|
450
|
+
.padding(.vertical, 10)
|
|
451
|
+
.background(Color.black.opacity(0.62))
|
|
452
|
+
}
|
|
453
|
+
|
|
393
454
|
private func roleLabel(for role: PiChatMessage.Role) -> String {
|
|
394
455
|
switch role {
|
|
395
456
|
case .system: return "system"
|
|
@@ -426,11 +487,11 @@ struct PiChatDock: View {
|
|
|
426
487
|
)
|
|
427
488
|
}
|
|
428
489
|
|
|
429
|
-
private func footerButton(_ label: String, tint: Color = Palette.textMuted, action: @escaping () -> Void) -> some View {
|
|
490
|
+
private func footerButton(_ label: String, tint: Color = Palette.textMuted, disabled: Bool = false, action: @escaping () -> Void) -> some View {
|
|
430
491
|
Button(label, action: action)
|
|
431
492
|
.buttonStyle(.plain)
|
|
432
493
|
.font(Typo.geistMonoBold(9))
|
|
433
|
-
.foregroundColor(tint)
|
|
494
|
+
.foregroundColor(disabled ? Palette.textMuted : tint)
|
|
434
495
|
.padding(.horizontal, 8)
|
|
435
496
|
.padding(.vertical, 5)
|
|
436
497
|
.background(
|
|
@@ -441,6 +502,8 @@ struct PiChatDock: View {
|
|
|
441
502
|
.strokeBorder(Palette.border, lineWidth: 0.5)
|
|
442
503
|
)
|
|
443
504
|
)
|
|
505
|
+
.opacity(disabled ? 0.65 : 1)
|
|
506
|
+
.disabled(disabled)
|
|
444
507
|
}
|
|
445
508
|
|
|
446
509
|
private func authCardBackground(tint: Color) -> some View {
|