Skip to content

Commit 68466fc

Browse files
committed
feat: release prep
1 parent 0f55410 commit 68466fc

File tree

14 files changed

+857
-74
lines changed

14 files changed

+857
-74
lines changed

apple/Clarissa/Clarissa.xcodeproj/project.pbxproj

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@
448448
CLANG_ENABLE_OBJC_WEAK = YES;
449449
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
450450
CODE_SIGN_STYLE = Automatic;
451-
CURRENT_PROJECT_VERSION = 1;
451+
CURRENT_PROJECT_VERSION = 15;
452452
DEVELOPMENT_TEAM = SDRCMNG666;
453453
GCC_C_LANGUAGE_STANDARD = gnu17;
454454
GCC_PREPROCESSOR_DEFINITIONS = (
@@ -458,7 +458,7 @@
458458
GENERATE_INFOPLIST_FILE = YES;
459459
IPHONEOS_DEPLOYMENT_TARGET = 26.2;
460460
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
461-
MARKETING_VERSION = 1.0;
461+
MARKETING_VERSION = 1.0.0;
462462
PRODUCT_BUNDLE_IDENTIFIER = dev.rye.ClarissaUITests;
463463
PRODUCT_NAME = "$(TARGET_NAME)";
464464
SDKROOT = iphoneos;
@@ -479,13 +479,13 @@
479479
CLANG_ENABLE_OBJC_WEAK = YES;
480480
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
481481
CODE_SIGN_STYLE = Automatic;
482-
CURRENT_PROJECT_VERSION = 1;
482+
CURRENT_PROJECT_VERSION = 15;
483483
DEVELOPMENT_TEAM = SDRCMNG666;
484484
GCC_C_LANGUAGE_STANDARD = gnu17;
485485
GENERATE_INFOPLIST_FILE = YES;
486486
IPHONEOS_DEPLOYMENT_TARGET = 26.2;
487487
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
488-
MARKETING_VERSION = 1.0;
488+
MARKETING_VERSION = 1.0.0;
489489
PRODUCT_BUNDLE_IDENTIFIER = dev.rye.ClarissaUITests;
490490
PRODUCT_NAME = "$(TARGET_NAME)";
491491
SDKROOT = iphoneos;
@@ -624,7 +624,7 @@
624624
"CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "Resources/Clarissa-iOS.entitlements";
625625
"CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "Resources/Clarissa-macOS.entitlements";
626626
CODE_SIGN_STYLE = Automatic;
627-
CURRENT_PROJECT_VERSION = 2;
627+
CURRENT_PROJECT_VERSION = 15;
628628
ENABLE_HARDENED_RUNTIME = YES;
629629
GENERATE_INFOPLIST_FILE = NO;
630630
INFOPLIST_FILE = Resources/Info.plist;
@@ -663,7 +663,7 @@
663663
"CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "Resources/Clarissa-iOS.entitlements";
664664
"CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "Resources/Clarissa-macOS.entitlements";
665665
CODE_SIGN_STYLE = Automatic;
666-
CURRENT_PROJECT_VERSION = 2;
666+
CURRENT_PROJECT_VERSION = 15;
667667
ENABLE_HARDENED_RUNTIME = YES;
668668
GENERATE_INFOPLIST_FILE = NO;
669669
INFOPLIST_FILE = Resources/Info.plist;
@@ -701,7 +701,7 @@
701701
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
702702
CODE_SIGN_ENTITLEMENTS = ClarissaWidgets/ClarissaWidgets.entitlements;
703703
CODE_SIGN_STYLE = Automatic;
704-
CURRENT_PROJECT_VERSION = 2;
704+
CURRENT_PROJECT_VERSION = 15;
705705
DEVELOPMENT_TEAM = SDRCMNG666;
706706
GENERATE_INFOPLIST_FILE = YES;
707707
INFOPLIST_FILE = ClarissaWidgets/Info.plist;
@@ -731,7 +731,7 @@
731731
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
732732
CODE_SIGN_ENTITLEMENTS = ClarissaWidgets/ClarissaWidgets.entitlements;
733733
CODE_SIGN_STYLE = Automatic;
734-
CURRENT_PROJECT_VERSION = 2;
734+
CURRENT_PROJECT_VERSION = 15;
735735
DEVELOPMENT_TEAM = SDRCMNG666;
736736
GENERATE_INFOPLIST_FILE = YES;
737737
INFOPLIST_FILE = ClarissaWidgets/Info.plist;
@@ -760,7 +760,7 @@
760760
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
761761
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
762762
CODE_SIGN_STYLE = Automatic;
763-
CURRENT_PROJECT_VERSION = 2;
763+
CURRENT_PROJECT_VERSION = 15;
764764
DEVELOPMENT_TEAM = SDRCMNG666;
765765
GENERATE_INFOPLIST_FILE = NO;
766766
INFOPLIST_FILE = ClarissaWatch/Resources/Info.plist;
@@ -790,7 +790,7 @@
790790
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
791791
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
792792
CODE_SIGN_STYLE = Automatic;
793-
CURRENT_PROJECT_VERSION = 2;
793+
CURRENT_PROJECT_VERSION = 15;
794794
DEVELOPMENT_TEAM = SDRCMNG666;
795795
GENERATE_INFOPLIST_FILE = NO;
796796
INFOPLIST_FILE = ClarissaWatch/Resources/Info.plist;

apple/Clarissa/ClarissaWatch/Sources/Views/WatchContentView.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ struct WatchContentView: View {
169169
}
170170
.buttonStyle(.plain)
171171
.disabled(isProcessing)
172+
.accessibilityLabel("Ask Clarissa")
173+
.accessibilityHint("Opens voice input to ask a question")
172174
}
173175
.padding(.bottom, 8)
174176
}
Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,7 @@
11
{
22
"sourceLanguage" : "en",
33
"strings" : {
4-
"About Clarissa" : {
5-
"comment" : "A menu item that shows information about Clarissa.",
6-
"isCommentAutoGenerated" : true
7-
},
8-
"Clarissa Documentation" : {
9-
"comment" : "A link text that directs to Clarissa's documentation.",
10-
"isCommentAutoGenerated" : true
11-
},
12-
"Clear Conversation" : {
13-
"comment" : "A button to clear the main chat view when pressed.",
14-
"isCommentAutoGenerated" : true
15-
},
16-
"New Conversation" : {
17-
"comment" : "The label of a menu item that starts a new conversation.",
18-
"isCommentAutoGenerated" : true
19-
},
20-
"Read Last Response" : {
21-
"comment" : "A button that reads the last response aloud.",
22-
"isCommentAutoGenerated" : true
23-
},
24-
"Start Voice Input" : {
25-
"comment" : "A button that starts voice input.",
26-
"isCommentAutoGenerated" : true
27-
},
28-
"Stop Speaking" : {
29-
"comment" : "A button to stop speaking the last response.",
30-
"isCommentAutoGenerated" : true
31-
},
32-
"Toggle Sidebar" : {
33-
"comment" : "A menu item that toggles the visibility of the sidebar in macOS.",
34-
"isCommentAutoGenerated" : true
35-
},
36-
"Voice" : {
37-
"comment" : "The title of a menu section related to voice input and output.",
38-
"isCommentAutoGenerated" : true
39-
}
4+
405
},
41-
"version" : "1.1"
6+
"version" : "1.0"
427
}

