@leonxin/meetgames 0.1.8 → 0.1.11

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 (285) hide show
  1. package/.agents/skills/meet-sdk-regression/SKILL.md +93 -0
  2. package/.cursor/mcp.example.json +16 -0
  3. package/.cursor/mcp.json +11 -0
  4. package/.cursor/skills/meetgames-mcp/SKILL.md +48 -0
  5. package/.vite/vitest/results.json +1 -0
  6. package/README.md +31 -8
  7. package/dist/aab-converter/aab-entry.d.ts +3 -0
  8. package/dist/aab-converter/aab-entry.d.ts.map +1 -0
  9. package/dist/aab-converter/aab-entry.js +49 -0
  10. package/dist/aab-converter/aab-entry.js.map +1 -0
  11. package/dist/aab-converter/apksExtractor.d.ts +2 -0
  12. package/dist/aab-converter/apksExtractor.d.ts.map +1 -0
  13. package/dist/aab-converter/apksExtractor.js +108 -0
  14. package/dist/aab-converter/apksExtractor.js.map +1 -0
  15. package/dist/aab-converter/bundletoolRunner.d.ts +15 -0
  16. package/dist/aab-converter/bundletoolRunner.d.ts.map +1 -0
  17. package/dist/aab-converter/bundletoolRunner.js +46 -0
  18. package/dist/aab-converter/bundletoolRunner.js.map +1 -0
  19. package/dist/aab-converter/cliArgs.d.ts +27 -0
  20. package/dist/aab-converter/cliArgs.d.ts.map +1 -0
  21. package/dist/aab-converter/cliArgs.js +170 -0
  22. package/dist/aab-converter/cliArgs.js.map +1 -0
  23. package/dist/aab-converter/convertAabToApk.d.ts +7 -0
  24. package/dist/aab-converter/convertAabToApk.d.ts.map +1 -0
  25. package/dist/aab-converter/convertAabToApk.js +69 -0
  26. package/dist/aab-converter/convertAabToApk.js.map +1 -0
  27. package/dist/aab-converter/resourcePaths.d.ts +4 -0
  28. package/dist/aab-converter/resourcePaths.d.ts.map +1 -0
  29. package/dist/aab-converter/resourcePaths.js +42 -0
  30. package/dist/aab-converter/resourcePaths.js.map +1 -0
  31. package/dist/aab-converter/signingOptions.d.ts +9 -0
  32. package/dist/aab-converter/signingOptions.d.ts.map +1 -0
  33. package/dist/aab-converter/signingOptions.js +21 -0
  34. package/dist/aab-converter/signingOptions.js.map +1 -0
  35. package/dist/aab-converter/types.d.ts +24 -0
  36. package/dist/aab-converter/types.d.ts.map +1 -0
  37. package/dist/aab-converter/types.js +2 -0
  38. package/dist/aab-converter/types.js.map +1 -0
  39. package/dist/android/adapter.d.ts.map +1 -1
  40. package/dist/android/adapter.js +2 -2
  41. package/dist/android/adapter.js.map +1 -1
  42. package/dist/android/detect.d.ts +2 -2
  43. package/dist/android/detect.d.ts.map +1 -1
  44. package/dist/android/detect.js +36 -8
  45. package/dist/android/detect.js.map +1 -1
  46. package/dist/cli.d.ts.map +1 -1
  47. package/dist/cli.js +157 -31
  48. package/dist/cli.js.map +1 -1
  49. package/dist/config/meetSdkDefaultConfig.d.ts +19 -2
  50. package/dist/config/meetSdkDefaultConfig.d.ts.map +1 -1
  51. package/dist/config/meetSdkDefaultConfig.js +67 -5
  52. package/dist/config/meetSdkDefaultConfig.js.map +1 -1
  53. package/dist/config/meetSdkIosConfig.d.ts +21 -0
  54. package/dist/config/meetSdkIosConfig.d.ts.map +1 -0
  55. package/dist/config/meetSdkIosConfig.js +66 -0
  56. package/dist/config/meetSdkIosConfig.js.map +1 -0
  57. package/dist/config/meetSdkRemoteConfig.d.ts +18 -1
  58. package/dist/config/meetSdkRemoteConfig.d.ts.map +1 -1
  59. package/dist/config/meetSdkRemoteConfig.js +61 -25
  60. package/dist/config/meetSdkRemoteConfig.js.map +1 -1
  61. package/dist/contracts/types.d.ts +19 -6
  62. package/dist/contracts/types.d.ts.map +1 -1
  63. package/dist/core/doctor.d.ts +17 -0
  64. package/dist/core/doctor.d.ts.map +1 -0
  65. package/dist/core/doctor.js +444 -0
  66. package/dist/core/doctor.js.map +1 -0
  67. package/dist/core/pipeline.d.ts.map +1 -1
  68. package/dist/core/pipeline.js +0 -15
  69. package/dist/core/pipeline.js.map +1 -1
  70. package/dist/core/platform.d.ts +12 -0
  71. package/dist/core/platform.d.ts.map +1 -0
  72. package/dist/core/platform.js +40 -0
  73. package/dist/core/platform.js.map +1 -0
  74. package/dist/core/reporter.js +1 -1
  75. package/dist/core/reporter.js.map +1 -1
  76. package/dist/core/workspace.d.ts +2 -2
  77. package/dist/core/workspace.d.ts.map +1 -1
  78. package/dist/core/workspace.js +4 -5
  79. package/dist/core/workspace.js.map +1 -1
  80. package/dist/index.d.ts +3 -1
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.js +3 -1
  83. package/dist/index.js.map +1 -1
  84. package/dist/ios/channelConfig.d.ts +1 -0
  85. package/dist/ios/channelConfig.d.ts.map +1 -1
  86. package/dist/ios/channelConfig.js +82 -0
  87. package/dist/ios/channelConfig.js.map +1 -1
  88. package/dist/ios/codeUtils.d.ts +1 -0
  89. package/dist/ios/codeUtils.d.ts.map +1 -1
  90. package/dist/ios/codeUtils.js +11 -2
  91. package/dist/ios/codeUtils.js.map +1 -1
  92. package/dist/ios/detect.d.ts +2 -2
  93. package/dist/ios/detect.d.ts.map +1 -1
  94. package/dist/ios/detect.js +49 -10
  95. package/dist/ios/detect.js.map +1 -1
  96. package/dist/ios/entitlements.d.ts +4 -0
  97. package/dist/ios/entitlements.d.ts.map +1 -0
  98. package/dist/ios/entitlements.js +53 -0
  99. package/dist/ios/entitlements.js.map +1 -0
  100. package/dist/ios/fileManager.d.ts.map +1 -1
  101. package/dist/ios/fileManager.js +3 -2
  102. package/dist/ios/fileManager.js.map +1 -1
  103. package/dist/ios/infoPlist.d.ts +1 -1
  104. package/dist/ios/infoPlist.d.ts.map +1 -1
  105. package/dist/ios/infoPlist.js.map +1 -1
  106. package/dist/ios/integrate.d.ts.map +1 -1
  107. package/dist/ios/integrate.js +211 -36
  108. package/dist/ios/integrate.js.map +1 -1
  109. package/dist/ios/pbxprojEditor.d.ts +2 -0
  110. package/dist/ios/pbxprojEditor.d.ts.map +1 -1
  111. package/dist/ios/pbxprojEditor.js +179 -1
  112. package/dist/ios/pbxprojEditor.js.map +1 -1
  113. package/dist/ios/pluginConfig.d.ts +1 -0
  114. package/dist/ios/pluginConfig.d.ts.map +1 -1
  115. package/dist/ios/pluginConfig.js +36 -4
  116. package/dist/ios/pluginConfig.js.map +1 -1
  117. package/dist/ios/sdkBundle.d.ts +1 -1
  118. package/dist/ios/sdkBundle.d.ts.map +1 -1
  119. package/dist/ios/sdkBundle.js +7 -5
  120. package/dist/ios/sdkBundle.js.map +1 -1
  121. package/dist/ios/template.d.ts +1 -0
  122. package/dist/ios/template.d.ts.map +1 -1
  123. package/dist/ios/template.js +14 -1
  124. package/dist/ios/template.js.map +1 -1
  125. package/dist/ios/types.d.ts +2 -2
  126. package/dist/ios/types.d.ts.map +1 -1
  127. package/dist/mcp/server.d.ts.map +1 -1
  128. package/dist/mcp/server.js +14 -13
  129. package/dist/mcp/server.js.map +1 -1
  130. package/dist/mcp/service.d.ts +8 -6
  131. package/dist/mcp/service.d.ts.map +1 -1
  132. package/dist/mcp/service.js +34 -14
  133. package/dist/mcp/service.js.map +1 -1
  134. package/dist/ops/handlers.d.ts.map +1 -1
  135. package/dist/ops/handlers.js +10 -4
  136. package/dist/ops/handlers.js.map +1 -1
  137. package/dist/remote/sdkHomeDownload.d.ts +65 -0
  138. package/dist/remote/sdkHomeDownload.d.ts.map +1 -0
  139. package/dist/remote/sdkHomeDownload.js +208 -0
  140. package/dist/remote/sdkHomeDownload.js.map +1 -0
  141. package/dist/remote/topsdkDownloadSdkConfig.d.ts.map +1 -1
  142. package/dist/remote/topsdkDownloadSdkConfig.js +11 -1
  143. package/dist/remote/topsdkDownloadSdkConfig.js.map +1 -1
  144. package/dist/shared/errors.d.ts +7 -0
  145. package/dist/shared/errors.d.ts.map +1 -0
  146. package/dist/shared/errors.js +16 -0
  147. package/dist/shared/errors.js.map +1 -0
  148. package/dist/shared/fileUtils.d.ts +5 -0
  149. package/dist/shared/fileUtils.d.ts.map +1 -0
  150. package/dist/shared/fileUtils.js +35 -0
  151. package/dist/shared/fileUtils.js.map +1 -0
  152. package/dist/shared/logger.d.ts +10 -0
  153. package/dist/shared/logger.d.ts.map +1 -0
  154. package/dist/shared/logger.js +37 -0
  155. package/dist/shared/logger.js.map +1 -0
  156. package/dist/shared/pathUtils.d.ts +4 -0
  157. package/dist/shared/pathUtils.d.ts.map +1 -0
  158. package/dist/shared/pathUtils.js +22 -0
  159. package/dist/shared/pathUtils.js.map +1 -0
  160. package/dist/shared/processRunner.d.ts +12 -0
  161. package/dist/shared/processRunner.d.ts.map +1 -0
  162. package/dist/shared/processRunner.js +31 -0
  163. package/dist/shared/processRunner.js.map +1 -0
  164. package/docs/AAB_CONVERTER_CLI_PLAN.md +392 -0
  165. package/docs/API.md +246 -32
  166. package/docs/CLI.md +292 -0
  167. package/docs/INTEGRATION.md +116 -0
  168. package/docs/MCP.md +86 -0
  169. package/docs/README.md +19 -10
  170. package/docs/{api → archive/api}/downloadSDKConfig.md +8 -6
  171. package/docs/{api → archive/api}/getChannelConfig-meetgames.md +1 -1
  172. package/docs/archive/ios-migration.md +2139 -0
  173. package/docs/{ → archive/product/}/346/212/200/346/234/257/346/226/271/346/241/210/350/260/203/347/240/224.md +7 -7
  174. package/docs/{ → archive/product/}/351/234/200/346/261/202/346/226/207/346/241/243.md +15 -14
  175. package/logs/convert-20260622-155037.log +5 -0
  176. package/logs/convert-20260622-155226.log +6 -0
  177. package/meetsdk-android.json +2 -1
  178. package/meetsdk-ios.json +15 -0
  179. package/package.json +10 -36
  180. package/scripts/package-aab-cli-win.mjs +193 -0
  181. package/src/aab-converter/aab-entry.ts +48 -0
  182. package/src/aab-converter/apksExtractor.ts +119 -0
  183. package/src/aab-converter/bundletoolRunner.ts +63 -0
  184. package/src/aab-converter/cliArgs.ts +194 -0
  185. package/src/aab-converter/convertAabToApk.ts +81 -0
  186. package/src/aab-converter/resourcePaths.ts +43 -0
  187. package/src/aab-converter/signingOptions.ts +29 -0
  188. package/src/aab-converter/types.ts +26 -0
  189. package/src/android/adapter.ts +9 -0
  190. package/src/android/assembleIntegrationJson.ts +33 -0
  191. package/src/android/detect.ts +132 -0
  192. package/src/android/downloadGoogleServicesJson.ts +56 -0
  193. package/src/android/gradle.ts +116 -0
  194. package/src/android/manifest.ts +50 -0
  195. package/src/android/meetSdkRemoteGradle.ts +837 -0
  196. package/src/cli.ts +488 -0
  197. package/src/config/fetchConfigWrite.ts +30 -0
  198. package/src/config/loadAndroidIntegration.ts +41 -0
  199. package/src/config/loadManifest.ts +40 -0
  200. package/src/config/meetSdkDefaultConfig.ts +99 -0
  201. package/src/config/meetSdkIosConfig.ts +87 -0
  202. package/src/config/meetSdkRemoteConfig.ts +1211 -0
  203. package/src/config/topsdkFeatureModules.ts +92 -0
  204. package/src/contracts/types.ts +121 -0
  205. package/src/core/doctor.ts +485 -0
  206. package/src/core/patch.ts +64 -0
  207. package/src/core/pipeline.ts +107 -0
  208. package/src/core/platform.ts +47 -0
  209. package/src/core/previewPatches.ts +23 -0
  210. package/src/core/reporter.ts +24 -0
  211. package/src/core/workspace.ts +29 -0
  212. package/src/entry.ts +7 -0
  213. package/src/index.ts +133 -0
  214. package/src/ios/channelConfig.ts +128 -0
  215. package/src/ios/codeUtils.ts +160 -0
  216. package/src/ios/detect.ts +105 -0
  217. package/src/ios/entitlements.ts +61 -0
  218. package/src/ios/fileManager.ts +48 -0
  219. package/src/ios/infoPlist.ts +55 -0
  220. package/src/ios/integrate.ts +516 -0
  221. package/src/ios/pbxprojEditor.ts +383 -0
  222. package/src/ios/pluginConfig.ts +97 -0
  223. package/src/ios/reserved.ts +8 -0
  224. package/src/ios/sdkBundle.ts +36 -0
  225. package/src/ios/template.ts +36 -0
  226. package/src/ios/types.ts +65 -0
  227. package/src/mcp/server.ts +170 -0
  228. package/src/mcp/service.ts +222 -0
  229. package/src/mcp-entry.ts +7 -0
  230. package/src/ops/fileStore.ts +56 -0
  231. package/src/ops/handlers.ts +304 -0
  232. package/src/remote/fetchJson.ts +22 -0
  233. package/src/remote/sdkHomeDownload.ts +274 -0
  234. package/src/remote/topsdkDownloadSdkConfig.ts +93 -0
  235. package/src/remote/topsdkGetSdkConfig.ts +122 -0
  236. package/src/remote/topsdkSign.ts +10 -0
  237. package/src/shared/errors.ts +16 -0
  238. package/src/shared/fileUtils.ts +41 -0
  239. package/src/shared/logger.ts +49 -0
  240. package/src/shared/pathUtils.ts +24 -0
  241. package/src/shared/processRunner.ts +43 -0
  242. package/test-projects/README.md +51 -0
  243. package/test-projects/_preview/pipeline.patch +281 -0
  244. package/tests/aab-converter.test.ts +213 -0
  245. package/tests/assemble.test.ts +12 -0
  246. package/tests/doctor.test.ts +89 -0
  247. package/tests/downloadGoogleServicesJson.test.ts +47 -0
  248. package/tests/fetch-remote.test.ts +23 -0
  249. package/tests/fetchConfigOverrides.test.ts +28 -0
  250. package/tests/fetchConfigWrite.test.ts +54 -0
  251. package/tests/gradle.test.ts +33 -0
  252. package/tests/integration-json.test.ts +29 -0
  253. package/tests/ios.codeUtils.test.ts +23 -0
  254. package/tests/ios.sdkBundle.test.ts +16 -0
  255. package/tests/loadManifest.test.ts +15 -0
  256. package/tests/manifest-xml.test.ts +30 -0
  257. package/tests/mcp.e2e.ts +217 -0
  258. package/tests/mcp.service.test.ts +53 -0
  259. package/tests/meetSdkRemoteConfig.test.ts +456 -0
  260. package/tests/meetSdkRemoteGradle.test.ts +414 -0
  261. package/tests/pipeline.android.test.ts +96 -0
  262. package/tests/pipeline.integration-json.test.ts +58 -0
  263. package/tests/pipeline.ios.test.ts +385 -0
  264. package/tests/pipeline.preview.patch.test.ts +85 -0
  265. package/tests/platformSelection.test.ts +77 -0
  266. package/tests/sdkHomeDownload.test.ts +124 -0
  267. package/tests/sdkVersionConfig.test.ts +130 -0
  268. package/tests/test-projects-hosts.test.ts +78 -0
  269. package/tests/topsdk.test.ts +53 -0
  270. package/tests/topsdkDownloadSdkConfig.test.ts +81 -0
  271. package/tests/topsdkFeatureModules.test.ts +116 -0
  272. package/tsconfig.json +19 -0
  273. package/vitest.config.ts +9 -0
  274. package/vitest.mcp.config.ts +11 -0
  275. package/bundled/android/sample.txt +0 -1
  276. package/docs/ANDROID.md +0 -133
  277. package/docs/CURSOR-MCP-SETUP.md +0 -72
  278. package/docs/MCP-SKILL.md +0 -63
  279. package/fixtures/api-samples/getChannelConfig-meetgames.sample.json +0 -123
  280. package/fixtures/meetsdk-remote-config.download-shape.json +0 -20
  281. package/fixtures/meetsdk-remote-config.mock.json +0 -69
  282. package/fixtures/recipes/android-default.fixture.yaml +0 -15
  283. package/fixtures/recipes/android-integration.fixture.json +0 -29
  284. package/fixtures/topsdk-config-reference.json +0 -39
  285. /package/docs/{api → archive/api}/getSDKConfig.md +0 -0
