Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- AI Chat: `@` mention detection no longer breaks when the cursor sits right after an emoji or other non-BMP character
- AI Chat: Fix Error prompt now reads "MongoDB query" and "Redis command" using the database display name, instead of the raw query language label
- Internal: tab session registry binds automatically when a coordinator falls back to creating its own registry, so unit tests no longer trip the filter-state debug assertion
- Connection-only payloads no longer create an empty `Query 1` tab when there is no query, title, or source file to populate it

## [0.39.1] - 2026-05-08

Expand Down
17 changes: 11 additions & 6 deletions TablePro/Core/Services/Infrastructure/SessionStateFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,17 @@ enum SessionStateFactory {
tabMgr.addTab(databaseName: payload.databaseName ?? activeDatabaseName)
}
case .query:
tabMgr.addTab(
initialQuery: payload.initialQuery,
title: payload.tabTitle,
databaseName: payload.databaseName ?? activeDatabaseName,
sourceFileURL: payload.sourceFileURL
)
let hasContent = payload.initialQuery != nil
|| payload.tabTitle != nil
|| payload.sourceFileURL != nil
if hasContent {
tabMgr.addTab(
initialQuery: payload.initialQuery,
title: payload.tabTitle,
databaseName: payload.databaseName ?? activeDatabaseName,
sourceFileURL: payload.sourceFileURL
)
}
case .createTable:
tabMgr.addCreateTableTab(
databaseName: payload.databaseName ?? activeDatabaseName
Expand Down
12 changes: 8 additions & 4 deletions TableProTests/ViewModels/AIChatViewModelMentionsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,21 @@ struct AIChatViewModelMentionsTests {
#expect(vm.attachedContext.isEmpty)
}

@Test("Sending with currentQuery attachment embeds the query text in the prompt")
func currentQueryResolved() {
@Test("Sending with currentQuery attachment resolves the query text on the wire")
func currentQueryResolved() async {
let vm = AIChatViewModel()
vm.connection = TestFixtures.makeConnection(type: .mysql)
vm.inputText = "Explain"
vm.attach(.currentQuery(text: "SELECT * FROM Customer"))

vm.sendMessage()

let userTurn = vm.messages.first(where: { $0.role == .user })
let prompt = userTurn?.plainText ?? ""
guard let userTurn = vm.messages.first(where: { $0.role == .user }) else {
Issue.record("expected a user turn after sendMessage")
return
}
let wire = await vm.resolveTurnForWire(userTurn)
let prompt = wire.plainText
#expect(prompt.contains("Explain"))
#expect(prompt.contains("SELECT * FROM Customer"))
#expect(prompt.contains("## Current Query"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,14 @@ struct MainContentCoordinatorLazyLoadTests {
func skipsWhenAlreadyExecuting() {
let (coordinator, tabManager) = makeCoordinator()
let tabId = addTableTab(to: tabManager)
seedRows(coordinator, for: tabId, rowCount: 1)
guard let idx = tabManager.tabs.firstIndex(where: { $0.id == tabId }) else {
Issue.record("expected tab to exist")
return
}
tabManager.tabs[idx].execution.lastExecutedAt = Date()
tabManager.tabs[idx].execution.isExecuting = true
coordinator.tabSessionRegistry.evict(for: tabId)

coordinator.lazyLoadCurrentTabIfNeeded()
#expect(coordinator.needsLazyLoad == false)
Expand Down
Loading