7.5 KiB
title, aliases, tags, created, updated, related
| title | aliases | tags | created | updated | related | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| naisei / reflect-skip — проект |
|
|
2026-05-17 | 2026-06-04 |
|
naisei / reflect-skip — проект
Статус
- Имя продукта: naisei
- Активная кодовая база:
~/Developer/reflect-skip/ - Android: публикуется на
https://reflect.qentra.top(F-Droid) - iOS: собирается через
Project.xcworkspace→Darwin/ReflectApp.xcodeproj - Текущая версия: v0.0.108 (ветка
feature/document-import;mainна v0.0.60, не слит)
Структура проекта
Два источника Swift-кода в reflect-skip
Sources/ReflectApp/— актуальный Skip-источник. Компилируется Darwin-проектом. Используется для iOS и Android.ReflectApp/— legacy iOS-only код, существовавший до перехода на Skip. КомпилируетсяReflectApp.xcodeprojв корне. Не используется в продакшне.
Как открывать iOS-проект
Всегда через Project.xcworkspace, не через ReflectApp.xcodeproj напрямую.
Как собирается Android
build-and-publish.sh → Skip компилирует Sources/ReflectApp/ → APK → F-Droid repo.
Прокси
- LaunchAgent:
ai.reflect-proxy→localhost:8765 - Cloudflare tunnel:
ai.qentra.top→localhost:8765 - Бэкенд:
claude-code(переключено сclaude-proxy) - Лог сессий:
~/Developer/reflect-skip/sessions.log
Агенты
- NarratorBot — нейтрализует ввод пользователя (убирает эмоциональную окраску, 3-е лицо); детектирует
[SCHEDULE:]тег для schedule intent - AnalystBot — задаёт 2-3 глубоких вопроса по профилю + контексту сессии; возвращает
AnalystJSONс полямиsessionComplete,moodDelta,suggestedInsight - SafetyClassifier — Layer 2, параллельный crisis detection; роутинг off-topic → redirect card
- SessionManager — управляет историей сессий, пейсингом (turn count, fatigue, hard limit 8 оборотов), closing-флоу
ProcessingResult (текущие кейсы)
enum ProcessingResult {
case questions([String], observation: String?)
case readyToClose([String]?, observation: String?)
case offTopic(String)
case scheduleIntent(String)
case crisis(CrisisDetectionResult)
case moodDeclining / moodImproving // через OrbState
case error(String)
}
Исправления (v0.0.92, 28 мая 2026) — Android vault validation
Веха: Android onboarding работает
✅ Алерт валидации vault отображается корректно
✅ Кнопки появились после выбора папки
✅ Дошли до экрана "Доброе утро"
Fix — @AppStorage вместо @State для UI-обновлений на Android
Проблема: @State var folderPickerError: String? и @State var vaultFound: Int? не триггерили Compose recompose в SkipFuse bridge.
Симптом: алерт не появлялся, кнопки не обновлялись, хотя логика SAF выполнялась.
Исправление: заменили на @AppStorage("_vaultErr") и @AppStorage("_vaultFound") — идут через SharedPreferences → всегда триггерят Compose recompose.
Файл: Sources/naisei/Views/OnboardingView.swift
Реализовано (v0.0.92 → v0.0.108)
- Session pacing + fatigue + recovery — turn counter, fatigue detection, session recovery флоу
- Structured session close —
generateClose(),applyOps(), ProfileManager DI; X-кнопка вызываетendSession() - Completion routing + insights —
readyToCloseв ProcessingResult,insights.md, agentic insight - One-card UX —
isActive,appendCard, growing TextEditor, history view - Schedule intent detection — Narrator
[SCHEDULE:]тег →ProcessingResult.scheduleIntent - Mood delta → Orb visual feedback —
MoodDeltaenum,AnalystJSON,OrbState.moodDeclining/moodImproving - Warm track — реальные даты сессий из file attributes,
lastSessionText,daysSinceLastSession→ Analyst context - LLM safety classifier + off-topic routing —
SafetyClassifierLayer 2, параллельный crisis detection, redirect card - Android voice bridge —
SpeechRecognizerbridge viaAndroidBridge, Kotlin companion вAndroidAppMain
Исправления (v0.0.25, май 2026)
Fix 1 — дублирование нарратора
buildSessionContext() вызывался после addMessage() → нарратор видел своё же сообщение в контексте.
Исправлено: поменяли порядок в Sources/SessionManager.swift.
Fix 2 — AnalystBot не видел текущий диалог
ProfileManager.loadRecentSessions(count: 3) загружал прошлые ФАЙЛЫ, не текущую сессию.
Исправлено: добавили buildCurrentSessionDialogue() (последние 8 пар user/analyst), передаём в analyze().
Fix 3 — нарратору уходили вопросы аналитика
sendBatchSummary() отправлял весь диалог включая вопросы аналитика.
Исправлено: фильтруем только user answers.
Obsidian-совместимость
Приложение читает сессии из папки observations/ (формат vault), а не sessions/.
- Папка сессий:
observations/в корне импортируемой директории - Именование файлов: ISO week —
2026-W20.md,2026-W21.md - Запись сессий: аппендит
## Сессия DD.MM.YYYY HH:mmв текущий недельный файл - Счётчик сессий: считается напрямую как количество
.mdфайлов вobservations/(не хранится в profile.md) - Профиль:
profile.md— строка**Имя:** Алексейнужна дляparseName() - Инсайты:
insights.md— произвольный формат, передаётся напрямую в Claude
Vault путь для импорта: personal/psychology/ (на Taiga).
Pitfalls
- Если на iOS-симуляторе не появляется
DevSetupView(ввод токена) — значитdev_setup_done = trueв UserDefaults. Удалить приложение с симулятора и запустить заново. ReflectApp/в корне — legacy, не трогать. Реальные правки только вSources/ReflectApp/.