apple/Clarissa/Resources/PrivacyInfo.xcprivacy

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,47 @@
2222
</dict>
2323
</array>
2424
<key>NSPrivacyCollectedDataTypes</key>
25-
<array/>
25+
<array>
26+
<!-- Precise Location - used for weather feature, not linked to identity -->
27+
<dict>
28+
<key>NSPrivacyCollectedDataType</key>
29+
<string>NSPrivacyCollectedDataTypePreciseLocation</string>
30+
<key>NSPrivacyCollectedDataTypeLinked</key>
31+
<false/>
32+
<key>NSPrivacyCollectedDataTypeTracking</key>
33+
<false/>
34+
<key>NSPrivacyCollectedDataTypePurposes</key>
35+
<array>
36+
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
37+
</array>
38+
</dict>
39+
<!-- Audio Data - used for voice input, processed on-device -->
40+
<dict>
41+
<key>NSPrivacyCollectedDataType</key>
42+
<string>NSPrivacyCollectedDataTypeAudioData</string>
43+
<key>NSPrivacyCollectedDataTypeLinked</key>
44+
<false/>
45+
<key>NSPrivacyCollectedDataTypeTracking</key>
46+
<false/>
47+
<key>NSPrivacyCollectedDataTypePurposes</key>
48+
<array>
49+
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
50+
</array>
51+
</dict>
52+
<!-- Contacts - used for contact lookup tool, not linked to identity -->
53+
<dict>
54+
<key>NSPrivacyCollectedDataType</key>
55+
<string>NSPrivacyCollectedDataTypeContacts</string>
56+
<key>NSPrivacyCollectedDataTypeLinked</key>
57+
<false/>
58+
<key>NSPrivacyCollectedDataTypeTracking</key>
59+
<false/>
60+
<key>NSPrivacyCollectedDataTypePurposes</key>
61+
<array>
62+
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
63+
</array>
64+
</dict>
65+
</array>
2666
<key>NSPrivacyTrackingDomains</key>
2767
<array/>
2868
<key>NSPrivacyTracking</key>

