@vfarcic/dot-ai 0.175.0 → 0.176.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/interfaces/rest-api.d.ts +37 -0
- package/dist/interfaces/rest-api.d.ts.map +1 -1
- package/dist/interfaces/rest-api.js +191 -0
- package/dist/tools/query.d.ts +13 -0
- package/dist/tools/query.d.ts.map +1 -1
- package/dist/tools/query.js +33 -1
- package/package.json +1 -1
- package/prompts/visualize-query.md +113 -0
- package/shared-prompts/prd-create.md +1 -3
- package/shared-prompts/prd-next.md +6 -6
- package/shared-prompts/prd-start.md +38 -110
- package/shared-prompts/prd-update-progress.md +2 -4
|
@@ -57,6 +57,38 @@ export interface ToolDiscoveryResponse extends RestApiResponse {
|
|
|
57
57
|
tags?: string[];
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Visualization types supported by the API
|
|
62
|
+
*/
|
|
63
|
+
export type VisualizationType = 'mermaid' | 'cards' | 'code' | 'table';
|
|
64
|
+
/**
|
|
65
|
+
* Individual visualization item
|
|
66
|
+
*/
|
|
67
|
+
export interface Visualization {
|
|
68
|
+
id: string;
|
|
69
|
+
label: string;
|
|
70
|
+
type: VisualizationType;
|
|
71
|
+
content: string | {
|
|
72
|
+
language: string;
|
|
73
|
+
code: string;
|
|
74
|
+
} | {
|
|
75
|
+
headers: string[];
|
|
76
|
+
rows: string[][];
|
|
77
|
+
} | Array<{
|
|
78
|
+
id: string;
|
|
79
|
+
title: string;
|
|
80
|
+
description?: string;
|
|
81
|
+
tags?: string[];
|
|
82
|
+
}>;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Visualization endpoint response format
|
|
86
|
+
*/
|
|
87
|
+
export interface VisualizationResponse {
|
|
88
|
+
title: string;
|
|
89
|
+
visualizations: Visualization[];
|
|
90
|
+
insights: string[];
|
|
91
|
+
}
|
|
60
92
|
/**
|
|
61
93
|
* REST API router configuration
|
|
62
94
|
*/
|
|
@@ -109,6 +141,11 @@ export declare class RestApiRouter {
|
|
|
109
141
|
* Handle prompt get requests
|
|
110
142
|
*/
|
|
111
143
|
private handlePromptsGetRequest;
|
|
144
|
+
/**
|
|
145
|
+
* Handle visualization requests (PRD #317)
|
|
146
|
+
* Returns structured visualization data for a query session
|
|
147
|
+
*/
|
|
148
|
+
private handleVisualize;
|
|
112
149
|
/**
|
|
113
150
|
* Set CORS headers
|
|
114
151
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rest-api.d.ts","sourceRoot":"","sources":["../../src/interfaces/rest-api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE5D,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE7D,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"rest-api.d.ts","sourceRoot":"","sources":["../../src/interfaces/rest-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,12 @@ const node_url_1 = require("node:url");
|
|
|
11
11
|
const openapi_generator_1 = require("./openapi-generator");
|
|
12
12
|
const resource_sync_handler_1 = require("./resource-sync-handler");
|
|
13
13
|
const prompts_1 = require("../tools/prompts");
|
|
14
|
+
const generic_session_manager_1 = require("../core/generic-session-manager");
|
|
15
|
+
const shared_prompt_loader_1 = require("../core/shared-prompt-loader");
|
|
16
|
+
const ai_provider_factory_1 = require("../core/ai-provider-factory");
|
|
17
|
+
const capability_tools_1 = require("../core/capability-tools");
|
|
18
|
+
const resource_tools_1 = require("../core/resource-tools");
|
|
19
|
+
const kubectl_tools_1 = require("../core/kubectl-tools");
|
|
14
20
|
/**
|
|
15
21
|
* HTTP status codes for REST responses
|
|
16
22
|
*/
|
|
@@ -138,6 +144,17 @@ class RestApiRouter {
|
|
|
138
144
|
await this.sendErrorResponse(res, requestId, HttpStatus.BAD_REQUEST, 'BAD_REQUEST', 'Prompt name is required');
|
|
139
145
|
}
|
|
140
146
|
break;
|
|
147
|
+
case 'visualize':
|
|
148
|
+
if (req.method === 'GET' && pathMatch.sessionId) {
|
|
149
|
+
await this.handleVisualize(req, res, requestId, pathMatch.sessionId);
|
|
150
|
+
}
|
|
151
|
+
else if (req.method !== 'GET') {
|
|
152
|
+
await this.sendErrorResponse(res, requestId, HttpStatus.METHOD_NOT_ALLOWED, 'METHOD_NOT_ALLOWED', 'Only GET method allowed for visualization');
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
await this.sendErrorResponse(res, requestId, HttpStatus.BAD_REQUEST, 'BAD_REQUEST', 'Session ID is required');
|
|
156
|
+
}
|
|
157
|
+
break;
|
|
141
158
|
default:
|
|
142
159
|
await this.sendErrorResponse(res, requestId, HttpStatus.NOT_FOUND, 'NOT_FOUND', 'Unknown API endpoint');
|
|
143
160
|
}
|
|
@@ -194,6 +211,13 @@ class RestApiRouter {
|
|
|
194
211
|
return { endpoint: 'prompt', promptName };
|
|
195
212
|
}
|
|
196
213
|
}
|
|
214
|
+
// Handle visualize endpoint (PRD #317)
|
|
215
|
+
if (cleanPath.startsWith('visualize/')) {
|
|
216
|
+
const sessionId = cleanPath.substring(10); // Remove 'visualize/'
|
|
217
|
+
if (sessionId) {
|
|
218
|
+
return { endpoint: 'visualize', sessionId };
|
|
219
|
+
}
|
|
220
|
+
}
|
|
197
221
|
return null;
|
|
198
222
|
}
|
|
199
223
|
/**
|
|
@@ -442,6 +466,173 @@ class RestApiRouter {
|
|
|
442
466
|
await this.sendErrorResponse(res, requestId, isValidationError ? HttpStatus.BAD_REQUEST : HttpStatus.INTERNAL_SERVER_ERROR, isValidationError ? 'VALIDATION_ERROR' : 'PROMPT_GET_ERROR', errorMessage);
|
|
443
467
|
}
|
|
444
468
|
}
|
|
469
|
+
/**
|
|
470
|
+
* Handle visualization requests (PRD #317)
|
|
471
|
+
* Returns structured visualization data for a query session
|
|
472
|
+
*/
|
|
473
|
+
async handleVisualize(req, res, requestId, sessionId) {
|
|
474
|
+
try {
|
|
475
|
+
this.logger.info('Processing visualization request', { requestId, sessionId });
|
|
476
|
+
// Load session data using GenericSessionManager with 'qry' prefix (matches query tool)
|
|
477
|
+
const sessionManager = new generic_session_manager_1.GenericSessionManager('qry');
|
|
478
|
+
const session = sessionManager.getSession(sessionId);
|
|
479
|
+
if (!session) {
|
|
480
|
+
await this.sendErrorResponse(res, requestId, HttpStatus.NOT_FOUND, 'SESSION_NOT_FOUND', `Session '${sessionId}' not found or has expired`);
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
// Generate AI-powered visualization (PRD #317 Milestone 4)
|
|
484
|
+
const aiProvider = (0, ai_provider_factory_1.createAIProvider)();
|
|
485
|
+
if (!aiProvider.isInitialized()) {
|
|
486
|
+
await this.sendErrorResponse(res, requestId, HttpStatus.SERVICE_UNAVAILABLE, 'AI_NOT_CONFIGURED', 'AI provider is not configured. Set ANTHROPIC_API_KEY or other AI provider credentials.');
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
// Load system prompt with session context
|
|
490
|
+
const systemPrompt = (0, shared_prompt_loader_1.loadPrompt)('visualize-query', {
|
|
491
|
+
intent: session.data.intent,
|
|
492
|
+
toolCallsData: JSON.stringify(session.data.toolCallsExecuted, null, 2)
|
|
493
|
+
});
|
|
494
|
+
// Tool executor - same as query tool
|
|
495
|
+
const executeVisualizationTools = async (toolName, input) => {
|
|
496
|
+
if (toolName.startsWith('search_capabilities') || toolName.startsWith('query_capabilities')) {
|
|
497
|
+
return (0, capability_tools_1.executeCapabilityTools)(toolName, input);
|
|
498
|
+
}
|
|
499
|
+
if (toolName.startsWith('search_resources') || toolName.startsWith('query_resources')) {
|
|
500
|
+
return (0, resource_tools_1.executeResourceTools)(toolName, input);
|
|
501
|
+
}
|
|
502
|
+
if (toolName.startsWith('kubectl_')) {
|
|
503
|
+
return (0, kubectl_tools_1.executeKubectlTools)(toolName, input);
|
|
504
|
+
}
|
|
505
|
+
return {
|
|
506
|
+
success: false,
|
|
507
|
+
error: `Unknown tool: ${toolName}`,
|
|
508
|
+
message: `Tool '${toolName}' is not implemented in visualization`
|
|
509
|
+
};
|
|
510
|
+
};
|
|
511
|
+
// Read-only kubectl tools for gathering additional data
|
|
512
|
+
const KUBECTL_READONLY_TOOLS = [
|
|
513
|
+
kubectl_tools_1.KUBECTL_API_RESOURCES_TOOL,
|
|
514
|
+
kubectl_tools_1.KUBECTL_GET_TOOL,
|
|
515
|
+
kubectl_tools_1.KUBECTL_DESCRIBE_TOOL,
|
|
516
|
+
kubectl_tools_1.KUBECTL_LOGS_TOOL,
|
|
517
|
+
kubectl_tools_1.KUBECTL_EVENTS_TOOL,
|
|
518
|
+
kubectl_tools_1.KUBECTL_GET_CRD_SCHEMA_TOOL
|
|
519
|
+
];
|
|
520
|
+
this.logger.info('Starting AI visualization generation with tools', { requestId, sessionId });
|
|
521
|
+
// Execute tool loop - AI can gather additional data if needed
|
|
522
|
+
const result = await aiProvider.toolLoop({
|
|
523
|
+
systemPrompt,
|
|
524
|
+
userMessage: 'Generate visualizations based on the query results provided. Use tools if you need additional information about any resources.',
|
|
525
|
+
tools: [...capability_tools_1.CAPABILITY_TOOLS, ...resource_tools_1.RESOURCE_TOOLS, ...KUBECTL_READONLY_TOOLS],
|
|
526
|
+
toolExecutor: executeVisualizationTools,
|
|
527
|
+
maxIterations: 5, // Limit iterations for visualization
|
|
528
|
+
operation: 'visualize-query'
|
|
529
|
+
});
|
|
530
|
+
this.logger.info('AI visualization generation completed', {
|
|
531
|
+
requestId,
|
|
532
|
+
sessionId,
|
|
533
|
+
iterations: result.iterations,
|
|
534
|
+
toolsUsed: [...new Set(result.toolCallsExecuted.map(tc => tc.tool))]
|
|
535
|
+
});
|
|
536
|
+
// Parse AI response as JSON
|
|
537
|
+
let visualizationResponse;
|
|
538
|
+
try {
|
|
539
|
+
// Extract JSON from response - it may have text before/after the JSON block
|
|
540
|
+
let jsonContent = result.finalMessage.trim();
|
|
541
|
+
// Find JSON block in markdown code fence
|
|
542
|
+
const jsonBlockMatch = jsonContent.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
543
|
+
if (jsonBlockMatch) {
|
|
544
|
+
jsonContent = jsonBlockMatch[1].trim();
|
|
545
|
+
}
|
|
546
|
+
else if (!jsonContent.startsWith('{')) {
|
|
547
|
+
// Try to find raw JSON object if no code fence
|
|
548
|
+
const jsonStart = jsonContent.indexOf('{');
|
|
549
|
+
const jsonEnd = jsonContent.lastIndexOf('}');
|
|
550
|
+
if (jsonStart !== -1 && jsonEnd !== -1) {
|
|
551
|
+
jsonContent = jsonContent.substring(jsonStart, jsonEnd + 1);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
const parsed = JSON.parse(jsonContent);
|
|
555
|
+
// Validate required fields
|
|
556
|
+
if (!parsed.title || !Array.isArray(parsed.visualizations) || !Array.isArray(parsed.insights)) {
|
|
557
|
+
throw new Error('Invalid visualization response structure');
|
|
558
|
+
}
|
|
559
|
+
// Validate each visualization has required fields
|
|
560
|
+
for (const viz of parsed.visualizations) {
|
|
561
|
+
if (!viz.id || !viz.label || !viz.type || viz.content === undefined) {
|
|
562
|
+
throw new Error(`Invalid visualization: missing required fields in ${JSON.stringify(viz)}`);
|
|
563
|
+
}
|
|
564
|
+
if (!['mermaid', 'cards', 'code', 'table'].includes(viz.type)) {
|
|
565
|
+
throw new Error(`Invalid visualization type: ${viz.type}`);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
// Normalize insights to strings if they are objects
|
|
569
|
+
const normalizedInsights = parsed.insights.map((insight) => {
|
|
570
|
+
if (typeof insight === 'string') {
|
|
571
|
+
return insight;
|
|
572
|
+
}
|
|
573
|
+
// Convert object insights to string format
|
|
574
|
+
if (insight.title && insight.description) {
|
|
575
|
+
const severity = insight.severity ? ` [${insight.severity}]` : '';
|
|
576
|
+
return `${insight.title}${severity}: ${insight.description}`;
|
|
577
|
+
}
|
|
578
|
+
return String(insight);
|
|
579
|
+
});
|
|
580
|
+
visualizationResponse = {
|
|
581
|
+
...parsed,
|
|
582
|
+
insights: normalizedInsights
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
catch (parseError) {
|
|
586
|
+
this.logger.error('Failed to parse AI visualization response', parseError instanceof Error ? parseError : new Error(String(parseError)), {
|
|
587
|
+
requestId,
|
|
588
|
+
sessionId,
|
|
589
|
+
rawResponse: result.finalMessage.substring(0, 500)
|
|
590
|
+
});
|
|
591
|
+
// Fallback to basic visualization on parse error
|
|
592
|
+
visualizationResponse = {
|
|
593
|
+
title: `Query: ${session.data.intent}`,
|
|
594
|
+
visualizations: [
|
|
595
|
+
{
|
|
596
|
+
id: 'raw-data',
|
|
597
|
+
label: 'Query Results',
|
|
598
|
+
type: 'code',
|
|
599
|
+
content: {
|
|
600
|
+
language: 'json',
|
|
601
|
+
code: JSON.stringify(session.data.toolCallsExecuted, null, 2)
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
],
|
|
605
|
+
insights: [
|
|
606
|
+
'AI visualization generation failed - showing raw query results',
|
|
607
|
+
`Query executed in ${session.data.iterations} iteration(s)`
|
|
608
|
+
]
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
const response = {
|
|
612
|
+
success: true,
|
|
613
|
+
data: visualizationResponse,
|
|
614
|
+
meta: {
|
|
615
|
+
timestamp: new Date().toISOString(),
|
|
616
|
+
requestId,
|
|
617
|
+
version: this.config.version
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
await this.sendJsonResponse(res, HttpStatus.OK, response);
|
|
621
|
+
this.logger.info('Visualization request completed', {
|
|
622
|
+
requestId,
|
|
623
|
+
sessionId,
|
|
624
|
+
visualizationCount: visualizationResponse.visualizations.length
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
catch (error) {
|
|
628
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
629
|
+
this.logger.error('Visualization request failed', error instanceof Error ? error : new Error(String(error)), {
|
|
630
|
+
requestId,
|
|
631
|
+
sessionId
|
|
632
|
+
});
|
|
633
|
+
await this.sendErrorResponse(res, requestId, HttpStatus.INTERNAL_SERVER_ERROR, 'VISUALIZATION_ERROR', 'Failed to generate visualization', { error: errorMessage });
|
|
634
|
+
}
|
|
635
|
+
}
|
|
445
636
|
/**
|
|
446
637
|
* Set CORS headers
|
|
447
638
|
*/
|
package/dist/tools/query.d.ts
CHANGED
|
@@ -17,11 +17,24 @@ export interface QueryInput {
|
|
|
17
17
|
intent: string;
|
|
18
18
|
interaction_id?: string;
|
|
19
19
|
}
|
|
20
|
+
export interface QuerySessionData {
|
|
21
|
+
intent: string;
|
|
22
|
+
summary: string;
|
|
23
|
+
toolsUsed: string[];
|
|
24
|
+
iterations: number;
|
|
25
|
+
toolCallsExecuted: Array<{
|
|
26
|
+
tool: string;
|
|
27
|
+
input: any;
|
|
28
|
+
output: any;
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
20
31
|
export interface QueryOutput {
|
|
21
32
|
success: boolean;
|
|
22
33
|
summary: string;
|
|
23
34
|
toolsUsed: string[];
|
|
24
35
|
iterations: number;
|
|
36
|
+
sessionId?: string;
|
|
37
|
+
visualizationUrl?: string;
|
|
25
38
|
error?: {
|
|
26
39
|
code: string;
|
|
27
40
|
message: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/tools/query.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/tools/query.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmBxB,eAAO,MAAM,eAAe,UAAU,CAAC;AACvC,eAAO,MAAM,sBAAsB,iWAAuV,CAAC;AAG3X,eAAO,MAAM,uBAAuB;;;CAGnC,CAAC;AAGF,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAGD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,KAAK,CAAC;QACvB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,GAAG,CAAC;QACX,MAAM,EAAE,GAAG,CAAC;KACb,CAAC,CAAC;CACJ;AAGD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AA8ED;;GAEG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAsI7D"}
|
package/dist/tools/query.js
CHANGED
|
@@ -49,6 +49,7 @@ const ai_provider_factory_1 = require("../core/ai-provider-factory");
|
|
|
49
49
|
const capability_tools_1 = require("../core/capability-tools");
|
|
50
50
|
const resource_tools_1 = require("../core/resource-tools");
|
|
51
51
|
const kubectl_tools_1 = require("../core/kubectl-tools");
|
|
52
|
+
const generic_session_manager_1 = require("../core/generic-session-manager");
|
|
52
53
|
const fs = __importStar(require("fs"));
|
|
53
54
|
const path = __importStar(require("path"));
|
|
54
55
|
// Tool metadata for MCP registration
|
|
@@ -59,6 +60,19 @@ exports.QUERY_TOOL_INPUT_SCHEMA = {
|
|
|
59
60
|
intent: zod_1.z.string().min(1).max(1000).describe('Natural language query about the cluster'),
|
|
60
61
|
interaction_id: zod_1.z.string().optional().describe('INTERNAL ONLY - Do not populate. Used for evaluation dataset generation.')
|
|
61
62
|
};
|
|
63
|
+
/**
|
|
64
|
+
* Get visualization URL if WEB_UI_BASE_URL is configured
|
|
65
|
+
* PRD #317: Feature toggle - only include URL when env var is set
|
|
66
|
+
*/
|
|
67
|
+
function getVisualizationUrl(sessionId) {
|
|
68
|
+
const baseUrl = process.env.WEB_UI_BASE_URL;
|
|
69
|
+
if (!baseUrl) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
// Remove trailing slash if present, then append /v/{sessionId}
|
|
73
|
+
const normalizedBaseUrl = baseUrl.replace(/\/$/, '');
|
|
74
|
+
return `${normalizedBaseUrl}/v/${sessionId}`;
|
|
75
|
+
}
|
|
62
76
|
/**
|
|
63
77
|
* Parse the AI's final JSON response for summary only
|
|
64
78
|
*/
|
|
@@ -179,11 +193,29 @@ async function handleQueryTool(args) {
|
|
|
179
193
|
iterations: result.iterations,
|
|
180
194
|
toolsUsed
|
|
181
195
|
});
|
|
196
|
+
// Store session for visualization (PRD #317)
|
|
197
|
+
const sessionManager = new generic_session_manager_1.GenericSessionManager('qry');
|
|
198
|
+
const session = sessionManager.createSession({
|
|
199
|
+
intent,
|
|
200
|
+
summary,
|
|
201
|
+
toolsUsed,
|
|
202
|
+
iterations: result.iterations,
|
|
203
|
+
toolCallsExecuted: result.toolCallsExecuted
|
|
204
|
+
});
|
|
205
|
+
// PRD #317: Include visualization URL when WEB_UI_BASE_URL is configured
|
|
206
|
+
const visualizationUrl = getVisualizationUrl(session.sessionId);
|
|
207
|
+
logger.info('Session created for visualization', {
|
|
208
|
+
requestId,
|
|
209
|
+
sessionId: session.sessionId,
|
|
210
|
+
...(visualizationUrl && { visualizationUrl })
|
|
211
|
+
});
|
|
182
212
|
const output = {
|
|
183
213
|
success: true,
|
|
184
214
|
summary,
|
|
185
215
|
toolsUsed,
|
|
186
|
-
iterations: result.iterations
|
|
216
|
+
iterations: result.iterations,
|
|
217
|
+
sessionId: session.sessionId,
|
|
218
|
+
...(visualizationUrl && { visualizationUrl })
|
|
187
219
|
};
|
|
188
220
|
return {
|
|
189
221
|
content: [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vfarcic/dot-ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.176.0",
|
|
4
4
|
"description": "AI-powered development productivity platform that enhances software development workflows through intelligent automation and AI-driven assistance",
|
|
5
5
|
"mcpName": "io.github.vfarcic/dot-ai",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Query Visualization Generator
|
|
2
|
+
|
|
3
|
+
You are a Kubernetes cluster visualization expert. Analyze the query results and generate visualizations that reveal relationships and patterns in the data.
|
|
4
|
+
|
|
5
|
+
## User Query
|
|
6
|
+
|
|
7
|
+
{{{intent}}}
|
|
8
|
+
|
|
9
|
+
## Query Results
|
|
10
|
+
|
|
11
|
+
{{{toolCallsData}}}
|
|
12
|
+
|
|
13
|
+
## Your Task
|
|
14
|
+
|
|
15
|
+
Thoroughly analyze the query results and surface everything valuable you can find. This includes but is not limited to:
|
|
16
|
+
- Relationships between resources
|
|
17
|
+
- Resource status and health
|
|
18
|
+
- Patterns and architectural insights
|
|
19
|
+
- Anything else worth knowing about these resources
|
|
20
|
+
|
|
21
|
+
If the provided data isn't sufficient for deep analysis, use the available tools to gather additional information. Don't limit yourself to what's already in the context - investigate further if it would produce more valuable insights.
|
|
22
|
+
|
|
23
|
+
## Analysis Approach
|
|
24
|
+
|
|
25
|
+
Include both obvious and non-obvious findings:
|
|
26
|
+
|
|
27
|
+
### Level 1: Obvious Relationships (include these)
|
|
28
|
+
- `metadata.ownerReferences` links
|
|
29
|
+
- Label selectors matching labels
|
|
30
|
+
- Explicit name references in spec fields
|
|
31
|
+
|
|
32
|
+
### Level 2: Deep Analysis (this is where you add unique value)
|
|
33
|
+
Go beyond the obvious. Analyze the data thoroughly. Here are some examples - but don't limit yourself to these:
|
|
34
|
+
|
|
35
|
+
- Inferred dependencies from env vars, config names, port numbers, mount paths
|
|
36
|
+
- Architectural patterns like sidecars, init containers, deployment strategies
|
|
37
|
+
- Potential issues: missing limits, no health checks, security concerns, single points of failure
|
|
38
|
+
- Implicit relationships from naming patterns, shared labels, operator conventions
|
|
39
|
+
- Capacity and scaling considerations
|
|
40
|
+
|
|
41
|
+
These are just examples. Analyze EVERYTHING in the data - annotations, labels, all spec fields, status conditions, anything. Surface whatever is valuable. The non-obvious insights are what make this worthwhile.
|
|
42
|
+
|
|
43
|
+
Do NOT assume what resources exist. Analyze only what's in the data.
|
|
44
|
+
|
|
45
|
+
## Output Format
|
|
46
|
+
|
|
47
|
+
Respond with ONLY a JSON object (no markdown code fences, no extra text):
|
|
48
|
+
|
|
49
|
+
{
|
|
50
|
+
"title": "Descriptive title based on what was found",
|
|
51
|
+
"visualizations": [...],
|
|
52
|
+
"insights": [...]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
## Visualization Types
|
|
56
|
+
|
|
57
|
+
Generate as many or as few visualizations as add value. You can:
|
|
58
|
+
- Include multiple visualizations of the same type (e.g., several mermaid diagrams for different aspects)
|
|
59
|
+
- Skip any type entirely if it doesn't add value for this data
|
|
60
|
+
- Use whatever combination best represents what you found
|
|
61
|
+
|
|
62
|
+
Each visualization:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
{
|
|
66
|
+
"id": "unique-id",
|
|
67
|
+
"label": "Tab Label",
|
|
68
|
+
"type": "mermaid" | "table" | "cards" | "code",
|
|
69
|
+
"content": <type-specific-content>
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### mermaid
|
|
74
|
+
For showing relationships between resources.
|
|
75
|
+
- `content`: Valid Mermaid diagram string
|
|
76
|
+
- Use `graph TD` or `graph LR` depending on relationship type
|
|
77
|
+
- Use subgraphs to group by namespace or logical grouping
|
|
78
|
+
- Arrows: `-->` for ownership/direct, `-.->` for inferred/indirect
|
|
79
|
+
- Keep readable - summarize similar resources rather than showing every instance
|
|
80
|
+
|
|
81
|
+
### table
|
|
82
|
+
For listing resources with their properties.
|
|
83
|
+
- `content`: `{ "headers": ["Col1", "Col2"], "rows": [["val1", "val2"]] }`
|
|
84
|
+
- Choose columns relevant to the resource types present
|
|
85
|
+
- Include status/condition information when available
|
|
86
|
+
|
|
87
|
+
### cards
|
|
88
|
+
For highlighting individual resources with status.
|
|
89
|
+
- `content`: `[{ "id": "unique", "title": "Name", "description": "Status info", "tags": ["tag1"] }]`
|
|
90
|
+
- Use for resources where individual status matters
|
|
91
|
+
- Tags should reflect actual state from the data
|
|
92
|
+
|
|
93
|
+
### code
|
|
94
|
+
For showing raw data or configurations.
|
|
95
|
+
- `content`: `{ "language": "yaml" | "json", "code": "..." }`
|
|
96
|
+
- Use sparingly - only when raw output adds value
|
|
97
|
+
|
|
98
|
+
## Insights
|
|
99
|
+
|
|
100
|
+
Generate insights that add value beyond what someone could see by just reading the raw data. Prioritize non-obvious findings over summaries of what's there.
|
|
101
|
+
|
|
102
|
+
Each insight should:
|
|
103
|
+
- Reference specific resource names from the data
|
|
104
|
+
- Explain WHY it matters, not just WHAT you found
|
|
105
|
+
- Be actionable when highlighting issues
|
|
106
|
+
|
|
107
|
+
## Rules
|
|
108
|
+
|
|
109
|
+
1. **Data-driven only** - Generate visualizations based on actual resources present
|
|
110
|
+
2. **Skip empty visualizations** - Don't include a topology diagram if there are no relationships
|
|
111
|
+
3. **Valid output** - Ensure Mermaid syntax is correct and JSON is valid
|
|
112
|
+
4. **Resource-agnostic** - Handle any Kubernetes resource type (core, CRDs, operators)
|
|
113
|
+
5. **JSON only** - No markdown fences, no explanations outside the JSON structure
|
|
@@ -164,9 +164,7 @@ If user chooses option 1, first commit and push the PRD (same as Option 2), then
|
|
|
164
164
|
|
|
165
165
|
**PRD committed and pushed.**
|
|
166
166
|
|
|
167
|
-
To start working on this PRD, run
|
|
168
|
-
|
|
169
|
-
*Note: Different agents/clients may have different syntax for executing commands and prompts (e.g., `/prd-start [issue-id]` in Claude Code, or other syntax in different MCP clients). Start a new conversation/context to run the prompt.*
|
|
167
|
+
To start working on this PRD, run `/prd-start [issue-id]`
|
|
170
168
|
|
|
171
169
|
---
|
|
172
170
|
|
|
@@ -28,7 +28,7 @@ You are helping analyze an existing Product Requirements Document (PRD) to sugge
|
|
|
28
28
|
**Skip detection/analysis if recent conversation shows:**
|
|
29
29
|
- **Recent PRD work discussed** - "We just worked on PRD 29", "Just completed PRD update", etc.
|
|
30
30
|
- **Specific PRD mentioned** - "PRD #X", "MCP Prompts PRD", etc.
|
|
31
|
-
- **PRD-specific commands used** - Recent use of
|
|
31
|
+
- **PRD-specific commands used** - Recent use of `/prd-update-progress`, `/prd-start` with specific PRD
|
|
32
32
|
- **Clear work context** - Discussion of specific features, tasks, or requirements for a known PRD
|
|
33
33
|
|
|
34
34
|
**If context is clear:**
|
|
@@ -248,16 +248,16 @@ This command should:
|
|
|
248
248
|
|
|
249
249
|
## Step 8: Update Progress After Completion
|
|
250
250
|
|
|
251
|
-
|
|
251
|
+
**CRITICAL: Do NOT update the PRD yourself. Do NOT edit PRD files directly. Your job is to prompt the user to run the update command.**
|
|
252
|
+
|
|
253
|
+
After the user completes the task implementation, output ONLY this message:
|
|
252
254
|
|
|
253
255
|
---
|
|
254
256
|
|
|
255
257
|
**Task implementation complete.**
|
|
256
258
|
|
|
257
|
-
To update PRD progress and commit your work, run
|
|
258
|
-
|
|
259
|
-
*Note: Different agents/clients may have different syntax for executing commands and prompts (e.g., `/prd-update-progress` in Claude Code, or other syntax in different MCP clients).*
|
|
259
|
+
To update PRD progress and commit your work, run `/prd-update-progress`.
|
|
260
260
|
|
|
261
261
|
---
|
|
262
262
|
|
|
263
|
-
|
|
263
|
+
Then STOP. Do not proceed further. The `/prd-update-progress` command handles PRD updates, progress tracking, and commits. This separation ensures proper workflow and avoids duplicate/conflicting updates.
|
|
@@ -12,22 +12,21 @@ arguments:
|
|
|
12
12
|
|
|
13
13
|
## Instructions
|
|
14
14
|
|
|
15
|
-
You are helping initiate active implementation work on a specific Product Requirements Document (PRD). This command
|
|
15
|
+
You are helping initiate active implementation work on a specific Product Requirements Document (PRD). This command sets up the implementation context (validates readiness, creates branch, prepares environment) then hands off to `/prd-next` for task identification.
|
|
16
16
|
|
|
17
|
-
**IMPORTANT**: Do NOT include time estimates or effort estimates in your responses. Focus on
|
|
17
|
+
**IMPORTANT**: Do NOT include time estimates or effort estimates in your responses. Focus on setup and readiness without speculating on duration.
|
|
18
18
|
|
|
19
19
|
## Process Overview
|
|
20
20
|
|
|
21
|
-
1. **Select Target PRD** -
|
|
22
|
-
2. **Validate PRD Readiness** - Ensure the
|
|
23
|
-
3. **Set Up Implementation Context** -
|
|
24
|
-
4. **
|
|
25
|
-
5. **Begin Implementation** - Launch into actual development work
|
|
21
|
+
1. **Select Target PRD** - Identify which PRD to implement
|
|
22
|
+
2. **Validate PRD Readiness** - Ensure the PRD is ready for implementation
|
|
23
|
+
3. **Set Up Implementation Context** - Create branch and prepare environment
|
|
24
|
+
4. **Hand Off to prd-next** - Delegate task identification to the appropriate prompt
|
|
26
25
|
|
|
27
26
|
## Step 0: Check for PRD Argument
|
|
28
27
|
|
|
29
28
|
**If `prdNumber` argument is provided ({{prdNumber}}):**
|
|
30
|
-
- Skip
|
|
29
|
+
- Skip context check and auto-detection
|
|
31
30
|
- Use PRD #{{prdNumber}} directly
|
|
32
31
|
- Proceed to Step 2 (PRD Readiness Validation)
|
|
33
32
|
|
|
@@ -38,19 +37,17 @@ You are helping initiate active implementation work on a specific Product Requir
|
|
|
38
37
|
|
|
39
38
|
**Check if PRD context is already clear from recent conversation:**
|
|
40
39
|
|
|
41
|
-
**Skip detection
|
|
40
|
+
**Skip detection if recent conversation shows:**
|
|
42
41
|
- **Recent PRD work discussed** - "We just worked on PRD 29", "Just completed PRD update", etc.
|
|
43
42
|
- **Specific PRD mentioned** - "PRD #X", "MCP Prompts PRD", etc.
|
|
44
|
-
- **PRD-specific commands used** - Recent use of
|
|
43
|
+
- **PRD-specific commands used** - Recent use of `/prd-update-progress`, `/prd-start` with specific PRD
|
|
45
44
|
- **Clear work context** - Discussion of specific features, tasks, or requirements for a known PRD
|
|
46
45
|
|
|
47
46
|
**If context is clear:**
|
|
48
47
|
- Skip to Step 2 (PRD Readiness Validation) using the known PRD
|
|
49
|
-
- Use conversation history to understand current state and recent progress
|
|
50
|
-
- Proceed directly with readiness validation based on known PRD status
|
|
51
48
|
|
|
52
49
|
**If context is unclear:**
|
|
53
|
-
- Continue to Step 1 (PRD Detection)
|
|
50
|
+
- Continue to Step 1 (PRD Detection)
|
|
54
51
|
|
|
55
52
|
## Step 1: Smart PRD Detection (Only if Context Unclear)
|
|
56
53
|
|
|
@@ -69,35 +66,16 @@ You are helping initiate active implementation work on a specific Product Requir
|
|
|
69
66
|
- Modified `prds/12-*.md` → PRD 12
|
|
70
67
|
- Changes in feature-specific directories
|
|
71
68
|
|
|
72
|
-
4. **Available PRDs Discovery** - List all PRDs in `prds/` directory
|
|
73
|
-
- `prds/12-documentation-testing.md`
|
|
74
|
-
- `prds/13-cicd-documentation-testing.md`
|
|
69
|
+
4. **Available PRDs Discovery** - List all PRDs in `prds/` directory
|
|
75
70
|
|
|
76
71
|
5. **Fallback to User Choice** - Only if context detection fails, ask user to specify
|
|
77
72
|
|
|
78
|
-
**PRD Detection Implementation:**
|
|
79
|
-
```bash
|
|
80
|
-
# Use these tools to gather context:
|
|
81
|
-
# 1. Check git branch: gitStatus shows current branch
|
|
82
|
-
# 2. Check git status: Look for modified PRD files
|
|
83
|
-
# 3. List PRDs: Use LS or Glob to find prds/*.md files
|
|
84
|
-
# 4. Recent commits: Use Bash 'git log --oneline -n 5' for recent context
|
|
85
|
-
```
|
|
86
|
-
|
|
87
73
|
**Detection Logic:**
|
|
88
74
|
- **High Confidence**: Branch name matches PRD pattern (e.g., `feature/prd-12-documentation-testing`)
|
|
89
75
|
- **Medium Confidence**: Modified PRD files in git status or recent commits mention PRD
|
|
90
76
|
- **Low Confidence**: Multiple PRDs available, use heuristics (most recent, largest)
|
|
91
77
|
- **No Context**: Present available options to user
|
|
92
78
|
|
|
93
|
-
**Example Detection Outputs:**
|
|
94
|
-
```markdown
|
|
95
|
-
🎯 **Auto-detected PRD 12** (Documentation Testing)
|
|
96
|
-
- Branch: `feature/prd-12-documentation-testing` ✅
|
|
97
|
-
- Modified files: `prds/12-documentation-testing.md` ✅
|
|
98
|
-
- Recent commits mention PRD 12 features ✅
|
|
99
|
-
```
|
|
100
|
-
|
|
101
79
|
**If context detection fails, ask the user:**
|
|
102
80
|
|
|
103
81
|
```markdown
|
|
@@ -105,7 +83,7 @@ You are helping initiate active implementation work on a specific Product Requir
|
|
|
105
83
|
|
|
106
84
|
Please provide the PRD number (e.g., "12", "PRD 12", or "36").
|
|
107
85
|
|
|
108
|
-
**Not sure which PRD to work on?**
|
|
86
|
+
**Not sure which PRD to work on?**
|
|
109
87
|
Execute `dot-ai:prds-get` prompt to see all available PRDs organized by priority and readiness.
|
|
110
88
|
|
|
111
89
|
**Your choice**: [Wait for user input]
|
|
@@ -113,8 +91,6 @@ Execute `dot-ai:prds-get` prompt to see all available PRDs organized by priority
|
|
|
113
91
|
|
|
114
92
|
**Once PRD is identified:**
|
|
115
93
|
- Read the PRD file from `prds/[issue-id]-[feature-name].md`
|
|
116
|
-
- Analyze completion status across all sections
|
|
117
|
-
- Identify patterns in completed vs remaining work
|
|
118
94
|
|
|
119
95
|
## Step 2: PRD Readiness Validation
|
|
120
96
|
|
|
@@ -136,14 +112,16 @@ For documentation-first PRDs:
|
|
|
136
112
|
### Implementation Readiness Checklist
|
|
137
113
|
```markdown
|
|
138
114
|
## PRD Readiness Check
|
|
139
|
-
- [ ] All functional requirements defined
|
|
140
|
-
- [ ] Success criteria measurable
|
|
141
|
-
- [ ] Dependencies available
|
|
142
|
-
- [ ] Documentation complete
|
|
143
|
-
- [ ] Integration points clear
|
|
144
|
-
- [ ] Implementation approach decided
|
|
115
|
+
- [ ] All functional requirements defined
|
|
116
|
+
- [ ] Success criteria measurable
|
|
117
|
+
- [ ] Dependencies available
|
|
118
|
+
- [ ] Documentation complete
|
|
119
|
+
- [ ] Integration points clear
|
|
120
|
+
- [ ] Implementation approach decided
|
|
145
121
|
```
|
|
146
122
|
|
|
123
|
+
**If PRD is not ready:** Inform the user what's missing and suggest they complete PRD planning first.
|
|
124
|
+
|
|
147
125
|
## Step 3: Implementation Context Setup
|
|
148
126
|
|
|
149
127
|
**⚠️ MANDATORY: Complete this step BEFORE proceeding to Step 4**
|
|
@@ -174,76 +152,29 @@ For documentation-first PRDs:
|
|
|
174
152
|
|
|
175
153
|
**DO NOT proceed to Step 4 until branch setup is confirmed.**
|
|
176
154
|
|
|
177
|
-
## Step 4:
|
|
155
|
+
## Step 4: Hand Off to prd-next
|
|
178
156
|
|
|
179
|
-
|
|
180
|
-
Identify the highest-priority first task by analyzing:
|
|
181
|
-
- **Foundation requirements**: Core capabilities that other features depend on
|
|
182
|
-
- **Blocking dependencies**: Items that prevent other work from starting
|
|
183
|
-
- **Quick wins**: Early deliverables that provide validation or value
|
|
184
|
-
- **Risk mitigation**: High-uncertainty items that should be tackled early
|
|
185
|
-
|
|
186
|
-
### Implementation Phases
|
|
187
|
-
For complex PRDs, identify logical implementation phases:
|
|
188
|
-
1. **Phase 1 - Foundation**: Core data structures, interfaces, basic functionality
|
|
189
|
-
2. **Phase 2 - Integration**: Connect with existing systems, implement workflows
|
|
190
|
-
3. **Phase 3 - Enhancement**: Advanced features, optimization, polish
|
|
191
|
-
4. **Phase 4 - Validation**: Testing, documentation updates, deployment
|
|
192
|
-
|
|
193
|
-
### First Task Recommendation
|
|
194
|
-
Select the single best first task based on:
|
|
195
|
-
- **Dependency analysis**: No blocking dependencies
|
|
196
|
-
- **Value delivery**: Provides meaningful progress toward PRD goals
|
|
197
|
-
- **Learning opportunity**: Generates insights for subsequent work
|
|
198
|
-
- **Validation potential**: Allows early testing of key assumptions
|
|
199
|
-
|
|
200
|
-
## Step 5: Begin Implementation
|
|
201
|
-
|
|
202
|
-
### Implementation Kickoff
|
|
203
|
-
Present the implementation plan:
|
|
157
|
+
Once the implementation context is set up, present this message to the user:
|
|
204
158
|
|
|
205
159
|
```markdown
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
## Selected First Task: [Task Name]
|
|
209
|
-
|
|
210
|
-
**Why this task first**: [Clear rationale for why this is the optimal starting point]
|
|
160
|
+
## Ready for Implementation 🚀
|
|
211
161
|
|
|
212
|
-
**
|
|
213
|
-
|
|
214
|
-
**
|
|
215
|
-
|
|
216
|
-
**Next steps after this**: [What becomes possible once this is done]
|
|
217
|
-
|
|
218
|
-
## Implementation Approach
|
|
219
|
-
[Brief technical approach and key decisions]
|
|
220
|
-
|
|
221
|
-
## Ready to Start?
|
|
222
|
-
Type 'yes' to begin implementation, or let me know if you'd prefer to start with a different task.
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
### Implementation Launch
|
|
226
|
-
If confirmed, provide:
|
|
227
|
-
- **Detailed task breakdown**: Step-by-step implementation guide
|
|
228
|
-
- **Code structure recommendations**: Files to create/modify
|
|
229
|
-
- **Testing approach**: How to validate the implementation
|
|
230
|
-
- **Progress checkpoints**: When to update the PRD with progress
|
|
231
|
-
|
|
232
|
-
## Step 6: Update Progress After Completion
|
|
233
|
-
|
|
234
|
-
After the user completes the task implementation, prompt them to update PRD progress:
|
|
162
|
+
**PRD**: [PRD Name] (#[PRD Number])
|
|
163
|
+
**Branch**: `[branch-name]`
|
|
164
|
+
**Status**: Ready for development
|
|
235
165
|
|
|
236
166
|
---
|
|
237
167
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
To update PRD progress and commit your work, run the `prd-update-progress` prompt.
|
|
241
|
-
|
|
242
|
-
*Note: Different agents/clients may have different syntax for executing commands and prompts (e.g., `/prd-update-progress` in Claude Code, or other syntax in different MCP clients).*
|
|
168
|
+
To identify and start working on your first task, run `/prd-next`.
|
|
169
|
+
```
|
|
243
170
|
|
|
244
|
-
|
|
171
|
+
**⚠️ STOP HERE - DO NOT:**
|
|
172
|
+
- Identify or recommend tasks to work on
|
|
173
|
+
- Analyze implementation priorities or critical paths
|
|
174
|
+
- Start any implementation work
|
|
175
|
+
- Continue beyond presenting the handoff message
|
|
245
176
|
|
|
246
|
-
|
|
177
|
+
`/prd-next` handles all task identification and implementation guidance.
|
|
247
178
|
|
|
248
179
|
## Success Criteria
|
|
249
180
|
|
|
@@ -251,13 +182,10 @@ This command should:
|
|
|
251
182
|
- ✅ Successfully identify the target PRD for implementation
|
|
252
183
|
- ✅ Validate that the PRD is ready for development work
|
|
253
184
|
- ✅ Set up proper implementation context (branch, environment)
|
|
254
|
-
- ✅
|
|
255
|
-
- ✅
|
|
256
|
-
- ✅ Bridge the gap between planning and actual coding work
|
|
185
|
+
- ✅ Hand off to `/prd-next` for task identification
|
|
186
|
+
- ✅ Bridge the gap between PRD planning and development setup
|
|
257
187
|
|
|
258
188
|
## Notes
|
|
259
189
|
|
|
260
|
-
- This command
|
|
261
|
-
-
|
|
262
|
-
- Use `prd-update-progress` to track implementation progress against PRD requirements
|
|
263
|
-
- Use `prd-done` when PRD implementation is complete and ready for deployment/closure
|
|
190
|
+
- This command focuses on **setup only** - it validates readiness, creates the branch, and prepares the environment
|
|
191
|
+
- Once setup is complete, `/prd-next` handles all task identification, implementation guidance, and progress tracking
|
|
@@ -302,7 +302,7 @@ After completing the PRD update and committing changes, guide the user based on
|
|
|
302
302
|
|
|
303
303
|
To continue working on this PRD:
|
|
304
304
|
1. Clear/reset the conversation context
|
|
305
|
-
2. Run
|
|
305
|
+
2. Run `/prd-next` to get the next task
|
|
306
306
|
|
|
307
307
|
---
|
|
308
308
|
|
|
@@ -314,8 +314,6 @@ To continue working on this PRD:
|
|
|
314
314
|
|
|
315
315
|
To finalize:
|
|
316
316
|
1. Clear/reset the conversation context
|
|
317
|
-
2. Run
|
|
317
|
+
2. Run `/prd-done` to move the PRD to the done folder and close the GitHub issue
|
|
318
318
|
|
|
319
319
|
---
|
|
320
|
-
|
|
321
|
-
*Note: Different agents/clients may have different syntax for executing prompts (e.g., `/prd-next`, `/prd-done` in Claude Code, or other syntax in different MCP clients).*
|