@goodandready/dsh-kanban 0.1.17 → 0.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,169 @@
1
+ # dsh-kanban — план реализации
2
+
3
+ > **Для исполнителя:** это план для агента, у которого нет контекста обсуждения.
4
+ > Перед любой правкой плагина DSH загрузи `dsh-plugin-authoring`.
5
+ > Перед правкой профиля `web` — `dsh-web-profile-repair`.
6
+ > Работа ведётся по `gitea-project-workflow`: issue → worktree от свежего
7
+ > `origin/main` → WIP PR → ревью → merge → deploy → cleanup → закрытие issue.
8
+
9
+ **Цель:** доска задач внутри DeepSeek Harness, которая берёт задачи из Gitea,
10
+ показывает по ним ход работы и умеет запускать по каждой задаче отдельную
11
+ сессию агента с выбранной моделью.
12
+
13
+ **Архитектура:** отдельный плагин `@goodandready/dsh-kanban` со своим
14
+ хранилищем задач. Gitea-доступ не дублируется — используется существующий
15
+ плагин `@goodandready/dsh-gitea`, которому для этого добавляется сервис cordis.
16
+ Запуск работы идёт через штатные сервисы ядра `agents`/`sessions`; плагин
17
+ поднимает сессию и отдаёт первое сообщение, дальше работу ведёт агент по
18
+ действующему воркфлоу.
19
+
20
+ **Стек:** Node (ESM), cordis, `@deepseek-ai/schemastery`, React в браузерной
21
+ половине через `window.__ModuleLoader__`, хранилище — `node:sqlite`.
22
+
23
+ ## Глобальные ограничения
24
+
25
+ - Имя пакета `@goodandready/dsh-kanban` обязано совпадать в трёх местах:
26
+ `package.json` → `name`, `cordis.patch.yml` → `name:`, `lib/client.js` →
27
+ `load({ id })`. Короткий id патча — `dsh-kanban`.
28
+ - Пространство настроек: `dsh-kanban`. Ключ слота карточки настроек обязан быть
29
+ равен пространству настроек, иначе карточка молча не появится.
30
+ - Настройки — карточкой в `settings.plugin.item`. Свой раздел настроек НЕ
31
+ заводить. Раздел верхнего уровня заводится только для экрана доски.
32
+ - Токен Gitea плагин не хранит, не спрашивает и не логирует. Доступ — только
33
+ через сервис `gitea` из `dsh-gitea`.
34
+ - Ни абсолютных путей, ни адресов инстансов, ни имён машин в коде и README.
35
+ Машинно-зависимое живёт в настройках с пустым значением по умолчанию.
36
+ - Все Git-операции — только через wrapper `git-<agent>`. Bare `git` запрещён.
37
+ - Conventional Commits обязательны: `<type>(<scope>)!: <действие>`, footer
38
+ `Refs: #<номер>`.
39
+ - Тесты идут без харнесса и без сети: `node --test test/*.test.mjs`.
40
+ - Всё поднятое в `ctx.effect` гасится возвращённым уборщиком.
41
+ - Хуки React объявляются выше всех возвратов.
42
+
43
+ ## Колонки доски
44
+
45
+ Колонки повторяют реальный воркфлоу, а не абстрактный «в работе → готово».
46
+
47
+ | Колонка | Признак входа |
48
+ |---|---|
49
+ | `backlog` | issue есть, никто не взял |
50
+ | `in-progress` | сессия поднята, в issue есть стартовый комментарий с планом и веткой |
51
+ | `review` | PR снят с WIP, ревьюер даёт PASS/FAIL |
52
+ | `deploy` | PR влит в `main`, ждём согласованный deploy и production-проверку |
53
+ | `cleanup` | ветка в Gitea, worktree и локальная ветка ещё не удалены |
54
+ | `done` | issue закрыт И cleanup записан в итоговом комментарии |
55
+
56
+ Колонка `cleanup` существует потому, что по воркфлоу задача не завершена, пока
57
+ cleanup не сделан и не записан. Доска, отправляющая карточку в `done` по merge,
58
+ будет врать ровно там, где копятся забытые ветки.
59
+
60
+ WIP PR НЕ двигает карточку в `review`: он открывается рано и означает «работа
61
+ идёт», а не «смотрите».
62
+
63
+ ## Что плагин НЕ делает
64
+
65
+ Эти границы заданы воркфлоу и нарушать их нельзя:
66
+
67
+ - Не создаёт ветки и worktree. По воркфлоу агент сначала делает preflight
68
+ (открытые ветки, `git status --short`) и только потом заводит worktree от
69
+ свежего `origin/main`. Плагин, создающий ветку заранее, ломает preflight.
70
+ - Не пишет стартовый комментарий в issue — это делает агент после preflight.
71
+ - Ветка и worktree на карточке — НАБЛЮДЕНИЕ, вычитанное из issue и событий
72
+ Gitea, а не намерение, заданное плагином.
73
+ - Не трогает Hermes Kanban. Это другая система, и она этому CLI запрещена.
74
+
75
+ ## Выпуски
76
+
77
+ **0.1 — доска, импорт, запуск.** Задачи хранятся локально, импортируются из
78
+ Gitea по кнопке, карточки двигаются вручную, по кнопке «Начать» поднимается
79
+ сессия с выбранной моделью. Синхронизация односторонняя: Gitea → канбан, в
80
+ момент импорта и по кнопке обновления.
81
+
82
+ **0.2 — автоперемещение.** События сессии агента, события Gitea, журнал
83
+ переходов с источником. Инструмент `board_move` для агента пишется, но по
84
+ умолчанию выключен — включается вместе с правкой скилла
85
+ `gitea-project-workflow`.
86
+
87
+ **0.3 — двусторонняя синхронизация.** Вебхуки Gitea, разрешение конфликтов по
88
+ времени изменения, очередь повторов, деградация до опроса.
89
+
90
+ ## Состав 0.1
91
+
92
+ | Issue | Репозиторий | Тема |
93
+ |---|---|---|
94
+ | G1 | dsh-gitea | Выставить сервис `gitea` наружу |
95
+ | G2 | dsh-gitea | Техдолг: `gitea_worktree_add` зовёт bare git |
96
+ | K1 | dsh-kanban | Каркас плагина и карточка настроек |
97
+ | K2 | dsh-kanban | Хранилище задач |
98
+ | K3 | dsh-kanban | HTTP-маршруты доски |
99
+ | K4 | dsh-kanban | Импорт задачи из Gitea |
100
+ | K5 | dsh-kanban | Экран доски |
101
+ | K6 | dsh-kanban | Запуск работы по задаче |
102
+ | K7 | dsh-kanban | Чип задачи в шапке чата |
103
+ | K8 | dsh-kanban | Документация и релизный гейт 0.1 |
104
+
105
+ Порядок: G1 → K1 → K2 → K3 → (K4, K5 параллельно) → K6 → K7 → K8.
106
+ G2 независим и может идти когда угодно.
107
+
108
+ ## Структура файлов
109
+
110
+ ```
111
+ lib/index.js точка входа хоста: Config, apply, регистрация маршрутов
112
+ lib/store.js хранилище задач: схема, CRUD, дробный индекс
113
+ lib/order.js дробный индекс (чистая функция, без БД)
114
+ lib/import.js перенос issue Gitea в задачу доски
115
+ lib/launcher.js запуск сессии по задаче
116
+ lib/routes.js обработчики HTTP
117
+ lib/client.js браузерная половина: раздел доски, карточка настроек, чип
118
+ test/*.test.mjs тесты без харнесса и без сети
119
+ ```
120
+
121
+ Разделение по ответственности, а не по слою. `order.js` отделён от `store.js`
122
+ потому, что дробный индекс — единственная нетривиальная логика в хранилище и
123
+ проверяется без БД вообще.
124
+
125
+ ## Проверенные интерфейсы ядра
126
+
127
+ Ниже — реальные сигнатуры, снятые с исходников, а не пересказ. Исполнитель
128
+ может опираться на них как есть.
129
+
130
+ Создание сессии с выбранной моделью и первое сообщение:
131
+
132
+ ```js
133
+ import { SessionId } from '@deepseek-ai/dsh-session'
134
+ import { createUserMessage } from '@deepseek-ai/dsh-llm'
135
+
136
+ const handle = await ctx.agents.create({
137
+ sessionId: SessionId(`kanban-${taskId}-${randomUUID()}`),
138
+ meta: { cwd }, // ОБЯЗАТЕЛЬНО абсолютный путь
139
+ agentOptions: { provider, model }, // maxTokens необязателен
140
+ })
141
+ await handle.agent.whenIdle()
142
+ handle.agent.followup(createUserMessage({
143
+ content,
144
+ source: { kind: 'plugin', plugin: 'dsh-kanban', form: 'task-start' },
145
+ }))
146
+ ```
147
+
148
+ - `ctx.agents.create(options)` возвращает `AgentHandle` с полями `agent` и
149
+ `dispose`. Живой образец — `dsh-messenger-gateway/lib/gateway.js:465`.
150
+ - `meta.cwd` валидируется ядром: неабсолютный путь бросает исключение.
151
+ - `agent.followup(message)` ставит обычный следующий ход и будит драйвер.
152
+ - `agent.session.id` — идентификатор сессии, по нему карточка связывается с
153
+ чатом.
154
+ - Модель по умолчанию берётся из сервиса `agentDefaultModel`; образец
155
+ разрешения провайдера и модели — `gateway.js:455`.
156
+
157
+ События сессии, нужные в 0.2: `assistant/message`, `turn/end`,
158
+ `approval/asked` (несёт `id`, имя инструмента, причину), `question/requested`.
159
+
160
+ ## Открытый технический риск
161
+
162
+ `node:sqlite` — встроенный модуль Node, но он появился не во всех версиях.
163
+ ПЕРВЫЙ шаг задачи K2 — проверить, что модуль есть в той версии Node, на которой
164
+ крутится харнесс. Если модуля нет, хранилище делается на одном JSON-файле с
165
+ атомарной записью (запись во временный файл рядом, затем `rename`), а схема
166
+ таблиц из K2 переносится в форму объекта один-в-один. Дробный индекс и весь
167
+ остальной план от выбора хранилища не зависят.
168
+
169
+ Решение принимается фактом проверки, а не догадкой, и записывается в issue K2.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-kanban",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "Visual Kanban board for DeepSeek Harness: Gitea-backed tasks, workflow columns, and a dedicated agent session per task.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -14,6 +14,7 @@
14
14
  "lib/",
15
15
  "cordis.patch.yml",
16
16
  "README.md",
17
+ "docs/",
17
18
  "LICENSE"
18
19
  ],
19
20
  "scripts": {
File without changes
File without changes