Skip to content

Commit b52fd52

Browse files
committed
chore: project cleanup; prepare for v2
1 parent 2a6bcaf commit b52fd52

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+5855
-1459
lines changed

CLAUDE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
* Always use Context7 MCP when I need library/API documentation, code generation, setup or configuration steps without me having to explicitly ask.
2+
3+
* Always use the `mcp__auggie-mcp__codebase-retrieval` tool for searching codebases using natural language queries without me having to explicitly ask.
14

25
Default to using Bun instead of Node.js.
36

ROADMAP.md

Lines changed: 218 additions & 133 deletions
Large diffs are not rendered by default.

apple/CHANGELOG.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,85 @@ All notable changes to the Clarissa Apple application will be documented in this
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [2.0.0] - 2026-02-06
9+
10+
### Added
11+
12+
#### Smarter Context & Memory
13+
14+
- **Token-budget session trimming** - Replaced hard 100-message limit with token-budget-based trimming that keeps messages until the budget is exceeded, then trims oldest non-system messages
15+
- **Error recovery UX** - Automatic summarization and retry when context window is exceeded, with a "conversation summarized" banner
16+
- **Manual summarize** - "Summarize conversation" button in the context indicator for proactive context management
17+
- **Memory intelligence** - Memories now have category (facts, preferences, routines, relationships), temporal type (permanent, recurring, one-time), confidence scores with decay/boost, and relationship links between related memories
18+
- **Multi-factor relevance ranking** - Memory retrieval weighted by topic (40%), confidence (30%), recency (20%), and category (10%)
19+
- **iCloud conflict resolution** - Timestamp-based merge with `modifiedAt` and `deviceId` fields instead of last-write-wins
20+
- **System prompt budget** - 6-priority budget enforcement (core instructions → summary → memories → proactive context → template → disabled tools) with per-section token caps
21+
22+
#### Conversation UX
23+
24+
- **Edit & Resend** - Long-press any user message to edit and resend from that point
25+
- **Regenerate** - Long-press any assistant message to regenerate the response
26+
- **Undo support** - One-level undo with ephemeral snapshot and banner after edit/regenerate
27+
- **Conversation templates** - 4 bundled templates (Morning Briefing, Meeting Prep, Research Mode, Quick Math) with specialized system prompts, tool sets, and response token hints
28+
- **Custom templates** - Create, edit, and manage your own conversation templates
29+
- **Template picker** - Empty-state grid in chat for quick template selection
30+
- **Conversation search** - Search and filter conversation history by date and topic
31+
- **Proactive intelligence** - Regex-based detection of weather, calendar, and schedule intents with parallel tool prefetch (2s timeout, FM-only, opt-in toggle)
32+
33+
#### Richer Tool Results
34+
35+
- **Expandable weather cards** - Tap to expand hourly/daily forecast with Swift Charts visualization
36+
- **Calendar deep links** - Tap events to open in Calendar.app, tap locations to open in Maps
37+
- **Contact actions** - Tap to call, message, or email directly from contact result cards
38+
- **Web preview cards** - Thumbnail preview with "Open in Browser" button
39+
- **Calculator history** - Copy results to clipboard with confirmation
40+
41+
#### Export & Sharing
42+
43+
- **PDF export** - Export conversations as styled PDF via WKWebView
44+
- **Share as image** - Share individual assistant responses as images (3x ImageRenderer)
45+
- **Code block copy** - Copy code blocks with syntax highlighting from MarkdownContentView
46+
47+
#### Agent Visibility
48+
49+
- **Agent plan preview** - Real-time tool execution plan inferred from tool calls as they happen
50+
- **Live Activity progress** - Dynamic Island shows step-by-step plan progress during multi-tool execution
51+
- **Tool plan view** - Step-by-step progress displayed inline in the chat UI
52+
53+
#### Platform Integration
54+
55+
- **Siri template shortcuts** - Start any bundled template via Siri ("Morning Briefing with Clarissa", etc.)
56+
- **Siri follow-up questions** - 5-minute conversation sessions for back-and-forth with Siri
57+
- **Watch template quick actions** - Morning Briefing and Meeting Prep as watch quick actions
58+
- **Watch template relay** - `templateId` in QueryRequest for Watch→iPhone template passing
59+
- **Share Extension** - Process shared text, URLs, and images via App Group storage
60+
- **Provider fallback banner** - Suggests OpenRouter when Foundation Models fails, with auto-dismiss
61+
62+
#### AI Capabilities
63+
64+
- **SpeechAnalyzer upgrade** - Replaced legacy Speech framework with SpeechAnalyzer for faster, more accurate transcription (15 languages)
65+
- **Guided generation** - `@Generable` structs with `@Guide` annotations for structured output with guaranteed correctness
66+
- **Content tagging** - Topic detection, entity extraction, and emotion/action detection via content tagging adapter
67+
- **Enhanced image understanding** - Foundation Models vision (ViTDet-L encoder) for multimodal image + text reasoning
68+
- **Document OCR** - Full-document text recognition, PDF extraction, handwriting recognition via Vision framework
69+
- **Private Cloud Compute** - Seamless fallback to Apple's privacy-preserving server inference with consent toggle
70+
- **Streaming partial generation** - `PartiallyGenerated` types for progressive UI updates during structured output
71+
72+
### Changed
73+
74+
- **ChatViewModel refactored** - Split from 1164 lines into facade pattern (761 lines) composing ProviderCoordinator, SessionCoordinator, and VoiceController
75+
- **Shared types extracted** - ToolStatus, ThinkingStatus, ChatMessage, and ToolDisplayNames moved to ChatTypes.swift
76+
- **AgentCallbacks** simplified as thin adapter on ChatViewModel updating @Published state + Live Activity
77+
78+
### Technical
79+
80+
- 55+ new unit tests (ProviderCoordinator, SessionCoordinator, ToolDisplayNames, ChatMessage export, context trimming edge cases, Share Extension round-trip, SystemPromptBudget overflow, memory conflict resolution, watch template queries)
81+
- iCloud KVS payload monitoring (warnings at 50KB, errors at 60KB)
82+
- DeviceIdentifier helper (identifierForVendor on iOS, persisted UUID on macOS)
83+
- Token budget overflow logging for future calibration
84+
85+
---
86+
887
## [1.0.0] - 2025-12-12
988

