| 2026-09-22 |
Длинная заметка проекта сворачивается: начало + «Развернуть»
...
Высота блока заметки (или README от ссылки) мерится по факту рендера
(ResizeObserver — картинки догружаются и растут): выше ~420px —
сворачивается, под ней подсказка «Заметка большая — показано начало»
и кнопка «Развернуть»/«Свернуть». Локали ×3, ТЗ 3.8/0.41.
Проверено headless: длинный README свёрнут (420px, подсказка на
месте), «Развернуть» раскрывает до полных ~4700px.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
9 hours ago
|
README вместо заметки-ссылки на проекте — как в описании задачи
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
9 hours ago
|
Рафф по старым миграциям: сортировка импортов, EOL, перенос строки
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
9 hours ago
|
README.md вместо описания-ссылки на репозиторий
...
Если описание задачи — одна ссылка на git-репозиторий, на странице
задачи вместо неё показывается README.md оттуда (с подписью-ссылкой
на источник; сырое описание в БД не меняется, чекбоксы README не
патчат описание).
Хост не обязан быть GitHub/GitLab (ТЗ 3.3, 0.41): селф-хостед системы
ищутся эвристикой — API github/gitlab/gitea + raw-пути web-интерфейсов
с дефолтной веткой HEAD (проверено на селф-хостед GitBucket);
не нашли — 404, остаётся ссылка. Кэш прочтений в памяти, 10 минут.
- backend: services/readme.py (эвристика + перебор, кэш),
GET /api/repo-readme?url=, тесты (кандидаты, кэш) — 159 тестов
- frontend: api.getRepoReadme, TaskView показывает README вместо
описания при одиночной ссылке; локали task.readmeFrom ×3
Проверено headless на живом фронте: git.gnexus.space (GitBucket) и
github.com — README рендерится, при неудаче остаётся ссылка.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
9 hours ago
|
Лоадеры и скелетоны: спиннер обновления в шапках, скелетоны под макет страниц
...
- Спиннер обновления (GnLoader circle, .refresh-loader fixed под топбаром) в
#actions шапок списков: задачи, стек, проекты, архив, проект, задача, опции
- Скелетоны заменены с рамочного .skeleton-stack на макет-мимикрирующие
карточки кита: списки — сетка карточек с бейджами, задача — сетка main/сайд,
статы — метрики, сад — блок + строки
- kit-overrides.css: только теговые бейджи/чипы без uppercase, позиция спиннера
- Локаль common.loading (ru/en/uk)
Проверено headless на живом фронте: скелетоны на первом входе (list 4 карточки,
task 5 карточек/12 линий, stats 3 метрики, garden блок+2 линии, projects 3,
archive 2, stack 3+6 бейджей), спиннер появляется при обновлении данных.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
10 hours ago
|
Теги: подсказки существующих по набору в полях тегов
...
GnTagInput кита (v0.4.0) без автодополнения — тонкая обёртка TagField:
строка чипов-подсказок под полем, фильтр по набираемому тексту (он читается
из всплывающего input-события внутреннего поля кита). Клик по подсказке
добавляет тег и очищает ввод синтетическим input-событием.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
10 hours ago
|
Теги — без аперкейса кита (бейджи тегов и чипы ввода тегов)
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
10 hours ago
|
Список задач: завершённые сортируются по дате закрытия, а не добавления
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
10 hours ago
|
Статус-блок: «Завершено» у задачи в работе, «Не хочется делать» — только до начала
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
10 hours ago
|
Предложение ИИ: кнопки «Не то» вместо «Я сам», все действия — мелкие
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
11 hours ago
|
Двуязычный промпт детализации: язык задачи → язык промпта
...
Маленькие модели мимикрируют под язык промпта, а правило «отвечай по-русски»
внутри английского промпта игнорируют: qwen3.5:2b отвечал английским на русские
задачи. Промпт теперь строится на языке исходника (_is_cyrillic → _prompt_ru /
_prompt_en), few-shot пример тоже на языке задачи.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
11 hours ago
|
ИИ-детализация: только оформление (заголовок/описание/теги EN), суммаризация проектов (ТЗ 0.40)
...
- Убрано ИИ-планирование с 0% попадания: LLM больше не предлагает
проект, приоритет и оценку времени — их заполняет пользователь
- Заполненные пользователем поля не угадываются при первичном анализе;
«Переспросить ИИ» (force) — полный анализ
- Ответ LLM — на языке исходного текста; новые теги — только английские
- Улучшено сжатие заголовка: лаконичное название + описание с шагами
- Суммаризация заметок проектов (projects.summary, миграция
a9b8c7d6e5f4): контекст LLM вместо полных заметок; перегенерация
при правке заметки
- Фикс \u-эскейпов в JSON-колонках (ensure_ascii=False): MCP-агенты
видят кириллицу, а не «u0432»
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
12 hours ago
|
Список задач: карточки двухколоночного grid не выходят за контейнер
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
12 hours ago
|
Массовое добавление задач: форма не закрывается, проект из контекста (ТЗ 0.39)
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
12 hours ago
|
Экран входа в стиле navi: подпись под лого, кнопка «Войти через GNEXUS»
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
13 hours ago
|
Вход с первой попытки: залогиненный с /login сразу уходит на return_to
...
Возврат с SSO попадал обратно на экран входа и требовал второй клик —
теперь /auth/me на /login подтверждает сессию и ведёт на return_to;
return_to не заворачивается сам в себя.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
13 hours ago
|
Экран входа /login: одна кнопка «Войти», редирект неавторизованных (ТЗ 0.38, 3.17)
...
- /login вне навигационной оболочки: логотип + кнопка, инициация SSO-флоу
с return_to (по образцу navi.gnexus.space)
- /auth/me 401 → редирект на /login с исходным адресом; /auth/logout
после очистки сессии ведёт на /login вместо JSON {"ok": true}
- api.ts/realtime.ts при 401 ведут на SPA-роут /login, а не на SSO-флоу —
иначе страница входа мгновенно уводила на авторизацию
- оффлайн (сетевая ошибка /auth/me) не считается «не залогинен» — ТЗ 3.15
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
13 hours ago
|
MdEditor: textarea на всю ширину контейнера
...
GnTextarea без ширины сжимался до ~20 символов, а .form-group кита
упёрт в max-width: 600px — перебито внутри компонента.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
13 hours ago
|
Сад: компактный старт 24×12, два расширения (ТЗ 0.37)
...
- старт 24×12 (было 32×20): дворик заполняется быстро, расширение
ощущается событием
- расширение I (ур. 3, 100) возвращает прежний старт 32×20; II (ур. 12,
250) — до 40×28; расширения III–V убраны
- предметы существующих садов, оказавшиеся за новой границей,
переставляются по спирали к дому при первом заходе (идемпотентно)
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
14 hours ago
|
Тосты: непрозрачный фон вместо rgba-тинки кита
...
Вариантные тосты кита красятся rgba(...,.18) — сквозь них просвечивает
страница. Перебито китовым базовым #1f2335 (селектор 0,2,0), цвет варианта
остаётся в рамке и иконке.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
14 hours ago
|
| 2026-09-21 |
Имя и аватар из SSO: users.name, синк по webhook и при логине (ТЗ 0.36)
...
- users.name (display_name из SSO), миграция f1a2b3c4d5e6
- webhook user.profile_updated: name ← profile.display_name (ключа нет —
не трогаем), avatar_url, locale; username_changed имя не меняет
- /auth/callback: name в сессию и БД (display_name, fallback username)
- /auth/me: профиль из БД, не из cookie-сессии — изменения от webhook
видны сразу, без повторного логина
- фронт: имя в сайдбаре (identity-title), email в meta
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Подготовка к деплою: GAUTH_WEBHOOK_SECRET в compose, чистка MCP_TOKEN
...
- docker-compose: проброс GAUTH_WEBHOOK_SECRET в api (без него webhook
молча 503 на проде); удалён устаревший MCP_TOKEN (ТЗ 0.34)
- .env.example/README: комментарий про per-user токены вместо env
- тест webhook_disabled: секрет пуст явно — Settings теперь читает
backend/.env с реальным секретом
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Фильтры проекта на моб — ширина 10rem (просьба пользователя)
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
«Новая задача» на моб — GnIconButton кита вместо ручного квадрата
...
Штатный компонент кита (.btn-icon 38×38, иконка 22px) вместо самодельного
сжатия .btn с перебивкой border-left; переключение display по брейкпоинту.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Мобильные UI-фиксы: переполнения дашборда/проекта, кнопки-иконки (360px)
...
- Dashboard/ProjectView: grid-треки minmax(0,1fr) вместо 1fr — min-content
nowrap-текста растягивал колонку и ломал страницу на телефоне
- Dashboard: заголовки задач на моб переносятся вместо ellipsis
- «Новая задача» в топбаре и шапке проекта — квадратная кнопка 42×42 на моб;
перебито правило кита .btn.btn-small.with-icon (border-left 32px)
- SettingsView: .token-create — кнопка «Сгенерировать» не уплывает за экран,
на моб поля в столбик
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Вебхуки от gnexus-auth: профиль, статус, отзыв MCP-токенов (ТЗ 0.35, 3.16)
...
- POST /auth/webhook: HMAC-SHA256 через gnexus_gauth (verify_and_parse_webhook),
секрет GAUTH_WEBHOOK_SECRET; не задан — 503 (приём выключен)
- user.email_changed / user.profile_updated — синхронизация User (email,
locale, avatar_url) без повторного логина
- user.blocked / user.archived / user.deleted — отзыв всех MCP-токенов
пользователя (агент теряет доступ вместе с аккаунтом); cookie-сессии
stateless — закрываются на стороне SSO (документировано)
- незнакомые типы (включая webhook.test) — 200 без действий, против retry-шторма
- тесты: подпись, 503 без секрета, битый payload, отзыв токенов, sync профиля
(9 новых; всего 145 passed)
- ТЗ 0.35 (3.16), deploy.md: GAUTH_WEBHOOK_SECRET + настройка webhook (п. 3.1)
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Мультиюзерность: фронтенд и ТЗ (ТЗ 0.34, батч 3)
...
- userScope.ts: localStorage-ключи скоупятся по user_id (второй аккаунт
в том же браузере не видит чужих фильтров/дедупа тостов)
- realtime.ts (дедуп own-activity) и ProjectView.vue (фильтры проекта) —
через scopedKey
- App.vue: setStorageUserId из /auth/me
- SettingsView: раздел «Токены MCP» — генерация (plaintext один раз,
с копированием), список, отзыв; api.ts: типы + listMcpTokens/
createMcpToken/deleteMcpToken
- McpView: текст «токен в Настройках» (connectTokenText) в ru/en/uk
- Локали: ключи mcpToken* в ru/en/uk (в ru/en/uk попали литералы
ru_new/en_new/uk_new вместо блоков — исправлено)
- docs/TZ.md → 0.34: 1.2 (мультиюзерность + claim-on-first-login),
3.10 (per-user токены, MCP_TOKEN удалён), 5 (User, McpToken,
AppSetting/AppSettingGlobal)
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|

