From 372a195ae0b5244ca650af231aa8f140281e6abb Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sat, 17 Oct 2026 09:23:28 +0400 Subject: [PATCH] =?UTF-8?q?chore(openspec):=20=D0=B0=D1=80=D1=85=D0=B8?= =?UTF-8?q?=D0=B2=20wiki-render=20(#53)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Дельта web-app влита в openspec/specs: изменено «Карточка задачи», добавлено «Разметка Jira в карточке». Co-Authored-By: Claude Opus 5.5 --- .../2026-10-17-wiki-render}/.openspec.yaml | 0 .../2026-10-17-wiki-render}/design.md | 0 .../2026-10-17-wiki-render}/proposal.md | 0 .../specs/web-app/spec.md | 0 openspec/specs/web-app/spec.md | 77 +++++++++++++++++-- 5 files changed, 72 insertions(+), 5 deletions(-) rename openspec/changes/{wiki-render => archive/2026-10-17-wiki-render}/.openspec.yaml (100%) rename openspec/changes/{wiki-render => archive/2026-10-17-wiki-render}/design.md (100%) rename openspec/changes/{wiki-render => archive/2026-10-17-wiki-render}/proposal.md (100%) rename openspec/changes/{wiki-render => archive/2026-10-17-wiki-render}/specs/web-app/spec.md (100%) diff --git a/openspec/changes/wiki-render/.openspec.yaml b/openspec/changes/archive/2026-10-17-wiki-render/.openspec.yaml similarity index 100% rename from openspec/changes/wiki-render/.openspec.yaml rename to openspec/changes/archive/2026-10-17-wiki-render/.openspec.yaml diff --git a/openspec/changes/wiki-render/design.md b/openspec/changes/archive/2026-10-17-wiki-render/design.md similarity index 100% rename from openspec/changes/wiki-render/design.md rename to openspec/changes/archive/2026-10-17-wiki-render/design.md diff --git a/openspec/changes/wiki-render/proposal.md b/openspec/changes/archive/2026-10-17-wiki-render/proposal.md similarity index 100% rename from openspec/changes/wiki-render/proposal.md rename to openspec/changes/archive/2026-10-17-wiki-render/proposal.md diff --git a/openspec/changes/wiki-render/specs/web-app/spec.md b/openspec/changes/archive/2026-10-17-wiki-render/specs/web-app/spec.md similarity index 100% rename from openspec/changes/wiki-render/specs/web-app/spec.md rename to openspec/changes/archive/2026-10-17-wiki-render/specs/web-app/spec.md diff --git a/openspec/specs/web-app/spec.md b/openspec/specs/web-app/spec.md index 8ba20e5..bc7d2f7 100644 --- a/openspec/specs/web-app/spec.md +++ b/openspec/specs/web-app/spec.md @@ -196,11 +196,12 @@ SHALL проверять агента (`GET /agent`; офлайн — преду «Связана с» (тип `связанные` в обе стороны), «Прочие» (тип Jira вне `link_types`: имя типа и направление «→» / «←»); в строке — ключ (открывает связанную задачу в окне), тема и статус Jira, а если задачи нет в зеркале — ключ и «нет в зеркале»; пустые группы не показываются, без связей — «связей нет»; -- «Описание» — текст с сохранёнными переносами строк, без разбора разметки Jira; длиннее 8 строк — свёрнуто с кнопкой - «развернуть» / «свернуть»; без описания раздела нет; -- «Комментарии (N)» — новые сверху, автор, время, текст с сохранёнными переносами без разбора разметки; кнопка - «Скрыть» / «Показать» сворачивает раздел, выбор SHALL запоминаться в браузере для всех карточек; без комментариев — - «комментариев нет»; +- «Описание» — текст, отрендеренный по требованию «Разметка Jira в карточке», с кнопкой «исходник» / «текст» в + заголовке раздела; длиннее 8 строк — свёрнуто с кнопкой «развернуть» / «свернуть» в обоих режимах; без описания + раздела нет; +- «Комментарии (N)» — новые сверху, автор, время, кнопка «исходник» / «текст» у каждого комментария, текст, + отрендеренный по требованию «Разметка Jira в карточке»; кнопка «Скрыть» / «Показать» сворачивает раздел, выбор SHALL + запоминаться в браузере для всех карточек; без комментариев — «комментариев нет»; - «Служебные заметки» (требование «Служебные заметки»); - «Прочие поля» — непустые из: тип, приоритет, автор, метки, плановое начало, обновлена в Jira, сосед по связям; - «Команды моста (N)» — 10 последних команд по задаче (id, пакет, тип, статус, время завершения, ошибка), раздел свёрнут @@ -276,3 +277,69 @@ SHALL сообщать об этом с кнопкой «Закрыть»; ха #### Scenario: Без интернета - **WHEN** приложение открыто на машине без доступа в интернет - **THEN** страница не запрашивает ресурсов вне хаба, текст набран IBM Plex Sans + +### Requirement: Разметка Jira в карточке +Описание задачи и текст каждого комментария в карточке SHALL показываться отрендеренной вики-разметкой Jira (хаб +хранит их как есть, в wiki) так, как их показывает Jira. Разбираются: +- блоки: заголовки `h1.`–`h6.` в начале строки; списки — строки, начинающиеся (после необязательных пробелов) с + маркеров `*`, `#` и пробела (уровень вложенности — числом маркеров, `*` — маркированный, `#` — нумерованный, + смешанная вложенность `*#` — по последнему маркеру) или с одного `-` и пробела (маркированный, первый уровень); + `--`, `*-` и прочие сочетания с `-` — не список; таблицы — строки, начинающиеся с + `|`, ячейки `||заголовок||` и `|ячейка|`; `{code}` / `{code:язык}` … `{code}` и `{noformat}` … `{noformat}` — + моноширинный блок без разбора разметки внутри; `{quote}` … `{quote}` и строка `bq. ` — цитата; открывающий тег + блока — в начале строки, закрывающий — в любом месте той же или последующей строки, текст после закрывающего тега + разбирается дальше как обычные строки; тег не в начале строки — текст как есть; строка `----` — + горизонтальная черта; прочие строки — абзацы, разделённые пустыми строками, одиночный перенос внутри абзаца — + перенос строки; +- внутри строки: `*жирный*`, `_курсив_`, `-зачёркнутый-`, `+подчёркнутый+`, `^верхний^`, `~нижний~`, `{{моно}}` + (`{{…}}` — без разбора внутри); маркер выделения действует, только если открывающий стоит в начале текста или после + пробела либо знака препинания и за ним не пробел и не тот же символ (`**x**` — текст как есть), а закрывающий стоит после не-пробела и за ним не буква и не + цифра (`data_type`, `2026-10-15`, `счёт-фактура`, `a*b*c` — обычный текст); `\\` — перенос строки; `\` перед + символом разметки — сам символ; +- ссылки: `[текст|адрес]`, `[адрес]` и голые адреса `http://`, `https://` — ссылка в новой вкладке, только для схем + `http`, `https`, `mailto`, иначе текст как есть; `[ключ задачи]`, `[текст|ключ задачи]` и ключ задачи в тексте вида + `ПРОЕКТ-123`, где `ПРОЕКТ` — `project_key` из настроек хаба, — ссылка, открывающая карточку этой задачи в окне + (`UTF-8`, `SHA-256` и ключи других проектов — текст); + `[~логин]` — «@логин». +Всё, что разборщик не распознал (`{panel}`, `{color}`, `!картинка!`, незакрытые маркеры и блоки и прочее), SHALL +показываться как текст исходника без потерь. Разметка MUST NOT превращаться в HTML строкой (`innerHTML`, +`dangerouslySetInnerHTML`): текст задачи не может добавить на страницу элементы, атрибуты или скрипты. Если рендер +блока завершился ошибкой, блок SHALL показываться исходником. + +Кнопка «исходник» у описания и у каждого комментария SHALL переключать этот блок на исходник — текст с сохранёнными +переносами строк, как без разбора разметки, — и обратно кнопкой «текст»; остальные блоки не переключаются. При каждом +открытии карточки (в том числе при переходе по связи) все блоки показываются отрендеренными, выбор не запоминается. + +#### Scenario: Описание со структурой +- **WHEN** описание AURORA-1620 — `h3. Контекст`, строка `Шаги:`, затем `# Загрузить ОСВ` и `# Открыть документ`, + затем пустая строка и `*Итог:* ошибка в {{data_type}}` +- **THEN** в «Описании» заголовок «Контекст», абзац «Шаги:», нумерованный список из двух пунктов и абзац, где «Итог:» — + жирным, «data_type» — моноширинным; символов `h3.`, `#`, `*`, `{{` не видно + +#### Scenario: Переключение на исходник +- **WHEN** в карточке AURORA-1620 у описания нажато «исходник» +- **THEN** описание показано исходником с переносами строк (видны `h3. Контекст` и `# Загрузить ОСВ`), кнопка — «текст»; + комментарии остаются отрендеренными; после «текст» описание снова отрендерено + +#### Scenario: Исходник у одного комментария +- **WHEN** у второго комментария нажато «исходник», затем открыта связанная задача и возврат «назад» +- **THEN** сразу после нажатия исходником показан только второй комментарий; после возврата все комментарии + отрендерены + +#### Scenario: Ключ задачи в тексте +- **WHEN** комментарий — `П. 1 ведётся в AURORA-1445; AURORA-1645 снята как дубль.` +- **THEN** «AURORA-1445» и «AURORA-1645» — ссылки; щелчок по первой меняет содержимое окна на AURORA-1445 + +#### Scenario: Неизвестная разметка и опасный адрес +- **WHEN** описание — `{color:red}важно{color}`, `!схема.png!` и `[нажми|javascript:alert(1)]` +- **THEN** все три показаны текстом исходника как есть, ссылки и картинки нет, скрипт не выполняется + +#### Scenario: Списки с отступом и пустыми строками +- **WHEN** описание — `Шаги воспроизведения:`, ` * Загрузить ОСВ.`, пустая строка, ` * Дождаться обработки.` +- **THEN** абзац «Шаги воспроизведения:» и маркированные пункты «Загрузить ОСВ.» и «Дождаться обработки.» без + звёздочек + +#### Scenario: Обычный текст не портится +- **WHEN** описание — `Поле data_type = null, дата 2026-10-15, оборот 18 803 903,65 - 9 351 102,89, a*b*c, UTF-8, + **важно**` +- **THEN** текст показан как есть, без курсива, зачёркивания, жирного и ссылок