@goodandready/dsh-kanban 0.2.2 → 0.2.8
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.
- package/README.md +24 -0
- package/{docs/README.ru.md → README.ru.md} +10 -0
- package/{docs/README.zh.md → README.zh.md} +21 -0
- package/lib/board-tool.js +151 -0
- package/lib/client.js +1020 -763
- package/lib/commands.js +6 -11
- package/lib/config.js +31 -29
- package/lib/events.js +2 -2
- package/lib/filters.js +2 -2
- package/lib/gitea.js +15 -0
- package/lib/index.js +171 -142
- package/lib/power.js +1 -1
- package/lib/progress-dump.js +3 -3
- package/lib/routes.js +403 -5
- package/lib/store.js +59 -9
- package/lib/sync.js +26 -3
- package/lib/task-service.js +56 -0
- package/lib/updater.js +338 -0
- package/lib/worktree.js +1 -1
- package/package.json +7 -3
- package/docs/design/DESIGN.md +0 -94
- package/docs/plans/2026-08-26-dsh-kanban-0.1.md +0 -169
- package/docs/plans/2026-09-07-quality-acceptance-gateway.md +0 -25
- package/docs/plans/2026-09-08-concurrency-safety.md +0 -8
- package/docs/plans/2026-09-08-diff-viewer-merge.md +0 -7
- package/docs/plans/2026-09-08-session-worktree-stability.md +0 -33
- package/docs/plans/2026-09-10-issue-238-settings-scope.md +0 -13
|
@@ -1,169 +0,0 @@
|
|
|
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.
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# План реализации: Human-in-the-Loop Quality & Acceptance Gateway (#205–#209)
|
|
2
|
-
|
|
3
|
-
Пакетная реализация сквозного контура контроля качества и человеческой приёмки для `@goodandready/dsh-kanban`:
|
|
4
|
-
- **#205**: DoD Acceptance Checklist с фиксацией доказательств (`board_checklist`)
|
|
5
|
-
- **#206**: Структурированный отчёт выполнения задачи (`board_report`)
|
|
6
|
-
- **#207**: Двусторонний цикл приёмки человеком (Accept / Send back with reason)
|
|
7
|
-
- **#208**: Ветка комментариев к задаче и синхронизация с агентом (`board_comments`, `board_comment_add`)
|
|
8
|
-
- **#209**: Протокольный шлюз запрета перевода задачи в Done агентом
|
|
9
|
-
|
|
10
|
-
## 1. Архитектурные требования
|
|
11
|
-
1. **Протокольный шлюз Done (#209)**: агент через инструмент `board_move` не может перевести задачу в `done`. Статус `done` может быть установлен только человеком.
|
|
12
|
-
2. **Шлюз перехода в Review (#205)**: если в задаче заданы обязательные пункты Definition of Done, переход в `review` блокируется до закрытия всех обязательных пунктов с предоставлением evidence.
|
|
13
|
-
3. **Отчёт выполнения (#206)**: агент формирует структурированный отчёт (`board_report`) с полями `summary`, `changed_files`, `checks_run`, `artifacts`, `risks`.
|
|
14
|
-
4. **Приёмка и возврат (#207)**: в колонке `review` человек может нажать «Принять» (в `done`) или «Вернуть» (в `in-progress`) с обязательным указанием причины, которая инжектируется в следующую сессию агента.
|
|
15
|
-
5. **Обсуждение задачи (#208)**: карточка содержит тред комментариев с поддержкой ролей `user` и `agent`, доступный через HTTP API и инструменты `board_comments`, `board_comment_add`.
|
|
16
|
-
|
|
17
|
-
## 2. Пошаговые задачи
|
|
18
|
-
- [ ] 1. Модель данных и миграции SQLite в `lib/store.js`.
|
|
19
|
-
- [ ] 2. Инструменты агента `board_checklist`, `board_report`, `board_comments`, `board_comment_add`, валидаторы `board_move` в `lib/board-tool.js`.
|
|
20
|
-
- [ ] 3. Регистрация инструментов в `lib/index.js`.
|
|
21
|
-
- [ ] 4. Маршруты `/accept`, `/reject`, `/checklist`, `/report`, `/comments` в `lib/routes.js`.
|
|
22
|
-
- [ ] 5. Инъекция замечаний возврата и DoD в `lib/launcher.js`.
|
|
23
|
-
- [ ] 6. Пользовательский интерфейс Task Drawer и карточек в `lib/client.js`.
|
|
24
|
-
- [ ] 7. Юнит-тесты: `test/checklist.test.mjs`, `test/report.test.mjs`, `test/acceptance.test.mjs`, `test/comments.test.mjs`.
|
|
25
|
-
- [ ] 8. Актуализация `docs/design/DESIGN.md`.
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
# Implementation Plan: Vector 2 — Concurrency & Safety (#214, #216, #224)
|
|
2
|
-
|
|
3
|
-
Implementation of resource protection, workspace claim boundaries, and database backup before snapshot import in `@goodandready/dsh-kanban` (v0.1.32).
|
|
4
|
-
|
|
5
|
-
## Issues Scope
|
|
6
|
-
1. **#214**: Global concurrent session limit and task queue (`maxConcurrentSessions`).
|
|
7
|
-
2. **#216**: Project workspace claim boundaries (`workspaceClaimBoundaries`).
|
|
8
|
-
3. **#224**: Automatic database safety backup before board snapshot import.
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
# Implementation Plan: Vector 3 — Git Diff / Commit Viewer & One-Click Merge (#211, #212)
|
|
2
|
-
|
|
3
|
-
Implementation of in-board git diff viewer and one-click worktree merge in `@goodandready/dsh-kanban` (v0.1.33).
|
|
4
|
-
|
|
5
|
-
## Issues Scope
|
|
6
|
-
1. **#211**: In-drawer Git Diff and commits viewer for human acceptance.
|
|
7
|
-
2. **#212**: One-click worktree branch merge upon acceptance (`--no-ff`) with automated cleanup.
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# План: Вектор 1 — Стабильность сессий и воркдеревьев (#227, #226, #213, #215)
|
|
2
|
-
|
|
3
|
-
## 1. Контекст и цели
|
|
4
|
-
Повышение отказоустойчивости жизненного цикла сессий задач в DSH Kanban:
|
|
5
|
-
- Сохранение привязки сессии к проекту в левом сайдбаре DSH (meta.cwd = projectRoot) при изоляции в воркдереве (#227).
|
|
6
|
-
- Возможность продолжить работу над задачей («↻ Продолжить / Resume») в существующем воркдереве без деструктивного сброса ветки (#226).
|
|
7
|
-
- Игнорирование структурного шума субмодулей и gitlink drift в проверках чистоты воркдерева checkWorktreeDirty (#213).
|
|
8
|
-
- Исключение дочерних сессий субагентов (invoke_subagent) из списка живых сессий и трекинга карточек (#215).
|
|
9
|
-
|
|
10
|
-
## 2. Архитектурные изменения
|
|
11
|
-
- **lib/worktree.js**:
|
|
12
|
-
- checkWorktreeDirty: вызов gitRunner(['status', '--porcelain', '--ignore-submodules=all'], worktreePath) для устранения ложного dirty-статуса от субмодулей.
|
|
13
|
-
- **lib/launcher.js**:
|
|
14
|
-
- obtainAgent: meta.cwd фиксируется как projectRoot, meta.worktreePath = worktreePath.
|
|
15
|
-
-
|
|
16
|
-
- liveSessions: фильтрация сессий с origin === 'subagent' или parentId !== undefined.
|
|
17
|
-
- **lib/lifecycle.js**:
|
|
18
|
-
- handleSessionEvent: игнорирование событий от сессий-субагентов.
|
|
19
|
-
- **lib/routes.js**:
|
|
20
|
-
- Эндпоинт POST /tasks/:id/resume.
|
|
21
|
-
- **lib/index.js**:
|
|
22
|
-
- Регистрация маршрута /dsh-kanban/tasks/:id/resume.
|
|
23
|
-
- **lib/client.js**:
|
|
24
|
-
- Кнопка «↻ Resume» в TaskDrawer.
|
|
25
|
-
|
|
26
|
-
## 3. Верификация
|
|
27
|
-
- Юнит-тесты: est/worktree-dirty.test.mjs, est/launcher-cwd.test.mjs, est/resume.test.mjs, est/subagent-filter.test.mjs.
|
|
28
|
-
- Полный прогон
|
|
29
|
-
pm test и
|
|
30
|
-
pm run compat.
|
|
31
|
-
- Проверка пакета
|
|
32
|
-
pm pack --dry-run --json.
|
|
33
|
-
- Тест на MiniPC test runner через dsh-test-plugin.
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# Issue #238: Убрать settings.section fallback и перевести обращение к службам на ctx.get
|
|
2
|
-
|
|
3
|
-
## Контекст
|
|
4
|
-
Issue #238 (priority/low, type/tech-debt, scope/webui) указывает:
|
|
5
|
-
1. Карточка настроек регистрирует запасной слот settings.section (строку в боковом списке настроек). Согласно дизайн-контракту и политике DSH-плагинов, боковой список настроек плоский и перегружен, а набор полей плагина должен жить исключительно как карточка внутри «Настройки → Плагины → Настройки плагинов» (settings.plugin.item).
|
|
6
|
-
2. В коде обнаружено обращение ctx.llm вместо канонического ctx.get('llm'). Контекст Cordis оборачивается в прокси, и свойства-поля могут возвращать undefined, поэтому доступ к службам должен выполняться строго через ctx.get('...').
|
|
7
|
-
|
|
8
|
-
## План работ
|
|
9
|
-
- [ ] 1. Исправить вызовы ctx.llm на ctx.get('llm') в lib/index.js (GET /dsh-kanban/models).
|
|
10
|
-
- [ ] 2. В lib/client.js убрать запасную регистрацию settings.section, оставив карточку только в слоте settings.plugin.item.
|
|
11
|
-
- [ ] 3. Актуализировать тесты в test/board-ui.test.mjs и test/identity.test.mjs.
|
|
12
|
-
- [ ] 4. Обновить docs/design/DESIGN.md (зафиксировать решение #238).
|
|
13
|
-
- [ ] 5. Выполнить полный тестовый прогон npm test (все 651 тест) и npm run compat.
|