21 Commits
Author SHA1 Message Date
rzen a7fc9ae336 Add changelog entries for project creation and sorting
Claude-Session: https://claude.ai/code/session_014esDWi42URLEC6Cj17hGQ3
2026-07-16 23:22:42 -04:00
rzen c5e8aea522 Projects tab: create via +, sort by activity/name/count
Declared-but-empty projects persist locally (UserDefaults) until a
note carries the name, at which point the project syncs via notes as
usual. Empty declared projects can be swipe-deleted.

Claude-Session: https://claude.ai/code/session_014esDWi42URLEC6Cj17hGQ3
2026-07-16 23:22:25 -04:00
rzen f877941c0d Move Projects tab ahead of Tags
Claude-Session: https://claude.ai/code/session_014esDWi42URLEC6Cj17hGQ3
2026-07-16 20:13:04 -04:00
rzen 80b18539f7 Add changelog entries for the Projects feature
Claude-Session: https://claude.ai/code/session_014esDWi42URLEC6Cj17hGQ3
2026-07-16 18:24:27 -04:00
rzen b2f16e8600 Add Projects: third tab, swipe-to-file, per-project note capture
Notes gain an optional project (schema v4, additive). Projects derive
from note values like tags — no separate entity. Tab naming
(Projects/Categories) is a Settings choice applied across the UI.

Claude-Session: https://claude.ai/code/session_014esDWi42URLEC6Cj17hGQ3
2026-07-16 18:24:11 -04:00
rzen a8085865bc Add changelog entries for list sorting and tap target fixes
Claude-Session: https://claude.ai/code/session_014esDWi42URLEC6Cj17hGQ3
2026-07-16 13:59:54 -04:00
rzen 14979d4a69 Float in-flight notes to top of list; make full row tappable
Claude-Session: https://claude.ai/code/session_014esDWi42URLEC6Cj17hGQ3
2026-07-16 13:59:22 -04:00
rzen 50adf522a8 Add calendar date badge to note list rows
Claude-Session: https://claude.ai/code/session_014esDWi42URLEC6Cj17hGQ3
2026-07-16 13:30:03 -04:00
rzen a21dd62f17 Refresh app icon artwork across iOS, macOS, and watchOS
Claude-Session: https://claude.ai/code/session_014esDWi42URLEC6Cj17hGQ3
2026-07-16 13:29:50 -04:00
rzen c5c90e9441 Decouple transcripts from note text; end-to-end watch transfer acks
Schema v3: transcription attempts accumulate on AudioInfo (text, locale,
confidence, forced flag) — latest attempt is displayed, payload.text is
purely user writing, v2 notes migrate at read time. Editor shows the
transcript in its own live-updating section with insert-into-note; search
matches transcripts weighted by confidence. Watch recordings are now
deleted only on the phone's durable-ingest ack (transferUserInfo), closing
every phone-side loss window; failed sidecar writes unstage instead of
orphaning, and unreadable inbox recordings are surfaced in logs.

Claude-Session: https://claude.ai/code/session_014esDWi42URLEC6Cj17hGQ3
2026-07-16 12:29:49 -04:00
rzen c29d25748a Fix silent watch recordings: async session activation, encoder settings, error surfacing
Watch recordings arrived on the phone as 28-byte header-only m4a files
(record() reported success but no audio was ever captured). Activate the
audio session via watchOS's async activate(options:), drop the .spokenAudio
mode experiment, match the phone recorder's proven AAC settings
(44.1 kHz / 48 kbps), and surface silent failures: an AVAudioRecorderDelegate
catches encode errors mid-take, and a stop-time guard detects a dead
header-only file, deletes it, and shows the failure on the watch instead of
shipping an unplayable note to the phone.

Claude-Session: https://claude.ai/code/session_014esDWi42URLEC6Cj17hGQ3
2026-07-15 19:42:24 -04:00
rzen 35e4d6750b Refactor capture UX: single New Note toolbar button, text-first editor
- NotesListView: remove two-button header; trailing New Note toolbar item (Cmd-N)
- NoteEditorView: text entry focused by default; extensible add-media bar
  (CaptureMedium enum, audio only for now) revealing the inline recorder;
  startRecording param removed
- Changelog entry updated
2026-07-15 18:39:11 -04:00
rzen 970eebaf3c Move search to a dedicated tab in the tab bar
Replace the Notes list's searchable accessory with a Tab(role: .search)
— the separated magnifier at the trailing edge of the iOS 26 tab bar —
backed by a new SearchView over text, tags, and capture location. The
Notes list drops its search state and always shows the context shelf
plus all notes.

