@creatoria/miniapp-mcp 0.1.3 → 0.2.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 +14 -3
- package/dist/app/cli/index.d.ts +6 -0
- package/dist/app/cli/index.d.ts.map +1 -0
- package/dist/app/cli/index.js +6 -0
- package/dist/app/cli/index.js.map +1 -0
- package/dist/app/index.d.ts +6 -0
- package/dist/app/index.d.ts.map +1 -0
- package/dist/app/index.js +6 -0
- package/dist/app/index.js.map +1 -0
- package/dist/app/server/index.d.ts +7 -0
- package/dist/app/server/index.d.ts.map +1 -0
- package/dist/app/server/index.js +6 -0
- package/dist/app/server/index.js.map +1 -0
- package/dist/capabilities/assert/index.d.ts +5 -0
- package/dist/capabilities/assert/index.d.ts.map +1 -0
- package/dist/capabilities/assert/index.js +5 -0
- package/dist/capabilities/assert/index.js.map +1 -0
- package/dist/capabilities/automator/index.d.ts +6 -0
- package/dist/capabilities/automator/index.d.ts.map +1 -0
- package/dist/capabilities/automator/index.js +6 -0
- package/dist/capabilities/automator/index.js.map +1 -0
- package/dist/capabilities/automator/schemas/close.d.ts +5 -0
- package/dist/capabilities/automator/schemas/close.d.ts.map +1 -0
- package/dist/capabilities/automator/schemas/close.js +11 -0
- package/dist/capabilities/automator/schemas/close.js.map +1 -0
- package/dist/capabilities/automator/schemas/connect.d.ts +11 -0
- package/dist/capabilities/automator/schemas/connect.d.ts.map +1 -0
- package/dist/capabilities/automator/schemas/connect.js +19 -0
- package/dist/capabilities/automator/schemas/connect.js.map +1 -0
- package/dist/capabilities/automator/schemas/disconnect.d.ts +5 -0
- package/dist/capabilities/automator/schemas/disconnect.d.ts.map +1 -0
- package/dist/capabilities/automator/schemas/disconnect.js +11 -0
- package/dist/capabilities/automator/schemas/disconnect.js.map +1 -0
- package/dist/capabilities/automator/schemas/index.d.ts +4 -0
- package/dist/capabilities/automator/schemas/index.d.ts.map +1 -0
- package/dist/capabilities/automator/schemas/index.js +12 -0
- package/dist/capabilities/automator/schemas/index.js.map +1 -0
- package/dist/capabilities/automator/schemas/launch.d.ts +17 -0
- package/dist/capabilities/automator/schemas/launch.d.ts.map +1 -0
- package/dist/capabilities/automator/schemas/launch.js +26 -0
- package/dist/capabilities/automator/schemas/launch.js.map +1 -0
- package/dist/capabilities/element/index.d.ts +5 -0
- package/dist/capabilities/element/index.d.ts.map +1 -0
- package/dist/capabilities/element/index.js +5 -0
- package/dist/capabilities/element/index.js.map +1 -0
- package/dist/capabilities/index.d.ts +15 -0
- package/dist/capabilities/index.d.ts.map +1 -0
- package/dist/capabilities/index.js +14 -0
- package/dist/capabilities/index.js.map +1 -0
- package/dist/capabilities/miniprogram/index.d.ts +5 -0
- package/dist/capabilities/miniprogram/index.d.ts.map +1 -0
- package/dist/capabilities/miniprogram/index.js +5 -0
- package/dist/capabilities/miniprogram/index.js.map +1 -0
- package/dist/capabilities/network/index.d.ts +5 -0
- package/dist/capabilities/network/index.d.ts.map +1 -0
- package/dist/capabilities/network/index.js +5 -0
- package/dist/capabilities/network/index.js.map +1 -0
- package/dist/capabilities/page/index.d.ts +5 -0
- package/dist/capabilities/page/index.d.ts.map +1 -0
- package/dist/capabilities/page/index.js +5 -0
- package/dist/capabilities/page/index.js.map +1 -0
- package/dist/capabilities/record/index.d.ts +5 -0
- package/dist/capabilities/record/index.d.ts.map +1 -0
- package/dist/capabilities/record/index.js +5 -0
- package/dist/capabilities/record/index.js.map +1 -0
- package/dist/capabilities/schema-registry.d.ts +4 -0
- package/dist/capabilities/schema-registry.d.ts.map +1 -0
- package/dist/capabilities/schema-registry.js +18 -0
- package/dist/capabilities/schema-registry.js.map +1 -0
- package/dist/capabilities/schema-types.d.ts +22 -0
- package/dist/capabilities/schema-types.d.ts.map +1 -0
- package/dist/capabilities/schema-types.js +2 -0
- package/dist/capabilities/schema-types.js.map +1 -0
- package/dist/capabilities/snapshot/index.d.ts +5 -0
- package/dist/capabilities/snapshot/index.d.ts.map +1 -0
- package/dist/capabilities/snapshot/index.js +5 -0
- package/dist/capabilities/snapshot/index.js.map +1 -0
- package/dist/config/loader.js +1 -1
- package/dist/config/loader.js.map +1 -1
- package/dist/core/element-ref.d.ts +1 -43
- package/dist/core/element-ref.d.ts.map +1 -1
- package/dist/core/element-ref.js +1 -212
- package/dist/core/element-ref.js.map +1 -1
- package/dist/core/logger.d.ts +1 -54
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +1 -377
- package/dist/core/logger.js.map +1 -1
- package/dist/core/output.d.ts +1 -20
- package/dist/core/output.d.ts.map +1 -1
- package/dist/core/output.js +1 -55
- package/dist/core/output.js.map +1 -1
- package/dist/core/report-generator.d.ts +1 -23
- package/dist/core/report-generator.d.ts.map +1 -1
- package/dist/core/report-generator.js +1 -211
- package/dist/core/report-generator.js.map +1 -1
- package/dist/core/session.d.ts +2 -82
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +2 -305
- package/dist/core/session.js.map +1 -1
- package/dist/core/timeout.d.ts +1 -48
- package/dist/core/timeout.d.ts.map +1 -1
- package/dist/core/timeout.js +1 -66
- package/dist/core/timeout.js.map +1 -1
- package/dist/core/tool-logger.d.ts +1 -82
- package/dist/core/tool-logger.d.ts.map +1 -1
- package/dist/core/tool-logger.js +1 -452
- package/dist/core/tool-logger.js.map +1 -1
- package/dist/core/validation.d.ts +1 -38
- package/dist/core/validation.d.ts.map +1 -1
- package/dist/core/validation.js +1 -92
- package/dist/core/validation.js.map +1 -1
- package/dist/runtime/element/element-ref.d.ts +44 -0
- package/dist/runtime/element/element-ref.d.ts.map +1 -0
- package/dist/runtime/element/element-ref.js +214 -0
- package/dist/runtime/element/element-ref.js.map +1 -0
- package/dist/runtime/element/index.d.ts +2 -0
- package/dist/runtime/element/index.d.ts.map +1 -0
- package/dist/runtime/element/index.js +2 -0
- package/dist/runtime/element/index.js.map +1 -0
- package/dist/runtime/index.d.ts +10 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +10 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/logging/index.d.ts +3 -0
- package/dist/runtime/logging/index.d.ts.map +1 -0
- package/dist/runtime/logging/index.js +3 -0
- package/dist/runtime/logging/index.js.map +1 -0
- package/dist/runtime/logging/logger.d.ts +55 -0
- package/dist/runtime/logging/logger.d.ts.map +1 -0
- package/dist/runtime/logging/logger.js +379 -0
- package/dist/runtime/logging/logger.js.map +1 -0
- package/dist/runtime/logging/tool-logger.d.ts +83 -0
- package/dist/runtime/logging/tool-logger.d.ts.map +1 -0
- package/dist/runtime/logging/tool-logger.js +454 -0
- package/dist/runtime/logging/tool-logger.js.map +1 -0
- package/dist/runtime/outputs/index.d.ts +3 -0
- package/dist/runtime/outputs/index.d.ts.map +1 -0
- package/dist/runtime/outputs/index.js +3 -0
- package/dist/runtime/outputs/index.js.map +1 -0
- package/dist/runtime/outputs/output-manager.d.ts +12 -0
- package/dist/runtime/outputs/output-manager.d.ts.map +1 -0
- package/dist/runtime/outputs/output-manager.js +39 -0
- package/dist/runtime/outputs/output-manager.js.map +1 -0
- package/dist/runtime/outputs/report-generator.d.ts +5 -0
- package/dist/runtime/outputs/report-generator.d.ts.map +1 -0
- package/dist/runtime/outputs/report-generator.js +175 -0
- package/dist/runtime/outputs/report-generator.js.map +1 -0
- package/dist/runtime/session/index.d.ts +3 -0
- package/dist/runtime/session/index.d.ts.map +1 -0
- package/dist/runtime/session/index.js +3 -0
- package/dist/runtime/session/index.js.map +1 -0
- package/dist/runtime/session/store.d.ts +28 -0
- package/dist/runtime/session/store.d.ts.map +1 -0
- package/dist/runtime/session/store.js +154 -0
- package/dist/runtime/session/store.js.map +1 -0
- package/dist/runtime/session/utils/cleanup.d.ts +3 -0
- package/dist/runtime/session/utils/cleanup.d.ts.map +1 -0
- package/dist/runtime/session/utils/cleanup.js +78 -0
- package/dist/runtime/session/utils/cleanup.js.map +1 -0
- package/dist/runtime/timeout/index.d.ts +2 -0
- package/dist/runtime/timeout/index.d.ts.map +1 -0
- package/dist/runtime/timeout/index.js +2 -0
- package/dist/runtime/timeout/index.js.map +1 -0
- package/dist/runtime/timeout/timeout.d.ts +49 -0
- package/dist/runtime/timeout/timeout.d.ts.map +1 -0
- package/dist/runtime/timeout/timeout.js +67 -0
- package/dist/runtime/timeout/timeout.js.map +1 -0
- package/dist/runtime/validation/index.d.ts +2 -0
- package/dist/runtime/validation/index.d.ts.map +1 -0
- package/dist/runtime/validation/index.js +2 -0
- package/dist/runtime/validation/index.js.map +1 -0
- package/dist/runtime/validation/validation.d.ts +39 -0
- package/dist/runtime/validation/validation.d.ts.map +1 -0
- package/dist/runtime/validation/validation.js +93 -0
- package/dist/runtime/validation/validation.js.map +1 -0
- package/dist/schemas/automator/miniprogram_close.json +12 -0
- package/dist/schemas/automator/miniprogram_connect.json +19 -0
- package/dist/schemas/automator/miniprogram_disconnect.json +12 -0
- package/dist/schemas/automator/miniprogram_launch.json +30 -0
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/index.js +1 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/miniprogram.d.ts +0 -1
- package/dist/tools/miniprogram.d.ts.map +1 -1
- package/dist/tools/miniprogram.js +17 -29
- package/dist/tools/miniprogram.js.map +1 -1
- package/dist/tools/page.js +2 -2
- package/dist/tools/page.js.map +1 -1
- package/docs/directory-structure-and-code-style-best-practices.md +91 -0
- package/docs/migration/README.md +34 -0
- package/docs/migration/TC-ALIGN-01-notes.md +35 -0
- package/docs/migration/runtime-skeleton.md +50 -0
- package/docs/migration/tool-schema-strategy.md +75 -0
- package/docs//345/256/214/346/225/264/345/256/236/347/216/260/346/226/271/346/241/210.md +14 -14
- package/docs//347/254/254/344/270/200/347/211/210/346/234/254/346/226/271/346/241/210.md +7 -7
- package/package.json +4 -2
- package/docs/SIMPLE_USAGE.md +0 -210
- package/docs/architecture.E-Docs.md +0 -1359
- package/docs/architecture.F1.md +0 -720
- package/docs/architecture.F2.md +0 -871
- package/docs/architecture.F3.md +0 -905
- package/docs/architecture.md +0 -90
- package/docs/charter.A1.align.yaml +0 -170
- package/docs/charter.A2.align.yaml +0 -199
- package/docs/charter.A3.align.yaml +0 -242
- package/docs/charter.A4.align.yaml +0 -227
- package/docs/charter.B1.align.yaml +0 -179
- package/docs/charter.B2.align.yaml +0 -200
- package/docs/charter.B3.align.yaml +0 -200
- package/docs/charter.B4.align.yaml +0 -188
- package/docs/charter.C1.align.yaml +0 -190
- package/docs/charter.C2.align.yaml +0 -202
- package/docs/charter.C3.align.yaml +0 -211
- package/docs/charter.C4.align.yaml +0 -263
- package/docs/charter.C5.align.yaml +0 -220
- package/docs/charter.D1.align.yaml +0 -190
- package/docs/charter.D2.align.yaml +0 -234
- package/docs/charter.D3.align.yaml +0 -206
- package/docs/charter.E-Docs.align.yaml +0 -294
- package/docs/charter.F1.align.yaml +0 -193
- package/docs/charter.F2.align.yaml +0 -248
- package/docs/charter.F3.align.yaml +0 -287
- package/docs/charter.G.align.yaml +0 -174
- package/docs/charter.align.yaml +0 -111
- package/docs/maintenance.md +0 -682
- package/docs/playwright-mcp/350/260/203/347/240/224.md +0 -53
- package/docs/setup-guide.md +0 -775
- package/docs/tasks.A1.atomize.md +0 -296
- package/docs/tasks.A2.atomize.md +0 -408
- package/docs/tasks.A3.atomize.md +0 -564
- package/docs/tasks.A4.atomize.md +0 -496
- package/docs/tasks.B1.atomize.md +0 -352
- package/docs/tasks.B2.atomize.md +0 -561
- package/docs/tasks.B3.atomize.md +0 -508
- package/docs/tasks.B4.atomize.md +0 -504
- package/docs/tasks.C1.atomize.md +0 -540
- package/docs/tasks.C2.atomize.md +0 -665
- package/docs/tasks.C3.atomize.md +0 -745
- package/docs/tasks.C4.atomize.md +0 -908
- package/docs/tasks.C5.atomize.md +0 -755
- package/docs/tasks.D1.atomize.md +0 -547
- package/docs/tasks.D2.atomize.md +0 -619
- package/docs/tasks.D3.atomize.md +0 -790
- package/docs/tasks.E-Docs.atomize.md +0 -1204
- package/docs/tasks.atomize.md +0 -189
|
@@ -1,212 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* Session report generator (F3)
|
|
3
|
-
*
|
|
4
|
-
* Generates JSON and Markdown reports from session tool call data
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Calculate summary statistics from tool call records
|
|
8
|
-
*/
|
|
9
|
-
function calculateSummary(toolCalls) {
|
|
10
|
-
if (toolCalls.length === 0) {
|
|
11
|
-
return {
|
|
12
|
-
totalCalls: 0,
|
|
13
|
-
successCount: 0,
|
|
14
|
-
failureCount: 0,
|
|
15
|
-
successRate: 0,
|
|
16
|
-
avgDuration: 0,
|
|
17
|
-
maxDuration: 0,
|
|
18
|
-
minDuration: 0,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
const successCount = toolCalls.filter((call) => call.success).length;
|
|
22
|
-
const failureCount = toolCalls.length - successCount;
|
|
23
|
-
const durations = toolCalls.map((call) => call.duration);
|
|
24
|
-
return {
|
|
25
|
-
totalCalls: toolCalls.length,
|
|
26
|
-
successCount,
|
|
27
|
-
failureCount,
|
|
28
|
-
successRate: toolCalls.length > 0 ? successCount / toolCalls.length : 0,
|
|
29
|
-
avgDuration: durations.reduce((sum, d) => sum + d, 0) / durations.length,
|
|
30
|
-
maxDuration: Math.max(...durations),
|
|
31
|
-
minDuration: Math.min(...durations),
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Generate JSON session report
|
|
36
|
-
*/
|
|
37
|
-
export function generateSessionReport(session) {
|
|
38
|
-
if (!session.reportData) {
|
|
39
|
-
throw new Error('Session report data not initialized');
|
|
40
|
-
}
|
|
41
|
-
const { reportData } = session;
|
|
42
|
-
const endTime = reportData.endTime || new Date();
|
|
43
|
-
const duration = endTime.getTime() - reportData.startTime.getTime();
|
|
44
|
-
const summary = calculateSummary(reportData.toolCalls);
|
|
45
|
-
// Extract failures for dedicated section
|
|
46
|
-
const failures = reportData.toolCalls
|
|
47
|
-
.filter((call) => !call.success && call.error)
|
|
48
|
-
.map((call) => ({
|
|
49
|
-
toolName: call.toolName,
|
|
50
|
-
timestamp: call.timestamp.toISOString(),
|
|
51
|
-
error: call.error.message,
|
|
52
|
-
snapshotPath: call.error.snapshotPath,
|
|
53
|
-
}));
|
|
54
|
-
return {
|
|
55
|
-
sessionId: session.sessionId,
|
|
56
|
-
startTime: reportData.startTime.toISOString(),
|
|
57
|
-
endTime: endTime.toISOString(),
|
|
58
|
-
duration,
|
|
59
|
-
summary,
|
|
60
|
-
toolCalls: reportData.toolCalls.map((call) => ({
|
|
61
|
-
...call,
|
|
62
|
-
timestamp: call.timestamp,
|
|
63
|
-
})),
|
|
64
|
-
failures,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Format duration in human-readable format
|
|
69
|
-
*/
|
|
70
|
-
function formatDuration(ms) {
|
|
71
|
-
if (ms < 1000) {
|
|
72
|
-
return `${ms}ms`;
|
|
73
|
-
}
|
|
74
|
-
if (ms < 60000) {
|
|
75
|
-
return `${(ms / 1000).toFixed(1)}s`;
|
|
76
|
-
}
|
|
77
|
-
const minutes = Math.floor(ms / 60000);
|
|
78
|
-
const seconds = Math.floor((ms % 60000) / 1000);
|
|
79
|
-
return `${minutes}m ${seconds}s`;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Format percentage
|
|
83
|
-
*/
|
|
84
|
-
function formatPercent(value) {
|
|
85
|
-
return `${(value * 100).toFixed(0)}%`;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Format timestamp for display
|
|
89
|
-
*/
|
|
90
|
-
function formatTimestamp(date) {
|
|
91
|
-
return date.toISOString().replace('T', ' ').replace('Z', '').split('.')[0];
|
|
92
|
-
}
|
|
93
|
-
function calculateToolStats(toolCalls) {
|
|
94
|
-
const statsMap = new Map();
|
|
95
|
-
for (const call of toolCalls) {
|
|
96
|
-
const existing = statsMap.get(call.toolName);
|
|
97
|
-
if (!existing) {
|
|
98
|
-
statsMap.set(call.toolName, {
|
|
99
|
-
toolName: call.toolName,
|
|
100
|
-
calls: 1,
|
|
101
|
-
success: call.success ? 1 : 0,
|
|
102
|
-
failure: call.success ? 0 : 1,
|
|
103
|
-
avgDuration: call.duration,
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
existing.calls++;
|
|
108
|
-
existing.success += call.success ? 1 : 0;
|
|
109
|
-
existing.failure += call.success ? 0 : 1;
|
|
110
|
-
existing.avgDuration =
|
|
111
|
-
(existing.avgDuration * (existing.calls - 1) + call.duration) / existing.calls;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return Array.from(statsMap.values()).sort((a, b) => b.calls - a.calls);
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Generate Markdown session report
|
|
118
|
-
*/
|
|
119
|
-
export function generateMarkdownReport(report) {
|
|
120
|
-
const lines = [];
|
|
121
|
-
// Header
|
|
122
|
-
lines.push(`# Session Report: ${report.sessionId}`);
|
|
123
|
-
lines.push('');
|
|
124
|
-
// Summary
|
|
125
|
-
lines.push('## Summary');
|
|
126
|
-
lines.push(`- **Duration**: ${formatDuration(report.duration)}`);
|
|
127
|
-
lines.push(`- **Total Calls**: ${report.summary.totalCalls}`);
|
|
128
|
-
lines.push(`- **Success Rate**: ${formatPercent(report.summary.successRate)} (${report.summary.successCount}/${report.summary.totalCalls})`);
|
|
129
|
-
lines.push(`- **Average Duration**: ${formatDuration(report.summary.avgDuration)}`);
|
|
130
|
-
lines.push('');
|
|
131
|
-
// Tool Call Statistics
|
|
132
|
-
if (report.toolCalls.length > 0) {
|
|
133
|
-
lines.push('## Tool Call Statistics');
|
|
134
|
-
lines.push('| Tool Name | Calls | Success | Failure | Avg Duration |');
|
|
135
|
-
lines.push('|-----------|-------|---------|---------|--------------|');
|
|
136
|
-
const toolStats = calculateToolStats(report.toolCalls);
|
|
137
|
-
for (const stats of toolStats) {
|
|
138
|
-
lines.push(`| ${stats.toolName} | ${stats.calls} | ${stats.success} | ${stats.failure} | ${formatDuration(stats.avgDuration)} |`);
|
|
139
|
-
}
|
|
140
|
-
lines.push('');
|
|
141
|
-
}
|
|
142
|
-
// Failures
|
|
143
|
-
if (report.failures.length > 0) {
|
|
144
|
-
lines.push('## Failures');
|
|
145
|
-
for (let i = 0; i < report.failures.length; i++) {
|
|
146
|
-
const failure = report.failures[i];
|
|
147
|
-
lines.push(`### ${i + 1}. ${failure.toolName}`);
|
|
148
|
-
lines.push(`- **Time**: ${formatTimestamp(new Date(failure.timestamp))}`);
|
|
149
|
-
lines.push(`- **Error**: ${failure.error}`);
|
|
150
|
-
if (failure.snapshotPath) {
|
|
151
|
-
lines.push(`- **Snapshot**: [${failure.snapshotPath}](${failure.snapshotPath})`);
|
|
152
|
-
}
|
|
153
|
-
lines.push('');
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
// Timeline
|
|
157
|
-
if (report.toolCalls.length > 0) {
|
|
158
|
-
lines.push('## Timeline');
|
|
159
|
-
lines.push('| Time | Tool | Status | Duration |');
|
|
160
|
-
lines.push('|------|------|--------|----------|');
|
|
161
|
-
for (const call of report.toolCalls) {
|
|
162
|
-
const status = call.success ? '✅' : '❌';
|
|
163
|
-
const time = formatTimestamp(call.timestamp);
|
|
164
|
-
lines.push(`| ${time} | ${call.toolName} | ${status} | ${formatDuration(call.duration)} |`);
|
|
165
|
-
}
|
|
166
|
-
lines.push('');
|
|
167
|
-
}
|
|
168
|
-
return lines.join('\n');
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Generate and save session reports (JSON + Markdown)
|
|
172
|
-
*
|
|
173
|
-
* Called automatically when session is disposed.
|
|
174
|
-
* Fire-and-forget pattern - errors are logged but not thrown.
|
|
175
|
-
*
|
|
176
|
-
* @param session Session state with reportData
|
|
177
|
-
*/
|
|
178
|
-
export async function generateAndSaveReports(session) {
|
|
179
|
-
if (!session.reportData) {
|
|
180
|
-
// Reporting not enabled for this session
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
if (!session.outputManager) {
|
|
184
|
-
session.logger?.warn('Cannot generate report: outputManager not available');
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
try {
|
|
188
|
-
// Set end time
|
|
189
|
-
session.reportData.endTime = new Date();
|
|
190
|
-
// Generate reports
|
|
191
|
-
const jsonReport = generateSessionReport(session);
|
|
192
|
-
const markdownReport = generateMarkdownReport(jsonReport);
|
|
193
|
-
// F3-P1: Save both reports in parallel for better performance
|
|
194
|
-
const [jsonPath, mdPath] = await Promise.all([
|
|
195
|
-
session.outputManager.writeFile('report.json', Buffer.from(JSON.stringify(jsonReport, null, 2))),
|
|
196
|
-
session.outputManager.writeFile('report.md', markdownReport),
|
|
197
|
-
]);
|
|
198
|
-
session.logger?.info('Session reports generated', {
|
|
199
|
-
jsonPath,
|
|
200
|
-
mdPath,
|
|
201
|
-
totalCalls: jsonReport.summary.totalCalls,
|
|
202
|
-
successRate: jsonReport.summary.successRate,
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
catch (error) {
|
|
206
|
-
session.logger?.error('Failed to generate session reports', {
|
|
207
|
-
error: error instanceof Error ? error.message : String(error),
|
|
208
|
-
});
|
|
209
|
-
// Don't throw - report generation failure shouldn't block session cleanup
|
|
210
|
-
}
|
|
211
|
-
}
|
|
1
|
+
export { generateSessionReport, generateMarkdownReport, generateAndSaveReports, } from '../runtime/outputs/report-generator.js';
|
|
212
2
|
//# sourceMappingURL=report-generator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report-generator.js","sourceRoot":"","sources":["../../src/core/report-generator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"report-generator.js","sourceRoot":"","sources":["../../src/core/report-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,wCAAwC,CAAA"}
|
package/dist/core/session.d.ts
CHANGED
|
@@ -1,83 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Each session maintains isolated state for miniProgram instances and elements
|
|
4
|
-
*/
|
|
5
|
-
import type { SessionState, SessionConfig, SessionMetrics, LoggerConfig } from '../types.js';
|
|
6
|
-
export declare class SessionStore {
|
|
7
|
-
private sessions;
|
|
8
|
-
private sessionTimeout;
|
|
9
|
-
private outputDir;
|
|
10
|
-
private loggerConfig?;
|
|
11
|
-
private enableSessionReport;
|
|
12
|
-
private cleanupInterval?;
|
|
13
|
-
constructor(config?: {
|
|
14
|
-
sessionTimeout?: number;
|
|
15
|
-
outputDir?: string;
|
|
16
|
-
loggerConfig?: LoggerConfig;
|
|
17
|
-
enableSessionReport?: boolean;
|
|
18
|
-
});
|
|
19
|
-
/**
|
|
20
|
-
* Get session by ID
|
|
21
|
-
*/
|
|
22
|
-
get(sessionId: string): SessionState | undefined;
|
|
23
|
-
/**
|
|
24
|
-
* Set session state
|
|
25
|
-
*/
|
|
26
|
-
set(sessionId: string, state: SessionState): void;
|
|
27
|
-
/**
|
|
28
|
-
* Cleanup session resources (internal helper)
|
|
29
|
-
*
|
|
30
|
-
* @throws AggregateError if cleanup operations fail
|
|
31
|
-
*/
|
|
32
|
-
private cleanupSessionResources;
|
|
33
|
-
/**
|
|
34
|
-
* Delete session and cleanup resources
|
|
35
|
-
*
|
|
36
|
-
* Properly cleans up all async resources:
|
|
37
|
-
* - Disconnects from miniProgram
|
|
38
|
-
* - Kills IDE process and waits for exit
|
|
39
|
-
* - Clears element cache
|
|
40
|
-
*
|
|
41
|
-
* @throws AggregateError if cleanup operations fail
|
|
42
|
-
*/
|
|
43
|
-
delete(sessionId: string): Promise<void>;
|
|
44
|
-
/**
|
|
45
|
-
* Check if session exists
|
|
46
|
-
*/
|
|
47
|
-
has(sessionId: string): boolean;
|
|
48
|
-
/**
|
|
49
|
-
* Dispose all sessions
|
|
50
|
-
*
|
|
51
|
-
* Async method to properly cleanup all resources
|
|
52
|
-
*/
|
|
53
|
-
dispose(): Promise<void>;
|
|
54
|
-
/**
|
|
55
|
-
* Get or create session
|
|
56
|
-
*/
|
|
57
|
-
getOrCreate(sessionId: string, config?: SessionConfig): SessionState;
|
|
58
|
-
/**
|
|
59
|
-
* Update session activity timestamp
|
|
60
|
-
*/
|
|
61
|
-
updateActivity(sessionId: string): void;
|
|
62
|
-
/**
|
|
63
|
-
* Check if session has expired
|
|
64
|
-
*/
|
|
65
|
-
private isSessionExpired;
|
|
66
|
-
/**
|
|
67
|
-
* Cleanup expired sessions periodically
|
|
68
|
-
*/
|
|
69
|
-
private startCleanupTimer;
|
|
70
|
-
/**
|
|
71
|
-
* Get session metrics for monitoring
|
|
72
|
-
*/
|
|
73
|
-
getMetrics(): SessionMetrics;
|
|
74
|
-
/**
|
|
75
|
-
* Get all session IDs
|
|
76
|
-
*/
|
|
77
|
-
getAllSessionIds(): string[];
|
|
78
|
-
/**
|
|
79
|
-
* Clear expired sessions manually
|
|
80
|
-
*/
|
|
81
|
-
cleanupExpired(): Promise<number>;
|
|
82
|
-
}
|
|
1
|
+
export { SessionStore } from '../runtime/session/store.js';
|
|
2
|
+
export { cleanupSessionResources } from '../runtime/session/utils/cleanup.js';
|
|
83
3
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAA"}
|
package/dist/core/session.js
CHANGED
|
@@ -1,306 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Each session maintains isolated state for miniProgram instances and elements
|
|
4
|
-
*/
|
|
5
|
-
import { join } from 'path';
|
|
6
|
-
import { createLogger } from './logger.js';
|
|
7
|
-
import { createOutputManager } from './output.js';
|
|
8
|
-
import { generateAndSaveReports } from './report-generator.js';
|
|
9
|
-
const DEFAULT_SESSION_TIMEOUT = 30 * 60 * 1000; // 30 minutes
|
|
10
|
-
const DEFAULT_OUTPUT_DIR = '.mcp-artifacts';
|
|
11
|
-
export class SessionStore {
|
|
12
|
-
sessions = new Map();
|
|
13
|
-
sessionTimeout;
|
|
14
|
-
outputDir;
|
|
15
|
-
loggerConfig;
|
|
16
|
-
enableSessionReport;
|
|
17
|
-
cleanupInterval;
|
|
18
|
-
constructor(config = {}) {
|
|
19
|
-
this.sessionTimeout = config.sessionTimeout || DEFAULT_SESSION_TIMEOUT;
|
|
20
|
-
this.outputDir = config.outputDir || DEFAULT_OUTPUT_DIR;
|
|
21
|
-
this.loggerConfig = config.loggerConfig;
|
|
22
|
-
this.enableSessionReport = config.enableSessionReport || false;
|
|
23
|
-
// Start periodic cleanup of timed-out sessions
|
|
24
|
-
this.startCleanupTimer();
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Get session by ID
|
|
28
|
-
*/
|
|
29
|
-
get(sessionId) {
|
|
30
|
-
const session = this.sessions.get(sessionId);
|
|
31
|
-
if (session && this.isSessionExpired(session)) {
|
|
32
|
-
console.error(`Session ${sessionId} has expired, cleaning up...`);
|
|
33
|
-
// Remove from map immediately (synchronous)
|
|
34
|
-
this.sessions.delete(sessionId);
|
|
35
|
-
// Fire-and-forget cleanup of resources (async operation)
|
|
36
|
-
void this.cleanupSessionResources(session, sessionId).catch((error) => {
|
|
37
|
-
console.error(`Failed to cleanup expired session ${sessionId}:`, error);
|
|
38
|
-
});
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
return session;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Set session state
|
|
45
|
-
*/
|
|
46
|
-
set(sessionId, state) {
|
|
47
|
-
this.sessions.set(sessionId, state);
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Cleanup session resources (internal helper)
|
|
51
|
-
*
|
|
52
|
-
* @throws AggregateError if cleanup operations fail
|
|
53
|
-
*/
|
|
54
|
-
async cleanupSessionResources(session, sessionId) {
|
|
55
|
-
const errors = [];
|
|
56
|
-
// F3: Generate session reports before cleanup (fire-and-forget)
|
|
57
|
-
if (session.reportData) {
|
|
58
|
-
try {
|
|
59
|
-
await generateAndSaveReports(session);
|
|
60
|
-
console.error(`Session reports generated for ${sessionId}`);
|
|
61
|
-
}
|
|
62
|
-
catch (error) {
|
|
63
|
-
// Don't add to errors - report generation failure shouldn't block cleanup
|
|
64
|
-
console.error(`Failed to generate session reports for ${sessionId}:`, error);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
// Issue #5: Dispose logger after report generation (to capture report logs)
|
|
68
|
-
if (session.logger?.dispose) {
|
|
69
|
-
try {
|
|
70
|
-
await session.logger.dispose();
|
|
71
|
-
console.error(`Logger disposed for session ${sessionId}`);
|
|
72
|
-
}
|
|
73
|
-
catch (error) {
|
|
74
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
75
|
-
errors.push(new Error(`Failed to dispose logger: ${err.message}`));
|
|
76
|
-
console.error(`Failed to dispose logger for session ${sessionId}:`, error);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
// Clean up miniProgram instance (async operation)
|
|
80
|
-
if (session.miniProgram) {
|
|
81
|
-
try {
|
|
82
|
-
if (typeof session.miniProgram.disconnect === 'function') {
|
|
83
|
-
await session.miniProgram.disconnect();
|
|
84
|
-
}
|
|
85
|
-
console.error(`Disconnected miniProgram for session ${sessionId}`);
|
|
86
|
-
}
|
|
87
|
-
catch (error) {
|
|
88
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
89
|
-
errors.push(new Error(`Failed to disconnect miniProgram: ${err.message}`));
|
|
90
|
-
console.error(`Failed to disconnect miniProgram for session ${sessionId}:`, error);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
// Clean up IDE process (async operation - wait for exit)
|
|
94
|
-
const ideProcess = session.ideProcess;
|
|
95
|
-
if (ideProcess) {
|
|
96
|
-
try {
|
|
97
|
-
if (typeof ideProcess.kill === 'function') {
|
|
98
|
-
// Wait for process to actually exit (only if once method exists)
|
|
99
|
-
if (typeof ideProcess.once === 'function') {
|
|
100
|
-
await new Promise((resolve, reject) => {
|
|
101
|
-
const timeout = setTimeout(() => {
|
|
102
|
-
reject(new Error('IDE process did not exit within 5 seconds'));
|
|
103
|
-
}, 5000);
|
|
104
|
-
ideProcess.once('exit', () => {
|
|
105
|
-
clearTimeout(timeout);
|
|
106
|
-
resolve();
|
|
107
|
-
});
|
|
108
|
-
ideProcess.kill();
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
// For test mocks or processes without event emitter
|
|
113
|
-
ideProcess.kill();
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
console.error(`Killed IDE process for session ${sessionId}`);
|
|
117
|
-
}
|
|
118
|
-
catch (error) {
|
|
119
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
120
|
-
errors.push(new Error(`Failed to kill IDE process: ${err.message}`));
|
|
121
|
-
console.error(`Failed to kill IDE process for session ${sessionId}:`, error);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
// Clear element cache (sync operation)
|
|
125
|
-
try {
|
|
126
|
-
session.elements.clear();
|
|
127
|
-
}
|
|
128
|
-
catch (error) {
|
|
129
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
130
|
-
errors.push(new Error(`Failed to clear element cache: ${err.message}`));
|
|
131
|
-
}
|
|
132
|
-
// If there were any errors, throw AggregateError
|
|
133
|
-
if (errors.length > 0) {
|
|
134
|
-
console.error(`Session ${sessionId} cleanup completed with ${errors.length} error(s)`);
|
|
135
|
-
throw new AggregateError(errors, `Session cleanup had ${errors.length} error(s)`);
|
|
136
|
-
}
|
|
137
|
-
console.error(`Session ${sessionId} cleaned up successfully`);
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Delete session and cleanup resources
|
|
141
|
-
*
|
|
142
|
-
* Properly cleans up all async resources:
|
|
143
|
-
* - Disconnects from miniProgram
|
|
144
|
-
* - Kills IDE process and waits for exit
|
|
145
|
-
* - Clears element cache
|
|
146
|
-
*
|
|
147
|
-
* @throws AggregateError if cleanup operations fail
|
|
148
|
-
*/
|
|
149
|
-
async delete(sessionId) {
|
|
150
|
-
const session = this.sessions.get(sessionId);
|
|
151
|
-
if (!session) {
|
|
152
|
-
this.sessions.delete(sessionId);
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
// Remove from session map first
|
|
156
|
-
this.sessions.delete(sessionId);
|
|
157
|
-
// Cleanup resources
|
|
158
|
-
await this.cleanupSessionResources(session, sessionId);
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Check if session exists
|
|
162
|
-
*/
|
|
163
|
-
has(sessionId) {
|
|
164
|
-
return this.sessions.has(sessionId);
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Dispose all sessions
|
|
168
|
-
*
|
|
169
|
-
* Async method to properly cleanup all resources
|
|
170
|
-
*/
|
|
171
|
-
async dispose() {
|
|
172
|
-
if (this.cleanupInterval) {
|
|
173
|
-
clearInterval(this.cleanupInterval);
|
|
174
|
-
this.cleanupInterval = undefined;
|
|
175
|
-
}
|
|
176
|
-
// Delete all sessions in parallel
|
|
177
|
-
const deletions = Array.from(this.sessions.keys()).map((sessionId) => this.delete(sessionId).catch((error) => {
|
|
178
|
-
console.error(`Failed to delete session ${sessionId} during dispose:`, error);
|
|
179
|
-
}));
|
|
180
|
-
await Promise.all(deletions);
|
|
181
|
-
console.error('All sessions disposed');
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Get or create session
|
|
185
|
-
*/
|
|
186
|
-
getOrCreate(sessionId, config) {
|
|
187
|
-
let session = this.get(sessionId);
|
|
188
|
-
if (!session) {
|
|
189
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
190
|
-
const outputDir = join(this.outputDir, `${sessionId}-${timestamp}`);
|
|
191
|
-
const now = new Date();
|
|
192
|
-
session = {
|
|
193
|
-
sessionId,
|
|
194
|
-
pages: [],
|
|
195
|
-
elements: new Map(),
|
|
196
|
-
outputDir,
|
|
197
|
-
createdAt: now,
|
|
198
|
-
lastActivity: now,
|
|
199
|
-
config,
|
|
200
|
-
logger: createLogger(sessionId, this.loggerConfig),
|
|
201
|
-
loggerConfig: this.loggerConfig,
|
|
202
|
-
outputManager: createOutputManager(outputDir),
|
|
203
|
-
// F3: Initialize report data if enabled
|
|
204
|
-
reportData: this.enableSessionReport
|
|
205
|
-
? {
|
|
206
|
-
toolCalls: [],
|
|
207
|
-
startTime: now,
|
|
208
|
-
}
|
|
209
|
-
: undefined,
|
|
210
|
-
};
|
|
211
|
-
this.set(sessionId, session);
|
|
212
|
-
console.error(`Created new session: ${sessionId}`);
|
|
213
|
-
}
|
|
214
|
-
return session;
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* Update session activity timestamp
|
|
218
|
-
*/
|
|
219
|
-
updateActivity(sessionId) {
|
|
220
|
-
const session = this.get(sessionId);
|
|
221
|
-
if (session) {
|
|
222
|
-
session.lastActivity = new Date();
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Check if session has expired
|
|
227
|
-
*/
|
|
228
|
-
isSessionExpired(session) {
|
|
229
|
-
const now = Date.now();
|
|
230
|
-
const lastActivity = session.lastActivity.getTime();
|
|
231
|
-
return now - lastActivity > this.sessionTimeout;
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Cleanup expired sessions periodically
|
|
235
|
-
*/
|
|
236
|
-
startCleanupTimer() {
|
|
237
|
-
// Check every 5 minutes
|
|
238
|
-
this.cleanupInterval = setInterval(async () => {
|
|
239
|
-
const expiredSessions = [];
|
|
240
|
-
for (const [sessionId, session] of this.sessions.entries()) {
|
|
241
|
-
if (this.isSessionExpired(session)) {
|
|
242
|
-
expiredSessions.push(sessionId);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
if (expiredSessions.length > 0) {
|
|
246
|
-
console.error(`Cleaning up ${expiredSessions.length} expired sessions`);
|
|
247
|
-
// Delete expired sessions in parallel with error handling
|
|
248
|
-
const deletions = expiredSessions.map((sessionId) => this.delete(sessionId).catch((error) => {
|
|
249
|
-
console.error(`Failed to delete expired session ${sessionId}:`, error);
|
|
250
|
-
}));
|
|
251
|
-
await Promise.all(deletions);
|
|
252
|
-
}
|
|
253
|
-
}, 5 * 60 * 1000); // 5 minutes
|
|
254
|
-
// Don't block process exit
|
|
255
|
-
this.cleanupInterval.unref();
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Get session metrics for monitoring
|
|
259
|
-
*/
|
|
260
|
-
getMetrics() {
|
|
261
|
-
const sessions = Array.from(this.sessions.values());
|
|
262
|
-
let oldestSession;
|
|
263
|
-
let totalElements = 0;
|
|
264
|
-
if (sessions.length > 0) {
|
|
265
|
-
const oldest = sessions.reduce((prev, curr) => prev.createdAt < curr.createdAt ? prev : curr);
|
|
266
|
-
oldestSession = {
|
|
267
|
-
sessionId: oldest.sessionId,
|
|
268
|
-
age: Date.now() - oldest.createdAt.getTime(),
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
for (const session of sessions) {
|
|
272
|
-
totalElements += session.elements.size;
|
|
273
|
-
}
|
|
274
|
-
return {
|
|
275
|
-
totalSessions: this.sessions.size,
|
|
276
|
-
activeSessions: sessions.filter((s) => !this.isSessionExpired(s)).length,
|
|
277
|
-
oldestSession,
|
|
278
|
-
totalElements,
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Get all session IDs
|
|
283
|
-
*/
|
|
284
|
-
getAllSessionIds() {
|
|
285
|
-
return Array.from(this.sessions.keys());
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Clear expired sessions manually
|
|
289
|
-
*/
|
|
290
|
-
async cleanupExpired() {
|
|
291
|
-
const expiredSessions = [];
|
|
292
|
-
for (const [sessionId, session] of this.sessions.entries()) {
|
|
293
|
-
if (this.isSessionExpired(session)) {
|
|
294
|
-
expiredSessions.push(sessionId);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
// Delete all expired sessions in parallel
|
|
298
|
-
await Promise.all(expiredSessions.map((sessionId) => this.delete(sessionId).catch((error) => {
|
|
299
|
-
console.error(`Failed to delete expired session ${sessionId}:`, error);
|
|
300
|
-
})));
|
|
301
|
-
return expiredSessions.length;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
// Note: sessionStore should be created in server.ts with proper configuration
|
|
305
|
-
// This allows outputDir and other options to be configured via ServerConfig
|
|
1
|
+
export { SessionStore } from '../runtime/session/store.js';
|
|
2
|
+
export { cleanupSessionResources } from '../runtime/session/utils/cleanup.js';
|
|
306
3
|
//# sourceMappingURL=session.js.map
|
package/dist/core/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAA"}
|