1089
### Added

apple/Clarissa/ClarissaWatch/Sources/ClarissaWatchApp.swift

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,35 +53,44 @@ struct ResponseHistoryItem: Identifiable, Codable {
5353
enum QuickAction: String, CaseIterable, Identifiable {
5454
case weather = "Weather"
5555
case nextMeeting = "Next meeting"
56-
case setTimer = "Set a 5 minute timer"
57-
case reminders = "What are my reminders?"
56+
case morningBriefing = "Morning Briefing"
57+
case meetingPrep = "Meeting Prep"
5858

5959
var id: String { rawValue }
6060

6161
var icon: String {
6262
switch self {
6363
case .weather: return "cloud.sun.fill"
6464
case .nextMeeting: return "calendar"
65-
case .setTimer: return "timer"
66-
case .reminders: return "checklist"
65+
case .morningBriefing: return "sunrise"
66+
case .meetingPrep: return "person.2"
6767
}
6868
}
6969

7070
var query: String {
7171
switch self {
7272
case .weather: return "What's the weather like?"
7373
case .nextMeeting: return "When is my next meeting?"
74-
case .setTimer: return "Set a timer for 5 minutes"
75-
case .reminders: return "What are my reminders for today?"
74+
case .morningBriefing: return "Give me my morning briefing"
75+
case .meetingPrep: return "Help me prepare for my next meeting"
7676
}
7777
}
7878

7979
var shortLabel: String {
8080
switch self {
8181
case .weather: return "Weather"
8282
case .nextMeeting: return "Next Meeting"
83-
case .setTimer: return "5min Timer"
84-
case .reminders: return "Reminders"
83+
case .morningBriefing: return "Briefing"
84+
case .meetingPrep: return "Prep"
85+
}
86+
}
87+
88+
/// Template ID to apply on the iPhone side (nil for plain queries)
89+
var templateId: String? {
90+
switch self {
91+
case .morningBriefing: return "morning_briefing"
92+
case .meetingPrep: return "meeting_prep"
93+
case .weather, .nextMeeting: return nil
8594
}
8695
}
8796
}
@@ -215,14 +224,14 @@ final class WatchAppState: ObservableObject {
215224
}
216225

217226
/// Send a query to the iPhone
218-
func sendQuery(_ text: String) {
227+
func sendQuery(_ text: String, templateId: String? = nil) {
219228
guard !text.isEmpty else { return }
220229

221230
pendingQuery = text
222231
status = .sending
223232
HapticManager.querySent()
224233

225-
if let requestId = connectivity.sendQuery(text) {
234+
if let requestId = connectivity.sendQuery(text, templateId: templateId) {
226235
pendingRequestId = requestId
227236
status = .waiting
228237
} else {
@@ -232,9 +241,9 @@ final class WatchAppState: ObservableObject {
232241
}
233242
}
234243

235-
/// Send a quick action query
244+
/// Send a quick action query (with optional template)
236245
func sendQuickAction(_ action: QuickAction) {
237-
sendQuery(action.query)
246+
sendQuery(action.query, templateId: action.templateId)
238247
}
239248

240249
/// Clear any error state

apple/Clarissa/ClarissaWatch/Sources/WatchConnectivityClient.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,23 @@ final class WatchConnectivityClient: NSObject, ObservableObject {
3737
}
3838

3939
/// Send a query to the iPhone for processing
40-
/// - Parameter text: The user's query text
40+
/// - Parameters:
41+
/// - text: The user's query text
42+
/// - templateId: Optional template ID to apply on the iPhone side
4143
/// - Returns: The request ID for tracking
4244
@discardableResult
43-
func sendQuery(_ text: String) -> UUID? {
45+
func sendQuery(_ text: String, templateId: String? = nil) -> UUID? {
4446
guard let session = session else {
4547
lastError = "Watch connectivity not initialized"
4648
return nil
4749
}
48-
50+
4951
guard session.isReachable else {
5052
lastError = "iPhone not reachable"
5153
return nil
5254
}
53-
54-
let request = QueryRequest(text: text)
55+
56+
let request = QueryRequest(text: text, templateId: templateId)
5557
pendingRequest = request
5658

5759
do {

apple/Clarissa/ClarissaWatch/Sources/WatchMessage.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,14 @@ struct QueryRequest: Codable, Sendable {
2929
let id: UUID
3030
let text: String
3131
let timestamp: Date
32-
33-
init(text: String) {
32+
/// Optional template ID to apply before processing (nil = no template)
33+
let templateId: String?
34+
35+
init(text: String, templateId: String? = nil) {
3436
self.id = UUID()
3537
self.text = text
3638
self.timestamp = Date()
39+
self.templateId = templateId
3740
}
3841
}
3942

0 commit comments

Comments
 (0)