@girardmedia/bootspring 2.0.21 → 2.0.23

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 (159) hide show
  1. package/bin/bootspring.js +5 -0
  2. package/cli/org.js +474 -0
  3. package/cli/preseed/index.js +16 -0
  4. package/cli/preseed/interactive.js +143 -0
  5. package/cli/preseed/templates.js +227 -0
  6. package/cli/preseed.js +9 -301
  7. package/cli/seed/builders/ai-context-builder.js +85 -0
  8. package/cli/seed/builders/index.js +13 -0
  9. package/cli/seed/builders/seed-builder.js +272 -0
  10. package/cli/seed/extractors/content-extractors.js +383 -0
  11. package/cli/seed/extractors/index.js +47 -0
  12. package/cli/seed/extractors/metadata-extractors.js +167 -0
  13. package/cli/seed/extractors/section-extractor.js +54 -0
  14. package/cli/seed/extractors/stack-extractors.js +228 -0
  15. package/cli/seed/index.js +18 -0
  16. package/cli/seed/utils/folder-structure.js +84 -0
  17. package/cli/seed/utils/index.js +11 -0
  18. package/cli/seed.js +23 -1074
  19. package/core/api-client.js +77 -0
  20. package/core/entitlements.js +36 -0
  21. package/core/organizations.js +223 -0
  22. package/core/policies.js +51 -6
  23. package/core/policy-matrix.js +303 -0
  24. package/core/project-context.js +1 -0
  25. package/dist/cli/index.d.ts +3 -0
  26. package/dist/cli/index.js +3220 -0
  27. package/dist/cli/index.js.map +1 -0
  28. package/dist/context-McpJQa_2.d.ts +5710 -0
  29. package/dist/core/index.d.ts +635 -0
  30. package/dist/core/index.js +2593 -0
  31. package/dist/core/index.js.map +1 -0
  32. package/dist/index-QqbeEiDm.d.ts +857 -0
  33. package/dist/index-UiYCgwiH.d.ts +174 -0
  34. package/dist/index.d.ts +453 -0
  35. package/dist/index.js +44228 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/mcp/index.d.ts +1 -0
  38. package/dist/mcp/index.js +41173 -0
  39. package/dist/mcp/index.js.map +1 -0
  40. package/generators/index.ts +82 -0
  41. package/intelligence/orchestrator/config/failure-signatures.js +48 -0
  42. package/intelligence/orchestrator/config/index.js +23 -0
  43. package/intelligence/orchestrator/config/pack-lifecycle.js +262 -0
  44. package/intelligence/orchestrator/config/phases.js +111 -0
  45. package/intelligence/orchestrator/config/remediation.js +150 -0
  46. package/intelligence/orchestrator/config/workflows.js +168 -0
  47. package/intelligence/orchestrator/core/index.js +16 -0
  48. package/intelligence/orchestrator/core/state-manager.js +88 -0
  49. package/intelligence/orchestrator/core/telemetry.js +24 -0
  50. package/intelligence/orchestrator/index.js +17 -0
  51. package/intelligence/orchestrator.js +17 -512
  52. package/mcp/contracts/mcp-contract.v1.json +1 -1
  53. package/package.json +16 -3
  54. package/src/cli/agent.ts +703 -0
  55. package/src/cli/analyze.ts +640 -0
  56. package/src/cli/audit.ts +707 -0
  57. package/src/cli/auth.ts +930 -0
  58. package/src/cli/billing.ts +364 -0
  59. package/src/cli/build.ts +1089 -0
  60. package/src/cli/business.ts +508 -0
  61. package/src/cli/checkpoint-utils.ts +236 -0
  62. package/src/cli/checkpoint.ts +757 -0
  63. package/src/cli/cloud-sync.ts +534 -0
  64. package/src/cli/content.ts +273 -0
  65. package/src/cli/context.ts +667 -0
  66. package/src/cli/dashboard.ts +133 -0
  67. package/src/cli/deploy.ts +704 -0
  68. package/src/cli/doctor.ts +480 -0
  69. package/src/cli/fundraise.ts +494 -0
  70. package/src/cli/generate.ts +346 -0
  71. package/src/cli/github-cmd.ts +566 -0
  72. package/src/cli/health.ts +599 -0
  73. package/src/cli/index.ts +113 -0
  74. package/src/cli/init.ts +838 -0
  75. package/src/cli/legal.ts +495 -0
  76. package/src/cli/log.ts +316 -0
  77. package/src/cli/loop.ts +1660 -0
  78. package/src/cli/manager.ts +878 -0
  79. package/src/cli/mcp.ts +275 -0
  80. package/src/cli/memory.ts +346 -0
  81. package/src/cli/metrics.ts +590 -0
  82. package/src/cli/monitor.ts +960 -0
  83. package/src/cli/mvp.ts +662 -0
  84. package/src/cli/onboard.ts +663 -0
  85. package/src/cli/orchestrator.ts +622 -0
  86. package/src/cli/plugin.ts +483 -0
  87. package/src/cli/prd.ts +671 -0
  88. package/src/cli/preseed-start.ts +1633 -0
  89. package/src/cli/preseed.ts +2434 -0
  90. package/src/cli/project.ts +526 -0
  91. package/src/cli/quality.ts +885 -0
  92. package/src/cli/security.ts +1079 -0
  93. package/src/cli/seed.ts +1224 -0
  94. package/src/cli/skill.ts +537 -0
  95. package/src/cli/suggest.ts +1225 -0
  96. package/src/cli/switch.ts +518 -0
  97. package/src/cli/task.ts +780 -0
  98. package/src/cli/telemetry.ts +172 -0
  99. package/src/cli/todo.ts +627 -0
  100. package/src/cli/types.ts +15 -0
  101. package/src/cli/update.ts +334 -0
  102. package/src/cli/visualize.ts +609 -0
  103. package/src/cli/watch.ts +895 -0
  104. package/src/cli/workspace.ts +709 -0
  105. package/src/core/action-recorder.ts +673 -0
  106. package/src/core/analyze-workflow.ts +1453 -0
  107. package/src/core/api-client.ts +1120 -0
  108. package/src/core/audit-workflow.ts +1681 -0
  109. package/src/core/auth.ts +471 -0
  110. package/src/core/build-orchestrator.ts +509 -0
  111. package/src/core/build-state.ts +621 -0
  112. package/src/core/checkpoint-engine.ts +482 -0
  113. package/src/core/config.ts +1285 -0
  114. package/src/core/context-loader.ts +694 -0
  115. package/src/core/context.ts +410 -0
  116. package/src/core/deploy-workflow.ts +1085 -0
  117. package/src/core/entitlements.ts +322 -0
  118. package/src/core/github-sync.ts +720 -0
  119. package/src/core/index.ts +981 -0
  120. package/src/core/ingest.ts +1186 -0
  121. package/src/core/metrics-engine.ts +886 -0
  122. package/src/core/mvp.ts +847 -0
  123. package/src/core/onboard-workflow.ts +1293 -0
  124. package/src/core/policies.ts +81 -0
  125. package/src/core/preseed-workflow.ts +1163 -0
  126. package/src/core/preseed.ts +1826 -0
  127. package/src/core/project-context.ts +380 -0
  128. package/src/core/project-state.ts +699 -0
  129. package/src/core/r2-sync.ts +691 -0
  130. package/src/core/scaffold.ts +1715 -0
  131. package/src/core/session.ts +286 -0
  132. package/src/core/task-extractor.ts +799 -0
  133. package/src/core/telemetry.ts +371 -0
  134. package/src/core/tier-enforcement.ts +737 -0
  135. package/src/core/utils.ts +437 -0
  136. package/src/index.ts +29 -0
  137. package/src/intelligence/agent-collab.ts +2376 -0
  138. package/src/intelligence/auto-suggest.ts +713 -0
  139. package/src/intelligence/content-gen.ts +1351 -0
  140. package/src/intelligence/cross-project.ts +1692 -0
  141. package/src/intelligence/git-memory.ts +529 -0
  142. package/src/intelligence/index.ts +318 -0
  143. package/src/intelligence/orchestrator.ts +534 -0
  144. package/src/intelligence/prd.ts +466 -0
  145. package/src/intelligence/recommendations.ts +982 -0
  146. package/src/intelligence/workflow-composer.ts +1472 -0
  147. package/src/mcp/capabilities.ts +233 -0
  148. package/src/mcp/index.ts +37 -0
  149. package/src/mcp/registry.ts +1268 -0
  150. package/src/mcp/response-formatter.ts +797 -0
  151. package/src/mcp/server.ts +240 -0
  152. package/src/types/agent.ts +69 -0
  153. package/src/types/config.ts +86 -0
  154. package/src/types/context.ts +77 -0
  155. package/src/types/index.ts +53 -0
  156. package/src/types/mcp.ts +91 -0
  157. package/src/types/skills.ts +47 -0
  158. package/src/types/workflow.ts +155 -0
  159. package/generators/index.js +0 -18
