Gives each conversation an opt-in, persistent memory file the model reads automatically every turn and writes to on its own initiative via a fenced ```update-notes``` block in its reply — no per-write approval, matching the Confab-as-CLAUDE.md-for-itself concept Rune wanted. /notes on|off|show, files live in ~/Library/Application Support/oAI/notes/, embedded ID header for future Git Sync compatibility. Adds DB migration v12.
30 lines
951 B
Swift
30 lines
951 B
Swift
//
|
|
// StringExtensionsTests.swift
|
|
// oAITests
|
|
//
|
|
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
|
// Copyright (C) 2026 Rune Olsen
|
|
|
|
import Testing
|
|
@testable import Confab
|
|
|
|
@Suite("String.sanitizedForFilename")
|
|
struct StringExtensionsTests {
|
|
|
|
@Test("Invalid filename characters are replaced with a dash")
|
|
func sanitizedForFilenameStripsInvalidChars() {
|
|
#expect("a/b\\c:d*e?f\"g<h>i|j".sanitizedForFilename() == "a-b-c-d-e-f-g-h-i-j")
|
|
}
|
|
|
|
@Test("A valid filename passes through unchanged")
|
|
func sanitizedForFilenameValidInput() {
|
|
#expect("My Chat 2026-01-15".sanitizedForFilename() == "My Chat 2026-01-15")
|
|
}
|
|
|
|
@Test("GitSyncService.sanitizeFilename delegates to the shared extension")
|
|
func gitSyncServiceDelegatesToExtension() {
|
|
let service = GitSyncService.shared
|
|
#expect(service.sanitizeFilename("a/b\\c:d*e?f\"g<h>i|j") == "a-b-c-d-e-f-g-h-i-j".sanitizedForFilename())
|
|
}
|
|
}
|