Статус: H0–H5 реализованы, H6 проверен как локальный кандидат. В Rust-продукт добавлены единый реестр 11 программ, broker protocol v2, живые документы Write/Sheets, страницы Hub, общий каталог шаблонов и настоящий macOS status item. Developer ID/notarization, принятый login item, полный VoiceOver и человеческая приёмка остаются воротами распространяемого релиза.
Результат реализации
Слой
Текущее состояние
Проверка
Hub
Все 11 программ, текущие документы, точное «Продолжить», компактная навигация
12 Sheets + 3 Write, schema v1, независимые документы
Hub и Write interaction tests
macOS
NSStatusItem/NSMenu, текущие, недавние, программы, Hub, privacy, single instance
Физический Mac; точный focus Write/Sheets
Поставка
Ad-hoc подписанный локальный bundle
codesign/plutil PASS; Developer ID/notarization ещё нужны
Настоящий Hub: живые документы с приложением, dirty-состоянием и адресным продолжением.Настоящий NSStatusItem: одновременно открытые Write и Sheets, недавние и программы.
1. Два способа войти в одно пространство
Большое окно · MOffice Hub
Для осмысленного выбора: посмотреть все программы, найти нужный файл, сравнить шаблоны, восстановить работу. Открывается из Dock, Spotlight, меню приложения и быстрого меню.
Слева — постоянная навигация.
На главной — программы, текущие и недавние документы, шаблон для старта.
Поиск по названиям файлов, программ и шаблонов.
Системная команда «Открыть файл…» всегда доступна.
Маленькое окно · строка меню Mac
Для короткого действия: вернуться в окно, открыть недавний файл или выбрать программу. Один монохромный значок MOffice справа в строке меню.
Три вкладки: «Открыто», «Недавние», «Программы».
Текущие окна — первые, включая несохранённые документы.
Шаблоны и поиск ведут в соответствующий раздел Hub.
Закрытие Hub не завершает редакторы и помощник.
Слова, которые не должны путать
Раздел
Что в нём находится
Что делает клик
Сейчас открыто
Живые документы и окна текущего сеанса, в том числе «Без названия». Метка изменений приходит от редактора.
Активирует конкретное окно и вкладку. Повторное нажатие не создаёт дубликат.
Недавние
История успешных открытий и сохранений. Сканирование папки не считается открытием.
Если документ уже открыт — фокусирует его; иначе открывает в подходящей программе.
Закреплённые
Избранные записи истории. Это ссылки на оригиналы, не копии.
Тот же единый сценарий открытия. Очистка истории не снимает закрепления.
Шаблоны
Готовые исходники с предпросмотром, приложением, категорией и доступностью.
Создаёт новый несохранённый документ. Изменения не попадают в оригинал шаблона.
Весь пакет в каталоге
Write, Sheets, Slides, Draw, Paint, PDF, Math, Notes, Mail, Base и Forms — 11 карточек с коротким объяснением назначения. Доступность каждой карточки определяется реальной установленной программой. «Планируется», «Не установлено», «Недоступно в этой версии» — разные состояния. Нельзя обещать запуск программы, которой ещё нет.
В текущем макете доступны карточки всех программ. Интерактивные экраны редактора демонстрируют передачу управления, а не полные функции всех 11 редакторов. Полноценные экраны Mail, Base, Draw и других программ остаются в существующих спецификациях этих продуктов.
2. Исходная база, с которой началась работа
Ниже сохранён аудит состояния до реализации. Срез локального дерева: d54c1b2. Проверены исходники Hub, брокера, слой macOS и снимок существующей сборки на демонстрационных данных. Это точечный аудит функции, а не повторная проверка готовности всего пакета.
Область
Было проверено до реализации
Что требовалось добавить
Hub
ui/meridian-hub/src/app.rs: главная, недавние, закреплённые, шаблоны, настройки, восстановление; есть Launcher.
Новая композиция, каталог всех 11 программ, раздел текущих окон, связанные состояния.
Программы
recents.rs: AppKind содержит 10 значений; Math отсутствует. Binary задан для Write и Sheets.
Единый реестр возможностей, включая Math; одинаковая маршрутизация в Hub, меню и брокере.
Недавние
broker.rs объединяет историю брокера и файлы из обычных папок; брокер ограничивает историю 200 записями, Hub имеет константу 500.
Определить один лимит (предлагается 200 для MVP); историю и обзор папок разделить. Удаление, закрепление и очистка синхронизируются.
Текущие окна
meridian-broker/src/proto.rs: Documents передаёт пути; Activated отмечает активное окно. Сервер умеет направлять файл уже открытому окну.
Нет публичного WindowList/FocusDocument, document_id для несохранённых, dirty/title/window_id и событий для панели.
Шаблоны
Экран Hub использует встроенные шаблоны Sheets. В протоколе есть New с необязательным template.
Общий каталог, предпросмотр, версии схемы, проверка шаблона и создание копии; Write подключать отдельно.
macOS
ui/meridian-platform/src/macos.rs строит обычные меню приложения. В просмотренных Hub/platform исходниках не найден NSStatusItem или popover быстрого доступа.
Нативный status item, панель, жизненный цикл помощника, фокус окон и опциональный вход в систему.
Это историческая база для сравнения. Актуальный результат, проверки и оставшиеся внешние ворота приведены в разделе «Результат реализации» выше.
Для документа без пути используется document_id. Если окно закрыто между показом списка и кликом, список обновляется; сохранённый файл можно открыть повторно, несохранённый — только из найденной копии восстановления. Состояние «Сохранён» показывается после подтверждения редактора.
Создать из шаблона
Hub → «Шаблоны» → категория / программа → предпросмотр → название → новый документ
Каталог показывает локальные шаблоны без сети и аккаунта. До запуска проверяем наличие программы и совместимость шаблона. В MVP нет магазина шаблонов, фоновых загрузок и выполнения макросов.
Открыть недавний файл
Недавние → проверить файл → определить программу → активировать или запустить → обновить историю
При перемещении — «Указать новое место». При недостатке прав — объяснение и системный выбор файла. При ошибке запуска — повторить или отменить. История обновляется после успеха, а не после нажатия кнопки.
Закрыть и вернуться
Красная кнопка Hub закрывает только Hub. Быстрый помощник остаётся, если включён. Команда «Завершить быстрый доступ» убирает помощник без закрытия редакторов. Команды «Закрыть всё» в первом выпуске нет: это исключает массовое вмешательство в несохранённые документы. При закрытии отдельного документа редактор предлагает сохранить, не сохранять или отменить.
Настройки и первый запуск
Начальный экран объясняет назначение Hub. Быстрый доступ предлагается включить, автозапуск при входе в macOS по умолчанию выключен и настраивается отдельно. Пользователь может остановить запись истории и скрыть названия в меню на время демонстрации экрана. Учётная запись для локальных файлов не требуется. В веб-макете переключатели меняют только демонстрационное состояние.
4. Макеты всех экранов функции
Каждая ссылка открывает кликабельное состояние. Кнопка «Все экраны» в макете показывает ту же карту. После экспериментов нажмите «Сначала», чтобы вернуть исходные демонстрационные документы.
Главная: создание нового, текущие окна, недавние документы и быстрый переход к шаблонам.Быстрое меню поверх Hub: выбор текущего документа, история, программы и вход в общий центр.
5. План реализации по фазам
Фазы H0–H6 относятся только к общему пространству и macOS-помощнику. Они не заменяют основной roadmap пакета. Оценка для одного инженера, знакомого с собственным Rust UI и AppKit: 23–36 рабочих дней после согласования границ. Это ориентир активной работы, а не календарное обещание. Проверка подписания, системных разрешений и приёмка владельцем могут увеличить календарь. Разработка остальных девяти программ в оценку не входит.
РЕАЛИЗОВАНО · H0 · КОНТРАКТ И БАЗОВАЯ ЛИНИЯ
Зафиксировать состав и границы
Цель: один согласованный список приложений, окон, шаблонов и состояний.
Сверить текущую ветку и параллельные изменения Hub/Sheets; назначить владельцев затрагиваемых файлов.
Зафиксировать 11 приложений, состояния доступности, поддержку форматов и поведение New/Open/Activate.
Снять базовые сценарии, время запуска и память текущей сборки; утвердить карту экранов.
Зависимости / риск: расхождения веток, текущие ограничения собственного UI и политики зависимостей. API проектируется под существующий платформенный слой, без замены его Qt или Electron.
Приёмка: согласован контракт данных и ошибок; у каждого приложения есть достоверный статус; есть воспроизводимая исходная сборка. Единый registry, protocol v2 и воспроизводимая локальная сборка зафиксированы в коде и тестах.
РЕАЛИЗОВАНО · H1 · ОБЩИЕ ДАННЫЕ
Дать Hub и меню одну правду
Цель: один реестр приложений и живых документов.
Добавить AppRegistry с bundle/binary, типами файлов, командами, доступностью и локализацией; включить Math.
Расширить брокер снимком открытых документов и событиями регистрации, изменения, активации и закрытия.
Ввести session_id/window_id/document_id; хранить dirty, title, optional path, last_active, состояние окна.
Добавить FocusDocument с подтверждением и понятными ошибками. Обновить оба существующих редактора.
Определить единую семантику recent/pin/remove, миграцию профиля и резервную копию старого файла.
Зависимость: H0. Риск: разные версии клиентов, дубликаты при гонке запуска, исчезнувшие окна. Сначала согласовать протокол версии 2, совместимость или контролируемый перезапуск всех компонентов пакета.
Приёмка: два окна Write + одно Sheets + несохранённый документ видны корректно; фокус без дублей; аварийно завершённый процесс удаляется из текущих; событие Save As сохраняет идентичность документа.
РЕАЛИЗОВАНО · H2 · ОБЩЕЕ ОКНО
Обновить настоящий Hub
Цель: перенести утверждённую композицию в собственную оболочку.
Главная, каталог программ, текущие, недавние и закреплённые, общий поиск.
Поиск по метаданным; отдельные группы документов, программ и шаблонов; пустые результаты.
Открытие через брокер; понятные состояния loading/error/missing/access denied.
Системный выбор файла, восстановление пути, удаление записи без удаления файла.
Зависимость: H1. Риск: системные пути с Unicode, сетевые тома и файловые диалоги. UI не должен блокироваться на проверке существования файла.
Приёмка: программа выбирается за 2 действия; открытый документ — за 1 действие в списке; 200 недавних файлов фильтруются без зависаний; Hub корректно закрывается отдельно от редакторов.
Подключить существующие Sheets-шаблоны; добавить небольшой проверенный набор Write.
Предпросмотр, фильтры, название новой копии, создание через брокер.
Проверять повреждённый ресурс, несовместимость версии и отсутствие редактора до открытия.
Подготовить контракт для будущих Slides/Notes/Forms; не выставлять неподдерживаемое как готовое.
Зависимость: H1–H2 и возможность редактора создать новый документ из исходника. Риск: текущий параметр template может трактоваться как id или путь — унифицировать перед интеграцией.
Приёмка: минимум 3 Write + 3 Sheets шаблона создают независимые документы; хэш оригинала не меняется после редактирования копии; повреждённый шаблон даёт понятное сообщение.
Цель: доступ к программам и документам из любого приложения.
Реализовать NSStatusItem и нативное NSMenu через AppKit-адаптер без нового UI-фреймворка.
Показать 3 раздела с компактными строками, действия «Открыть…», «Шаблоны», «Hub».
Подписать помощник на данные брокера; без отдельной истории и постоянного опроса файлов.
Обработать активацию окна в другом Space, свёрнутое окно, несколько мониторов, полноэкранный режим.
Закрывать popover по Escape/вне панели; удерживать его в доступной области экрана, озвучивать элементы VoiceOver.
Повторный запуск пакета не создаёт второго значка. Завершение помощника не завершает документы.
Зависимость: H1, H2; переход к шаблонам — H3. Риск: фокус AppKit и политика активности отдельных процессов; веб-макет не доказывает эту часть.
Приёмка на реальном Mac: Hub закрыт, меню доступно; выбор документа активирует нужное окно/вкладку; 20 повторных активаций не создают копий; процессы помощника и брокера корректно восстанавливаются.
РЕАЛИЗОВАНО ЛОКАЛЬНО · H5 · ЖИЗНЕННЫЙ ЦИКЛ И ПРИВАТНОСТЬ
Предсказуемое поведение при запуске и выходе
Цель: быстрый доступ работает по явному выбору пользователя.
Настройки меню и автозапуска раздельные. На macOS 13+ использовать SMAppService; при более старом deployment target явно ограничить функцию или спроектировать отдельную поддержку.
Показать фактическое состояние системного разрешения, включая requiresApproval/disabled; не выдавать положение переключателя за успех.
История: остановка записи, очистка без удаления файлов, сохранение закреплений; приватный режим названий.
Первый запуск, сон/пробуждение, выход/вход в систему, обновление bundle и восстановление соединения.
Восстановление предлагает отдельную копию; содержимое несохранённых документов принадлежит редактору, не помощнику.
Зависимость: H4 и упакованный bundle. Риск: notarization, подпись и системные разрешения потребуют отдельного пользовательского действия, если его запросит macOS.
Приёмка: отключённый автозапуск не возвращается сам; удаление истории не удаляет данные; отозванное разрешение отображается честно; в приватном режиме меню не раскрывает названия и пути.
КАНДИДАТ · H6 · ПРИЁМКА И ПОСТАВКА
Проверить рабочий пакет целиком
Цель: проверенная сборка с инструкцией и возвратом к прошлой версии.
Контрактные тесты брокера и интеграционные проверки двух настоящих редакторов.
Ручные проверки macOS: Spaces, несколько мониторов, VoiceOver, масштаб, темы и клавиатура.
Падение редактора, гонки кликов, 200 записей истории, 30 текущих документов, потерянный и недоступный файл.
Проверить профиль после обновления и возврата, bundle/helper signatures, чистую установку и удаление.
Измерить холодный/тёплый запуск, задержку списка и память; зафиксировать машину и версию ОС.
Записать ограничения, инструкцию, доказательства и демонстрацию владельцу.
Зависимость: H1–H5. Риск: внешняя подпись и ручная приёмка не заменяются зелёными unit-тестами.
Выход: все обязательные сценарии ниже пройдены на целевом Mac; версия исходников и установленного приложения совпадают; есть подписанный артефакт (для распространения), журнал проверки и проверенный rollback. До этого — кандидат, не готовый релиз.
Рекомендуемый порядок поставки
Первая полезная поставка: H0–H2 — общий Hub с честными состояниями и живыми окнами. Полный запрос: H0–H6 — Hub + шаблоны + меню macOS + настройки + приёмка. Запуск остальных редакторов подключать по мере готовности, не задерживая общий интерфейс и не подменяя их макетами в production.
app_id, display_name, icon, supported_formats, bundle/binary, capabilities, available/reason. Источник один для Hub, меню и маршрутизации.
LiveDocument
session_id, window_id, document_id, app_id, title, path?, dirty, last_active, window_state. document_id не зависит от имени или Save As. Путь никогда не является единственным идентификатором.
RecentDocument
file identity / bookmark, display path, app_id, last_opened, pinned, availability. Не содержит текста документа. Лимит 200, закрепления и удаление по одному контракту.
Template
template_id, app_id, format/version, locale, category, preview, resource/hash. Редактор создаёт независимый документ без пути.
Брокер и события
В рабочем срезе реализованы DocumentList, FocusDocument, снимки документов и DocumentsChanged. Дальнейшее расширение: подтверждение активации/запуска и дополнительные структурированные ошибки. В запросе — correlation id и ожидаемая сессия; в ответе — результат, а не просто «процесс запущен». Порядок событий защищается ревизией snapshot; после переподключения клиент перечитывает снимок.
При завершении клиента его документы уходят из живого списка. Сохранённые пути остаются в истории, crash-копии — в восстановлении. На время запуска UI показывает отменяемое ожидание; повторные клики объединяются в одну операцию. Для символических ссылок и регистра пути проверяется файловая идентичность, чтобы избежать дублей. Нельзя превращать «недавние» в неявное сканирование личных папок.
macOS-адаптер
Реализован отдельный meridian-menubar в составе app bundle с прямым AppKit-адаптером. Он держит status item и подписку на брокер, но не рендерит документы и не поднимает окна редакторов при старте. Hub остаётся обычным клиентом. AppKit-вызовы выполняются на main thread. Используется существующий стиль FFI/Objective-C проекта; новый UI-фреймворк не требуется.
Apple предоставляет NSStatusItem и NSPopover для этого варианта. Для сравнения SwiftUI предлагает MenuBarExtra с оконным представлением, но переход проекта на SwiftUI в план не входит. Регистрация login item на macOS 13+ — через SMAppService.
За рамками этой функции
Облачная синхронизация, аккаунт и подписки, магазин шаблонов, индекс содержимого всей файловой системы, глобальный перехват клавиатуры, автосохранение чужих редакторов и полная реализация девяти будущих программ не входят в H0–H6. Cmd+K работает в Hub; глобальную комбинацию для помощника можно спроектировать позднее с обработкой конфликтов.
7. Что считать готовностью
Проверка
Ожидаемый результат
Список и запуск
Все 11 программ представлены. Каждая запускает реальную программу либо объясняет недоступность. Нет декоративного «Открыть».
Текущие
Два документа с одинаковым именем, несколько окон и «Без названия» различимы; точный фокус без дубликатов, метки изменений актуальны.
Недавние
Открытие, pin/unpin, очистка и отключение записи одинаковы в Hub/меню. Файлы не удаляются.
Шаблоны
Предпросмотр соответствует ресурсу; новая копия независима; неподдерживаемый шаблон не выглядит успешно открытым.
Закрытие
Close Hub, quit helper и close document различны; несохранённый документ нельзя потерять без явного выбора.
Сбои
Потеря соединения не показывает устаревший список как живой; повтор восстанавливает снимок; файл без доступа и файл без приложения различаются.
macOS
Физические проверки входа/выхода, сна, Spaces, экрана с вырезом, полного экрана, двух мониторов и изменения системных разрешений.
Доступность
Tab/Shift+Tab, Enter, Escape, VoiceOver, контраст и увеличение текста; фокус после закрытия панели возвращается к исходному контролу.
Производительность
Замерено на Apple M5 Max: реальное меню p95 133,4 мс; фильтр 200 записей p95 0,098 мс; снимок 30 живых документов p95 0,057 мс. Все три локальных бюджета пройдены.
Поставка
Совпадение source/build/runtime, подписанный bundle при распространении, сохранность профиля и проверенная предыдущая версия для rollback.
Как проверить этот макет за 3 минуты
Откройте главное окно, затем нажмите значок MOffice справа в верхней строке.
Выберите «Бюджет проекта» — открывается экран Sheets, число текущих документов не увеличивается.
Вернитесь в Hub → шаблоны → «Квартальный отчёт» → задайте название → создайте документ.
Измените текст, сохраните и откройте раздел «Сейчас открыто».
Закройте несохранённый документ: проверьте отмену и сохранение.
В «Все экраны» откройте «Файл не найден», затем укажите новое место.
Проверьте тёмную тему и скрытие названий в меню. Нажмите «Сначала».
Только вымышленные документы и localStorage текущего браузера. Ни содержимое, ни названия файлов с компьютера пользователя на сервер не передаются. Веб-макет не обращается к домашним папкам и не запрашивает права macOS.