@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.
- package/bin/bootspring.js +5 -0
- package/cli/org.js +474 -0
- package/cli/preseed/index.js +16 -0
- package/cli/preseed/interactive.js +143 -0
- package/cli/preseed/templates.js +227 -0
- package/cli/preseed.js +9 -301
- package/cli/seed/builders/ai-context-builder.js +85 -0
- package/cli/seed/builders/index.js +13 -0
- package/cli/seed/builders/seed-builder.js +272 -0
- package/cli/seed/extractors/content-extractors.js +383 -0
- package/cli/seed/extractors/index.js +47 -0
- package/cli/seed/extractors/metadata-extractors.js +167 -0
- package/cli/seed/extractors/section-extractor.js +54 -0
- package/cli/seed/extractors/stack-extractors.js +228 -0
- package/cli/seed/index.js +18 -0
- package/cli/seed/utils/folder-structure.js +84 -0
- package/cli/seed/utils/index.js +11 -0
- package/cli/seed.js +23 -1074
- package/core/api-client.js +77 -0
- package/core/entitlements.js +36 -0
- package/core/organizations.js +223 -0
- package/core/policies.js +51 -6
- package/core/policy-matrix.js +303 -0
- package/core/project-context.js +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +3220 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/context-McpJQa_2.d.ts +5710 -0
- package/dist/core/index.d.ts +635 -0
- package/dist/core/index.js +2593 -0
- package/dist/core/index.js.map +1 -0
- package/dist/index-QqbeEiDm.d.ts +857 -0
- package/dist/index-UiYCgwiH.d.ts +174 -0
- package/dist/index.d.ts +453 -0
- package/dist/index.js +44228 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.js +41173 -0
- package/dist/mcp/index.js.map +1 -0
- package/generators/index.ts +82 -0
- package/intelligence/orchestrator/config/failure-signatures.js +48 -0
- package/intelligence/orchestrator/config/index.js +23 -0
- package/intelligence/orchestrator/config/pack-lifecycle.js +262 -0
- package/intelligence/orchestrator/config/phases.js +111 -0
- package/intelligence/orchestrator/config/remediation.js +150 -0
- package/intelligence/orchestrator/config/workflows.js +168 -0
- package/intelligence/orchestrator/core/index.js +16 -0
- package/intelligence/orchestrator/core/state-manager.js +88 -0
- package/intelligence/orchestrator/core/telemetry.js +24 -0
- package/intelligence/orchestrator/index.js +17 -0
- package/intelligence/orchestrator.js +17 -512
- package/mcp/contracts/mcp-contract.v1.json +1 -1
- package/package.json +16 -3
- package/src/cli/agent.ts +703 -0
- package/src/cli/analyze.ts +640 -0
- package/src/cli/audit.ts +707 -0
- package/src/cli/auth.ts +930 -0
- package/src/cli/billing.ts +364 -0
- package/src/cli/build.ts +1089 -0
- package/src/cli/business.ts +508 -0
- package/src/cli/checkpoint-utils.ts +236 -0
- package/src/cli/checkpoint.ts +757 -0
- package/src/cli/cloud-sync.ts +534 -0
- package/src/cli/content.ts +273 -0
- package/src/cli/context.ts +667 -0
- package/src/cli/dashboard.ts +133 -0
- package/src/cli/deploy.ts +704 -0
- package/src/cli/doctor.ts +480 -0
- package/src/cli/fundraise.ts +494 -0
- package/src/cli/generate.ts +346 -0
- package/src/cli/github-cmd.ts +566 -0
- package/src/cli/health.ts +599 -0
- package/src/cli/index.ts +113 -0
- package/src/cli/init.ts +838 -0
- package/src/cli/legal.ts +495 -0
- package/src/cli/log.ts +316 -0
- package/src/cli/loop.ts +1660 -0
- package/src/cli/manager.ts +878 -0
- package/src/cli/mcp.ts +275 -0
- package/src/cli/memory.ts +346 -0
- package/src/cli/metrics.ts +590 -0
- package/src/cli/monitor.ts +960 -0
- package/src/cli/mvp.ts +662 -0
- package/src/cli/onboard.ts +663 -0
- package/src/cli/orchestrator.ts +622 -0
- package/src/cli/plugin.ts +483 -0
- package/src/cli/prd.ts +671 -0
- package/src/cli/preseed-start.ts +1633 -0
- package/src/cli/preseed.ts +2434 -0
- package/src/cli/project.ts +526 -0
- package/src/cli/quality.ts +885 -0
- package/src/cli/security.ts +1079 -0
- package/src/cli/seed.ts +1224 -0
- package/src/cli/skill.ts +537 -0
- package/src/cli/suggest.ts +1225 -0
- package/src/cli/switch.ts +518 -0
- package/src/cli/task.ts +780 -0
- package/src/cli/telemetry.ts +172 -0
- package/src/cli/todo.ts +627 -0
- package/src/cli/types.ts +15 -0
- package/src/cli/update.ts +334 -0
- package/src/cli/visualize.ts +609 -0
- package/src/cli/watch.ts +895 -0
- package/src/cli/workspace.ts +709 -0
- package/src/core/action-recorder.ts +673 -0
- package/src/core/analyze-workflow.ts +1453 -0
- package/src/core/api-client.ts +1120 -0
- package/src/core/audit-workflow.ts +1681 -0
- package/src/core/auth.ts +471 -0
- package/src/core/build-orchestrator.ts +509 -0
- package/src/core/build-state.ts +621 -0
- package/src/core/checkpoint-engine.ts +482 -0
- package/src/core/config.ts +1285 -0
- package/src/core/context-loader.ts +694 -0
- package/src/core/context.ts +410 -0
- package/src/core/deploy-workflow.ts +1085 -0
- package/src/core/entitlements.ts +322 -0
- package/src/core/github-sync.ts +720 -0
- package/src/core/index.ts +981 -0
- package/src/core/ingest.ts +1186 -0
- package/src/core/metrics-engine.ts +886 -0
- package/src/core/mvp.ts +847 -0
- package/src/core/onboard-workflow.ts +1293 -0
- package/src/core/policies.ts +81 -0
- package/src/core/preseed-workflow.ts +1163 -0
- package/src/core/preseed.ts +1826 -0
- package/src/core/project-context.ts +380 -0
- package/src/core/project-state.ts +699 -0
- package/src/core/r2-sync.ts +691 -0
- package/src/core/scaffold.ts +1715 -0
- package/src/core/session.ts +286 -0
- package/src/core/task-extractor.ts +799 -0
- package/src/core/telemetry.ts +371 -0
- package/src/core/tier-enforcement.ts +737 -0
- package/src/core/utils.ts +437 -0
- package/src/index.ts +29 -0
- package/src/intelligence/agent-collab.ts +2376 -0
- package/src/intelligence/auto-suggest.ts +713 -0
- package/src/intelligence/content-gen.ts +1351 -0
- package/src/intelligence/cross-project.ts +1692 -0
- package/src/intelligence/git-memory.ts +529 -0
- package/src/intelligence/index.ts +318 -0
- package/src/intelligence/orchestrator.ts +534 -0
- package/src/intelligence/prd.ts +466 -0
- package/src/intelligence/recommendations.ts +982 -0
- package/src/intelligence/workflow-composer.ts +1472 -0
- package/src/mcp/capabilities.ts +233 -0
- package/src/mcp/index.ts +37 -0
- package/src/mcp/registry.ts +1268 -0
- package/src/mcp/response-formatter.ts +797 -0
- package/src/mcp/server.ts +240 -0
- package/src/types/agent.ts +69 -0
- package/src/types/config.ts +86 -0
- package/src/types/context.ts +77 -0
- package/src/types/index.ts +53 -0
- package/src/types/mcp.ts +91 -0
- package/src/types/skills.ts +47 -0
- package/src/types/workflow.ts +155 -0
- 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
|
+
}
|