@specforge/mcp 2.1.6 → 2.3.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.
Files changed (177) hide show
  1. package/dist/cli/commands/blocked.js +6 -6
  2. package/dist/cli/commands/blocked.js.map +1 -1
  3. package/dist/cli/commands/debug/test.d.ts.map +1 -1
  4. package/dist/cli/commands/debug/test.js +4 -3
  5. package/dist/cli/commands/debug/test.js.map +1 -1
  6. package/dist/cli/commands/doctor.d.ts.map +1 -1
  7. package/dist/cli/commands/doctor.js +39 -23
  8. package/dist/cli/commands/doctor.js.map +1 -1
  9. package/dist/cli/commands/feedback.d.ts +16 -0
  10. package/dist/cli/commands/feedback.d.ts.map +1 -0
  11. package/dist/cli/commands/feedback.js +220 -0
  12. package/dist/cli/commands/feedback.js.map +1 -0
  13. package/dist/cli/commands/feedback.types.d.ts +116 -0
  14. package/dist/cli/commands/feedback.types.d.ts.map +1 -0
  15. package/dist/cli/commands/feedback.types.js +97 -0
  16. package/dist/cli/commands/feedback.types.js.map +1 -0
  17. package/dist/cli/commands/index.d.ts +1 -0
  18. package/dist/cli/commands/index.d.ts.map +1 -1
  19. package/dist/cli/commands/index.js +1 -0
  20. package/dist/cli/commands/index.js.map +1 -1
  21. package/dist/cli/commands/init.d.ts.map +1 -1
  22. package/dist/cli/commands/init.js +7 -3
  23. package/dist/cli/commands/init.js.map +1 -1
  24. package/dist/cli/commands/next.js +3 -3
  25. package/dist/cli/commands/next.js.map +1 -1
  26. package/dist/cli/commands/review/epic-review.js +2 -2
  27. package/dist/cli/commands/review/epic-review.js.map +1 -1
  28. package/dist/cli/commands/review/types.d.ts +1 -1
  29. package/dist/cli/commands/review/types.d.ts.map +1 -1
  30. package/dist/cli/commands/scaffold/agent-types.d.ts +49 -0
  31. package/dist/cli/commands/scaffold/agent-types.d.ts.map +1 -0
  32. package/dist/cli/commands/scaffold/agent-types.js +37 -0
  33. package/dist/cli/commands/scaffold/agent-types.js.map +1 -0
  34. package/dist/cli/commands/scaffold/display.d.ts +31 -2
  35. package/dist/cli/commands/scaffold/display.d.ts.map +1 -1
  36. package/dist/cli/commands/scaffold/display.js +176 -14
  37. package/dist/cli/commands/scaffold/display.js.map +1 -1
  38. package/dist/cli/commands/scaffold/register.d.ts.map +1 -1
  39. package/dist/cli/commands/scaffold/register.js +8 -4
  40. package/dist/cli/commands/scaffold/register.js.map +1 -1
  41. package/dist/cli/commands/scaffold/scaffold.d.ts +1 -1
  42. package/dist/cli/commands/scaffold/scaffold.d.ts.map +1 -1
  43. package/dist/cli/commands/scaffold/scaffold.js +522 -30
  44. package/dist/cli/commands/scaffold/scaffold.js.map +1 -1
  45. package/dist/cli/commands/scaffold/targets.d.ts +12 -0
  46. package/dist/cli/commands/scaffold/targets.d.ts.map +1 -1
  47. package/dist/cli/commands/scaffold/targets.js +33 -0
  48. package/dist/cli/commands/scaffold/targets.js.map +1 -1
  49. package/dist/cli/commands/scaffold/types.d.ts +34 -1
  50. package/dist/cli/commands/scaffold/types.d.ts.map +1 -1
  51. package/dist/cli/commands/scaffold/types.js.map +1 -1
  52. package/dist/cli/commands/scaffold/utils.d.ts +22 -1
  53. package/dist/cli/commands/scaffold/utils.d.ts.map +1 -1
  54. package/dist/cli/commands/scaffold/utils.js +106 -0
  55. package/dist/cli/commands/scaffold/utils.js.map +1 -1
  56. package/dist/cli/commands/session/start.js +1 -1
  57. package/dist/cli/commands/session/start.js.map +1 -1
  58. package/dist/cli/commands/status.types.d.ts +1 -1
  59. package/dist/cli/commands/status.types.d.ts.map +1 -1
  60. package/dist/cli/commands/status.types.js +2 -2
  61. package/dist/cli/commands/status.types.js.map +1 -1
  62. package/dist/cli/commands/ticket/resolver.js +1 -1
  63. package/dist/cli/commands/ticket/resolver.js.map +1 -1
  64. package/dist/cli/commands/tickets.js +1 -1
  65. package/dist/cli/commands/tickets.js.map +1 -1
  66. package/dist/cli/commands/tickets.types.d.ts +1 -1
  67. package/dist/cli/commands/tickets.types.d.ts.map +1 -1
  68. package/dist/cli/config/writer.d.ts +32 -13
  69. package/dist/cli/config/writer.d.ts.map +1 -1
  70. package/dist/cli/config/writer.js +30 -11
  71. package/dist/cli/config/writer.js.map +1 -1
  72. package/dist/cli/index.d.ts.map +1 -1
  73. package/dist/cli/index.js +3 -1
  74. package/dist/cli/index.js.map +1 -1
  75. package/dist/cli/templates/agents/content/core/sfag-implementer.d.ts +8 -0
  76. package/dist/cli/templates/agents/content/core/sfag-implementer.d.ts.map +1 -0
  77. package/dist/cli/templates/agents/content/core/sfag-implementer.js +111 -0
  78. package/dist/cli/templates/agents/content/core/sfag-implementer.js.map +1 -0
  79. package/dist/cli/templates/agents/content/core/sfag-orchestrator.d.ts +8 -0
  80. package/dist/cli/templates/agents/content/core/sfag-orchestrator.d.ts.map +1 -0
  81. package/dist/cli/templates/agents/content/core/sfag-orchestrator.js +105 -0
  82. package/dist/cli/templates/agents/content/core/sfag-orchestrator.js.map +1 -0
  83. package/dist/cli/templates/agents/content/core/sfag-spec-creator.d.ts +8 -0
  84. package/dist/cli/templates/agents/content/core/sfag-spec-creator.d.ts.map +1 -0
  85. package/dist/cli/templates/agents/content/core/sfag-spec-creator.js +124 -0
  86. package/dist/cli/templates/agents/content/core/sfag-spec-creator.js.map +1 -0
  87. package/dist/cli/templates/agents/content/core/sfag-ticket-implementer.d.ts +8 -0
  88. package/dist/cli/templates/agents/content/core/sfag-ticket-implementer.d.ts.map +1 -0
  89. package/dist/cli/templates/agents/content/core/sfag-ticket-implementer.js +130 -0
  90. package/dist/cli/templates/agents/content/core/sfag-ticket-implementer.js.map +1 -0
  91. package/dist/cli/templates/agents/content/research/sfag-package-researcher.d.ts +8 -0
  92. package/dist/cli/templates/agents/content/research/sfag-package-researcher.d.ts.map +1 -0
  93. package/dist/cli/templates/agents/content/research/sfag-package-researcher.js +151 -0
  94. package/dist/cli/templates/agents/content/research/sfag-package-researcher.js.map +1 -0
  95. package/dist/cli/templates/agents/content/task-type/sfag-api-implementer.d.ts +8 -0
  96. package/dist/cli/templates/agents/content/task-type/sfag-api-implementer.d.ts.map +1 -0
  97. package/dist/cli/templates/agents/content/task-type/sfag-api-implementer.js +130 -0
  98. package/dist/cli/templates/agents/content/task-type/sfag-api-implementer.js.map +1 -0
  99. package/dist/cli/templates/agents/content/task-type/sfag-docs-writer.d.ts +8 -0
  100. package/dist/cli/templates/agents/content/task-type/sfag-docs-writer.d.ts.map +1 -0
  101. package/dist/cli/templates/agents/content/task-type/sfag-docs-writer.js +181 -0
  102. package/dist/cli/templates/agents/content/task-type/sfag-docs-writer.js.map +1 -0
  103. package/dist/cli/templates/agents/content/task-type/sfag-frontend-builder.d.ts +8 -0
  104. package/dist/cli/templates/agents/content/task-type/sfag-frontend-builder.d.ts.map +1 -0
  105. package/dist/cli/templates/agents/content/task-type/sfag-frontend-builder.js +139 -0
  106. package/dist/cli/templates/agents/content/task-type/sfag-frontend-builder.js.map +1 -0
  107. package/dist/cli/templates/agents/content/task-type/sfag-infra-architect.d.ts +8 -0
  108. package/dist/cli/templates/agents/content/task-type/sfag-infra-architect.d.ts.map +1 -0
  109. package/dist/cli/templates/agents/content/task-type/sfag-infra-architect.js +147 -0
  110. package/dist/cli/templates/agents/content/task-type/sfag-infra-architect.js.map +1 -0
  111. package/dist/cli/templates/agents/content/task-type/sfag-schema-designer.d.ts +8 -0
  112. package/dist/cli/templates/agents/content/task-type/sfag-schema-designer.d.ts.map +1 -0
  113. package/dist/cli/templates/agents/content/task-type/sfag-schema-designer.js +130 -0
  114. package/dist/cli/templates/agents/content/task-type/sfag-schema-designer.js.map +1 -0
  115. package/dist/cli/templates/agents/content/task-type/sfag-test-writer.d.ts +8 -0
  116. package/dist/cli/templates/agents/content/task-type/sfag-test-writer.d.ts.map +1 -0
  117. package/dist/cli/templates/agents/content/task-type/sfag-test-writer.js +169 -0
  118. package/dist/cli/templates/agents/content/task-type/sfag-test-writer.js.map +1 -0
  119. package/dist/cli/templates/agents/index.d.ts +23 -0
  120. package/dist/cli/templates/agents/index.d.ts.map +1 -0
  121. package/dist/cli/templates/agents/index.js +63 -0
  122. package/dist/cli/templates/agents/index.js.map +1 -0
  123. package/dist/cli/templates/content/sf-create-epics.d.ts +1 -1
  124. package/dist/cli/templates/content/sf-create-epics.d.ts.map +1 -1
  125. package/dist/cli/templates/content/sf-create-epics.js +72 -13
  126. package/dist/cli/templates/content/sf-create-epics.js.map +1 -1
  127. package/dist/cli/templates/content/sf-create-spec.d.ts +1 -1
  128. package/dist/cli/templates/content/sf-create-spec.d.ts.map +1 -1
  129. package/dist/cli/templates/content/sf-create-spec.js +91 -22
  130. package/dist/cli/templates/content/sf-create-spec.js.map +1 -1
  131. package/dist/cli/templates/content/sf-create-tickets.d.ts +1 -1
  132. package/dist/cli/templates/content/sf-create-tickets.d.ts.map +1 -1
  133. package/dist/cli/templates/content/sf-create-tickets.js +90 -18
  134. package/dist/cli/templates/content/sf-create-tickets.js.map +1 -1
  135. package/dist/cli/templates/index.d.ts +2 -1
  136. package/dist/cli/templates/index.d.ts.map +1 -1
  137. package/dist/cli/templates/index.js +4 -1
  138. package/dist/cli/templates/index.js.map +1 -1
  139. package/dist/lib/index.d.ts +1 -0
  140. package/dist/lib/index.d.ts.map +1 -1
  141. package/dist/lib/index.js +1 -0
  142. package/dist/lib/index.js.map +1 -1
  143. package/dist/lib/workflow-definitions.d.ts +41 -0
  144. package/dist/lib/workflow-definitions.d.ts.map +1 -0
  145. package/dist/lib/workflow-definitions.js +511 -0
  146. package/dist/lib/workflow-definitions.js.map +1 -0
  147. package/dist/tools/core/bulk.d.ts.map +1 -1
  148. package/dist/tools/core/bulk.js +5 -30
  149. package/dist/tools/core/bulk.js.map +1 -1
  150. package/dist/tools/core/epic.d.ts.map +1 -1
  151. package/dist/tools/core/epic.js +95 -11
  152. package/dist/tools/core/epic.js.map +1 -1
  153. package/dist/tools/core/feedback.d.ts +110 -0
  154. package/dist/tools/core/feedback.d.ts.map +1 -0
  155. package/dist/tools/core/feedback.js +303 -0
  156. package/dist/tools/core/feedback.js.map +1 -0
  157. package/dist/tools/core/help.d.ts.map +1 -1
  158. package/dist/tools/core/help.js +17 -2
  159. package/dist/tools/core/help.js.map +1 -1
  160. package/dist/tools/core/index.d.ts +2 -0
  161. package/dist/tools/core/index.d.ts.map +1 -1
  162. package/dist/tools/core/index.js +2 -0
  163. package/dist/tools/core/index.js.map +1 -1
  164. package/dist/tools/core/specification.d.ts.map +1 -1
  165. package/dist/tools/core/specification.js +98 -9
  166. package/dist/tools/core/specification.js.map +1 -1
  167. package/dist/tools/core/ticket.d.ts.map +1 -1
  168. package/dist/tools/core/ticket.js +48 -11
  169. package/dist/tools/core/ticket.js.map +1 -1
  170. package/dist/tools/core/workflow-guide.d.ts +13 -0
  171. package/dist/tools/core/workflow-guide.d.ts.map +1 -0
  172. package/dist/tools/core/workflow-guide.js +332 -0
  173. package/dist/tools/core/workflow-guide.js.map +1 -0
  174. package/dist/tools/index.d.ts.map +1 -1
  175. package/dist/tools/index.js +131 -96
  176. package/dist/tools/index.js.map +1 -1
  177. package/package.json +1 -1
