@specforge/mcp 3.3.9 → 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/tools/core/blueprint.d.ts.map +1 -1
- package/dist/tools/core/blueprint.js +4 -29
- package/dist/tools/core/blueprint.js.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/index.d.ts.map +1 -1
- package/dist/tools/index.js +150 -1261
- 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';
|
|
@@ -140,40 +140,6 @@ export function getTools() {
|
|
|
140
140
|
required: ['projectId'],
|
|
141
141
|
},
|
|
142
142
|
},
|
|
143
|
-
{
|
|
144
|
-
name: 'get_specification',
|
|
145
|
-
description: `Get specification with optional summary mode or full details.
|
|
146
|
-
|
|
147
|
-
Use summary: true for minimal response (~70 tokens) with key fields only (id, title, status, priority, epicCount, ticketCount, completedTicketCount).
|
|
148
|
-
|
|
149
|
-
Optional includes (ignored when summary=true):
|
|
150
|
-
- 'status': Progress, ticket counts, blockers (replaces get_specification_status)
|
|
151
|
-
- 'epics': List of epics with summary data
|
|
152
|
-
- 'patterns': Tech stack, code patterns, naming conventions`,
|
|
153
|
-
inputSchema: {
|
|
154
|
-
type: 'object',
|
|
155
|
-
properties: {
|
|
156
|
-
specificationId: {
|
|
157
|
-
type: 'string',
|
|
158
|
-
description: 'The ID of the specification to retrieve',
|
|
159
|
-
},
|
|
160
|
-
summary: {
|
|
161
|
-
type: 'boolean',
|
|
162
|
-
description: 'Return minimal summary fields only (~70 tokens vs ~600 full). Ignores include parameter when true. Default: false',
|
|
163
|
-
default: false,
|
|
164
|
-
},
|
|
165
|
-
include: {
|
|
166
|
-
type: 'array',
|
|
167
|
-
items: {
|
|
168
|
-
type: 'string',
|
|
169
|
-
enum: ['status', 'epics', 'patterns'],
|
|
170
|
-
},
|
|
171
|
-
description: 'Optional data to include in response (ignored when summary=true)',
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
required: ['specificationId'],
|
|
175
|
-
},
|
|
176
|
-
},
|
|
177
143
|
{
|
|
178
144
|
name: 'lookup_specification',
|
|
179
145
|
description: 'Fast specification lookup by title. Returns minimal data (id, title, status, epicCount, ticketCount) for token efficiency.',
|
|
@@ -197,7 +163,7 @@ Optional includes (ignored when summary=true):
|
|
|
197
163
|
// ========================================================================
|
|
198
164
|
{
|
|
199
165
|
name: 'list_epics',
|
|
200
|
-
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.',
|
|
201
167
|
inputSchema: {
|
|
202
168
|
type: 'object',
|
|
203
169
|
properties: {
|
|
@@ -251,39 +217,6 @@ Optional includes (ignored when summary=true):
|
|
|
251
217
|
required: ['specificationId'],
|
|
252
218
|
},
|
|
253
219
|
},
|
|
254
|
-
{
|
|
255
|
-
name: 'get_epic',
|
|
256
|
-
description: `Get epic with optional summary mode or full details.
|
|
257
|
-
|
|
258
|
-
Use summary: true for minimal response (~80 tokens) with key fields only (id, epicNumber, title, status, objective, ticketCount, completedTicketCount).
|
|
259
|
-
|
|
260
|
-
Optional includes (ignored when summary=true):
|
|
261
|
-
- 'status': Progress percentage, ticket counts, active tickets (replaces get_epic_status)
|
|
262
|
-
- 'tickets': List of tickets with summary data`,
|
|
263
|
-
inputSchema: {
|
|
264
|
-
type: 'object',
|
|
265
|
-
properties: {
|
|
266
|
-
epicId: {
|
|
267
|
-
type: 'string',
|
|
268
|
-
description: 'The ID of the epic to retrieve',
|
|
269
|
-
},
|
|
270
|
-
summary: {
|
|
271
|
-
type: 'boolean',
|
|
272
|
-
description: 'Return minimal summary fields only (~80 tokens vs ~400 full). Ignores include parameter when true. Default: false',
|
|
273
|
-
default: false,
|
|
274
|
-
},
|
|
275
|
-
include: {
|
|
276
|
-
type: 'array',
|
|
277
|
-
items: {
|
|
278
|
-
type: 'string',
|
|
279
|
-
enum: ['status', 'tickets'],
|
|
280
|
-
},
|
|
281
|
-
description: 'Optional data to include in response (ignored when summary=true)',
|
|
282
|
-
},
|
|
283
|
-
},
|
|
284
|
-
required: ['epicId'],
|
|
285
|
-
},
|
|
286
|
-
},
|
|
287
220
|
{
|
|
288
221
|
name: 'lookup_epic',
|
|
289
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.",
|
|
@@ -311,7 +244,7 @@ Optional includes (ignored when summary=true):
|
|
|
311
244
|
// ========================================================================
|
|
312
245
|
{
|
|
313
246
|
name: 'list_tickets',
|
|
314
|
-
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.',
|
|
315
248
|
inputSchema: {
|
|
316
249
|
type: 'object',
|
|
317
250
|
properties: {
|
|
@@ -382,44 +315,6 @@ Optional includes (ignored when summary=true):
|
|
|
382
315
|
required: ['epicId'],
|
|
383
316
|
},
|
|
384
317
|
},
|
|
385
|
-
{
|
|
386
|
-
name: 'get_ticket',
|
|
387
|
-
description: `Get ticket with optional summary mode or full details.
|
|
388
|
-
|
|
389
|
-
Use summary: true for minimal response (~100 tokens) with key fields only (id, ticketNumber, title, status, complexity, estimatedHours, priority).
|
|
390
|
-
|
|
391
|
-
For full details, statusReason is auto-included for pending tickets explaining why the ticket is blocked.
|
|
392
|
-
|
|
393
|
-
Optional includes (ignored when summary=true):
|
|
394
|
-
- 'dependencies': Tickets this blocks and is blocked by (replaces get_ticket_dependencies)
|
|
395
|
-
- 'testStatus': Test results and history (replaces get_ticket_test_status)
|
|
396
|
-
- 'commits': Linked git commits (replaces get_ticket_commits)
|
|
397
|
-
- 'prs': Linked pull requests (replaces get_ticket_prs)
|
|
398
|
-
- 'statusReason': Why ticket is pending (auto-included for pending tickets)`,
|
|
399
|
-
inputSchema: {
|
|
400
|
-
type: 'object',
|
|
401
|
-
properties: {
|
|
402
|
-
ticketId: {
|
|
403
|
-
type: 'string',
|
|
404
|
-
description: 'The ID of the ticket to retrieve',
|
|
405
|
-
},
|
|
406
|
-
summary: {
|
|
407
|
-
type: 'boolean',
|
|
408
|
-
description: 'Return minimal summary fields only (~100 tokens vs ~500 full). Ignores include parameter when true. Default: false',
|
|
409
|
-
default: false,
|
|
410
|
-
},
|
|
411
|
-
include: {
|
|
412
|
-
type: 'array',
|
|
413
|
-
items: {
|
|
414
|
-
type: 'string',
|
|
415
|
-
enum: ['dependencies', 'testStatus', 'commits', 'prs', 'statusReason'],
|
|
416
|
-
},
|
|
417
|
-
description: 'Additional data to include (ignored when summary=true). statusReason is auto-included for pending tickets.',
|
|
418
|
-
},
|
|
419
|
-
},
|
|
420
|
-
required: ['ticketId'],
|
|
421
|
-
},
|
|
422
|
-
},
|
|
423
318
|
{
|
|
424
319
|
name: 'lookup_ticket',
|
|
425
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.",
|
|
@@ -459,90 +354,6 @@ Optional includes (ignored when summary=true):
|
|
|
459
354
|
},
|
|
460
355
|
},
|
|
461
356
|
// ========================================================================
|
|
462
|
-
// Core Operations - Dependencies (Epic 3)
|
|
463
|
-
// ========================================================================
|
|
464
|
-
{
|
|
465
|
-
name: 'add_dependency',
|
|
466
|
-
description: 'Add a dependency between two tickets. The first ticket will depend on the second.',
|
|
467
|
-
inputSchema: {
|
|
468
|
-
type: 'object',
|
|
469
|
-
properties: {
|
|
470
|
-
ticketId: {
|
|
471
|
-
type: 'string',
|
|
472
|
-
description: 'The ID of the ticket that will depend on another',
|
|
473
|
-
},
|
|
474
|
-
dependsOnId: {
|
|
475
|
-
type: 'string',
|
|
476
|
-
description: 'The ID of the ticket it will depend on',
|
|
477
|
-
},
|
|
478
|
-
type: {
|
|
479
|
-
type: 'string',
|
|
480
|
-
enum: ['blocks', 'requires'],
|
|
481
|
-
description: "Type of dependency (default: 'requires')",
|
|
482
|
-
},
|
|
483
|
-
},
|
|
484
|
-
required: ['ticketId', 'dependsOnId'],
|
|
485
|
-
},
|
|
486
|
-
},
|
|
487
|
-
{
|
|
488
|
-
name: 'remove_dependency',
|
|
489
|
-
description: 'Remove a dependency between two tickets',
|
|
490
|
-
inputSchema: {
|
|
491
|
-
type: 'object',
|
|
492
|
-
properties: {
|
|
493
|
-
ticketId: {
|
|
494
|
-
type: 'string',
|
|
495
|
-
description: 'The ID of the dependent ticket',
|
|
496
|
-
},
|
|
497
|
-
dependsOnId: {
|
|
498
|
-
type: 'string',
|
|
499
|
-
description: 'The ID of the ticket it depends on',
|
|
500
|
-
},
|
|
501
|
-
dependencyId: {
|
|
502
|
-
type: 'string',
|
|
503
|
-
description: 'Alternative: Direct ID of the dependency record',
|
|
504
|
-
},
|
|
505
|
-
},
|
|
506
|
-
},
|
|
507
|
-
},
|
|
508
|
-
{
|
|
509
|
-
name: 'get_dependency_tree',
|
|
510
|
-
description: 'Get the full dependency tree for a specification, showing all tickets and their dependency relationships',
|
|
511
|
-
inputSchema: {
|
|
512
|
-
type: 'object',
|
|
513
|
-
properties: {
|
|
514
|
-
specificationId: {
|
|
515
|
-
type: 'string',
|
|
516
|
-
description: 'The ID of the specification',
|
|
517
|
-
},
|
|
518
|
-
},
|
|
519
|
-
required: ['specificationId'],
|
|
520
|
-
},
|
|
521
|
-
},
|
|
522
|
-
{
|
|
523
|
-
name: 'check_circular_dependencies',
|
|
524
|
-
description: `Check for circular dependencies between tickets in a specification.
|
|
525
|
-
|
|
526
|
-
Returns any cycles found where tickets depend on each other in a loop (e.g., A→B→C→A).
|
|
527
|
-
|
|
528
|
-
Examples:
|
|
529
|
-
- check_circular_dependencies specificationId="spec-123"
|
|
530
|
-
- check_circular_dependencies projectId="proj-123" // Check all specs in project`,
|
|
531
|
-
inputSchema: {
|
|
532
|
-
type: 'object',
|
|
533
|
-
properties: {
|
|
534
|
-
specificationId: {
|
|
535
|
-
type: 'string',
|
|
536
|
-
description: 'Specification ID to check (optional if projectId provided)',
|
|
537
|
-
},
|
|
538
|
-
projectId: {
|
|
539
|
-
type: 'string',
|
|
540
|
-
description: 'Project ID to check all specifications (optional if specificationId provided)',
|
|
541
|
-
},
|
|
542
|
-
},
|
|
543
|
-
},
|
|
544
|
-
},
|
|
545
|
-
// ========================================================================
|
|
546
357
|
// Context & AI Tools (Epic 4)
|
|
547
358
|
// ========================================================================
|
|
548
359
|
{
|
|
@@ -600,20 +411,6 @@ Examples:
|
|
|
600
411
|
required: ['specificationId'],
|
|
601
412
|
},
|
|
602
413
|
},
|
|
603
|
-
{
|
|
604
|
-
name: 'get_critical_path',
|
|
605
|
-
description: 'Get the critical path (longest dependency chain) for a specification',
|
|
606
|
-
inputSchema: {
|
|
607
|
-
type: 'object',
|
|
608
|
-
properties: {
|
|
609
|
-
specificationId: {
|
|
610
|
-
type: 'string',
|
|
611
|
-
description: 'The ID of the specification',
|
|
612
|
-
},
|
|
613
|
-
},
|
|
614
|
-
required: ['specificationId'],
|
|
615
|
-
},
|
|
616
|
-
},
|
|
617
414
|
{
|
|
618
415
|
name: 'get_patterns',
|
|
619
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.',
|
|
@@ -636,7 +433,7 @@ Examples:
|
|
|
636
433
|
// ========================================================================
|
|
637
434
|
{
|
|
638
435
|
name: 'start_work_session',
|
|
639
|
-
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.',
|
|
640
437
|
inputSchema: {
|
|
641
438
|
type: 'object',
|
|
642
439
|
properties: {
|
|
@@ -763,7 +560,9 @@ Use this instead of calling update_ticket for checklist changes. Provides:
|
|
|
763
560
|
- Auto-calculated progress percentage
|
|
764
561
|
- Completion readiness hints
|
|
765
562
|
|
|
766
|
-
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.`,
|
|
767
566
|
inputSchema: {
|
|
768
567
|
type: 'object',
|
|
769
568
|
properties: {
|
|
@@ -888,6 +687,10 @@ IMPORTANT: All acceptance criteria must be validated and all implementation step
|
|
|
888
687
|
type: 'boolean',
|
|
889
688
|
description: 'Clear existing blocker and resume work.',
|
|
890
689
|
},
|
|
690
|
+
getTicket: {
|
|
691
|
+
type: 'boolean',
|
|
692
|
+
description: 'Fetch full ticket details. Can be the sole operation or combined with other actions.',
|
|
693
|
+
},
|
|
891
694
|
},
|
|
892
695
|
required: ['ticketId'],
|
|
893
696
|
},
|
|
@@ -952,7 +755,7 @@ Combines:
|
|
|
952
755
|
- Status, complexity, priority filters
|
|
953
756
|
|
|
954
757
|
At least one of: query, files, tags, or relatedTo is required.
|
|
955
|
-
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.`,
|
|
956
759
|
inputSchema: {
|
|
957
760
|
type: 'object',
|
|
958
761
|
properties: {
|
|
@@ -1129,7 +932,7 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
|
|
|
1129
932
|
// ========================================================================
|
|
1130
933
|
{
|
|
1131
934
|
name: 'create_specification',
|
|
1132
|
-
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.',
|
|
1133
936
|
inputSchema: {
|
|
1134
937
|
type: 'object',
|
|
1135
938
|
properties: {
|
|
@@ -1293,659 +1096,45 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
|
|
|
1293
1096
|
},
|
|
1294
1097
|
},
|
|
1295
1098
|
{
|
|
1296
|
-
name: '
|
|
1297
|
-
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.',
|
|
1298
1101
|
inputSchema: {
|
|
1299
1102
|
type: 'object',
|
|
1300
1103
|
properties: {
|
|
1301
|
-
|
|
1302
|
-
type: 'string',
|
|
1303
|
-
description: 'The ID of the specification',
|
|
1304
|
-
},
|
|
1305
|
-
title: {
|
|
1306
|
-
type: 'string',
|
|
1307
|
-
description: 'Epic title',
|
|
1308
|
-
},
|
|
1309
|
-
description: {
|
|
1310
|
-
type: 'string',
|
|
1311
|
-
description: 'Detailed description',
|
|
1312
|
-
},
|
|
1313
|
-
objective: {
|
|
1104
|
+
projectId: {
|
|
1314
1105
|
type: 'string',
|
|
1315
|
-
description: '
|
|
1316
|
-
},
|
|
1317
|
-
epicNumber: {
|
|
1318
|
-
type: 'number',
|
|
1319
|
-
description: 'Epic number (auto-incremented if not provided)',
|
|
1106
|
+
description: 'The ID of the project to import into',
|
|
1320
1107
|
},
|
|
1321
1108
|
content: {
|
|
1322
1109
|
type: 'string',
|
|
1323
|
-
description: '
|
|
1324
|
-
},
|
|
1325
|
-
scope: {
|
|
1326
|
-
type: 'string',
|
|
1327
|
-
description: "What's in/out of scope for this epic",
|
|
1328
|
-
},
|
|
1329
|
-
goals: {
|
|
1330
|
-
type: 'array',
|
|
1331
|
-
items: { type: 'string' },
|
|
1332
|
-
description: 'Epic-specific goals',
|
|
1333
|
-
},
|
|
1334
|
-
guardrails: {
|
|
1335
|
-
type: 'array',
|
|
1336
|
-
items: { type: 'string' },
|
|
1337
|
-
description: 'What NOT to do for this epic',
|
|
1338
|
-
},
|
|
1339
|
-
risks: {
|
|
1340
|
-
type: 'array',
|
|
1341
|
-
items: { type: 'string' },
|
|
1342
|
-
description: 'Risk factors for this epic',
|
|
1343
|
-
},
|
|
1344
|
-
constraints: {
|
|
1345
|
-
type: 'array',
|
|
1346
|
-
items: { type: 'string' },
|
|
1347
|
-
description: 'Technical or business constraints for this epic',
|
|
1348
|
-
},
|
|
1349
|
-
assumptions: {
|
|
1350
|
-
type: 'array',
|
|
1351
|
-
items: { type: 'string' },
|
|
1352
|
-
description: 'Key assumptions made for this epic',
|
|
1353
|
-
},
|
|
1354
|
-
architecture: {
|
|
1355
|
-
type: 'string',
|
|
1356
|
-
description: 'Architectural approach for this epic',
|
|
1357
|
-
},
|
|
1358
|
-
fileStructure: {
|
|
1359
|
-
type: 'string',
|
|
1360
|
-
description: 'File/folder organization for this epic',
|
|
1361
|
-
},
|
|
1362
|
-
techStack: {
|
|
1363
|
-
type: 'array',
|
|
1364
|
-
items: { type: 'string' },
|
|
1365
|
-
description: 'Technologies used (subset of specification)',
|
|
1366
|
-
},
|
|
1367
|
-
dependencies: {
|
|
1368
|
-
type: 'array',
|
|
1369
|
-
items: { type: 'string' },
|
|
1370
|
-
description: 'Required packages/libraries',
|
|
1371
|
-
},
|
|
1372
|
-
apiContracts: {
|
|
1373
|
-
type: 'object',
|
|
1374
|
-
description: 'API specifications for this epic',
|
|
1375
|
-
},
|
|
1376
|
-
acceptanceCriteria: {
|
|
1377
|
-
type: 'array',
|
|
1378
|
-
items: { type: 'string' },
|
|
1379
|
-
description: 'Epic-level success criteria',
|
|
1110
|
+
description: 'Raw markdown content to parse and import',
|
|
1380
1111
|
},
|
|
1381
|
-
|
|
1112
|
+
title: {
|
|
1382
1113
|
type: 'string',
|
|
1383
|
-
|
|
1384
|
-
description: 'Priority level',
|
|
1385
|
-
},
|
|
1386
|
-
tags: {
|
|
1387
|
-
type: 'array',
|
|
1388
|
-
items: { type: 'string' },
|
|
1389
|
-
description: 'Categorization tags',
|
|
1390
|
-
},
|
|
1391
|
-
estimatedHours: {
|
|
1392
|
-
type: 'number',
|
|
1393
|
-
description: 'Total estimated hours for epic',
|
|
1394
|
-
},
|
|
1395
|
-
// Pattern inheritance fields (epic level)
|
|
1396
|
-
sharedPatterns: {
|
|
1397
|
-
type: 'object',
|
|
1398
|
-
description: 'Patterns shared by all tickets in this epic',
|
|
1399
|
-
properties: {
|
|
1400
|
-
errorHandling: { type: 'string', description: 'Override error handling for this epic' },
|
|
1401
|
-
returnType: { type: 'string', description: 'Epic-specific return type' },
|
|
1402
|
-
actionPrefix: { type: 'string', description: 'Redux/action prefix for this epic' },
|
|
1403
|
-
stateSlice: { type: 'string', description: 'State slice path for this epic' },
|
|
1404
|
-
},
|
|
1405
|
-
},
|
|
1406
|
-
additionalImports: {
|
|
1407
|
-
type: 'array',
|
|
1408
|
-
items: { type: 'string' },
|
|
1409
|
-
description: 'Additional imports for tickets in this epic (added to spec-level imports)',
|
|
1410
|
-
},
|
|
1411
|
-
commonFiles: {
|
|
1412
|
-
type: 'object',
|
|
1413
|
-
description: 'Common file paths for this epic',
|
|
1414
|
-
properties: {
|
|
1415
|
-
reducer: { type: 'string', description: 'Reducer file path' },
|
|
1416
|
-
actions: { type: 'string', description: 'Actions file path' },
|
|
1417
|
-
types: { type: 'string', description: 'Types file path' },
|
|
1418
|
-
index: { type: 'string', description: 'Index/barrel file path' },
|
|
1419
|
-
},
|
|
1114
|
+
description: 'Override the parsed title (optional)',
|
|
1420
1115
|
},
|
|
1421
|
-
|
|
1116
|
+
specificationTypeId: {
|
|
1422
1117
|
type: 'string',
|
|
1423
|
-
|
|
1424
|
-
description: 'Response verbosity: full (default, ~500 tokens), minimal (~50 tokens), id-only (~20 tokens)',
|
|
1118
|
+
description: 'Specification type ID (uses default if not provided)',
|
|
1425
1119
|
},
|
|
1426
1120
|
},
|
|
1427
|
-
required: ['
|
|
1121
|
+
required: ['projectId', 'content'],
|
|
1428
1122
|
},
|
|
1429
1123
|
},
|
|
1124
|
+
// ========================================================================
|
|
1125
|
+
// Implementation Session Operations
|
|
1126
|
+
// ========================================================================
|
|
1430
1127
|
{
|
|
1431
|
-
name: '
|
|
1432
|
-
description: '
|
|
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.',
|
|
1433
1130
|
inputSchema: {
|
|
1434
1131
|
type: 'object',
|
|
1435
1132
|
properties: {
|
|
1436
|
-
|
|
1437
|
-
type: 'string',
|
|
1438
|
-
description: 'The ID of the epic',
|
|
1439
|
-
},
|
|
1440
|
-
title: {
|
|
1441
|
-
type: 'string',
|
|
1442
|
-
description: 'Ticket title',
|
|
1443
|
-
},
|
|
1444
|
-
ticketNumber: {
|
|
1445
|
-
type: 'number',
|
|
1446
|
-
description: 'Ticket number (auto-incremented if not provided)',
|
|
1447
|
-
},
|
|
1448
|
-
description: {
|
|
1133
|
+
specificationId: {
|
|
1449
1134
|
type: 'string',
|
|
1450
|
-
description: '
|
|
1451
|
-
},
|
|
1452
|
-
implementation: {
|
|
1453
|
-
type: 'object',
|
|
1454
|
-
description: 'Detailed implementation steps (JSON)',
|
|
1135
|
+
description: 'The ID of the specification to create a session for',
|
|
1455
1136
|
},
|
|
1456
|
-
|
|
1457
|
-
type: 'object',
|
|
1458
|
-
description: 'Technical details like stack, endpoints (JSON)',
|
|
1459
|
-
},
|
|
1460
|
-
acceptanceCriteria: {
|
|
1461
|
-
type: 'array',
|
|
1462
|
-
items: { type: 'string' },
|
|
1463
|
-
description: 'Success criteria',
|
|
1464
|
-
},
|
|
1465
|
-
priority: {
|
|
1466
|
-
type: 'string',
|
|
1467
|
-
enum: ['high', 'medium', 'low'],
|
|
1468
|
-
description: 'Priority level',
|
|
1469
|
-
},
|
|
1470
|
-
complexity: {
|
|
1471
|
-
type: 'string',
|
|
1472
|
-
enum: ['small', 'medium', 'large', 'xlarge'],
|
|
1473
|
-
description: 'Size/complexity indicator',
|
|
1474
|
-
},
|
|
1475
|
-
tags: {
|
|
1476
|
-
type: 'array',
|
|
1477
|
-
items: { type: 'string' },
|
|
1478
|
-
description: 'Categorization tags',
|
|
1479
|
-
},
|
|
1480
|
-
notes: {
|
|
1481
|
-
type: 'string',
|
|
1482
|
-
description: 'Additional context, warnings, or considerations',
|
|
1483
|
-
},
|
|
1484
|
-
estimatedHours: {
|
|
1485
|
-
type: 'number',
|
|
1486
|
-
description: 'Estimated effort in hours',
|
|
1487
|
-
},
|
|
1488
|
-
dependsOn: {
|
|
1489
|
-
type: 'array',
|
|
1490
|
-
items: { type: 'string' },
|
|
1491
|
-
description: 'Array of ticket IDs this ticket depends on',
|
|
1492
|
-
},
|
|
1493
|
-
validationStrictness: {
|
|
1494
|
-
type: 'string',
|
|
1495
|
-
enum: ['lenient', 'normal', 'strict'],
|
|
1496
|
-
description: 'Warning strictness level. lenient=warnings only, normal=warnings+recommendations, strict=all. Default: normal',
|
|
1497
|
-
},
|
|
1498
|
-
responseMode: {
|
|
1499
|
-
type: 'string',
|
|
1500
|
-
enum: ['full', 'minimal', 'id-only'],
|
|
1501
|
-
description: 'Response verbosity: full (default, ~500 tokens), minimal (~50 tokens), id-only (~20 tokens)',
|
|
1502
|
-
},
|
|
1503
|
-
},
|
|
1504
|
-
required: ['epicId', 'title'],
|
|
1505
|
-
},
|
|
1506
|
-
},
|
|
1507
|
-
{
|
|
1508
|
-
name: 'import_specification',
|
|
1509
|
-
description: 'Import a markdown file as a complete specification with AI-powered parsing. Parses epics from ## headers and tickets from ### headers.',
|
|
1510
|
-
inputSchema: {
|
|
1511
|
-
type: 'object',
|
|
1512
|
-
properties: {
|
|
1513
|
-
projectId: {
|
|
1514
|
-
type: 'string',
|
|
1515
|
-
description: 'The ID of the project to import into',
|
|
1516
|
-
},
|
|
1517
|
-
content: {
|
|
1518
|
-
type: 'string',
|
|
1519
|
-
description: 'Raw markdown content to parse and import',
|
|
1520
|
-
},
|
|
1521
|
-
title: {
|
|
1522
|
-
type: 'string',
|
|
1523
|
-
description: 'Override the parsed title (optional)',
|
|
1524
|
-
},
|
|
1525
|
-
specificationTypeId: {
|
|
1526
|
-
type: 'string',
|
|
1527
|
-
description: 'Specification type ID (uses default if not provided)',
|
|
1528
|
-
},
|
|
1529
|
-
},
|
|
1530
|
-
required: ['projectId', 'content'],
|
|
1531
|
-
},
|
|
1532
|
-
},
|
|
1533
|
-
// ========================================================================
|
|
1534
|
-
// Update Operations
|
|
1535
|
-
// ========================================================================
|
|
1536
|
-
{
|
|
1537
|
-
name: 'update_ticket',
|
|
1538
|
-
description: "Update a ticket's properties (status, description, estimate, etc.).\n\n" +
|
|
1539
|
-
'When status changes, counts are automatically propagated up the hierarchy ' +
|
|
1540
|
-
'(Epic → Specification → Project).',
|
|
1541
|
-
inputSchema: {
|
|
1542
|
-
type: 'object',
|
|
1543
|
-
properties: {
|
|
1544
|
-
ticketId: {
|
|
1545
|
-
type: 'string',
|
|
1546
|
-
description: 'The ID of the ticket to update',
|
|
1547
|
-
},
|
|
1548
|
-
title: {
|
|
1549
|
-
type: 'string',
|
|
1550
|
-
description: 'New title (optional)',
|
|
1551
|
-
},
|
|
1552
|
-
description: {
|
|
1553
|
-
type: 'string',
|
|
1554
|
-
description: 'New description (optional)',
|
|
1555
|
-
},
|
|
1556
|
-
status: {
|
|
1557
|
-
type: 'string',
|
|
1558
|
-
enum: ['pending', 'ready', 'active', 'done'],
|
|
1559
|
-
description: 'Ticket status. pending/ready may be recalculated based on dependencies.',
|
|
1560
|
-
},
|
|
1561
|
-
priority: {
|
|
1562
|
-
type: 'string',
|
|
1563
|
-
enum: ['low', 'medium', 'high', 'critical'],
|
|
1564
|
-
description: 'Priority level (optional)',
|
|
1565
|
-
},
|
|
1566
|
-
complexity: {
|
|
1567
|
-
type: 'string',
|
|
1568
|
-
enum: ['small', 'medium', 'large', 'xlarge'],
|
|
1569
|
-
description: 'Size/complexity indicator (optional)',
|
|
1570
|
-
},
|
|
1571
|
-
blockReason: {
|
|
1572
|
-
type: 'string',
|
|
1573
|
-
description: 'External block reason. Forces status to pending until cleared.',
|
|
1574
|
-
},
|
|
1575
|
-
notes: {
|
|
1576
|
-
type: 'string',
|
|
1577
|
-
description: 'Additional context, warnings, or considerations (optional)',
|
|
1578
|
-
},
|
|
1579
|
-
estimatedHours: {
|
|
1580
|
-
type: 'number',
|
|
1581
|
-
description: 'Estimated hours (optional)',
|
|
1582
|
-
},
|
|
1583
|
-
tags: {
|
|
1584
|
-
type: 'array',
|
|
1585
|
-
items: { type: 'string' },
|
|
1586
|
-
description: 'Tags (optional)',
|
|
1587
|
-
},
|
|
1588
|
-
acceptanceCriteria: {
|
|
1589
|
-
type: 'array',
|
|
1590
|
-
items: { type: 'string' },
|
|
1591
|
-
description: 'Acceptance criteria (optional)',
|
|
1592
|
-
},
|
|
1593
|
-
implementation: {
|
|
1594
|
-
type: 'object',
|
|
1595
|
-
description: 'Detailed implementation steps (JSON) (optional)',
|
|
1596
|
-
},
|
|
1597
|
-
technicalDetails: {
|
|
1598
|
-
type: 'object',
|
|
1599
|
-
description: 'Technical details like stack, endpoints (JSON) (optional)',
|
|
1600
|
-
},
|
|
1601
|
-
validationStrictness: {
|
|
1602
|
-
type: 'string',
|
|
1603
|
-
enum: ['lenient', 'normal', 'strict'],
|
|
1604
|
-
description: 'Warning strictness level (default: normal)',
|
|
1605
|
-
default: 'normal',
|
|
1606
|
-
},
|
|
1607
|
-
responseMode: {
|
|
1608
|
-
type: 'string',
|
|
1609
|
-
enum: ['full', 'minimal', 'id-only'],
|
|
1610
|
-
description: 'Response verbosity: full (default, ~500 tokens), minimal (~50 tokens), id-only (~20 tokens)',
|
|
1611
|
-
},
|
|
1612
|
-
},
|
|
1613
|
-
required: ['ticketId'],
|
|
1614
|
-
},
|
|
1615
|
-
},
|
|
1616
|
-
{
|
|
1617
|
-
name: 'update_epic',
|
|
1618
|
-
description: "Update an epic's properties",
|
|
1619
|
-
inputSchema: {
|
|
1620
|
-
type: 'object',
|
|
1621
|
-
properties: {
|
|
1622
|
-
epicId: {
|
|
1623
|
-
type: 'string',
|
|
1624
|
-
description: 'The ID of the epic to update',
|
|
1625
|
-
},
|
|
1626
|
-
title: {
|
|
1627
|
-
type: 'string',
|
|
1628
|
-
description: 'New title (optional)',
|
|
1629
|
-
},
|
|
1630
|
-
description: {
|
|
1631
|
-
type: 'string',
|
|
1632
|
-
description: 'New description (optional)',
|
|
1633
|
-
},
|
|
1634
|
-
status: {
|
|
1635
|
-
type: 'string',
|
|
1636
|
-
enum: ['todo', 'in_progress', 'completed'],
|
|
1637
|
-
description: 'New status (optional)',
|
|
1638
|
-
},
|
|
1639
|
-
objective: {
|
|
1640
|
-
type: 'string',
|
|
1641
|
-
description: 'New objective (optional)',
|
|
1642
|
-
},
|
|
1643
|
-
scope: {
|
|
1644
|
-
type: 'string',
|
|
1645
|
-
description: 'What\'s in/out of scope (optional)',
|
|
1646
|
-
},
|
|
1647
|
-
goals: {
|
|
1648
|
-
type: 'array',
|
|
1649
|
-
items: { type: 'string' },
|
|
1650
|
-
description: 'Epic-specific goals (optional)',
|
|
1651
|
-
},
|
|
1652
|
-
guardrails: {
|
|
1653
|
-
type: 'array',
|
|
1654
|
-
items: { type: 'string' },
|
|
1655
|
-
description: 'What NOT to do (optional)',
|
|
1656
|
-
},
|
|
1657
|
-
risks: {
|
|
1658
|
-
type: 'array',
|
|
1659
|
-
items: { type: 'string' },
|
|
1660
|
-
description: 'Risk factors (optional)',
|
|
1661
|
-
},
|
|
1662
|
-
constraints: {
|
|
1663
|
-
type: 'array',
|
|
1664
|
-
items: { type: 'string' },
|
|
1665
|
-
description: 'Technical/business constraints (optional)',
|
|
1666
|
-
},
|
|
1667
|
-
assumptions: {
|
|
1668
|
-
type: 'array',
|
|
1669
|
-
items: { type: 'string' },
|
|
1670
|
-
description: 'Key assumptions (optional)',
|
|
1671
|
-
},
|
|
1672
|
-
architecture: {
|
|
1673
|
-
type: 'string',
|
|
1674
|
-
description: 'Architectural approach (optional)',
|
|
1675
|
-
},
|
|
1676
|
-
fileStructure: {
|
|
1677
|
-
type: 'string',
|
|
1678
|
-
description: 'File/folder organization (optional)',
|
|
1679
|
-
},
|
|
1680
|
-
techStack: {
|
|
1681
|
-
type: 'array',
|
|
1682
|
-
items: { type: 'string' },
|
|
1683
|
-
description: 'Technologies used (optional)',
|
|
1684
|
-
},
|
|
1685
|
-
dependencies: {
|
|
1686
|
-
type: 'array',
|
|
1687
|
-
items: { type: 'string' },
|
|
1688
|
-
description: 'Required packages/libraries (optional)',
|
|
1689
|
-
},
|
|
1690
|
-
apiContracts: {
|
|
1691
|
-
type: 'object',
|
|
1692
|
-
description: 'API specifications (optional)',
|
|
1693
|
-
},
|
|
1694
|
-
acceptanceCriteria: {
|
|
1695
|
-
type: 'array',
|
|
1696
|
-
items: { type: 'string' },
|
|
1697
|
-
description: 'Success criteria (optional)',
|
|
1698
|
-
},
|
|
1699
|
-
tags: {
|
|
1700
|
-
type: 'array',
|
|
1701
|
-
items: { type: 'string' },
|
|
1702
|
-
description: 'Categorization tags (optional)',
|
|
1703
|
-
},
|
|
1704
|
-
estimatedHours: {
|
|
1705
|
-
type: 'number',
|
|
1706
|
-
description: 'Total estimated hours (optional)',
|
|
1707
|
-
},
|
|
1708
|
-
priority: {
|
|
1709
|
-
type: 'string',
|
|
1710
|
-
enum: ['low', 'medium', 'high', 'critical'],
|
|
1711
|
-
description: 'Priority level (optional)',
|
|
1712
|
-
},
|
|
1713
|
-
// Pattern inheritance fields (epic level)
|
|
1714
|
-
sharedPatterns: {
|
|
1715
|
-
type: 'object',
|
|
1716
|
-
description: 'Patterns shared by all tickets in this epic (optional)',
|
|
1717
|
-
properties: {
|
|
1718
|
-
errorHandling: { type: 'string', description: 'Override error handling for this epic' },
|
|
1719
|
-
returnType: { type: 'string', description: 'Epic-specific return type' },
|
|
1720
|
-
actionPrefix: { type: 'string', description: 'Redux/action prefix for this epic' },
|
|
1721
|
-
stateSlice: { type: 'string', description: 'State slice path for this epic' },
|
|
1722
|
-
},
|
|
1723
|
-
},
|
|
1724
|
-
additionalImports: {
|
|
1725
|
-
type: 'array',
|
|
1726
|
-
items: { type: 'string' },
|
|
1727
|
-
description: 'Additional imports for tickets in this epic (optional)',
|
|
1728
|
-
},
|
|
1729
|
-
commonFiles: {
|
|
1730
|
-
type: 'object',
|
|
1731
|
-
description: 'Common file paths for this epic (optional)',
|
|
1732
|
-
properties: {
|
|
1733
|
-
reducer: { type: 'string', description: 'Reducer file path' },
|
|
1734
|
-
actions: { type: 'string', description: 'Actions file path' },
|
|
1735
|
-
types: { type: 'string', description: 'Types file path' },
|
|
1736
|
-
index: { type: 'string', description: 'Index/barrel file path' },
|
|
1737
|
-
},
|
|
1738
|
-
},
|
|
1739
|
-
responseMode: {
|
|
1740
|
-
type: 'string',
|
|
1741
|
-
enum: ['full', 'minimal', 'id-only'],
|
|
1742
|
-
description: 'Response verbosity: full (default, ~500 tokens), minimal (~50 tokens), id-only (~20 tokens)',
|
|
1743
|
-
},
|
|
1744
|
-
},
|
|
1745
|
-
required: ['epicId'],
|
|
1746
|
-
},
|
|
1747
|
-
},
|
|
1748
|
-
{
|
|
1749
|
-
name: 'update_specification',
|
|
1750
|
-
description: "Update a specification's properties",
|
|
1751
|
-
inputSchema: {
|
|
1752
|
-
type: 'object',
|
|
1753
|
-
properties: {
|
|
1754
|
-
specificationId: {
|
|
1755
|
-
type: 'string',
|
|
1756
|
-
description: 'The ID of the specification to update',
|
|
1757
|
-
},
|
|
1758
|
-
title: {
|
|
1759
|
-
type: 'string',
|
|
1760
|
-
description: 'New title (optional)',
|
|
1761
|
-
},
|
|
1762
|
-
description: {
|
|
1763
|
-
type: 'string',
|
|
1764
|
-
description: 'New description (optional)',
|
|
1765
|
-
},
|
|
1766
|
-
status: {
|
|
1767
|
-
type: 'string',
|
|
1768
|
-
enum: ['draft', 'planning', 'ready', 'in_progress', 'completed'],
|
|
1769
|
-
description: 'New status (optional)',
|
|
1770
|
-
},
|
|
1771
|
-
background: {
|
|
1772
|
-
type: 'string',
|
|
1773
|
-
description: 'New background (optional)',
|
|
1774
|
-
},
|
|
1775
|
-
scope: {
|
|
1776
|
-
type: 'string',
|
|
1777
|
-
description: 'New scope (optional)',
|
|
1778
|
-
},
|
|
1779
|
-
goals: {
|
|
1780
|
-
type: 'array',
|
|
1781
|
-
items: { type: 'string' },
|
|
1782
|
-
description: 'Business/user/technical objectives (optional)',
|
|
1783
|
-
},
|
|
1784
|
-
requirements: {
|
|
1785
|
-
type: 'array',
|
|
1786
|
-
items: { type: 'string' },
|
|
1787
|
-
description: 'Functional requirements (optional)',
|
|
1788
|
-
},
|
|
1789
|
-
nonFunctionalRequirements: {
|
|
1790
|
-
type: 'array',
|
|
1791
|
-
items: { type: 'string' },
|
|
1792
|
-
description: 'Non-functional requirements like performance, security (optional)',
|
|
1793
|
-
},
|
|
1794
|
-
successMetrics: {
|
|
1795
|
-
type: 'array',
|
|
1796
|
-
items: { type: 'string' },
|
|
1797
|
-
description: 'KPIs to measure success (optional)',
|
|
1798
|
-
},
|
|
1799
|
-
constraints: {
|
|
1800
|
-
type: 'array',
|
|
1801
|
-
items: { type: 'string' },
|
|
1802
|
-
description: 'Technical/business constraints (optional)',
|
|
1803
|
-
},
|
|
1804
|
-
assumptions: {
|
|
1805
|
-
type: 'array',
|
|
1806
|
-
items: { type: 'string' },
|
|
1807
|
-
description: 'Key assumptions made (optional)',
|
|
1808
|
-
},
|
|
1809
|
-
risks: {
|
|
1810
|
-
type: 'array',
|
|
1811
|
-
items: { type: 'string' },
|
|
1812
|
-
description: 'Risk factors and mitigations (optional)',
|
|
1813
|
-
},
|
|
1814
|
-
guardrails: {
|
|
1815
|
-
type: 'array',
|
|
1816
|
-
items: { type: 'string' },
|
|
1817
|
-
description: 'What NOT to do (optional)',
|
|
1818
|
-
},
|
|
1819
|
-
architecture: {
|
|
1820
|
-
type: 'string',
|
|
1821
|
-
description: 'Architectural approach (optional)',
|
|
1822
|
-
},
|
|
1823
|
-
fileStructure: {
|
|
1824
|
-
type: 'string',
|
|
1825
|
-
description: 'File/folder organization (optional)',
|
|
1826
|
-
},
|
|
1827
|
-
techStack: {
|
|
1828
|
-
type: 'array',
|
|
1829
|
-
items: { type: 'string' },
|
|
1830
|
-
description: 'Technologies to use (optional)',
|
|
1831
|
-
},
|
|
1832
|
-
dependencies: {
|
|
1833
|
-
type: 'array',
|
|
1834
|
-
items: { type: 'string' },
|
|
1835
|
-
description: 'Required packages/libraries (optional)',
|
|
1836
|
-
},
|
|
1837
|
-
apiContracts: {
|
|
1838
|
-
type: 'object',
|
|
1839
|
-
description: 'API specifications (optional)',
|
|
1840
|
-
},
|
|
1841
|
-
acceptanceCriteria: {
|
|
1842
|
-
type: 'array',
|
|
1843
|
-
items: { type: 'string' },
|
|
1844
|
-
description: 'Success criteria (optional)',
|
|
1845
|
-
},
|
|
1846
|
-
tags: {
|
|
1847
|
-
type: 'array',
|
|
1848
|
-
items: { type: 'string' },
|
|
1849
|
-
description: 'Categorization tags (optional)',
|
|
1850
|
-
},
|
|
1851
|
-
estimatedHours: {
|
|
1852
|
-
type: 'number',
|
|
1853
|
-
description: 'Total estimated hours (optional)',
|
|
1854
|
-
},
|
|
1855
|
-
targetAudience: {
|
|
1856
|
-
type: 'string',
|
|
1857
|
-
description: 'Who this is for - developers, users, stakeholders, etc. (optional)',
|
|
1858
|
-
},
|
|
1859
|
-
priority: {
|
|
1860
|
-
type: 'string',
|
|
1861
|
-
enum: ['low', 'medium', 'high', 'critical'],
|
|
1862
|
-
description: 'Priority level (optional)',
|
|
1863
|
-
},
|
|
1864
|
-
validationCommands: {
|
|
1865
|
-
type: 'object',
|
|
1866
|
-
description: 'Validation commands (test, lint, build, typeCheck, custom) (optional)',
|
|
1867
|
-
properties: {
|
|
1868
|
-
test: { type: 'string', description: 'Test command' },
|
|
1869
|
-
lint: { type: 'string', description: 'Lint command' },
|
|
1870
|
-
build: { type: 'string', description: 'Build command' },
|
|
1871
|
-
typeCheck: { type: 'string', description: 'Type check command' },
|
|
1872
|
-
preValidation: { type: 'string', description: 'Pre-validation command' },
|
|
1873
|
-
postValidation: { type: 'string', description: 'Post-validation command' },
|
|
1874
|
-
custom: {
|
|
1875
|
-
type: 'object',
|
|
1876
|
-
description: 'Custom validation commands',
|
|
1877
|
-
additionalProperties: { type: 'string' },
|
|
1878
|
-
},
|
|
1879
|
-
},
|
|
1880
|
-
},
|
|
1881
|
-
workingDirectory: {
|
|
1882
|
-
type: 'string',
|
|
1883
|
-
description: 'Working directory for commands (optional)',
|
|
1884
|
-
},
|
|
1885
|
-
outputDirectory: {
|
|
1886
|
-
type: 'string',
|
|
1887
|
-
description: 'Output directory for build artifacts (optional)',
|
|
1888
|
-
},
|
|
1889
|
-
// Pattern inheritance fields (specification level)
|
|
1890
|
-
codeStandards: {
|
|
1891
|
-
type: 'object',
|
|
1892
|
-
description: 'Code standards inherited by all epics/tickets (optional)',
|
|
1893
|
-
properties: {
|
|
1894
|
-
language: { type: 'string', description: 'Primary language (e.g., "TypeScript")' },
|
|
1895
|
-
asyncPattern: { type: 'string', description: 'Async pattern (e.g., "async/await")' },
|
|
1896
|
-
errorHandling: { type: 'string', description: 'Error handling approach' },
|
|
1897
|
-
documentation: { type: 'string', description: 'Documentation style' },
|
|
1898
|
-
testing: { type: 'string', description: 'Testing approach' },
|
|
1899
|
-
naming: {
|
|
1900
|
-
type: 'object',
|
|
1901
|
-
description: 'Naming conventions',
|
|
1902
|
-
properties: {
|
|
1903
|
-
files: { type: 'string', description: 'File naming convention' },
|
|
1904
|
-
functions: { type: 'string', description: 'Function naming convention' },
|
|
1905
|
-
interfaces: { type: 'string', description: 'Interface naming convention' },
|
|
1906
|
-
actions: { type: 'string', description: 'Action naming convention' },
|
|
1907
|
-
},
|
|
1908
|
-
},
|
|
1909
|
-
},
|
|
1910
|
-
},
|
|
1911
|
-
commonImports: {
|
|
1912
|
-
type: 'array',
|
|
1913
|
-
items: { type: 'string' },
|
|
1914
|
-
description: 'Common imports inherited by all epics/tickets (optional)',
|
|
1915
|
-
},
|
|
1916
|
-
returnTypes: {
|
|
1917
|
-
type: 'object',
|
|
1918
|
-
description: 'Standard return types for CRUD operations (optional)',
|
|
1919
|
-
properties: {
|
|
1920
|
-
create: { type: 'string', description: 'Return type for create operations' },
|
|
1921
|
-
update: { type: 'string', description: 'Return type for update operations' },
|
|
1922
|
-
delete: { type: 'string', description: 'Return type for delete operations' },
|
|
1923
|
-
list: { type: 'string', description: 'Return type for list operations' },
|
|
1924
|
-
},
|
|
1925
|
-
},
|
|
1926
|
-
responseMode: {
|
|
1927
|
-
type: 'string',
|
|
1928
|
-
enum: ['full', 'minimal', 'id-only'],
|
|
1929
|
-
description: 'Response verbosity: full (default, ~500 tokens), minimal (~50 tokens), id-only (~20 tokens)',
|
|
1930
|
-
},
|
|
1931
|
-
},
|
|
1932
|
-
required: ['specificationId'],
|
|
1933
|
-
},
|
|
1934
|
-
},
|
|
1935
|
-
// ========================================================================
|
|
1936
|
-
// Implementation Session Operations
|
|
1937
|
-
// ========================================================================
|
|
1938
|
-
{
|
|
1939
|
-
name: 'start_implementation_session',
|
|
1940
|
-
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.',
|
|
1941
|
-
inputSchema: {
|
|
1942
|
-
type: 'object',
|
|
1943
|
-
properties: {
|
|
1944
|
-
specificationId: {
|
|
1945
|
-
type: 'string',
|
|
1946
|
-
description: 'The ID of the specification to create a session for',
|
|
1947
|
-
},
|
|
1948
|
-
config: {
|
|
1137
|
+
config: {
|
|
1949
1138
|
type: 'object',
|
|
1950
1139
|
description: 'Optional session configuration',
|
|
1951
1140
|
properties: {
|
|
@@ -2008,51 +1197,6 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
|
|
|
2008
1197
|
required: ['sessionId', 'status'],
|
|
2009
1198
|
},
|
|
2010
1199
|
},
|
|
2011
|
-
// ========================================================================
|
|
2012
|
-
// Bulk Operations
|
|
2013
|
-
// ========================================================================
|
|
2014
|
-
{
|
|
2015
|
-
name: 'bulk_add_dependencies',
|
|
2016
|
-
description: 'Add multiple dependencies between tickets in a single atomic transaction.',
|
|
2017
|
-
inputSchema: {
|
|
2018
|
-
type: 'object',
|
|
2019
|
-
properties: {
|
|
2020
|
-
dependencies: {
|
|
2021
|
-
type: 'array',
|
|
2022
|
-
description: 'Array of dependency definitions',
|
|
2023
|
-
items: {
|
|
2024
|
-
type: 'object',
|
|
2025
|
-
properties: {
|
|
2026
|
-
ticketId: {
|
|
2027
|
-
type: 'string',
|
|
2028
|
-
description: 'ID of the ticket that will depend on another',
|
|
2029
|
-
},
|
|
2030
|
-
dependsOnId: {
|
|
2031
|
-
type: 'string',
|
|
2032
|
-
description: 'ID of the ticket it will depend on',
|
|
2033
|
-
},
|
|
2034
|
-
type: {
|
|
2035
|
-
type: 'string',
|
|
2036
|
-
enum: ['blocks', 'requires'],
|
|
2037
|
-
description: "Type of dependency (default: 'requires')",
|
|
2038
|
-
},
|
|
2039
|
-
},
|
|
2040
|
-
required: ['ticketId', 'dependsOnId'],
|
|
2041
|
-
},
|
|
2042
|
-
},
|
|
2043
|
-
skipCircularCheck: {
|
|
2044
|
-
type: 'boolean',
|
|
2045
|
-
description: 'Skip validation of circular dependencies (default: false)',
|
|
2046
|
-
},
|
|
2047
|
-
onError: {
|
|
2048
|
-
type: 'string',
|
|
2049
|
-
enum: ['rollback', 'continue'],
|
|
2050
|
-
description: "Error handling mode: 'rollback' stops and undoes all, 'continue' skips failures (default: 'continue')",
|
|
2051
|
-
},
|
|
2052
|
-
},
|
|
2053
|
-
required: ['dependencies'],
|
|
2054
|
-
},
|
|
2055
|
-
},
|
|
2056
1200
|
{
|
|
2057
1201
|
name: 'bulk_update_tickets',
|
|
2058
1202
|
description: 'Update multiple tickets in a single atomic operation. All updates succeed or all fail (unless atomic: false).',
|
|
@@ -2450,34 +1594,6 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
|
|
|
2450
1594
|
// ========================================================================
|
|
2451
1595
|
// Delete Operations
|
|
2452
1596
|
// ========================================================================
|
|
2453
|
-
{
|
|
2454
|
-
name: 'delete_ticket',
|
|
2455
|
-
description: 'Delete a ticket and all its related records (dependencies, test results, discoveries, blueprint references)',
|
|
2456
|
-
inputSchema: {
|
|
2457
|
-
type: 'object',
|
|
2458
|
-
properties: {
|
|
2459
|
-
ticketId: {
|
|
2460
|
-
type: 'string',
|
|
2461
|
-
description: 'The ID of the ticket to delete',
|
|
2462
|
-
},
|
|
2463
|
-
},
|
|
2464
|
-
required: ['ticketId'],
|
|
2465
|
-
},
|
|
2466
|
-
},
|
|
2467
|
-
{
|
|
2468
|
-
name: 'delete_epic',
|
|
2469
|
-
description: 'Delete an epic and cascade delete all its tickets and related records',
|
|
2470
|
-
inputSchema: {
|
|
2471
|
-
type: 'object',
|
|
2472
|
-
properties: {
|
|
2473
|
-
epicId: {
|
|
2474
|
-
type: 'string',
|
|
2475
|
-
description: 'The ID of the epic to delete',
|
|
2476
|
-
},
|
|
2477
|
-
},
|
|
2478
|
-
required: ['epicId'],
|
|
2479
|
-
},
|
|
2480
|
-
},
|
|
2481
1597
|
{
|
|
2482
1598
|
name: 'delete_specification',
|
|
2483
1599
|
description: 'Delete a specification and cascade delete all epics, tickets, and related records',
|
|
@@ -2571,50 +1687,42 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
|
|
|
2571
1687
|
// Review & Completion
|
|
2572
1688
|
// ========================================================================
|
|
2573
1689
|
{
|
|
2574
|
-
name: '
|
|
2575
|
-
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.',
|
|
2576
1692
|
inputSchema: {
|
|
2577
1693
|
type: 'object',
|
|
2578
1694
|
properties: {
|
|
2579
1695
|
specificationId: {
|
|
2580
1696
|
type: 'string',
|
|
2581
|
-
description: 'The ID of the specification to review',
|
|
2582
|
-
},
|
|
2583
|
-
page: {
|
|
2584
|
-
type: 'integer',
|
|
2585
|
-
description: 'Page number for paginated results (default: 1)',
|
|
2586
|
-
},
|
|
2587
|
-
pageSize: {
|
|
2588
|
-
type: 'integer',
|
|
2589
|
-
description: 'Number of items per page (default: 20)',
|
|
1697
|
+
description: 'The ID of the specification to review',
|
|
2590
1698
|
},
|
|
2591
1699
|
},
|
|
2592
1700
|
required: ['specificationId'],
|
|
2593
1701
|
},
|
|
2594
1702
|
},
|
|
2595
1703
|
{
|
|
2596
|
-
name: '
|
|
2597
|
-
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.',
|
|
2598
1706
|
inputSchema: {
|
|
2599
1707
|
type: 'object',
|
|
2600
1708
|
properties: {
|
|
2601
1709
|
specificationId: {
|
|
2602
1710
|
type: 'string',
|
|
2603
|
-
description: 'The ID of the specification to
|
|
1711
|
+
description: 'The ID of the specification to complete',
|
|
2604
1712
|
},
|
|
2605
1713
|
},
|
|
2606
1714
|
required: ['specificationId'],
|
|
2607
1715
|
},
|
|
2608
1716
|
},
|
|
2609
1717
|
{
|
|
2610
|
-
name: '
|
|
2611
|
-
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.',
|
|
2612
1720
|
inputSchema: {
|
|
2613
1721
|
type: 'object',
|
|
2614
1722
|
properties: {
|
|
2615
1723
|
specificationId: {
|
|
2616
1724
|
type: 'string',
|
|
2617
|
-
description: 'The ID of the specification to
|
|
1725
|
+
description: 'The ID of the specification to reopen',
|
|
2618
1726
|
},
|
|
2619
1727
|
},
|
|
2620
1728
|
required: ['specificationId'],
|
|
@@ -2640,6 +1748,83 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
|
|
|
2640
1748
|
},
|
|
2641
1749
|
},
|
|
2642
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
|
+
},
|
|
2643
1828
|
];
|
|
2644
1829
|
return tools;
|
|
2645
1830
|
}
|
|
@@ -2750,14 +1935,6 @@ export function createToolHandlers(apiClient) {
|
|
|
2750
1935
|
fields: argsWithContext.fields,
|
|
2751
1936
|
});
|
|
2752
1937
|
},
|
|
2753
|
-
get_specification: async (_client, args) => {
|
|
2754
|
-
validateRequired(args, 'specificationId');
|
|
2755
|
-
return await apiClient.call('get_specification', {
|
|
2756
|
-
specificationId: args.specificationId,
|
|
2757
|
-
summary: args.summary,
|
|
2758
|
-
include: args.include,
|
|
2759
|
-
});
|
|
2760
|
-
},
|
|
2761
1938
|
lookup_specification: async (_client, args) => {
|
|
2762
1939
|
validateRequired(args, 'title');
|
|
2763
1940
|
// Inject projectId from .specforge.json if not provided
|
|
@@ -2782,14 +1959,6 @@ export function createToolHandlers(apiClient) {
|
|
|
2782
1959
|
fields: argsWithContext.fields,
|
|
2783
1960
|
});
|
|
2784
1961
|
},
|
|
2785
|
-
get_epic: async (_client, args) => {
|
|
2786
|
-
validateRequired(args, 'epicId');
|
|
2787
|
-
return await apiClient.call('get_epic', {
|
|
2788
|
-
epicId: args.epicId,
|
|
2789
|
-
summary: args.summary,
|
|
2790
|
-
include: args.include,
|
|
2791
|
-
});
|
|
2792
|
-
},
|
|
2793
1962
|
lookup_epic: async (_client, args) => {
|
|
2794
1963
|
// Must provide either title or number
|
|
2795
1964
|
if (!args.title && args.number === undefined) {
|
|
@@ -2821,14 +1990,6 @@ export function createToolHandlers(apiClient) {
|
|
|
2821
1990
|
fields: argsWithContext.fields,
|
|
2822
1991
|
});
|
|
2823
1992
|
},
|
|
2824
|
-
get_ticket: async (_client, args) => {
|
|
2825
|
-
validateRequired(args, 'ticketId');
|
|
2826
|
-
return await apiClient.call('get_ticket', {
|
|
2827
|
-
ticketId: args.ticketId,
|
|
2828
|
-
summary: args.summary,
|
|
2829
|
-
include: args.include,
|
|
2830
|
-
});
|
|
2831
|
-
},
|
|
2832
1993
|
lookup_ticket: async (_client, args) => {
|
|
2833
1994
|
validateRequired(args, 'epicId');
|
|
2834
1995
|
// Must provide either title or number
|
|
@@ -2866,42 +2027,6 @@ export function createToolHandlers(apiClient) {
|
|
|
2866
2027
|
});
|
|
2867
2028
|
},
|
|
2868
2029
|
// ========================================================================
|
|
2869
|
-
// Core Operations - Dependencies
|
|
2870
|
-
// ========================================================================
|
|
2871
|
-
add_dependency: async (_client, args) => {
|
|
2872
|
-
validateRequired(args, 'ticketId');
|
|
2873
|
-
validateRequired(args, 'dependsOnId');
|
|
2874
|
-
return await apiClient.call('add_dependency', {
|
|
2875
|
-
ticketId: args.ticketId,
|
|
2876
|
-
dependsOnId: args.dependsOnId,
|
|
2877
|
-
type: args.type,
|
|
2878
|
-
});
|
|
2879
|
-
},
|
|
2880
|
-
remove_dependency: async (_client, args) => {
|
|
2881
|
-
// Either dependencyId or (ticketId + dependsOnId) required
|
|
2882
|
-
if (!args.dependencyId && !args.ticketId) {
|
|
2883
|
-
throw new Error('Either dependencyId or ticketId is required');
|
|
2884
|
-
}
|
|
2885
|
-
return await apiClient.call('remove_dependency', {
|
|
2886
|
-
ticketId: args.ticketId,
|
|
2887
|
-
dependsOnId: args.dependsOnId,
|
|
2888
|
-
dependencyId: args.dependencyId,
|
|
2889
|
-
});
|
|
2890
|
-
},
|
|
2891
|
-
get_dependency_tree: async (_client, args) => {
|
|
2892
|
-
validateRequired(args, 'specificationId');
|
|
2893
|
-
return await apiClient.call('get_dependency_tree', {
|
|
2894
|
-
specificationId: args.specificationId,
|
|
2895
|
-
});
|
|
2896
|
-
},
|
|
2897
|
-
check_circular_dependencies: async (_client, args) => {
|
|
2898
|
-
const argsWithContext = injectContext(args, ['specificationId', 'projectId']);
|
|
2899
|
-
return await apiClient.call('check_circular_dependencies', {
|
|
2900
|
-
specificationId: argsWithContext.specificationId,
|
|
2901
|
-
projectId: argsWithContext.projectId,
|
|
2902
|
-
});
|
|
2903
|
-
},
|
|
2904
|
-
// ========================================================================
|
|
2905
2030
|
// Context & AI Tools
|
|
2906
2031
|
// ========================================================================
|
|
2907
2032
|
get_implementation_context: async (_client, args) => {
|
|
@@ -2976,16 +2101,6 @@ export function createToolHandlers(apiClient) {
|
|
|
2976
2101
|
specificationId: argsWithContext.specificationId,
|
|
2977
2102
|
});
|
|
2978
2103
|
},
|
|
2979
|
-
get_critical_path: async (_client, args) => {
|
|
2980
|
-
// Inject specificationId from .specforge.json if not provided
|
|
2981
|
-
const argsWithContext = injectContext(args, ['specificationId']);
|
|
2982
|
-
if (!argsWithContext.specificationId) {
|
|
2983
|
-
throw new Error('specificationId is required. Set working context with "specforge switch" or provide explicitly.');
|
|
2984
|
-
}
|
|
2985
|
-
return await apiClient.call('get_critical_path', {
|
|
2986
|
-
specificationId: argsWithContext.specificationId,
|
|
2987
|
-
});
|
|
2988
|
-
},
|
|
2989
2104
|
get_patterns: async (_client, args) => {
|
|
2990
2105
|
// Inject specificationId from .specforge.json if not provided
|
|
2991
2106
|
const argsWithContext = injectContext(args, ['specificationId']);
|
|
@@ -3162,6 +2277,7 @@ export function createToolHandlers(apiClient) {
|
|
|
3162
2277
|
filesDeleted: args.filesDeleted,
|
|
3163
2278
|
blockReason: args.blockReason,
|
|
3164
2279
|
clearBlockReason: args.clearBlockReason,
|
|
2280
|
+
getTicket: args.getTicket,
|
|
3165
2281
|
});
|
|
3166
2282
|
},
|
|
3167
2283
|
// ========================================================================
|
|
@@ -3276,79 +2392,6 @@ export function createToolHandlers(apiClient) {
|
|
|
3276
2392
|
});
|
|
3277
2393
|
return formatWriteResponse(result, responseMode, 'Specification created');
|
|
3278
2394
|
},
|
|
3279
|
-
create_epic: async (_client, args) => {
|
|
3280
|
-
validateRequired(args, 'specificationId', 'title', 'description', 'objective');
|
|
3281
|
-
const responseMode = getResponseModeFromArgs(args);
|
|
3282
|
-
const result = await apiClient.call('create_epic', {
|
|
3283
|
-
specificationId: args.specificationId,
|
|
3284
|
-
title: args.title,
|
|
3285
|
-
description: args.description,
|
|
3286
|
-
objective: args.objective,
|
|
3287
|
-
epicNumber: args.epicNumber,
|
|
3288
|
-
content: args.content,
|
|
3289
|
-
scope: args.scope,
|
|
3290
|
-
goals: args.goals,
|
|
3291
|
-
acceptanceCriteria: args.acceptanceCriteria,
|
|
3292
|
-
priority: args.priority,
|
|
3293
|
-
tags: args.tags,
|
|
3294
|
-
estimatedHours: args.estimatedHours,
|
|
3295
|
-
order: args.order,
|
|
3296
|
-
// FI-003 fields
|
|
3297
|
-
guardrails: args.guardrails,
|
|
3298
|
-
risks: args.risks,
|
|
3299
|
-
constraints: args.constraints,
|
|
3300
|
-
assumptions: args.assumptions,
|
|
3301
|
-
architecture: args.architecture,
|
|
3302
|
-
fileStructure: args.fileStructure,
|
|
3303
|
-
techStack: args.techStack,
|
|
3304
|
-
dependencies: args.dependencies,
|
|
3305
|
-
apiContracts: args.apiContracts,
|
|
3306
|
-
// Pattern inheritance fields (F7-002)
|
|
3307
|
-
sharedPatterns: args.sharedPatterns,
|
|
3308
|
-
additionalImports: args.additionalImports,
|
|
3309
|
-
commonFiles: args.commonFiles,
|
|
3310
|
-
});
|
|
3311
|
-
return formatWriteResponse(result, responseMode, 'Epic created');
|
|
3312
|
-
},
|
|
3313
|
-
create_ticket: async (_client, args) => {
|
|
3314
|
-
validateRequired(args, 'epicId', 'title');
|
|
3315
|
-
const responseMode = getResponseModeFromArgs(args);
|
|
3316
|
-
// Extract validation options
|
|
3317
|
-
const validationStrictness = args.validationStrictness === 'lenient' || args.validationStrictness === 'strict'
|
|
3318
|
-
? args.validationStrictness
|
|
3319
|
-
: 'normal';
|
|
3320
|
-
// Create the ticket
|
|
3321
|
-
const result = await apiClient.call('create_ticket', {
|
|
3322
|
-
epicId: args.epicId,
|
|
3323
|
-
title: args.title,
|
|
3324
|
-
ticketNumber: args.ticketNumber,
|
|
3325
|
-
description: args.description,
|
|
3326
|
-
implementation: args.implementation,
|
|
3327
|
-
technicalDetails: args.technicalDetails,
|
|
3328
|
-
acceptanceCriteria: args.acceptanceCriteria,
|
|
3329
|
-
priority: args.priority,
|
|
3330
|
-
complexity: args.complexity,
|
|
3331
|
-
tags: args.tags,
|
|
3332
|
-
estimatedHours: args.estimatedHours,
|
|
3333
|
-
order: args.order,
|
|
3334
|
-
dependsOn: args.dependsOn,
|
|
3335
|
-
notes: args.notes, // F8-001: Add missing notes field
|
|
3336
|
-
});
|
|
3337
|
-
// Run validation
|
|
3338
|
-
const validation = validateTicket({
|
|
3339
|
-
complexity: args.complexity,
|
|
3340
|
-
implementation: args.implementation,
|
|
3341
|
-
technicalDetails: args.technicalDetails,
|
|
3342
|
-
notes: args.notes,
|
|
3343
|
-
acceptanceCriteria: args.acceptanceCriteria,
|
|
3344
|
-
});
|
|
3345
|
-
// Filter warnings by strictness level
|
|
3346
|
-
const warnings = filterWarningsByStrictness(validation.warnings, validationStrictness);
|
|
3347
|
-
// Add validation results to response
|
|
3348
|
-
result.warnings = warnings;
|
|
3349
|
-
result.completenessScore = validation.completenessScore;
|
|
3350
|
-
return formatWriteResponse(result, responseMode, 'Ticket created');
|
|
3351
|
-
},
|
|
3352
2395
|
import_specification: async (_client, args) => {
|
|
3353
2396
|
validateRequired(args, 'projectId', 'content');
|
|
3354
2397
|
return await apiClient.call('import_specification', {
|
|
@@ -3359,145 +2402,6 @@ export function createToolHandlers(apiClient) {
|
|
|
3359
2402
|
});
|
|
3360
2403
|
},
|
|
3361
2404
|
// ========================================================================
|
|
3362
|
-
// Update Operations
|
|
3363
|
-
// ========================================================================
|
|
3364
|
-
update_ticket: async (_client, args) => {
|
|
3365
|
-
validateRequired(args, 'ticketId');
|
|
3366
|
-
const responseMode = getResponseModeFromArgs(args);
|
|
3367
|
-
// Extract validation options
|
|
3368
|
-
const validationStrictness = args.validationStrictness === 'lenient' || args.validationStrictness === 'strict'
|
|
3369
|
-
? args.validationStrictness
|
|
3370
|
-
: 'normal';
|
|
3371
|
-
// Get current ticket to calculate previous completeness score
|
|
3372
|
-
let previousCompletenessScore;
|
|
3373
|
-
try {
|
|
3374
|
-
const currentTicket = await apiClient.call('get_ticket', {
|
|
3375
|
-
ticketId: args.ticketId,
|
|
3376
|
-
});
|
|
3377
|
-
// Calculate previous completeness score
|
|
3378
|
-
const prevValidation = validateTicket({
|
|
3379
|
-
complexity: currentTicket.complexity,
|
|
3380
|
-
implementation: currentTicket.implementation,
|
|
3381
|
-
technicalDetails: currentTicket.technicalDetails,
|
|
3382
|
-
notes: currentTicket.notes,
|
|
3383
|
-
acceptanceCriteria: currentTicket.acceptanceCriteria,
|
|
3384
|
-
});
|
|
3385
|
-
previousCompletenessScore = prevValidation.completenessScore;
|
|
3386
|
-
}
|
|
3387
|
-
catch {
|
|
3388
|
-
// If we can't get the current ticket, skip previous score tracking
|
|
3389
|
-
previousCompletenessScore = undefined;
|
|
3390
|
-
}
|
|
3391
|
-
// Update the ticket
|
|
3392
|
-
const result = await apiClient.call('update_ticket', {
|
|
3393
|
-
ticketId: args.ticketId,
|
|
3394
|
-
title: args.title,
|
|
3395
|
-
description: args.description,
|
|
3396
|
-
status: args.status,
|
|
3397
|
-
priority: args.priority,
|
|
3398
|
-
estimatedHours: args.estimatedHours,
|
|
3399
|
-
tags: args.tags,
|
|
3400
|
-
acceptanceCriteria: args.acceptanceCriteria,
|
|
3401
|
-
// Additional fields
|
|
3402
|
-
complexity: args.complexity,
|
|
3403
|
-
notes: args.notes,
|
|
3404
|
-
implementation: args.implementation,
|
|
3405
|
-
technicalDetails: args.technicalDetails,
|
|
3406
|
-
blockReason: args.blockReason,
|
|
3407
|
-
});
|
|
3408
|
-
// Run validation on updated ticket
|
|
3409
|
-
// Use the updated values (from args) merged with existing values (from result)
|
|
3410
|
-
// The result should contain the final state after update
|
|
3411
|
-
const validation = validateTicket({
|
|
3412
|
-
complexity: (args.complexity || result.complexity),
|
|
3413
|
-
implementation: (args.implementation || result.implementation),
|
|
3414
|
-
technicalDetails: (args.technicalDetails || result.technicalDetails),
|
|
3415
|
-
notes: (args.notes || result.notes),
|
|
3416
|
-
acceptanceCriteria: (args.acceptanceCriteria || result.acceptanceCriteria),
|
|
3417
|
-
});
|
|
3418
|
-
// Filter warnings by strictness level
|
|
3419
|
-
const warnings = filterWarningsByStrictness(validation.warnings, validationStrictness);
|
|
3420
|
-
// Add validation results to response
|
|
3421
|
-
result.warnings = warnings;
|
|
3422
|
-
result.completenessScore = validation.completenessScore;
|
|
3423
|
-
if (previousCompletenessScore !== undefined) {
|
|
3424
|
-
result.previousCompletenessScore = previousCompletenessScore;
|
|
3425
|
-
}
|
|
3426
|
-
return formatWriteResponse(result, responseMode, 'Ticket updated');
|
|
3427
|
-
},
|
|
3428
|
-
update_epic: async (_client, args) => {
|
|
3429
|
-
validateRequired(args, 'epicId');
|
|
3430
|
-
const responseMode = getResponseModeFromArgs(args);
|
|
3431
|
-
const result = await apiClient.call('update_epic', {
|
|
3432
|
-
epicId: args.epicId,
|
|
3433
|
-
title: args.title,
|
|
3434
|
-
description: args.description,
|
|
3435
|
-
status: args.status,
|
|
3436
|
-
objective: args.objective,
|
|
3437
|
-
priority: args.priority,
|
|
3438
|
-
// FI-003 fields
|
|
3439
|
-
scope: args.scope,
|
|
3440
|
-
goals: args.goals,
|
|
3441
|
-
guardrails: args.guardrails,
|
|
3442
|
-
risks: args.risks,
|
|
3443
|
-
constraints: args.constraints,
|
|
3444
|
-
assumptions: args.assumptions,
|
|
3445
|
-
architecture: args.architecture,
|
|
3446
|
-
fileStructure: args.fileStructure,
|
|
3447
|
-
techStack: args.techStack,
|
|
3448
|
-
dependencies: args.dependencies,
|
|
3449
|
-
apiContracts: args.apiContracts,
|
|
3450
|
-
acceptanceCriteria: args.acceptanceCriteria,
|
|
3451
|
-
tags: args.tags,
|
|
3452
|
-
estimatedHours: args.estimatedHours,
|
|
3453
|
-
// Pattern inheritance fields (F7-002)
|
|
3454
|
-
sharedPatterns: args.sharedPatterns,
|
|
3455
|
-
additionalImports: args.additionalImports,
|
|
3456
|
-
commonFiles: args.commonFiles,
|
|
3457
|
-
});
|
|
3458
|
-
return formatWriteResponse(result, responseMode, 'Epic updated');
|
|
3459
|
-
},
|
|
3460
|
-
update_specification: async (_client, args) => {
|
|
3461
|
-
validateRequired(args, 'specificationId');
|
|
3462
|
-
const responseMode = getResponseModeFromArgs(args);
|
|
3463
|
-
const result = await apiClient.call('update_specification', {
|
|
3464
|
-
specificationId: args.specificationId,
|
|
3465
|
-
title: args.title,
|
|
3466
|
-
description: args.description,
|
|
3467
|
-
status: args.status,
|
|
3468
|
-
background: args.background,
|
|
3469
|
-
scope: args.scope,
|
|
3470
|
-
priority: args.priority,
|
|
3471
|
-
// FI-003 fields
|
|
3472
|
-
goals: args.goals,
|
|
3473
|
-
requirements: args.requirements,
|
|
3474
|
-
nonFunctionalRequirements: args.nonFunctionalRequirements,
|
|
3475
|
-
successMetrics: args.successMetrics,
|
|
3476
|
-
constraints: args.constraints,
|
|
3477
|
-
assumptions: args.assumptions,
|
|
3478
|
-
risks: args.risks,
|
|
3479
|
-
guardrails: args.guardrails,
|
|
3480
|
-
architecture: args.architecture,
|
|
3481
|
-
fileStructure: args.fileStructure,
|
|
3482
|
-
techStack: args.techStack,
|
|
3483
|
-
dependencies: args.dependencies,
|
|
3484
|
-
apiContracts: args.apiContracts,
|
|
3485
|
-
acceptanceCriteria: args.acceptanceCriteria,
|
|
3486
|
-
tags: args.tags,
|
|
3487
|
-
estimatedHours: args.estimatedHours,
|
|
3488
|
-
targetAudience: args.targetAudience,
|
|
3489
|
-
// Pattern inheritance fields (F7-001)
|
|
3490
|
-
codeStandards: args.codeStandards,
|
|
3491
|
-
commonImports: args.commonImports,
|
|
3492
|
-
returnTypes: args.returnTypes,
|
|
3493
|
-
// Validation and workflow fields
|
|
3494
|
-
validationCommands: args.validationCommands,
|
|
3495
|
-
workingDirectory: args.workingDirectory,
|
|
3496
|
-
outputDirectory: args.outputDirectory,
|
|
3497
|
-
});
|
|
3498
|
-
return formatWriteResponse(result, responseMode, 'Specification updated');
|
|
3499
|
-
},
|
|
3500
|
-
// ========================================================================
|
|
3501
2405
|
// Implementation Session Operations
|
|
3502
2406
|
// ========================================================================
|
|
3503
2407
|
start_implementation_session: async (_client, args) => {
|
|
@@ -3516,33 +2420,6 @@ export function createToolHandlers(apiClient) {
|
|
|
3516
2420
|
summary: args.summary,
|
|
3517
2421
|
});
|
|
3518
2422
|
},
|
|
3519
|
-
// ========================================================================
|
|
3520
|
-
// Bulk Operations
|
|
3521
|
-
// ========================================================================
|
|
3522
|
-
bulk_add_dependencies: async (_client, args) => {
|
|
3523
|
-
validateRequired(args, 'dependencies');
|
|
3524
|
-
if (!Array.isArray(args.dependencies) || args.dependencies.length === 0) {
|
|
3525
|
-
throw new Error('dependencies array is required and must not be empty');
|
|
3526
|
-
}
|
|
3527
|
-
// Validate each dependency has required fields
|
|
3528
|
-
const deps = args.dependencies;
|
|
3529
|
-
for (let i = 0; i < deps.length; i++) {
|
|
3530
|
-
if (!deps[i].ticketId || typeof deps[i].ticketId !== 'string') {
|
|
3531
|
-
throw new Error(`dependencies[${i}].ticketId is required`);
|
|
3532
|
-
}
|
|
3533
|
-
if (!deps[i].dependsOnId || typeof deps[i].dependsOnId !== 'string') {
|
|
3534
|
-
throw new Error(`dependencies[${i}].dependsOnId is required`);
|
|
3535
|
-
}
|
|
3536
|
-
if (deps[i].ticketId === deps[i].dependsOnId) {
|
|
3537
|
-
throw new Error(`dependencies[${i}]: ticket cannot depend on itself`);
|
|
3538
|
-
}
|
|
3539
|
-
}
|
|
3540
|
-
return await apiClient.call('bulk_add_dependencies', {
|
|
3541
|
-
dependencies: args.dependencies,
|
|
3542
|
-
skipCircularCheck: args.skipCircularCheck,
|
|
3543
|
-
onError: args.onError,
|
|
3544
|
-
});
|
|
3545
|
-
},
|
|
3546
2423
|
bulk_update_tickets: async (_client, args) => {
|
|
3547
2424
|
if (!args.updates || !Array.isArray(args.updates) || args.updates.length === 0) {
|
|
3548
2425
|
throw new Error('updates array is required and must not be empty');
|
|
@@ -3672,18 +2549,6 @@ export function createToolHandlers(apiClient) {
|
|
|
3672
2549
|
// ========================================================================
|
|
3673
2550
|
// Delete Operations
|
|
3674
2551
|
// ========================================================================
|
|
3675
|
-
delete_ticket: async (_client, args) => {
|
|
3676
|
-
validateRequired(args, 'ticketId');
|
|
3677
|
-
return await apiClient.call('delete_ticket', {
|
|
3678
|
-
ticketId: args.ticketId,
|
|
3679
|
-
});
|
|
3680
|
-
},
|
|
3681
|
-
delete_epic: async (_client, args) => {
|
|
3682
|
-
validateRequired(args, 'epicId');
|
|
3683
|
-
return await apiClient.call('delete_epic', {
|
|
3684
|
-
epicId: args.epicId,
|
|
3685
|
-
});
|
|
3686
|
-
},
|
|
3687
2552
|
delete_specification: async (_client, args) => {
|
|
3688
2553
|
validateRequired(args, 'specificationId');
|
|
3689
2554
|
return await apiClient.call('delete_specification', {
|
|
@@ -3733,14 +2598,6 @@ export function createToolHandlers(apiClient) {
|
|
|
3733
2598
|
// ========================================================================
|
|
3734
2599
|
// Review & Completion
|
|
3735
2600
|
// ========================================================================
|
|
3736
|
-
review_planning: async (_client, args) => {
|
|
3737
|
-
const argsWithContext = injectContextRequired(args, ['specificationId']);
|
|
3738
|
-
return await apiClient.call('review_planning', {
|
|
3739
|
-
specificationId: argsWithContext.specificationId,
|
|
3740
|
-
page: argsWithContext.page,
|
|
3741
|
-
pageSize: argsWithContext.pageSize,
|
|
3742
|
-
});
|
|
3743
|
-
},
|
|
3744
2601
|
review_implementation: async (_client, args) => {
|
|
3745
2602
|
const argsWithContext = injectContextRequired(args, ['specificationId']);
|
|
3746
2603
|
return await apiClient.call('review_implementation', {
|
|
@@ -3753,12 +2610,44 @@ export function createToolHandlers(apiClient) {
|
|
|
3753
2610
|
specificationId: argsWithContext.specificationId,
|
|
3754
2611
|
});
|
|
3755
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
|
+
},
|
|
3756
2619
|
// ========================================================================
|
|
3757
2620
|
// Agent Teams - Workspace Files (Local-only)
|
|
3758
2621
|
// ========================================================================
|
|
3759
2622
|
get_workspace_files: async (_client, args) => {
|
|
3760
2623
|
return await getWorkspaceFiles(args);
|
|
3761
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
|
+
},
|
|
3762
2651
|
};
|
|
3763
2652
|
}
|
|
3764
2653
|
/**
|