@recapt/mcp 0.0.18-beta → 0.0.20-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/cli/index.d.ts +0 -11
  2. package/dist/cli/index.js +1059 -21
  3. package/dist/index.d.ts +0 -18
  4. package/dist/index.js +3205 -247
  5. package/dist/tools/catalog/anthropicToolCatalog.json +1306 -0
  6. package/dist/tools/catalog/toolCatalog.json +4078 -382
  7. package/package.json +10 -3
  8. package/skills/self-improvement.md +388 -222
  9. package/templates/self-improvement-full.md +91 -0
  10. package/templates/{self-improvement.md → self-improvement-lite.md} +13 -9
  11. package/dist/api/client.d.ts +0 -14
  12. package/dist/api/client.js +0 -67
  13. package/dist/cli/commands/setup-self-improvement-gh.d.ts +0 -7
  14. package/dist/cli/commands/setup-self-improvement-gh.js +0 -310
  15. package/dist/cli/commands/setup.d.ts +0 -7
  16. package/dist/cli/commands/setup.js +0 -173
  17. package/dist/cli/commands/skill.d.ts +0 -24
  18. package/dist/cli/commands/skill.js +0 -264
  19. package/dist/cli/utils/ide-config.d.ts +0 -31
  20. package/dist/cli/utils/ide-config.js +0 -294
  21. package/dist/cli/utils/prompts.d.ts +0 -22
  22. package/dist/cli/utils/prompts.js +0 -71
  23. package/dist/tools/analyzeFlow.d.ts +0 -7
  24. package/dist/tools/analyzeFlow.js +0 -68
  25. package/dist/tools/analyzeFunnel.d.ts +0 -7
  26. package/dist/tools/analyzeFunnel.js +0 -63
  27. package/dist/tools/catalog/callTool.d.ts +0 -22
  28. package/dist/tools/catalog/callTool.js +0 -92
  29. package/dist/tools/catalog/index.d.ts +0 -11
  30. package/dist/tools/catalog/index.js +0 -11
  31. package/dist/tools/catalog/searchTools.d.ts +0 -22
  32. package/dist/tools/catalog/searchTools.js +0 -194
  33. package/dist/tools/compareCohorts.d.ts +0 -6
  34. package/dist/tools/compareCohorts.js +0 -84
  35. package/dist/tools/comparePeriods.d.ts +0 -6
  36. package/dist/tools/comparePeriods.js +0 -54
  37. package/dist/tools/detectDrift.d.ts +0 -6
  38. package/dist/tools/detectDrift.js +0 -55
  39. package/dist/tools/detectRegressions.d.ts +0 -6
  40. package/dist/tools/detectRegressions.js +0 -63
  41. package/dist/tools/diagnostic.d.ts +0 -6
  42. package/dist/tools/diagnostic.js +0 -109
  43. package/dist/tools/discoverPersonas.d.ts +0 -6
  44. package/dist/tools/discoverPersonas.js +0 -50
  45. package/dist/tools/getActionableIssues.d.ts +0 -7
  46. package/dist/tools/getActionableIssues.js +0 -55
  47. package/dist/tools/getAnomalies.d.ts +0 -6
  48. package/dist/tools/getAnomalies.js +0 -53
  49. package/dist/tools/getConsoleErrors.d.ts +0 -6
  50. package/dist/tools/getConsoleErrors.js +0 -61
  51. package/dist/tools/getDeadClicks.d.ts +0 -6
  52. package/dist/tools/getDeadClicks.js +0 -42
  53. package/dist/tools/getDomains.d.ts +0 -6
  54. package/dist/tools/getDomains.js +0 -34
  55. package/dist/tools/getElementFriction.d.ts +0 -6
  56. package/dist/tools/getElementFriction.js +0 -45
  57. package/dist/tools/getFlowFriction.d.ts +0 -7
  58. package/dist/tools/getFlowFriction.js +0 -57
  59. package/dist/tools/getFormFriction.d.ts +0 -6
  60. package/dist/tools/getFormFriction.js +0 -42
  61. package/dist/tools/getIssues.d.ts +0 -6
  62. package/dist/tools/getIssues.js +0 -82
  63. package/dist/tools/getJourneyPatterns.d.ts +0 -7
  64. package/dist/tools/getJourneyPatterns.js +0 -50
  65. package/dist/tools/getPageMetrics.d.ts +0 -6
  66. package/dist/tools/getPageMetrics.js +0 -47
  67. package/dist/tools/getPageTrends.d.ts +0 -6
  68. package/dist/tools/getPageTrends.js +0 -46
  69. package/dist/tools/getSessionDetails.d.ts +0 -6
  70. package/dist/tools/getSessionDetails.js +0 -70
  71. package/dist/tools/getSessionPages.d.ts +0 -7
  72. package/dist/tools/getSessionPages.js +0 -74
  73. package/dist/tools/getUxHealthReport.d.ts +0 -7
  74. package/dist/tools/getUxHealthReport.js +0 -50
  75. package/dist/tools/improvementRun.d.ts +0 -6
  76. package/dist/tools/improvementRun.js +0 -315
  77. package/dist/tools/knowledge.d.ts +0 -6
  78. package/dist/tools/knowledge.js +0 -186
  79. package/dist/tools/listPages.d.ts +0 -6
  80. package/dist/tools/listPages.js +0 -50
  81. package/dist/tools/listSessions.d.ts +0 -7
  82. package/dist/tools/listSessions.js +0 -67
  83. package/dist/tools/memory.d.ts +0 -7
  84. package/dist/tools/memory.js +0 -119
  85. package/dist/tools/predictOutcomes.d.ts +0 -6
  86. package/dist/tools/predictOutcomes.js +0 -66
  87. package/dist/tools/remediation.d.ts +0 -6
  88. package/dist/tools/remediation.js +0 -223
  89. package/dist/tools/scanSite.d.ts +0 -6
  90. package/dist/tools/scanSite.js +0 -51
  91. package/dist/tools/searchSessions.d.ts +0 -6
  92. package/dist/tools/searchSessions.js +0 -51
  93. package/dist/tools/triage.d.ts +0 -6
  94. package/dist/tools/triage.js +0 -114
  95. package/dist/tools/triageSessions.d.ts +0 -8
  96. package/dist/tools/triageSessions.js +0 -197
  97. package/dist/tools/upgradeOptions.d.ts +0 -7
  98. package/dist/tools/upgradeOptions.js +0 -67
