@goodandready/dsh-kanban 0.2.18 → 0.2.20
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/lib/board-tool.js +18 -48
- package/lib/client.js +85 -176
- package/lib/commands.js +21 -38
- package/lib/config.js +29 -54
- package/lib/cron.js +13 -13
- package/lib/events.js +1 -1
- package/lib/filters.js +58 -82
- package/lib/git-provider.js +23 -23
- package/lib/gitea.js +51 -109
- package/lib/github.js +27 -31
- package/lib/import.js +46 -67
- package/lib/index.js +88 -137
- package/lib/intake.js +23 -31
- package/lib/launcher.js +100 -167
- package/lib/lifecycle.js +11 -17
- package/lib/markdown.js +16 -23
- package/lib/metrics.js +23 -25
- package/lib/order.js +25 -28
- package/lib/outbound.js +25 -26
- package/lib/plan.js +23 -45
- package/lib/power.js +2 -2
- package/lib/progress-dump.js +17 -17
- package/lib/routes.js +86 -145
- package/lib/store.js +59 -78
- package/lib/sync.js +56 -98
- package/lib/templates.js +29 -29
- package/lib/time.js +8 -17
- package/lib/transitions.js +36 -57
- package/lib/webhook.js +16 -23
- package/lib/workflow-bridge.js +58 -58
- package/lib/worktree.js +58 -58
- package/package.json +1 -1
package/lib/board-tool.js
CHANGED
|
@@ -1,18 +1,7 @@
|
|
|
1
|
-
// Определение инструмента board_move — отдельно от обвязки cordis, чтобы
|
|
2
|
-
// проверяться без харнесса и без `@deepseek-ai/dsh-tools`.
|
|
3
1
|
//
|
|
4
|
-
// Форма объекта задана контрактом `defineTool` из dsh-tools, и она НЕ является
|
|
5
2
|
// JSON Schema:
|
|
6
3
|
//
|
|
7
|
-
// parameters — карта «имя -> схема значения», без корня `type: 'object'`;
|
|
8
|
-
// необязательность выражается ОТСУТСТВИЕМ `required: true`
|
|
9
|
-
// (`required: false`, `optional` и `nullable` отвергаются);
|
|
10
|
-
// output — обязателен: `defineTool` читает `options.output.render`
|
|
11
|
-
// безусловно, и без него падает не инструмент, а загрузка
|
|
12
|
-
// всего профиля.
|
|
13
4
|
//
|
|
14
|
-
// Схема объекта требует явного `additionalProperties`; здесь результат —
|
|
15
|
-
// строка, поэтому схема строковая.
|
|
16
5
|
|
|
17
6
|
import { COLUMN_ORDER as COLUMNS } from './config.js'
|
|
18
7
|
import { resolveTransition } from './transitions.js'
|
|
@@ -20,33 +9,23 @@ import { TOOL_FORBIDDEN_COLUMNS } from './commands.js'
|
|
|
20
9
|
import { parsePlan, applyPlan, serializePlan, planProgress, MAX_ITEMS } from './plan.js'
|
|
21
10
|
|
|
22
11
|
/**
|
|
23
|
-
*
|
|
12
|
+
* Columns accessible by the tool.
|
|
24
13
|
*
|
|
25
|
-
* `done`
|
|
26
|
-
* значение, которое она получит отказом, — приглашение его попробовать.
|
|
14
|
+
* `done` is omitted from ENUM to prevent the model from attempting it.
|
|
27
15
|
*/
|
|
28
16
|
const TOOL_COLUMNS = COLUMNS.filter((c) => !TOOL_FORBIDDEN_COLUMNS.includes(c))
|
|
29
17
|
|
|
30
18
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* dsh-tools переехал с `ctx.session` на `ctx.agent.session`. Читаем оба:
|
|
34
|
-
* промах здесь не роняет ничего, он молча превращает инструмент в отказ
|
|
35
|
-
* «за этой сессией нет карточки» — а такое ищут долго.
|
|
19
|
+
* Session ID from tool execution context.
|
|
20
|
+
* Reads both `ctx.session` and `ctx.agent.session` across dsh-tools versions.
|
|
36
21
|
*/
|
|
37
22
|
export function sessionIdFromExec(exec) {
|
|
38
23
|
return String(exec?.agent?.session?.id ?? exec?.session?.id ?? '')
|
|
39
24
|
}
|
|
40
25
|
|
|
41
26
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* Одна сессия может вести пачку. Пока задача одна — называть нечего. Как
|
|
45
|
-
* только их несколько, инструмент ОБЯЗАН сказать, какую двигает: догадка тут
|
|
46
|
-
* означает подвинутую не ту карточку, и заметят это нескоро.
|
|
47
|
-
*
|
|
48
|
-
* Ссылку принимаем в том виде, в каком агент её видит: `repo#номер` либо
|
|
49
|
-
* идентификатор карточки.
|
|
27
|
+
* Task linked to session context.
|
|
28
|
+
* Accepts `repo#number` or task ID.
|
|
50
29
|
*
|
|
51
30
|
* @returns {{task: object}|{error: string}}
|
|
52
31
|
*/
|
|
@@ -72,14 +51,14 @@ export function pickTask(store, exec, ref) {
|
|
|
72
51
|
return { task: found }
|
|
73
52
|
}
|
|
74
53
|
|
|
75
|
-
/**
|
|
54
|
+
/** Formatted task reference for agent. */
|
|
76
55
|
function nameOf(task) {
|
|
77
56
|
return task.repo && typeof task.issueNumber === 'number'
|
|
78
57
|
? `${task.repo}#${task.issueNumber}`
|
|
79
58
|
: task.id
|
|
80
59
|
}
|
|
81
60
|
|
|
82
|
-
/**
|
|
61
|
+
/** board_move tool definition for `defineTool`. */
|
|
83
62
|
export function boardMoveDefinition({ store, config }) {
|
|
84
63
|
return {
|
|
85
64
|
name: 'board_move',
|
|
@@ -110,7 +89,7 @@ export function boardMoveDefinition({ store, config }) {
|
|
|
110
89
|
if (picked.error !== undefined) return picked.error
|
|
111
90
|
const task = picked.task
|
|
112
91
|
|
|
113
|
-
//
|
|
92
|
+
// Workspace boundary verification (#216)
|
|
114
93
|
const claimBoundaries = typeof config === 'function' ? config()?.workspaceClaimBoundaries : config?.workspaceClaimBoundaries
|
|
115
94
|
if (claimBoundaries !== false && typeof task.workspaceId === 'string' && task.workspaceId.trim() !== '') {
|
|
116
95
|
const sessionWs = String(exec?.agent?.session?.meta?.workspaceId ?? exec?.session?.meta?.workspaceId ?? '').trim()
|
|
@@ -118,8 +97,7 @@ export function boardMoveDefinition({ store, config }) {
|
|
|
118
97
|
return `Cannot move card: task belongs to workspace "${task.workspaceId}", but current session belongs to workspace "${sessionWs}". Cross-workspace moves are restricted by workspaceClaimBoundaries.`
|
|
119
98
|
}
|
|
120
99
|
}
|
|
121
|
-
//
|
|
122
|
-
// мимо схемы, а завершение задачи не должно опираться на заявление.
|
|
100
|
+
// Model cannot transition directly to done without workflow validation
|
|
123
101
|
if (column === 'done' || TOOL_FORBIDDEN_COLUMNS.includes(column)) {
|
|
124
102
|
return 'The done column is a human-only acceptance boundary. A task is not finished by moving its card: move it to review for human acceptance; only a human can accept and move it to done.'
|
|
125
103
|
}
|
|
@@ -147,13 +125,7 @@ export function boardMoveDefinition({ store, config }) {
|
|
|
147
125
|
}
|
|
148
126
|
|
|
149
127
|
/**
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
* План получаем прямо от агента, а не разбором его сообщений: разбор — это
|
|
153
|
-
* гадание, а чужой `todo_list` завёл бы зависимость от соседнего плагина.
|
|
154
|
-
*
|
|
155
|
-
* Список пунктов необязателен. Агент публикует план один раз, а дальше двигает
|
|
156
|
-
* только указатель: гонять весь список ради одного числа незачем.
|
|
128
|
+
* board_plan tool definition for `defineTool`.
|
|
157
129
|
*/
|
|
158
130
|
export function boardPlanDefinition({ store }) {
|
|
159
131
|
return {
|
|
@@ -179,9 +151,7 @@ export function boardPlanDefinition({ store }) {
|
|
|
179
151
|
render: (_args, value) => [{ type: 'text', text: String(value) }],
|
|
180
152
|
},
|
|
181
153
|
async execute({ items, current }, exec) {
|
|
182
|
-
//
|
|
183
|
-
// задачей порознь. Поэтому пишем его всем задачам сессии — иначе на
|
|
184
|
-
// карточках второй и третьей плана не будет вовсе.
|
|
154
|
+
// Plan is shared across session tasks
|
|
185
155
|
const tasks = store.listTasksBySession(sessionIdFromExec(exec))
|
|
186
156
|
if (tasks.length === 0) return 'This session has no kanban task behind it.'
|
|
187
157
|
const task = tasks[0]
|
|
@@ -197,7 +167,7 @@ export function boardPlanDefinition({ store }) {
|
|
|
197
167
|
}
|
|
198
168
|
|
|
199
169
|
|
|
200
|
-
/**
|
|
170
|
+
/** board_checklist tool definition (#205) */
|
|
201
171
|
export function boardChecklistDefinition({ store }) {
|
|
202
172
|
return {
|
|
203
173
|
name: 'board_checklist',
|
|
@@ -248,7 +218,7 @@ export function boardChecklistDefinition({ store }) {
|
|
|
248
218
|
}
|
|
249
219
|
}
|
|
250
220
|
|
|
251
|
-
/**
|
|
221
|
+
/** board_report tool definition (#206) */
|
|
252
222
|
export function boardReportDefinition({ store }) {
|
|
253
223
|
return {
|
|
254
224
|
name: 'board_report',
|
|
@@ -308,7 +278,7 @@ export function boardReportDefinition({ store }) {
|
|
|
308
278
|
}
|
|
309
279
|
}
|
|
310
280
|
|
|
311
|
-
/**
|
|
281
|
+
/** board_comments tool definition (#208) */
|
|
312
282
|
export function boardCommentsDefinition({ store }) {
|
|
313
283
|
return {
|
|
314
284
|
name: 'board_comments',
|
|
@@ -336,7 +306,7 @@ export function boardCommentsDefinition({ store }) {
|
|
|
336
306
|
}
|
|
337
307
|
}
|
|
338
308
|
|
|
339
|
-
/**
|
|
309
|
+
/** board_comment_add tool definition (#208) */
|
|
340
310
|
export function boardCommentAddDefinition({ store }) {
|
|
341
311
|
return {
|
|
342
312
|
name: 'board_comment_add',
|
|
@@ -368,7 +338,7 @@ export function boardCommentAddDefinition({ store }) {
|
|
|
368
338
|
}
|
|
369
339
|
}
|
|
370
340
|
|
|
371
|
-
/**
|
|
341
|
+
/** board_decompose tool definition (#248) */
|
|
372
342
|
export function boardDecomposeDefinition({ store, gitea }) {
|
|
373
343
|
return {
|
|
374
344
|
name: 'board_decompose',
|
|
@@ -458,7 +428,7 @@ export function boardDecomposeDefinition({ store, gitea }) {
|
|
|
458
428
|
}
|
|
459
429
|
}
|
|
460
430
|
|
|
461
|
-
/**
|
|
431
|
+
/** board_checklist_item tool definition (#248) */
|
|
462
432
|
export function boardChecklistItemDefinition({ store }) {
|
|
463
433
|
return {
|
|
464
434
|
name: 'board_checklist_item',
|