@vfarcic/dot-ai 0.115.0 ā 0.117.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/README.md +21 -18
- package/dist/core/ai-provider-factory.d.ts +4 -2
- package/dist/core/ai-provider-factory.d.ts.map +1 -1
- package/dist/core/ai-provider-factory.js +17 -6
- package/dist/core/capability-operations.js +1 -1
- package/dist/core/generic-session-manager.d.ts +67 -0
- package/dist/core/generic-session-manager.d.ts.map +1 -0
- package/dist/core/generic-session-manager.js +192 -0
- package/dist/core/pattern-operations.js +1 -1
- package/dist/core/providers/noop-provider.d.ts +47 -0
- package/dist/core/providers/noop-provider.d.ts.map +1 -0
- package/dist/core/providers/noop-provider.js +63 -0
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +13 -13
- package/dist/core/session-utils.d.ts +3 -6
- package/dist/core/session-utils.d.ts.map +1 -1
- package/dist/core/session-utils.js +5 -13
- package/dist/core/shared-prompt-loader.d.ts +15 -3
- package/dist/core/shared-prompt-loader.d.ts.map +1 -1
- package/dist/core/shared-prompt-loader.js +67 -14
- package/dist/core/unified-creation-session.d.ts +3 -10
- package/dist/core/unified-creation-session.d.ts.map +1 -1
- package/dist/core/unified-creation-session.js +34 -75
- package/dist/core/unified-creation-types.d.ts +31 -22
- package/dist/core/unified-creation-types.d.ts.map +1 -1
- package/dist/evaluation/eval-runner.js +12 -3
- package/dist/evaluation/evaluators/base-comparative.d.ts +2 -0
- package/dist/evaluation/evaluators/base-comparative.d.ts.map +1 -1
- package/dist/evaluation/evaluators/base-comparative.js +13 -1
- package/dist/evaluation/graph-generator.d.ts +56 -0
- package/dist/evaluation/graph-generator.d.ts.map +1 -0
- package/dist/evaluation/graph-generator.js +694 -0
- package/dist/evaluation/metadata-loader.d.ts +39 -0
- package/dist/evaluation/metadata-loader.d.ts.map +1 -0
- package/dist/evaluation/metadata-loader.js +74 -0
- package/dist/evaluation/platform-synthesizer.d.ts +5 -1
- package/dist/evaluation/platform-synthesizer.d.ts.map +1 -1
- package/dist/evaluation/platform-synthesizer.js +65 -23
- package/dist/evaluation/run-platform-synthesis.js +22 -5
- package/dist/interfaces/mcp.d.ts.map +1 -1
- package/dist/interfaces/mcp.js +9 -34
- package/dist/tools/answer-question.d.ts.map +1 -1
- package/dist/tools/answer-question.js +12 -12
- package/dist/tools/choose-solution.js +1 -1
- package/dist/tools/generate-manifests.d.ts.map +1 -1
- package/dist/tools/generate-manifests.js +9 -10
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -6
- package/dist/tools/organizational-data.js +12 -12
- package/dist/tools/project-setup/discovery.d.ts +15 -0
- package/dist/tools/project-setup/discovery.d.ts.map +1 -0
- package/dist/tools/project-setup/discovery.js +104 -0
- package/dist/tools/project-setup/generate-scope.d.ts +15 -0
- package/dist/tools/project-setup/generate-scope.d.ts.map +1 -0
- package/dist/tools/project-setup/generate-scope.js +237 -0
- package/dist/tools/project-setup/report-scan.d.ts +15 -0
- package/dist/tools/project-setup/report-scan.d.ts.map +1 -0
- package/dist/tools/project-setup/report-scan.js +156 -0
- package/dist/tools/project-setup/types.d.ts +111 -0
- package/dist/tools/project-setup/types.d.ts.map +1 -0
- package/dist/tools/project-setup/types.js +8 -0
- package/dist/tools/project-setup.d.ts +28 -0
- package/dist/tools/project-setup.d.ts.map +1 -0
- package/dist/tools/project-setup.js +134 -0
- package/dist/tools/recommend.js +1 -1
- package/dist/tools/remediate.js +1 -1
- package/dist/tools/version.d.ts +0 -7
- package/dist/tools/version.d.ts.map +1 -1
- package/dist/tools/version.js +5 -34
- package/package.json +4 -2
- package/prompts/capability-inference.md +2 -2
- package/prompts/infrastructure-trigger-expansion.md +2 -2
- package/prompts/intent-analysis.md +2 -2
- package/prompts/kyverno-generation.md +14 -14
- package/prompts/manifest-generation.md +5 -5
- package/prompts/map-intent-to-operation.md +2 -2
- package/prompts/pattern-complete-error.md +1 -1
- package/prompts/pattern-complete-success.md +4 -4
- package/prompts/pattern-rationale.md +1 -1
- package/prompts/pattern-resources.md +1 -1
- package/prompts/pattern-review.md +5 -5
- package/prompts/policy-complete-apply.md +4 -4
- package/prompts/policy-complete-discard.md +1 -1
- package/prompts/policy-complete-error.md +1 -1
- package/prompts/policy-complete-save.md +4 -4
- package/prompts/policy-complete-success.md +4 -4
- package/prompts/policy-namespace-scope.md +1 -1
- package/prompts/question-generation.md +5 -5
- package/prompts/resource-analysis.md +3 -3
- package/prompts/resource-selection.md +3 -3
- package/prompts/solution-enhancement.md +4 -4
- package/scripts/anthropic.nu +9 -13
- package/scripts/common.nu +31 -33
- package/scripts/ingress.nu +5 -4
- package/scripts/kubernetes.nu +38 -53
- package/dist/core/doc-discovery.d.ts +0 -38
- package/dist/core/doc-discovery.d.ts.map +0 -1
- package/dist/core/doc-discovery.js +0 -231
- package/dist/core/doc-testing-session.d.ts +0 -109
- package/dist/core/doc-testing-session.d.ts.map +0 -1
- package/dist/core/doc-testing-session.js +0 -696
- package/dist/core/doc-testing-types.d.ts +0 -127
- package/dist/core/doc-testing-types.d.ts.map +0 -1
- package/dist/core/doc-testing-types.js +0 -53
- package/dist/core/nushell-runtime.d.ts +0 -39
- package/dist/core/nushell-runtime.d.ts.map +0 -1
- package/dist/core/nushell-runtime.js +0 -103
- package/dist/core/platform-operations.d.ts +0 -70
- package/dist/core/platform-operations.d.ts.map +0 -1
- package/dist/core/platform-operations.js +0 -294
- package/dist/tools/build-platform.d.ts +0 -25
- package/dist/tools/build-platform.d.ts.map +0 -1
- package/dist/tools/build-platform.js +0 -277
- package/dist/tools/test-docs.d.ts +0 -22
- package/dist/tools/test-docs.d.ts.map +0 -1
- package/dist/tools/test-docs.js +0 -351
- package/prompts/doc-testing-done.md +0 -51
- package/prompts/doc-testing-fix.md +0 -120
- package/prompts/doc-testing-scan.md +0 -140
- package/prompts/doc-testing-test-section.md +0 -169
- package/prompts/platform-operations-parse-script-help.md +0 -68
- package/scripts/ack.nu +0 -195
- package/scripts/argo-workflows.nu +0 -47
- package/scripts/argocd.nu +0 -85
- package/scripts/aso.nu +0 -74
- package/scripts/backstage.nu +0 -349
- package/scripts/cert-manager.nu +0 -13
- package/scripts/cnpg.nu +0 -14
- package/scripts/dot.nu +0 -32
- package/scripts/external-secrets.nu +0 -110
- package/scripts/gatekeeper.nu +0 -19
- package/scripts/github.nu +0 -42
- package/scripts/image.nu +0 -67
- package/scripts/kro.nu +0 -11
- package/scripts/kubevela.nu +0 -22
- package/scripts/port.nu +0 -71
- package/scripts/prometheus.nu +0 -21
- package/scripts/registry.nu +0 -55
- package/scripts/storage.nu +0 -210
- package/scripts/tests.nu +0 -12
- package/scripts/velero.nu +0 -45
- package/shared-prompts/validate-docs.md +0 -22
|
@@ -1,696 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Documentation Testing Session Manager
|
|
4
|
-
*
|
|
5
|
-
* Handles creating, loading, saving, and managing documentation validation sessions.
|
|
6
|
-
* Uses the existing session directory infrastructure from session-utils.ts.
|
|
7
|
-
*/
|
|
8
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
-
if (k2 === undefined) k2 = k;
|
|
10
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
-
}
|
|
14
|
-
Object.defineProperty(o, k2, desc);
|
|
15
|
-
}) : (function(o, m, k, k2) {
|
|
16
|
-
if (k2 === undefined) k2 = k;
|
|
17
|
-
o[k2] = m[k];
|
|
18
|
-
}));
|
|
19
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
-
}) : function(o, v) {
|
|
22
|
-
o["default"] = v;
|
|
23
|
-
});
|
|
24
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
-
var ownKeys = function(o) {
|
|
26
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
-
var ar = [];
|
|
28
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
-
return ar;
|
|
30
|
-
};
|
|
31
|
-
return ownKeys(o);
|
|
32
|
-
};
|
|
33
|
-
return function (mod) {
|
|
34
|
-
if (mod && mod.__esModule) return mod;
|
|
35
|
-
var result = {};
|
|
36
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
-
__setModuleDefault(result, mod);
|
|
38
|
-
return result;
|
|
39
|
-
};
|
|
40
|
-
})();
|
|
41
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
exports.DocTestingSessionManager = void 0;
|
|
43
|
-
const fs = __importStar(require("fs"));
|
|
44
|
-
const path = __importStar(require("path"));
|
|
45
|
-
const shared_prompt_loader_1 = require("./shared-prompt-loader");
|
|
46
|
-
const session_utils_1 = require("./session-utils");
|
|
47
|
-
const doc_testing_types_1 = require("./doc-testing-types");
|
|
48
|
-
class DocTestingSessionManager {
|
|
49
|
-
/**
|
|
50
|
-
* Create a new validation session
|
|
51
|
-
*/
|
|
52
|
-
createSession(filePath, args) {
|
|
53
|
-
const sessionDir = (0, session_utils_1.getAndValidateSessionDirectory)(args, true); // requireWrite=true
|
|
54
|
-
const sessionId = this.generateSessionId();
|
|
55
|
-
const session = {
|
|
56
|
-
sessionId,
|
|
57
|
-
filePath,
|
|
58
|
-
startTime: new Date().toISOString(),
|
|
59
|
-
currentPhase: doc_testing_types_1.ValidationPhase.SCAN,
|
|
60
|
-
status: doc_testing_types_1.SessionStatus.ACTIVE,
|
|
61
|
-
metadata: {
|
|
62
|
-
totalSections: 0,
|
|
63
|
-
completedSections: 0,
|
|
64
|
-
sectionStatus: {},
|
|
65
|
-
nextItemId: 1,
|
|
66
|
-
sessionDir,
|
|
67
|
-
lastUpdated: new Date().toISOString()
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
this.saveSession(session, args);
|
|
71
|
-
return session;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Load existing session
|
|
75
|
-
*/
|
|
76
|
-
loadSession(sessionId, args) {
|
|
77
|
-
const sessionDir = (0, session_utils_1.getAndValidateSessionDirectory)(args, false); // requireWrite=false
|
|
78
|
-
const sessionFile = path.join(sessionDir, `doc-test-${sessionId}.json`);
|
|
79
|
-
if (!fs.existsSync(sessionFile)) {
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
try {
|
|
83
|
-
const sessionData = JSON.parse(fs.readFileSync(sessionFile, 'utf8'));
|
|
84
|
-
return sessionData;
|
|
85
|
-
}
|
|
86
|
-
catch (error) {
|
|
87
|
-
console.error(`Failed to load session ${sessionId}:`, error);
|
|
88
|
-
return null;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Save session state
|
|
93
|
-
*/
|
|
94
|
-
saveSession(session, args) {
|
|
95
|
-
const sessionDir = (0, session_utils_1.getAndValidateSessionDirectory)(args, true); // requireWrite=true
|
|
96
|
-
session.metadata.lastUpdated = new Date().toISOString();
|
|
97
|
-
const sessionFile = path.join(sessionDir, `doc-test-${session.sessionId}.json`);
|
|
98
|
-
fs.writeFileSync(sessionFile, JSON.stringify(session, null, 2));
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Get universal agent instructions for documentation testing workflow
|
|
102
|
-
*/
|
|
103
|
-
getAgentInstructions() {
|
|
104
|
-
return `
|
|
105
|
-
DOCUMENTATION TESTING WORKFLOW:
|
|
106
|
-
1. Use the provided prompt to complete the requested task (scan, test section, analyze, or fix)
|
|
107
|
-
2. Return results in the exact format specified in the prompt
|
|
108
|
-
3. Submit results by calling testDocs with these parameters:
|
|
109
|
-
- sessionId: the session ID provided in the response
|
|
110
|
-
- results: your formatted results (JSON for section testing, JSON array for scan results)
|
|
111
|
-
- sectionId: (only when testing individual sections) the specific section ID
|
|
112
|
-
|
|
113
|
-
RESULT SUBMISSION:
|
|
114
|
-
- Always include the sessionId when submitting results
|
|
115
|
-
- Include sectionId when testing individual sections
|
|
116
|
-
- For section testing: use JSON format {"whatWasDone": "...", "issues": [...]}
|
|
117
|
-
- For scan results: use JSON format {"sections": ["Section 1", "Section 2", ...]}
|
|
118
|
-
- After submitting, the system automatically provides the next step
|
|
119
|
-
|
|
120
|
-
WORKFLOW PHASES:
|
|
121
|
-
- scan: Identify testable sections ā submit {"sections": [...]} JSON
|
|
122
|
-
- test: Test individual sections ā submit {"whatWasDone": "...", "issues": [...]} JSON
|
|
123
|
-
- analyze: Review all test results ā submit analysis
|
|
124
|
-
- fix: Apply fixes based on analysis ā submit fix results
|
|
125
|
-
|
|
126
|
-
The system manages session state and workflow progression automatically.`;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Get next workflow step for AI agent
|
|
130
|
-
*/
|
|
131
|
-
getNextStep(sessionId, args, phaseOverride) {
|
|
132
|
-
const session = this.loadSession(sessionId, args);
|
|
133
|
-
if (!session) {
|
|
134
|
-
return null;
|
|
135
|
-
}
|
|
136
|
-
const targetPhase = phaseOverride || session.currentPhase;
|
|
137
|
-
// Handle done phase - mark session as completed
|
|
138
|
-
if (targetPhase === doc_testing_types_1.ValidationPhase.DONE) {
|
|
139
|
-
return this.getDonePhaseStep(session, args);
|
|
140
|
-
}
|
|
141
|
-
// Handle section-by-section testing workflow
|
|
142
|
-
if (targetPhase === doc_testing_types_1.ValidationPhase.TEST) {
|
|
143
|
-
return this.getTestPhaseStep(session, args);
|
|
144
|
-
}
|
|
145
|
-
const prompt = this.loadPhasePrompt(targetPhase, session);
|
|
146
|
-
const nextPhase = this.getNextPhase(targetPhase);
|
|
147
|
-
return {
|
|
148
|
-
sessionId,
|
|
149
|
-
phase: targetPhase,
|
|
150
|
-
prompt,
|
|
151
|
-
nextPhase,
|
|
152
|
-
nextAction: 'testDocs',
|
|
153
|
-
instruction: `Complete the ${targetPhase} phase and submit your results to continue the workflow.`,
|
|
154
|
-
agentInstructions: this.getAgentInstructions(),
|
|
155
|
-
workflow: {
|
|
156
|
-
completed: [], // Will be populated when we add phase tracking
|
|
157
|
-
current: targetPhase,
|
|
158
|
-
remaining: this.getRemainingPhases(targetPhase)
|
|
159
|
-
},
|
|
160
|
-
data: {
|
|
161
|
-
filePath: session.filePath,
|
|
162
|
-
sessionDir: session.metadata.sessionDir
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Handle done phase - mark session as completed and provide summary
|
|
168
|
-
*/
|
|
169
|
-
getDonePhaseStep(session, args) {
|
|
170
|
-
// Update session status to completed
|
|
171
|
-
session.status = doc_testing_types_1.SessionStatus.COMPLETED;
|
|
172
|
-
session.currentPhase = doc_testing_types_1.ValidationPhase.DONE;
|
|
173
|
-
session.metadata.lastUpdated = new Date().toISOString();
|
|
174
|
-
// Save the updated session
|
|
175
|
-
this.saveSession(session, args);
|
|
176
|
-
// Load and populate done phase prompt
|
|
177
|
-
const prompt = this.loadPhasePrompt(doc_testing_types_1.ValidationPhase.DONE, session);
|
|
178
|
-
return {
|
|
179
|
-
sessionId: session.sessionId,
|
|
180
|
-
phase: doc_testing_types_1.ValidationPhase.DONE,
|
|
181
|
-
prompt,
|
|
182
|
-
nextPhase: undefined, // No next phase - session is complete
|
|
183
|
-
nextAction: undefined, // No next action required
|
|
184
|
-
instruction: 'Documentation testing session completed successfully.',
|
|
185
|
-
agentInstructions: 'This session is now complete. No further action is required.',
|
|
186
|
-
workflow: {
|
|
187
|
-
completed: [doc_testing_types_1.ValidationPhase.SCAN, doc_testing_types_1.ValidationPhase.TEST, doc_testing_types_1.ValidationPhase.ANALYZE, doc_testing_types_1.ValidationPhase.FIX],
|
|
188
|
-
current: doc_testing_types_1.ValidationPhase.DONE,
|
|
189
|
-
remaining: []
|
|
190
|
-
},
|
|
191
|
-
data: {
|
|
192
|
-
filePath: session.filePath,
|
|
193
|
-
sessionDir: session.metadata.sessionDir,
|
|
194
|
-
sessionComplete: true,
|
|
195
|
-
summary: this.generateStatusSummary(session)
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Generate final session summary for done phase
|
|
201
|
-
*/
|
|
202
|
-
generateFinalSummary(session) {
|
|
203
|
-
if (!session.sectionResults) {
|
|
204
|
-
return "No test results available.";
|
|
205
|
-
}
|
|
206
|
-
// Count all items by status
|
|
207
|
-
const allItems = [];
|
|
208
|
-
Object.values(session.sectionResults).forEach(result => {
|
|
209
|
-
allItems.push(...result.issues);
|
|
210
|
-
});
|
|
211
|
-
if (allItems.length === 0) {
|
|
212
|
-
return "ā
**No issues found** - Documentation appears to be in excellent condition!";
|
|
213
|
-
}
|
|
214
|
-
const statusCounts = {
|
|
215
|
-
pending: allItems.filter(item => item.status === 'pending').length,
|
|
216
|
-
fixed: allItems.filter(item => item.status === 'fixed').length,
|
|
217
|
-
deferred: allItems.filter(item => item.status === 'deferred').length,
|
|
218
|
-
failed: allItems.filter(item => item.status === 'failed').length
|
|
219
|
-
};
|
|
220
|
-
const total = allItems.length;
|
|
221
|
-
let summary = `## Testing Results\n\n`;
|
|
222
|
-
summary += `**Total Items Identified**: ${total}\n\n`;
|
|
223
|
-
if (statusCounts.fixed > 0) {
|
|
224
|
-
summary += `ā
**Successfully Fixed**: ${statusCounts.fixed} items\n`;
|
|
225
|
-
}
|
|
226
|
-
if (statusCounts.deferred > 0) {
|
|
227
|
-
summary += `š **Deferred/Ignored**: ${statusCounts.deferred} items\n`;
|
|
228
|
-
}
|
|
229
|
-
if (statusCounts.pending > 0) {
|
|
230
|
-
summary += `ā³ **Remaining for Future**: ${statusCounts.pending} items\n`;
|
|
231
|
-
}
|
|
232
|
-
if (statusCounts.failed > 0) {
|
|
233
|
-
summary += `ā **Fix Attempts Failed**: ${statusCounts.failed} items\n`;
|
|
234
|
-
}
|
|
235
|
-
const addressedItems = statusCounts.fixed + statusCounts.deferred;
|
|
236
|
-
const completionRate = total > 0 ? Math.round((addressedItems / total) * 100) : 100;
|
|
237
|
-
summary += `\n**Completion Rate**: ${completionRate}% (${addressedItems}/${total} items addressed)\n`;
|
|
238
|
-
if (statusCounts.pending > 0 || statusCounts.failed > 0) {
|
|
239
|
-
summary += `\nš” **Next Steps**: Start a new testing session to address the remaining ${statusCounts.pending + statusCounts.failed} items.`;
|
|
240
|
-
}
|
|
241
|
-
else {
|
|
242
|
-
summary += `\nš **Excellent!** All identified items have been addressed.`;
|
|
243
|
-
}
|
|
244
|
-
return summary;
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* Get all active sessions
|
|
248
|
-
*/
|
|
249
|
-
getActiveSessions(args) {
|
|
250
|
-
const sessionDir = (0, session_utils_1.getAndValidateSessionDirectory)(args, false); // requireWrite=false
|
|
251
|
-
const sessions = [];
|
|
252
|
-
if (!fs.existsSync(sessionDir)) {
|
|
253
|
-
return sessions;
|
|
254
|
-
}
|
|
255
|
-
const files = fs.readdirSync(sessionDir);
|
|
256
|
-
for (const file of files) {
|
|
257
|
-
if (file.startsWith('doc-test-') && file.endsWith('.json')) {
|
|
258
|
-
const sessionId = file.replace('doc-test-', '').replace('.json', '');
|
|
259
|
-
const session = this.loadSession(sessionId, args);
|
|
260
|
-
if (session && session.status === doc_testing_types_1.SessionStatus.ACTIVE) {
|
|
261
|
-
sessions.push(session);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
return sessions;
|
|
266
|
-
}
|
|
267
|
-
// Private helper methods
|
|
268
|
-
generateSessionId() {
|
|
269
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
270
|
-
const random = Math.random().toString(36).substring(2, 10);
|
|
271
|
-
return `${timestamp}-${random}`;
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* Load phase prompt from file
|
|
275
|
-
*/
|
|
276
|
-
loadPhasePrompt(phase, session) {
|
|
277
|
-
// Prepare template variables for all phases
|
|
278
|
-
const templateVariables = {
|
|
279
|
-
filePath: session.filePath,
|
|
280
|
-
sessionId: session.sessionId,
|
|
281
|
-
phase: phase,
|
|
282
|
-
totalSections: session.metadata.totalSections.toString(),
|
|
283
|
-
completedSections: session.metadata.completedSections.toString()
|
|
284
|
-
};
|
|
285
|
-
// Handle phase-specific template variables
|
|
286
|
-
if (phase === doc_testing_types_1.ValidationPhase.FIX) {
|
|
287
|
-
templateVariables.statusSummary = this.generateStatusSummary(session);
|
|
288
|
-
templateVariables.pendingItems = this.generatePendingItemsList(session);
|
|
289
|
-
}
|
|
290
|
-
if (phase === doc_testing_types_1.ValidationPhase.DONE) {
|
|
291
|
-
templateVariables.finalSummary = this.generateFinalSummary(session);
|
|
292
|
-
templateVariables.completionTime = session.metadata.lastUpdated;
|
|
293
|
-
templateVariables.sessionDir = session.metadata.sessionDir;
|
|
294
|
-
}
|
|
295
|
-
const result = (0, shared_prompt_loader_1.loadPrompt)(`doc-testing-${phase}`, templateVariables);
|
|
296
|
-
// Check if prompt loading failed and return fallback
|
|
297
|
-
if (result.startsWith('Error loading prompt:')) {
|
|
298
|
-
return `Read the file at "${session.filePath}" and process it for phase ${phase}.`;
|
|
299
|
-
}
|
|
300
|
-
// Check for unreplaced template variables and warn
|
|
301
|
-
const unreplacedVars = result.match(/\{[^}]+\}/g);
|
|
302
|
-
if (unreplacedVars) {
|
|
303
|
-
console.error(`Warning: Unreplaced template variables in ${phase} prompt:`, unreplacedVars);
|
|
304
|
-
}
|
|
305
|
-
return result;
|
|
306
|
-
}
|
|
307
|
-
getNextPhase(currentPhase) {
|
|
308
|
-
const phases = [doc_testing_types_1.ValidationPhase.SCAN, doc_testing_types_1.ValidationPhase.TEST, doc_testing_types_1.ValidationPhase.ANALYZE, doc_testing_types_1.ValidationPhase.FIX];
|
|
309
|
-
const currentIndex = phases.indexOf(currentPhase);
|
|
310
|
-
return currentIndex < phases.length - 1 ? phases[currentIndex + 1] : undefined;
|
|
311
|
-
}
|
|
312
|
-
getRemainingPhases(currentPhase) {
|
|
313
|
-
const phases = [doc_testing_types_1.ValidationPhase.SCAN, doc_testing_types_1.ValidationPhase.TEST, doc_testing_types_1.ValidationPhase.ANALYZE, doc_testing_types_1.ValidationPhase.FIX];
|
|
314
|
-
const currentIndex = phases.indexOf(currentPhase);
|
|
315
|
-
return phases.slice(currentIndex + 1);
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Update the status of a specific section
|
|
319
|
-
*/
|
|
320
|
-
updateSectionStatus(sessionId, sectionId, status, args) {
|
|
321
|
-
const session = this.loadSession(sessionId, args);
|
|
322
|
-
if (!session) {
|
|
323
|
-
throw new Error(`Session ${sessionId} not found`);
|
|
324
|
-
}
|
|
325
|
-
session.metadata.sectionStatus[sectionId] = status;
|
|
326
|
-
// Update completed sections count
|
|
327
|
-
session.metadata.completedSections = Object.values(session.metadata.sectionStatus)
|
|
328
|
-
.filter(s => s === doc_testing_types_1.SectionStatus.COMPLETED).length;
|
|
329
|
-
this.saveSession(session, args);
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* Get sections for a session
|
|
333
|
-
*/
|
|
334
|
-
getSections(sessionId, args) {
|
|
335
|
-
const session = this.loadSession(sessionId, args);
|
|
336
|
-
return session?.sections || null;
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Get the next test phase step - handles section-by-section testing
|
|
340
|
-
*/
|
|
341
|
-
getTestPhaseStep(session, args) {
|
|
342
|
-
// If no sections available, fall back to regular test phase
|
|
343
|
-
if (!session.sections || session.sections.length === 0) {
|
|
344
|
-
const prompt = this.loadPhasePrompt(doc_testing_types_1.ValidationPhase.TEST, session);
|
|
345
|
-
return {
|
|
346
|
-
sessionId: session.sessionId,
|
|
347
|
-
phase: doc_testing_types_1.ValidationPhase.TEST,
|
|
348
|
-
prompt,
|
|
349
|
-
nextPhase: doc_testing_types_1.ValidationPhase.ANALYZE,
|
|
350
|
-
nextAction: 'testDocs',
|
|
351
|
-
instruction: 'Complete the test phase and submit your results to continue the workflow.',
|
|
352
|
-
agentInstructions: this.getAgentInstructions(),
|
|
353
|
-
workflow: {
|
|
354
|
-
completed: [],
|
|
355
|
-
current: doc_testing_types_1.ValidationPhase.TEST,
|
|
356
|
-
remaining: [doc_testing_types_1.ValidationPhase.ANALYZE, doc_testing_types_1.ValidationPhase.FIX]
|
|
357
|
-
},
|
|
358
|
-
data: {
|
|
359
|
-
filePath: session.filePath,
|
|
360
|
-
sessionDir: session.metadata.sessionDir
|
|
361
|
-
}
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
// Find the next section to test
|
|
365
|
-
const nextSection = this.getNextSectionToTest(session);
|
|
366
|
-
if (!nextSection) {
|
|
367
|
-
// All sections tested, move to fix phase
|
|
368
|
-
return {
|
|
369
|
-
sessionId: session.sessionId,
|
|
370
|
-
phase: doc_testing_types_1.ValidationPhase.FIX,
|
|
371
|
-
prompt: this.loadPhasePrompt(doc_testing_types_1.ValidationPhase.FIX, session),
|
|
372
|
-
nextPhase: undefined, // FIX is the final phase
|
|
373
|
-
nextAction: 'testDocs',
|
|
374
|
-
instruction: 'Present the pending items to the user for selection. Ask which fixes they want to apply. DO NOT auto-select or auto-defer items.',
|
|
375
|
-
agentInstructions: this.getAgentInstructions(),
|
|
376
|
-
workflow: {
|
|
377
|
-
completed: [doc_testing_types_1.ValidationPhase.SCAN, doc_testing_types_1.ValidationPhase.TEST],
|
|
378
|
-
current: doc_testing_types_1.ValidationPhase.FIX,
|
|
379
|
-
remaining: []
|
|
380
|
-
},
|
|
381
|
-
data: {
|
|
382
|
-
filePath: session.filePath,
|
|
383
|
-
sessionDir: session.metadata.sessionDir,
|
|
384
|
-
allSectionsTested: true
|
|
385
|
-
}
|
|
386
|
-
};
|
|
387
|
-
}
|
|
388
|
-
// Update section status to testing
|
|
389
|
-
this.updateSectionStatus(session.sessionId, nextSection.id, doc_testing_types_1.SectionStatus.TESTING, args);
|
|
390
|
-
const prompt = this.loadSectionTestPrompt(nextSection, session);
|
|
391
|
-
const remainingSections = this.getRemainingTestSections(session);
|
|
392
|
-
const nextPhase = remainingSections.length > 0 ? doc_testing_types_1.ValidationPhase.TEST : doc_testing_types_1.ValidationPhase.ANALYZE;
|
|
393
|
-
return {
|
|
394
|
-
sessionId: session.sessionId,
|
|
395
|
-
phase: doc_testing_types_1.ValidationPhase.TEST,
|
|
396
|
-
prompt,
|
|
397
|
-
nextPhase,
|
|
398
|
-
nextAction: 'testDocs',
|
|
399
|
-
instruction: `Test the "${nextSection.title}" section and submit your results to continue the workflow.`,
|
|
400
|
-
agentInstructions: this.getAgentInstructions(),
|
|
401
|
-
workflow: {
|
|
402
|
-
completed: [doc_testing_types_1.ValidationPhase.SCAN],
|
|
403
|
-
current: doc_testing_types_1.ValidationPhase.TEST,
|
|
404
|
-
remaining: remainingSections.length > 0 ? [doc_testing_types_1.ValidationPhase.TEST, doc_testing_types_1.ValidationPhase.ANALYZE, doc_testing_types_1.ValidationPhase.FIX] : [doc_testing_types_1.ValidationPhase.ANALYZE, doc_testing_types_1.ValidationPhase.FIX]
|
|
405
|
-
},
|
|
406
|
-
data: {
|
|
407
|
-
filePath: session.filePath,
|
|
408
|
-
sessionDir: session.metadata.sessionDir,
|
|
409
|
-
currentSection: nextSection,
|
|
410
|
-
sectionsRemaining: remainingSections.length,
|
|
411
|
-
totalSections: session.sections.length
|
|
412
|
-
}
|
|
413
|
-
};
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* Find the next section that needs testing
|
|
417
|
-
*/
|
|
418
|
-
getNextSectionToTest(session) {
|
|
419
|
-
if (!session.sections)
|
|
420
|
-
return null;
|
|
421
|
-
// Find sections that are pending
|
|
422
|
-
for (const section of session.sections) {
|
|
423
|
-
const status = session.metadata.sectionStatus[section.id];
|
|
424
|
-
// Skip if already tested or currently testing
|
|
425
|
-
if (status === doc_testing_types_1.SectionStatus.COMPLETED || status === doc_testing_types_1.SectionStatus.TESTING) {
|
|
426
|
-
continue;
|
|
427
|
-
}
|
|
428
|
-
// Return first pending section (no dependencies to check)
|
|
429
|
-
return section;
|
|
430
|
-
}
|
|
431
|
-
return null;
|
|
432
|
-
}
|
|
433
|
-
/**
|
|
434
|
-
* Get remaining sections that need testing
|
|
435
|
-
*/
|
|
436
|
-
getRemainingTestSections(session) {
|
|
437
|
-
if (!session.sections)
|
|
438
|
-
return [];
|
|
439
|
-
return session.sections.filter(section => {
|
|
440
|
-
const status = session.metadata.sectionStatus[section.id];
|
|
441
|
-
return status === doc_testing_types_1.SectionStatus.PENDING;
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* Load section-specific test prompt
|
|
446
|
-
*/
|
|
447
|
-
loadSectionTestPrompt(section, session) {
|
|
448
|
-
const result = (0, shared_prompt_loader_1.loadPrompt)('doc-testing-test-section', {
|
|
449
|
-
filePath: session.filePath,
|
|
450
|
-
sessionId: session.sessionId,
|
|
451
|
-
sectionId: section.id,
|
|
452
|
-
sectionTitle: section.title,
|
|
453
|
-
totalSections: session.sections?.length.toString() || '0',
|
|
454
|
-
sectionsRemaining: this.getRemainingTestSections(session).length.toString()
|
|
455
|
-
});
|
|
456
|
-
// Check if prompt loading failed and return fallback
|
|
457
|
-
if (result.startsWith('Error loading prompt:')) {
|
|
458
|
-
return `Test the "${section.title}" section of ${session.filePath}.\n\nAnalyze this section and test everything you determine is testable within it.`;
|
|
459
|
-
}
|
|
460
|
-
// Check for unreplaced template variables and warn
|
|
461
|
-
const unreplacedVars = result.match(/\{[^}]+\}/g);
|
|
462
|
-
if (unreplacedVars) {
|
|
463
|
-
console.error(`Warning: Unreplaced template variables in section test prompt:`, unreplacedVars);
|
|
464
|
-
}
|
|
465
|
-
return result;
|
|
466
|
-
}
|
|
467
|
-
/**
|
|
468
|
-
* Convert string arrays to FixableItem arrays with generated IDs
|
|
469
|
-
*/
|
|
470
|
-
convertToFixableItems(items, session) {
|
|
471
|
-
return items.map((item) => {
|
|
472
|
-
// If already a FixableItem object, return as-is
|
|
473
|
-
if (typeof item === 'object' && item.id !== undefined) {
|
|
474
|
-
return item;
|
|
475
|
-
}
|
|
476
|
-
// Convert string to FixableItem with generated ID
|
|
477
|
-
const fixableItem = {
|
|
478
|
-
id: session.metadata.nextItemId++,
|
|
479
|
-
text: item,
|
|
480
|
-
status: 'pending'
|
|
481
|
-
};
|
|
482
|
-
return fixableItem;
|
|
483
|
-
});
|
|
484
|
-
}
|
|
485
|
-
/**
|
|
486
|
-
* Store test results for a specific section
|
|
487
|
-
*/
|
|
488
|
-
storeSectionTestResults(sessionId, sectionId, results, args) {
|
|
489
|
-
const session = this.loadSession(sessionId, args);
|
|
490
|
-
if (!session) {
|
|
491
|
-
throw new Error(`Session ${sessionId} not found`);
|
|
492
|
-
}
|
|
493
|
-
// Parse and validate JSON results
|
|
494
|
-
let parsedResults; // Use 'any' initially to handle both old and new formats
|
|
495
|
-
try {
|
|
496
|
-
parsedResults = JSON.parse(results);
|
|
497
|
-
// Validate required fields
|
|
498
|
-
if (typeof parsedResults.whatWasDone !== 'string') {
|
|
499
|
-
throw new Error('Missing or invalid "whatWasDone" field');
|
|
500
|
-
}
|
|
501
|
-
if (!Array.isArray(parsedResults.issues)) {
|
|
502
|
-
throw new Error('Missing or invalid "issues" field - must be array');
|
|
503
|
-
}
|
|
504
|
-
// Convert string array to FixableItem array with tracking
|
|
505
|
-
// Note: Format consolidated in PRD #34 - issues now contain both problems and solutions
|
|
506
|
-
const processedResults = {
|
|
507
|
-
whatWasDone: parsedResults.whatWasDone,
|
|
508
|
-
issues: this.convertToFixableItems(parsedResults.issues, session)
|
|
509
|
-
};
|
|
510
|
-
parsedResults = processedResults;
|
|
511
|
-
}
|
|
512
|
-
catch (error) {
|
|
513
|
-
throw new Error(`Invalid JSON results format: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
514
|
-
}
|
|
515
|
-
// Initialize sectionResults if it doesn't exist
|
|
516
|
-
if (!session.sectionResults) {
|
|
517
|
-
session.sectionResults = {};
|
|
518
|
-
}
|
|
519
|
-
// Store the parsed results
|
|
520
|
-
session.sectionResults[sectionId] = parsedResults;
|
|
521
|
-
// Update section status to completed
|
|
522
|
-
if (session.metadata.sectionStatus[sectionId]) {
|
|
523
|
-
session.metadata.sectionStatus[sectionId] = doc_testing_types_1.SectionStatus.COMPLETED;
|
|
524
|
-
// Update completed sections count
|
|
525
|
-
session.metadata.completedSections = Object.values(session.metadata.sectionStatus)
|
|
526
|
-
.filter(status => status === doc_testing_types_1.SectionStatus.COMPLETED).length;
|
|
527
|
-
}
|
|
528
|
-
this.saveSession(session, args);
|
|
529
|
-
}
|
|
530
|
-
/**
|
|
531
|
-
* Process scan results by converting section titles into DocumentSection objects
|
|
532
|
-
*/
|
|
533
|
-
processScanResults(sessionId, sectionTitles, args) {
|
|
534
|
-
const session = this.loadSession(sessionId, args);
|
|
535
|
-
if (!session) {
|
|
536
|
-
throw new Error(`Session ${sessionId} not found`);
|
|
537
|
-
}
|
|
538
|
-
// Convert section titles to DocumentSection objects and initialize status
|
|
539
|
-
const sections = sectionTitles.map((title, index) => ({
|
|
540
|
-
id: `section_${index + 1}`,
|
|
541
|
-
title: title.trim()
|
|
542
|
-
}));
|
|
543
|
-
// Update session with sections and reset counters
|
|
544
|
-
session.sections = sections;
|
|
545
|
-
session.metadata.totalSections = sections.length;
|
|
546
|
-
session.metadata.completedSections = 0;
|
|
547
|
-
session.metadata.nextItemId = 1; // Initialize ID counter for fix tracking
|
|
548
|
-
session.metadata.sectionStatus = sections.reduce((acc, section) => {
|
|
549
|
-
acc[section.id] = doc_testing_types_1.SectionStatus.PENDING;
|
|
550
|
-
return acc;
|
|
551
|
-
}, {});
|
|
552
|
-
// Move to test phase after processing scan results
|
|
553
|
-
session.currentPhase = doc_testing_types_1.ValidationPhase.TEST;
|
|
554
|
-
this.saveSession(session, args);
|
|
555
|
-
}
|
|
556
|
-
/**
|
|
557
|
-
* Generate status summary for fix phase
|
|
558
|
-
*/
|
|
559
|
-
generateStatusSummary(session) {
|
|
560
|
-
if (!session.sectionResults) {
|
|
561
|
-
return "No test results available.";
|
|
562
|
-
}
|
|
563
|
-
const allItems = [];
|
|
564
|
-
// Collect all FixableItems from all sections
|
|
565
|
-
Object.values(session.sectionResults).forEach(result => {
|
|
566
|
-
allItems.push(...result.issues);
|
|
567
|
-
});
|
|
568
|
-
if (allItems.length === 0) {
|
|
569
|
-
return "No issues found during testing.";
|
|
570
|
-
}
|
|
571
|
-
// Count by status
|
|
572
|
-
const statusCounts = {
|
|
573
|
-
pending: allItems.filter(item => item.status === 'pending').length,
|
|
574
|
-
fixed: allItems.filter(item => item.status === 'fixed').length,
|
|
575
|
-
deferred: allItems.filter(item => item.status === 'deferred').length,
|
|
576
|
-
failed: allItems.filter(item => item.status === 'failed').length
|
|
577
|
-
};
|
|
578
|
-
const total = allItems.length;
|
|
579
|
-
const remaining = statusCounts.pending + statusCounts.failed;
|
|
580
|
-
let summary = `**Total Items**: ${total}\n`;
|
|
581
|
-
if (statusCounts.fixed > 0)
|
|
582
|
-
summary += `ā
**Fixed**: ${statusCounts.fixed}\n`;
|
|
583
|
-
if (statusCounts.deferred > 0)
|
|
584
|
-
summary += `š **Deferred**: ${statusCounts.deferred}\n`;
|
|
585
|
-
if (remaining > 0)
|
|
586
|
-
summary += `ā³ **Remaining**: ${remaining} (${statusCounts.pending} pending, ${statusCounts.failed} failed)\n`;
|
|
587
|
-
if (remaining === 0) {
|
|
588
|
-
summary += "\nš All items have been addressed!";
|
|
589
|
-
}
|
|
590
|
-
return summary;
|
|
591
|
-
}
|
|
592
|
-
/**
|
|
593
|
-
* Generate formatted list of pending/failed items for fix phase
|
|
594
|
-
*/
|
|
595
|
-
generatePendingItemsList(session) {
|
|
596
|
-
if (!session.sectionResults) {
|
|
597
|
-
return "No test results available.";
|
|
598
|
-
}
|
|
599
|
-
const pendingItems = [];
|
|
600
|
-
// Collect all pending/failed items from all sections
|
|
601
|
-
// Note: Format consolidated in PRD #34 - all issues now include problems and solutions
|
|
602
|
-
Object.values(session.sectionResults).forEach(result => {
|
|
603
|
-
const pendingIssues = result.issues.filter(item => item.status === 'pending' || item.status === 'failed');
|
|
604
|
-
pendingItems.push(...pendingIssues);
|
|
605
|
-
});
|
|
606
|
-
if (pendingItems.length === 0) {
|
|
607
|
-
return "No pending items - all issues have been addressed!";
|
|
608
|
-
}
|
|
609
|
-
let output = "";
|
|
610
|
-
// Format all pending items (consolidated format with problems and solutions)
|
|
611
|
-
if (pendingItems.length > 0) {
|
|
612
|
-
output += "### Items Requiring Attention\n";
|
|
613
|
-
output += "*Each item includes both the problem and its fix*\n\n";
|
|
614
|
-
pendingItems.forEach(item => {
|
|
615
|
-
const statusIndicator = item.status === 'failed' ? ' ā [RETRY]' : '';
|
|
616
|
-
output += `${item.id}. ${item.text}${statusIndicator}\n`;
|
|
617
|
-
});
|
|
618
|
-
}
|
|
619
|
-
return output;
|
|
620
|
-
}
|
|
621
|
-
/**
|
|
622
|
-
* Update the status of a specific FixableItem by ID
|
|
623
|
-
*/
|
|
624
|
-
updateFixableItemStatus(sessionId, itemId, status, explanation, args) {
|
|
625
|
-
const session = this.loadSession(sessionId, args || {});
|
|
626
|
-
if (!session || !session.sectionResults) {
|
|
627
|
-
throw new Error(`Session ${sessionId} not found or has no test results`);
|
|
628
|
-
}
|
|
629
|
-
let itemFound = false;
|
|
630
|
-
// Search through all sections to find the item with the specified ID
|
|
631
|
-
Object.values(session.sectionResults).forEach(result => {
|
|
632
|
-
// Check issues (consolidated format - all items are in issues array)
|
|
633
|
-
const issueIndex = result.issues.findIndex(item => item.id === itemId);
|
|
634
|
-
if (issueIndex !== -1) {
|
|
635
|
-
result.issues[issueIndex].status = status;
|
|
636
|
-
if (explanation)
|
|
637
|
-
result.issues[issueIndex].explanation = explanation;
|
|
638
|
-
itemFound = true;
|
|
639
|
-
return;
|
|
640
|
-
}
|
|
641
|
-
});
|
|
642
|
-
if (!itemFound) {
|
|
643
|
-
throw new Error(`FixableItem with ID ${itemId} not found in session ${sessionId}`);
|
|
644
|
-
}
|
|
645
|
-
this.saveSession(session, args || {});
|
|
646
|
-
}
|
|
647
|
-
/**
|
|
648
|
-
* Update multiple FixableItem statuses at once
|
|
649
|
-
*/
|
|
650
|
-
updateMultipleFixableItemStatuses(sessionId, updates, args) {
|
|
651
|
-
const session = this.loadSession(sessionId, args || {});
|
|
652
|
-
if (!session || !session.sectionResults) {
|
|
653
|
-
throw new Error(`Session ${sessionId} not found or has no test results`);
|
|
654
|
-
}
|
|
655
|
-
const notFoundItems = [];
|
|
656
|
-
// Update each item
|
|
657
|
-
updates.forEach(update => {
|
|
658
|
-
let itemFound = false;
|
|
659
|
-
Object.values(session.sectionResults).forEach(result => {
|
|
660
|
-
// Check issues (consolidated format - all items are in issues array)
|
|
661
|
-
const issueIndex = result.issues.findIndex(item => item.id === update.itemId);
|
|
662
|
-
if (issueIndex !== -1) {
|
|
663
|
-
result.issues[issueIndex].status = update.status;
|
|
664
|
-
if (update.explanation)
|
|
665
|
-
result.issues[issueIndex].explanation = update.explanation;
|
|
666
|
-
itemFound = true;
|
|
667
|
-
return;
|
|
668
|
-
}
|
|
669
|
-
});
|
|
670
|
-
if (!itemFound) {
|
|
671
|
-
notFoundItems.push(update.itemId);
|
|
672
|
-
}
|
|
673
|
-
});
|
|
674
|
-
if (notFoundItems.length > 0) {
|
|
675
|
-
throw new Error(`FixableItems with IDs not found: ${notFoundItems.join(', ')}`);
|
|
676
|
-
}
|
|
677
|
-
this.saveSession(session, args || {});
|
|
678
|
-
}
|
|
679
|
-
/**
|
|
680
|
-
* Get all FixableItems with pending or failed status
|
|
681
|
-
*/
|
|
682
|
-
getPendingFixableItems(sessionId, args) {
|
|
683
|
-
const session = this.loadSession(sessionId, args || {});
|
|
684
|
-
if (!session || !session.sectionResults) {
|
|
685
|
-
return [];
|
|
686
|
-
}
|
|
687
|
-
const pendingItems = [];
|
|
688
|
-
// Collect all pending/failed items (consolidated format)
|
|
689
|
-
Object.values(session.sectionResults).forEach(result => {
|
|
690
|
-
const pendingIssues = result.issues.filter(item => item.status === 'pending' || item.status === 'failed');
|
|
691
|
-
pendingItems.push(...pendingIssues);
|
|
692
|
-
});
|
|
693
|
-
return pendingItems.sort((a, b) => a.id - b.id); // Sort by ID for consistent ordering
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
exports.DocTestingSessionManager = DocTestingSessionManager;
|