apple/Clarissa/Sources/Constants.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ public enum ClarissaConstants {
8989

9090
/// Maximum session count to display (shows "99+" for higher)
9191
public static let maxDisplayedSessionCount = 99
92+
93+
// MARK: - Accessibility
94+
95+
/// Minimum touch target size for accessibility (44pt per Apple HIG)
96+
public static let minimumTouchTargetSize: CGFloat = 44
97+
98+
/// Minimum contrast ratio for text (WCAG AA standard)
99+
public static let minimumContrastRatio: Double = 4.5
92100
}
93101

94102
// MARK: - macOS Menu Command Notifications

apple/Clarissa/Sources/Persistence/MemoryManager.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ import os.log
33

44
private let logger = Logger(subsystem: "dev.rye.Clarissa", category: "MemoryManager")
55

6+
/// Sync status for iCloud memory synchronization
7+
public enum MemorySyncStatus: Sendable {
8+
case idle
9+
case syncing
10+
case synced
11+
case error(String)
12+
}
13+
614
/// Manages long-term memories for the agent
715
/// Syncs across devices via iCloud Key-Value Storage (NSUbiquitousKeyValueStore)
816
/// On macOS, also syncs with CLI at ~/.clarissa/memories.json for cross-app memory sharing
@@ -13,6 +21,9 @@ public actor MemoryManager {
1321
private var memories: [Memory] = []
1422
private var isLoaded = false
1523

24+
/// Current sync status for UI display
25+
private(set) var syncStatus: MemorySyncStatus = .idle
26+
1627
/// Keychain storage (injectable for testing)
1728
private let keychain: KeychainStorage
1829

@@ -206,6 +217,11 @@ public actor MemoryManager {
206217
return memories
207218
}
208219

220+
/// Get the current sync status
221+
public func getSyncStatus() -> MemorySyncStatus {
222+
return syncStatus
223+
}
224+
209225
/// Get memories formatted for the system prompt
210226
/// Includes topic tags when available for better context
211227
/// Optimized for token efficiency while maintaining clarity
@@ -395,12 +411,15 @@ public actor MemoryManager {
395411
}
396412

397413
private func save() async {
414+
syncStatus = .syncing
415+
398416
do {
399417
let encoder = JSONEncoder()
400418
let data = try encoder.encode(memories)
401419

402420
guard let jsonString = String(data: data, encoding: .utf8) else {
403421
logger.error("Failed to encode memories to string")
422+
syncStatus = .error("Failed to encode memories")
404423
return
405424
}
406425

@@ -417,8 +436,11 @@ public actor MemoryManager {
417436
#if os(macOS)
418437
await saveToSharedCLIFile()
419438
#endif
439+
440+
syncStatus = .synced
420441
} catch {
421442
logger.error("Failed to save memories to Keychain: \(error.localizedDescription)")
443+
syncStatus = .error(error.localizedDescription)
422444
}
423445
}
424446

apple/Clarissa/Sources/UI/ChatViewModel.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import Foundation
22
import SwiftUI
33
import Combine
4+
#if canImport(WidgetKit)
5+
import WidgetKit
6+
#endif
47
#if canImport(UIKit)
58
import UIKit
69
#elseif canImport(AppKit)
@@ -527,10 +530,13 @@ final class ChatViewModel: ObservableObject, AgentCallbacks {
527530
/// Load the current session from persistence
528531
private func loadCurrentSession() async {
529532
// In screenshot mode, load demo data instead of real session
533+
// Only available in DEBUG builds for App Store screenshots
534+
#if DEBUG
530535
if DemoData.isScreenshotMode {
531536
loadDemoData()
532537
return
533538
}
539+
#endif
534540

535541
let session = await SessionManager.shared.getCurrentSession()
536542
let savedMessages = session.messages
@@ -555,9 +561,16 @@ final class ChatViewModel: ObservableObject, AgentCallbacks {
555561
// Load into agent
556562
agent.loadMessages(savedMessages)
557563
updateContextStats()
564+
565+
// Refresh widgets with current session data
566+
#if canImport(WidgetKit)
567+
WidgetCenter.shared.reloadAllTimelines()
568+
#endif
558569
}
559570

560571
/// Load demo data for screenshot mode based on current scenario
572+
/// Only available in DEBUG builds for App Store screenshots
573+
#if DEBUG
561574
private func loadDemoData() {
562575
let scenario = DemoData.currentScenario
563576
switch scenario {
@@ -575,6 +588,7 @@ final class ChatViewModel: ObservableObject, AgentCallbacks {
575588
messages = []
576589
}
577590
}
591+
#endif
578592

579593
/// Save the current session
580594
private func saveCurrentSession() async {
@@ -648,6 +662,11 @@ final class ChatViewModel: ObservableObject, AgentCallbacks {
648662
// Load into agent for context
649663
agent.loadMessages(session.messages)
650664
updateContextStats()
665+
666+
// Refresh widgets after session switch
667+
#if canImport(WidgetKit)
668+
WidgetCenter.shared.reloadAllTimelines()
669+
#endif
651670
}
652671

653672
/// Get all sessions for history display

0 commit comments

Comments
 (0)