@@ -0,0 +1,170 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import * as z from "zod";
4
+ import { meetgamesDoctor, meetgamesFetchConfig, meetgamesIntegrate, meetgamesSetup } from "./service.js";
5
+
6
+ function toErrorResult(error: unknown) {
7
+ const message = error instanceof Error ? error.message : String(error);
8
+ return {
9
+ content: [{ type: "text" as const, text: `Error: ${message}` }],
10
+ isError: true,
11
+ };
12
+ }
13
+
14
+ function toSuccessResult<T extends Record<string, unknown>>(data: T) {
15
+ return {
16
+ content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }],
17
+ structuredContent: data,
18
+ };
19
+ }
20
+
21
+ export function createMeetgamesMcpServer(): McpServer {
22
+ const server = new McpServer({
23
+ name: "meetgames-mcp",
24
+ version: "0.1.0",
25
+ });
26
+
27
+ server.registerTool(
28
+ "meetgames_doctor",
29
+ {
30
+ description: "Inspect project workspace and return Android/iOS detection summary.",
31
+ inputSchema: {
32
+ projectRoot: z.string().optional().describe("Absolute or relative project root; default is current working directory."),
33
+ appTarget: z.string().optional().describe("App target to integrate/check: Android application Gradle module or iOS App target name."),
34
+ },
35
+ },
36
+ async ({ projectRoot, appTarget }) => {
37
+ try {
38
+ return toSuccessResult(meetgamesDoctor({ projectRoot, appTarget }));
39
+ } catch (error) {
40
+ return toErrorResult(error);
41
+ }
42
+ }
43
+ );
44
+
45
+ server.registerTool(
46
+ "meetgames_fetch_config",
47
+ {
48
+ description:
49
+ "Download TOPSDK meetsdk-remote-config.json via downloadSDKConfig and write it into project root.",
50
+ inputSchema: {
51
+ projectRoot: z.string().optional().describe("Absolute or relative project root; default is current working directory."),
52
+ env: z.enum(["prod", "pre", "test"]).optional().describe("TOPSDK API environment."),
53
+ appId: z.string().optional().describe("Application id; required if not in local config."),
54
+ appSecret: z.string().optional().describe("Application secret for downloadSDKConfig sign (required unless TOPSDK_APP_SECRET is set)."),
55
+ channelType: z.string().optional().describe("Channel type e.g. GOOGLE; required if not in local config."),
56
+ },
57
+ },
58
+ async ({ projectRoot, env, appId, appSecret, channelType }) => {
59
+ try {
60
+ const result = await meetgamesFetchConfig({
61
+ projectRoot,
62
+ env,
63
+ appId,
64
+ appSecret,
65
+ channelType,
66
+ });
67
+ return toSuccessResult(result);
68
+ } catch (error) {
69
+ return toErrorResult(error);
70
+ }
71
+ }
72
+ );
73
+
74
+ server.registerTool(
75
+ "meetgames_integrate_dry_run",
76
+ {
77
+ description: "Run integrate with built-in recipe in dry-run mode and return report + patch.",
78
+ inputSchema: {
79
+ projectRoot: z.string().optional().describe("Absolute or relative project root; default is current working directory."),
80
+ appTarget: z.string().optional().describe("App target to integrate/check: Android application Gradle module or iOS App target name."),
81
+ },
82
+ },
83
+ async ({ projectRoot, appTarget }) => {
84
+ try {
85
+ const result = await meetgamesIntegrate({ projectRoot, appTarget, dryRun: true });
86
+ if (result.hasErrors) {
87
+ return {
88
+ ...toSuccessResult(result),
89
+ isError: true,
90
+ };
91
+ }
92
+ return toSuccessResult(result);
93
+ } catch (error) {
94
+ return toErrorResult(error);
95
+ }
96
+ }
97
+ );
98
+
99
+ server.registerTool(
100
+ "meetgames_integrate_apply",
101
+ {
102
+ description: "Run integrate with built-in recipe and write changes to disk.",
103
+ inputSchema: {
104
+ projectRoot: z.string().optional().describe("Absolute or relative project root; default is current working directory."),
105
+ appTarget: z.string().optional().describe("App target to integrate/check: Android application Gradle module or iOS App target name."),
106
+ },
107
+ },
108
+ async ({ projectRoot, appTarget }) => {
109
+ try {
110
+ const result = await meetgamesIntegrate({ projectRoot, appTarget, dryRun: false });
111
+ if (result.hasErrors) {
112
+ return {
113
+ ...toSuccessResult(result),
114
+ isError: true,
115
+ };
116
+ }
117
+ return toSuccessResult(result);
118
+ } catch (error) {
119
+ return toErrorResult(error);
120
+ }
121
+ }
122
+ );
123
+
124
+ server.registerTool(
125
+ "meetgames_setup",
126
+ {
127
+ description:
128
+ "Download meetsdk-remote-config.json then run default integrate recipe (fetch-config + integrate).",
129
+ inputSchema: {
130
+ projectRoot: z.string().optional().describe("Absolute or relative project root; default is current working directory."),
131
+ env: z.enum(["prod", "pre", "test"]).optional().describe("TOPSDK API environment."),
132
+ appId: z.string().optional().describe("Application id; required if not in local config."),
133
+ appSecret: z.string().optional().describe("Application secret for downloadSDKConfig sign (required unless TOPSDK_APP_SECRET is set)."),
134
+ channelType: z.string().optional().describe("Channel type e.g. GOOGLE; required if not in local config."),
135
+ appTarget: z.string().optional().describe("App target to integrate/check: Android application Gradle module or iOS App target name."),
136
+ dryRun: z.boolean().optional().describe("If true, integrate step previews only; fetch always writes config."),
137
+ },
138
+ },
139
+ async ({ projectRoot, env, appId, appSecret, channelType, appTarget, dryRun }) => {
140
+ try {
141
+ const result = await meetgamesSetup({
142
+ projectRoot,
143
+ appTarget,
144
+ env,
145
+ appId,
146
+ appSecret,
147
+ channelType,
148
+ dryRun: dryRun ?? false,
149
+ });
150
+ if (result.integrate.hasErrors) {
151
+ return {
152
+ ...toSuccessResult(result),
153
+ isError: true,
154
+ };
155
+ }
156
+ return toSuccessResult(result);
157
+ } catch (error) {
158
+ return toErrorResult(error);
159
+ }
160
+ }
161
+ );
162
+
163
+ return server;
164
+ }
165
+
166
+ export async function startMeetgamesMcpServer(): Promise<void> {
167
+ const server = createMeetgamesMcpServer();
168
+ const transport = new StdioServerTransport();
169
+ await server.connect(transport);
170
+ }
@@ -0,0 +1,222 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { loadManifestFile } from "../config/loadManifest.js";
4
+ import {
5
+ MEETSDK_REMOTE_CONFIG_FILENAME,
6
+ readMeetSdkRemoteChannel,
7
+ tryParseAsMeetSdkRemoteConfig,
8
+ type MeetSdkRemoteConfig,
9
+ } from "../config/meetSdkRemoteConfig.js";
10
+ import {
11
+ validateDownloadSdkConfigForWrite,
12
+ writeDownloadSdkConfigRaw,
13
+ } from "../config/fetchConfigWrite.js";
14
+ import type { PipelineReport } from "../contracts/types.js";
15
+ import type { BinaryCopy } from "../ops/handlers.js";
16
+ import { runPipeline } from "../core/pipeline.js";
17
+ import {
18
+ detectSinglePlatform,
19
+ manifestForPlatform,
20
+ platformContext,
21
+ type DetectedPlatform,
22
+ } from "../core/platform.js";
23
+ import { buildWorkspaceContext, resolvePackageRoot } from "../core/workspace.js";
24
+ import { defaultTopSdkBaseUrl, fetchTopSdkDownloadSdkConfig, type TopSdkApiEnv } from "../remote/topsdkDownloadSdkConfig.js";
25
+
26
+ const DEFAULT_MANIFEST_REL = "recipes/integrate-default.yaml";
27
+
28
+ function ensureProjectRoot(projectRoot?: string): string {
29
+ const root = path.resolve(projectRoot?.trim() || process.cwd());
30
+ if (!fs.existsSync(root) || !fs.statSync(root).isDirectory()) {
31
+ throw new Error(`project root does not exist or is not a directory: ${root}`);
32
+ }
33
+ return root;
34
+ }
35
+
36
+ function readLocalMeetSdkRemoteConfig(projectRoot: string): MeetSdkRemoteConfig | null {
37
+ const configPath = path.join(projectRoot, MEETSDK_REMOTE_CONFIG_FILENAME);
38
+ if (!fs.existsSync(configPath)) return null;
39
+ try {
40
+ return tryParseAsMeetSdkRemoteConfig(JSON.parse(fs.readFileSync(configPath, "utf8")) as unknown);
41
+ } catch {
42
+ return null;
43
+ }
44
+ }
45
+
46
+ function ensureDefaultManifestPath(packageRoot: string): string {
47
+ const manifestPath = path.join(packageRoot, DEFAULT_MANIFEST_REL);
48
+ if (!fs.existsSync(manifestPath)) {
49
+ throw new Error(`default manifest not found: ${manifestPath}`);
50
+ }
51
+ return manifestPath;
52
+ }
53
+
54
+ function ensureSinglePlatformContext(
55
+ projectRoot: string,
56
+ packageRoot: string,
57
+ appTarget?: string
58
+ ): {
59
+ platform: DetectedPlatform;
60
+ ctx: ReturnType<typeof buildWorkspaceContext>;
61
+ } {
62
+ const detectedCtx = buildWorkspaceContext(projectRoot, packageRoot, { appTarget });
63
+ const detected = detectSinglePlatform(detectedCtx);
64
+ if (!detected.ok) throw new Error(detected.error);
65
+ const platformCtx = platformContext(detectedCtx, detected.platform);
66
+ return {
67
+ platform: detected.platform,
68
+ ctx: platformCtx,
69
+ };
70
+ }
71
+
72
+ function resolveAppTarget(params: { appTarget?: string }): string | undefined {
73
+ return params.appTarget?.trim() || undefined;
74
+ }
75
+
76
+ export function meetgamesDoctor(params: { projectRoot?: string; appTarget?: string }): {
77
+ projectRoot: string;
78
+ packageRoot: string;
79
+ platform: DetectedPlatform;
80
+ android?: object;
81
+ ios?: object;
82
+ iosReserved?: object;
83
+ } {
84
+ const projectRoot = ensureProjectRoot(params.projectRoot);
85
+ const packageRoot = resolvePackageRoot();
86
+ const { platform, ctx } = ensureSinglePlatformContext(
87
+ projectRoot,
88
+ packageRoot,
89
+ resolveAppTarget(params)
90
+ );
91
+ const out: {
92
+ projectRoot: string;
93
+ packageRoot: string;
94
+ platform: DetectedPlatform;
95
+ android?: object;
96
+ ios?: object;
97
+ iosReserved?: object;
98
+ } = {
99
+ projectRoot: ctx.projectRoot,
100
+ packageRoot: ctx.packageRoot,
101
+ platform,
102
+ };
103
+ if (platform === "android") out.android = ctx.android;
104
+ if (platform === "ios") {
105
+ out.ios = ctx.ios;
106
+ out.iosReserved = ctx.iosReserved;
107
+ }
108
+ return out;
109
+ }
110
+
111
+ export async function meetgamesFetchConfig(params: {
112
+ projectRoot?: string;
113
+ env?: TopSdkApiEnv;
114
+ appId?: string;
115
+ appSecret?: string;
116
+ channelType?: string;
117
+ }): Promise<{
118
+ outputPath: string;
119
+ requestUrl: string;
120
+ env: TopSdkApiEnv;
121
+ warnings: string[];
122
+ }> {
123
+ const projectRoot = ensureProjectRoot(params.projectRoot);
124
+ const out = path.join(projectRoot, MEETSDK_REMOTE_CONFIG_FILENAME);
125
+ const localConfig = readLocalMeetSdkRemoteConfig(projectRoot);
126
+
127
+ const appId = params.appId || localConfig?.topsdk.appId || process.env.TOPSDK_APP_ID || "";
128
+ const appSecret = params.appSecret || process.env.TOPSDK_APP_SECRET || "";
129
+ const channelType =
130
+ params.channelType ||
131
+ (localConfig ? readMeetSdkRemoteChannel(localConfig) : "") ||
132
+ process.env.TOPSDK_CHANNEL_TYPE ||
133
+ "";
134
+ const env = params.env ?? "prod";
135
+ const warnings: string[] = [];
136
+
137
+ if (!appId || !channelType || !appSecret) {
138
+ throw new Error(
139
+ `fetch-config requires appId, appSecret, and channelType (appSecret via appSecret param or TOPSDK_APP_SECRET only; not from ${MEETSDK_REMOTE_CONFIG_FILENAME}).`
140
+ );
141
+ }
142
+
143
+ const baseUrl = process.env.TOPSDK_API_BASE_URL?.trim() || defaultTopSdkBaseUrl(env);
144
+ const res = await fetchTopSdkDownloadSdkConfig({
145
+ baseUrl,
146
+ appId,
147
+ appSecret,
148
+ channelType,
149
+ });
150
+ const validation = validateDownloadSdkConfigForWrite(res.body);
151
+ if (!validation) {
152
+ throw new Error(`downloadSDKConfig response is not a valid ${MEETSDK_REMOTE_CONFIG_FILENAME} document`);
153
+ }
154
+ warnings.push(...validation.warnings);
155
+
156
+ writeDownloadSdkConfigRaw(out, res.text);
157
+ return { outputPath: out, requestUrl: res.url, env, warnings };
158
+ }
159
+
160
+ export async function meetgamesIntegrate(params: {
161
+ projectRoot?: string;
162
+ appTarget?: string;
163
+ dryRun: boolean;
164
+ }): Promise<{
165
+ dryRun: boolean;
166
+ manifestPath: string;
167
+ report: PipelineReport;
168
+ patch: string;
169
+ binaryCopies: BinaryCopy[];
170
+ hasErrors: boolean;
171
+ }> {
172
+ const projectRoot = ensureProjectRoot(params.projectRoot);
173
+ const packageRoot = resolvePackageRoot();
174
+ const manifestPath = ensureDefaultManifestPath(packageRoot);
175
+ const manifest = loadManifestFile(manifestPath);
176
+ const { platform, ctx } = ensureSinglePlatformContext(
177
+ projectRoot,
178
+ packageRoot,
179
+ resolveAppTarget(params)
180
+ );
181
+ const { report, patch, binaryCopies } = await runPipeline(ctx, manifestForPlatform(manifest, platform), { dryRun: params.dryRun });
182
+ return {
183
+ dryRun: params.dryRun,
184
+ manifestPath,
185
+ report,
186
+ patch,
187
+ binaryCopies,
188
+ hasErrors: report.errors.length > 0,
189
+ };
190
+ }
191
+
192
+ /** 先 downloadSDKConfig 落盘,再跑默认 integrate 配方(与 CLI `setup` 一致)。 */
193
+ export async function meetgamesSetup(params: {
194
+ projectRoot?: string;
195
+ appTarget?: string;
196
+ env?: TopSdkApiEnv;
197
+ appId?: string;
198
+ appSecret?: string;
199
+ channelType?: string;
200
+ dryRun: boolean;
201
+ }): Promise<{
202
+ fetch: Awaited<ReturnType<typeof meetgamesFetchConfig>>;
203
+ integrate: Awaited<ReturnType<typeof meetgamesIntegrate>>;
204
+ }> {
205
+ const projectRoot = ensureProjectRoot(params.projectRoot);
206
+ const packageRoot = resolvePackageRoot();
207
+ const appTarget = resolveAppTarget(params);
208
+ ensureSinglePlatformContext(projectRoot, packageRoot, appTarget);
209
+ const fetch = await meetgamesFetchConfig({
210
+ projectRoot,
211
+ env: params.env,
212
+ appId: params.appId,
213
+ appSecret: params.appSecret,
214
+ channelType: params.channelType,
215
+ });
216
+ const integrate = await meetgamesIntegrate({
217
+ projectRoot,
218
+ appTarget,
219
+ dryRun: params.dryRun,
220
+ });
221
+ return { fetch, integrate };
222
+ }
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import { startMeetgamesMcpServer } from "./mcp/server.js";
3
+
4
+ startMeetgamesMcpServer().catch((err: unknown) => {
5
+ console.error(err);
6
+ process.exit(1);
7
+ });
@@ -0,0 +1,56 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+
4
+ /** Tracks text file originals and pending content for dry-run / apply */
5
+ export class TextFileStore {
6
+ private readonly projectRoot: string;
7
+ private readonly map = new Map<string, { original: string; current: string }>();
8
+
9
+ constructor(projectRoot: string) {
10
+ this.projectRoot = projectRoot;
11
+ }
12
+
13
+ rel(abs: string): string {
14
+ return path.relative(this.projectRoot, abs).split(path.sep).join("/");
15
+ }
16
+
17
+ read(rel: string): string {
18
+ const existing = this.map.get(rel);
19
+ if (existing) return existing.current;
20
+ const abs = path.join(this.projectRoot, rel);
21
+ if (!fs.existsSync(abs)) return "";
22
+ const content = fs.readFileSync(abs, "utf8");
23
+ this.map.set(rel, { original: content, current: content });
24
+ return content;
25
+ }
26
+
27
+ write(rel: string, content: string): void {
28
+ const abs = path.join(this.projectRoot, rel);
29
+ const existing = this.map.get(rel);
30
+ if (existing) {
31
+ existing.current = content;
32
+ return;
33
+ }
34
+ let original = "";
35
+ if (fs.existsSync(abs)) original = fs.readFileSync(abs, "utf8");
36
+ this.map.set(rel, { original, current: content });
37
+ }
38
+
39
+ /** Files where current !== original */
40
+ changedEntries(): Array<{ rel: string; original: string; current: string }> {
41
+ const out: Array<{ rel: string; original: string; current: string }> = [];
42
+ for (const [rel, v] of this.map) {
43
+ if (v.current !== v.original) out.push({ rel, original: v.original, current: v.current });
44
+ }
45
+ return out;
46
+ }
47
+
48
+ flushToDisk(): void {
49
+ for (const [rel, v] of this.map) {
50
+ if (v.current === v.original) continue;
51
+ const abs = path.join(this.projectRoot, rel);
52
+ fs.mkdirSync(path.dirname(abs), { recursive: true });
53
+ fs.writeFileSync(abs, v.current, "utf8");
54
+ }
55
+ }
56
+ }