firebase-tools 14.16.0 → 14.17.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/lib/crashlytics/{listNotes.js → events.js} +11 -9
- package/lib/crashlytics/filters.js +77 -0
- package/lib/crashlytics/issues.js +50 -0
- package/lib/crashlytics/notes.js +67 -0
- package/lib/crashlytics/reports.js +47 -0
- package/lib/crashlytics/types.js +60 -0
- package/lib/deploy/apphosting/deploy.js +2 -1
- package/lib/deploy/apphosting/util.js +5 -8
- package/lib/emulator/apphosting/developmentServer.js +3 -3
- package/lib/emulator/apphosting/serve.js +29 -29
- package/lib/emulator/initEmulators.js +1 -1
- package/lib/init/features/dataconnect/index.js +29 -4
- package/lib/init/features/dataconnect/sdk.js +17 -12
- package/lib/mcp/tools/crashlytics/events.js +42 -0
- package/lib/mcp/tools/crashlytics/index.js +16 -20
- package/lib/mcp/tools/crashlytics/issues.js +56 -0
- package/lib/mcp/tools/crashlytics/notes.js +78 -0
- package/lib/mcp/tools/crashlytics/reports.js +100 -0
- package/package.json +1 -1
- package/lib/crashlytics/addNote.js +0 -27
- package/lib/crashlytics/deleteNote.js +0 -23
- package/lib/crashlytics/getIssueDetails.js +0 -26
- package/lib/crashlytics/getSampleCrash.js +0 -34
- package/lib/crashlytics/listTopDevices.js +0 -33
- package/lib/crashlytics/listTopIssues.js +0 -30
- package/lib/crashlytics/listTopOperatingSystems.js +0 -32
- package/lib/crashlytics/listTopVersions.js +0 -32
- package/lib/crashlytics/updateIssue.js +0 -35
- package/lib/mcp/tools/crashlytics/add_note.js +0 -32
- package/lib/mcp/tools/crashlytics/constants.js +0 -11
- package/lib/mcp/tools/crashlytics/delete_note.js +0 -35
- package/lib/mcp/tools/crashlytics/get_issue_details.js +0 -31
- package/lib/mcp/tools/crashlytics/get_sample_crash.js +0 -43
- package/lib/mcp/tools/crashlytics/list_notes.js +0 -37
- package/lib/mcp/tools/crashlytics/list_top_devices.js +0 -33
- package/lib/mcp/tools/crashlytics/list_top_issues.js +0 -38
- package/lib/mcp/tools/crashlytics/list_top_operating_systems.js +0 -33
- package/lib/mcp/tools/crashlytics/list_top_versions.js +0 -33
- package/lib/mcp/tools/crashlytics/update_issue.js +0 -37
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.list_events = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_1 = require("../../tool");
|
|
6
|
+
const util_1 = require("../../util");
|
|
7
|
+
const events_1 = require("../../../crashlytics/events");
|
|
8
|
+
const types_1 = require("../../../crashlytics/types");
|
|
9
|
+
const filters_1 = require("../../../crashlytics/filters");
|
|
10
|
+
function pruneThreads(sample) {
|
|
11
|
+
var _a, _b, _c;
|
|
12
|
+
if (((_a = sample.issue) === null || _a === void 0 ? void 0 : _a.errorType) === types_1.ErrorType.FATAL || ((_b = sample.issue) === null || _b === void 0 ? void 0 : _b.errorType) === types_1.ErrorType.ANR) {
|
|
13
|
+
sample.threads = (_c = sample.threads) === null || _c === void 0 ? void 0 : _c.filter((t) => t.crashed || t.blamed);
|
|
14
|
+
}
|
|
15
|
+
return sample;
|
|
16
|
+
}
|
|
17
|
+
exports.list_events = (0, tool_1.tool)({
|
|
18
|
+
name: "list_events",
|
|
19
|
+
description: `Lists the most recent events matching the given filters.
|
|
20
|
+
Can be used to fetch sample crashes and exceptions for an issue,
|
|
21
|
+
which will include stack traces and other data useful for debugging.`,
|
|
22
|
+
inputSchema: zod_1.z.object({
|
|
23
|
+
appId: filters_1.ApplicationIdSchema,
|
|
24
|
+
filter: filters_1.EventFilterSchema,
|
|
25
|
+
pageSize: zod_1.z.number().describe("Number of rows to return").default(1),
|
|
26
|
+
}),
|
|
27
|
+
annotations: {
|
|
28
|
+
title: "List Crashlytics Events",
|
|
29
|
+
readOnlyHint: true,
|
|
30
|
+
},
|
|
31
|
+
_meta: {
|
|
32
|
+
requiresAuth: true,
|
|
33
|
+
},
|
|
34
|
+
}, async ({ appId, filter, pageSize }) => {
|
|
35
|
+
if (!appId)
|
|
36
|
+
return (0, util_1.mcpError)(`Must specify 'appId' parameter.`);
|
|
37
|
+
if (!filter || !filter.issueId)
|
|
38
|
+
return (0, util_1.mcpError)(`Must specify 'issue_id' parameter.`);
|
|
39
|
+
const samples = await (0, events_1.listEvents)(appId, filter, pageSize);
|
|
40
|
+
samples.events = samples.events.map((e) => pruneThreads(e));
|
|
41
|
+
return (0, util_1.toContent)(samples);
|
|
42
|
+
});
|
|
@@ -1,25 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.crashlyticsTools = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const list_notes_1 = require("./list_notes");
|
|
9
|
-
const list_top_devices_1 = require("./list_top_devices");
|
|
10
|
-
const list_top_issues_1 = require("./list_top_issues");
|
|
11
|
-
const list_top_operating_systems_1 = require("./list_top_operating_systems");
|
|
12
|
-
const list_top_versions_1 = require("./list_top_versions");
|
|
13
|
-
const update_issue_1 = require("./update_issue");
|
|
4
|
+
const notes_1 = require("./notes");
|
|
5
|
+
const issues_1 = require("./issues");
|
|
6
|
+
const events_1 = require("./events");
|
|
7
|
+
const reports_1 = require("./reports");
|
|
14
8
|
exports.crashlyticsTools = [
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
9
|
+
notes_1.create_note,
|
|
10
|
+
notes_1.delete_note,
|
|
11
|
+
issues_1.get_issue,
|
|
12
|
+
events_1.list_events,
|
|
13
|
+
notes_1.list_notes,
|
|
14
|
+
reports_1.get_top_issues,
|
|
15
|
+
reports_1.get_top_variants,
|
|
16
|
+
reports_1.get_top_versions,
|
|
17
|
+
reports_1.get_top_apple_devices,
|
|
18
|
+
reports_1.get_top_android_devices,
|
|
19
|
+
reports_1.get_top_operating_systems,
|
|
20
|
+
issues_1.update_issue,
|
|
25
21
|
];
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.update_issue = exports.get_issue = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_1 = require("../../tool");
|
|
6
|
+
const util_1 = require("../../util");
|
|
7
|
+
const issues_1 = require("../../../crashlytics/issues");
|
|
8
|
+
const types_1 = require("../../../crashlytics/types");
|
|
9
|
+
const filters_1 = require("../../../crashlytics/filters");
|
|
10
|
+
exports.get_issue = (0, tool_1.tool)({
|
|
11
|
+
name: "get_issue",
|
|
12
|
+
description: `Gets data for a Crashlytics issue, which can be used as a starting point for debugging.`,
|
|
13
|
+
inputSchema: zod_1.z.object({
|
|
14
|
+
appId: filters_1.ApplicationIdSchema,
|
|
15
|
+
issueId: filters_1.IssueIdSchema,
|
|
16
|
+
}),
|
|
17
|
+
annotations: {
|
|
18
|
+
title: "Get Crashlytics Issue Details",
|
|
19
|
+
readOnlyHint: true,
|
|
20
|
+
},
|
|
21
|
+
_meta: {
|
|
22
|
+
requiresAuth: true,
|
|
23
|
+
},
|
|
24
|
+
}, async ({ appId, issueId }) => {
|
|
25
|
+
if (!appId)
|
|
26
|
+
return (0, util_1.mcpError)(`Must specify 'appId' parameter.`);
|
|
27
|
+
if (!issueId)
|
|
28
|
+
return (0, util_1.mcpError)(`Must specify 'issueId' parameter.`);
|
|
29
|
+
return (0, util_1.toContent)(await (0, issues_1.getIssue)(appId, issueId));
|
|
30
|
+
});
|
|
31
|
+
exports.update_issue = (0, tool_1.tool)({
|
|
32
|
+
name: "update_issue",
|
|
33
|
+
description: "Update the state of Crashlytics issue.",
|
|
34
|
+
inputSchema: zod_1.z.object({
|
|
35
|
+
appId: filters_1.ApplicationIdSchema,
|
|
36
|
+
issueId: filters_1.IssueIdSchema,
|
|
37
|
+
state: zod_1.z
|
|
38
|
+
.nativeEnum(types_1.State)
|
|
39
|
+
.describe("The new state for the issue. Can be 'OPEN' or 'CLOSED'."),
|
|
40
|
+
}),
|
|
41
|
+
annotations: {
|
|
42
|
+
title: "Update Crashlytics Issue",
|
|
43
|
+
readOnlyHint: false,
|
|
44
|
+
},
|
|
45
|
+
_meta: {
|
|
46
|
+
requiresAuth: true,
|
|
47
|
+
},
|
|
48
|
+
}, async ({ appId, issueId, state }) => {
|
|
49
|
+
if (!appId)
|
|
50
|
+
return (0, util_1.mcpError)(`Must specify 'app_id' parameter.`);
|
|
51
|
+
if (!issueId)
|
|
52
|
+
return (0, util_1.mcpError)(`Must specify 'issue_id' parameter.`);
|
|
53
|
+
if (!state)
|
|
54
|
+
return (0, util_1.mcpError)(`Must specify 'state' parameter.`);
|
|
55
|
+
return (0, util_1.toContent)(await (0, issues_1.updateIssue)(appId, issueId, state));
|
|
56
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.delete_note = exports.list_notes = exports.create_note = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const tool_1 = require("../../tool");
|
|
6
|
+
const util_1 = require("../../util");
|
|
7
|
+
const notes_1 = require("../../../crashlytics/notes");
|
|
8
|
+
const filters_1 = require("../../../crashlytics/filters");
|
|
9
|
+
exports.create_note = (0, tool_1.tool)({
|
|
10
|
+
name: "create_note",
|
|
11
|
+
description: "Add a note to an issue from crashlytics.",
|
|
12
|
+
inputSchema: zod_1.z.object({
|
|
13
|
+
appId: filters_1.ApplicationIdSchema,
|
|
14
|
+
issueId: filters_1.IssueIdSchema,
|
|
15
|
+
note: zod_1.z.string().describe("The note to add to the issue."),
|
|
16
|
+
}),
|
|
17
|
+
annotations: {
|
|
18
|
+
title: "Add note to Crashlytics issue.",
|
|
19
|
+
readOnlyHint: false,
|
|
20
|
+
},
|
|
21
|
+
_meta: {
|
|
22
|
+
requiresAuth: true,
|
|
23
|
+
},
|
|
24
|
+
}, async ({ appId, issueId, note }) => {
|
|
25
|
+
if (!appId)
|
|
26
|
+
return (0, util_1.mcpError)(`Must specify 'appId' parameter.`);
|
|
27
|
+
if (!issueId)
|
|
28
|
+
return (0, util_1.mcpError)(`Must specify 'issueId' parameter.`);
|
|
29
|
+
if (!note)
|
|
30
|
+
return (0, util_1.mcpError)(`Must specify 'note' parameter.`);
|
|
31
|
+
return (0, util_1.toContent)(await (0, notes_1.createNote)(appId, issueId, note));
|
|
32
|
+
});
|
|
33
|
+
exports.list_notes = (0, tool_1.tool)({
|
|
34
|
+
name: "list_notes",
|
|
35
|
+
description: "List all notes for an issue in Crashlytics.",
|
|
36
|
+
inputSchema: zod_1.z.object({
|
|
37
|
+
appId: filters_1.ApplicationIdSchema,
|
|
38
|
+
issueId: filters_1.IssueIdSchema,
|
|
39
|
+
pageSize: zod_1.z.number().optional().default(20).describe("Number of rows to return"),
|
|
40
|
+
}),
|
|
41
|
+
annotations: {
|
|
42
|
+
title: "List notes for a Crashlytics issue.",
|
|
43
|
+
readOnlyHint: true,
|
|
44
|
+
},
|
|
45
|
+
_meta: {
|
|
46
|
+
requiresAuth: true,
|
|
47
|
+
},
|
|
48
|
+
}, async ({ appId, issueId, pageSize }) => {
|
|
49
|
+
if (!appId)
|
|
50
|
+
return (0, util_1.mcpError)(`Must specify 'appId' parameter.`);
|
|
51
|
+
if (!issueId)
|
|
52
|
+
return (0, util_1.mcpError)(`Must specify 'issueId' parameter.`);
|
|
53
|
+
return (0, util_1.toContent)(await (0, notes_1.listNotes)(appId, issueId, pageSize));
|
|
54
|
+
});
|
|
55
|
+
exports.delete_note = (0, tool_1.tool)({
|
|
56
|
+
name: "delete_note",
|
|
57
|
+
description: "Delete a note from a Crashlytics issue.",
|
|
58
|
+
inputSchema: zod_1.z.object({
|
|
59
|
+
appId: filters_1.ApplicationIdSchema,
|
|
60
|
+
issueId: filters_1.IssueIdSchema,
|
|
61
|
+
noteId: zod_1.z.string().describe("The id of the note to delete"),
|
|
62
|
+
}),
|
|
63
|
+
annotations: {
|
|
64
|
+
title: "Delete Crashlytics Issue Note",
|
|
65
|
+
readOnlyHint: true,
|
|
66
|
+
},
|
|
67
|
+
_meta: {
|
|
68
|
+
requiresAuth: true,
|
|
69
|
+
},
|
|
70
|
+
}, async ({ appId, issueId, noteId }) => {
|
|
71
|
+
if (!appId)
|
|
72
|
+
return (0, util_1.mcpError)(`Must specify 'appId' parameter.`);
|
|
73
|
+
if (!issueId)
|
|
74
|
+
return (0, util_1.mcpError)(`Must specify 'issueId' parameter.`);
|
|
75
|
+
if (!noteId)
|
|
76
|
+
return (0, util_1.mcpError)(`Must specify 'noteId' parameter.`);
|
|
77
|
+
return (0, util_1.toContent)(await (0, notes_1.deleteNote)(appId, issueId, noteId));
|
|
78
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get_top_operating_systems = exports.get_top_android_devices = exports.get_top_apple_devices = exports.get_top_versions = exports.get_top_variants = exports.get_top_issues = void 0;
|
|
4
|
+
const tool_1 = require("../../tool");
|
|
5
|
+
const util_1 = require("../../util");
|
|
6
|
+
const reports_1 = require("../../../crashlytics/reports");
|
|
7
|
+
function getReportContent(report) {
|
|
8
|
+
return async ({ appId, filter, pageSize }) => {
|
|
9
|
+
if (!appId)
|
|
10
|
+
return (0, util_1.mcpError)(`Must specify 'appId' parameter.`);
|
|
11
|
+
filter !== null && filter !== void 0 ? filter : (filter = {});
|
|
12
|
+
return (0, util_1.toContent)(await (0, reports_1.getReport)(report, appId, filter, pageSize));
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
exports.get_top_issues = (0, tool_1.tool)({
|
|
16
|
+
name: "get_top_issues",
|
|
17
|
+
description: `Counts events and distinct impacted users, grouped by *issue*.
|
|
18
|
+
Groups are sorted by event count, in descending order.
|
|
19
|
+
Only counts events matching the given filters.`,
|
|
20
|
+
inputSchema: reports_1.ReportInputSchema,
|
|
21
|
+
annotations: {
|
|
22
|
+
title: "Get Crashlytics Top Issues Report",
|
|
23
|
+
readOnlyHint: true,
|
|
24
|
+
},
|
|
25
|
+
_meta: {
|
|
26
|
+
requiresAuth: true,
|
|
27
|
+
},
|
|
28
|
+
}, getReportContent(reports_1.CrashlyticsReport.TopIssues));
|
|
29
|
+
exports.get_top_variants = (0, tool_1.tool)({
|
|
30
|
+
name: "get_top_variants",
|
|
31
|
+
description: `Counts events and distinct impacted users, grouped by issue *variant*.
|
|
32
|
+
Groups are sorted by event count, in descending order.
|
|
33
|
+
Only counts events matching the given filters.`,
|
|
34
|
+
inputSchema: reports_1.ReportInputSchema,
|
|
35
|
+
annotations: {
|
|
36
|
+
title: "Get Crashlytics Top Variants Report",
|
|
37
|
+
readOnlyHint: true,
|
|
38
|
+
},
|
|
39
|
+
_meta: {
|
|
40
|
+
requiresAuth: true,
|
|
41
|
+
},
|
|
42
|
+
}, getReportContent(reports_1.CrashlyticsReport.TopVariants));
|
|
43
|
+
exports.get_top_versions = (0, tool_1.tool)({
|
|
44
|
+
name: "get_top_versions",
|
|
45
|
+
description: `Counts events and distinct impacted users, grouped by *version*.
|
|
46
|
+
Groups are sorted by event count, in descending order.
|
|
47
|
+
Only counts events matching the given filters.`,
|
|
48
|
+
inputSchema: reports_1.ReportInputSchema,
|
|
49
|
+
annotations: {
|
|
50
|
+
title: "Get Crashlytics Top Versions Report",
|
|
51
|
+
readOnlyHint: true,
|
|
52
|
+
},
|
|
53
|
+
_meta: {
|
|
54
|
+
requiresAuth: true,
|
|
55
|
+
},
|
|
56
|
+
}, getReportContent(reports_1.CrashlyticsReport.TopVersions));
|
|
57
|
+
exports.get_top_apple_devices = (0, tool_1.tool)({
|
|
58
|
+
name: "get_top_apple_devices",
|
|
59
|
+
description: `Counts events and distinct impacted users, grouped by apple *device*.
|
|
60
|
+
Groups are sorted by event count, in descending order.
|
|
61
|
+
Only counts events matching the given filters.
|
|
62
|
+
Only relevant for iOS, iPadOS and MacOS applications.`,
|
|
63
|
+
inputSchema: reports_1.ReportInputSchema,
|
|
64
|
+
annotations: {
|
|
65
|
+
title: "Get Crashlytics Top Apple Devices Report",
|
|
66
|
+
readOnlyHint: true,
|
|
67
|
+
},
|
|
68
|
+
_meta: {
|
|
69
|
+
requiresAuth: true,
|
|
70
|
+
},
|
|
71
|
+
}, getReportContent(reports_1.CrashlyticsReport.TopAppleDevices));
|
|
72
|
+
exports.get_top_android_devices = (0, tool_1.tool)({
|
|
73
|
+
name: "get_top_android_devices",
|
|
74
|
+
description: `Counts events and distinct impacted users, grouped by android *device*.
|
|
75
|
+
Groups are sorted by event count, in descending order.
|
|
76
|
+
Only counts events matching the given filters.
|
|
77
|
+
Only relevant for Android applications.`,
|
|
78
|
+
inputSchema: reports_1.ReportInputSchema,
|
|
79
|
+
annotations: {
|
|
80
|
+
title: "Get Crashlytics Top Android Devices Report",
|
|
81
|
+
readOnlyHint: true,
|
|
82
|
+
},
|
|
83
|
+
_meta: {
|
|
84
|
+
requiresAuth: true,
|
|
85
|
+
},
|
|
86
|
+
}, getReportContent(reports_1.CrashlyticsReport.TopAndroidDevices));
|
|
87
|
+
exports.get_top_operating_systems = (0, tool_1.tool)({
|
|
88
|
+
name: "get_top_operating_systems",
|
|
89
|
+
description: `Counts events and distinct impacted users, grouped by *operating system*.
|
|
90
|
+
Groups are sorted by event count, in descending order.
|
|
91
|
+
Only counts events matching the given filters.`,
|
|
92
|
+
inputSchema: reports_1.ReportInputSchema,
|
|
93
|
+
annotations: {
|
|
94
|
+
title: "Get Crashlytics Top Operating Systems Report",
|
|
95
|
+
readOnlyHint: true,
|
|
96
|
+
},
|
|
97
|
+
_meta: {
|
|
98
|
+
requiresAuth: true,
|
|
99
|
+
},
|
|
100
|
+
}, getReportContent(reports_1.CrashlyticsReport.TopOperatingSystems));
|
package/package.json
CHANGED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.addNote = void 0;
|
|
4
|
-
const logger_1 = require("../logger");
|
|
5
|
-
const error_1 = require("../error");
|
|
6
|
-
const utils_1 = require("./utils");
|
|
7
|
-
async function addNote(appId, issueId, note) {
|
|
8
|
-
const requestProjectNumber = (0, utils_1.parseProjectNumber)(appId);
|
|
9
|
-
logger_1.logger.debug(`[mcp][crashlytics] addNote called with appId: ${appId}, issueId: ${issueId}, note: ${note}`);
|
|
10
|
-
try {
|
|
11
|
-
const response = await utils_1.CRASHLYTICS_API_CLIENT.request({
|
|
12
|
-
method: "POST",
|
|
13
|
-
headers: {
|
|
14
|
-
"Content-Type": "application/json",
|
|
15
|
-
},
|
|
16
|
-
path: `/projects/${requestProjectNumber}/apps/${appId}/issues/${issueId}/notes`,
|
|
17
|
-
body: { body: note },
|
|
18
|
-
timeout: utils_1.TIMEOUT,
|
|
19
|
-
});
|
|
20
|
-
return response.body;
|
|
21
|
-
}
|
|
22
|
-
catch (err) {
|
|
23
|
-
logger_1.logger.debug(err.message);
|
|
24
|
-
throw new error_1.FirebaseError(`Failed to add note to issue ${issueId} for app ${appId}. Error: ${err}.`, { original: err });
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
exports.addNote = addNote;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deleteNote = void 0;
|
|
4
|
-
const logger_1 = require("../logger");
|
|
5
|
-
const error_1 = require("../error");
|
|
6
|
-
const utils_1 = require("./utils");
|
|
7
|
-
async function deleteNote(appId, issueId, noteId) {
|
|
8
|
-
const requestProjectNumber = (0, utils_1.parseProjectNumber)(appId);
|
|
9
|
-
logger_1.logger.debug(`[mcp][crashlytics] deleteNote called with appId: ${appId}, issueId: ${issueId}, noteId: ${noteId}`);
|
|
10
|
-
try {
|
|
11
|
-
await utils_1.CRASHLYTICS_API_CLIENT.request({
|
|
12
|
-
method: "DELETE",
|
|
13
|
-
path: `/projects/${requestProjectNumber}/apps/${appId}/issues/${issueId}/notes/${noteId}`,
|
|
14
|
-
timeout: utils_1.TIMEOUT,
|
|
15
|
-
});
|
|
16
|
-
return `Successfully deleted note ${noteId} from issue ${issueId}.`;
|
|
17
|
-
}
|
|
18
|
-
catch (err) {
|
|
19
|
-
logger_1.logger.debug(err.message);
|
|
20
|
-
throw new error_1.FirebaseError(`Failed to delete note ${noteId} from issue ${issueId} for app ${appId}. Error: ${err}.`, { original: err });
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
exports.deleteNote = deleteNote;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getIssueDetails = void 0;
|
|
4
|
-
const logger_1 = require("../logger");
|
|
5
|
-
const error_1 = require("../error");
|
|
6
|
-
const utils_1 = require("./utils");
|
|
7
|
-
async function getIssueDetails(appId, issueId) {
|
|
8
|
-
const requestProjectNumber = (0, utils_1.parseProjectNumber)(appId);
|
|
9
|
-
logger_1.logger.debug(`[mcp][crashlytics] getIssueDetails called with appId: ${appId}, issueId: ${issueId}`);
|
|
10
|
-
try {
|
|
11
|
-
const response = await utils_1.CRASHLYTICS_API_CLIENT.request({
|
|
12
|
-
method: "GET",
|
|
13
|
-
headers: {
|
|
14
|
-
"Content-Type": "application/json",
|
|
15
|
-
},
|
|
16
|
-
path: `/projects/${requestProjectNumber}/apps/${appId}/issues/${issueId}`,
|
|
17
|
-
timeout: utils_1.TIMEOUT,
|
|
18
|
-
});
|
|
19
|
-
return response.body;
|
|
20
|
-
}
|
|
21
|
-
catch (err) {
|
|
22
|
-
logger_1.logger.debug(err.message);
|
|
23
|
-
throw new error_1.FirebaseError(`Failed to fetch the issue details for the Firebase AppId ${appId}, IssueId ${issueId}. Error: ${err}.`, { original: err });
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
exports.getIssueDetails = getIssueDetails;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getSampleCrash = void 0;
|
|
4
|
-
const logger_1 = require("../logger");
|
|
5
|
-
const error_1 = require("../error");
|
|
6
|
-
const utils_1 = require("./utils");
|
|
7
|
-
async function getSampleCrash(appId, issueId, sampleCount, variantId) {
|
|
8
|
-
const requestProjectNumber = (0, utils_1.parseProjectNumber)(appId);
|
|
9
|
-
logger_1.logger.debug(`[mcp][crashlytics] getSampleCrash called with appId: ${appId}, issueId: ${issueId}, sampleCount: ${sampleCount}, variantId: ${variantId}`);
|
|
10
|
-
try {
|
|
11
|
-
const queryParams = new URLSearchParams();
|
|
12
|
-
queryParams.set("filter.issue.id", issueId);
|
|
13
|
-
queryParams.set("page_size", String(sampleCount));
|
|
14
|
-
if (variantId) {
|
|
15
|
-
queryParams.set("filter.issue.variant_id", variantId);
|
|
16
|
-
}
|
|
17
|
-
logger_1.logger.debug(`[mcp][crashlytics] getSampleCrash query paramaters: ${queryParams}`);
|
|
18
|
-
const response = await utils_1.CRASHLYTICS_API_CLIENT.request({
|
|
19
|
-
method: "GET",
|
|
20
|
-
headers: {
|
|
21
|
-
"Content-Type": "application/json",
|
|
22
|
-
},
|
|
23
|
-
path: `/projects/${requestProjectNumber}/apps/${appId}/events`,
|
|
24
|
-
queryParams: queryParams,
|
|
25
|
-
timeout: utils_1.TIMEOUT,
|
|
26
|
-
});
|
|
27
|
-
return response.body;
|
|
28
|
-
}
|
|
29
|
-
catch (err) {
|
|
30
|
-
logger_1.logger.debug(err.message);
|
|
31
|
-
throw new error_1.FirebaseError(`Failed to fetch the same crash for the Firebase AppId ${appId}, IssueId ${issueId}. Error: ${err}.`, { original: err });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
exports.getSampleCrash = getSampleCrash;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.listTopDevices = void 0;
|
|
4
|
-
const logger_1 = require("../logger");
|
|
5
|
-
const error_1 = require("../error");
|
|
6
|
-
const utils_1 = require("./utils");
|
|
7
|
-
async function listTopDevices(appId, deviceCount, issueId) {
|
|
8
|
-
const requestProjectNumber = (0, utils_1.parseProjectNumber)(appId);
|
|
9
|
-
const platformPath = (0, utils_1.parsePlatform)(appId);
|
|
10
|
-
try {
|
|
11
|
-
const queryParams = new URLSearchParams();
|
|
12
|
-
queryParams.set("page_size", `${deviceCount}`);
|
|
13
|
-
if (issueId) {
|
|
14
|
-
queryParams.set("filter.issue.id", issueId);
|
|
15
|
-
}
|
|
16
|
-
logger_1.logger.debug(`[mcp][crashlytics] listTopDevices called with appId: ${appId}, deviceCount: ${deviceCount}, issueId: ${issueId}`);
|
|
17
|
-
const response = await utils_1.CRASHLYTICS_API_CLIENT.request({
|
|
18
|
-
method: "GET",
|
|
19
|
-
headers: {
|
|
20
|
-
"Content-Type": "application/json",
|
|
21
|
-
},
|
|
22
|
-
path: `/projects/${requestProjectNumber}/apps/${appId}/reports/${platformPath}`,
|
|
23
|
-
queryParams: queryParams,
|
|
24
|
-
timeout: utils_1.TIMEOUT,
|
|
25
|
-
});
|
|
26
|
-
return response.body;
|
|
27
|
-
}
|
|
28
|
-
catch (err) {
|
|
29
|
-
logger_1.logger.debug(err.message);
|
|
30
|
-
throw new error_1.FirebaseError(`Failed to fetch the top devices for the Firebase app id: ${appId}. Error: ${err}.`, { original: err });
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
exports.listTopDevices = listTopDevices;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.listTopIssues = void 0;
|
|
4
|
-
const logger_1 = require("../logger");
|
|
5
|
-
const error_1 = require("../error");
|
|
6
|
-
const utils_1 = require("./utils");
|
|
7
|
-
async function listTopIssues(appId, issueType, issueCount) {
|
|
8
|
-
const requestProjectNumber = (0, utils_1.parseProjectNumber)(appId);
|
|
9
|
-
try {
|
|
10
|
-
const queryParams = new URLSearchParams();
|
|
11
|
-
queryParams.set("page_size", `${issueCount}`);
|
|
12
|
-
queryParams.set("filter.issue.error_types", `${issueType}`);
|
|
13
|
-
logger_1.logger.debug(`[mcp][crashlytics] listTopIssues called with appId: ${appId}, issueType: ${issueType}, issueCount: ${issueCount}`);
|
|
14
|
-
const response = await utils_1.CRASHLYTICS_API_CLIENT.request({
|
|
15
|
-
method: "GET",
|
|
16
|
-
headers: {
|
|
17
|
-
"Content-Type": "application/json",
|
|
18
|
-
},
|
|
19
|
-
path: `/projects/${requestProjectNumber}/apps/${appId}/reports/topIssues`,
|
|
20
|
-
queryParams: queryParams,
|
|
21
|
-
timeout: utils_1.TIMEOUT,
|
|
22
|
-
});
|
|
23
|
-
return response.body;
|
|
24
|
-
}
|
|
25
|
-
catch (err) {
|
|
26
|
-
logger_1.logger.debug(err.message);
|
|
27
|
-
throw new error_1.FirebaseError(`Failed to fetch the top issues for the Firebase app id: ${appId}. Error: ${err}.`, { original: err });
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
exports.listTopIssues = listTopIssues;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.listTopOperatingSystems = void 0;
|
|
4
|
-
const logger_1 = require("../logger");
|
|
5
|
-
const error_1 = require("../error");
|
|
6
|
-
const utils_1 = require("./utils");
|
|
7
|
-
async function listTopOperatingSystems(appId, osCount, issueId) {
|
|
8
|
-
const requestProjectNumber = (0, utils_1.parseProjectNumber)(appId);
|
|
9
|
-
try {
|
|
10
|
-
const queryParams = new URLSearchParams();
|
|
11
|
-
queryParams.set("page_size", `${osCount}`);
|
|
12
|
-
if (issueId) {
|
|
13
|
-
queryParams.set("filter.issue.id", issueId);
|
|
14
|
-
}
|
|
15
|
-
logger_1.logger.debug(`[mcp][crashlytics] listTopOperatingSystems called with appId: ${appId}, osCount: ${osCount}, issueId: ${issueId}`);
|
|
16
|
-
const response = await utils_1.CRASHLYTICS_API_CLIENT.request({
|
|
17
|
-
method: "GET",
|
|
18
|
-
headers: {
|
|
19
|
-
"Content-Type": "application/json",
|
|
20
|
-
},
|
|
21
|
-
path: `/projects/${requestProjectNumber}/apps/${appId}/reports/topOperatingSystems`,
|
|
22
|
-
queryParams: queryParams,
|
|
23
|
-
timeout: utils_1.TIMEOUT,
|
|
24
|
-
});
|
|
25
|
-
return response.body;
|
|
26
|
-
}
|
|
27
|
-
catch (err) {
|
|
28
|
-
logger_1.logger.debug(err.message);
|
|
29
|
-
throw new error_1.FirebaseError(`Failed to fetch the top operating systems for the Firebase app id: ${appId}. Error: ${err}.`, { original: err });
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
exports.listTopOperatingSystems = listTopOperatingSystems;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.listTopVersions = void 0;
|
|
4
|
-
const logger_1 = require("../logger");
|
|
5
|
-
const error_1 = require("../error");
|
|
6
|
-
const utils_1 = require("./utils");
|
|
7
|
-
async function listTopVersions(appId, versionCount, issueId) {
|
|
8
|
-
const requestProjectNumber = (0, utils_1.parseProjectNumber)(appId);
|
|
9
|
-
try {
|
|
10
|
-
const queryParams = new URLSearchParams();
|
|
11
|
-
queryParams.set("page_size", `${versionCount}`);
|
|
12
|
-
if (issueId) {
|
|
13
|
-
queryParams.set("filter.issue.id", issueId);
|
|
14
|
-
}
|
|
15
|
-
logger_1.logger.debug(`[mcp][crashlytics] listTopVersions called with appId: ${appId}, versionCount: ${versionCount}, issueId: ${issueId}`);
|
|
16
|
-
const response = await utils_1.CRASHLYTICS_API_CLIENT.request({
|
|
17
|
-
method: "GET",
|
|
18
|
-
headers: {
|
|
19
|
-
"Content-Type": "application/json",
|
|
20
|
-
},
|
|
21
|
-
path: `/projects/${requestProjectNumber}/apps/${appId}/reports/topVersions`,
|
|
22
|
-
queryParams: queryParams,
|
|
23
|
-
timeout: utils_1.TIMEOUT,
|
|
24
|
-
});
|
|
25
|
-
return response.body;
|
|
26
|
-
}
|
|
27
|
-
catch (err) {
|
|
28
|
-
logger_1.logger.debug(err.message);
|
|
29
|
-
throw new error_1.FirebaseError(`Failed to fetch the top versions for the Firebase app id: ${appId}. Error: ${err}.`, { original: err });
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
exports.listTopVersions = listTopVersions;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.updateIssue = exports.IssueState = void 0;
|
|
4
|
-
const logger_1 = require("../logger");
|
|
5
|
-
const error_1 = require("../error");
|
|
6
|
-
const utils_1 = require("./utils");
|
|
7
|
-
var IssueState;
|
|
8
|
-
(function (IssueState) {
|
|
9
|
-
IssueState["OPEN"] = "OPEN";
|
|
10
|
-
IssueState["CLOSED"] = "CLOSED";
|
|
11
|
-
})(IssueState = exports.IssueState || (exports.IssueState = {}));
|
|
12
|
-
async function updateIssue(appId, issueId, state) {
|
|
13
|
-
const requestProjectNumber = (0, utils_1.parseProjectNumber)(appId);
|
|
14
|
-
try {
|
|
15
|
-
logger_1.logger.debug(`[mcp][crashlytics] updateIssue called with appId: ${appId}, issueId: ${issueId}, state: ${state}`);
|
|
16
|
-
const response = await utils_1.CRASHLYTICS_API_CLIENT.request({
|
|
17
|
-
method: "PATCH",
|
|
18
|
-
headers: {
|
|
19
|
-
"Content-Type": "application/json",
|
|
20
|
-
},
|
|
21
|
-
path: `/projects/${requestProjectNumber}/apps/${appId}/issues/${issueId}`,
|
|
22
|
-
queryParams: { updateMask: "state" },
|
|
23
|
-
body: { state },
|
|
24
|
-
timeout: utils_1.TIMEOUT,
|
|
25
|
-
});
|
|
26
|
-
return response.body;
|
|
27
|
-
}
|
|
28
|
-
catch (err) {
|
|
29
|
-
logger_1.logger.debug(err.message);
|
|
30
|
-
throw new error_1.FirebaseError(`Failed to update issue ${issueId} for app ${appId}. Error: ${err}.`, {
|
|
31
|
-
original: err,
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
exports.updateIssue = updateIssue;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.add_note = void 0;
|
|
4
|
-
const zod_1 = require("zod");
|
|
5
|
-
const tool_1 = require("../../tool");
|
|
6
|
-
const util_1 = require("../../util");
|
|
7
|
-
const addNote_1 = require("../../../crashlytics/addNote");
|
|
8
|
-
const constants_1 = require("./constants");
|
|
9
|
-
exports.add_note = (0, tool_1.tool)({
|
|
10
|
-
name: "add_note",
|
|
11
|
-
description: "Add a note to an issue from crashlytics.",
|
|
12
|
-
inputSchema: zod_1.z.object({
|
|
13
|
-
app_id: constants_1.APP_ID_FIELD,
|
|
14
|
-
issue_id: zod_1.z.string().describe("The issue id to add the note to."),
|
|
15
|
-
note: zod_1.z.string().describe("The note to add to the issue."),
|
|
16
|
-
}),
|
|
17
|
-
annotations: {
|
|
18
|
-
title: "Add note to Crashlytics issue.",
|
|
19
|
-
readOnlyHint: true,
|
|
20
|
-
},
|
|
21
|
-
_meta: {
|
|
22
|
-
requiresAuth: true,
|
|
23
|
-
},
|
|
24
|
-
}, async ({ app_id, issue_id, note }) => {
|
|
25
|
-
if (!app_id)
|
|
26
|
-
return (0, util_1.mcpError)(`Must specify 'app_id' parameter.`);
|
|
27
|
-
if (!issue_id)
|
|
28
|
-
return (0, util_1.mcpError)(`Must specify 'issue_id' parameter.`);
|
|
29
|
-
if (!note)
|
|
30
|
-
return (0, util_1.mcpError)(`Must specify 'note' parameter.`);
|
|
31
|
-
return (0, util_1.toContent)(await (0, addNote_1.addNote)(app_id, issue_id, note));
|
|
32
|
-
});
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.APP_ID_FIELD = void 0;
|
|
4
|
-
const zod_1 = require("zod");
|
|
5
|
-
exports.APP_ID_FIELD = zod_1.z
|
|
6
|
-
.string()
|
|
7
|
-
.describe("AppId for the application. For an Android application, read the " +
|
|
8
|
-
"mobilesdk_app_id value specified in the google-services.json file for " +
|
|
9
|
-
"the current package name. For an iOS Application, read the GOOGLE_APP_ID " +
|
|
10
|
-
"from GoogleService-Info.plist. If neither is available, ask the user to " +
|
|
11
|
-
"provide the app id.");
|