@@ -0,0 +1,797 @@
1
+ /**
2
+ * Bootspring MCP Response Formatter
3
+ * Creates well-structured, human-friendly tool responses
4
+ *
5
+ * @package bootspring
6
+ * @module mcp/response-formatter
7
+ */
8
+
9
+ import type { MCPToolResult, MCPContent } from '../types/mcp';
10
+
11
+ // =============================================================================
12
+ // Types
13
+ // =============================================================================
14
+
15
+ /**
16
+ * Success response options
17
+ */
18
+ export interface SuccessOptions {
19
+ summary?: string | undefined;
20
+ data?: unknown;
21
+ hints?: string[] | undefined;
22
+ meta?: Record<string, unknown> | undefined;
23
+ }
24
+
25
+ /**
26
+ * List response options
27
+ */
28
+ export interface ListOptions<T> {
29
+ title: string;
30
+ items: T[];
31
+ formatter?: ((item: T, index: number) => string) | undefined;
32
+ emptyMessage?: string | undefined;
33
+ hints?: string[] | undefined;
34
+ }
35
+
36
+ /**
37
+ * Agent data for display
38
+ */
39
+ export interface AgentData {
40
+ name: string;
41
+ category?: string | undefined;
42
+ description: string;
43
+ expertise: string[];
44
+ systemPrompt?: string | undefined;
45
+ }
46
+
47
+ /**
48
+ * Skill data for display
49
+ */
50
+ export interface SkillData {
51
+ name: string;
52
+ description: string;
53
+ tags?: string[] | undefined;
54
+ }
55
+
56
+ /**
57
+ * Todo item for display
58
+ */
59
+ export interface TodoItem {
60
+ text: string;
61
+ status?: string | undefined;
62
+ }
63
+
64
+ /**
65
+ * Quality gate results
66
+ */
67
+ export interface QualityGateResults {
68
+ name?: string | undefined;
69
+ gate?: string | undefined;
70
+ status: 'pass' | 'fail';
71
+ passed: number;
72
+ failed: number;
73
+ skipped?: number | undefined;
74
+ results: QualityCheckResult[];
75
+ }
76
+
77
+ /**
78
+ * Individual quality check result
79
+ */
80
+ export interface QualityCheckResult {
81
+ name: string;
82
+ status: 'pass' | 'fail' | 'skip';
83
+ message?: string | undefined;
84
+ }
85
+
86
+ /**
87
+ * Context validation result
88
+ */
89
+ export interface ContextValidationResult {
90
+ valid: boolean;
91
+ errors?: string[] | undefined;
92
+ warnings?: string[] | undefined;
93
+ suggestions?: string[] | undefined;
94
+ }
95
+
96
+ /**
97
+ * Project context for display
98
+ */
99
+ export interface ProjectContextDisplay {
100
+ project?: {
101
+ name?: string | undefined;
102
+ version?: string | undefined;
103
+ } | undefined;
104
+ stack?: {
105
+ framework?: string | undefined;
106
+ language?: string | undefined;
107
+ database?: string | undefined;
108
+ } | undefined;
109
+ plugins?: Record<string, unknown> | undefined;
110
+ }
111
+
112
+ /**
113
+ * Orchestrator status
114
+ */
115
+ export interface OrchestratorStatus {
116
+ currentPhase?: string | undefined;
117
+ availableAgents?: number | undefined;
118
+ activeWorkflow?: string | undefined;
119
+ activeWorkflowSignalProgress?: {
120
+ completedSignals: unknown[];
121
+ totalSignals: number;
122
+ } | undefined;
123
+ recentSuggestions?: Array<{ text?: string | undefined } | string> | undefined;
124
+ }
125
+
126
+ /**
127
+ * PRD data for display
128
+ */
129
+ export interface PRDData {
130
+ name: string;
131
+ stories: Array<{
132
+ title: string;
133
+ status: string;
134
+ }>;
135
+ }
136
+
137
+ /**
138
+ * Progress info
139
+ */
140
+ export interface ProgressInfo {
141
+ completed: number;
142
+ total: number;
143
+ percentage: number;
144
+ }
145
+
146
+ /**
147
+ * Assist response
148
+ */
149
+ export interface AssistResponseData {
150
+ confidenceTier?: 'high' | 'medium' | 'low' | 'very_low' | undefined;
151
+ understood?: {
152
+ intent?: string | undefined;
153
+ confidence?: number | undefined;
154
+ description?: string | undefined;
155
+ } | undefined;
156
+ primarySuggestion?: {
157
+ message: string;
158
+ } | undefined;
159
+ clarificationNeeded?: boolean | undefined;
160
+ clarificationQuestion?: string | undefined;
161
+ clarificationOptions?: string[] | undefined;
162
+ suggestions?: Array<{ message: string }> | undefined;
163
+ memoryInsight?: {
164
+ message: string;
165
+ recommendation: string;
166
+ } | undefined;
167
+ recommendedTool?: {
168
+ name: string;
169
+ args: Record<string, unknown>;
170
+ reason: string;
171
+ } | undefined;
172
+ }
173
+
174
+ /**
175
+ * Intent detection result
176
+ */
177
+ export interface IntentDetectionData {
178
+ intent?: string | undefined;
179
+ intentDescription?: string | undefined;
180
+ intentConfidence?: number | undefined;
181
+ matches?: Array<{
182
+ category: string;
183
+ keywordCount: number;
184
+ }> | undefined;
185
+ suggestedAgents?: string[] | undefined;
186
+ proactiveSuggestions?: Array<{ message: string }> | undefined;
187
+ }
188
+
189
+ /**
190
+ * Extended MCP tool result with metadata
191
+ */
192
+ export interface MCPToolResultWithMeta extends MCPToolResult {
193
+ _meta?: Record<string, unknown> | undefined;
194
+ }
195
+
196
+ // =============================================================================
197
+ // Functions
198
+ // =============================================================================
199
+
200
+ /**
201
+ * Format a success response with structured output
202
+ */
203
+ export function success(options: SuccessOptions): MCPToolResultWithMeta {
204
+ const { summary, data, hints = [], meta = {} } = options;
205
+ const sections: string[] = [];
206
+
207
+ // Summary section
208
+ if (summary) {
209
+ sections.push(`\u2713 ${summary}`);
210
+ }
211
+
212
+ // Data section
213
+ if (data !== undefined && data !== null) {
214
+ if (typeof data === 'string') {
215
+ sections.push(data);
216
+ } else {
217
+ sections.push(JSON.stringify(data, null, 2));
218
+ }
219
+ }
220
+
221
+ // Hints section
222
+ if (hints && hints.length > 0) {
223
+ sections.push('\n\ud83d\udca1 Hints:');
224
+ hints.forEach(hint => sections.push(` \u2022 ${hint}`));
225
+ }
226
+
227
+ return {
228
+ content: [{
229
+ type: 'text',
230
+ text: sections.join('\n')
231
+ }],
232
+ _meta: meta
233
+ };
234
+ }
235
+
236
+ /**
237
+ * Format an error response
238
+ */
239
+ export function error(message: string, suggestions: string[] = []): MCPToolResult {
240
+ const sections: string[] = [`\u2717 Error: ${message}`];
241
+
242
+ if (suggestions.length > 0) {
243
+ sections.push('\n\ud83d\udca1 Suggestions:');
244
+ suggestions.forEach(s => sections.push(` \u2022 ${s}`));
245
+ }
246
+
247
+ return {
248
+ content: [{
249
+ type: 'text',
250
+ text: sections.join('\n')
251
+ }],
252
+ isError: true
253
+ };
254
+ }
255
+
256
+ /**
257
+ * Format a warning response
258
+ */
259
+ export function warning(message: string, suggestions: string[] = []): MCPToolResult {
260
+ const sections: string[] = [`\u26a0\ufe0f Warning: ${message}`];
261
+
262
+ if (suggestions.length > 0) {
263
+ sections.push('\n\ud83d\udca1 Suggestions:');
264
+ suggestions.forEach(s => sections.push(` \u2022 ${s}`));
265
+ }
266
+
267
+ return {
268
+ content: [{
269
+ type: 'text',
270
+ text: sections.join('\n')
271
+ }]
272
+ };
273
+ }
274
+
275
+ /**
276
+ * Format a list response with items
277
+ */
278
+ export function list<T>(options: ListOptions<T>): MCPToolResult {
279
+ const { title, items, formatter, emptyMessage = 'No items found', hints = [] } = options;
280
+ const sections: string[] = [];
281
+
282
+ sections.push(`\ud83d\udccb ${title}`);
283
+ sections.push(` ${items.length} item(s)\n`);
284
+
285
+ if (items.length === 0) {
286
+ sections.push(` ${emptyMessage}`);
287
+ } else {
288
+ items.forEach((item, index) => {
289
+ const formatted = formatter ? formatter(item, index) : String(item);
290
+ sections.push(formatted);
291
+ });
292
+ }
293
+
294
+ if (hints && hints.length > 0) {
295
+ sections.push('\n\ud83d\udca1 Hints:');
296
+ hints.forEach(hint => sections.push(` \u2022 ${hint}`));
297
+ }
298
+
299
+ return {
300
+ content: [{
301
+ type: 'text',
302
+ text: sections.join('\n')
303
+ }]
304
+ };
305
+ }
306
+
307
+ /**
308
+ * Format agent details for display
309
+ */
310
+ export function agentDetails(id: string, agent: AgentData): MCPToolResult {
311
+ const sections: string[] = [
312
+ `\ud83e\udd16 Agent: ${agent.name}`,
313
+ ` ID: ${id}`,
314
+ ` Category: ${agent.category ?? 'General'}`,
315
+ '',
316
+ agent.description,
317
+ '',
318
+ '\ud83d\udcda Expertise:',
319
+ ...agent.expertise.map(e => ` \u2022 ${e}`),
320
+ ''
321
+ ];
322
+
323
+ if (agent.systemPrompt) {
324
+ sections.push('\ud83d\udcdd System Prompt Available: Yes');
325
+ }
326
+
327
+ sections.push(
328
+ '',
329
+ '\ud83d\udca1 Usage:',
330
+ ' Invoke this agent with a topic to get specialized assistance'
331
+ );
332
+
333
+ return {
334
+ content: [{
335
+ type: 'text',
336
+ text: sections.join('\n')
337
+ }]
338
+ };
339
+ }
340
+
341
+ /**
342
+ * Format skill details for display
343
+ */
344
+ export function skillDetails(id: string, skill: SkillData, content: string | null = null): MCPToolResult {
345
+ const sections: string[] = [
346
+ `\ud83d\udcd6 Skill: ${skill.name}`,
347
+ ` ID: ${id}`,
348
+ '',
349
+ skill.description,
350
+ ''
351
+ ];
352
+
353
+ if (skill.tags && skill.tags.length > 0) {
354
+ sections.push(`\ud83c\udff7\ufe0f Tags: ${skill.tags.join(', ')}`);
355
+ sections.push('');
356
+ }
357
+
358
+ if (content) {
359
+ sections.push('---', '', content);
360
+ }
361
+
362
+ return {
363
+ content: [{
364
+ type: 'text',
365
+ text: sections.join('\n')
366
+ }]
367
+ };
368
+ }
369
+
370
+ /**
371
+ * Format todo list for display
372
+ */
373
+ export function todoList(pending: TodoItem[], completed: TodoItem[]): MCPToolResult {
374
+ const sections: string[] = [
375
+ '\ud83d\udccb Project Todo List',
376
+ ''
377
+ ];
378
+
379
+ sections.push(`\u23f3 Pending (${pending.length}):`);
380
+ if (pending.length === 0) {
381
+ sections.push(' No pending tasks! \ud83c\udf89');
382
+ } else {
383
+ pending.forEach((t, i) => {
384
+ sections.push(` ${i}. [ ] ${t.text}`);
385
+ });
386
+ }
387
+
388
+ sections.push('');
389
+ sections.push(`\u2705 Completed (${completed.length}):`);
390
+ if (completed.length === 0) {
391
+ sections.push(' No completed tasks yet');
392
+ } else {
393
+ completed.slice(0, 5).forEach(t => {
394
+ sections.push(` [x] ${t.text}`);
395
+ });
396
+ if (completed.length > 5) {
397
+ sections.push(` ... and ${completed.length - 5} more`);
398
+ }
399
+ }
400
+
401
+ sections.push(
402
+ '',
403
+ '\ud83d\udca1 Actions:',
404
+ ' \u2022 Add: bootspring_todo action=add text="your task"',
405
+ ' \u2022 Complete: bootspring_todo action=done index=0',
406
+ ' \u2022 Remove: bootspring_todo action=remove index=0'
407
+ );
408
+
409
+ return {
410
+ content: [{
411
+ type: 'text',
412
+ text: sections.join('\n')
413
+ }]
414
+ };
415
+ }
416
+
417
+ /**
418
+ * Format quality gate results
419
+ */
420
+ export function qualityResults(results: QualityGateResults): MCPToolResult {
421
+ const statusIcon = results.status === 'pass' ? '\u2705' : '\u274c';
422
+ const sections: string[] = [
423
+ `${statusIcon} Quality Gate: ${results.name ?? results.gate ?? 'Unknown'}`,
424
+ ` Status: ${results.status.toUpperCase()}`,
425
+ ` Passed: ${results.passed} | Failed: ${results.failed} | Skipped: ${results.skipped ?? 0}`,
426
+ ''
427
+ ];
428
+
429
+ sections.push('\ud83d\udcca Check Results:');
430
+ for (const check of results.results) {
431
+ const icon = check.status === 'pass'
432
+ ? '\u2713'
433
+ : check.status === 'fail'
434
+ ? '\u2717'
435
+ : '\u25cb';
436
+ sections.push(` ${icon} ${check.name}: ${check.status}`);
437
+ if (check.status === 'fail' && check.message) {
438
+ const shortMessage = check.message.split('\n')[0]?.slice(0, 60) ?? '';
439
+ sections.push(` ${shortMessage}...`);
440
+ }
441
+ }
442
+
443
+ if (results.status === 'fail') {
444
+ sections.push(
445
+ '',
446
+ '\ud83d\udca1 Next Steps:',
447
+ ' \u2022 Fix the failing checks and re-run the gate',
448
+ ' \u2022 Use --skip <check> to skip specific checks if needed'
449
+ );
450
+ }
451
+
452
+ return {
453
+ content: [{
454
+ type: 'text',
455
+ text: sections.join('\n')
456
+ }]
457
+ };
458
+ }
459
+
460
+ /**
461
+ * Format context validation results
462
+ */
463
+ export function contextValidation(validation: ContextValidationResult): MCPToolResult {
464
+ const statusIcon = validation.valid ? '\u2705' : '\u26a0\ufe0f';
465
+ const sections: string[] = [
466
+ `${statusIcon} Project Validation`,
467
+ ` Valid: ${validation.valid}`,
468
+ ''
469
+ ];
470
+
471
+ if (validation.errors && validation.errors.length > 0) {
472
+ sections.push('\u274c Errors:');
473
+ validation.errors.forEach(e => sections.push(` \u2022 ${e}`));
474
+ sections.push('');
475
+ }
476
+
477
+ if (validation.warnings && validation.warnings.length > 0) {
478
+ sections.push('\u26a0\ufe0f Warnings:');
479
+ validation.warnings.forEach(w => sections.push(` \u2022 ${w}`));
480
+ sections.push('');
481
+ }
482
+
483
+ if (validation.suggestions && validation.suggestions.length > 0) {
484
+ sections.push('\ud83d\udca1 Suggestions:');
485
+ validation.suggestions.forEach(s => sections.push(` \u2022 ${s}`));
486
+ }
487
+
488
+ return {
489
+ content: [{
490
+ type: 'text',
491
+ text: sections.join('\n')
492
+ }]
493
+ };
494
+ }
495
+
496
+ /**
497
+ * Format project context summary
498
+ */
499
+ export function contextSummary(ctx: ProjectContextDisplay): MCPToolResult {
500
+ const sections: string[] = [
501
+ `\ud83d\udcc1 Project: ${ctx.project?.name ?? 'Unknown'}`,
502
+ ` Version: ${ctx.project?.version ?? 'N/A'}`,
503
+ ''
504
+ ];
505
+
506
+ if (ctx.stack) {
507
+ sections.push('\ud83d\udee0\ufe0f Tech Stack:');
508
+ if (ctx.stack.framework) sections.push(` Framework: ${ctx.stack.framework}`);
509
+ if (ctx.stack.language) sections.push(` Language: ${ctx.stack.language}`);
510
+ if (ctx.stack.database) sections.push(` Database: ${ctx.stack.database}`);
511
+ sections.push('');
512
+ }
513
+
514
+ if (ctx.plugins && Object.keys(ctx.plugins).length > 0) {
515
+ sections.push('\ud83d\udd0c Active Plugins:');
516
+ Object.keys(ctx.plugins).forEach(p => {
517
+ sections.push(` \u2022 ${p}`);
518
+ });
519
+ sections.push('');
520
+ }
521
+
522
+ sections.push(
523
+ '\ud83d\udca1 Commands:',
524
+ ' \u2022 bootspring_context action=validate - Check project health',
525
+ ' \u2022 bootspring_generate - Regenerate CLAUDE.md',
526
+ ' \u2022 bootspring_agent action=list - See available agents'
527
+ );
528
+
529
+ return {
530
+ content: [{
531
+ type: 'text',
532
+ text: sections.join('\n')
533
+ }]
534
+ };
535
+ }
536
+
537
+ /**
538
+ * Format orchestrator status
539
+ */
540
+ export function orchestratorStatus(status: OrchestratorStatus): MCPToolResult {
541
+ const sections: string[] = [
542
+ '\ud83c\udfaf Orchestrator Status',
543
+ '',
544
+ ` Phase: ${status.currentPhase ?? 'Unknown'}`,
545
+ ` Available Agents: ${status.availableAgents ?? 0}`,
546
+ ` Active Workflow: ${status.activeWorkflow ?? 'None'}`,
547
+ ''
548
+ ];
549
+
550
+ if (status.activeWorkflowSignalProgress) {
551
+ sections.push(
552
+ ` Checkpoint Signals: ${status.activeWorkflowSignalProgress.completedSignals.length}/${status.activeWorkflowSignalProgress.totalSignals}`,
553
+ ''
554
+ );
555
+ }
556
+
557
+ if (status.recentSuggestions && status.recentSuggestions.length > 0) {
558
+ sections.push('\ud83d\udca1 Recent Suggestions:');
559
+ status.recentSuggestions.forEach(s => {
560
+ const text = typeof s === 'string' ? s : s.text ?? '';
561
+ sections.push(` \u2022 ${text}`);
562
+ });
563
+ }
564
+
565
+ return {
566
+ content: [{
567
+ type: 'text',
568
+ text: sections.join('\n')
569
+ }]
570
+ };
571
+ }
572
+
573
+ /**
574
+ * Format PRD/loop status
575
+ */
576
+ export function loopStatus(prd: PRDData, progress: ProgressInfo): MCPToolResult {
577
+ const sections: string[] = [
578
+ `\ud83d\udccb PRD: ${prd.name}`,
579
+ '',
580
+ ` Progress: ${progress.completed}/${progress.total} stories (${Math.round(progress.percentage)}%)`,
581
+ ''
582
+ ];
583
+
584
+ const progressBar = generateProgressBar(progress.percentage);
585
+ sections.push(` ${progressBar}`);
586
+ sections.push('');
587
+
588
+ sections.push('\ud83d\udcd6 Stories:');
589
+ prd.stories.forEach(s => {
590
+ const icon = s.status === 'complete'
591
+ ? '\u2705'
592
+ : s.status === 'in-progress'
593
+ ? '\ud83d\udd04'
594
+ : '\u23f3';
595
+ sections.push(` ${icon} ${s.title} (${s.status})`);
596
+ });
597
+
598
+ sections.push(
599
+ '',
600
+ '\ud83d\udca1 Actions:',
601
+ ' \u2022 bootspring_loop action=next - Get next story to work on',
602
+ ' \u2022 bootspring_loop action=complete storyId=X - Mark story complete'
603
+ );
604
+
605
+ return {
606
+ content: [{
607
+ type: 'text',
608
+ text: sections.join('\n')
609
+ }]
610
+ };
611
+ }
612
+
613
+ /**
614
+ * Generate a simple progress bar
615
+ */
616
+ export function generateProgressBar(percentage: number): string {
617
+ const width = 20;
618
+ const filled = Math.round((percentage / 100) * width);
619
+ const empty = width - filled;
620
+ return '[' + '\u2588'.repeat(filled) + '\u2591'.repeat(empty) + '] ' + Math.round(percentage) + '%';
621
+ }
622
+
623
+ /**
624
+ * Format assist response (proactive suggestions)
625
+ */
626
+ export function assistResponse(response: AssistResponseData): MCPToolResult {
627
+ const sections: string[] = [];
628
+ const confidenceIcon: Record<string, string> = {
629
+ high: '\ud83c\udfaf',
630
+ medium: '\ud83d\udcad',
631
+ low: '\ud83e\udd14',
632
+ very_low: '\u2753'
633
+ };
634
+
635
+ // Header
636
+ sections.push(`${confidenceIcon[response.confidenceTier ?? 'medium'] ?? '\ud83d\udcad'} Understanding Your Request`);
637
+ sections.push('');
638
+
639
+ // What we understood
640
+ if (response.understood) {
641
+ sections.push(`**Intent**: ${response.understood.intent ?? 'Unknown'}`);
642
+ sections.push(`**Confidence**: ${((response.understood.confidence ?? 0) * 100).toFixed(0)}%`);
643
+ if (response.understood.description) {
644
+ sections.push(`**Action**: ${response.understood.description}`);
645
+ }
646
+ sections.push('');
647
+ }
648
+
649
+ // Primary suggestion
650
+ if (response.primarySuggestion) {
651
+ sections.push('### Recommended Action');
652
+ sections.push(`${response.primarySuggestion.message}`);
653
+ sections.push('');
654
+ }
655
+
656
+ // Clarification needed
657
+ if (response.clarificationNeeded) {
658
+ sections.push('### Need More Info');
659
+ sections.push(response.clarificationQuestion ?? '');
660
+ if (response.clarificationOptions && response.clarificationOptions.length > 0) {
661
+ sections.push('');
662
+ sections.push('Options:');
663
+ response.clarificationOptions.forEach(opt => {
664
+ sections.push(` \u2022 ${opt}`);
665
+ });
666
+ }
667
+ sections.push('');
668
+ }
669
+
670
+ // Other suggestions
671
+ if (response.suggestions && response.suggestions.length > 0) {
672
+ sections.push('### Other Options');
673
+ response.suggestions.forEach((s, i) => {
674
+ sections.push(`${i + 1}. ${s.message}`);
675
+ });
676
+ sections.push('');
677
+ }
678
+
679
+ // Memory insight
680
+ if (response.memoryInsight) {
681
+ sections.push('### From Experience');
682
+ sections.push(`\ud83d\udca1 ${response.memoryInsight.message}`);
683
+ sections.push(`Recommendation: **${response.memoryInsight.recommendation}**`);
684
+ sections.push('');
685
+ }
686
+
687
+ // Tool call
688
+ if (response.recommendedTool) {
689
+ sections.push('### Tool to Use');
690
+ sections.push('```json');
691
+ sections.push(JSON.stringify({
692
+ tool: response.recommendedTool.name,
693
+ args: response.recommendedTool.args
694
+ }, null, 2));
695
+ sections.push('```');
696
+ sections.push(`*${response.recommendedTool.reason}*`);
697
+ }
698
+
699
+ return {
700
+ content: [{
701
+ type: 'text',
702
+ text: sections.join('\n')
703
+ }]
704
+ };
705
+ }
706
+
707
+ /**
708
+ * Format intent detection results
709
+ */
710
+ export function intentDetection(detection: IntentDetectionData): MCPToolResult {
711
+ const sections: string[] = [
712
+ '\ud83e\udde0 Intent Analysis',
713
+ ''
714
+ ];
715
+
716
+ if (detection.intent) {
717
+ sections.push(`**Primary Intent**: ${detection.intent}`);
718
+ sections.push(`**Description**: ${detection.intentDescription ?? 'N/A'}`);
719
+ sections.push(`**Confidence**: ${((detection.intentConfidence ?? 0) * 100).toFixed(0)}%`);
720
+ sections.push('');
721
+ }
722
+
723
+ if (detection.matches && detection.matches.length > 0) {
724
+ sections.push('\ud83d\udcc2 Matched Categories:');
725
+ detection.matches.forEach(m => {
726
+ sections.push(` \u2022 ${m.category} (${m.keywordCount} keywords)`);
727
+ });
728
+ sections.push('');
729
+ }
730
+
731
+ if (detection.suggestedAgents && detection.suggestedAgents.length > 0) {
732
+ sections.push('\ud83e\udd16 Suggested Agents:');
733
+ detection.suggestedAgents.forEach(a => {
734
+ sections.push(` \u2022 ${a}`);
735
+ });
736
+ sections.push('');
737
+ }
738
+
739
+ if (detection.proactiveSuggestions && detection.proactiveSuggestions.length > 0) {
740
+ sections.push('\ud83d\udca1 Proactive Suggestions:');
741
+ detection.proactiveSuggestions.forEach(s => {
742
+ sections.push(` \u2022 ${s.message}`);
743
+ });
744
+ }
745
+
746
+ return {
747
+ content: [{
748
+ type: 'text',
749
+ text: sections.join('\n')
750
+ }]
751
+ };
752
+ }
753
+
754
+ /**
755
+ * Format capabilities list for showing what bootspring can do
756
+ */
757
+ export function capabilitiesList(_capabilities: unknown): MCPToolResult {
758
+ const sections: string[] = [
759
+ '\ud83d\ude80 What Bootspring Can Do',
760
+ '',
761
+ '**Natural Language Understanding**',
762
+ ' "Help me add authentication"',
763
+ ' "Why is my API slow?"',
764
+ ' "Deploy to production"',
765
+ '',
766
+ '**Expert Agents**',
767
+ ' \u2022 database-expert - Schema design, queries, migrations',
768
+ ' \u2022 security-expert - Auth, vulnerabilities, best practices',
769
+ ' \u2022 frontend-expert - React, components, styling',
770
+ ' \u2022 performance-expert - Optimization, caching, profiling',
771
+ ' \u2022 And more...',
772
+ '',
773
+ '**Workflows**',
774
+ ' \u2022 Feature development',
775
+ ' \u2022 Security audit',
776
+ ' \u2022 Performance optimization',
777
+ ' \u2022 Launch preparation',
778
+ '',
779
+ '**Quality Gates**',
780
+ ' \u2022 Pre-commit checks',
781
+ ' \u2022 Test validation',
782
+ ' \u2022 Security scanning',
783
+ '',
784
+ '**Skills & Patterns**',
785
+ ' \u2022 Code patterns for auth, payments, API',
786
+ ' \u2022 Best practices and examples',
787
+ '',
788
+ '\ud83d\udca1 Try: bootspring_assist message="help me with..."'
789
+ ];
790
+
791
+ return {
792
+ content: [{
793
+ type: 'text',
794
+ text: sections.join('\n')
795
+ }]
796
+ };
797
+ }