androjack-mcp 1.3.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.
Files changed (70) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +34 -0
  3. package/.github/pull_request_template.md +16 -0
  4. package/CONTRIBUTING.md +27 -0
  5. package/LICENSE +21 -0
  6. package/README.md +592 -0
  7. package/SECURITY.md +26 -0
  8. package/assets/AndroJack banner.png +0 -0
  9. package/assets/killer_argument.png +0 -0
  10. package/build/constants.js +412 -0
  11. package/build/http-server.js +163 -0
  12. package/build/http.js +151 -0
  13. package/build/index.js +553 -0
  14. package/build/install.js +379 -0
  15. package/build/logger.js +57 -0
  16. package/build/tools/api-level.js +170 -0
  17. package/build/tools/api36-compliance.js +282 -0
  18. package/build/tools/architecture.js +75 -0
  19. package/build/tools/build-publish.js +362 -0
  20. package/build/tools/component.js +90 -0
  21. package/build/tools/debugger.js +82 -0
  22. package/build/tools/gradle.js +234 -0
  23. package/build/tools/kmp.js +348 -0
  24. package/build/tools/kotlin-patterns.js +500 -0
  25. package/build/tools/large-screen.js +366 -0
  26. package/build/tools/m3-expressive.js +447 -0
  27. package/build/tools/navigation3.js +331 -0
  28. package/build/tools/ondevice-ai.js +283 -0
  29. package/build/tools/permissions.js +404 -0
  30. package/build/tools/play-policy.js +221 -0
  31. package/build/tools/scalability.js +621 -0
  32. package/build/tools/search.js +89 -0
  33. package/build/tools/testing.js +439 -0
  34. package/build/tools/wear.js +337 -0
  35. package/build/tools/xr.js +274 -0
  36. package/config/antigravity_mcp.json +32 -0
  37. package/config/claude_desktop_config.json +17 -0
  38. package/config/cursor_mcp.json +21 -0
  39. package/config/jetbrains_mcp.json +28 -0
  40. package/config/kiro_mcp.json +40 -0
  41. package/config/vscode_mcp.json +24 -0
  42. package/config/windsurf_mcp.json +18 -0
  43. package/package.json +51 -0
  44. package/src/constants.ts +436 -0
  45. package/src/http-server.ts +186 -0
  46. package/src/http.ts +190 -0
  47. package/src/index.ts +702 -0
  48. package/src/install.ts +441 -0
  49. package/src/logger.ts +67 -0
  50. package/src/tools/api-level.ts +198 -0
  51. package/src/tools/api36-compliance.ts +289 -0
  52. package/src/tools/architecture.ts +94 -0
  53. package/src/tools/build-publish.ts +379 -0
  54. package/src/tools/component.ts +106 -0
  55. package/src/tools/debugger.ts +111 -0
  56. package/src/tools/gradle.ts +288 -0
  57. package/src/tools/kmp.ts +352 -0
  58. package/src/tools/kotlin-patterns.ts +534 -0
  59. package/src/tools/large-screen.ts +391 -0
  60. package/src/tools/m3-expressive.ts +473 -0
  61. package/src/tools/navigation3.ts +338 -0
  62. package/src/tools/ondevice-ai.ts +287 -0
  63. package/src/tools/permissions.ts +445 -0
  64. package/src/tools/play-policy.ts +229 -0
  65. package/src/tools/scalability.ts +646 -0
  66. package/src/tools/search.ts +112 -0
  67. package/src/tools/testing.ts +460 -0
  68. package/src/tools/wear.ts +343 -0
  69. package/src/tools/xr.ts +278 -0
  70. package/tsconfig.json +17 -0