@@ -0,0 +1,332 @@
1
+ // mcp/src/tools/core/workflow-guide.ts
2
+ /**
3
+ * Workflow Guide Tool
4
+ *
5
+ * Guides AI agents through SpecForge workflows, providing step-by-step
6
+ * instructions and contextual next actions.
7
+ */
8
+ import { createOperationRouter } from './router.js';
9
+ import { WORKFLOW_TYPES, getWorkflowDefinition, } from '../../lib/workflow-definitions.js';
10
+ export const workflowGuideTool = {
11
+ name: 'workflow_guide',
12
+ description: `Get guidance for SpecForge workflows. Operations:
13
+ - guide: Get full workflow instructions for a workflow type
14
+ - status: Get current workflow state and progress
15
+ - next: Get the specific next action to take`,
16
+ inputSchema: {
17
+ type: 'object',
18
+ properties: {
19
+ operation: {
20
+ type: 'string',
21
+ enum: ['guide', 'status', 'next'],
22
+ description: 'The operation to perform',
23
+ },
24
+ workflowType: {
25
+ type: 'string',
26
+ enum: WORKFLOW_TYPES,
27
+ description: 'Workflow type (required for guide): creation, implementation, review, finalize',
28
+ },
29
+ specificationId: {
30
+ type: 'string',
31
+ description: 'Specification ID (uses working context if not provided)',
32
+ },
33
+ },
34
+ required: ['operation'],
35
+ },
36
+ };
37
+ function validateRequired(args, ...fields) {
38
+ for (const field of fields) {
39
+ if (args[field] === undefined || args[field] === null || args[field] === '') {
40
+ throw new Error(`${field} is required`);
41
+ }
42
+ }
43
+ }
44
+ /**
45
+ * Determine the current and next step based on context and progress
46
+ */
47
+ function determineStep(context, progress) {
48
+ const hasActiveSession = context.activeSession != null;
49
+ const hasSpec = context.specificationId != null;
50
+ const hasEpic = context.epicId != null;
51
+ const hasTicket = context.ticketId != null;
52
+ // If we have an active session, we're in implementation workflow
53
+ if (hasActiveSession) {
54
+ // Check if we're in the middle of implementing
55
+ if (progress && progress.tickets.active > 0) {
56
+ return {
57
+ currentStep: 'implement',
58
+ nextStep: 'Continue implementing, report progress, then validate and complete',
59
+ };
60
+ }
61
+ return {
62
+ currentStep: 'session_active',
63
+ nextStep: 'Continue with session - implement the ticket and complete when done',
64
+ };
65
+ }
66
+ // Creation workflow logic
67
+ if (!hasSpec) {
68
+ return {
69
+ currentStep: 'no_specification',
70
+ nextStep: 'Create or select a specification to work on',
71
+ };
72
+ }
73
+ if (!progress) {
74
+ return {
75
+ currentStep: 'specification_selected',
76
+ nextStep: 'Plan and create epics for the specification',
77
+ };
78
+ }
79
+ // Check overall progress
80
+ const allEpicsDone = progress.epics.done === progress.epics.total && progress.epics.total > 0;
81
+ const allTicketsDone = progress.tickets.done === progress.tickets.total && progress.tickets.total > 0;
82
+ if (allEpicsDone && allTicketsDone) {
83
+ return {
84
+ currentStep: 'implementation_complete',
85
+ nextStep: 'Run finalize workflow - verify, create PR, end session',
86
+ };
87
+ }
88
+ if (progress.epics.total === 0) {
89
+ return {
90
+ currentStep: 'no_epics',
91
+ nextStep: 'Plan and create the first epic',
92
+ };
93
+ }
94
+ if (progress.tickets.total === 0) {
95
+ return {
96
+ currentStep: 'no_tickets',
97
+ nextStep: 'Plan and create tickets for the current epic',
98
+ };
99
+ }
100
+ if (progress.tickets.ready > 0) {
101
+ return {
102
+ currentStep: 'tickets_ready',
103
+ nextStep: 'Start a session and implement the next ready ticket',
104
+ };
105
+ }
106
+ if (progress.tickets.done < progress.tickets.total) {
107
+ return {
108
+ currentStep: 'tickets_blocked',
109
+ nextStep: 'Resolve blocked tickets or check dependencies',
110
+ };
111
+ }
112
+ return {
113
+ currentStep: 'unknown',
114
+ nextStep: 'Check workflow status and context',
115
+ };
116
+ }
117
+ /**
118
+ * Generate actionable next step recommendation
119
+ */
120
+ function generateNextAction(status) {
121
+ const { currentStep, currentState } = status;
122
+ switch (currentStep) {
123
+ case 'no_specification':
124
+ return {
125
+ step: 'create_specification',
126
+ reason: 'No specification is selected in the working context',
127
+ action: {
128
+ description: 'Create a new specification with full context',
129
+ tool: 'specification',
130
+ operation: 'create',
131
+ suggestedArgs: {
132
+ projectId: currentState.workingContext.projectId,
133
+ },
134
+ },
135
+ beforeProceeding: [
136
+ 'Gather requirements from user',
137
+ 'Understand the problem being solved',
138
+ 'Define scope and goals',
139
+ ],
140
+ };
141
+ case 'no_epics':
142
+ case 'specification_selected':
143
+ return {
144
+ step: 'create_epic',
145
+ reason: 'Specification exists but has no epics',
146
+ action: {
147
+ description: 'Plan epic structure then create the first epic',
148
+ tool: 'epic',
149
+ operation: 'create',
150
+ suggestedArgs: {
151
+ specificationId: currentState.workingContext.specificationId,
152
+ },
153
+ },
154
+ beforeProceeding: [
155
+ 'Discuss epic breakdown with user',
156
+ 'Identify logical phases',
157
+ 'Consider dependencies between epics',
158
+ ],
159
+ };
160
+ case 'no_tickets':
161
+ return {
162
+ step: 'create_ticket',
163
+ reason: 'Epic exists but has no tickets',
164
+ action: {
165
+ description: 'Plan ticket structure then create tickets one at a time',
166
+ tool: 'ticket',
167
+ operation: 'create',
168
+ suggestedArgs: {
169
+ epicId: currentState.workingContext.epicId,
170
+ },
171
+ },
172
+ beforeProceeding: [
173
+ 'Break epic into focused tickets',
174
+ 'Define acceptance criteria for each',
175
+ 'Map out dependencies',
176
+ ],
177
+ };
178
+ case 'tickets_ready':
179
+ return {
180
+ step: 'start_implementation',
181
+ reason: `${currentState.progress?.tickets.ready} ticket(s) are ready to implement`,
182
+ action: {
183
+ description: 'Start a session and begin implementing',
184
+ tool: 'session',
185
+ operation: 'start',
186
+ },
187
+ beforeProceeding: [
188
+ 'Get full implementation context with context.implementation',
189
+ 'Review acceptance criteria',
190
+ 'Ask user about unclear requirements',
191
+ ],
192
+ context: 'Use workflow.next_actionable to find the best ticket to start',
193
+ };
194
+ case 'session_active':
195
+ case 'implement':
196
+ return {
197
+ step: 'continue_implementation',
198
+ reason: 'Active session in progress',
199
+ action: {
200
+ description: 'Continue implementing the current ticket',
201
+ tool: 'session',
202
+ operation: 'progress',
203
+ suggestedArgs: {
204
+ ticketId: currentState.activeSession?.ticketId,
205
+ },
206
+ },
207
+ beforeProceeding: ['Review where you left off', 'Check ticket requirements'],
208
+ context: `Working on: ${currentState.activeSession?.ticketTitle}`,
209
+ };
210
+ case 'tickets_blocked':
211
+ return {
212
+ step: 'resolve_blockers',
213
+ reason: 'All remaining tickets are blocked by dependencies',
214
+ action: {
215
+ description: 'Check blocked tickets and resolve dependencies',
216
+ tool: 'workflow',
217
+ operation: 'blocked',
218
+ suggestedArgs: {
219
+ specificationId: currentState.workingContext.specificationId,
220
+ },
221
+ },
222
+ beforeProceeding: [
223
+ 'Review what tickets are blocking',
224
+ 'Check if any dependencies can be resolved',
225
+ ],
226
+ };
227
+ case 'implementation_complete':
228
+ return {
229
+ step: 'finalize',
230
+ reason: 'All epics and tickets are complete',
231
+ action: {
232
+ description: 'Run finalize workflow to create PR',
233
+ tool: 'workflow_guide',
234
+ operation: 'guide',
235
+ suggestedArgs: {
236
+ workflowType: 'finalize',
237
+ },
238
+ },
239
+ beforeProceeding: [
240
+ 'Run full test suite',
241
+ 'Check documentation is updated',
242
+ 'Review all changes',
243
+ ],
244
+ };
245
+ default:
246
+ return {
247
+ step: 'check_status',
248
+ reason: 'Current state is unclear',
249
+ action: {
250
+ description: 'Get working context to understand current state',
251
+ tool: 'context',
252
+ operation: 'working',
253
+ },
254
+ };
255
+ }
256
+ }
257
+ export function createWorkflowGuideOperations(apiClient) {
258
+ return {
259
+ guide: async (args, _userId) => {
260
+ validateRequired(args, 'workflowType');
261
+ const workflowType = args.workflowType;
262
+ const workflow = getWorkflowDefinition(workflowType);
263
+ if (!workflow) {
264
+ throw new Error(`Unknown workflow type: ${workflowType}. Valid types: ${WORKFLOW_TYPES.join(', ')}`);
265
+ }
266
+ return workflow;
267
+ },
268
+ status: async (args, _userId) => {
269
+ // Get working context
270
+ const context = (await apiClient.call('get_working_context', {}));
271
+ // Determine workflow type from context
272
+ const hasActiveSession = context.activeSession != null;
273
+ const workflowType = hasActiveSession ? 'implementation' : 'creation';
274
+ // Get progress if we have a specification
275
+ let progress = null;
276
+ const specId = args.specificationId || context.specificationId;
277
+ if (specId) {
278
+ try {
279
+ const spec = (await apiClient.call('get_specification', {
280
+ specificationId: specId,
281
+ summary: true,
282
+ }));
283
+ progress = {
284
+ epics: {
285
+ total: spec.epicCount ?? 0,
286
+ done: spec.completedEpicCount ?? 0,
287
+ },
288
+ tickets: {
289
+ total: spec.ticketCount ?? 0,
290
+ done: spec.completedTicketCount ?? 0,
291
+ ready: spec.readyTicketCount ?? 0,
292
+ active: spec.activeTicketCount ?? 0,
293
+ },
294
+ };
295
+ }
296
+ catch {
297
+ // Specification might not exist yet
298
+ progress = null;
299
+ }
300
+ }
301
+ // Determine current and next step
302
+ const { currentStep, nextStep } = determineStep(context, progress);
303
+ return {
304
+ workflow: workflowType,
305
+ currentState: {
306
+ activeSession: context.activeSession,
307
+ workingContext: {
308
+ projectId: context.projectId,
309
+ specificationId: context.specificationId,
310
+ epicId: context.epicId,
311
+ ticketId: context.ticketId,
312
+ },
313
+ progress,
314
+ },
315
+ currentStep,
316
+ nextStep,
317
+ };
318
+ },
319
+ next: async (args, userId) => {
320
+ // Get current status first
321
+ const statusHandler = createWorkflowGuideOperations(apiClient).status;
322
+ const status = (await statusHandler(args, userId));
323
+ // Generate actionable next step
324
+ return generateNextAction(status);
325
+ },
326
+ };
327
+ }
328
+ export function createWorkflowGuideHandler(apiClient) {
329
+ const operations = createWorkflowGuideOperations(apiClient);
330
+ return createOperationRouter('workflow_guide', operations);
331
+ }
332
+ //# sourceMappingURL=workflow-guide.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-guide.js","sourceRoot":"","sources":["../../../src/tools/core/workflow-guide.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC;;;;;GAKG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,EACL,cAAc,EACd,qBAAqB,GAGtB,MAAM,mCAAmC,CAAC;AAE3C,MAAM,CAAC,MAAM,iBAAiB,GAAS;IACrC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE;;;6CAG8B;IAC3C,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,SAAS,EAAE;gBACT,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC;gBACjC,WAAW,EAAE,0BAA0B;aACxC;YACD,YAAY,EAAE;gBACZ,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,cAAqC;gBAC3C,WAAW,EAAE,gFAAgF;aAC9F;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,yDAAyD;aACvE;SACF;QACD,QAAQ,EAAE,CAAC,WAAW,CAAC;KACxB;CACF,CAAC;AAEF,SAAS,gBAAgB,CAAC,IAA0B,EAAE,GAAG,MAAgB;IACvE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;YAC5E,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,cAAc,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;AACH,CAAC;AAqED;;GAEG;AACH,SAAS,aAAa,CACpB,OAAuB,EACvB,QAA6B;IAE7B,MAAM,gBAAgB,GAAG,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC;IACvD,MAAM,OAAO,GAAG,OAAO,CAAC,eAAe,IAAI,IAAI,CAAC;IAChD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC;IACvC,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;IAE3C,iEAAiE;IACjE,IAAI,gBAAgB,EAAE,CAAC;QACrB,+CAA+C;QAC/C,IAAI,QAAQ,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,OAAO;gBACL,WAAW,EAAE,WAAW;gBACxB,QAAQ,EAAE,oEAAoE;aAC/E,CAAC;QACJ,CAAC;QACD,OAAO;YACL,WAAW,EAAE,gBAAgB;YAC7B,QAAQ,EAAE,qEAAqE;SAChF,CAAC;IACJ,CAAC;IAED,0BAA0B;IAC1B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,WAAW,EAAE,kBAAkB;YAC/B,QAAQ,EAAE,6CAA6C;SACxD,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,WAAW,EAAE,wBAAwB;YACrC,QAAQ,EAAE,6CAA6C;SACxD,CAAC;IACJ,CAAC;IAED,yBAAyB;IACzB,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;IAC9F,MAAM,cAAc,GAClB,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC;IAEjF,IAAI,YAAY,IAAI,cAAc,EAAE,CAAC;QACnC,OAAO;YACL,WAAW,EAAE,yBAAyB;YACtC,QAAQ,EAAE,wDAAwD;SACnE,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO;YACL,WAAW,EAAE,UAAU;YACvB,QAAQ,EAAE,gCAAgC;SAC3C,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO;YACL,WAAW,EAAE,YAAY;YACzB,QAAQ,EAAE,8CAA8C;SACzD,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO;YACL,WAAW,EAAE,eAAe;YAC5B,QAAQ,EAAE,qDAAqD;SAChE,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACnD,OAAO;YACL,WAAW,EAAE,iBAAiB;YAC9B,QAAQ,EAAE,+CAA+C;SAC1D,CAAC;IACJ,CAAC;IAED,OAAO;QACL,WAAW,EAAE,SAAS;QACtB,QAAQ,EAAE,mCAAmC;KAC9C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CAAC,MAAsB;IAChD,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAE7C,QAAQ,WAAW,EAAE,CAAC;QACpB,KAAK,kBAAkB;YACrB,OAAO;gBACL,IAAI,EAAE,sBAAsB;gBAC5B,MAAM,EAAE,qDAAqD;gBAC7D,MAAM,EAAE;oBACN,WAAW,EAAE,8CAA8C;oBAC3D,IAAI,EAAE,eAAe;oBACrB,SAAS,EAAE,QAAQ;oBACnB,aAAa,EAAE;wBACb,SAAS,EAAE,YAAY,CAAC,cAAc,CAAC,SAAS;qBACjD;iBACF;gBACD,gBAAgB,EAAE;oBAChB,+BAA+B;oBAC/B,qCAAqC;oBACrC,wBAAwB;iBACzB;aACF,CAAC;QAEJ,KAAK,UAAU,CAAC;QAChB,KAAK,wBAAwB;YAC3B,OAAO;gBACL,IAAI,EAAE,aAAa;gBACnB,MAAM,EAAE,uCAAuC;gBAC/C,MAAM,EAAE;oBACN,WAAW,EAAE,gDAAgD;oBAC7D,IAAI,EAAE,MAAM;oBACZ,SAAS,EAAE,QAAQ;oBACnB,aAAa,EAAE;wBACb,eAAe,EAAE,YAAY,CAAC,cAAc,CAAC,eAAe;qBAC7D;iBACF;gBACD,gBAAgB,EAAE;oBAChB,kCAAkC;oBAClC,yBAAyB;oBACzB,qCAAqC;iBACtC;aACF,CAAC;QAEJ,KAAK,YAAY;YACf,OAAO;gBACL,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,gCAAgC;gBACxC,MAAM,EAAE;oBACN,WAAW,EAAE,yDAAyD;oBACtE,IAAI,EAAE,QAAQ;oBACd,SAAS,EAAE,QAAQ;oBACnB,aAAa,EAAE;wBACb,MAAM,EAAE,YAAY,CAAC,cAAc,CAAC,MAAM;qBAC3C;iBACF;gBACD,gBAAgB,EAAE;oBAChB,iCAAiC;oBACjC,qCAAqC;oBACrC,sBAAsB;iBACvB;aACF,CAAC;QAEJ,KAAK,eAAe;YAClB,OAAO;gBACL,IAAI,EAAE,sBAAsB;gBAC5B,MAAM,EAAE,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,mCAAmC;gBAClF,MAAM,EAAE;oBACN,WAAW,EAAE,wCAAwC;oBACrD,IAAI,EAAE,SAAS;oBACf,SAAS,EAAE,OAAO;iBACnB;gBACD,gBAAgB,EAAE;oBAChB,6DAA6D;oBAC7D,4BAA4B;oBAC5B,qCAAqC;iBACtC;gBACD,OAAO,EAAE,+DAA+D;aACzE,CAAC;QAEJ,KAAK,gBAAgB,CAAC;QACtB,KAAK,WAAW;YACd,OAAO;gBACL,IAAI,EAAE,yBAAyB;gBAC/B,MAAM,EAAE,4BAA4B;gBACpC,MAAM,EAAE;oBACN,WAAW,EAAE,0CAA0C;oBACvD,IAAI,EAAE,SAAS;oBACf,SAAS,EAAE,UAAU;oBACrB,aAAa,EAAE;wBACb,QAAQ,EAAE,YAAY,CAAC,aAAa,EAAE,QAAQ;qBAC/C;iBACF;gBACD,gBAAgB,EAAE,CAAC,2BAA2B,EAAE,2BAA2B,CAAC;gBAC5E,OAAO,EAAE,eAAe,YAAY,CAAC,aAAa,EAAE,WAAW,EAAE;aAClE,CAAC;QAEJ,KAAK,iBAAiB;YACpB,OAAO;gBACL,IAAI,EAAE,kBAAkB;gBACxB,MAAM,EAAE,mDAAmD;gBAC3D,MAAM,EAAE;oBACN,WAAW,EAAE,gDAAgD;oBAC7D,IAAI,EAAE,UAAU;oBAChB,SAAS,EAAE,SAAS;oBACpB,aAAa,EAAE;wBACb,eAAe,EAAE,YAAY,CAAC,cAAc,CAAC,eAAe;qBAC7D;iBACF;gBACD,gBAAgB,EAAE;oBAChB,kCAAkC;oBAClC,2CAA2C;iBAC5C;aACF,CAAC;QAEJ,KAAK,yBAAyB;YAC5B,OAAO;gBACL,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,oCAAoC;gBAC5C,MAAM,EAAE;oBACN,WAAW,EAAE,oCAAoC;oBACjD,IAAI,EAAE,gBAAgB;oBACtB,SAAS,EAAE,OAAO;oBAClB,aAAa,EAAE;wBACb,YAAY,EAAE,UAAU;qBACzB;iBACF;gBACD,gBAAgB,EAAE;oBAChB,qBAAqB;oBACrB,gCAAgC;oBAChC,oBAAoB;iBACrB;aACF,CAAC;QAEJ;YACE,OAAO;gBACL,IAAI,EAAE,cAAc;gBACpB,MAAM,EAAE,0BAA0B;gBAClC,MAAM,EAAE;oBACN,WAAW,EAAE,iDAAiD;oBAC9D,IAAI,EAAE,SAAS;oBACf,SAAS,EAAE,SAAS;iBACrB;aACF,CAAC;IACN,CAAC;AACH,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC3C,SAAoB;IAEpB,OAAO;QACL,KAAK,EAAE,KAAK,EAAE,IAA0B,EAAE,OAAe,EAAE,EAAE;YAC3D,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;YACvC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAsB,CAAC;YAEjD,MAAM,QAAQ,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC;YACrD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CACb,0BAA0B,YAAY,kBAAkB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACpF,CAAC;YACJ,CAAC;YAED,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,IAA0B,EAAE,OAAe,EAAE,EAAE;YAC5D,sBAAsB;YACtB,MAAM,OAAO,GAAG,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAmB,CAAC;YAEpF,uCAAuC;YACvC,MAAM,gBAAgB,GAAG,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC;YACvD,MAAM,YAAY,GAAG,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,UAAU,CAAC;YAEtE,0CAA0C;YAC1C,IAAI,QAAQ,GAAwB,IAAI,CAAC;YACzC,MAAM,MAAM,GAAI,IAAI,CAAC,eAA0B,IAAI,OAAO,CAAC,eAAe,CAAC;YAE3E,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,mBAAmB,EAAE;wBACtD,eAAe,EAAE,MAAM;wBACvB,OAAO,EAAE,IAAI;qBACd,CAAC,CAAyB,CAAC;oBAE5B,QAAQ,GAAG;wBACT,KAAK,EAAE;4BACL,KAAK,EAAE,IAAI,CAAC,SAAS,IAAI,CAAC;4BAC1B,IAAI,EAAE,IAAI,CAAC,kBAAkB,IAAI,CAAC;yBACnC;wBACD,OAAO,EAAE;4BACP,KAAK,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC;4BAC5B,IAAI,EAAE,IAAI,CAAC,oBAAoB,IAAI,CAAC;4BACpC,KAAK,EAAE,IAAI,CAAC,gBAAgB,IAAI,CAAC;4BACjC,MAAM,EAAE,IAAI,CAAC,iBAAiB,IAAI,CAAC;yBACpC;qBACF,CAAC;gBACJ,CAAC;gBAAC,MAAM,CAAC;oBACP,oCAAoC;oBACpC,QAAQ,GAAG,IAAI,CAAC;gBAClB,CAAC;YACH,CAAC;YAED,kCAAkC;YAClC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAEnE,OAAO;gBACL,QAAQ,EAAE,YAAY;gBACtB,YAAY,EAAE;oBACZ,aAAa,EAAE,OAAO,CAAC,aAAa;oBACpC,cAAc,EAAE;wBACd,SAAS,EAAE,OAAO,CAAC,SAAS;wBAC5B,eAAe,EAAE,OAAO,CAAC,eAAe;wBACxC,MAAM,EAAE,OAAO,CAAC,MAAM;wBACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;qBAC3B;oBACD,QAAQ;iBACT;gBACD,WAAW;gBACX,QAAQ;aACS,CAAC;QACtB,CAAC;QAED,IAAI,EAAE,KAAK,EAAE,IAA0B,EAAE,MAAc,EAAE,EAAE;YACzD,2BAA2B;YAC3B,MAAM,aAAa,GAAG,6BAA6B,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC;YACtE,MAAM,MAAM,GAAG,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAmB,CAAC;YAErE,gCAAgC;YAChC,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,SAAoB;IAC7D,MAAM,UAAU,GAAG,6BAA6B,CAAC,SAAS,CAAC,CAAC;IAC5D,OAAO,qBAAqB,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;AAC7D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAML,gBAAgB,EAKjB,MAAM,wBAAwB,CAAC;AAmBhC;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AA6ED,wBAAgB,QAAQ,IAAI,IAAI,EAAE,CA8tEjC;AAED;;GAEG;AACH,KAAK,WAAW,GAAG,CACjB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,OAAO,CAAC,OAAO,CAAC,CAAC;AA6EtB;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,SAAS,GACnB,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAogC7B;AAqCD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,GAAE,OAAe,GACrB,OAAO,CAAC,OAAO,CAAC,CA4DlB;AAED;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,GAAE,OAAe,GACrB,OAAO,CAAC,OAAO,GAAG,gBAAgB,CAAC,CAOrC;AAGD,OAAO,EACL,eAAe,EACf,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAML,gBAAgB,EAKjB,MAAM,wBAAwB,CAAC;AAsBhC;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AA6ED,wBAAgB,QAAQ,IAAI,IAAI,EAAE,CA2xEjC;AAED;;GAEG;AACH,KAAK,WAAW,GAAG,CACjB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,OAAO,CAAC,OAAO,CAAC,CAAC;AA6EtB;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,SAAS,GACnB,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAq+B7B;AAqCD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,GAAE,OAAe,GACrB,OAAO,CAAC,OAAO,CAAC,CA4DlB;AAED;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,GAAE,OAAe,GACrB,OAAO,CAAC,OAAO,GAAG,gBAAgB,CAAC,CAOrC;AAGD,OAAO,EACL,eAAe,EACf,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAC"}
@@ -17,6 +17,9 @@
17
17
  import { ValidationError, ApiError, validateToolArgs, formatMCPError, transformError, validateTicket, filterWarningsByStrictness, } from '../validation/index.js';
