kanbango 2.0.0 → 2.1.0
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/CHANGELOG.md +8 -0
- package/README.md +70 -275
- package/kanban.js +21 -1
- package/mcp-server.js +5 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,14 @@ All notable changes to kanbango will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.1.0] - 2026-07-09
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- `test_cases` field (array of strings) as a first-class task attribute in all views (planning, execution, full)
|
|
12
|
+
- `test_cases` parameter in `kanban_create` MCP tool input schema
|
|
13
|
+
- Patch support for `test_cases` in `kanban_update` MCP tool
|
|
14
|
+
- Markdown parsing of `## Test Cases` / `## Przypadki Testowe` sections
|
|
15
|
+
|
|
8
16
|
## [2.0.0] - 2026-07-07
|
|
9
17
|
|
|
10
18
|
### Added
|
package/README.md
CHANGED
|
@@ -1,267 +1,89 @@
|
|
|
1
1
|
# kanbango
|
|
2
2
|
|
|
3
|
-
JSON-first local Kanban board
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- 📊 Local Kanban board stored in JSON task files
|
|
8
|
-
- 🎨 Modern web GUI with drag-and-drop interface
|
|
9
|
-
- 🖥️ Full CLI support for automation and CI/CD
|
|
10
|
-
- 🤖 AI-friendly API (JSON output)
|
|
11
|
-
- 📁 Four columns: Active, Planned, Icebox, Done
|
|
12
|
-
- ✅ Subtasks with progress tracking
|
|
13
|
-
- 🏷️ Epic grouping
|
|
3
|
+
JSON-first local Kanban board for developers and AI agents — CLI, web GUI, and MCP server in one lightweight package.
|
|
14
4
|
|
|
15
5
|
## Installation
|
|
16
6
|
|
|
17
|
-
### Global (recommended)
|
|
7
|
+
### Global (recommended for CLI)
|
|
18
8
|
```bash
|
|
19
9
|
npm install -g kanbango
|
|
20
10
|
```
|
|
21
11
|
|
|
22
|
-
### Local
|
|
12
|
+
### Local per project (recommended for MCP)
|
|
23
13
|
```bash
|
|
24
14
|
npm install -D kanbango
|
|
25
15
|
```
|
|
26
16
|
|
|
27
|
-
###
|
|
17
|
+
### No install
|
|
28
18
|
```bash
|
|
29
19
|
npx kanbango --help
|
|
30
20
|
```
|
|
31
21
|
|
|
32
|
-
## NPM Package
|
|
33
|
-
|
|
34
|
-
- Package name: `kanbango`
|
|
35
|
-
- Binaries: `kanban`, `kanban-cmd`
|
|
36
|
-
- MCP server entrypoint: `mcp-server.js` (run via `npx kanbango mcp`)
|
|
37
|
-
|
|
38
|
-
## Requirements
|
|
39
|
-
|
|
40
|
-
- Node.js 16+
|
|
41
|
-
|
|
42
22
|
## Quick Start
|
|
43
23
|
|
|
44
24
|
```bash
|
|
45
|
-
# Initialize backlog
|
|
25
|
+
# Initialize backlog directories
|
|
46
26
|
kanban init
|
|
47
27
|
|
|
48
|
-
# Start web GUI
|
|
28
|
+
# Start web GUI at http://localhost:5500
|
|
49
29
|
kanban serve
|
|
50
30
|
|
|
51
|
-
# List all tasks
|
|
31
|
+
# List all tasks
|
|
52
32
|
kanban list --json
|
|
53
33
|
|
|
54
|
-
# Add a
|
|
55
|
-
kanban add "
|
|
34
|
+
# Add a task
|
|
35
|
+
kanban add "My task" --col planned --epic "Phase 1"
|
|
56
36
|
|
|
57
|
-
# Show
|
|
37
|
+
# Show details
|
|
58
38
|
kanban show PI-001
|
|
59
39
|
|
|
60
|
-
# Move
|
|
40
|
+
# Move between columns (active | planned | icebox | done)
|
|
61
41
|
kanban move PI-001 active
|
|
62
42
|
|
|
63
|
-
# Toggle subtask
|
|
43
|
+
# Toggle subtask completion
|
|
64
44
|
kanban toggle PI-001 0
|
|
65
45
|
```
|
|
66
46
|
|
|
67
|
-
|
|
47
|
+
### Columns
|
|
68
48
|
|
|
69
|
-
|
|
|
70
|
-
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
73
|
-
| `
|
|
74
|
-
| `
|
|
75
|
-
| `kanban show <ID>` | Show task details |
|
|
76
|
-
| `kanban add <TITLE>` | Add new task |
|
|
77
|
-
| `kanban move <ID> <COL>` | Move task to column |
|
|
78
|
-
| `kanban toggle <ID> <IDX>` | Toggle subtask |
|
|
79
|
-
|
|
80
|
-
## Columns
|
|
81
|
-
|
|
82
|
-
- `active` — In progress (max 1-2 tasks)
|
|
83
|
-
- `planned` — Planned for implementation
|
|
84
|
-
- `icebox` — Frozen / nice-to-have
|
|
85
|
-
- `done` — Completed
|
|
49
|
+
| Column | Purpose |
|
|
50
|
+
|--------|---------|
|
|
51
|
+
| `active` | In progress (keep to 1–2 tasks) |
|
|
52
|
+
| `planned` | Ready to implement |
|
|
53
|
+
| `icebox` | Nice-to-have / frozen |
|
|
54
|
+
| `done` | Completed |
|
|
86
55
|
|
|
87
56
|
## Data Structure
|
|
88
57
|
|
|
89
|
-
Tasks are
|
|
58
|
+
Tasks are JSON files in `backlog/<column>/`:
|
|
90
59
|
|
|
91
60
|
```json
|
|
92
61
|
{
|
|
93
|
-
"id": "PI-001-feature
|
|
94
|
-
"title": "Feature
|
|
62
|
+
"id": "PI-001-my-feature",
|
|
63
|
+
"title": "My Feature",
|
|
95
64
|
"column": "planned",
|
|
96
65
|
"epic_group": "Phase 1",
|
|
97
|
-
"created": "2026-07-
|
|
98
|
-
"description": "High-level context
|
|
99
|
-
"specs": "Technical details
|
|
100
|
-
"acceptance_criteria": [
|
|
101
|
-
"First condition",
|
|
102
|
-
"Second condition"
|
|
103
|
-
],
|
|
66
|
+
"created": "2026-07-08",
|
|
67
|
+
"description": "High-level context.",
|
|
68
|
+
"specs": "Technical details.",
|
|
69
|
+
"acceptance_criteria": ["Works as expected"],
|
|
104
70
|
"subtasks": [
|
|
105
|
-
{
|
|
106
|
-
|
|
107
|
-
"text": "First subtask",
|
|
108
|
-
"done": false,
|
|
109
|
-
"description": "Execution details for the subtask"
|
|
110
|
-
}
|
|
111
|
-
],
|
|
112
|
-
"notes": "Optional freeform notes"
|
|
71
|
+
{ "id": "st-1", "text": "First step", "done": false }
|
|
72
|
+
]
|
|
113
73
|
}
|
|
114
74
|
```
|
|
115
75
|
|
|
116
|
-
##
|
|
117
|
-
|
|
118
|
-
The `kanban-cmd` command provides simplified JSON output for AI agents:
|
|
119
|
-
|
|
120
|
-
```bash
|
|
121
|
-
# For AI: always use JSON output
|
|
122
|
-
kanban-cmd list
|
|
123
|
-
|
|
124
|
-
# Filter by column
|
|
125
|
-
kanban-cmd list --col active
|
|
126
|
-
|
|
127
|
-
# Show task details
|
|
128
|
-
kanban-cmd show PI-001
|
|
129
|
-
|
|
130
|
-
# Add task (AI-friendly)
|
|
131
|
-
kanban-cmd add "New task" --col planned --epic "Phase 1"
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### JSON Output Format
|
|
135
|
-
|
|
136
|
-
```json
|
|
137
|
-
[
|
|
138
|
-
{
|
|
139
|
-
"id": "PI-001-feature-title",
|
|
140
|
-
"title": "Feature Title",
|
|
141
|
-
"column": "planned",
|
|
142
|
-
"epic_group": "Phase 1",
|
|
143
|
-
"created": "2026-07-07",
|
|
144
|
-
"description": "High-level context and implementation plan.",
|
|
145
|
-
"specs": "Technical details and constraints.",
|
|
146
|
-
"acceptance_criteria": [
|
|
147
|
-
"First condition"
|
|
148
|
-
],
|
|
149
|
-
"tasks": [
|
|
150
|
-
{
|
|
151
|
-
"id": "st-1",
|
|
152
|
-
"done": false,
|
|
153
|
-
"text": "First subtask",
|
|
154
|
-
"description": "Execution details for the subtask"
|
|
155
|
-
}
|
|
156
|
-
]
|
|
157
|
-
}
|
|
158
|
-
]
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
## MCP Task Views
|
|
162
|
-
|
|
163
|
-
`kanban_read` supports compact response shaping so agents can avoid reading the whole task every time.
|
|
164
|
-
|
|
165
|
-
```json
|
|
166
|
-
{
|
|
167
|
-
"operation": "show",
|
|
168
|
-
"task_id": "PI-001-feature-title",
|
|
169
|
-
"view": "planning"
|
|
170
|
-
}
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
Supported views:
|
|
174
|
-
|
|
175
|
-
- `summary` - `id`, `title`, `column`, `epic_group`, `created`, `progress`
|
|
176
|
-
- `planning` - summary + `description`, `specs`, `acceptance_criteria`
|
|
177
|
-
- `execution` - planning + `subtasks`
|
|
178
|
-
- `full` - execution + `notes`
|
|
179
|
-
|
|
180
|
-
You can also request explicit fields:
|
|
181
|
-
|
|
182
|
-
```json
|
|
183
|
-
{
|
|
184
|
-
"operation": "show",
|
|
185
|
-
"task_id": "PI-001-feature-title",
|
|
186
|
-
"fields": ["title", "description", "acceptance_criteria"]
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
`kanban_update` supports patch-style updates and compact responses:
|
|
191
|
-
|
|
192
|
-
```json
|
|
193
|
-
{
|
|
194
|
-
"operation": "update",
|
|
195
|
-
"task_id": "PI-001-feature-title",
|
|
196
|
-
"patch": {
|
|
197
|
-
"description": "Updated plan",
|
|
198
|
-
"acceptance_criteria": ["OAuth works"]
|
|
199
|
-
},
|
|
200
|
-
"return": "summary"
|
|
201
|
-
}
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
Errors are returned as structured JSON:
|
|
205
|
-
|
|
206
|
-
```json
|
|
207
|
-
{
|
|
208
|
-
"error": {
|
|
209
|
-
"code": "TASK_NOT_FOUND",
|
|
210
|
-
"message": "Task PI-999-missing was not found",
|
|
211
|
-
"hint": "Call kanban_read with operation=list to discover valid task ids",
|
|
212
|
-
"details": {
|
|
213
|
-
"task_id": "PI-999-missing"
|
|
214
|
-
},
|
|
215
|
-
"retryable": false
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
## Web GUI
|
|
221
|
-
|
|
222
|
-
Start the web interface:
|
|
223
|
-
```bash
|
|
224
|
-
kanban serve 5500
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
Features:
|
|
228
|
-
- Swimlanes grouped by epic
|
|
229
|
-
- Drag-and-drop between columns
|
|
230
|
-
- Inline editing
|
|
231
|
-
- Real-time subtask checkboxes
|
|
232
|
-
- Progress tracking
|
|
233
|
-
|
|
234
|
-
## Directory Structure
|
|
76
|
+
## MCP Server (for Claude Code, OpenCode, Cursor)
|
|
235
77
|
|
|
236
|
-
|
|
237
|
-
backlog/
|
|
238
|
-
├── active/ # Tasks in progress
|
|
239
|
-
├── planned/ # Planned tasks
|
|
240
|
-
├── icebox/ # Frozen tasks
|
|
241
|
-
└── done/ # Completed tasks
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
## API for AI Agents
|
|
245
|
-
|
|
246
|
-
See [API.md](API.md) for detailed API function definitions.
|
|
247
|
-
|
|
248
|
-
## MCP Server
|
|
249
|
-
|
|
250
|
-
This package includes a Model Context Protocol (MCP) server for integration with MCP-compatible clients.
|
|
251
|
-
|
|
252
|
-
### Using the MCP server
|
|
78
|
+
Run the MCP server to let AI agents read / create / update your board:
|
|
253
79
|
|
|
254
80
|
```bash
|
|
255
|
-
# Run the MCP server directly
|
|
256
|
-
npm run mcp
|
|
257
|
-
|
|
258
|
-
# Or using npx
|
|
259
81
|
npx kanbango mcp
|
|
260
82
|
```
|
|
261
83
|
|
|
262
|
-
###
|
|
84
|
+
### Give it to your agent
|
|
263
85
|
|
|
264
|
-
|
|
86
|
+
Add this to your MCP client config (`.mcp.json`, `opencode.json`, or Claude Desktop config):
|
|
265
87
|
|
|
266
88
|
```json
|
|
267
89
|
{
|
|
@@ -274,87 +96,60 @@ For MCP clients, add this to your configuration:
|
|
|
274
96
|
}
|
|
275
97
|
```
|
|
276
98
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
Install locally in the project so each repo controls its own MCP version:
|
|
99
|
+
Or generate the config files automatically:
|
|
280
100
|
|
|
281
101
|
```bash
|
|
282
|
-
npm install -D kanbango
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
Then point MCP to the local package:
|
|
286
|
-
|
|
287
|
-
```json
|
|
288
|
-
{
|
|
289
|
-
"mcpServers": {
|
|
290
|
-
"kanbango": {
|
|
291
|
-
"command": "node",
|
|
292
|
-
"args": ["./node_modules/kanbango/mcp-server.js"]
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
If you prefer `npx`, you can still use it, but versioning is less explicit:
|
|
299
|
-
|
|
300
|
-
```json
|
|
301
|
-
{
|
|
302
|
-
"mcpServers": {
|
|
303
|
-
"kanbango": {
|
|
304
|
-
"command": "npx",
|
|
305
|
-
"args": ["kanbango", "mcp"]
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
### MCP Project Automation (Claude Code + OpenCode)
|
|
312
|
-
|
|
313
|
-
Generate project configs automatically (creates `.mcp.json` and `opencode.json` in the current folder):
|
|
314
|
-
|
|
315
|
-
```bash
|
|
316
|
-
# Local install (recommended)
|
|
317
102
|
npx kanbango mcp-init
|
|
103
|
+
```
|
|
318
104
|
|
|
319
|
-
|
|
320
|
-
npx kanbango mcp-init --npx
|
|
105
|
+
### What the agent can do
|
|
321
106
|
|
|
322
|
-
|
|
323
|
-
npx kanbango mcp-init --claude
|
|
107
|
+
Once connected, your agent gets access to these tools:
|
|
324
108
|
|
|
325
|
-
|
|
326
|
-
|
|
109
|
+
| Tool | What it does |
|
|
110
|
+
|------|-------------|
|
|
111
|
+
| `kanban_read` | List tasks, filter by column/epic, show details |
|
|
112
|
+
| `kanban_create` | Add new tasks |
|
|
113
|
+
| `kanban_update` | Move, edit, toggle subtasks |
|
|
114
|
+
| `kanban_gui_start` | Start web GUI from the agent |
|
|
115
|
+
| `kanban_gui_stop` | Stop web GUI |
|
|
116
|
+
| `kanban_gui_status` | Check if GUI is running |
|
|
327
117
|
|
|
328
|
-
|
|
329
|
-
npx kanbango mcp-init --force
|
|
330
|
-
```
|
|
118
|
+
Your agent stays in sync with your real board — every change is persisted as JSON files.
|
|
331
119
|
|
|
332
|
-
|
|
120
|
+
## CLI Reference
|
|
333
121
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
122
|
+
| Command | Description |
|
|
123
|
+
|---------|-------------|
|
|
124
|
+
| `kanban init` | Create backlog directory structure |
|
|
125
|
+
| `kanban serve [PORT]` | Start web GUI (default 5500) |
|
|
126
|
+
| `kanban list [--col <col>] [--json]` | List tasks |
|
|
127
|
+
| `kanban show <ID>` | Show task details |
|
|
128
|
+
| `kanban add <TITLE>` | Add a new task |
|
|
129
|
+
| `kanban move <ID> <COL>` | Move task |
|
|
130
|
+
| `kanban toggle <ID> <IDX>` | Toggle subtask |
|
|
131
|
+
| `kanban mcp-init` | Generate MCP config files |
|
|
340
132
|
|
|
341
|
-
##
|
|
133
|
+
## Web GUI
|
|
342
134
|
|
|
343
135
|
```bash
|
|
344
|
-
|
|
345
|
-
|
|
136
|
+
kanban serve
|
|
137
|
+
```
|
|
138
|
+
- Swimlanes grouped by epic
|
|
139
|
+
- Drag-and-drop between columns
|
|
140
|
+
- Inline editing and subtask checkboxes
|
|
346
141
|
|
|
347
|
-
|
|
348
|
-
npm test
|
|
142
|
+
## Using as a Node.js module
|
|
349
143
|
|
|
350
|
-
|
|
351
|
-
|
|
144
|
+
```js
|
|
145
|
+
const kanban = require('kanbango');
|
|
146
|
+
const tasks = await kanban.allEpics();
|
|
352
147
|
```
|
|
353
148
|
|
|
354
|
-
##
|
|
149
|
+
## Requirements
|
|
355
150
|
|
|
356
|
-
|
|
151
|
+
Node.js 16+
|
|
357
152
|
|
|
358
|
-
##
|
|
153
|
+
## License
|
|
359
154
|
|
|
360
|
-
|
|
155
|
+
MIT
|
package/kanban.js
CHANGED
|
@@ -20,7 +20,8 @@ const VIEW_FIELDS = {
|
|
|
20
20
|
'progress',
|
|
21
21
|
'description',
|
|
22
22
|
'specs',
|
|
23
|
-
'acceptance_criteria'
|
|
23
|
+
'acceptance_criteria',
|
|
24
|
+
'test_cases'
|
|
24
25
|
],
|
|
25
26
|
execution: [
|
|
26
27
|
'id',
|
|
@@ -32,6 +33,7 @@ const VIEW_FIELDS = {
|
|
|
32
33
|
'description',
|
|
33
34
|
'specs',
|
|
34
35
|
'acceptance_criteria',
|
|
36
|
+
'test_cases',
|
|
35
37
|
'subtasks'
|
|
36
38
|
],
|
|
37
39
|
full: [
|
|
@@ -44,6 +46,7 @@ const VIEW_FIELDS = {
|
|
|
44
46
|
'description',
|
|
45
47
|
'specs',
|
|
46
48
|
'acceptance_criteria',
|
|
49
|
+
'test_cases',
|
|
47
50
|
'subtasks',
|
|
48
51
|
'notes'
|
|
49
52
|
]
|
|
@@ -110,6 +113,7 @@ function normalizeTask(task) {
|
|
|
110
113
|
description: normalizeString(task.description),
|
|
111
114
|
specs: normalizeString(task.specs),
|
|
112
115
|
acceptance_criteria: normalizeStringArray(task.acceptance_criteria),
|
|
116
|
+
test_cases: normalizeStringArray(task.test_cases),
|
|
113
117
|
subtasks: normalizeSubtasks(task.subtasks || task.tasks),
|
|
114
118
|
notes: normalizeString(task.notes)
|
|
115
119
|
};
|
|
@@ -128,6 +132,7 @@ function serializeTask(task) {
|
|
|
128
132
|
description: normalized.description,
|
|
129
133
|
specs: normalized.specs,
|
|
130
134
|
acceptance_criteria: normalized.acceptance_criteria,
|
|
135
|
+
test_cases: normalized.test_cases,
|
|
131
136
|
subtasks: normalized.subtasks,
|
|
132
137
|
notes: normalized.notes
|
|
133
138
|
};
|
|
@@ -227,6 +232,7 @@ async function parseMarkdownTask(filePath, column) {
|
|
|
227
232
|
description: extractSection(text, ['Opis', 'Description']),
|
|
228
233
|
specs: extractSection(text, ['Specs', 'Specyfikacja']),
|
|
229
234
|
acceptance_criteria: parseListSection(extractSection(text, ['Acceptance Criteria', 'Kryteria Akceptacji'])),
|
|
235
|
+
test_cases: parseListSection(extractSection(text, ['Test Cases', 'Przypadki Testowe'])),
|
|
230
236
|
subtasks,
|
|
231
237
|
notes: extractSection(text, ['Notes'])
|
|
232
238
|
});
|
|
@@ -471,6 +477,7 @@ async function doCreate(title, column = 'planned', epicGroup = '—', extra = {}
|
|
|
471
477
|
description: extra.description,
|
|
472
478
|
specs: extra.specs,
|
|
473
479
|
acceptance_criteria: extra.acceptance_criteria,
|
|
480
|
+
test_cases: extra.test_cases,
|
|
474
481
|
subtasks: extra.subtasks,
|
|
475
482
|
notes: extra.notes
|
|
476
483
|
});
|
|
@@ -530,6 +537,19 @@ async function updateTask(taskId, patch) {
|
|
|
530
537
|
}
|
|
531
538
|
next.acceptance_criteria = patch.acceptance_criteria;
|
|
532
539
|
}
|
|
540
|
+
if (patch.test_cases !== undefined) {
|
|
541
|
+
if (!Array.isArray(patch.test_cases)) {
|
|
542
|
+
throw createKanbanError(
|
|
543
|
+
'VALIDATION_ERROR',
|
|
544
|
+
'test_cases must be an array of strings',
|
|
545
|
+
'Send test_cases as an array',
|
|
546
|
+
{ field: 'test_cases' },
|
|
547
|
+
false,
|
|
548
|
+
400
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
next.test_cases = patch.test_cases;
|
|
552
|
+
}
|
|
533
553
|
if (patch.subtasks !== undefined || patch.tasks !== undefined) {
|
|
534
554
|
const subtasks = patch.subtasks !== undefined ? patch.subtasks : patch.tasks;
|
|
535
555
|
if (!Array.isArray(subtasks)) {
|
package/mcp-server.js
CHANGED
|
@@ -219,6 +219,11 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
219
219
|
description: 'What must be true for the task to be complete',
|
|
220
220
|
items: { type: 'string' }
|
|
221
221
|
},
|
|
222
|
+
test_cases: {
|
|
223
|
+
type: 'array',
|
|
224
|
+
description: 'Test case scenarios verifying acceptance criteria',
|
|
225
|
+
items: { type: 'string' }
|
|
226
|
+
},
|
|
222
227
|
subtasks: {
|
|
223
228
|
type: 'array',
|
|
224
229
|
description: 'Optional subtask list',
|