Files
obsidian-vault/personal/projects/nolvu-reflect-skip.md
T

7.6 KiB
Raw Blame History

title, aliases, tags, created, updated, related
title aliases tags created updated related
naisei / reflect-skip — проект
naisei
nolvu
reflect-skip
Naisei проект
Reflect Skip
personal
project
app
psychology
skip-tools
2026-05-17 2026-06-04
personal/projects/psychologist-app/overview
personal/projects/psychologist-app/dev-setup

naisei / reflect-skip — проект

Статус

  • Имя продукта: naisei
  • Активная кодовая база: ~/Developer/reflect-skip/
  • Android: публикуется на https://reflect.qentra.top (F-Droid, сервер локально на Mac через CF tunnel → localhost:8766, не VPS)
  • iOS: собирается через Project.xcworkspaceDarwin/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-proxylocalhost:8765
  • Cloudflare tunnel: ai.qentra.toplocalhost: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 closegenerateClose(), applyOps(), ProfileManager DI; X-кнопка вызывает endSession()
  • Completion routing + insightsreadyToClose в ProcessingResult, insights.md, agentic insight
  • One-card UXisActive, appendCard, growing TextEditor, history view
  • Schedule intent detection — Narrator [SCHEDULE:] тег → ProcessingResult.scheduleIntent
  • Mood delta → Orb visual feedbackMoodDelta enum, AnalystJSON, OrbState.moodDeclining/moodImproving
  • Warm track — реальные даты сессий из file attributes, lastSessionText, daysSinceLastSession → Analyst context
  • LLM safety classifier + off-topic routingSafetyClassifier Layer 2, параллельный crisis detection, redirect card
  • Android voice bridgeSpeechRecognizer bridge via AndroidBridge, 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/.

Связанные заметки