6.9 KiB
6.9 KiB
project-tasks — VS Code Extension
Хранение
Формат: Markdown + YAML frontmatter (один .task.md файл на задачу)
---
id: "..."
title: "Пофиксить баг логина"
status: todo # todo | in-progress | done | cancelled
priority: high # low | medium | high | critical
tags: [bug, frontend]
assignee: ""
created: 2026-07-12T10:00:00Z
updated: 2026-07-12T10:00:00Z
---
Описание задачи в markdown...
Структура папок:
.vscode/tasks/— проектные задачи- глобальная папка — настраивается (
projectTasks.globalPath)
Оба пути настраиваются через VS Code settings.
UI в основном окне (Split-редактор)
Через Custom Editor + WebView:
- Activity Bar — вкладка Project Tasks
- Task Dashboard — WebView в editor area со split layout:
- Левая панель — список задач с фильтрацией/группировкой
- Правая панель — содержимое выбранной задачи (редактируемый markdown)
- TreeView — быстрый просмотр по статусу
Архитектура кода
Актуальная раскладка (после рефакторинга портов/адаптеров):
src/
├── extension.ts # composition root (DI, register)
├── ports.ts # IFileSystem, ITaskRepository, IConfigProvider
├── error.ts # AppError + factories (единый каталог ошибок)
├── model/task.ts
├── storage/
│ ├── FsTaskRepository.ts
│ ├── NodeFileSystem.ts
│ └── VscodeConfigProvider.ts
├── commands/ # use-cases без vscode UI
│ ├── createTask.ts
│ ├── openTask.ts
│ ├── deleteTask.ts
│ └── changeStatus.ts
├── views/
│ └── taskTreeProvider.ts # (+ dashboard later)
└── utils/
├── uuid.ts
└── markdown.ts # parse/serialize frontmatter
tests/helpers/InMemoryFileSystem.ts
UI (input box, quick pick, open editor) — тонкие адаптеры; бизнес-логика в
use-cases + ITaskRepository. Ошибки — AppError из error.ts.
План реализации
| Фаза | Что делаем |
|---|---|
| 1. Scaffold | Extension, TypeScript, сборка, package.json |
| 2. Storage | CRUD .task.md, парсинг frontmatter, unit-тесты storage |
| 3. TreeView | sidebar по статусу, file watcher |
| 4. Команды | createTask, deleteTask, changeStatus, openTask (use-cases → wiring UI) |
| 5. Task Dashboard | WebView split layout |
| 6. Глобальные задачи | использование globalPath |
| 7. Kanban | drag-n-drop |
| 8. Публикация | vsce publish |
Фаза 4 — команды (use-cases)
| Команда | Поведение |
|---|---|
createTask |
title + folder → defaults todo/medium; empty title / no folder |
deleteTask |
folder + id → delete; not found |
changeStatus |
folder + id + status → update; not found |
openTask |
folder + id → path + task для editor; not found |
Зависимости
front-matter— разбор YAML frontmatter (body + attributes)js-yaml— сериализация frontmatter обратно в YAML (dump)uuid— генерация IDneverthrow—Result/ResultAsyncдля use-casesvitest/eslint— dev
История изменений (решения, не чеклист)
Краткая летопись смен относительно изначального наброска плана. Детали
рефакторинга storage/тестов — в архиве docs/REFACTOR-AND-TEST.md (документ
закрыт, не ведём).
Изначальный набросок (v0)
- Парсинг:
gray-matter - Storage:
taskStore.ts(CRUD),configStore.ts(settings) - Сборка/скелет:
yo code-ориентированный scaffold - Дерево модулей: storage + views (tree/list/dashboard) + commands + utils
Рефакторинг storage / чистая архитектура
taskStore/configStore→ порты (IFileSystem,ITaskRepository,IConfigProvider) и адаптеры:FsTaskRepository,NodeFileSystem,VscodeConfigProvider
extension.ts— composition root (DI), tree зависит от портов- Unit-тесты: Vitest, colocation,
InMemoryFileSystemвtests/helpers/
gray-matter → front-matter + js-yaml
- Было в плане: один пакет
gray-matterна parse (+ stringify при необходимости). - Стало:
front-matterдля чтения attributes/body;js-yaml(dump) для записи frontmatter вserializeTask. - Зачем:
gray-matterдаёт лишние возможности парсинга (eval для JS и прочая «магия»), которые для задач не нужны; Vite на eval ругается, с точки зрения безопасности это нежелательно. Поэтому parse черезfront-matter, serialize черезjs-yaml(dump). Формат файла тот же: Markdown + YAML frontmatter.
neverthrow + AppError
- Use-cases возвращают
ResultAsync<T, AppError>вместо кастомных{ ok, reason }. - Каталог ошибок:
src/error.ts(AppErrorCode, factoriesAppError.noFolder()и т.д.).
Прочее относительно v0
- Сборка: Vite (extension bundle), не классический
tsc-only из yo code - В модели/файле задачи зафиксирован
idв frontmatter (нужен для list/get/update/delete) - Фаза 4: use-cases в
src/commands/*тестируются без vscode; UI — отдельные адаптеры