@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 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
- /** Определение board_move, готовое к передаче в `defineTool`. */
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
- // Проверка границ владения воркспейсом (#216)
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
- // Перечисление уже не предлагает `done`, но модель может прислать его
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
- * Определение board_plan, готовое к передаче в `defineTool`.
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
- /** Определение board_checklist (#205) */
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
- /** Определение board_report (#206) */
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
- /** Определение board_comments (#208) */
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
- /** Определение board_comment_add (#208) */
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
- /** Определение board_decompose (#248) */
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
- /** Определение board_checklist_item (#248) */
431
+ /** board_checklist_item tool definition (#248) */
462
432
  export function boardChecklistItemDefinition({ store }) {
463
433
  return {
464
434
  name: 'board_checklist_item',