@tmhs/mobile-mcp 0.7.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +23 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/addMap.d.ts +3 -0
- package/dist/tools/addMap.d.ts.map +1 -0
- package/dist/tools/addMap.js +223 -0
- package/dist/tools/addMap.js.map +1 -0
- package/dist/tools/checkOfflineReady.d.ts +3 -0
- package/dist/tools/checkOfflineReady.d.ts.map +1 -0
- package/dist/tools/checkOfflineReady.js +190 -0
- package/dist/tools/checkOfflineReady.js.map +1 -0
- package/dist/tools/generateForm.d.ts +3 -0
- package/dist/tools/generateForm.d.ts.map +1 -0
- package/dist/tools/generateForm.js +337 -0
- package/dist/tools/generateForm.js.map +1 -0
- package/dist/tools/generateTestFile.d.ts +3 -0
- package/dist/tools/generateTestFile.d.ts.map +1 -0
- package/dist/tools/generateTestFile.js +184 -0
- package/dist/tools/generateTestFile.js.map +1 -0
- package/dist/tools/profilePerformance.d.ts +3 -0
- package/dist/tools/profilePerformance.d.ts.map +1 -0
- package/dist/tools/profilePerformance.js +222 -0
- package/dist/tools/profilePerformance.js.map +1 -0
- package/dist/tools/runTests.d.ts +3 -0
- package/dist/tools/runTests.d.ts.map +1 -0
- package/dist/tools/runTests.js +165 -0
- package/dist/tools/runTests.js.map +1 -0
- package/dist/tools/securityAudit.d.ts +3 -0
- package/dist/tools/securityAudit.d.ts.map +1 -0
- package/dist/tools/securityAudit.js +213 -0
- package/dist/tools/securityAudit.js.map +1 -0
- package/dist/tools/setupCI.d.ts +3 -0
- package/dist/tools/setupCI.d.ts.map +1 -0
- package/dist/tools/setupCI.js +202 -0
- package/dist/tools/setupCI.js.map +1 -0
- package/dist/tools/setupI18n.d.ts +3 -0
- package/dist/tools/setupI18n.d.ts.map +1 -0
- package/dist/tools/setupI18n.js +155 -0
- package/dist/tools/setupI18n.js.map +1 -0
- package/dist/tools/setupMonitoring.d.ts +3 -0
- package/dist/tools/setupMonitoring.d.ts.map +1 -0
- package/dist/tools/setupMonitoring.js +250 -0
- package/dist/tools/setupMonitoring.js.map +1 -0
- package/dist/tools/setupRealtime.d.ts +3 -0
- package/dist/tools/setupRealtime.d.ts.map +1 -0
- package/dist/tools/setupRealtime.js +311 -0
- package/dist/tools/setupRealtime.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupCI.d.ts","sourceRoot":"","sources":["../../src/tools/setupCI.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAqKzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAiEhD"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
3
|
+
import { join, dirname } from "node:path";
|
|
4
|
+
import { textResponse, errorResponse } from "../types.js";
|
|
5
|
+
const inputSchema = {
|
|
6
|
+
project_path: z
|
|
7
|
+
.string()
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Absolute path to the project root. Defaults to cwd."),
|
|
10
|
+
framework: z
|
|
11
|
+
.enum(["expo", "flutter"])
|
|
12
|
+
.optional()
|
|
13
|
+
.default("expo")
|
|
14
|
+
.describe("Project framework (default: expo)."),
|
|
15
|
+
platforms: z
|
|
16
|
+
.enum(["ios", "android", "both"])
|
|
17
|
+
.optional()
|
|
18
|
+
.default("both")
|
|
19
|
+
.describe("Target platforms for CI builds (default: both)."),
|
|
20
|
+
include_tests: z
|
|
21
|
+
.boolean()
|
|
22
|
+
.optional()
|
|
23
|
+
.default(true)
|
|
24
|
+
.describe("Include a test step in the workflow (default: true)."),
|
|
25
|
+
include_eas_build: z
|
|
26
|
+
.boolean()
|
|
27
|
+
.optional()
|
|
28
|
+
.default(false)
|
|
29
|
+
.describe("Include EAS Build step for Expo projects (default: false). Requires EXPO_TOKEN secret."),
|
|
30
|
+
};
|
|
31
|
+
function generateExpoWorkflow(platforms, includeTests, includeEas) {
|
|
32
|
+
const platformList = platforms === "both" ? "ios, android" : platforms;
|
|
33
|
+
let testStep = "";
|
|
34
|
+
if (includeTests) {
|
|
35
|
+
testStep = `
|
|
36
|
+
- name: Run tests
|
|
37
|
+
run: npx jest --ci --coverage`;
|
|
38
|
+
}
|
|
39
|
+
let easStep = "";
|
|
40
|
+
if (includeEas) {
|
|
41
|
+
const platformFlag = platforms === "both" ? "all" : platforms;
|
|
42
|
+
easStep = `
|
|
43
|
+
|
|
44
|
+
eas-build:
|
|
45
|
+
needs: lint-and-test
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
if: github.ref == 'refs/heads/main'
|
|
48
|
+
strategy:
|
|
49
|
+
matrix:
|
|
50
|
+
platform: [${platformList}]
|
|
51
|
+
steps:
|
|
52
|
+
- uses: actions/checkout@v4
|
|
53
|
+
|
|
54
|
+
- uses: actions/setup-node@v4
|
|
55
|
+
with:
|
|
56
|
+
node-version: 20
|
|
57
|
+
cache: npm
|
|
58
|
+
|
|
59
|
+
- run: npm ci
|
|
60
|
+
|
|
61
|
+
- uses: expo/expo-github-action@v8
|
|
62
|
+
with:
|
|
63
|
+
eas-version: latest
|
|
64
|
+
token: \${{ secrets.EXPO_TOKEN }}
|
|
65
|
+
|
|
66
|
+
- name: Build for \${{ matrix.platform }}
|
|
67
|
+
run: eas build --platform \${{ matrix.platform }} --profile production --non-interactive`;
|
|
68
|
+
}
|
|
69
|
+
return `name: CI
|
|
70
|
+
|
|
71
|
+
on:
|
|
72
|
+
push:
|
|
73
|
+
branches: [main]
|
|
74
|
+
pull_request:
|
|
75
|
+
branches: [main]
|
|
76
|
+
|
|
77
|
+
jobs:
|
|
78
|
+
lint-and-test:
|
|
79
|
+
runs-on: ubuntu-latest
|
|
80
|
+
steps:
|
|
81
|
+
- uses: actions/checkout@v4
|
|
82
|
+
|
|
83
|
+
- uses: actions/setup-node@v4
|
|
84
|
+
with:
|
|
85
|
+
node-version: 20
|
|
86
|
+
cache: npm
|
|
87
|
+
|
|
88
|
+
- run: npm ci
|
|
89
|
+
|
|
90
|
+
- name: Type check
|
|
91
|
+
run: npx tsc --noEmit
|
|
92
|
+
|
|
93
|
+
- name: Lint
|
|
94
|
+
run: npx expo lint
|
|
95
|
+
${testStep}
|
|
96
|
+
${easStep}
|
|
97
|
+
`;
|
|
98
|
+
}
|
|
99
|
+
function generateFlutterWorkflow(platforms, includeTests) {
|
|
100
|
+
let testStep = "";
|
|
101
|
+
if (includeTests) {
|
|
102
|
+
testStep = `
|
|
103
|
+
- name: Run tests
|
|
104
|
+
run: flutter test --coverage`;
|
|
105
|
+
}
|
|
106
|
+
let buildSteps = "";
|
|
107
|
+
if (platforms === "android" || platforms === "both") {
|
|
108
|
+
buildSteps += `
|
|
109
|
+
- name: Build Android APK
|
|
110
|
+
run: flutter build apk --release`;
|
|
111
|
+
}
|
|
112
|
+
if (platforms === "ios" || platforms === "both") {
|
|
113
|
+
buildSteps += `
|
|
114
|
+
|
|
115
|
+
build-ios:
|
|
116
|
+
needs: test
|
|
117
|
+
runs-on: macos-latest
|
|
118
|
+
steps:
|
|
119
|
+
- uses: actions/checkout@v4
|
|
120
|
+
|
|
121
|
+
- uses: subosito/flutter-action@v2
|
|
122
|
+
with:
|
|
123
|
+
channel: stable
|
|
124
|
+
cache: true
|
|
125
|
+
|
|
126
|
+
- run: flutter pub get
|
|
127
|
+
|
|
128
|
+
- name: Build iOS
|
|
129
|
+
run: flutter build ios --release --no-codesign`;
|
|
130
|
+
}
|
|
131
|
+
return `name: CI
|
|
132
|
+
|
|
133
|
+
on:
|
|
134
|
+
push:
|
|
135
|
+
branches: [main]
|
|
136
|
+
pull_request:
|
|
137
|
+
branches: [main]
|
|
138
|
+
|
|
139
|
+
jobs:
|
|
140
|
+
test:
|
|
141
|
+
runs-on: ubuntu-latest
|
|
142
|
+
steps:
|
|
143
|
+
- uses: actions/checkout@v4
|
|
144
|
+
|
|
145
|
+
- uses: subosito/flutter-action@v2
|
|
146
|
+
with:
|
|
147
|
+
channel: stable
|
|
148
|
+
cache: true
|
|
149
|
+
|
|
150
|
+
- run: flutter pub get
|
|
151
|
+
|
|
152
|
+
- name: Analyze
|
|
153
|
+
run: flutter analyze
|
|
154
|
+
${testStep}
|
|
155
|
+
${buildSteps}
|
|
156
|
+
`;
|
|
157
|
+
}
|
|
158
|
+
export function register(server) {
|
|
159
|
+
server.tool("mobile_setupCI", "Generate a GitHub Actions CI workflow for build, test, and optional EAS Build deployment. Creates .github/workflows/ci.yml.", inputSchema, async (args) => {
|
|
160
|
+
try {
|
|
161
|
+
const root = args.project_path || process.cwd();
|
|
162
|
+
const workflowPath = join(root, ".github", "workflows", "ci.yml");
|
|
163
|
+
if (existsSync(workflowPath)) {
|
|
164
|
+
return textResponse(JSON.stringify({
|
|
165
|
+
success: false,
|
|
166
|
+
message: `Workflow already exists at ${workflowPath}. Delete or rename it before generating a new one.`,
|
|
167
|
+
existing_file: workflowPath,
|
|
168
|
+
}, null, 2));
|
|
169
|
+
}
|
|
170
|
+
const workflow = args.framework === "flutter"
|
|
171
|
+
? generateFlutterWorkflow(args.platforms, args.include_tests)
|
|
172
|
+
: generateExpoWorkflow(args.platforms, args.include_tests, args.include_eas_build);
|
|
173
|
+
mkdirSync(dirname(workflowPath), { recursive: true });
|
|
174
|
+
writeFileSync(workflowPath, workflow, "utf-8");
|
|
175
|
+
const secrets = [];
|
|
176
|
+
if (args.include_eas_build && args.framework === "expo") {
|
|
177
|
+
secrets.push("EXPO_TOKEN - EAS CLI authentication token");
|
|
178
|
+
}
|
|
179
|
+
return textResponse(JSON.stringify({
|
|
180
|
+
success: true,
|
|
181
|
+
file_created: workflowPath,
|
|
182
|
+
framework: args.framework,
|
|
183
|
+
platforms: args.platforms,
|
|
184
|
+
includes_tests: args.include_tests,
|
|
185
|
+
includes_eas_build: args.include_eas_build,
|
|
186
|
+
required_secrets: secrets.length > 0 ? secrets : undefined,
|
|
187
|
+
next_steps: [
|
|
188
|
+
"Review the generated workflow at .github/workflows/ci.yml",
|
|
189
|
+
"Commit and push to trigger the first run",
|
|
190
|
+
...(secrets.length > 0
|
|
191
|
+
? ["Add required secrets in GitHub repo Settings > Secrets and variables > Actions"]
|
|
192
|
+
: []),
|
|
193
|
+
"Consider adding branch protection rules to require CI to pass",
|
|
194
|
+
],
|
|
195
|
+
}, null, 2));
|
|
196
|
+
}
|
|
197
|
+
catch (err) {
|
|
198
|
+
return errorResponse(err);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=setupCI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupCI.js","sourceRoot":"","sources":["../../src/tools/setupCI.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupI18n.d.ts","sourceRoot":"","sources":["../../src/tools/setupI18n.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA2FzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA8FhD"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { textResponse, errorResponse } from "../types.js";
|
|
5
|
+
const inputSchema = {
|
|
6
|
+
project_path: z
|
|
7
|
+
.string()
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Absolute path to the project root. Defaults to cwd."),
|
|
10
|
+
framework: z
|
|
11
|
+
.enum(["expo", "flutter"])
|
|
12
|
+
.optional()
|
|
13
|
+
.default("expo")
|
|
14
|
+
.describe("Project framework (default: expo)."),
|
|
15
|
+
default_locale: z
|
|
16
|
+
.string()
|
|
17
|
+
.optional()
|
|
18
|
+
.default("en")
|
|
19
|
+
.describe("Default locale code (default: en)."),
|
|
20
|
+
additional_locales: z
|
|
21
|
+
.array(z.string())
|
|
22
|
+
.optional()
|
|
23
|
+
.default([])
|
|
24
|
+
.describe("Additional locale codes to create placeholder files for (e.g. ['es', 'fr', 'de'])."),
|
|
25
|
+
};
|
|
26
|
+
function generateExpoI18nConfig(defaultLocale) {
|
|
27
|
+
return `import i18n from "i18next";
|
|
28
|
+
import { initReactI18next } from "react-i18next";
|
|
29
|
+
import { getLocales } from "expo-localization";
|
|
30
|
+
import ${defaultLocale} from "./${defaultLocale}.json";
|
|
31
|
+
|
|
32
|
+
const deviceLocale = getLocales()[0]?.languageCode ?? "${defaultLocale}";
|
|
33
|
+
|
|
34
|
+
i18n.use(initReactI18next).init({
|
|
35
|
+
resources: {
|
|
36
|
+
${defaultLocale}: { translation: ${defaultLocale} },
|
|
37
|
+
},
|
|
38
|
+
lng: deviceLocale,
|
|
39
|
+
fallbackLng: "${defaultLocale}",
|
|
40
|
+
interpolation: {
|
|
41
|
+
escapeValue: false,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
export default i18n;
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
function generateLocaleJson(locale) {
|
|
49
|
+
return JSON.stringify({
|
|
50
|
+
common: {
|
|
51
|
+
ok: locale === "en" ? "OK" : `[${locale}] OK`,
|
|
52
|
+
cancel: locale === "en" ? "Cancel" : `[${locale}] Cancel`,
|
|
53
|
+
save: locale === "en" ? "Save" : `[${locale}] Save`,
|
|
54
|
+
delete: locale === "en" ? "Delete" : `[${locale}] Delete`,
|
|
55
|
+
loading: locale === "en" ? "Loading..." : `[${locale}] Loading...`,
|
|
56
|
+
},
|
|
57
|
+
errors: {
|
|
58
|
+
generic: locale === "en" ? "Something went wrong" : `[${locale}] Something went wrong`,
|
|
59
|
+
network: locale === "en" ? "Check your internet connection" : `[${locale}] Check your internet connection`,
|
|
60
|
+
},
|
|
61
|
+
}, null, 2);
|
|
62
|
+
}
|
|
63
|
+
function generateFlutterL10nYaml(defaultLocale) {
|
|
64
|
+
return `arb-dir: lib/l10n
|
|
65
|
+
template-arb-file: app_${defaultLocale}.arb
|
|
66
|
+
output-localization-file: app_localizations.dart
|
|
67
|
+
output-class: AppLocalizations
|
|
68
|
+
`;
|
|
69
|
+
}
|
|
70
|
+
function generateArbFile(locale) {
|
|
71
|
+
const data = {
|
|
72
|
+
"@@locale": locale,
|
|
73
|
+
ok: locale === "en" ? "OK" : `[${locale}] OK`,
|
|
74
|
+
"@ok": JSON.stringify({ description: "Generic OK button label" }),
|
|
75
|
+
cancel: locale === "en" ? "Cancel" : `[${locale}] Cancel`,
|
|
76
|
+
"@cancel": JSON.stringify({ description: "Generic Cancel button label" }),
|
|
77
|
+
save: locale === "en" ? "Save" : `[${locale}] Save`,
|
|
78
|
+
"@save": JSON.stringify({ description: "Generic Save button label" }),
|
|
79
|
+
errorGeneric: locale === "en" ? "Something went wrong" : `[${locale}] Something went wrong`,
|
|
80
|
+
"@errorGeneric": JSON.stringify({ description: "Generic error message" }),
|
|
81
|
+
};
|
|
82
|
+
return JSON.stringify(data, null, 2);
|
|
83
|
+
}
|
|
84
|
+
export function register(server) {
|
|
85
|
+
server.tool("mobile_setupI18n", "Initialize internationalization (i18n) config with locale files and translation structure. Supports i18next for Expo and flutter_localizations for Flutter.", inputSchema, async (args) => {
|
|
86
|
+
try {
|
|
87
|
+
const root = args.project_path || process.cwd();
|
|
88
|
+
const locales = [args.default_locale, ...args.additional_locales];
|
|
89
|
+
const filesCreated = [];
|
|
90
|
+
if (args.framework === "flutter") {
|
|
91
|
+
const l10nDir = join(root, "lib", "l10n");
|
|
92
|
+
mkdirSync(l10nDir, { recursive: true });
|
|
93
|
+
const l10nYamlPath = join(root, "l10n.yaml");
|
|
94
|
+
if (!existsSync(l10nYamlPath)) {
|
|
95
|
+
writeFileSync(l10nYamlPath, generateFlutterL10nYaml(args.default_locale), "utf-8");
|
|
96
|
+
filesCreated.push(l10nYamlPath);
|
|
97
|
+
}
|
|
98
|
+
for (const locale of locales) {
|
|
99
|
+
const arbPath = join(l10nDir, `app_${locale}.arb`);
|
|
100
|
+
if (!existsSync(arbPath)) {
|
|
101
|
+
writeFileSync(arbPath, generateArbFile(locale), "utf-8");
|
|
102
|
+
filesCreated.push(arbPath);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return textResponse(JSON.stringify({
|
|
106
|
+
success: true,
|
|
107
|
+
framework: "flutter",
|
|
108
|
+
files_created: filesCreated,
|
|
109
|
+
default_locale: args.default_locale,
|
|
110
|
+
locales,
|
|
111
|
+
next_steps: [
|
|
112
|
+
"Add flutter_localizations to pubspec.yaml dependencies",
|
|
113
|
+
"Add generate: true to pubspec.yaml",
|
|
114
|
+
"Import and add AppLocalizations.delegate to MaterialApp localizationsDelegates",
|
|
115
|
+
"Add AppLocalizations.supportedLocales to MaterialApp supportedLocales",
|
|
116
|
+
"Run flutter gen-l10n to generate the dart files",
|
|
117
|
+
"Use AppLocalizations.of(context)!.ok in your widgets",
|
|
118
|
+
],
|
|
119
|
+
}, null, 2));
|
|
120
|
+
}
|
|
121
|
+
const i18nDir = join(root, "i18n");
|
|
122
|
+
mkdirSync(i18nDir, { recursive: true });
|
|
123
|
+
for (const locale of locales) {
|
|
124
|
+
const localePath = join(i18nDir, `${locale}.json`);
|
|
125
|
+
if (!existsSync(localePath)) {
|
|
126
|
+
writeFileSync(localePath, generateLocaleJson(locale) + "\n", "utf-8");
|
|
127
|
+
filesCreated.push(localePath);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const configPath = join(i18nDir, "index.ts");
|
|
131
|
+
if (!existsSync(configPath)) {
|
|
132
|
+
writeFileSync(configPath, generateExpoI18nConfig(args.default_locale), "utf-8");
|
|
133
|
+
filesCreated.push(configPath);
|
|
134
|
+
}
|
|
135
|
+
return textResponse(JSON.stringify({
|
|
136
|
+
success: true,
|
|
137
|
+
framework: "expo",
|
|
138
|
+
files_created: filesCreated,
|
|
139
|
+
default_locale: args.default_locale,
|
|
140
|
+
locales,
|
|
141
|
+
next_steps: [
|
|
142
|
+
"Install dependencies: npx expo install i18next react-i18next expo-localization",
|
|
143
|
+
'Import i18n config in your app entry: import "./i18n"',
|
|
144
|
+
'Use translations: const { t } = useTranslation(); t("common.ok")',
|
|
145
|
+
"Add more locale files to i18n/ for each supported language",
|
|
146
|
+
"Consider i18next-parser for extracting strings from code",
|
|
147
|
+
],
|
|
148
|
+
}, null, 2));
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
return errorResponse(err);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=setupI18n.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupI18n.js","sourceRoot":"","sources":["../../src/tools/setupI18n.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupMonitoring.d.ts","sourceRoot":"","sources":["../../src/tools/setupMonitoring.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAsMzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoFhD"}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { textResponse, errorResponse } from "../types.js";
|
|
5
|
+
const inputSchema = {
|
|
6
|
+
project_path: z
|
|
7
|
+
.string()
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Absolute path to the project root. Defaults to cwd."),
|
|
10
|
+
provider: z
|
|
11
|
+
.enum(["sentry", "datadog"])
|
|
12
|
+
.optional()
|
|
13
|
+
.default("sentry")
|
|
14
|
+
.describe("APM provider (default: sentry)."),
|
|
15
|
+
framework: z
|
|
16
|
+
.enum(["expo", "flutter"])
|
|
17
|
+
.optional()
|
|
18
|
+
.default("expo")
|
|
19
|
+
.describe("Framework (default: expo)."),
|
|
20
|
+
output_directory: z
|
|
21
|
+
.string()
|
|
22
|
+
.optional()
|
|
23
|
+
.default("lib")
|
|
24
|
+
.describe("Output directory relative to project root (default: lib)."),
|
|
25
|
+
};
|
|
26
|
+
function generateSentryExpo() {
|
|
27
|
+
return `import * as Sentry from "@sentry/react-native";
|
|
28
|
+
|
|
29
|
+
Sentry.init({
|
|
30
|
+
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN!,
|
|
31
|
+
tracesSampleRate: __DEV__ ? 1.0 : 0.2,
|
|
32
|
+
profilesSampleRate: __DEV__ ? 1.0 : 0.1,
|
|
33
|
+
enableAutoSessionTracking: true,
|
|
34
|
+
environment: __DEV__ ? "development" : "production",
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export function startSpan(name: string, op: string): Sentry.Span | undefined {
|
|
38
|
+
return Sentry.startInactiveSpan({ name, op });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function captureError(error: unknown, context?: Record<string, unknown>): void {
|
|
42
|
+
Sentry.captureException(error, { extra: context });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function setUser(id: string, email?: string): void {
|
|
46
|
+
Sentry.setUser({ id, email });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function clearUser(): void {
|
|
50
|
+
Sentry.setUser(null);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function addBreadcrumb(
|
|
54
|
+
category: string,
|
|
55
|
+
message: string,
|
|
56
|
+
level: Sentry.SeverityLevel = "info",
|
|
57
|
+
): void {
|
|
58
|
+
Sentry.addBreadcrumb({ category, message, level });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const SentryWrap = Sentry.wrap;
|
|
62
|
+
`;
|
|
63
|
+
}
|
|
64
|
+
function generateSentryFlutter() {
|
|
65
|
+
return `import 'package:sentry_flutter/sentry_flutter.dart';
|
|
66
|
+
|
|
67
|
+
Future<void> initMonitoring() async {
|
|
68
|
+
await SentryFlutter.init(
|
|
69
|
+
(options) {
|
|
70
|
+
options.dsn = const String.fromEnvironment('SENTRY_DSN');
|
|
71
|
+
options.tracesSampleRate = 0.2;
|
|
72
|
+
options.profilesSampleRate = 0.1;
|
|
73
|
+
options.environment =
|
|
74
|
+
const bool.fromEnvironment('dart.vm.product') ? 'production' : 'development';
|
|
75
|
+
},
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
Future<void> captureError(dynamic error, StackTrace stackTrace, {Map<String, dynamic>? extra}) async {
|
|
80
|
+
await Sentry.captureException(error, stackTrace: stackTrace, withScope: (scope) {
|
|
81
|
+
if (extra != null) {
|
|
82
|
+
for (final entry in extra.entries) {
|
|
83
|
+
scope.setExtra(entry.key, entry.value);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
ISentrySpan startSpan(String operation, String description) {
|
|
90
|
+
final transaction = Sentry.startTransaction(operation, description);
|
|
91
|
+
return transaction;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
void setUser(String id, {String? email}) {
|
|
95
|
+
Sentry.configureScope((scope) {
|
|
96
|
+
scope.setUser(SentryUser(id: id, email: email));
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
void clearUser() {
|
|
101
|
+
Sentry.configureScope((scope) {
|
|
102
|
+
scope.setUser(null);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
`;
|
|
106
|
+
}
|
|
107
|
+
function generateDatadogExpo() {
|
|
108
|
+
return `import {
|
|
109
|
+
DdSdkReactNative,
|
|
110
|
+
DdSdkReactNativeConfiguration,
|
|
111
|
+
DdLogs,
|
|
112
|
+
DdTrace,
|
|
113
|
+
DdRum,
|
|
114
|
+
} from "@datadog/mobile-react-native";
|
|
115
|
+
|
|
116
|
+
const config = new DdSdkReactNativeConfiguration(
|
|
117
|
+
process.env.EXPO_PUBLIC_DD_CLIENT_TOKEN!,
|
|
118
|
+
__DEV__ ? "development" : "production",
|
|
119
|
+
process.env.EXPO_PUBLIC_DD_APPLICATION_ID!,
|
|
120
|
+
true, // track interactions
|
|
121
|
+
true, // track XHR
|
|
122
|
+
true, // track errors
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
config.site = "US1";
|
|
126
|
+
config.nativeCrashReportEnabled = true;
|
|
127
|
+
config.sessionSamplingRate = __DEV__ ? 100 : 20;
|
|
128
|
+
|
|
129
|
+
export async function initMonitoring(): Promise<void> {
|
|
130
|
+
await DdSdkReactNative.initialize(config);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export async function startSpan(name: string, resourceName: string): Promise<string> {
|
|
134
|
+
return DdTrace.startSpan(name, { "resource.name": resourceName });
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export async function finishSpan(spanId: string): Promise<void> {
|
|
138
|
+
await DdTrace.finishSpan(spanId);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function logError(message: string, context?: Record<string, unknown>): void {
|
|
142
|
+
DdLogs.error(message, context ?? {});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function logInfo(message: string, context?: Record<string, unknown>): void {
|
|
146
|
+
DdLogs.info(message, context ?? {});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function trackAction(name: string, context?: Record<string, unknown>): void {
|
|
150
|
+
DdRum.addAction("custom", name, context ?? {});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function setUser(id: string, name?: string, email?: string): void {
|
|
154
|
+
DdSdkReactNative.setUser({ id, name, email });
|
|
155
|
+
}
|
|
156
|
+
`;
|
|
157
|
+
}
|
|
158
|
+
function generateDatadogFlutter() {
|
|
159
|
+
return `import 'package:datadog_flutter_plugin/datadog_flutter_plugin.dart';
|
|
160
|
+
|
|
161
|
+
Future<void> initMonitoring() async {
|
|
162
|
+
final configuration = DatadogConfiguration(
|
|
163
|
+
clientToken: const String.fromEnvironment('DD_CLIENT_TOKEN'),
|
|
164
|
+
env: const bool.fromEnvironment('dart.vm.product') ? 'production' : 'development',
|
|
165
|
+
site: DatadogSite.us1,
|
|
166
|
+
nativeCrashReportEnabled: true,
|
|
167
|
+
loggingConfiguration: DatadogLoggingConfiguration(),
|
|
168
|
+
rumConfiguration: DatadogRumConfiguration(
|
|
169
|
+
applicationId: const String.fromEnvironment('DD_APPLICATION_ID'),
|
|
170
|
+
sessionSamplingRate: 20,
|
|
171
|
+
traceSamplingRate: 20,
|
|
172
|
+
),
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
await DatadogSdk.instance.initialize(configuration, TrackingConsent.granted);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
void logError(String message, {Map<String, dynamic>? attributes}) {
|
|
179
|
+
DatadogSdk.instance.logs?.error(message, attributes: attributes ?? {});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
void logInfo(String message, {Map<String, dynamic>? attributes}) {
|
|
183
|
+
DatadogSdk.instance.logs?.info(message, attributes: attributes ?? {});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
void trackAction(String name, {Map<String, dynamic>? attributes}) {
|
|
187
|
+
DatadogSdk.instance.rum?.addAction(RumActionType.custom, name, attributes ?? {});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
void setUser(String id, {String? name, String? email}) {
|
|
191
|
+
DatadogSdk.instance.setUserInfo(id: id, name: name, email: email);
|
|
192
|
+
}
|
|
193
|
+
`;
|
|
194
|
+
}
|
|
195
|
+
export function register(server) {
|
|
196
|
+
server.tool("mobile_setupMonitoring", "Configure application performance monitoring (APM) with Sentry Performance or Datadog RUM. Generates a monitoring module with error capture, tracing, user context, and breadcrumbs.", inputSchema, async (args) => {
|
|
197
|
+
try {
|
|
198
|
+
const root = args.project_path || process.cwd();
|
|
199
|
+
const outDir = join(root, args.output_directory);
|
|
200
|
+
mkdirSync(outDir, { recursive: true });
|
|
201
|
+
const isFlutter = args.framework === "flutter";
|
|
202
|
+
const ext = isFlutter ? "dart" : "ts";
|
|
203
|
+
const fileName = `monitoring.${ext}`;
|
|
204
|
+
const filePath = join(outDir, fileName);
|
|
205
|
+
if (existsSync(filePath)) {
|
|
206
|
+
return errorResponse(new Error(`File already exists: ${filePath}`));
|
|
207
|
+
}
|
|
208
|
+
let content;
|
|
209
|
+
let dependencies;
|
|
210
|
+
const nextSteps = [];
|
|
211
|
+
if (args.provider === "datadog") {
|
|
212
|
+
if (isFlutter) {
|
|
213
|
+
content = generateDatadogFlutter();
|
|
214
|
+
dependencies = ["datadog_flutter_plugin"];
|
|
215
|
+
nextSteps.push("Add DD_CLIENT_TOKEN and DD_APPLICATION_ID to --dart-define or .env", "Call initMonitoring() in main() before runApp()", "Wrap MaterialApp with DatadogNavigationObserver for auto route tracking");
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
content = generateDatadogExpo();
|
|
219
|
+
dependencies = ["@datadog/mobile-react-native"];
|
|
220
|
+
nextSteps.push("Set EXPO_PUBLIC_DD_CLIENT_TOKEN and EXPO_PUBLIC_DD_APPLICATION_ID in .env", "Call initMonitoring() in your app root (_layout.tsx)", "Wrap navigation with DatadogProvider for auto view tracking");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
if (isFlutter) {
|
|
225
|
+
content = generateSentryFlutter();
|
|
226
|
+
dependencies = ["sentry_flutter"];
|
|
227
|
+
nextSteps.push("Add SENTRY_DSN to --dart-define or .env", "Call initMonitoring() in main() before runApp()", "Wrap runApp with Sentry's runZonedGuarded for automatic error capture");
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
content = generateSentryExpo();
|
|
231
|
+
dependencies = ["@sentry/react-native"];
|
|
232
|
+
nextSteps.push("Set EXPO_PUBLIC_SENTRY_DSN in .env", "Wrap your root component with SentryWrap (e.g., export default SentryWrap(App))", "Run npx sentry-expo-upload-sourcemaps for production source maps", "Configure EAS Build to include Sentry plugin in app.config");
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
writeFileSync(filePath, content, "utf-8");
|
|
236
|
+
return textResponse(JSON.stringify({
|
|
237
|
+
success: true,
|
|
238
|
+
provider: args.provider,
|
|
239
|
+
framework: args.framework,
|
|
240
|
+
file_created: filePath,
|
|
241
|
+
dependencies_needed: dependencies,
|
|
242
|
+
next_steps: nextSteps,
|
|
243
|
+
}, null, 2));
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
return errorResponse(err);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=setupMonitoring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupMonitoring.js","sourceRoot":"","sources":["../../src/tools/setupMonitoring.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupRealtime.d.ts","sourceRoot":"","sources":["../../src/tools/setupRealtime.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiQzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyFhD"}
|