Claude-Session: https://claude.ai/code/session_01GKfAiKiQKLDTmbiGva4FGE
2026-07-15 16:25:34 -04:00
rzen 798abf3b90 Watch: show version/build on screen, surface recording errors in UI
A tester on real hardware has no console, so a failed start looked like
a dead button and there was no way to tell which build the watch had
actually installed. Show the stamped version/build under the record
button, display the last start error in place of the hint text, and
fall back to the default audio session mode if .spokenAudio is rejected
with the .record category.

Claude-Session: https://claude.ai/code/session_01GKfAiKiQKLDTmbiGva4FGE
2026-07-15 16:07:32 -04:00
rzen 8bdda913a7 Add dictation-locale transcription (incl. Russian), rework list capture UI
- TranscriptionSettings/Service route per-locale to SpeechTranscriber or
  DictationTranscriber (union of both supported sets, speech preferred);
  neutral-confidence ranking fallback keeps mixed-engine auto-pick working
- NotesListView: text + voice capture buttons above the list (glassProminent),
  search moved to the iOS 26 toolbar search accessory (.minimize)
- Changelog entries for languages, capture buttons, search placement
2026-07-15 15:31:03 -04:00
rzen 3a9c36d843 Fix dead record button after mic permission denial
The watch app's permission-denied state was a computed property reading
AVAudioApplication.shared.recordPermission — external state Observation
cannot track — so after a denied prompt the UI never flipped to the
'Microphone access is off' screen and the record button silently did
nothing. Store the denied flag as a tracked property instead, updated
on every permission request.

Also: log (instead of swallow) recorder start failures, drop phantom
recordings when no file was written (the watch simulator has no audio
input device), sweep orphaned metadata sidecars on reconcile, and add a
DEBUG-only 'autorecord' launch argument for CLI-driven testing.

Claude-Session: https://claude.ai/code/session_01GKfAiKiQKLDTmbiGva4FGE
2026-07-15 14:58:57 -04:00
rzen 86d74806c9 Add voice notes: on-device transcription, multi-language, watch capture
- Schema v2: Note.AudioInfo, .m4a sidecar next to the note JSON in iCloud
- AudioRecorderService (iOS/macOS) + SpeechAnalyzer transcription pipeline
  with enabled-language set and confidence-based auto-pick, re-transcribe menu
- Settings > Transcription > Languages with asset download/reserve handling
- watchOS app + accessory complication: one-button recorder, WCSession
  transferFile to phone, WatchInbox staging, direct-upsert ingestion
- Player UI, transcription status chips, quick-capture mic in notes list
- Version 0.2, changelog + README updated
2026-07-15 13:30:43 -04:00
rzen 6a93cedaa6 Set PRODUCT_NAME to Contextful (fixes ITMS-90129 on macOS)
The Mac App Store requires a globally unique CFBundleName, which follows
PRODUCT_NAME — 'Notes' is taken (by Notes). The module name stays 'Notes'
via PRODUCT_MODULE_NAME so code and tests are untouched; TEST_HOST is
pinned explicitly since xcodegen derives it from the target name.
2026-07-14 21:21:24 -04:00
rzen c42e375044 Rename display name to Contextful on both platforms 2026-07-14 21:06:26 -04:00
rzen cf8616107b Add IndieAbout + IndieBackup, TestFlight release pipeline
IndieAbout: About section in iOS Settings and macOS About window; LICENSE
switched to the portfolio-standard ISC text (reflowed for in-app rendering).

IndieBackup: files-only backup/restore of the iCloud container documents
('.notesbackup' document type on both platforms), SwiftData cache rebuilt
via SyncEngine.rebuildCache() after restore, monitors suspended during the
file swap, onOpenURL import with pre-launch queueing.

Release pipeline: Scripts/release.sh (ios|mac|all) archives and uploads via
xcodebuild + ASC API key; platform-partitioned build numbers (iOS even,
macOS odd) since both targets share one bundle ID and build sequence.
2026-07-14 20:50:06 -04:00
rzen 9b231a1978 Initial scaffold: context-aware notes app for iOS + macOS
XcodeGen project (Notes / NotesMac / NotesTests), Swift 6 strict concurrency,
iCloud-document storage via IndieSync with a SwiftData cache, automatic
capture context (location, place, time zone, device) on every note,
context-based relevance ranking with a 'Right here, right now' shelf,
tags, search, and the square.and.pencil-on-red app icon.
2026-07-14 20:30:46 -04:00