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
73 changes: 0 additions & 73 deletions TablePro/Core/AI/OllamaDetector.swift

This file was deleted.

18 changes: 3 additions & 15 deletions TablePro/Core/Diagnostics/TableLoadHistoryStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,6 @@ internal actor TableLoadHistoryStore: TableLoadSummarySink {
pruneIfNeeded()
}

internal func records() -> [TableLoadPerformanceRecord] {
loadIfNeeded()
return Self.decodeRecords(in: Self.readFile(at: fileURL)).map(\.record)
}

/// Byte-for-byte stable for the same input, so an external report can diff two exports.
internal func exportJSON() -> Data {
(try? Self.makeEncoder(prettyPrinted: true).encode(records())) ?? Data()
}

/// The first touch in a process reconciles the file against the retention rules, so a history
/// left behind by a build that quit before pruning cannot grow past its caps.
private func loadIfNeeded() {
Expand Down Expand Up @@ -197,7 +187,7 @@ internal actor TableLoadHistoryStore: TableLoadSummarySink {
}

private static func encode(_ record: TableLoadPerformanceRecord) -> Data? {
guard var data = try? makeEncoder(prettyPrinted: false).encode(record) else {
guard var data = try? makeEncoder().encode(record) else {
logger.error("Table load history record could not be encoded")
return nil
}
Expand All @@ -214,11 +204,9 @@ internal actor TableLoadHistoryStore: TableLoadSummarySink {
}
}

internal static func makeEncoder(prettyPrinted: Bool) -> JSONEncoder {
internal static func makeEncoder() -> JSONEncoder {
let encoder = JSONEncoder()
encoder.outputFormatting = prettyPrinted
? [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes]
: [.sortedKeys, .withoutEscapingSlashes]
encoder.outputFormatting = [.sortedKeys, .withoutEscapingSlashes]
encoder.dateEncodingStrategy = .custom { date, encoder in
var container = encoder.singleValueContainer()
try container.encode(timestamps.format(date))
Expand Down
140 changes: 0 additions & 140 deletions TablePro/Core/MCP/Transport/MCPStdioMessageTransport.swift

This file was deleted.

34 changes: 3 additions & 31 deletions TablePro/Core/Services/Policy/ManagedPolicy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,50 +17,22 @@ internal enum ManagedPolicy: String, CaseIterable, Sendable {
/// raised to this; a stronger choice is left alone, so the policy is a floor and never a ceiling.
case minimumSafeModeLevel = "com.TablePro.policy.minimumSafeModeLevel"

/// Stops the MCP server from listening, so an AI client cannot reach the databases at all.
case mcpServerDisabled = "com.TablePro.policy.mcpServerDisabled"

/// Stops the in-app AI assistant, including inline suggestions.
case aiAssistantDisabled = "com.TablePro.policy.aiAssistantDisabled"

/// Stops plugins being installed, from the registry or from a file.
case pluginInstallDisabled = "com.TablePro.policy.pluginInstallDisabled"

internal var key: String { rawValue }
}

internal protocol ManagedPolicyReading: Sendable {
/// True when a configuration profile supplies this key, so the UI for it must be disabled.
func isManaged(_ policy: ManagedPolicy) -> Bool
func bool(_ policy: ManagedPolicy) -> Bool
func string(_ policy: ManagedPolicy) -> String?
}

/// Reads policy out of the standard preferences chain.
///
/// macOS already merges a configuration profile's values into `UserDefaults` at the highest
/// priority, so reading a managed key needs no special path: the forced value simply wins. The one
/// thing the normal API cannot tell you is *whether* a key was forced, which is what
/// `CFPreferencesAppValueIsForced` is for. Its own header says callers "should use this function to
/// determine whether or not to disable UI elements corresponding to those preference keys".
/// Reads policy out of the standard preferences chain. macOS merges a configuration profile's
/// values into `UserDefaults` at the highest priority, so the forced value simply wins.
internal struct ManagedPolicyReader: ManagedPolicyReading, @unchecked Sendable {
internal static let shared = ManagedPolicyReader()

private let defaults: UserDefaults
private let applicationID: String

internal init(defaults: UserDefaults = .standard, applicationID: String = Bundle.main.bundleIdentifier ?? "") {
internal init(defaults: UserDefaults = .standard) {
self.defaults = defaults
self.applicationID = applicationID
}

internal func isManaged(_ policy: ManagedPolicy) -> Bool {
guard !applicationID.isEmpty else { return false }
return CFPreferencesAppValueIsForced(policy.key as CFString, applicationID as CFString)
}

internal func bool(_ policy: ManagedPolicy) -> Bool {
defaults.bool(forKey: policy.key)
}

internal func string(_ policy: ManagedPolicy) -> String? {
Expand Down
Loading
Loading