Мультиюзерность: изоляция данных, per-user MCP-токены, claim при первом логине (ТЗ 0.34, бэкенд)
...
- Модели: User (профиль из SSO), McpToken (только sha256-хэш),
user_id на tasks/projects/tags/documents/xp_events/coin_events/garden_items;
уникальности имени проекта/тега — составные (per-user); app_settings →
per-user (PK user_id+key), старая таблица → app_settings_global (источник claim)
- Миграция f9a0b1c2d3e4 (Postgres): новые таблицы, user_id на 7 таблиц,
составные уникальности, частичные индексы дейли/уровня per-user
- Claim-on-first-login (ТЗ 1.2): первый вошедший забирает строки с user_id NULL
и копирует глобальные настройки; upsert профиля в callback
- Scoping всех API и сервисов: tasks/projects/tags/attachments/settings/xp/
garden + xp/garden/closing/options/recurrence/detailing; чужое — 404
- MCP (ТЗ 3.10): per-user bearer-токены вместо env MCP_TOKEN (middleware →
sha256 → request.state.gntodo_user_id), 8 тулов с Context; SSE publish(uid)
- API /api/mcp-tokens: список/генерация (plaintext один раз)/отзыв
- Тесты: test_multiuser (изоляция двух пользователей, claim, per-user дейли/
настройки), test_mcp_tokens; 135 passed, ruff, mypy strict
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
docs/deploy.md — пошаговый деплой на VPS для агента
...
Предпосылки → .env (таблица переменных, генерация секретов) → SSO callback
(ручной шаг — остановиться и спросить пользователя) → compose up → внешний
TLS-прокси (пример nginx, критичность Host для /mcp) → чеклист проверки с
ожидаемыми ответами → MCP для агентов → обновление/бэкапы/диагностика.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|