18
18
  import { resolvePatternsWithCache, getPatternOverrides, flattenCodeStandards, } from '../patterns/index.js';
19
19
  import { getResponseModeFromArgs, formatWriteResponse, } from '../lib/response.js';
20
+ import { createFeedbackHandler } from './core/feedback.js';
21
+ import { createWorkflowGuideHandler } from './core/workflow-guide.js';
22
+ import { WORKFLOW_TYPES } from '../lib/workflow-definitions.js';
20
23
  /**
21
24
  * Get list of all available tools
22
25
  *
@@ -1049,7 +1052,7 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
1049
1052
  // ========================================================================
1050
1053
  {
1051
1054
  name: 'create_specification',
1052
- description: 'Create a new specification with optional nested epics and tickets for bulk creation',
1055
+ description: 'Create a new specification with full context. Create epics separately using epic.create for better quality.',
1053
1056
  inputSchema: {
1054
1057
  type: 'object',
1055
1058
  properties: {
@@ -1166,32 +1169,6 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
1166
1169
  type: 'string',
1167
1170
  description: 'Who this specification is for (developers, users, stakeholders, etc.)',
1168
1171
  },
1169
- epics: {
1170
- type: 'array',
1171
- description: 'Nested epics to create (bulk creation)',
1172
- items: {
1173
- type: 'object',
1174
- properties: {
1175
- title: { type: 'string' },
1176
- description: { type: 'string' },
1177
- objective: { type: 'string' },
1178
- tickets: {
1179
- type: 'array',
1180
- items: {
1181
- type: 'object',
1182
- properties: {
1183
- title: { type: 'string' },
1184
- description: { type: 'string' },
1185
- acceptanceCriteria: { type: 'array', items: { type: 'string' } },
1186
- estimatedHours: { type: 'number' },
1187
- },
1188
- required: ['title'],
1189
- },
1190
- },
1191
- },
1192
- required: ['title', 'description', 'objective'],
1193
- },
1194
- },
1195
1172
  // Pattern inheritance fields (specification level)
1196
1173
  codeStandards: {
1197
1174
  type: 'object',
@@ -1240,7 +1217,7 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
1240
1217
  },
1241
1218
  {
1242
1219
  name: 'create_epic',
1243
- description: 'Create a new epic in a specification with optional nested tickets for bulk creation',
1220
+ description: 'Create a new epic in a specification with full context. Create tickets separately using ticket.create for better quality.',
1244
1221
  inputSchema: {
1245
1222
  type: 'object',
1246
1223
  properties: {
@@ -1338,30 +1315,6 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
1338
1315
  type: 'number',
1339
1316
  description: 'Total estimated hours for epic',
1340
1317
  },
1341
- tickets: {
1342
- type: 'array',
1343
- description: 'Nested tickets to create (bulk creation) with optional inline dependencies',
1344
- items: {
1345
- type: 'object',
1346
- properties: {
1347
- title: { type: 'string' },
1348
- description: { type: 'string' },
1349
- acceptanceCriteria: { type: 'array', items: { type: 'string' } },
1350
- estimatedHours: { type: 'number' },
1351
- complexity: { type: 'string', enum: ['small', 'medium', 'large', 'xlarge'] },
1352
- priority: { type: 'string', enum: ['high', 'medium', 'low'] },
1353
- implementation: { type: 'object', description: 'Implementation details' },
1354
- technicalDetails: { type: 'object', description: 'Technical details' },
1355
- tags: { type: 'array', items: { type: 'string' } },
1356
- dependsOn: {
1357
- type: 'array',
1358
- items: { type: 'number' },
1359
- description: 'Indexes of other tickets in this array that this ticket depends on',
1360
- },
1361
- },
1362
- required: ['title'],
1363
- },
1364
- },
1365
1318
  // Pattern inheritance fields (epic level)
1366
1319
  sharedPatterns: {
1367
1320
  type: 'object',
@@ -2328,6 +2281,115 @@ At least one scope filter (projectId, specificationId, or epicId) is required.`,
2328
2281
  required: [],
2329
2282
  },
2330
2283
  },
2284
+ // ========================================================================
2285
+ // Feedback Tool (Local-only)
2286
+ // ========================================================================
2287
+ {
2288
+ name: 'feedback',
2289
+ description: `Submit and manage feedback about MCP tools. Operations:
2290
+ - submit: Submit new feedback (requires category, summary)
2291
+ - list: List recent feedback entries
2292
+ - get: Get a specific feedback entry by ID`,
2293
+ inputSchema: {
2294
+ type: 'object',
2295
+ properties: {
2296
+ operation: {
2297
+ type: 'string',
2298
+ enum: ['submit', 'list', 'get'],
2299
+ description: 'The operation to perform',
2300
+ },
2301
+ // For submit operation
2302
+ category: {
2303
+ type: 'string',
2304
+ enum: ['bug', 'feature_request', 'usability', 'documentation', 'performance'],
2305
+ description: 'Feedback category (required for submit)',
2306
+ },
2307
+ summary: {
2308
+ type: 'string',
2309
+ description: 'Brief summary of the feedback (required for submit)',
2310
+ },
2311
+ severity: {
2312
+ type: 'string',
2313
+ enum: ['critical', 'high', 'medium', 'low'],
2314
+ description: 'Severity level (default: medium)',
2315
+ },
2316
+ tool: {
2317
+ type: 'string',
2318
+ description: 'Which MCP tool this relates to',
2319
+ },
2320
+ toolOperation: {
2321
+ type: 'string',
2322
+ description: 'Specific operation within the tool',
2323
+ },
2324
+ details: {
2325
+ type: 'string',
2326
+ description: 'Extended description',
2327
+ },
2328
+ expected: {
2329
+ type: 'string',
2330
+ description: 'Expected behavior',
2331
+ },
2332
+ actual: {
2333
+ type: 'string',
2334
+ description: 'Actual behavior',
2335
+ },
2336
+ errorMessage: {
2337
+ type: 'string',
2338
+ description: 'Error message if reporting a bug',
2339
+ },
2340
+ ticketId: {
2341
+ type: 'string',
2342
+ description: 'Related ticket ID',
2343
+ },
2344
+ // For list operation
2345
+ limit: {
2346
+ type: 'number',
2347
+ description: 'Maximum entries to return (default: 10)',
2348
+ },
2349
+ categoryFilter: {
2350
+ type: 'string',
2351
+ enum: ['bug', 'feature_request', 'usability', 'documentation', 'performance'],
2352
+ description: 'Filter by category',
2353
+ },
2354
+ // For get operation
2355
+ feedbackId: {
2356
+ type: 'string',
2357
+ description: 'Feedback ID to retrieve (required for get)',
2358
+ },
2359
+ },
2360
+ required: ['operation'],
2361
+ },
2362
+ },
2363
+ // ========================================================================
2364
+ // Workflow Guide Tool
2365
+ // ========================================================================
2366
+ {
2367
+ name: 'workflow_guide',
2368
+ description: `Get guidance for SpecForge workflows. Operations:
2369
+ - guide: Get full workflow instructions for a workflow type
2370
+ - status: Get current workflow state and progress
2371
+ - next: Get the specific next action to take`,
2372
+ inputSchema: {
2373
+ type: 'object',
2374
+ properties: {
2375
+ operation: {
2376
+ type: 'string',
2377
+ enum: ['guide', 'status', 'next'],
2378
+ description: 'The operation to perform',
2379
+ },
2380
+ workflowType: {
2381
+ type: 'string',
2382
+ enum: WORKFLOW_TYPES,
2383
+ description: 'Workflow type (required for guide): creation, implementation, review, finalize',
2384
+ },
2385
+ specificationId: {
2386
+ type: 'string',
2387
+ description: 'Specification ID (uses working context if not provided)',
2388
+ },
2389
+ },
2390
+ required: ['operation'],
2391
+ },
2392
+ },
2331
2393
  ];
2332
2394
  // Apply format parameter to all read operations
2333
2395
  return tools.map(tool => READ_TOOL_NAMES.has(tool.name) ? addFormatParameter(tool) : tool);
@@ -2898,7 +2960,6 @@ export function createToolHandlers(apiClient) {
2898
2960
  priority: args.priority,
2899
2961
  tags: args.tags,
2900
2962
  estimatedHours: args.estimatedHours,
2901
- epics: args.epics,
2902
2963
  // FI-003 fields
2903
2964
  nonFunctionalRequirements: args.nonFunctionalRequirements,
2904
2965
  successMetrics: args.successMetrics,
@@ -2921,48 +2982,6 @@ export function createToolHandlers(apiClient) {
2921
2982
  create_epic: async (_client, args) => {
2922
2983
  validateRequired(args, 'specificationId', 'title', 'description', 'objective');
2923
2984
  const responseMode = getResponseModeFromArgs(args);
2924
- // Validate inline dependencies if tickets are provided with dependsOn
2925
- if (args.tickets && Array.isArray(args.tickets)) {
2926
- const tickets = args.tickets;
2927
- const ticketCount = tickets.length;
2928
- for (let i = 0; i < ticketCount; i++) {
2929
- const ticket = tickets[i];
2930
- if (ticket.dependsOn && Array.isArray(ticket.dependsOn)) {
2931
- for (const depIndex of ticket.dependsOn) {
2932
- // Check bounds
2933
- if (typeof depIndex !== 'number' || depIndex < 0 || depIndex >= ticketCount) {
2934
- throw new Error(`tickets[${i}].dependsOn: index ${depIndex} is out of bounds (must be 0-${ticketCount - 1})`);
2935
- }
2936
- // Check self-reference
2937
- if (depIndex === i) {
2938
- throw new Error(`tickets[${i}].dependsOn: ticket cannot depend on itself`);
2939
- }
2940
- }
2941
- }
2942
- }
2943
- // Check for circular dependencies using DFS
2944
- const hasCycle = (startIdx, visited, path) => {
2945
- if (path.has(startIdx))
2946
- return true;
2947
- if (visited.has(startIdx))
2948
- return false;
2949
- visited.add(startIdx);
2950
- path.add(startIdx);
2951
- const deps = tickets[startIdx].dependsOn || [];
2952
- for (const depIdx of deps) {
2953
- if (hasCycle(depIdx, visited, path))
2954
- return true;
2955
- }
2956
- path.delete(startIdx);
2957
- return false;
2958
- };
2959
- const visited = new Set();
2960
- for (let i = 0; i < ticketCount; i++) {
2961
- if (hasCycle(i, visited, new Set())) {
2962
- throw new Error(`Circular dependency detected in tickets array`);
2963
- }
2964
- }
2965
- }
2966
2985
  const result = await apiClient.call('create_epic', {
2967
2986
  specificationId: args.specificationId,
2968
2987
  title: args.title,
@@ -2977,7 +2996,6 @@ export function createToolHandlers(apiClient) {
2977
2996
  tags: args.tags,
2978
2997
  estimatedHours: args.estimatedHours,
2979
2998
  order: args.order,
2980
- tickets: args.tickets,
2981
2999
  // FI-003 fields
2982
3000
  guardrails: args.guardrails,
2983
3001
  risks: args.risks,
@@ -3344,6 +3362,23 @@ export function createToolHandlers(apiClient) {
3344
3362
  verbose: args.verbose,
3345
3363
  });
3346
3364
  },
3365
+ // ========================================================================
3366
+ // Feedback Tool (Local-only)
3367
+ // ========================================================================
3368
+ feedback: async (_client, args) => {
3369
+ // Get user ID from API client config (or use a default)
3370
+ const userId = 'local-user';
3371
+ const handler = createFeedbackHandler();
3372
+ return await handler(args, userId);
3373
+ },
3374
+ // ========================================================================
3375
+ // Workflow Guide Tool
3376
+ // ========================================================================
3377
+ workflow_guide: async (_client, args) => {
3378
+ const userId = 'local-user';
3379
+ const handler = createWorkflowGuideHandler(apiClient);
3380
+ return await handler(args, userId);
3381
+ },
3347
3382
  };
3348
3383
  }
3349
3384
  /**