@@ -0,0 +1,366 @@
1
+ /**
2
+ * Tool 12 – android_large_screen_guide
3
+ *
4
+ * Complete reference for Android large screen and adaptive layout development.
5
+ * Google Play Store quality guidelines require apps to properly support
6
+ * tablets, foldables, and ChromeOS — this tool enforces that standard.
7
+ *
8
+ * Sources:
9
+ * - developer.android.com/guide/topics/large-screens
10
+ * - developer.android.com/develop/ui/compose/layouts/adaptive
11
+ * - developer.android.com/develop/ui/views/layout/responsive-ui
12
+ */
13
+ // ── Knowledge base ─────────────────────────────────────────────────────────────
14
+ const OVERVIEW = `
15
+ ## Android Large Screen & Adaptive Layout Overview
16
+
17
+ ### Why this matters — Play Store quality bar (2024+)
18
+ Google Play now surfaces large-screen-optimized apps preferentially on tablets and foldables.
19
+ Apps that don't support large screens receive lower quality ratings that reduce discovery.
20
+
21
+ ### The three device classes (WindowSizeClass)
22
+
23
+ | Class | Width | Typical Device |
24
+ |-------|-------|---------------|
25
+ | Compact | < 600dp | Phone portrait |
26
+ | Medium | 600–840dp | Phone landscape, foldable, small tablet |
27
+ | Expanded | > 840dp | Tablet, large foldable unfolded, ChromeOS |
28
+
29
+ Rule: **Design for Compact first, adapt for Medium and Expanded.**
30
+
31
+ ### Key Jetpack libraries
32
+
33
+ \`\`\`kotlin
34
+ // libs.versions.toml
35
+ window = { group = "androidx.window", name = "window", version = "1.4.0" }
36
+ adaptive = { group = "androidx.compose.material3.adaptive", name = "adaptive", version = "1.1.0" }
37
+ adaptive-nav = { group = "androidx.compose.material3.adaptive", name = "adaptive-navigation", version = "1.1.0" }
38
+
39
+ // build.gradle.kts
40
+ implementation(libs.window)
41
+ implementation(libs.adaptive)
42
+ implementation(libs.adaptive.nav)
43
+ \`\`\`
44
+
45
+ **Official guide:** https://developer.android.com/guide/topics/large-screens/get-started-with-large-screens
46
+ `;
47
+ const WINDOW_SIZE_CLASS = `
48
+ ## WindowSizeClass — Adaptive Layout Foundation
49
+
50
+ \`\`\`kotlin
51
+ // Source: developer.android.com/develop/ui/compose/layouts/adaptive/use-window-size-classes
52
+
53
+ // ── In your Activity / entry Composable ──────────────────────────────
54
+ @Composable
55
+ fun App() {
56
+ // currentWindowAdaptiveInfo provides WindowSizeClass + FoldingFeature
57
+ val adaptiveInfo = currentWindowAdaptiveInfo()
58
+ val windowSizeClass = adaptiveInfo.windowSizeClass
59
+
60
+ AppContent(windowSizeClass = windowSizeClass)
61
+ }
62
+
63
+ @Composable
64
+ fun AppContent(windowSizeClass: WindowSizeClass) {
65
+ when {
66
+ windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_EXPANDED_LOWER_BOUND) -> {
67
+ // Expanded — show two-pane layout (list + detail side-by-side)
68
+ TwoPaneLayout()
69
+ }
70
+ windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) -> {
71
+ // Medium — show navigation rail
72
+ NavigationRailLayout()
73
+ }
74
+ else -> {
75
+ // Compact — show bottom navigation
76
+ BottomNavLayout()
77
+ }
78
+ }
79
+ }
80
+ \`\`\`
81
+
82
+ ### WindowSizeClass breakpoints (dp)
83
+
84
+ | Breakpoint constant | Value |
85
+ |---------------------|-------|
86
+ | WIDTH_DP_COMPACT_LOWER_BOUND | 0dp |
87
+ | WIDTH_DP_MEDIUM_LOWER_BOUND | 600dp |
88
+ | WIDTH_DP_EXPANDED_LOWER_BOUND | 840dp |
89
+ | HEIGHT_DP_COMPACT_LOWER_BOUND | 0dp |
90
+ | HEIGHT_DP_MEDIUM_LOWER_BOUND | 480dp |
91
+ | HEIGHT_DP_EXPANDED_LOWER_BOUND | 900dp |
92
+ `;
93
+ const NAVIGATION_PATTERNS = `
94
+ ## Adaptive Navigation — M3 NavigationSuiteScaffold
95
+
96
+ The correct M3 pattern adapts navigation component type automatically based on window size.
97
+
98
+ \`\`\`kotlin
99
+ // Source: developer.android.com/develop/ui/compose/layouts/adaptive/adaptive-navigation-suite-scaffold
100
+
101
+ // ── Setup ─────────────────────────────────────────────────────────────
102
+ // Dependency:
103
+ // implementation("androidx.compose.material3:material3-adaptive-navigation-suite:1.4.0")
104
+
105
+ enum class AppDestination(val icon: ImageVector, val label: String) {
106
+ HOME(Icons.Filled.Home, "Home"),
107
+ SEARCH(Icons.Filled.Search, "Search"),
108
+ PROFILE(Icons.Filled.Person, "Profile"),
109
+ }
110
+
111
+ @Composable
112
+ fun AdaptiveApp() {
113
+ var currentDest by remember { mutableStateOf(AppDestination.HOME) }
114
+
115
+ // NavigationSuiteScaffold automatically switches between:
116
+ // - BottomNavigationBar (Compact width)
117
+ // - NavigationRail (Medium width)
118
+ // - NavigationDrawer (Expanded width)
119
+ NavigationSuiteScaffold(
120
+ navigationSuiteItems = {
121
+ AppDestination.entries.forEach { dest ->
122
+ item(
123
+ icon = { Icon(dest.icon, contentDescription = dest.label) },
124
+ label = { Text(dest.label) },
125
+ selected = currentDest == dest,
126
+ onClick = { currentDest = dest }
127
+ )
128
+ }
129
+ }
130
+ ) {
131
+ when (currentDest) {
132
+ AppDestination.HOME -> HomeScreen()
133
+ AppDestination.SEARCH -> SearchScreen()
134
+ AppDestination.PROFILE -> ProfileScreen()
135
+ }
136
+ }
137
+ }
138
+ \`\`\`
139
+ `;
140
+ const TWO_PANE = `
141
+ ## Two-Pane List-Detail Layout
142
+
143
+ The canonical large screen pattern: list on left, detail on right.
144
+ Use ListDetailPaneScaffold from the Adaptive library.
145
+
146
+ \`\`\`kotlin
147
+ // Source: developer.android.com/develop/ui/compose/layouts/adaptive/list-detail-pane-scaffold
148
+
149
+ @Composable
150
+ fun UserListDetailScreen() {
151
+ val navigator = rememberListDetailPaneScaffoldNavigator<Int>()
152
+
153
+ BackHandler(navigator.canNavigateBack()) {
154
+ navigator.navigateBack()
155
+ }
156
+
157
+ ListDetailPaneScaffold(
158
+ directive = navigator.scaffoldDirective,
159
+ value = navigator.scaffoldValue,
160
+ listPane = {
161
+ AnimatedPane {
162
+ UserList(
163
+ onUserClick = { userId ->
164
+ navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, userId)
165
+ }
166
+ )
167
+ }
168
+ },
169
+ detailPane = {
170
+ AnimatedPane {
171
+ navigator.currentDestination?.content?.let { userId ->
172
+ UserDetailScreen(userId = userId)
173
+ } ?: run {
174
+ // Placeholder shown when no item is selected
175
+ Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
176
+ Text("Select a user")
177
+ }
178
+ }
179
+ }
180
+ }
181
+ )
182
+ }
183
+ \`\`\`
184
+
185
+ ### Key behaviors
186
+ - **Compact** — full-screen list; detail replaces list on navigation
187
+ - **Expanded** — list and detail shown side-by-side simultaneously
188
+ - **BackHandler** required — system back should navigate back to list on compact
189
+ `;
190
+ const FOLDABLES = `
191
+ ## Foldables — Hinge & Fold Awareness
192
+
193
+ \`\`\`kotlin
194
+ // Source: developer.android.com/guide/topics/large-screens/learn-about-foldables
195
+
196
+ @Composable
197
+ fun FoldAwareLayout() {
198
+ val foldingFeature = currentWindowAdaptiveInfo().windowPosture.hingeList.firstOrNull()
199
+
200
+ if (foldingFeature != null && foldingFeature.isSeparating) {
201
+ // Device is folded at the hinge — show content on each half
202
+ val hingeLeft = foldingFeature.bounds.left
203
+ val hingeRight = foldingFeature.bounds.right
204
+ // Place content avoiding the hinge area
205
+ TwoHalvesLayout(leftBound = hingeLeft, rightBound = hingeRight)
206
+ } else {
207
+ // Unfolded or non-foldable — standard layout
208
+ StandardLayout()
209
+ }
210
+ }
211
+
212
+ // ── WindowInfoTracker for non-Compose contexts ────────────────────────
213
+ // In an Activity or Fragment:
214
+ lifecycleScope.launch {
215
+ lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
216
+ WindowInfoTracker.getOrCreate(this@MainActivity)
217
+ .windowLayoutInfo(this@MainActivity)
218
+ .collect { layoutInfo ->
219
+ val foldingFeatures = layoutInfo.displayFeatures
220
+ .filterIsInstance<FoldingFeature>()
221
+ // React to fold state changes
222
+ }
223
+ }
224
+ }
225
+ \`\`\`
226
+
227
+ ### FoldingFeature properties
228
+ | Property | Values | Meaning |
229
+ |----------|--------|---------|
230
+ | \`state\` | FLAT, HALF_OPENED | Current fold angle |
231
+ | \`orientation\` | HORIZONTAL, VERTICAL | Hinge direction |
232
+ | \`isSeparating\` | true/false | Whether hinge occludes content |
233
+ | \`occlusionType\` | NONE, FULL | Whether hinge is physically present |
234
+ `;
235
+ const CONTINUITY = `
236
+ ## Continuity — Surviving Configuration Changes
237
+
238
+ Large screen apps get more configuration changes (fold/unfold, rotation, window resize).
239
+
240
+ \`\`\`kotlin
241
+ // ── ViewModel survives ALL config changes ─────────────────────────────
242
+ // (already the correct pattern — nothing extra needed)
243
+
244
+ // ── Compose state that survives process death ─────────────────────────
245
+ // Use rememberSaveable + a custom saver for complex types:
246
+ @Composable
247
+ fun PersistentScreen() {
248
+ var selectedId by rememberSaveable { mutableStateOf<Int?>(null) }
249
+ // selectedId survives rotation, fold, and process death
250
+ }
251
+
252
+ // ── For complex types, write a Saver: ─────────────────────────────────
253
+ val UiStateSaver = Saver<UiState, Int>(
254
+ save = { state -> (state as? UiState.Success)?.data?.id ?: -1 },
255
+ restore = { id -> if (id >= 0) UiState.Success(User(id, "")) else UiState.Loading }
256
+ )
257
+ var state by rememberSaveable(stateSaver = UiStateSaver) { mutableStateOf(UiState.Loading) }
258
+
259
+ // ── Test config changes in unit test ──────────────────────────────────
260
+ // ActivityScenario handles rotation:
261
+ activityScenario.onActivity { activity ->
262
+ activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
263
+ }
264
+ // Verify ViewModel state persists across rotation
265
+ \`\`\`
266
+
267
+ ### Manifest — do NOT disable config changes for large screen
268
+ \`\`\`xml
269
+ <!-- ❌ Anti-pattern — breaks system-managed resizing on large screens -->
270
+ <activity android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout">
271
+
272
+ <!-- ✅ Let the system handle it; use ViewModel + rememberSaveable -->
273
+ <!-- No configChanges needed for most apps -->
274
+ \`\`\`
275
+ `;
276
+ const PLAY_QUALITY = `
277
+ ## Google Play Large Screen Quality Guidelines
278
+
279
+ **Source:** developer.android.com/docs/quality-guidelines/large-screen-app-quality
280
+
281
+ ### Tier 1 — Large Screen Optimized (required for Featured placement)
282
+ - [ ] App functional in landscape orientation on tablet
283
+ - [ ] No hardcoded portrait-only orientation in manifest
284
+ - [ ] No distortion or pixel-scaling artifacts on large screen
285
+ - [ ] Correctly handles multi-window (split-screen) mode
286
+ - [ ] UI is not stretched/letter-boxed — uses full width on tablets
287
+ - [ ] \`resizeableActivity\` not set to \`false\`
288
+
289
+ ### Tier 2 — Large Screen Ready
290
+ - [ ] NavigationSuiteScaffold or equivalent (Rail on medium, Drawer on expanded)
291
+ - [ ] Two-pane list-detail layout for list → detail flows on expanded
292
+ - [ ] No input devices missing (keyboard, mouse support for ChromeOS)
293
+ - [ ] Keyboard navigation works via Tab and arrow keys
294
+ - [ ] Predictive back gesture implemented
295
+
296
+ ### Manifest requirements
297
+ \`\`\`xml
298
+ <manifest>
299
+ <!-- Support all screen sizes -->
300
+ <supports-screens
301
+ android:smallScreens="true"
302
+ android:normalScreens="true"
303
+ android:largeScreens="true"
304
+ android:xlargeScreens="true"
305
+ android:resizeable="true" />
306
+
307
+ <application>
308
+ <!-- CRITICAL: Do NOT set android:screenOrientation="portrait" for any Activity -->
309
+ <!-- CRITICAL: Do NOT set android:resizeableActivity="false" -->
310
+ <activity android:name=".MainActivity"
311
+ android:windowSoftInputMode="adjustResize" />
312
+ </application>
313
+ </manifest>
314
+ \`\`\`
315
+
316
+ **Checklist tool:** https://developer.android.com/docs/quality-guidelines/large-screen-app-quality
317
+ `;
318
+ // ── Topic routing ──────────────────────────────────────────────────────────────
319
+ const TOPICS = [
320
+ { keywords: ["overview", "intro", "what is", "large screen", "adaptive", "why"], content: OVERVIEW },
321
+ { keywords: ["windowsizeclass", "window size", "breakpoint", "compact", "medium", "expanded", "class"], content: WINDOW_SIZE_CLASS },
322
+ { keywords: ["navigation", "rail", "drawer", "bottom nav", "navigationsuitescaffold", "adaptive nav"], content: NAVIGATION_PATTERNS },
323
+ { keywords: ["two pane", "twopane", "list detail", "split", "listdetailpane", "detail pane"], content: TWO_PANE },
324
+ { keywords: ["fold", "foldable", "hinge", "unfold", "half", "windowinfotracker", "foldingfeature"], content: FOLDABLES },
325
+ { keywords: ["config", "continuity", "rotation", "orientation", "rememberSaveable", "configChanges", "survive", "persist"], content: CONTINUITY },
326
+ { keywords: ["play", "quality", "tier", "checklist", "guideline", "requirement", "manifest", "optimize"], content: PLAY_QUALITY },
327
+ ];
328
+ const INDEX = `
329
+ ## Android Large Screen & Adaptive Layout Guide
330
+
331
+ **Query topics available:**
332
+
333
+ | Topic | Example query |
334
+ |-------|----|
335
+ | Overview & device classes | "large screen overview" |
336
+ | WindowSizeClass | "windowsizeclass breakpoints" |
337
+ | Adaptive navigation | "NavigationSuiteScaffold" |
338
+ | List-detail two-pane | "ListDetailPaneScaffold" |
339
+ | Foldables & hinge | "foldable hinge FoldingFeature" |
340
+ | Config change continuity | "survive rotation rememberSaveable" |
341
+ | Play Store quality bar | "Play quality checklist" |
342
+
343
+ **Official sources:**
344
+ - https://developer.android.com/guide/topics/large-screens
345
+ - https://developer.android.com/develop/ui/compose/layouts/adaptive
346
+ - https://developer.android.com/docs/quality-guidelines/large-screen-app-quality
347
+ `;
348
+ export async function androidLargeScreenGuide(topic) {
349
+ const trimmed = topic.trim();
350
+ if (!trimmed || trimmed.toLowerCase() === "list" || trimmed.toLowerCase() === "help") {
351
+ return INDEX;
352
+ }
353
+ const lower = trimmed.toLowerCase();
354
+ const found = TOPICS.find(t => t.keywords.some(k => lower.includes(k)));
355
+ if (found) {
356
+ return (found.content.trim() +
357
+ `\n\n---\n` +
358
+ `**Official docs:** https://developer.android.com/guide/topics/large-screens\n` +
359
+ `> 📐 GROUNDING GATE: Large screen code must use WindowSizeClass, NavigationSuiteScaffold, and ListDetailPaneScaffold — not hardcoded pixel values or orientation locks.`);
360
+ }
361
+ return (`## Large Screen: "${trimmed}"\n\n` +
362
+ `No built-in entry found. Check:\n` +
363
+ `- https://developer.android.com/guide/topics/large-screens\n` +
364
+ `- https://developer.android.com/develop/ui/compose/layouts/adaptive\n\n` +
365
+ INDEX);
366
+ }