Docker-деплой готов к проде (ТЗ 0.33, M7)
...
- nginx: client_max_body_size 20m (вложения до 10 МБ падали бы с 413),
HTTP/1.1-апстрим с keepalive и без буферизации для /api/ и /mcp/ (SSE),
кэш хэшированной статики на год, gzip
- compose: убраны контейнеры ollama/ollama-init (Ollama — внешний сервер,
OLLAMA_BASE_URL из .env); restart для db; healthcheck api через
/api/health (start_period 30s на миграции); модель по умолчанию
согласована с конфигом (qwen3.5:2b-q4_K_M, открытый вопрос ТЗ 8.5 закрыт)
- mcp_server: FastMCP пропускал только Host localhost — в проде за nginx
/mcp отвечал 421; разрешённый Host берётся из GAUTH_REDIRECT_URI
(dev-поведение не изменилось, защита от DNS-rebinding сохранена)
- README: раздел «Деплой» — шаги, внешний TLS-прокси, лимит тела,
буферизация SSE, почему 1 воркер uvicorn
- ТЗ 0.33: TLS — внешний reverse-proxy; Ollama — внешний сервер
Проверено локально полным стеком (db+api+web на :8135): сборка образов,
SPA/health/SSO-редирект/413/gzip/MCP-флоу (initialize → tools/call),
MCP с чужим Host — 421. 117 backend-тестов, mypy, ruff — чисто.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|