@specforge/mcp 3.3.8 → 3.5.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/dist/cli/commands/set-status.js +1 -1
- package/dist/cli/commands/set-status.js.map +1 -1
- package/dist/cli/commands/specs.types.d.ts +1 -1
- package/dist/cli/commands/specs.types.d.ts.map +1 -1
- package/dist/cli/commands/specs.types.js +6 -0
- package/dist/cli/commands/specs.types.js.map +1 -1
- package/dist/lib/format.d.ts +0 -32
- package/dist/lib/format.d.ts.map +1 -1
- package/dist/lib/format.js +0 -40
- package/dist/lib/format.js.map +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +6 -17
- package/dist/server.js.map +1 -1
- package/dist/tools/core/blueprint.d.ts.map +1 -1
- package/dist/tools/core/blueprint.js +4 -34
- package/dist/tools/core/blueprint.js.map +1 -1
- package/dist/tools/core/dependency.d.ts.map +1 -1
- package/dist/tools/core/dependency.js +0 -2
- package/dist/tools/core/dependency.js.map +1 -1
- package/dist/tools/core/epic.d.ts.map +1 -1
- package/dist/tools/core/epic.js +0 -2
- package/dist/tools/core/epic.js.map +1 -1
- package/dist/tools/core/lookup.d.ts.map +1 -1
- package/dist/tools/core/lookup.js +0 -6
- package/dist/tools/core/lookup.js.map +1 -1
- package/dist/tools/core/pattern.d.ts.map +1 -1
- package/dist/tools/core/pattern.js +0 -2
- package/dist/tools/core/pattern.js.map +1 -1
- package/dist/tools/core/project.d.ts.map +1 -1
- package/dist/tools/core/project.js +0 -2
- package/dist/tools/core/project.js.map +1 -1
- package/dist/tools/core/session.d.ts.map +1 -1
- package/dist/tools/core/session.js +0 -3
- package/dist/tools/core/session.js.map +1 -1
- package/dist/tools/core/specification.d.ts.map +1 -1
- package/dist/tools/core/specification.js +0 -1
- package/dist/tools/core/specification.js.map +1 -1
- package/dist/tools/core/ticket.d.ts.map +1 -1
- package/dist/tools/core/ticket.js +24 -1
- package/dist/tools/core/ticket.js.map +1 -1
- package/dist/tools/core/types.d.ts +0 -1
- package/dist/tools/core/types.d.ts.map +1 -1
- package/dist/tools/core/workflow-guide.d.ts.map +1 -1
- package/dist/tools/core/workflow-guide.js +3 -1
- package/dist/tools/core/workflow-guide.js.map +1 -1
- package/dist/tools/core/workflow.d.ts.map +1 -1
- package/dist/tools/core/workflow.js +0 -2
- package/dist/tools/core/workflow.js.map +1 -1
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +212 -1423
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/package.json +1 -1
package/dist/tools/index.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* - Search: Search, find by file/tag, find related
|
|
15
15
|
* - Git: Link commits and PRs, get linked items
|
|
16
16
|
*/
|
|
17
|
-
import { ValidationError, ApiError, validateToolArgs, formatMCPError, transformError,
|
|
17
|
+
import { ValidationError, ApiError, validateToolArgs, formatMCPError, transformError, } from '../validation/index.js';
|
|
18
18
|
import { resolvePatternsWithCache, getPatternOverrides, flattenCodeStandards, } from '../patterns/index.js';
|
|
19
19
|
import { getResponseModeFromArgs, formatWriteResponse, } from '../lib/response.js';
|
|
20
20
|
import { createFeedbackHandler } from './core/feedback.js';
|
|
@@ -33,75 +33,6 @@ import { findProjectRoot } from '../cli/config/paths.js';
|
|
|
33
33
|
*
|
|
34
34
|
* @returns Array of tool definitions
|
|
35
35
|
*/
|
|
36
|
-
/**
|
|
37
|
-
* Format parameter definition for read operations
|
|
38
|
-
* Allows AI agents to request JSON or TOON-formatted responses
|
|
39
|
-
*/
|
|
40
|
-
const FORMAT_PARAMETER = {
|
|
41
|
-
type: 'string',
|
|
42
|
-
enum: ['json', 'toon'],
|
|
43
|
-
description: 'Output format. TOON (default) provides ~44% token reduction. Use "json" for structured data processing.',
|
|
44
|
-
default: 'toon',
|
|
45
|
-
};
|
|
46
|
-
/**
|
|
47
|
-
* List of read operation tool names that support the format parameter
|
|
48
|
-
* Write operations (create_*, update_*, report_*, etc.) are excluded
|
|
49
|
-
*/
|
|
50
|
-
const READ_TOOL_NAMES = new Set([
|
|
51
|
-
// Project operations
|
|
52
|
-
'list_projects',
|
|
53
|
-
'get_project',
|
|
54
|
-
'lookup_project',
|
|
55
|
-
// Specification operations
|
|
56
|
-
'list_specifications',
|
|
57
|
-
'get_specification',
|
|
58
|
-
'lookup_specification',
|
|
59
|
-
// Blueprint operations
|
|
60
|
-
'blueprint',
|
|
61
|
-
// Epic operations
|
|
62
|
-
'list_epics',
|
|
63
|
-
'get_epic',
|
|
64
|
-
'lookup_epic',
|
|
65
|
-
// Ticket operations
|
|
66
|
-
'list_tickets',
|
|
67
|
-
'get_ticket',
|
|
68
|
-
'lookup_ticket',
|
|
69
|
-
'lookup_tickets_by_status',
|
|
70
|
-
// Dependency operations
|
|
71
|
-
'get_dependency_tree',
|
|
72
|
-
'check_circular_dependencies',
|
|
73
|
-
// Context operations
|
|
74
|
-
'get_implementation_context',
|
|
75
|
-
'get_next_actionable_tickets',
|
|
76
|
-
'get_blocked_tickets',
|
|
77
|
-
'get_critical_path',
|
|
78
|
-
'get_patterns',
|
|
79
|
-
// Status & Analytics
|
|
80
|
-
'get_report',
|
|
81
|
-
// Search operations
|
|
82
|
-
'search_tickets',
|
|
83
|
-
// Agent Teams (read operations)
|
|
84
|
-
'get_epic_dependency_graph',
|
|
85
|
-
'get_implementation_plan',
|
|
86
|
-
// Review operations
|
|
87
|
-
'review_planning',
|
|
88
|
-
'review_implementation',
|
|
89
|
-
]);
|
|
90
|
-
/**
|
|
91
|
-
* Add format parameter to a tool's input schema
|
|
92
|
-
*/
|
|
93
|
-
function addFormatParameter(tool) {
|
|
94
|
-
return {
|
|
95
|
-
...tool,
|
|
96
|
-
inputSchema: {
|
|
97
|
-
...tool.inputSchema,
|
|
98
|
-
properties: {
|
|
99
|
-
...tool.inputSchema.properties,
|
|
100
|
-
format: FORMAT_PARAMETER,
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
36
|
export function getTools() {
|
|
106
37
|
const tools = [
|
|
107
38
|
// ========================================================================
|
|
@@ -140,11 +71,6 @@ export function getTools() {
|
|
|
140
71
|
type: 'string',
|
|
141
72
|
description: 'Project name to search for (partial match, case-insensitive)',
|
|
142
73
|
},
|
|
143
|
-
format: {
|
|
144
|
-
type: 'string',
|
|
145
|
-
enum: ['json', 'toon'],
|
|
146
|
-
description: 'Output format (default: json)',
|
|
147
|
-
},
|
|
148
74
|
},
|
|
149
75
|
required: ['name'],
|
|
150
76
|
},
|
|
@@ -214,40 +140,6 @@ export function getTools() {
|
|
|
214
140
|
required: ['projectId'],
|
|
215
141
|
},
|
|
216
142
|
},
|
|
217
|
-
{
|
|
218
|
-
name: 'get_specification',
|
|
219
|
-
description: `Get specification with optional summary mode or full details.
|
|
220
|
-
|
|
221
|
-
Use summary: true for minimal response (~70 tokens) with key fields only (id, title, status, priority, epicCount, ticketCount, completedTicketCount).
|
|
222
|
-
|
|
223
|
-
Optional includes (ignored when summary=true):
|
|
224
|
-
- 'status': Progress, ticket counts, blockers (replaces get_specification_status)
|
|
225
|
-
- 'epics': List of epics with summary data
|
|
226
|
-
- 'patterns': Tech stack, code patterns, naming conventions`,
|
|
227
|
-
inputSchema: {
|
|
228
|
-
type: 'object',
|
|
229
|
-
properties: {
|
|
230
|
-
specificationId: {
|
|
231
|
-
type: 'string',
|
|
232
|
-
description: 'The ID of the specification to retrieve',
|
|
233
|
-
},
|
|
234
|
-
summary: {
|
|
235
|
-
type: 'boolean',
|
|
236
|
-
description: 'Return minimal summary fields only (~70 tokens vs ~600 full). Ignores include parameter when true. Default: false',
|
|
237
|
-
default: false,
|
|
238
|
-
},
|
|
239
|
-
include: {
|
|
240
|
-
type: 'array',
|
|
241
|
-
items: {
|
|
242
|
-
type: 'string',
|
|
243
|
-
enum: ['status', 'epics', 'patterns'],
|
|
244
|
-
},
|
|
245
|
-
description: 'Optional data to include in response (ignored when summary=true)',
|
|
246
|
-
},
|
|
247
|
-
},
|
|
248
|
-
required: ['specificationId'],
|
|
249
|
-
},
|
|
250
|
-
},
|
|
251
143
|
{
|
|
252
144
|
name: 'lookup_specification',
|
|
253
145
|
description: 'Fast specification lookup by title. Returns minimal data (id, title, status, epicCount, ticketCount) for token efficiency.',
|
|
@@ -262,11 +154,6 @@ Optional includes (ignored when summary=true):
|
|
|
262
154
|
type: 'string',
|
|
263
155
|
description: 'Specification title to search for (partial match, case-insensitive)',
|
|
264
156
|
},
|
|
265
|
-
format: {
|
|
266
|
-
type: 'string',
|
|
267
|
-
enum: ['json', 'toon'],
|
|
268
|
-
description: 'Output format (default: json)',
|
|
269
|
-
},
|
|
270
157
|
},
|
|
271
158
|
required: ['projectId', 'title'],
|
|
272
159
|
},
|
|
@@ -276,7 +163,7 @@ Optional includes (ignored when summary=true):
|
|
|
276
163
|
// ========================================================================
|
|
277
164
|
{
|
|
278
165
|
name: 'list_epics',
|
|
279
|
-
description: 'List epics for a specification with optional status and field filters. Supports pagination with limit/offset. Use fields to select specific fields and reduce token usage.',
|
|
166
|
+
description: 'List epics for a specification with optional status and field filters. Supports pagination with limit/offset. Use fields to select specific fields and reduce token usage. During active planning sessions, field selection and result limits are automatically enforced.',
|
|
280
167
|
inputSchema: {
|
|
281
168
|
type: 'object',
|
|
282
169
|
properties: {
|
|
@@ -330,39 +217,6 @@ Optional includes (ignored when summary=true):
|
|
|
330
217
|
required: ['specificationId'],
|
|
331
218
|
},
|
|
332
219
|
},
|
|
333
|
-
{
|
|
334
|
-
name: 'get_epic',
|
|
335
|
-
description: `Get epic with optional summary mode or full details.
|
|
336
|
-
|
|
337
|
-
Use summary: true for minimal response (~80 tokens) with key fields only (id, epicNumber, title, status, objective, ticketCount, completedTicketCount).
|
|
338
|
-
|
|
339
|
-
Optional includes (ignored when summary=true):
|
|
340
|
-
- 'status': Progress percentage, ticket counts, active tickets (replaces get_epic_status)
|
|
341
|
-
- 'tickets': List of tickets with summary data`,
|
|
342
|
-
inputSchema: {
|
|
343
|
-
type: 'object',
|
|
344
|
-
properties: {
|
|
345
|
-
epicId: {
|
|
346
|
-
type: 'string',
|
|
347
|
-
description: 'The ID of the epic to retrieve',
|
|
348
|
-
},
|
|
349
|
-
summary: {
|
|
350
|
-
type: 'boolean',
|
|
351
|
-
description: 'Return minimal summary fields only (~80 tokens vs ~400 full). Ignores include parameter when true. Default: false',
|
|
352
|
-
default: false,
|
|
353
|
-
},
|
|
354
|
-
include: {
|
|
355
|
-
type: 'array',
|
|
356
|
-
items: {
|
|
357
|
-
type: 'string',
|
|
358
|
-
enum: ['status', 'tickets'],
|
|
359
|
-
},
|
|
360
|
-
description: 'Optional data to include in response (ignored when summary=true)',
|
|
361
|
-
},
|
|
362
|
-
},
|
|
363
|
-
required: ['epicId'],
|
|
364
|
-
},
|
|
365
|
-
},
|
|
366
220
|
{
|
|
367
221
|
name: 'lookup_epic',
|
|
368
222
|
description: "Fast epic lookup by number or title. Returns minimal data (id, number, title, status, ticketCount). Use 'number' for exact match, 'title' for partial match.",
|
|
@@ -381,11 +235,6 @@ Optional includes (ignored when summary=true):
|
|
|
381
235
|
type: 'string',
|
|
382
236
|
description: 'Epic title for partial match lookup',
|
|
383
237
|
},
|
|
384
|
-
format: {
|
|
385
|
-
type: 'string',
|
|
386
|
-
enum: ['json', 'toon'],
|
|
387
|
-
description: 'Output format (default: json)',
|
|
388
|
-
},
|
|
389
238
|
},
|
|
390
239
|
required: ['specificationId'],
|
|
391
240
|
},
|
|
@@ -395,7 +244,7 @@ Optional includes (ignored when summary=true):
|
|
|
395
244
|
// ========================================================================
|
|
396
245
|
{
|
|
397
246
|
name: 'list_tickets',
|
|
398
|
-
description: 'List tickets for an epic with optional status and field filters. Supports pagination with limit/offset. Use fields to select specific fields and reduce token usage. Use include: ["statusReason"] to get reasons why pending tickets are blocked.',
|
|
247
|
+
description: 'List tickets for an epic with optional status and field filters. Supports pagination with limit/offset. Use fields to select specific fields and reduce token usage. Use include: ["statusReason"] to get reasons why pending tickets are blocked. During active planning sessions, field selection and result limits are automatically enforced.',
|
|
399
248
|
inputSchema: {
|
|
400
249
|
type: 'object',
|
|
401
250
|
properties: {
|
|
@@ -466,44 +315,6 @@ Optional includes (ignored when summary=true):
|
|
|
466
315
|
required: ['epicId'],
|
|
467
316
|
},
|
|
468
317
|
},
|
|
469
|
-
{
|
|
470
|
-
name: 'get_ticket',
|
|
471
|
-
description: `Get ticket with optional summary mode or full details.
|
|
472
|
-
|
|
473
|
-
Use summary: true for minimal response (~100 tokens) with key fields only (id, ticketNumber, title, status, complexity, estimatedHours, priority).
|
|
474
|
-
|
|
475
|
-
For full details, statusReason is auto-included for pending tickets explaining why the ticket is blocked.
|
|
476
|
-
|
|
477
|
-
Optional includes (ignored when summary=true):
|
|
478
|
-
- 'dependencies': Tickets this blocks and is blocked by (replaces get_ticket_dependencies)
|
|
479
|
-
- 'testStatus': Test results and history (replaces get_ticket_test_status)
|
|
480
|
-
- 'commits': Linked git commits (replaces get_ticket_commits)
|
|
481
|
-
- 'prs': Linked pull requests (replaces get_ticket_prs)
|
|
482
|
-
- 'statusReason': Why ticket is pending (auto-included for pending tickets)`,
|
|
483
|
-
inputSchema: {
|
|
484
|
-
type: 'object',
|
|
485
|
-
properties: {
|
|
486
|
-
ticketId: {
|
|
487
|
-
type: 'string',
|
|
488
|
-
description: 'The ID of the ticket to retrieve',
|
|
489
|
-
},
|
|
490
|
-
summary: {
|
|
491
|
-
type: 'boolean',
|
|
492
|
-
description: 'Return minimal summary fields only (~100 tokens vs ~500 full). Ignores include parameter when true. Default: false',
|
|
493
|
-
default: false,
|
|
494
|
-
},
|
|
495
|
-
include: {
|
|
496
|
-
type: 'array',
|
|
497
|
-
items: {
|
|
498
|
-
type: 'string',
|
|
499
|
-
enum: ['dependencies', 'testStatus', 'commits', 'prs', 'statusReason'],
|
|
500
|
-
},
|
|
501
|
-
description: 'Additional data to include (ignored when summary=true). statusReason is auto-included for pending tickets.',
|
|
502
|
-
},
|
|
503
|
-
},
|
|
504
|
-
required: ['ticketId'],
|
|
505
|
-
},
|
|
506
|
-
},
|
|
507
318
|
{
|
|
508
319
|
name: 'lookup_ticket',
|
|
509
320
|
description: "Fast ticket lookup by number or title. Returns minimal data (id, number, title, status, complexity). Use 'number' for exact match, 'title' for partial match.",
|
|
@@ -522,11 +333,6 @@ Optional includes (ignored when summary=true):
|
|
|
522
333
|
type: 'string',
|
|
523
334
|
description: 'Ticket title for partial match lookup',
|
|
524
335
|
},
|
|
525
|
-
format: {
|
|
526
|
-
type: 'string',
|
|
527
|
-
enum: ['json', 'toon'],
|
|
528
|
-
description: 'Output format (default: json)',
|
|
529
|
-
},
|
|
530
336
|
},
|
|
531
337
|
required: ['epicId'],
|
|
532
338
|
},
|
|
@@ -548,90 +354,6 @@ Optional includes (ignored when summary=true):
|
|
|
548
354
|
},
|
|
549
355
|
},
|
|
550
356
|
// ========================================================================
|
|
551
|
-
// Core Operations - Dependencies (Epic 3)
|
|
552
|
-
// ========================================================================
|
|
553
|
-
{
|
|
554
|
-
name: 'add_dependency',
|
|
555
|
-
description: 'Add a dependency between two tickets. The first ticket will depend on the second.',
|
|
556
|
-
inputSchema: {
|
|
557
|
-
type: 'object',
|
|
558
|
-
properties: {
|
|
559
|
-
ticketId: {
|
|
560
|
-
type: 'string',
|
|
561
|
-
description: 'The ID of the ticket that will depend on another',
|
|
562
|
-
},
|
|
563
|
-
dependsOnId: {
|
|
564
|
-
type: 'string',
|
|
565
|
-
description: 'The ID of the ticket it will depend on',
|
|
566
|
-
},
|
|
567
|
-
type: {
|
|
568
|
-
type: 'string',
|
|
569
|
-
enum: ['blocks', 'requires'],
|
|
570
|
-
description: "Type of dependency (default: 'requires')",
|
|
571
|
-
},
|
|
572
|
-
},
|
|
573
|
-
required: ['ticketId', 'dependsOnId'],
|
|
574
|
-
},
|
|
575
|
-
},
|
|
576
|
-
{
|
|
577
|
-
name: 'remove_dependency',
|
|
578
|
-
description: 'Remove a dependency between two tickets',
|
|
579
|
-
inputSchema: {
|
|
580
|
-
type: 'object',
|
|
581
|
-
properties: {
|
|
582
|
-
ticketId: {
|
|
583
|
-
type: 'string',
|
|
584
|
-
description: 'The ID of the dependent ticket',
|
|
585
|
-
},
|
|
586
|
-
dependsOnId: {
|
|
587
|
-
type: 'string',
|
|
588
|
-
description: 'The ID of the ticket it depends on',
|
|
589
|
-
},
|
|
590
|
-
dependencyId: {
|
|
591
|
-
type: 'string',
|
|
592
|
-
description: 'Alternative: Direct ID of the dependency record',
|
|
593
|
-
},
|
|
594
|
-
},
|
|
595
|
-
},
|
|
596
|
-
},
|
|
597
|
-
{
|
|
598
|
-
name: 'get_dependency_tree',
|
|
599
|
-
description: 'Get the full dependency tree for a specification, showing all tickets and their dependency relationships',
|
|
600
|
-
inputSchema: {
|
|
601
|
-
type: 'object',
|
|
602
|
-
properties: {
|
|
603
|
-
specificationId: {
|
|
604
|
-
type: 'string',
|
|
605
|
-
description: 'The ID of the specification',
|
|
606
|
-
},
|
|
607
|
-
},
|
|
608
|
-
required: ['specificationId'],
|
|
609
|
-
},
|
|
610
|
-
},
|
|
611
|
-
{
|
|
612
|
-
name: 'check_circular_dependencies',
|
|
613
|
-
description: `Check for circular dependencies between tickets in a specification.
|
|
614
|
-
|
|
615
|
-
Returns any cycles found where tickets depend on each other in a loop (e.g., A→B→C→A).
|
|
616
|
-
|
|
617
|
-
Examples:
|
|
618
|
-
- check_circular_dependencies specificationId="spec-123"
|
|
619
|
-
- check_circular_dependencies projectId="proj-123" // Check all specs in project`,
|
|
620
|
-
inputSchema: {
|
|
621
|
-
type: 'object',
|
|
622
|
-
properties: {
|
|
623
|
-
specificationId: {
|
|
624
|
-
type: 'string',
|
|
625
|
-
description: 'Specification ID to check (optional if projectId provided)',
|
|
626
|
-
},
|
|
627
|
-
projectId: {
|
|
628
|
-
type: 'string',
|
|
629
|
-
description: 'Project ID to check all specifications (optional if specificationId provided)',
|
|
630
|
-
},
|
|
631
|
-
},
|
|
632
|
-
},
|
|
633
|
-
},
|
|
634
|
-
// ========================================================================
|
|
635
357
|
// Context & AI Tools (Epic 4)
|
|
636
358
|
// ========================================================================
|
|
637
359
|
{
|
|
@@ -689,20 +411,6 @@ Examples:
|
|
|
689
411
|
required: ['specificationId'],
|
|
690
412
|
},
|
|
691
413
|
},
|
|
692
|
-
{
|
|
693
|
-
name: 'get_critical_path',
|
|
694
|
-
description: 'Get the critical path (longest dependency chain) for a specification',
|
|
695
|
-
inputSchema: {
|
|
696
|
-
type: 'object',
|
|
697
|
-
properties: {
|
|
698
|
-
specificationId: {
|
|
699
|
-
type: 'string',
|
|
700
|
-
description: 'The ID of the specification',
|
|
701
|
-
},
|
|
702
|
-
},
|
|
703
|
-
required: ['specificationId'],
|
|
704
|
-
},
|
|
705
|
-
},
|
|
706
414
|
{
|
|
707
415
|
name: 'get_patterns',
|
|
708
416
|
description: 'Get patterns for a specification or ticket with full inheritance chain. When ticketId is provided, returns resolved patterns with spec → epic → ticket inheritance.',
|
|
@@ -725,7 +433,7 @@ Examples:
|
|
|
725
433
|
// ========================================================================
|
|
726
434
|
{
|
|
727
435
|
name: 'start_work_session',
|
|
728
|
-
description: 'Start working on a ticket.
|
|
436
|
+
description: 'Start working on a ticket. Returns full ticket details (description, implementation steps, AC, technicalDetails, codeReferences, typeReferences, tags, notes, complexity, priority) alongside checklistState and workSessionId. No need to call get_ticket separately. Returns error with statusReason if ticket is pending.',
|
|
729
437
|
inputSchema: {
|
|
730
438
|
type: 'object',
|
|
731
439
|
properties: {
|
|
@@ -852,7 +560,9 @@ Use this instead of calling update_ticket for checklist changes. Provides:
|
|
|
852
560
|
- Auto-calculated progress percentage
|
|
853
561
|
- Completion readiness hints
|
|
854
562
|
|
|
855
|
-
IMPORTANT: All acceptance criteria must be validated and all implementation steps must be completed via this tool before calling complete_work_session. The completion gate enforces this
|
|
563
|
+
IMPORTANT: All acceptance criteria must be validated and all implementation steps must be completed via this tool before calling complete_work_session. The completion gate enforces this.
|
|
564
|
+
|
|
565
|
+
Set getTicket: true to fetch full ticket details in the response — useful for re-reading ticket context mid-implementation. Can be the sole operation or combined with other actions.`,
|
|
856
566
|
inputSchema: {
|
|
857
567
|
type: 'object',
|
|
858
568
|
properties: {
|
|
@@ -977,6 +687,10 @@ IMPORTANT: All acceptance criteria must be validated and all implementation step
|
|
|
977
687
|
type: 'boolean',
|
|
978
688
|
description: 'Clear existing blocker and resume work.',
|
|
979
689
|
},
|
|
690
|
+
getTicket: {
|
|
691
|
+
type: 'boolean',
|
|
692
|
+
description: 'Fetch full ticket details. Can be the sole operation or combined with other actions.',
|
|
693
|
+
},
|
|
980
694
|
},
|
|
981
695
|
required: ['ticketId'],
|
|
982
696
|
},
|
|
@@ -1014,11 +728,6 @@ Format options:
|
|
|
1014
728
|
type: 'string',
|
|
1015
729
|
description: 'ID of the scoped entity (projectId, specificationId, or epicId)',
|
|
1016
730
|
},
|
|
1017
|
-
format: {
|
|
1018
|
-
type: 'string',
|
|
1019
|
-
enum: ['json', 'toon', 'summary'],
|
|
1020
|
-
description: 'Output format: json (full structured), toon (~44% smaller), summary (key metrics only ~70% smaller). Default: json',
|
|
1021
|
-
},
|
|
1022
731
|
startDate: {
|
|
1023
732
|
type: 'string',
|
|
1024
733
|
description: 'Start date for work report (ISO 8601)',
|
|
@@ -1046,7 +755,7 @@ Combines:
|
|
|
1046
755
|
- Status, complexity, priority filters
|
|
1047
756
|
|
|
1048
757
|
At least one of: query, files, tags, or relatedTo is required.
|
|
1049
|
-
At least one scope filter (projectId, specificationId, or epicId) is required.`,
|
|
758
|
+
At least one scope filter (projectId, specificationId, or epicId) is required. During active planning sessions, prefer lookup_ticket for targeted lookups.`,
|
|
1050
759
|
inputSchema: {
|
|
1051
760
|
type: 'object',
|
|
1052
761
|
properties: {
|
|
@@ -1223,7 +932,7 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
|
|
|
1223
932
|
// ========================================================================
|
|
1224
933
|
{
|
|
1225
934
|
name: 'create_specification',
|
|
1226
|
-
description: 'Create a new specification with full context. Create epics separately using epic.create for better quality.',
|
|
935
|
+
description: 'Create a new specification with full context. Create epics separately using epic.create for better quality. After creation, use start_planning_session to begin structured planning.',
|
|
1227
936
|
inputSchema: {
|
|
1228
937
|
type: 'object',
|
|
1229
938
|
properties: {
|
|
@@ -1387,766 +1096,107 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
|
|
|
1387
1096
|
},
|
|
1388
1097
|
},
|
|
1389
1098
|
{
|
|
1390
|
-
name: '
|
|
1391
|
-
description: '
|
|
1099
|
+
name: 'import_specification',
|
|
1100
|
+
description: 'Import a markdown file as a complete specification with AI-powered parsing. Parses epics from ## headers and tickets from ### headers.',
|
|
1392
1101
|
inputSchema: {
|
|
1393
1102
|
type: 'object',
|
|
1394
1103
|
properties: {
|
|
1395
|
-
|
|
1104
|
+
projectId: {
|
|
1396
1105
|
type: 'string',
|
|
1397
|
-
description: 'The ID of the
|
|
1106
|
+
description: 'The ID of the project to import into',
|
|
1107
|
+
},
|
|
1108
|
+
content: {
|
|
1109
|
+
type: 'string',
|
|
1110
|
+
description: 'Raw markdown content to parse and import',
|
|
1398
1111
|
},
|
|
1399
1112
|
title: {
|
|
1400
1113
|
type: 'string',
|
|
1401
|
-
description: '
|
|
1114
|
+
description: 'Override the parsed title (optional)',
|
|
1402
1115
|
},
|
|
1403
|
-
|
|
1116
|
+
specificationTypeId: {
|
|
1404
1117
|
type: 'string',
|
|
1405
|
-
description: '
|
|
1118
|
+
description: 'Specification type ID (uses default if not provided)',
|
|
1406
1119
|
},
|
|
1407
|
-
|
|
1120
|
+
},
|
|
1121
|
+
required: ['projectId', 'content'],
|
|
1122
|
+
},
|
|
1123
|
+
},
|
|
1124
|
+
// ========================================================================
|
|
1125
|
+
// Implementation Session Operations
|
|
1126
|
+
// ========================================================================
|
|
1127
|
+
{
|
|
1128
|
+
name: 'start_implementation_session',
|
|
1129
|
+
description: 'Start an implementation session for a specification. An implementation session is for autonomous multi-ticket implementation, tracking completed/failed/skipped tickets. This is different from a work session (session.start) which is for working on a single ticket. Returns actionable and blocked tickets.',
|
|
1130
|
+
inputSchema: {
|
|
1131
|
+
type: 'object',
|
|
1132
|
+
properties: {
|
|
1133
|
+
specificationId: {
|
|
1408
1134
|
type: 'string',
|
|
1409
|
-
description: '
|
|
1135
|
+
description: 'The ID of the specification to create a session for',
|
|
1410
1136
|
},
|
|
1411
|
-
|
|
1412
|
-
type: '
|
|
1413
|
-
description: '
|
|
1137
|
+
config: {
|
|
1138
|
+
type: 'object',
|
|
1139
|
+
description: 'Optional session configuration',
|
|
1140
|
+
properties: {
|
|
1141
|
+
mode: {
|
|
1142
|
+
type: 'string',
|
|
1143
|
+
enum: ['single', 'autonomous', 'guided'],
|
|
1144
|
+
description: 'Implementation mode (default: autonomous)',
|
|
1145
|
+
},
|
|
1146
|
+
maxTickets: {
|
|
1147
|
+
type: 'number',
|
|
1148
|
+
description: 'Maximum tickets to process (null = unlimited, default: 5)',
|
|
1149
|
+
},
|
|
1150
|
+
stopOnFailure: {
|
|
1151
|
+
type: 'boolean',
|
|
1152
|
+
description: 'Stop session on first failure (default: false)',
|
|
1153
|
+
},
|
|
1154
|
+
autoCommit: {
|
|
1155
|
+
type: 'boolean',
|
|
1156
|
+
description: 'Auto-commit after each ticket (default: true)',
|
|
1157
|
+
},
|
|
1158
|
+
reviewAtEpicBoundaries: {
|
|
1159
|
+
type: 'boolean',
|
|
1160
|
+
description: 'Pause when crossing epic boundaries (default: false)',
|
|
1161
|
+
},
|
|
1162
|
+
epicReviewList: {
|
|
1163
|
+
type: 'array',
|
|
1164
|
+
items: { type: 'string' },
|
|
1165
|
+
description: 'Epic IDs that require review',
|
|
1166
|
+
},
|
|
1167
|
+
},
|
|
1414
1168
|
},
|
|
1415
|
-
|
|
1416
|
-
type: '
|
|
1417
|
-
description: '
|
|
1169
|
+
force: {
|
|
1170
|
+
type: 'boolean',
|
|
1171
|
+
description: 'Force create by ending any existing active session (default: false)',
|
|
1418
1172
|
},
|
|
1419
|
-
|
|
1173
|
+
},
|
|
1174
|
+
required: ['specificationId'],
|
|
1175
|
+
},
|
|
1176
|
+
},
|
|
1177
|
+
{
|
|
1178
|
+
name: 'end_session',
|
|
1179
|
+
description: 'End an implementation session (started with start_implementation_session). Returns final stats. This is different from session.complete which completes work on a single ticket.',
|
|
1180
|
+
inputSchema: {
|
|
1181
|
+
type: 'object',
|
|
1182
|
+
properties: {
|
|
1183
|
+
sessionId: {
|
|
1420
1184
|
type: 'string',
|
|
1421
|
-
description:
|
|
1185
|
+
description: 'The ID of the session to end',
|
|
1422
1186
|
},
|
|
1423
|
-
|
|
1424
|
-
type: '
|
|
1425
|
-
|
|
1426
|
-
description: '
|
|
1187
|
+
status: {
|
|
1188
|
+
type: 'string',
|
|
1189
|
+
enum: ['completed', 'aborted'],
|
|
1190
|
+
description: 'How the session ended',
|
|
1427
1191
|
},
|
|
1428
|
-
|
|
1429
|
-
type: '
|
|
1430
|
-
|
|
1431
|
-
description: 'What NOT to do for this epic',
|
|
1432
|
-
},
|
|
1433
|
-
risks: {
|
|
1434
|
-
type: 'array',
|
|
1435
|
-
items: { type: 'string' },
|
|
1436
|
-
description: 'Risk factors for this epic',
|
|
1437
|
-
},
|
|
1438
|
-
constraints: {
|
|
1439
|
-
type: 'array',
|
|
1440
|
-
items: { type: 'string' },
|
|
1441
|
-
description: 'Technical or business constraints for this epic',
|
|
1442
|
-
},
|
|
1443
|
-
assumptions: {
|
|
1444
|
-
type: 'array',
|
|
1445
|
-
items: { type: 'string' },
|
|
1446
|
-
description: 'Key assumptions made for this epic',
|
|
1447
|
-
},
|
|
1448
|
-
architecture: {
|
|
1449
|
-
type: 'string',
|
|
1450
|
-
description: 'Architectural approach for this epic',
|
|
1451
|
-
},
|
|
1452
|
-
fileStructure: {
|
|
1453
|
-
type: 'string',
|
|
1454
|
-
description: 'File/folder organization for this epic',
|
|
1455
|
-
},
|
|
1456
|
-
techStack: {
|
|
1457
|
-
type: 'array',
|
|
1458
|
-
items: { type: 'string' },
|
|
1459
|
-
description: 'Technologies used (subset of specification)',
|
|
1460
|
-
},
|
|
1461
|
-
dependencies: {
|
|
1462
|
-
type: 'array',
|
|
1463
|
-
items: { type: 'string' },
|
|
1464
|
-
description: 'Required packages/libraries',
|
|
1465
|
-
},
|
|
1466
|
-
apiContracts: {
|
|
1467
|
-
type: 'object',
|
|
1468
|
-
description: 'API specifications for this epic',
|
|
1469
|
-
},
|
|
1470
|
-
acceptanceCriteria: {
|
|
1471
|
-
type: 'array',
|
|
1472
|
-
items: { type: 'string' },
|
|
1473
|
-
description: 'Epic-level success criteria',
|
|
1474
|
-
},
|
|
1475
|
-
priority: {
|
|
1476
|
-
type: 'string',
|
|
1477
|
-
enum: ['high', 'medium', 'low'],
|
|
1478
|
-
description: 'Priority level',
|
|
1479
|
-
},
|
|
1480
|
-
tags: {
|
|
1481
|
-
type: 'array',
|
|
1482
|
-
items: { type: 'string' },
|
|
1483
|
-
description: 'Categorization tags',
|
|
1484
|
-
},
|
|
1485
|
-
estimatedHours: {
|
|
1486
|
-
type: 'number',
|
|
1487
|
-
description: 'Total estimated hours for epic',
|
|
1488
|
-
},
|
|
1489
|
-
// Pattern inheritance fields (epic level)
|
|
1490
|
-
sharedPatterns: {
|
|
1491
|
-
type: 'object',
|
|
1492
|
-
description: 'Patterns shared by all tickets in this epic',
|
|
1493
|
-
properties: {
|
|
1494
|
-
errorHandling: { type: 'string', description: 'Override error handling for this epic' },
|
|
1495
|
-
returnType: { type: 'string', description: 'Epic-specific return type' },
|
|
1496
|
-
actionPrefix: { type: 'string', description: 'Redux/action prefix for this epic' },
|
|
1497
|
-
stateSlice: { type: 'string', description: 'State slice path for this epic' },
|
|
1498
|
-
},
|
|
1499
|
-
},
|
|
1500
|
-
additionalImports: {
|
|
1501
|
-
type: 'array',
|
|
1502
|
-
items: { type: 'string' },
|
|
1503
|
-
description: 'Additional imports for tickets in this epic (added to spec-level imports)',
|
|
1504
|
-
},
|
|
1505
|
-
commonFiles: {
|
|
1506
|
-
type: 'object',
|
|
1507
|
-
description: 'Common file paths for this epic',
|
|
1508
|
-
properties: {
|
|
1509
|
-
reducer: { type: 'string', description: 'Reducer file path' },
|
|
1510
|
-
actions: { type: 'string', description: 'Actions file path' },
|
|
1511
|
-
types: { type: 'string', description: 'Types file path' },
|
|
1512
|
-
index: { type: 'string', description: 'Index/barrel file path' },
|
|
1513
|
-
},
|
|
1514
|
-
},
|
|
1515
|
-
responseMode: {
|
|
1516
|
-
type: 'string',
|
|
1517
|
-
enum: ['full', 'minimal', 'id-only'],
|
|
1518
|
-
description: 'Response verbosity: full (default, ~500 tokens), minimal (~50 tokens), id-only (~20 tokens)',
|
|
1519
|
-
},
|
|
1520
|
-
},
|
|
1521
|
-
required: ['specificationId', 'title', 'description', 'objective'],
|
|
1522
|
-
},
|
|
1523
|
-
},
|
|
1524
|
-
{
|
|
1525
|
-
name: 'create_ticket',
|
|
1526
|
-
description: 'Create a new ticket in an epic. Returns validation warnings based on complexity level.',
|
|
1527
|
-
inputSchema: {
|
|
1528
|
-
type: 'object',
|
|
1529
|
-
properties: {
|
|
1530
|
-
epicId: {
|
|
1531
|
-
type: 'string',
|
|
1532
|
-
description: 'The ID of the epic',
|
|
1533
|
-
},
|
|
1534
|
-
title: {
|
|
1535
|
-
type: 'string',
|
|
1536
|
-
description: 'Ticket title',
|
|
1537
|
-
},
|
|
1538
|
-
ticketNumber: {
|
|
1539
|
-
type: 'number',
|
|
1540
|
-
description: 'Ticket number (auto-incremented if not provided)',
|
|
1541
|
-
},
|
|
1542
|
-
description: {
|
|
1543
|
-
type: 'string',
|
|
1544
|
-
description: 'Ticket description',
|
|
1545
|
-
},
|
|
1546
|
-
implementation: {
|
|
1547
|
-
type: 'object',
|
|
1548
|
-
description: 'Detailed implementation steps (JSON)',
|
|
1549
|
-
},
|
|
1550
|
-
technicalDetails: {
|
|
1551
|
-
type: 'object',
|
|
1552
|
-
description: 'Technical details like stack, endpoints (JSON)',
|
|
1553
|
-
},
|
|
1554
|
-
acceptanceCriteria: {
|
|
1555
|
-
type: 'array',
|
|
1556
|
-
items: { type: 'string' },
|
|
1557
|
-
description: 'Success criteria',
|
|
1558
|
-
},
|
|
1559
|
-
priority: {
|
|
1560
|
-
type: 'string',
|
|
1561
|
-
enum: ['high', 'medium', 'low'],
|
|
1562
|
-
description: 'Priority level',
|
|
1563
|
-
},
|
|
1564
|
-
complexity: {
|
|
1565
|
-
type: 'string',
|
|
1566
|
-
enum: ['small', 'medium', 'large', 'xlarge'],
|
|
1567
|
-
description: 'Size/complexity indicator',
|
|
1568
|
-
},
|
|
1569
|
-
tags: {
|
|
1570
|
-
type: 'array',
|
|
1571
|
-
items: { type: 'string' },
|
|
1572
|
-
description: 'Categorization tags',
|
|
1573
|
-
},
|
|
1574
|
-
notes: {
|
|
1575
|
-
type: 'string',
|
|
1576
|
-
description: 'Additional context, warnings, or considerations',
|
|
1577
|
-
},
|
|
1578
|
-
estimatedHours: {
|
|
1579
|
-
type: 'number',
|
|
1580
|
-
description: 'Estimated effort in hours',
|
|
1581
|
-
},
|
|
1582
|
-
dependsOn: {
|
|
1583
|
-
type: 'array',
|
|
1584
|
-
items: { type: 'string' },
|
|
1585
|
-
description: 'Array of ticket IDs this ticket depends on',
|
|
1586
|
-
},
|
|
1587
|
-
validationStrictness: {
|
|
1588
|
-
type: 'string',
|
|
1589
|
-
enum: ['lenient', 'normal', 'strict'],
|
|
1590
|
-
description: 'Warning strictness level. lenient=warnings only, normal=warnings+recommendations, strict=all. Default: normal',
|
|
1591
|
-
},
|
|
1592
|
-
responseMode: {
|
|
1593
|
-
type: 'string',
|
|
1594
|
-
enum: ['full', 'minimal', 'id-only'],
|
|
1595
|
-
description: 'Response verbosity: full (default, ~500 tokens), minimal (~50 tokens), id-only (~20 tokens)',
|
|
1596
|
-
},
|
|
1597
|
-
},
|
|
1598
|
-
required: ['epicId', 'title'],
|
|
1599
|
-
},
|
|
1600
|
-
},
|
|
1601
|
-
{
|
|
1602
|
-
name: 'import_specification',
|
|
1603
|
-
description: 'Import a markdown file as a complete specification with AI-powered parsing. Parses epics from ## headers and tickets from ### headers.',
|
|
1604
|
-
inputSchema: {
|
|
1605
|
-
type: 'object',
|
|
1606
|
-
properties: {
|
|
1607
|
-
projectId: {
|
|
1608
|
-
type: 'string',
|
|
1609
|
-
description: 'The ID of the project to import into',
|
|
1610
|
-
},
|
|
1611
|
-
content: {
|
|
1612
|
-
type: 'string',
|
|
1613
|
-
description: 'Raw markdown content to parse and import',
|
|
1614
|
-
},
|
|
1615
|
-
title: {
|
|
1616
|
-
type: 'string',
|
|
1617
|
-
description: 'Override the parsed title (optional)',
|
|
1618
|
-
},
|
|
1619
|
-
specificationTypeId: {
|
|
1620
|
-
type: 'string',
|
|
1621
|
-
description: 'Specification type ID (uses default if not provided)',
|
|
1622
|
-
},
|
|
1623
|
-
},
|
|
1624
|
-
required: ['projectId', 'content'],
|
|
1625
|
-
},
|
|
1626
|
-
},
|
|
1627
|
-
// ========================================================================
|
|
1628
|
-
// Update Operations
|
|
1629
|
-
// ========================================================================
|
|
1630
|
-
{
|
|
1631
|
-
name: 'update_ticket',
|
|
1632
|
-
description: "Update a ticket's properties (status, description, estimate, etc.).\n\n" +
|
|
1633
|
-
'When status changes, counts are automatically propagated up the hierarchy ' +
|
|
1634
|
-
'(Epic → Specification → Project).',
|
|
1635
|
-
inputSchema: {
|
|
1636
|
-
type: 'object',
|
|
1637
|
-
properties: {
|
|
1638
|
-
ticketId: {
|
|
1639
|
-
type: 'string',
|
|
1640
|
-
description: 'The ID of the ticket to update',
|
|
1641
|
-
},
|
|
1642
|
-
title: {
|
|
1643
|
-
type: 'string',
|
|
1644
|
-
description: 'New title (optional)',
|
|
1645
|
-
},
|
|
1646
|
-
description: {
|
|
1647
|
-
type: 'string',
|
|
1648
|
-
description: 'New description (optional)',
|
|
1649
|
-
},
|
|
1650
|
-
status: {
|
|
1651
|
-
type: 'string',
|
|
1652
|
-
enum: ['pending', 'ready', 'active', 'done'],
|
|
1653
|
-
description: 'Ticket status. pending/ready may be recalculated based on dependencies.',
|
|
1654
|
-
},
|
|
1655
|
-
priority: {
|
|
1656
|
-
type: 'string',
|
|
1657
|
-
enum: ['low', 'medium', 'high', 'critical'],
|
|
1658
|
-
description: 'Priority level (optional)',
|
|
1659
|
-
},
|
|
1660
|
-
complexity: {
|
|
1661
|
-
type: 'string',
|
|
1662
|
-
enum: ['small', 'medium', 'large', 'xlarge'],
|
|
1663
|
-
description: 'Size/complexity indicator (optional)',
|
|
1664
|
-
},
|
|
1665
|
-
blockReason: {
|
|
1666
|
-
type: 'string',
|
|
1667
|
-
description: 'External block reason. Forces status to pending until cleared.',
|
|
1668
|
-
},
|
|
1669
|
-
notes: {
|
|
1670
|
-
type: 'string',
|
|
1671
|
-
description: 'Additional context, warnings, or considerations (optional)',
|
|
1672
|
-
},
|
|
1673
|
-
estimatedHours: {
|
|
1674
|
-
type: 'number',
|
|
1675
|
-
description: 'Estimated hours (optional)',
|
|
1676
|
-
},
|
|
1677
|
-
tags: {
|
|
1678
|
-
type: 'array',
|
|
1679
|
-
items: { type: 'string' },
|
|
1680
|
-
description: 'Tags (optional)',
|
|
1681
|
-
},
|
|
1682
|
-
acceptanceCriteria: {
|
|
1683
|
-
type: 'array',
|
|
1684
|
-
items: { type: 'string' },
|
|
1685
|
-
description: 'Acceptance criteria (optional)',
|
|
1686
|
-
},
|
|
1687
|
-
implementation: {
|
|
1688
|
-
type: 'object',
|
|
1689
|
-
description: 'Detailed implementation steps (JSON) (optional)',
|
|
1690
|
-
},
|
|
1691
|
-
technicalDetails: {
|
|
1692
|
-
type: 'object',
|
|
1693
|
-
description: 'Technical details like stack, endpoints (JSON) (optional)',
|
|
1694
|
-
},
|
|
1695
|
-
validationStrictness: {
|
|
1696
|
-
type: 'string',
|
|
1697
|
-
enum: ['lenient', 'normal', 'strict'],
|
|
1698
|
-
description: 'Warning strictness level (default: normal)',
|
|
1699
|
-
default: 'normal',
|
|
1700
|
-
},
|
|
1701
|
-
responseMode: {
|
|
1702
|
-
type: 'string',
|
|
1703
|
-
enum: ['full', 'minimal', 'id-only'],
|
|
1704
|
-
description: 'Response verbosity: full (default, ~500 tokens), minimal (~50 tokens), id-only (~20 tokens)',
|
|
1705
|
-
},
|
|
1706
|
-
},
|
|
1707
|
-
required: ['ticketId'],
|
|
1708
|
-
},
|
|
1709
|
-
},
|
|
1710
|
-
{
|
|
1711
|
-
name: 'update_epic',
|
|
1712
|
-
description: "Update an epic's properties",
|
|
1713
|
-
inputSchema: {
|
|
1714
|
-
type: 'object',
|
|
1715
|
-
properties: {
|
|
1716
|
-
epicId: {
|
|
1717
|
-
type: 'string',
|
|
1718
|
-
description: 'The ID of the epic to update',
|
|
1719
|
-
},
|
|
1720
|
-
title: {
|
|
1721
|
-
type: 'string',
|
|
1722
|
-
description: 'New title (optional)',
|
|
1723
|
-
},
|
|
1724
|
-
description: {
|
|
1725
|
-
type: 'string',
|
|
1726
|
-
description: 'New description (optional)',
|
|
1727
|
-
},
|
|
1728
|
-
status: {
|
|
1729
|
-
type: 'string',
|
|
1730
|
-
enum: ['todo', 'in_progress', 'completed'],
|
|
1731
|
-
description: 'New status (optional)',
|
|
1732
|
-
},
|
|
1733
|
-
objective: {
|
|
1734
|
-
type: 'string',
|
|
1735
|
-
description: 'New objective (optional)',
|
|
1736
|
-
},
|
|
1737
|
-
scope: {
|
|
1738
|
-
type: 'string',
|
|
1739
|
-
description: 'What\'s in/out of scope (optional)',
|
|
1740
|
-
},
|
|
1741
|
-
goals: {
|
|
1742
|
-
type: 'array',
|
|
1743
|
-
items: { type: 'string' },
|
|
1744
|
-
description: 'Epic-specific goals (optional)',
|
|
1745
|
-
},
|
|
1746
|
-
guardrails: {
|
|
1747
|
-
type: 'array',
|
|
1748
|
-
items: { type: 'string' },
|
|
1749
|
-
description: 'What NOT to do (optional)',
|
|
1750
|
-
},
|
|
1751
|
-
risks: {
|
|
1752
|
-
type: 'array',
|
|
1753
|
-
items: { type: 'string' },
|
|
1754
|
-
description: 'Risk factors (optional)',
|
|
1755
|
-
},
|
|
1756
|
-
constraints: {
|
|
1757
|
-
type: 'array',
|
|
1758
|
-
items: { type: 'string' },
|
|
1759
|
-
description: 'Technical/business constraints (optional)',
|
|
1760
|
-
},
|
|
1761
|
-
assumptions: {
|
|
1762
|
-
type: 'array',
|
|
1763
|
-
items: { type: 'string' },
|
|
1764
|
-
description: 'Key assumptions (optional)',
|
|
1765
|
-
},
|
|
1766
|
-
architecture: {
|
|
1767
|
-
type: 'string',
|
|
1768
|
-
description: 'Architectural approach (optional)',
|
|
1769
|
-
},
|
|
1770
|
-
fileStructure: {
|
|
1771
|
-
type: 'string',
|
|
1772
|
-
description: 'File/folder organization (optional)',
|
|
1773
|
-
},
|
|
1774
|
-
techStack: {
|
|
1775
|
-
type: 'array',
|
|
1776
|
-
items: { type: 'string' },
|
|
1777
|
-
description: 'Technologies used (optional)',
|
|
1778
|
-
},
|
|
1779
|
-
dependencies: {
|
|
1780
|
-
type: 'array',
|
|
1781
|
-
items: { type: 'string' },
|
|
1782
|
-
description: 'Required packages/libraries (optional)',
|
|
1783
|
-
},
|
|
1784
|
-
apiContracts: {
|
|
1785
|
-
type: 'object',
|
|
1786
|
-
description: 'API specifications (optional)',
|
|
1787
|
-
},
|
|
1788
|
-
acceptanceCriteria: {
|
|
1789
|
-
type: 'array',
|
|
1790
|
-
items: { type: 'string' },
|
|
1791
|
-
description: 'Success criteria (optional)',
|
|
1792
|
-
},
|
|
1793
|
-
tags: {
|
|
1794
|
-
type: 'array',
|
|
1795
|
-
items: { type: 'string' },
|
|
1796
|
-
description: 'Categorization tags (optional)',
|
|
1797
|
-
},
|
|
1798
|
-
estimatedHours: {
|
|
1799
|
-
type: 'number',
|
|
1800
|
-
description: 'Total estimated hours (optional)',
|
|
1801
|
-
},
|
|
1802
|
-
priority: {
|
|
1803
|
-
type: 'string',
|
|
1804
|
-
enum: ['low', 'medium', 'high', 'critical'],
|
|
1805
|
-
description: 'Priority level (optional)',
|
|
1806
|
-
},
|
|
1807
|
-
// Pattern inheritance fields (epic level)
|
|
1808
|
-
sharedPatterns: {
|
|
1809
|
-
type: 'object',
|
|
1810
|
-
description: 'Patterns shared by all tickets in this epic (optional)',
|
|
1811
|
-
properties: {
|
|
1812
|
-
errorHandling: { type: 'string', description: 'Override error handling for this epic' },
|
|
1813
|
-
returnType: { type: 'string', description: 'Epic-specific return type' },
|
|
1814
|
-
actionPrefix: { type: 'string', description: 'Redux/action prefix for this epic' },
|
|
1815
|
-
stateSlice: { type: 'string', description: 'State slice path for this epic' },
|
|
1816
|
-
},
|
|
1817
|
-
},
|
|
1818
|
-
additionalImports: {
|
|
1819
|
-
type: 'array',
|
|
1820
|
-
items: { type: 'string' },
|
|
1821
|
-
description: 'Additional imports for tickets in this epic (optional)',
|
|
1822
|
-
},
|
|
1823
|
-
commonFiles: {
|
|
1824
|
-
type: 'object',
|
|
1825
|
-
description: 'Common file paths for this epic (optional)',
|
|
1826
|
-
properties: {
|
|
1827
|
-
reducer: { type: 'string', description: 'Reducer file path' },
|
|
1828
|
-
actions: { type: 'string', description: 'Actions file path' },
|
|
1829
|
-
types: { type: 'string', description: 'Types file path' },
|
|
1830
|
-
index: { type: 'string', description: 'Index/barrel file path' },
|
|
1831
|
-
},
|
|
1832
|
-
},
|
|
1833
|
-
responseMode: {
|
|
1834
|
-
type: 'string',
|
|
1835
|
-
enum: ['full', 'minimal', 'id-only'],
|
|
1836
|
-
description: 'Response verbosity: full (default, ~500 tokens), minimal (~50 tokens), id-only (~20 tokens)',
|
|
1837
|
-
},
|
|
1838
|
-
},
|
|
1839
|
-
required: ['epicId'],
|
|
1840
|
-
},
|
|
1841
|
-
},
|
|
1842
|
-
{
|
|
1843
|
-
name: 'update_specification',
|
|
1844
|
-
description: "Update a specification's properties",
|
|
1845
|
-
inputSchema: {
|
|
1846
|
-
type: 'object',
|
|
1847
|
-
properties: {
|
|
1848
|
-
specificationId: {
|
|
1849
|
-
type: 'string',
|
|
1850
|
-
description: 'The ID of the specification to update',
|
|
1851
|
-
},
|
|
1852
|
-
title: {
|
|
1853
|
-
type: 'string',
|
|
1854
|
-
description: 'New title (optional)',
|
|
1855
|
-
},
|
|
1856
|
-
description: {
|
|
1857
|
-
type: 'string',
|
|
1858
|
-
description: 'New description (optional)',
|
|
1859
|
-
},
|
|
1860
|
-
status: {
|
|
1861
|
-
type: 'string',
|
|
1862
|
-
enum: ['draft', 'planning', 'ready', 'in_progress', 'completed'],
|
|
1863
|
-
description: 'New status (optional)',
|
|
1864
|
-
},
|
|
1865
|
-
background: {
|
|
1866
|
-
type: 'string',
|
|
1867
|
-
description: 'New background (optional)',
|
|
1868
|
-
},
|
|
1869
|
-
scope: {
|
|
1870
|
-
type: 'string',
|
|
1871
|
-
description: 'New scope (optional)',
|
|
1872
|
-
},
|
|
1873
|
-
goals: {
|
|
1874
|
-
type: 'array',
|
|
1875
|
-
items: { type: 'string' },
|
|
1876
|
-
description: 'Business/user/technical objectives (optional)',
|
|
1877
|
-
},
|
|
1878
|
-
requirements: {
|
|
1879
|
-
type: 'array',
|
|
1880
|
-
items: { type: 'string' },
|
|
1881
|
-
description: 'Functional requirements (optional)',
|
|
1882
|
-
},
|
|
1883
|
-
nonFunctionalRequirements: {
|
|
1884
|
-
type: 'array',
|
|
1885
|
-
items: { type: 'string' },
|
|
1886
|
-
description: 'Non-functional requirements like performance, security (optional)',
|
|
1887
|
-
},
|
|
1888
|
-
successMetrics: {
|
|
1889
|
-
type: 'array',
|
|
1890
|
-
items: { type: 'string' },
|
|
1891
|
-
description: 'KPIs to measure success (optional)',
|
|
1892
|
-
},
|
|
1893
|
-
constraints: {
|
|
1894
|
-
type: 'array',
|
|
1895
|
-
items: { type: 'string' },
|
|
1896
|
-
description: 'Technical/business constraints (optional)',
|
|
1897
|
-
},
|
|
1898
|
-
assumptions: {
|
|
1899
|
-
type: 'array',
|
|
1900
|
-
items: { type: 'string' },
|
|
1901
|
-
description: 'Key assumptions made (optional)',
|
|
1902
|
-
},
|
|
1903
|
-
risks: {
|
|
1904
|
-
type: 'array',
|
|
1905
|
-
items: { type: 'string' },
|
|
1906
|
-
description: 'Risk factors and mitigations (optional)',
|
|
1907
|
-
},
|
|
1908
|
-
guardrails: {
|
|
1909
|
-
type: 'array',
|
|
1910
|
-
items: { type: 'string' },
|
|
1911
|
-
description: 'What NOT to do (optional)',
|
|
1912
|
-
},
|
|
1913
|
-
architecture: {
|
|
1914
|
-
type: 'string',
|
|
1915
|
-
description: 'Architectural approach (optional)',
|
|
1916
|
-
},
|
|
1917
|
-
fileStructure: {
|
|
1918
|
-
type: 'string',
|
|
1919
|
-
description: 'File/folder organization (optional)',
|
|
1920
|
-
},
|
|
1921
|
-
techStack: {
|
|
1922
|
-
type: 'array',
|
|
1923
|
-
items: { type: 'string' },
|
|
1924
|
-
description: 'Technologies to use (optional)',
|
|
1925
|
-
},
|
|
1926
|
-
dependencies: {
|
|
1927
|
-
type: 'array',
|
|
1928
|
-
items: { type: 'string' },
|
|
1929
|
-
description: 'Required packages/libraries (optional)',
|
|
1930
|
-
},
|
|
1931
|
-
apiContracts: {
|
|
1932
|
-
type: 'object',
|
|
1933
|
-
description: 'API specifications (optional)',
|
|
1934
|
-
},
|
|
1935
|
-
acceptanceCriteria: {
|
|
1936
|
-
type: 'array',
|
|
1937
|
-
items: { type: 'string' },
|
|
1938
|
-
description: 'Success criteria (optional)',
|
|
1939
|
-
},
|
|
1940
|
-
tags: {
|
|
1941
|
-
type: 'array',
|
|
1942
|
-
items: { type: 'string' },
|
|
1943
|
-
description: 'Categorization tags (optional)',
|
|
1944
|
-
},
|
|
1945
|
-
estimatedHours: {
|
|
1946
|
-
type: 'number',
|
|
1947
|
-
description: 'Total estimated hours (optional)',
|
|
1948
|
-
},
|
|
1949
|
-
targetAudience: {
|
|
1950
|
-
type: 'string',
|
|
1951
|
-
description: 'Who this is for - developers, users, stakeholders, etc. (optional)',
|
|
1952
|
-
},
|
|
1953
|
-
priority: {
|
|
1954
|
-
type: 'string',
|
|
1955
|
-
enum: ['low', 'medium', 'high', 'critical'],
|
|
1956
|
-
description: 'Priority level (optional)',
|
|
1957
|
-
},
|
|
1958
|
-
validationCommands: {
|
|
1959
|
-
type: 'object',
|
|
1960
|
-
description: 'Validation commands (test, lint, build, typeCheck, custom) (optional)',
|
|
1961
|
-
properties: {
|
|
1962
|
-
test: { type: 'string', description: 'Test command' },
|
|
1963
|
-
lint: { type: 'string', description: 'Lint command' },
|
|
1964
|
-
build: { type: 'string', description: 'Build command' },
|
|
1965
|
-
typeCheck: { type: 'string', description: 'Type check command' },
|
|
1966
|
-
preValidation: { type: 'string', description: 'Pre-validation command' },
|
|
1967
|
-
postValidation: { type: 'string', description: 'Post-validation command' },
|
|
1968
|
-
custom: {
|
|
1969
|
-
type: 'object',
|
|
1970
|
-
description: 'Custom validation commands',
|
|
1971
|
-
additionalProperties: { type: 'string' },
|
|
1972
|
-
},
|
|
1973
|
-
},
|
|
1974
|
-
},
|
|
1975
|
-
workingDirectory: {
|
|
1976
|
-
type: 'string',
|
|
1977
|
-
description: 'Working directory for commands (optional)',
|
|
1978
|
-
},
|
|
1979
|
-
outputDirectory: {
|
|
1980
|
-
type: 'string',
|
|
1981
|
-
description: 'Output directory for build artifacts (optional)',
|
|
1982
|
-
},
|
|
1983
|
-
// Pattern inheritance fields (specification level)
|
|
1984
|
-
codeStandards: {
|
|
1985
|
-
type: 'object',
|
|
1986
|
-
description: 'Code standards inherited by all epics/tickets (optional)',
|
|
1987
|
-
properties: {
|
|
1988
|
-
language: { type: 'string', description: 'Primary language (e.g., "TypeScript")' },
|
|
1989
|
-
asyncPattern: { type: 'string', description: 'Async pattern (e.g., "async/await")' },
|
|
1990
|
-
errorHandling: { type: 'string', description: 'Error handling approach' },
|
|
1991
|
-
documentation: { type: 'string', description: 'Documentation style' },
|
|
1992
|
-
testing: { type: 'string', description: 'Testing approach' },
|
|
1993
|
-
naming: {
|
|
1994
|
-
type: 'object',
|
|
1995
|
-
description: 'Naming conventions',
|
|
1996
|
-
properties: {
|
|
1997
|
-
files: { type: 'string', description: 'File naming convention' },
|
|
1998
|
-
functions: { type: 'string', description: 'Function naming convention' },
|
|
1999
|
-
interfaces: { type: 'string', description: 'Interface naming convention' },
|
|
2000
|
-
actions: { type: 'string', description: 'Action naming convention' },
|
|
2001
|
-
},
|
|
2002
|
-
},
|
|
2003
|
-
},
|
|
2004
|
-
},
|
|
2005
|
-
commonImports: {
|
|
2006
|
-
type: 'array',
|
|
2007
|
-
items: { type: 'string' },
|
|
2008
|
-
description: 'Common imports inherited by all epics/tickets (optional)',
|
|
2009
|
-
},
|
|
2010
|
-
returnTypes: {
|
|
2011
|
-
type: 'object',
|
|
2012
|
-
description: 'Standard return types for CRUD operations (optional)',
|
|
2013
|
-
properties: {
|
|
2014
|
-
create: { type: 'string', description: 'Return type for create operations' },
|
|
2015
|
-
update: { type: 'string', description: 'Return type for update operations' },
|
|
2016
|
-
delete: { type: 'string', description: 'Return type for delete operations' },
|
|
2017
|
-
list: { type: 'string', description: 'Return type for list operations' },
|
|
2018
|
-
},
|
|
2019
|
-
},
|
|
2020
|
-
responseMode: {
|
|
2021
|
-
type: 'string',
|
|
2022
|
-
enum: ['full', 'minimal', 'id-only'],
|
|
2023
|
-
description: 'Response verbosity: full (default, ~500 tokens), minimal (~50 tokens), id-only (~20 tokens)',
|
|
2024
|
-
},
|
|
2025
|
-
},
|
|
2026
|
-
required: ['specificationId'],
|
|
2027
|
-
},
|
|
2028
|
-
},
|
|
2029
|
-
// ========================================================================
|
|
2030
|
-
// Implementation Session Operations
|
|
2031
|
-
// ========================================================================
|
|
2032
|
-
{
|
|
2033
|
-
name: 'start_implementation_session',
|
|
2034
|
-
description: 'Start an implementation session for a specification. An implementation session is for autonomous multi-ticket implementation, tracking completed/failed/skipped tickets. This is different from a work session (session.start) which is for working on a single ticket. Returns actionable and blocked tickets.',
|
|
2035
|
-
inputSchema: {
|
|
2036
|
-
type: 'object',
|
|
2037
|
-
properties: {
|
|
2038
|
-
specificationId: {
|
|
2039
|
-
type: 'string',
|
|
2040
|
-
description: 'The ID of the specification to create a session for',
|
|
2041
|
-
},
|
|
2042
|
-
config: {
|
|
2043
|
-
type: 'object',
|
|
2044
|
-
description: 'Optional session configuration',
|
|
2045
|
-
properties: {
|
|
2046
|
-
mode: {
|
|
2047
|
-
type: 'string',
|
|
2048
|
-
enum: ['single', 'autonomous', 'guided'],
|
|
2049
|
-
description: 'Implementation mode (default: autonomous)',
|
|
2050
|
-
},
|
|
2051
|
-
maxTickets: {
|
|
2052
|
-
type: 'number',
|
|
2053
|
-
description: 'Maximum tickets to process (null = unlimited, default: 5)',
|
|
2054
|
-
},
|
|
2055
|
-
stopOnFailure: {
|
|
2056
|
-
type: 'boolean',
|
|
2057
|
-
description: 'Stop session on first failure (default: false)',
|
|
2058
|
-
},
|
|
2059
|
-
autoCommit: {
|
|
2060
|
-
type: 'boolean',
|
|
2061
|
-
description: 'Auto-commit after each ticket (default: true)',
|
|
2062
|
-
},
|
|
2063
|
-
reviewAtEpicBoundaries: {
|
|
2064
|
-
type: 'boolean',
|
|
2065
|
-
description: 'Pause when crossing epic boundaries (default: false)',
|
|
2066
|
-
},
|
|
2067
|
-
epicReviewList: {
|
|
2068
|
-
type: 'array',
|
|
2069
|
-
items: { type: 'string' },
|
|
2070
|
-
description: 'Epic IDs that require review',
|
|
2071
|
-
},
|
|
2072
|
-
},
|
|
2073
|
-
},
|
|
2074
|
-
force: {
|
|
2075
|
-
type: 'boolean',
|
|
2076
|
-
description: 'Force create by ending any existing active session (default: false)',
|
|
2077
|
-
},
|
|
2078
|
-
},
|
|
2079
|
-
required: ['specificationId'],
|
|
2080
|
-
},
|
|
2081
|
-
},
|
|
2082
|
-
{
|
|
2083
|
-
name: 'end_session',
|
|
2084
|
-
description: 'End an implementation session (started with start_implementation_session). Returns final stats. This is different from session.complete which completes work on a single ticket.',
|
|
2085
|
-
inputSchema: {
|
|
2086
|
-
type: 'object',
|
|
2087
|
-
properties: {
|
|
2088
|
-
sessionId: {
|
|
2089
|
-
type: 'string',
|
|
2090
|
-
description: 'The ID of the session to end',
|
|
2091
|
-
},
|
|
2092
|
-
status: {
|
|
2093
|
-
type: 'string',
|
|
2094
|
-
enum: ['completed', 'aborted'],
|
|
2095
|
-
description: 'How the session ended',
|
|
2096
|
-
},
|
|
2097
|
-
summary: {
|
|
2098
|
-
type: 'string',
|
|
2099
|
-
description: 'End-of-session summary',
|
|
1192
|
+
summary: {
|
|
1193
|
+
type: 'string',
|
|
1194
|
+
description: 'End-of-session summary',
|
|
2100
1195
|
},
|
|
2101
1196
|
},
|
|
2102
1197
|
required: ['sessionId', 'status'],
|
|
2103
1198
|
},
|
|
2104
1199
|
},
|
|
2105
|
-
// ========================================================================
|
|
2106
|
-
// Bulk Operations
|
|
2107
|
-
// ========================================================================
|
|
2108
|
-
{
|
|
2109
|
-
name: 'bulk_add_dependencies',
|
|
2110
|
-
description: 'Add multiple dependencies between tickets in a single atomic transaction.',
|
|
2111
|
-
inputSchema: {
|
|
2112
|
-
type: 'object',
|
|
2113
|
-
properties: {
|
|
2114
|
-
dependencies: {
|
|
2115
|
-
type: 'array',
|
|
2116
|
-
description: 'Array of dependency definitions',
|
|
2117
|
-
items: {
|
|
2118
|
-
type: 'object',
|
|
2119
|
-
properties: {
|
|
2120
|
-
ticketId: {
|
|
2121
|
-
type: 'string',
|
|
2122
|
-
description: 'ID of the ticket that will depend on another',
|
|
2123
|
-
},
|
|
2124
|
-
dependsOnId: {
|
|
2125
|
-
type: 'string',
|
|
2126
|
-
description: 'ID of the ticket it will depend on',
|
|
2127
|
-
},
|
|
2128
|
-
type: {
|
|
2129
|
-
type: 'string',
|
|
2130
|
-
enum: ['blocks', 'requires'],
|
|
2131
|
-
description: "Type of dependency (default: 'requires')",
|
|
2132
|
-
},
|
|
2133
|
-
},
|
|
2134
|
-
required: ['ticketId', 'dependsOnId'],
|
|
2135
|
-
},
|
|
2136
|
-
},
|
|
2137
|
-
skipCircularCheck: {
|
|
2138
|
-
type: 'boolean',
|
|
2139
|
-
description: 'Skip validation of circular dependencies (default: false)',
|
|
2140
|
-
},
|
|
2141
|
-
onError: {
|
|
2142
|
-
type: 'string',
|
|
2143
|
-
enum: ['rollback', 'continue'],
|
|
2144
|
-
description: "Error handling mode: 'rollback' stops and undoes all, 'continue' skips failures (default: 'continue')",
|
|
2145
|
-
},
|
|
2146
|
-
},
|
|
2147
|
-
required: ['dependencies'],
|
|
2148
|
-
},
|
|
2149
|
-
},
|
|
2150
1200
|
{
|
|
2151
1201
|
name: 'bulk_update_tickets',
|
|
2152
1202
|
description: 'Update multiple tickets in a single atomic operation. All updates succeed or all fail (unless atomic: false).',
|
|
@@ -2544,34 +1594,6 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
|
|
|
2544
1594
|
// ========================================================================
|
|
2545
1595
|
// Delete Operations
|
|
2546
1596
|
// ========================================================================
|
|
2547
|
-
{
|
|
2548
|
-
name: 'delete_ticket',
|
|
2549
|
-
description: 'Delete a ticket and all its related records (dependencies, test results, discoveries, blueprint references)',
|
|
2550
|
-
inputSchema: {
|
|
2551
|
-
type: 'object',
|
|
2552
|
-
properties: {
|
|
2553
|
-
ticketId: {
|
|
2554
|
-
type: 'string',
|
|
2555
|
-
description: 'The ID of the ticket to delete',
|
|
2556
|
-
},
|
|
2557
|
-
},
|
|
2558
|
-
required: ['ticketId'],
|
|
2559
|
-
},
|
|
2560
|
-
},
|
|
2561
|
-
{
|
|
2562
|
-
name: 'delete_epic',
|
|
2563
|
-
description: 'Delete an epic and cascade delete all its tickets and related records',
|
|
2564
|
-
inputSchema: {
|
|
2565
|
-
type: 'object',
|
|
2566
|
-
properties: {
|
|
2567
|
-
epicId: {
|
|
2568
|
-
type: 'string',
|
|
2569
|
-
description: 'The ID of the epic to delete',
|
|
2570
|
-
},
|
|
2571
|
-
},
|
|
2572
|
-
required: ['epicId'],
|
|
2573
|
-
},
|
|
2574
|
-
},
|
|
2575
1597
|
{
|
|
2576
1598
|
name: 'delete_specification',
|
|
2577
1599
|
description: 'Delete a specification and cascade delete all epics, tickets, and related records',
|
|
@@ -2665,54 +1687,42 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
|
|
|
2665
1687
|
// Review & Completion
|
|
2666
1688
|
// ========================================================================
|
|
2667
1689
|
{
|
|
2668
|
-
name: '
|
|
2669
|
-
description: 'Review the
|
|
1690
|
+
name: 'review_implementation',
|
|
1691
|
+
description: 'Review the implementation progress and quality of a specification. Analyzes completed tickets, test coverage, code quality signals, and remaining work. Returns a progress report with recommendations.',
|
|
2670
1692
|
inputSchema: {
|
|
2671
1693
|
type: 'object',
|
|
2672
1694
|
properties: {
|
|
2673
1695
|
specificationId: {
|
|
2674
1696
|
type: 'string',
|
|
2675
|
-
description: 'The ID of the specification to review',
|
|
2676
|
-
},
|
|
2677
|
-
page: {
|
|
2678
|
-
type: 'integer',
|
|
2679
|
-
description: 'Page number for paginated results (default: 1)',
|
|
2680
|
-
},
|
|
2681
|
-
pageSize: {
|
|
2682
|
-
type: 'integer',
|
|
2683
|
-
description: 'Number of items per page (default: 20)',
|
|
2684
|
-
},
|
|
2685
|
-
includeFullReport: {
|
|
2686
|
-
type: 'boolean',
|
|
2687
|
-
description: 'Whether to include the full detailed report (default: false)',
|
|
1697
|
+
description: 'The ID of the specification to review',
|
|
2688
1698
|
},
|
|
2689
1699
|
},
|
|
2690
1700
|
required: ['specificationId'],
|
|
2691
1701
|
},
|
|
2692
1702
|
},
|
|
2693
1703
|
{
|
|
2694
|
-
name: '
|
|
2695
|
-
description: '
|
|
1704
|
+
name: 'complete_specification',
|
|
1705
|
+
description: 'Mark a specification as complete. Validates that all epics and tickets are done, calculates final metrics, and transitions the specification to completed status. Use review_implementation first to check readiness.',
|
|
2696
1706
|
inputSchema: {
|
|
2697
1707
|
type: 'object',
|
|
2698
1708
|
properties: {
|
|
2699
1709
|
specificationId: {
|
|
2700
1710
|
type: 'string',
|
|
2701
|
-
description: 'The ID of the specification to
|
|
1711
|
+
description: 'The ID of the specification to complete',
|
|
2702
1712
|
},
|
|
2703
1713
|
},
|
|
2704
1714
|
required: ['specificationId'],
|
|
2705
1715
|
},
|
|
2706
1716
|
},
|
|
2707
1717
|
{
|
|
2708
|
-
name: '
|
|
2709
|
-
description: '
|
|
1718
|
+
name: 'reopen_specification',
|
|
1719
|
+
description: 'Reopen a specification in "ready" status, regressing to "planning". After reopening, call start_planning_session to begin a new planning session.',
|
|
2710
1720
|
inputSchema: {
|
|
2711
1721
|
type: 'object',
|
|
2712
1722
|
properties: {
|
|
2713
1723
|
specificationId: {
|
|
2714
1724
|
type: 'string',
|
|
2715
|
-
description: 'The ID of the specification to
|
|
1725
|
+
description: 'The ID of the specification to reopen',
|
|
2716
1726
|
},
|
|
2717
1727
|
},
|
|
2718
1728
|
required: ['specificationId'],
|
|
@@ -2738,9 +1748,85 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
|
|
|
2738
1748
|
},
|
|
2739
1749
|
},
|
|
2740
1750
|
},
|
|
1751
|
+
// ========================================================================
|
|
1752
|
+
// Planning Session Operations
|
|
1753
|
+
// ========================================================================
|
|
1754
|
+
{
|
|
1755
|
+
name: 'start_planning_session',
|
|
1756
|
+
description: 'Start or resume a guided planning session for a specification. Auto-detects the current state — whether the spec is new, partially complete, or needs refinement after review. Returns current status, progress scores, blockers, and suggested next actions. Always call this before using action_planning_session.',
|
|
1757
|
+
inputSchema: {
|
|
1758
|
+
type: 'object',
|
|
1759
|
+
properties: {
|
|
1760
|
+
specificationId: {
|
|
1761
|
+
type: 'string',
|
|
1762
|
+
description: 'The ID of the specification to plan',
|
|
1763
|
+
},
|
|
1764
|
+
},
|
|
1765
|
+
required: ['specificationId'],
|
|
1766
|
+
},
|
|
1767
|
+
},
|
|
1768
|
+
{
|
|
1769
|
+
name: 'action_planning_session',
|
|
1770
|
+
description: "Execute a planning action within an active session. Wraps all planning operations (create/update epics, tickets, dependencies, blueprints) and read operations (get_ticket for inspecting details) with automatic status tracking. The spec status advances or regresses automatically based on the action type and gate checks. Returns updated progress, blockers, and next suggested actions after every call. Use responseDetail to control verbosity: 'minimal' (~80 tokens) for rapid iteration, 'standard' (~200 tokens, default) for normal work, 'full' (~500 tokens) for debugging.",
|
|
1771
|
+
inputSchema: {
|
|
1772
|
+
type: 'object',
|
|
1773
|
+
properties: {
|
|
1774
|
+
specificationId: {
|
|
1775
|
+
type: 'string',
|
|
1776
|
+
description: 'The ID of the specification',
|
|
1777
|
+
},
|
|
1778
|
+
operation: {
|
|
1779
|
+
type: 'object',
|
|
1780
|
+
description: 'The operation to perform. Must include a "type" field.',
|
|
1781
|
+
properties: {
|
|
1782
|
+
type: {
|
|
1783
|
+
type: 'string',
|
|
1784
|
+
enum: [
|
|
1785
|
+
'set_metadata',
|
|
1786
|
+
'create_epic',
|
|
1787
|
+
'update_epic',
|
|
1788
|
+
'create_ticket',
|
|
1789
|
+
'update_ticket',
|
|
1790
|
+
'delete_epic',
|
|
1791
|
+
'delete_ticket',
|
|
1792
|
+
'add_dependencies',
|
|
1793
|
+
'remove_dependency',
|
|
1794
|
+
'create_blueprint',
|
|
1795
|
+
'link_blueprint',
|
|
1796
|
+
'get_ticket',
|
|
1797
|
+
'advance_phase',
|
|
1798
|
+
'get_status',
|
|
1799
|
+
],
|
|
1800
|
+
description: 'The type of planning operation to perform',
|
|
1801
|
+
},
|
|
1802
|
+
},
|
|
1803
|
+
required: ['type'],
|
|
1804
|
+
},
|
|
1805
|
+
responseDetail: {
|
|
1806
|
+
type: 'string',
|
|
1807
|
+
enum: ['minimal', 'standard', 'full'],
|
|
1808
|
+
description: 'Response detail level: minimal (~80 tokens), standard (~200, default), full (~500)',
|
|
1809
|
+
},
|
|
1810
|
+
},
|
|
1811
|
+
required: ['specificationId', 'operation'],
|
|
1812
|
+
},
|
|
1813
|
+
},
|
|
1814
|
+
{
|
|
1815
|
+
name: 'complete_planning_session',
|
|
1816
|
+
description: "Complete the planning session and submit the spec for final review. Spec must be in 'validating' status. Runs a dry-run check first, then full review if no errors. Transitions spec to 'ready' on success. If the spec isn't in validating yet, returns what's needed to get there.",
|
|
1817
|
+
inputSchema: {
|
|
1818
|
+
type: 'object',
|
|
1819
|
+
properties: {
|
|
1820
|
+
specificationId: {
|
|
1821
|
+
type: 'string',
|
|
1822
|
+
description: 'The ID of the specification to complete planning for',
|
|
1823
|
+
},
|
|
1824
|
+
},
|
|
1825
|
+
required: ['specificationId'],
|
|
1826
|
+
},
|
|
1827
|
+
},
|
|
2741
1828
|
];
|
|
2742
|
-
|
|
2743
|
-
return tools.map(tool => READ_TOOL_NAMES.has(tool.name) ? addFormatParameter(tool) : tool);
|
|
1829
|
+
return tools;
|
|
2744
1830
|
}
|
|
2745
1831
|
/**
|
|
2746
1832
|
* Retry configuration for transient failures
|
|
@@ -2849,14 +1935,6 @@ export function createToolHandlers(apiClient) {
|
|
|
2849
1935
|
fields: argsWithContext.fields,
|
|
2850
1936
|
});
|
|
2851
1937
|
},
|
|
2852
|
-
get_specification: async (_client, args) => {
|
|
2853
|
-
validateRequired(args, 'specificationId');
|
|
2854
|
-
return await apiClient.call('get_specification', {
|
|
2855
|
-
specificationId: args.specificationId,
|
|
2856
|
-
summary: args.summary,
|
|
2857
|
-
include: args.include,
|
|
2858
|
-
});
|
|
2859
|
-
},
|
|
2860
1938
|
lookup_specification: async (_client, args) => {
|
|
2861
1939
|
validateRequired(args, 'title');
|
|
2862
1940
|
// Inject projectId from .specforge.json if not provided
|
|
@@ -2881,14 +1959,6 @@ export function createToolHandlers(apiClient) {
|
|
|
2881
1959
|
fields: argsWithContext.fields,
|
|
2882
1960
|
});
|
|
2883
1961
|
},
|
|
2884
|
-
get_epic: async (_client, args) => {
|
|
2885
|
-
validateRequired(args, 'epicId');
|
|
2886
|
-
return await apiClient.call('get_epic', {
|
|
2887
|
-
epicId: args.epicId,
|
|
2888
|
-
summary: args.summary,
|
|
2889
|
-
include: args.include,
|
|
2890
|
-
});
|
|
2891
|
-
},
|
|
2892
1962
|
lookup_epic: async (_client, args) => {
|
|
2893
1963
|
// Must provide either title or number
|
|
2894
1964
|
if (!args.title && args.number === undefined) {
|
|
@@ -2920,14 +1990,6 @@ export function createToolHandlers(apiClient) {
|
|
|
2920
1990
|
fields: argsWithContext.fields,
|
|
2921
1991
|
});
|
|
2922
1992
|
},
|
|
2923
|
-
get_ticket: async (_client, args) => {
|
|
2924
|
-
validateRequired(args, 'ticketId');
|
|
2925
|
-
return await apiClient.call('get_ticket', {
|
|
2926
|
-
ticketId: args.ticketId,
|
|
2927
|
-
summary: args.summary,
|
|
2928
|
-
include: args.include,
|
|
2929
|
-
});
|
|
2930
|
-
},
|
|
2931
1993
|
lookup_ticket: async (_client, args) => {
|
|
2932
1994
|
validateRequired(args, 'epicId');
|
|
2933
1995
|
// Must provide either title or number
|
|
@@ -2965,42 +2027,6 @@ export function createToolHandlers(apiClient) {
|
|
|
2965
2027
|
});
|
|
2966
2028
|
},
|
|
2967
2029
|
// ========================================================================
|
|
2968
|
-
// Core Operations - Dependencies
|
|
2969
|
-
// ========================================================================
|
|
2970
|
-
add_dependency: async (_client, args) => {
|
|
2971
|
-
validateRequired(args, 'ticketId');
|
|
2972
|
-
validateRequired(args, 'dependsOnId');
|
|
2973
|
-
return await apiClient.call('add_dependency', {
|
|
2974
|
-
ticketId: args.ticketId,
|
|
2975
|
-
dependsOnId: args.dependsOnId,
|
|
2976
|
-
type: args.type,
|
|
2977
|
-
});
|
|
2978
|
-
},
|
|
2979
|
-
remove_dependency: async (_client, args) => {
|
|
2980
|
-
// Either dependencyId or (ticketId + dependsOnId) required
|
|
2981
|
-
if (!args.dependencyId && !args.ticketId) {
|
|
2982
|
-
throw new Error('Either dependencyId or ticketId is required');
|
|
2983
|
-
}
|
|
2984
|
-
return await apiClient.call('remove_dependency', {
|
|
2985
|
-
ticketId: args.ticketId,
|
|
2986
|
-
dependsOnId: args.dependsOnId,
|
|
2987
|
-
dependencyId: args.dependencyId,
|
|
2988
|
-
});
|
|
2989
|
-
},
|
|
2990
|
-
get_dependency_tree: async (_client, args) => {
|
|
2991
|
-
validateRequired(args, 'specificationId');
|
|
2992
|
-
return await apiClient.call('get_dependency_tree', {
|
|
2993
|
-
specificationId: args.specificationId,
|
|
2994
|
-
});
|
|
2995
|
-
},
|
|
2996
|
-
check_circular_dependencies: async (_client, args) => {
|
|
2997
|
-
const argsWithContext = injectContext(args, ['specificationId', 'projectId']);
|
|
2998
|
-
return await apiClient.call('check_circular_dependencies', {
|
|
2999
|
-
specificationId: argsWithContext.specificationId,
|
|
3000
|
-
projectId: argsWithContext.projectId,
|
|
3001
|
-
});
|
|
3002
|
-
},
|
|
3003
|
-
// ========================================================================
|
|
3004
2030
|
// Context & AI Tools
|
|
3005
2031
|
// ========================================================================
|
|
3006
2032
|
get_implementation_context: async (_client, args) => {
|
|
@@ -3075,16 +2101,6 @@ export function createToolHandlers(apiClient) {
|
|
|
3075
2101
|
specificationId: argsWithContext.specificationId,
|
|
3076
2102
|
});
|
|
3077
2103
|
},
|
|
3078
|
-
get_critical_path: async (_client, args) => {
|
|
3079
|
-
// Inject specificationId from .specforge.json if not provided
|
|
3080
|
-
const argsWithContext = injectContext(args, ['specificationId']);
|
|
3081
|
-
if (!argsWithContext.specificationId) {
|
|
3082
|
-
throw new Error('specificationId is required. Set working context with "specforge switch" or provide explicitly.');
|
|
3083
|
-
}
|
|
3084
|
-
return await apiClient.call('get_critical_path', {
|
|
3085
|
-
specificationId: argsWithContext.specificationId,
|
|
3086
|
-
});
|
|
3087
|
-
},
|
|
3088
2104
|
get_patterns: async (_client, args) => {
|
|
3089
2105
|
// Inject specificationId from .specforge.json if not provided
|
|
3090
2106
|
const argsWithContext = injectContext(args, ['specificationId']);
|
|
@@ -3261,6 +2277,7 @@ export function createToolHandlers(apiClient) {
|
|
|
3261
2277
|
filesDeleted: args.filesDeleted,
|
|
3262
2278
|
blockReason: args.blockReason,
|
|
3263
2279
|
clearBlockReason: args.clearBlockReason,
|
|
2280
|
+
getTicket: args.getTicket,
|
|
3264
2281
|
});
|
|
3265
2282
|
},
|
|
3266
2283
|
// ========================================================================
|
|
@@ -3375,79 +2392,6 @@ export function createToolHandlers(apiClient) {
|
|
|
3375
2392
|
});
|
|
3376
2393
|
return formatWriteResponse(result, responseMode, 'Specification created');
|
|
3377
2394
|
},
|
|
3378
|
-
create_epic: async (_client, args) => {
|
|
3379
|
-
validateRequired(args, 'specificationId', 'title', 'description', 'objective');
|
|
3380
|
-
const responseMode = getResponseModeFromArgs(args);
|
|
3381
|
-
const result = await apiClient.call('create_epic', {
|
|
3382
|
-
specificationId: args.specificationId,
|
|
3383
|
-
title: args.title,
|
|
3384
|
-
description: args.description,
|
|
3385
|
-
objective: args.objective,
|
|
3386
|
-
epicNumber: args.epicNumber,
|
|
3387
|
-
content: args.content,
|
|
3388
|
-
scope: args.scope,
|
|
3389
|
-
goals: args.goals,
|
|
3390
|
-
acceptanceCriteria: args.acceptanceCriteria,
|
|
3391
|
-
priority: args.priority,
|
|
3392
|
-
tags: args.tags,
|
|
3393
|
-
estimatedHours: args.estimatedHours,
|
|
3394
|
-
order: args.order,
|
|
3395
|
-
// FI-003 fields
|
|
3396
|
-
guardrails: args.guardrails,
|
|
3397
|
-
risks: args.risks,
|
|
3398
|
-
constraints: args.constraints,
|
|
3399
|
-
assumptions: args.assumptions,
|
|
3400
|
-
architecture: args.architecture,
|
|
3401
|
-
fileStructure: args.fileStructure,
|
|
3402
|
-
techStack: args.techStack,
|
|
3403
|
-
dependencies: args.dependencies,
|
|
3404
|
-
apiContracts: args.apiContracts,
|
|
3405
|
-
// Pattern inheritance fields (F7-002)
|
|
3406
|
-
sharedPatterns: args.sharedPatterns,
|
|
3407
|
-
additionalImports: args.additionalImports,
|
|
3408
|
-
commonFiles: args.commonFiles,
|
|
3409
|
-
});
|
|
3410
|
-
return formatWriteResponse(result, responseMode, 'Epic created');
|
|
3411
|
-
},
|
|
3412
|
-
create_ticket: async (_client, args) => {
|
|
3413
|
-
validateRequired(args, 'epicId', 'title');
|
|
3414
|
-
const responseMode = getResponseModeFromArgs(args);
|
|
3415
|
-
// Extract validation options
|
|
3416
|
-
const validationStrictness = args.validationStrictness === 'lenient' || args.validationStrictness === 'strict'
|
|
3417
|
-
? args.validationStrictness
|
|
3418
|
-
: 'normal';
|
|
3419
|
-
// Create the ticket
|
|
3420
|
-
const result = await apiClient.call('create_ticket', {
|
|
3421
|
-
epicId: args.epicId,
|
|
3422
|
-
title: args.title,
|
|
3423
|
-
ticketNumber: args.ticketNumber,
|
|
3424
|
-
description: args.description,
|
|
3425
|
-
implementation: args.implementation,
|
|
3426
|
-
technicalDetails: args.technicalDetails,
|
|
3427
|
-
acceptanceCriteria: args.acceptanceCriteria,
|
|
3428
|
-
priority: args.priority,
|
|
3429
|
-
complexity: args.complexity,
|
|
3430
|
-
tags: args.tags,
|
|
3431
|
-
estimatedHours: args.estimatedHours,
|
|
3432
|
-
order: args.order,
|
|
3433
|
-
dependsOn: args.dependsOn,
|
|
3434
|
-
notes: args.notes, // F8-001: Add missing notes field
|
|
3435
|
-
});
|
|
3436
|
-
// Run validation
|
|
3437
|
-
const validation = validateTicket({
|
|
3438
|
-
complexity: args.complexity,
|
|
3439
|
-
implementation: args.implementation,
|
|
3440
|
-
technicalDetails: args.technicalDetails,
|
|
3441
|
-
notes: args.notes,
|
|
3442
|
-
acceptanceCriteria: args.acceptanceCriteria,
|
|
3443
|
-
});
|
|
3444
|
-
// Filter warnings by strictness level
|
|
3445
|
-
const warnings = filterWarningsByStrictness(validation.warnings, validationStrictness);
|
|
3446
|
-
// Add validation results to response
|
|
3447
|
-
result.warnings = warnings;
|
|
3448
|
-
result.completenessScore = validation.completenessScore;
|
|
3449
|
-
return formatWriteResponse(result, responseMode, 'Ticket created');
|
|
3450
|
-
},
|
|
3451
2395
|
import_specification: async (_client, args) => {
|
|
3452
2396
|
validateRequired(args, 'projectId', 'content');
|
|
3453
2397
|
return await apiClient.call('import_specification', {
|
|
@@ -3458,145 +2402,6 @@ export function createToolHandlers(apiClient) {
|
|
|
3458
2402
|
});
|
|
3459
2403
|
},
|
|
3460
2404
|
// ========================================================================
|
|
3461
|
-
// Update Operations
|
|
3462
|
-
// ========================================================================
|
|
3463
|
-
update_ticket: async (_client, args) => {
|
|
3464
|
-
validateRequired(args, 'ticketId');
|
|
3465
|
-
const responseMode = getResponseModeFromArgs(args);
|
|
3466
|
-
// Extract validation options
|
|
3467
|
-
const validationStrictness = args.validationStrictness === 'lenient' || args.validationStrictness === 'strict'
|
|
3468
|
-
? args.validationStrictness
|
|
3469
|
-
: 'normal';
|
|
3470
|
-
// Get current ticket to calculate previous completeness score
|
|
3471
|
-
let previousCompletenessScore;
|
|
3472
|
-
try {
|
|
3473
|
-
const currentTicket = await apiClient.call('get_ticket', {
|
|
3474
|
-
ticketId: args.ticketId,
|
|
3475
|
-
});
|
|
3476
|
-
// Calculate previous completeness score
|
|
3477
|
-
const prevValidation = validateTicket({
|
|
3478
|
-
complexity: currentTicket.complexity,
|
|
3479
|
-
implementation: currentTicket.implementation,
|
|
3480
|
-
technicalDetails: currentTicket.technicalDetails,
|
|
3481
|
-
notes: currentTicket.notes,
|
|
3482
|
-
acceptanceCriteria: currentTicket.acceptanceCriteria,
|
|
3483
|
-
});
|
|
3484
|
-
previousCompletenessScore = prevValidation.completenessScore;
|
|
3485
|
-
}
|
|
3486
|
-
catch {
|
|
3487
|
-
// If we can't get the current ticket, skip previous score tracking
|
|
3488
|
-
previousCompletenessScore = undefined;
|
|
3489
|
-
}
|
|
3490
|
-
// Update the ticket
|
|
3491
|
-
const result = await apiClient.call('update_ticket', {
|
|
3492
|
-
ticketId: args.ticketId,
|
|
3493
|
-
title: args.title,
|
|
3494
|
-
description: args.description,
|
|
3495
|
-
status: args.status,
|
|
3496
|
-
priority: args.priority,
|
|
3497
|
-
estimatedHours: args.estimatedHours,
|
|
3498
|
-
tags: args.tags,
|
|
3499
|
-
acceptanceCriteria: args.acceptanceCriteria,
|
|
3500
|
-
// Additional fields
|
|
3501
|
-
complexity: args.complexity,
|
|
3502
|
-
notes: args.notes,
|
|
3503
|
-
implementation: args.implementation,
|
|
3504
|
-
technicalDetails: args.technicalDetails,
|
|
3505
|
-
blockReason: args.blockReason,
|
|
3506
|
-
});
|
|
3507
|
-
// Run validation on updated ticket
|
|
3508
|
-
// Use the updated values (from args) merged with existing values (from result)
|
|
3509
|
-
// The result should contain the final state after update
|
|
3510
|
-
const validation = validateTicket({
|
|
3511
|
-
complexity: (args.complexity || result.complexity),
|
|
3512
|
-
implementation: (args.implementation || result.implementation),
|
|
3513
|
-
technicalDetails: (args.technicalDetails || result.technicalDetails),
|
|
3514
|
-
notes: (args.notes || result.notes),
|
|
3515
|
-
acceptanceCriteria: (args.acceptanceCriteria || result.acceptanceCriteria),
|
|
3516
|
-
});
|
|
3517
|
-
// Filter warnings by strictness level
|
|
3518
|
-
const warnings = filterWarningsByStrictness(validation.warnings, validationStrictness);
|
|
3519
|
-
// Add validation results to response
|
|
3520
|
-
result.warnings = warnings;
|
|
3521
|
-
result.completenessScore = validation.completenessScore;
|
|
3522
|
-
if (previousCompletenessScore !== undefined) {
|
|
3523
|
-
result.previousCompletenessScore = previousCompletenessScore;
|
|
3524
|
-
}
|
|
3525
|
-
return formatWriteResponse(result, responseMode, 'Ticket updated');
|
|
3526
|
-
},
|
|
3527
|
-
update_epic: async (_client, args) => {
|
|
3528
|
-
validateRequired(args, 'epicId');
|
|
3529
|
-
const responseMode = getResponseModeFromArgs(args);
|
|
3530
|
-
const result = await apiClient.call('update_epic', {
|
|
3531
|
-
epicId: args.epicId,
|
|
3532
|
-
title: args.title,
|
|
3533
|
-
description: args.description,
|
|
3534
|
-
status: args.status,
|
|
3535
|
-
objective: args.objective,
|
|
3536
|
-
priority: args.priority,
|
|
3537
|
-
// FI-003 fields
|
|
3538
|
-
scope: args.scope,
|
|
3539
|
-
goals: args.goals,
|
|
3540
|
-
guardrails: args.guardrails,
|
|
3541
|
-
risks: args.risks,
|
|
3542
|
-
constraints: args.constraints,
|
|
3543
|
-
assumptions: args.assumptions,
|
|
3544
|
-
architecture: args.architecture,
|
|
3545
|
-
fileStructure: args.fileStructure,
|
|
3546
|
-
techStack: args.techStack,
|
|
3547
|
-
dependencies: args.dependencies,
|
|
3548
|
-
apiContracts: args.apiContracts,
|
|
3549
|
-
acceptanceCriteria: args.acceptanceCriteria,
|
|
3550
|
-
tags: args.tags,
|
|
3551
|
-
estimatedHours: args.estimatedHours,
|
|
3552
|
-
// Pattern inheritance fields (F7-002)
|
|
3553
|
-
sharedPatterns: args.sharedPatterns,
|
|
3554
|
-
additionalImports: args.additionalImports,
|
|
3555
|
-
commonFiles: args.commonFiles,
|
|
3556
|
-
});
|
|
3557
|
-
return formatWriteResponse(result, responseMode, 'Epic updated');
|
|
3558
|
-
},
|
|
3559
|
-
update_specification: async (_client, args) => {
|
|
3560
|
-
validateRequired(args, 'specificationId');
|
|
3561
|
-
const responseMode = getResponseModeFromArgs(args);
|
|
3562
|
-
const result = await apiClient.call('update_specification', {
|
|
3563
|
-
specificationId: args.specificationId,
|
|
3564
|
-
title: args.title,
|
|
3565
|
-
description: args.description,
|
|
3566
|
-
status: args.status,
|
|
3567
|
-
background: args.background,
|
|
3568
|
-
scope: args.scope,
|
|
3569
|
-
priority: args.priority,
|
|
3570
|
-
// FI-003 fields
|
|
3571
|
-
goals: args.goals,
|
|
3572
|
-
requirements: args.requirements,
|
|
3573
|
-
nonFunctionalRequirements: args.nonFunctionalRequirements,
|
|
3574
|
-
successMetrics: args.successMetrics,
|
|
3575
|
-
constraints: args.constraints,
|
|
3576
|
-
assumptions: args.assumptions,
|
|
3577
|
-
risks: args.risks,
|
|
3578
|
-
guardrails: args.guardrails,
|
|
3579
|
-
architecture: args.architecture,
|
|
3580
|
-
fileStructure: args.fileStructure,
|
|
3581
|
-
techStack: args.techStack,
|
|
3582
|
-
dependencies: args.dependencies,
|
|
3583
|
-
apiContracts: args.apiContracts,
|
|
3584
|
-
acceptanceCriteria: args.acceptanceCriteria,
|
|
3585
|
-
tags: args.tags,
|
|
3586
|
-
estimatedHours: args.estimatedHours,
|
|
3587
|
-
targetAudience: args.targetAudience,
|
|
3588
|
-
// Pattern inheritance fields (F7-001)
|
|
3589
|
-
codeStandards: args.codeStandards,
|
|
3590
|
-
commonImports: args.commonImports,
|
|
3591
|
-
returnTypes: args.returnTypes,
|
|
3592
|
-
// Validation and workflow fields
|
|
3593
|
-
validationCommands: args.validationCommands,
|
|
3594
|
-
workingDirectory: args.workingDirectory,
|
|
3595
|
-
outputDirectory: args.outputDirectory,
|
|
3596
|
-
});
|
|
3597
|
-
return formatWriteResponse(result, responseMode, 'Specification updated');
|
|
3598
|
-
},
|
|
3599
|
-
// ========================================================================
|
|
3600
2405
|
// Implementation Session Operations
|
|
3601
2406
|
// ========================================================================
|
|
3602
2407
|
start_implementation_session: async (_client, args) => {
|
|
@@ -3615,33 +2420,6 @@ export function createToolHandlers(apiClient) {
|
|
|
3615
2420
|
summary: args.summary,
|
|
3616
2421
|
});
|
|
3617
2422
|
},
|
|
3618
|
-
// ========================================================================
|
|
3619
|
-
// Bulk Operations
|
|
3620
|
-
// ========================================================================
|
|
3621
|
-
bulk_add_dependencies: async (_client, args) => {
|
|
3622
|
-
validateRequired(args, 'dependencies');
|
|
3623
|
-
if (!Array.isArray(args.dependencies) || args.dependencies.length === 0) {
|
|
3624
|
-
throw new Error('dependencies array is required and must not be empty');
|
|
3625
|
-
}
|
|
3626
|
-
// Validate each dependency has required fields
|
|
3627
|
-
const deps = args.dependencies;
|
|
3628
|
-
for (let i = 0; i < deps.length; i++) {
|
|
3629
|
-
if (!deps[i].ticketId || typeof deps[i].ticketId !== 'string') {
|
|
3630
|
-
throw new Error(`dependencies[${i}].ticketId is required`);
|
|
3631
|
-
}
|
|
3632
|
-
if (!deps[i].dependsOnId || typeof deps[i].dependsOnId !== 'string') {
|
|
3633
|
-
throw new Error(`dependencies[${i}].dependsOnId is required`);
|
|
3634
|
-
}
|
|
3635
|
-
if (deps[i].ticketId === deps[i].dependsOnId) {
|
|
3636
|
-
throw new Error(`dependencies[${i}]: ticket cannot depend on itself`);
|
|
3637
|
-
}
|
|
3638
|
-
}
|
|
3639
|
-
return await apiClient.call('bulk_add_dependencies', {
|
|
3640
|
-
dependencies: args.dependencies,
|
|
3641
|
-
skipCircularCheck: args.skipCircularCheck,
|
|
3642
|
-
onError: args.onError,
|
|
3643
|
-
});
|
|
3644
|
-
},
|
|
3645
2423
|
bulk_update_tickets: async (_client, args) => {
|
|
3646
2424
|
if (!args.updates || !Array.isArray(args.updates) || args.updates.length === 0) {
|
|
3647
2425
|
throw new Error('updates array is required and must not be empty');
|
|
@@ -3771,18 +2549,6 @@ export function createToolHandlers(apiClient) {
|
|
|
3771
2549
|
// ========================================================================
|
|
3772
2550
|
// Delete Operations
|
|
3773
2551
|
// ========================================================================
|
|
3774
|
-
delete_ticket: async (_client, args) => {
|
|
3775
|
-
validateRequired(args, 'ticketId');
|
|
3776
|
-
return await apiClient.call('delete_ticket', {
|
|
3777
|
-
ticketId: args.ticketId,
|
|
3778
|
-
});
|
|
3779
|
-
},
|
|
3780
|
-
delete_epic: async (_client, args) => {
|
|
3781
|
-
validateRequired(args, 'epicId');
|
|
3782
|
-
return await apiClient.call('delete_epic', {
|
|
3783
|
-
epicId: args.epicId,
|
|
3784
|
-
});
|
|
3785
|
-
},
|
|
3786
2552
|
delete_specification: async (_client, args) => {
|
|
3787
2553
|
validateRequired(args, 'specificationId');
|
|
3788
2554
|
return await apiClient.call('delete_specification', {
|
|
@@ -3832,15 +2598,6 @@ export function createToolHandlers(apiClient) {
|
|
|
3832
2598
|
// ========================================================================
|
|
3833
2599
|
// Review & Completion
|
|
3834
2600
|
// ========================================================================
|
|
3835
|
-
review_planning: async (_client, args) => {
|
|
3836
|
-
const argsWithContext = injectContextRequired(args, ['specificationId']);
|
|
3837
|
-
return await apiClient.call('review_planning', {
|
|
3838
|
-
specificationId: argsWithContext.specificationId,
|
|
3839
|
-
page: argsWithContext.page,
|
|
3840
|
-
pageSize: argsWithContext.pageSize,
|
|
3841
|
-
includeFullReport: argsWithContext.includeFullReport,
|
|
3842
|
-
});
|
|
3843
|
-
},
|
|
3844
2601
|
review_implementation: async (_client, args) => {
|
|
3845
2602
|
const argsWithContext = injectContextRequired(args, ['specificationId']);
|
|
3846
2603
|
return await apiClient.call('review_implementation', {
|
|
@@ -3853,12 +2610,44 @@ export function createToolHandlers(apiClient) {
|
|
|
3853
2610
|
specificationId: argsWithContext.specificationId,
|
|
3854
2611
|
});
|
|
3855
2612
|
},
|
|
2613
|
+
reopen_specification: async (_client, args) => {
|
|
2614
|
+
const argsWithContext = injectContextRequired(args, ['specificationId']);
|
|
2615
|
+
return await apiClient.call('reopen_specification', {
|
|
2616
|
+
specificationId: argsWithContext.specificationId,
|
|
2617
|
+
});
|
|
2618
|
+
},
|
|
3856
2619
|
// ========================================================================
|
|
3857
2620
|
// Agent Teams - Workspace Files (Local-only)
|
|
3858
2621
|
// ========================================================================
|
|
3859
2622
|
get_workspace_files: async (_client, args) => {
|
|
3860
2623
|
return await getWorkspaceFiles(args);
|
|
3861
2624
|
},
|
|
2625
|
+
// ========================================================================
|
|
2626
|
+
// Planning Session Operations
|
|
2627
|
+
// ========================================================================
|
|
2628
|
+
start_planning_session: async (_client, args) => {
|
|
2629
|
+
validateRequired(args, 'specificationId');
|
|
2630
|
+
return await apiClient.call('start_planning_session', {
|
|
2631
|
+
specificationId: args.specificationId,
|
|
2632
|
+
});
|
|
2633
|
+
},
|
|
2634
|
+
action_planning_session: async (_client, args) => {
|
|
2635
|
+
validateRequired(args, 'specificationId');
|
|
2636
|
+
if (!args.operation || typeof args.operation !== 'object') {
|
|
2637
|
+
throw new Error('Missing required argument: operation');
|
|
2638
|
+
}
|
|
2639
|
+
return await apiClient.call('action_planning_session', {
|
|
2640
|
+
specificationId: args.specificationId,
|
|
2641
|
+
operation: args.operation,
|
|
2642
|
+
responseDetail: args.responseDetail,
|
|
2643
|
+
});
|
|
2644
|
+
},
|
|
2645
|
+
complete_planning_session: async (_client, args) => {
|
|
2646
|
+
validateRequired(args, 'specificationId');
|
|
2647
|
+
return await apiClient.call('complete_planning_session', {
|
|
2648
|
+
specificationId: args.specificationId,
|
|
2649
|
+
});
|
|
2650
|
+
},
|
|
3862
2651
|
};
|
|
3863
2652
|
}
|
|
3864
2653
|
/**
|