@@ -1,223 +0,0 @@
1
- /**
2
- * Remediation tools for self-improvement workflow.
3
- *
4
- * Provides fix proposal, deployment confirmation, evaluation, and history tracking.
5
- */
6
- import { z } from "zod";
7
- import { apiGet, apiPost, apiPatch, isApiConfigured } from "../api/client.js";
8
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
- export function registerRemediationTools(server) {
10
- server.registerTool("propose_fix", {
11
- description: "Propose a fix for an issue. Creates a remediation record with baseline metrics for later evaluation. Include detailed diagnosis and code suggestions when possible.",
12
- inputSchema: z.object({
13
- issue_id: z.string().describe("The ID of the issue to fix"),
14
- diagnosis: z
15
- .string()
16
- .describe("Detailed analysis of the root cause of the issue"),
17
- proposed_fix: z
18
- .string()
19
- .describe("Description of the proposed fix and how it addresses the root cause"),
20
- code_snippet: z
21
- .string()
22
- .optional()
23
- .describe("Suggested code changes (if applicable)"),
24
- affected_files: z
25
- .array(z.string())
26
- .optional()
27
- .describe("List of files that need to be modified"),
28
- confidence: z
29
- .number()
30
- .min(0)
31
- .max(1)
32
- .describe("Confidence level in the fix (0-1). Use <0.7 when uncertain."),
33
- }),
34
- }, async ({ issue_id, diagnosis, proposed_fix, code_snippet, affected_files, confidence, }) => {
35
- if (!isApiConfigured()) {
36
- return {
37
- content: [
38
- {
39
- type: "text",
40
- text: JSON.stringify({ error: "API not configured" }),
41
- },
42
- ],
43
- isError: true,
44
- };
45
- }
46
- const { data, error } = await apiPost("/remediations", {
47
- issue_id,
48
- diagnosis,
49
- proposed_fix,
50
- code_snippet,
51
- affected_files,
52
- confidence,
53
- });
54
- if (error) {
55
- return {
56
- content: [{ type: "text", text: JSON.stringify({ error }) }],
57
- isError: true,
58
- };
59
- }
60
- return { content: [{ type: "text", text: JSON.stringify(data) }] };
61
- });
62
- server.registerTool("list_pending_fixes", {
63
- description: "List all proposed fixes awaiting deployment. Use to show the user what fixes are ready to be deployed.",
64
- inputSchema: z.object({}),
65
- }, async () => {
66
- if (!isApiConfigured()) {
67
- return {
68
- content: [
69
- {
70
- type: "text",
71
- text: JSON.stringify({ error: "API not configured" }),
72
- },
73
- ],
74
- isError: true,
75
- };
76
- }
77
- const { data, error } = await apiGet("/remediations/pending");
78
- if (error) {
79
- return {
80
- content: [{ type: "text", text: JSON.stringify({ error }) }],
81
- isError: true,
82
- };
83
- }
84
- return { content: [{ type: "text", text: JSON.stringify(data) }] };
85
- });
86
- server.registerTool("list_remediations", {
87
- description: "List remediation records with optional filters. Use to review past and current fix attempts.",
88
- inputSchema: z.object({
89
- status: z
90
- .enum([
91
- "proposed",
92
- "deployed",
93
- "evaluating",
94
- "succeeded",
95
- "failed",
96
- "reverted",
97
- ])
98
- .optional()
99
- .describe("Filter by remediation status"),
100
- issue_id: z.string().optional().describe("Filter by issue ID"),
101
- page_path: z.string().optional().describe("Filter by page path"),
102
- limit: z
103
- .number()
104
- .optional()
105
- .default(20)
106
- .describe("Maximum number of results (default: 20)"),
107
- }),
108
- }, async ({ status, issue_id, page_path, limit, }) => {
109
- if (!isApiConfigured()) {
110
- return {
111
- content: [
112
- {
113
- type: "text",
114
- text: JSON.stringify({ error: "API not configured" }),
115
- },
116
- ],
117
- isError: true,
118
- };
119
- }
120
- const { data, error } = await apiGet("/remediations", {
121
- status,
122
- issue_id,
123
- page_path,
124
- limit: limit ?? 20,
125
- });
126
- if (error) {
127
- return {
128
- content: [{ type: "text", text: JSON.stringify({ error }) }],
129
- isError: true,
130
- };
131
- }
132
- return { content: [{ type: "text", text: JSON.stringify(data) }] };
133
- });
134
- server.registerTool("confirm_deployment", {
135
- description: "Confirm that a proposed fix has been deployed to production. This starts the evaluation timer. Call this when the user confirms they have deployed the fix.",
136
- inputSchema: z.object({
137
- remediation_id: z
138
- .string()
139
- .describe("The ID of the remediation to mark as deployed"),
140
- }),
141
- }, async ({ remediation_id }) => {
142
- if (!isApiConfigured()) {
143
- return {
144
- content: [
145
- {
146
- type: "text",
147
- text: JSON.stringify({ error: "API not configured" }),
148
- },
149
- ],
150
- isError: true,
151
- };
152
- }
153
- const { data, error } = await apiPatch(`/remediations/${remediation_id}/deploy`, {});
154
- if (error) {
155
- return {
156
- content: [{ type: "text", text: JSON.stringify({ error }) }],
157
- isError: true,
158
- };
159
- }
160
- return { content: [{ type: "text", text: JSON.stringify(data) }] };
161
- });
162
- server.registerTool("evaluate_fix", {
163
- description: "Evaluate if a deployed fix improved metrics. Compares post-deployment metrics to baseline. Returns success/partial/failed outcome with detailed verdict. Wait at least 24 hours after deployment for reliable results.",
164
- inputSchema: z.object({
165
- remediation_id: z
166
- .string()
167
- .describe("The ID of the remediation to evaluate"),
168
- min_hours: z
169
- .number()
170
- .optional()
171
- .default(24)
172
- .describe("Minimum hours since deployment required (default: 24)"),
173
- }),
174
- }, async ({ remediation_id, min_hours, }) => {
175
- if (!isApiConfigured()) {
176
- return {
177
- content: [
178
- {
179
- type: "text",
180
- text: JSON.stringify({ error: "API not configured" }),
181
- },
182
- ],
183
- isError: true,
184
- };
185
- }
186
- const { data, error } = await apiPost(`/remediations/${remediation_id}/evaluate`, { min_hours: min_hours ?? 24 });
187
- if (error) {
188
- return {
189
- content: [{ type: "text", text: JSON.stringify({ error }) }],
190
- isError: true,
191
- };
192
- }
193
- return { content: [{ type: "text", text: JSON.stringify(data) }] };
194
- });
195
- server.registerTool("get_fix_history", {
196
- description: "Get the full remediation history for an issue. Shows all fix attempts, their outcomes, and current status. Use before proposing a new fix to learn from past attempts.",
197
- inputSchema: z.object({
198
- issue_id: z
199
- .string()
200
- .describe("The ID of the issue to get fix history for"),
201
- }),
202
- }, async ({ issue_id }) => {
203
- if (!isApiConfigured()) {
204
- return {
205
- content: [
206
- {
207
- type: "text",
208
- text: JSON.stringify({ error: "API not configured" }),
209
- },
210
- ],
211
- isError: true,
212
- };
213
- }
214
- const { data, error } = await apiGet(`/remediations/history/${issue_id}`);
215
- if (error) {
216
- return {
217
- content: [{ type: "text", text: JSON.stringify({ error }) }],
218
- isError: true,
219
- };
220
- }
221
- return { content: [{ type: "text", text: JSON.stringify(data) }] };
222
- });
223
- }
@@ -1,6 +0,0 @@
1
- /**
2
- * scan_site tool
3
- *
4
- * One-shot site health scan across all pages.
5
- */
6
- export declare function registerScanSite(server: any): void;
@@ -1,51 +0,0 @@
1
- /**
2
- * scan_site tool
3
- *
4
- * One-shot site health scan across all pages.
5
- */
6
- import { z } from "zod";
7
- import { apiGet, isApiConfigured } from "../api/client.js";
8
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
- export function registerScanSite(server) {
10
- server.registerTool("scan_site", {
11
- description: "One-shot site health scan. Lists all pages and computes aggregate metrics " +
12
- "for the top-N pages (default 10) sorted by session count. Returns a ranked " +
13
- "table with frustration and health grade per page. " +
14
- "Use this as the FIRST tool when the user asks a broad question without naming a specific page.",
15
- inputSchema: z.object({
16
- top_n: z
17
- .number()
18
- .optional()
19
- .default(10)
20
- .describe("Number of top pages to analyze (default 10)"),
21
- offset: z
22
- .number()
23
- .optional()
24
- .default(0)
25
- .describe("Skip first N pages for pagination (default 0)"),
26
- }),
27
- }, async ({ top_n, offset }) => {
28
- if (!isApiConfigured()) {
29
- return {
30
- content: [
31
- {
32
- type: "text",
33
- text: JSON.stringify({ error: "API not configured" }),
34
- },
35
- ],
36
- isError: true,
37
- };
38
- }
39
- const { data, error } = await apiGet("/site/overview", {
40
- top_n: top_n ?? 10,
41
- offset: offset ?? 0,
42
- });
43
- if (error) {
44
- return {
45
- content: [{ type: "text", text: JSON.stringify({ error }) }],
46
- isError: true,
47
- };
48
- }
49
- return { content: [{ type: "text", text: JSON.stringify(data) }] };
50
- });
51
- }
@@ -1,6 +0,0 @@
1
- /**
2
- * search_sessions tool
3
- *
4
- * Search sessions by natural language query using vector search.
5
- */
6
- export declare function registerSearchSessions(server: any): void;
@@ -1,51 +0,0 @@
1
- /**
2
- * search_sessions tool
3
- *
4
- * Search sessions by natural language query using vector search.
5
- */
6
- import { z } from "zod";
7
- import { apiPost, isApiConfigured } from "../api/client.js";
8
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
- export function registerSearchSessions(server) {
10
- server.registerTool("search_sessions", {
11
- description: 'Search sessions by natural language query. Examples: "frustrated users on checkout", "rage clicks on pricing page", "confused users who abandoned cart".',
12
- inputSchema: z.object({
13
- query: z
14
- .string()
15
- .describe("Natural language search query describing the sessions you want to find"),
16
- page_path: z
17
- .string()
18
- .optional()
19
- .describe("Optional: filter to a specific page path"),
20
- limit: z
21
- .number()
22
- .optional()
23
- .default(10)
24
- .describe("Maximum number of sessions to return (default: 10)"),
25
- }),
26
- }, async ({ query, page_path, limit, }) => {
27
- if (!isApiConfigured()) {
28
- return {
29
- content: [
30
- {
31
- type: "text",
32
- text: JSON.stringify({ error: "API not configured" }),
33
- },
34
- ],
35
- isError: true,
36
- };
37
- }
38
- const { data, error } = await apiPost("/sessions/search", {
39
- query,
40
- page_path,
41
- limit: limit ?? 10,
42
- });
43
- if (error) {
44
- return {
45
- content: [{ type: "text", text: JSON.stringify({ error }) }],
46
- isError: true,
47
- };
48
- }
49
- return { content: [{ type: "text", text: JSON.stringify(data) }] };
50
- });
51
- }
@@ -1,6 +0,0 @@
1
- /**
2
- * Triage tools for self-improvement workflow.
3
- *
4
- * Provides issue dismissal, marking intended behavior, and issue history.
5
- */
6
- export declare function registerTriageTools(server: any): void;
@@ -1,114 +0,0 @@
1
- /**
2
- * Triage tools for self-improvement workflow.
3
- *
4
- * Provides issue dismissal, marking intended behavior, and issue history.
5
- */
6
- import { z } from "zod";
7
- import { apiGet, apiPost, isApiConfigured } from "../api/client.js";
8
- const DISMISS_REASONS = [
9
- "stale",
10
- "intended",
11
- "duplicate",
12
- "false_positive",
13
- ];
14
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
- export function registerTriageTools(server) {
16
- server.registerTool("dismiss_issue", {
17
- description: "Dismiss an issue as a false positive. Creates site knowledge to prevent re-flagging. Use when an issue is stale, intended behavior, a duplicate, or a false positive. Always confirm with user before dismissing.",
18
- inputSchema: z.object({
19
- issue_id: z.string().describe("The ID of the issue to dismiss"),
20
- reason: z
21
- .enum(DISMISS_REASONS)
22
- .describe("Reason for dismissal: stale, intended, duplicate, or false_positive"),
23
- explanation: z
24
- .string()
25
- .describe("Detailed explanation of why this issue is being dismissed"),
26
- create_knowledge: z
27
- .boolean()
28
- .optional()
29
- .default(true)
30
- .describe("Whether to create site knowledge entry (default: true)"),
31
- }),
32
- }, async ({ issue_id, reason, explanation, create_knowledge, }) => {
33
- if (!isApiConfigured()) {
34
- return {
35
- content: [
36
- {
37
- type: "text",
38
- text: JSON.stringify({ error: "API not configured" }),
39
- },
40
- ],
41
- isError: true,
42
- };
43
- }
44
- const { data, error } = await apiPost(`/issues/${issue_id}/dismiss`, {
45
- reason,
46
- explanation,
47
- create_knowledge: create_knowledge ?? true,
48
- });
49
- if (error) {
50
- return {
51
- content: [{ type: "text", text: JSON.stringify({ error }) }],
52
- isError: true,
53
- };
54
- }
55
- return { content: [{ type: "text", text: JSON.stringify(data) }] };
56
- });
57
- server.registerTool("mark_intended_behavior", {
58
- description: "Mark an issue as intended behavior. This is a shortcut for dismissing with reason 'intended' and always creates site knowledge. Use when the detected behavior is by design (e.g., disabled button clicks are expected).",
59
- inputSchema: z.object({
60
- issue_id: z
61
- .string()
62
- .describe("The ID of the issue to mark as intended"),
63
- explanation: z
64
- .string()
65
- .describe("Explanation of why this behavior is intended"),
66
- }),
67
- }, async ({ issue_id, explanation, }) => {
68
- if (!isApiConfigured()) {
69
- return {
70
- content: [
71
- {
72
- type: "text",
73
- text: JSON.stringify({ error: "API not configured" }),
74
- },
75
- ],
76
- isError: true,
77
- };
78
- }
79
- const { data, error } = await apiPost(`/issues/${issue_id}/mark-intended`, { explanation });
80
- if (error) {
81
- return {
82
- content: [{ type: "text", text: JSON.stringify({ error }) }],
83
- isError: true,
84
- };
85
- }
86
- return { content: [{ type: "text", text: JSON.stringify(data) }] };
87
- });
88
- server.registerTool("get_issue_history", {
89
- description: "Get the full history of an issue including status changes, remediation attempts, and outcomes. Use to understand past fix attempts before proposing new ones.",
90
- inputSchema: z.object({
91
- issue_id: z.string().describe("The ID of the issue to get history for"),
92
- }),
93
- }, async ({ issue_id }) => {
94
- if (!isApiConfigured()) {
95
- return {
96
- content: [
97
- {
98
- type: "text",
99
- text: JSON.stringify({ error: "API not configured" }),
100
- },
101
- ],
102
- isError: true,
103
- };
104
- }
105
- const { data, error } = await apiGet(`/issues/${issue_id}/history`);
106
- if (error) {
107
- return {
108
- content: [{ type: "text", text: JSON.stringify({ error }) }],
109
- isError: true,
110
- };
111
- }
112
- return { content: [{ type: "text", text: JSON.stringify(data) }] };
113
- });
114
- }
@@ -1,8 +0,0 @@
1
- /**
2
- * triage_sessions tool
3
- *
4
- * Automatically triages sessions to find compromised user experiences.
5
- * Analyzes user comments, frustration signals, rage clicks, and console errors.
6
- * Thin proxy to external-api /sessions/triage endpoint.
7
- */
8
- export declare function registerTriageSessions(server: any): void;
@@ -1,197 +0,0 @@
1
- /**
2
- * triage_sessions tool
3
- *
4
- * Automatically triages sessions to find compromised user experiences.
5
- * Analyzes user comments, frustration signals, rage clicks, and console errors.
6
- * Thin proxy to external-api /sessions/triage endpoint.
7
- */
8
- import { z } from "zod";
9
- import { apiGet, isApiConfigured } from "../api/client.js";
10
- function formatDuration(seconds) {
11
- if (!seconds)
12
- return "unknown";
13
- if (seconds < 60)
14
- return `${seconds}s`;
15
- if (seconds < 3600)
16
- return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
17
- const hours = Math.floor(seconds / 3600);
18
- const mins = Math.floor((seconds % 3600) / 60);
19
- return `${hours}h ${mins}m`;
20
- }
21
- function getActionReason(session) {
22
- const reasons = [];
23
- if (session.user_comments.length > 0) {
24
- reasons.push(`USER FEEDBACK: ${session.user_comments.length} comment(s) - "${session.user_comments[0].text.slice(0, 100)}${session.user_comments[0].text.length > 100 ? "..." : ""}"`);
25
- }
26
- if (session.behavioral_signals.frustration >= 0.5) {
27
- reasons.push(`HIGH FRUSTRATION: ${(session.behavioral_signals.frustration * 100).toFixed(0)}%`);
28
- }
29
- else if (session.behavioral_signals.frustration >= 0.3) {
30
- reasons.push(`MODERATE FRUSTRATION: ${(session.behavioral_signals.frustration * 100).toFixed(0)}%`);
31
- }
32
- if (session.behavioral_signals.has_rage_clicks) {
33
- reasons.push("RAGE CLICKS detected");
34
- }
35
- if (session.console_errors.length > 0) {
36
- const errorCount = session.console_errors.reduce((sum, e) => sum + e.count, 0);
37
- reasons.push(`JS ERRORS: ${errorCount} error(s) - "${session.console_errors[0].message.slice(0, 80)}..."`);
38
- }
39
- if (!session.behavioral_signals.has_behavioral_data) {
40
- reasons.push("NOTE: No behavioral analysis data available for this session");
41
- }
42
- if (reasons.length === 0) {
43
- reasons.push("Low severity - no major issues detected");
44
- }
45
- return reasons.join("\n - ");
46
- }
47
- function formatTriageOutput(data) {
48
- const lines = [];
49
- // Summary
50
- lines.push("# SESSION TRIAGE RESULTS\n");
51
- lines.push(`Total sessions analyzed: ${data.summary.total_sessions}`);
52
- lines.push(`Sessions with issues: ${data.summary.flagged_sessions}`);
53
- lines.push(`Sessions with user comments: ${data.summary.sessions_with_comments}`);
54
- if (data.sessions.length === 0) {
55
- lines.push("\nNo sessions require attention.");
56
- return lines.join("\n");
57
- }
58
- // Group by severity
59
- const critical = data.sessions.filter((s) => s.severity === "critical");
60
- const high = data.sessions.filter((s) => s.severity === "high");
61
- const medium = data.sessions.filter((s) => s.severity === "medium");
62
- const low = data.sessions.filter((s) => s.severity === "low");
63
- lines.push("\n## PRIORITY SUMMARY");
64
- lines.push(`- CRITICAL: ${critical.length} session(s) - investigate immediately`);
65
- lines.push(`- HIGH: ${high.length} session(s) - investigate soon`);
66
- lines.push(`- MEDIUM: ${medium.length} session(s) - review when possible`);
67
- lines.push(`- LOW: ${low.length} session(s) - likely okay`);
68
- // Action recommendations
69
- lines.push("\n## RECOMMENDED ACTIONS\n");
70
- if (critical.length > 0) {
71
- lines.push("### CRITICAL - Investigate Immediately\n");
72
- for (const s of critical) {
73
- lines.push(`**Session ${s.session_id.slice(-8)}** (${formatDuration(s.duration_seconds)}, ${s.device})`);
74
- lines.push(` Replay: ${s.replay_url}`);
75
- lines.push(` Score: ${(s.triage_score * 100).toFixed(0)}%`);
76
- lines.push(` Why: ${getActionReason(s)}`);
77
- if (s.pages_visited.length > 0) {
78
- lines.push(` Pages: ${s.pages_visited.slice(0, 3).join(", ")}${s.pages_visited.length > 3 ? ` (+${s.pages_visited.length - 3} more)` : ""}`);
79
- }
80
- lines.push("");
81
- }
82
- }
83
- if (high.length > 0) {
84
- lines.push("### HIGH - Investigate Soon\n");
85
- for (const s of high) {
86
- lines.push(`**Session ${s.session_id.slice(-8)}** (${formatDuration(s.duration_seconds)}, ${s.device})`);
87
- lines.push(` Replay: ${s.replay_url}`);
88
- lines.push(` Score: ${(s.triage_score * 100).toFixed(0)}%`);
89
- lines.push(` Why: ${getActionReason(s)}`);
90
- if (s.pages_visited.length > 0) {
91
- lines.push(` Pages: ${s.pages_visited.slice(0, 3).join(", ")}${s.pages_visited.length > 3 ? ` (+${s.pages_visited.length - 3} more)` : ""}`);
92
- }
93
- lines.push("");
94
- }
95
- }
96
- if (medium.length > 0) {
97
- lines.push("### MEDIUM - Review When Possible\n");
98
- for (const s of medium) {
99
- lines.push(`- Session ${s.session_id.slice(-8)} (${formatDuration(s.duration_seconds)}): ${getActionReason(s).split("\n")[0]}`);
100
- lines.push(` ${s.replay_url}`);
101
- }
102
- lines.push("");
103
- }
104
- if (low.length > 0) {
105
- lines.push("### LOW - Likely Okay\n");
106
- lines.push(`${low.length} session(s) with minor or no issues detected.`);
107
- if (low.length <= 3) {
108
- for (const s of low) {
109
- lines.push(`- Session ${s.session_id.slice(-8)}: ${s.replay_url}`);
110
- }
111
- }
112
- lines.push("");
113
- }
114
- // Raw data for reference (compact)
115
- lines.push("\n## RAW DATA (for detailed analysis)\n");
116
- lines.push("```json");
117
- lines.push(JSON.stringify({
118
- summary: data.summary,
119
- sessions: data.sessions.map((s) => ({
120
- id: s.session_id,
121
- severity: s.severity,
122
- score: s.triage_score,
123
- url: s.replay_url,
124
- comments: s.user_comments.length,
125
- frustration: s.behavioral_signals.frustration,
126
- rage_clicks: s.behavioral_signals.has_rage_clicks,
127
- errors: s.console_errors.length,
128
- has_data: s.behavioral_signals.has_behavioral_data,
129
- })),
130
- }, null, 2));
131
- lines.push("```");
132
- return lines.join("\n");
133
- }
134
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
135
- export function registerTriageSessions(server) {
136
- server.registerTool("triage_sessions", {
137
- description: "Automatically triage sessions to find compromised user experiences. " +
138
- "Analyzes user comments, frustration signals, rage clicks, and console errors. " +
139
- "Returns flagged sessions with evidence and replay links. Use this to identify " +
140
- "sessions that need attention without manually reviewing every recording. " +
141
- "Can triage specific sessions by ID(s) or scan for problematic sessions. " +
142
- "NOTE: Session replay URLs require a paid plan (Starter+). Free tier users " +
143
- "can see session summaries and triage scores but not watch replays.",
144
- inputSchema: z.object({
145
- session_ids: z
146
- .array(z.string())
147
- .optional()
148
- .describe("Triage specific sessions by ID. If provided, other filters are ignored."),
149
- days: z
150
- .number()
151
- .optional()
152
- .default(7)
153
- .describe("Lookback period in days (default: 7). Ignored if session_ids is provided."),
154
- page_path: z
155
- .string()
156
- .optional()
157
- .describe("Filter to sessions that visited a specific page"),
158
- min_severity: z
159
- .enum(["critical", "high", "medium", "low"])
160
- .optional()
161
- .describe("Minimum severity to include in results"),
162
- limit: z
163
- .number()
164
- .optional()
165
- .default(20)
166
- .describe("Maximum sessions to return (default: 20, max: 100)"),
167
- }),
168
- }, async ({ session_ids, days, page_path, min_severity, limit, }) => {
169
- if (!isApiConfigured()) {
170
- return {
171
- content: [
172
- {
173
- type: "text",
174
- text: JSON.stringify({ error: "API not configured" }),
175
- },
176
- ],
177
- isError: true,
178
- };
179
- }
180
- const { data, error } = await apiGet("/sessions/triage", {
181
- session_ids: session_ids?.join(","),
182
- days: session_ids?.length ? undefined : (days ?? 7),
183
- page_path: session_ids?.length ? undefined : page_path,
184
- min_severity,
185
- limit: session_ids?.length ? session_ids.length : (limit ?? 20),
186
- });
187
- if (error) {
188
- return {
189
- content: [{ type: "text", text: JSON.stringify({ error }) }],
190
- isError: true,
191
- };
192
- }
193
- // Format output for better LLM comprehension
194
- const formattedOutput = formatTriageOutput(data);
195
- return { content: [{ type: "text", text: formattedOutput }] };
196
- });
197
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * get_upgrade_options tool
3
- *
4
- * Provides upgrade information for AI agents to communicate upgrade paths to users.
5
- * Part of the "Diagnose Free, Solve Paid" pattern.
6
- */
7
- export declare function registerGetUpgradeOptions(server: any): void;