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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Window menu: "Integrations Activity" opens a dedicated, resizable window for the MCP activity log and connected clients. The window has a sidebar (Activity Log / Connected Clients) and a unified toolbar with native search, filter menu, refresh, and export. Window size is remembered across launches.
- Sample database (Chinook) bundled — open from welcome screen with one click; reset via File menu
- Connection string detection — paste a `postgres://`, `mysql://`, `redis://`, or `mongodb://` URL, then click Use to auto-fill the connection form
- Activation telemetry: the daily heartbeat now reports three write-once timestamps per device (first connection attempt, first successful connection, first executed query), so we can see where new users drop off during activation. The values are stored locally in UserDefaults, set once and never overwritten, and the server also refuses to overwrite them once received. Both Mac and iOS send the same fields.
Expand All @@ -31,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Settings > Integrations is now a flat preferences pane per macOS HIG. The activity log, the connected-clients list, and the setup instructions have moved out of Settings: activity and connections live in the new Integrations Activity window (Window menu), and setup instructions open in a "Connect a Client…" sheet from the Settings pane. Settings keeps only configuration: server toggle, status, port, row limits, query timeout, authentication tokens, and network options.
- MCP: idle session timeout raised from 5 to 15 minutes.
- MCP: complete internal rewrite of the server, stdio bridge, and protocol dispatcher for spec compliance. Public API of `MCPServerManager` and the on-disk handshake format are unchanged; clients do not need to re-pair.
- Internal: introduce `TabSession` as the foundation type for the editor tab/window subsystem rewrite. Currently a parallel structure mirroring `QueryTab`; subsequent PRs migrate state ownership and lifecycle hooks per `docs/architecture/tab-subsystem-rewrite.md`. No user-visible behavior change in this PR.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// IntegrationsActivityWindowFactory.swift
// TablePro
//

import AppKit
import SwiftUI

@MainActor
internal enum IntegrationsActivityWindowFactory {
private static let identifier = NSUserInterfaceItemIdentifier("integrations-activity")
private static let autosaveName: NSWindow.FrameAutosaveName = "IntegrationsActivityWindow"
private static let defaultSize = NSSize(width: 960, height: 600)
private static let minimumSize = NSSize(width: 720, height: 420)

internal static func openOrFront() {
if let existing = existingWindow() {
existing.makeKeyAndOrderFront(nil)
NSApp.activate(ignoringOtherApps: true)
return
}
let window = makeWindow()
window.makeKeyAndOrderFront(nil)
NSApp.activate(ignoringOtherApps: true)
}

private static func existingWindow() -> NSWindow? {
NSApp.windows.first { $0.identifier == identifier }
}

private static func makeWindow() -> NSWindow {
let hostingController = NSHostingController(rootView: IntegrationsActivityView())
let window = NSWindow(contentViewController: hostingController)
window.identifier = identifier
window.title = String(localized: "Integrations Activity")
window.styleMask = [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView]
window.toolbarStyle = .unified
window.titlebarSeparatorStyle = .automatic
window.collectionBehavior.insert(.fullScreenPrimary)
window.isReleasedWhenClosed = false
window.setContentSize(defaultSize)
window.minSize = minimumSize
window.applyAutosaveName(autosaveName)
return window
}
}
60 changes: 57 additions & 3 deletions TablePro/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -1480,6 +1480,9 @@
},
"%1$@, %2$@" : {
"shouldTranslate" : false
},
"%d connected" : {

},
"%d connections found" : {
"localizations" : {
Expand Down Expand Up @@ -3853,6 +3856,9 @@
}
}
}
},
"Active %@" : {

},
"Active Connections" : {
"localizations" : {
Expand Down Expand Up @@ -3985,8 +3991,15 @@
}
}
}
},
"Activity" : {

},
"Activity is retained for 90 days" : {

},
"Activity is retained for 90 days." : {
"extractionState" : "stale",
"localizations" : {
"tr" : {
"stringUnit" : {
Expand Down Expand Up @@ -7836,9 +7849,6 @@
}
}
}
},
"Bundled sample database" : {

},
"Bytes Received" : {
"localizations" : {
Expand Down Expand Up @@ -8845,6 +8855,12 @@
}
}
}
},
"Choose a section from the sidebar." : {

},
"Choose your client and follow the steps to connect it to TablePro." : {

},
"Claude Code" : {
"localizations" : {
Expand Down Expand Up @@ -9044,6 +9060,9 @@
}
}
}
},
"Clear Filters" : {

},
"Clear History..." : {
"localizations" : {
Expand Down Expand Up @@ -9135,6 +9154,7 @@
}
},
"Clear search" : {
"extractionState" : "stale",
"localizations" : {
"tr" : {
"stringUnit" : {
Expand Down Expand Up @@ -9557,6 +9577,9 @@
}
}
}
},
"Clients will appear here while they have an active MCP session." : {

},
"Clipboard is empty or contains no text data." : {
"localizations" : {
Expand Down Expand Up @@ -10706,6 +10729,9 @@
}
}
}
},
"Connect a Client…" : {

},
"Connect Anyway" : {
"localizations" : {
Expand Down Expand Up @@ -15730,6 +15756,9 @@
},
"Disconnect from a database" : {

},
"Disconnect the selected client" : {

},
"Disconnected" : {
"localizations" : {
Expand Down Expand Up @@ -18839,6 +18868,7 @@
}
},
"Export activity to CSV" : {
"extractionState" : "stale",
"localizations" : {
"tr" : {
"stringUnit" : {
Expand Down Expand Up @@ -19374,6 +19404,7 @@
}
},
"Export…" : {
"extractionState" : "stale",
"localizations" : {
"tr" : {
"stringUnit" : {
Expand Down Expand Up @@ -21035,6 +21066,9 @@
}
}
}
},
"Filter activity" : {

},
"Filter column" : {
"localizations" : {
Expand Down Expand Up @@ -24619,6 +24653,9 @@
}
}
}
},
"Integrations Activity" : {

},
"Integrations: Failed" : {
"localizations" : {
Expand Down Expand Up @@ -27009,6 +27046,7 @@
}
},
"Local only - not synced to iCloud" : {
"extractionState" : "stale",
"localizations" : {
"tr" : {
"stringUnit" : {
Expand All @@ -27029,6 +27067,9 @@
}
}
}
},
"Local only, not synced to iCloud" : {

},
"localhost" : {
"localizations" : {
Expand Down Expand Up @@ -29462,6 +29503,9 @@
}
}
}
},
"No activity matches the current filters." : {

},
"No activity yet" : {
"localizations" : {
Expand Down Expand Up @@ -30043,6 +30087,9 @@
}
}
}
},
"No matching activity" : {

},
"No matching connections" : {
"extractionState" : "stale",
Expand Down Expand Up @@ -41089,6 +41136,7 @@
}
},
"Settings" : {
"extractionState" : "stale",
"localizations" : {
"tr" : {
"stringUnit" : {
Expand Down Expand Up @@ -50334,6 +50382,9 @@
}
}
}
},
"via %@" : {

},
"View" : {
"localizations" : {
Expand All @@ -50356,6 +50407,9 @@
}
}
}
},
"View Activity…" : {

},
"View ER Diagram" : {
"localizations" : {
Expand Down
6 changes: 6 additions & 0 deletions TablePro/TableProApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,12 @@ struct AppMenuCommands: Commands {

Divider()

Button(String(localized: "Integrations Activity")) {
IntegrationsActivityWindowFactory.openOrFront()
}

Divider()

Button("Bring All to Front") {
NSApp.arrangeInFront(nil)
}
Expand Down
Loading
Loading