replicant-mcp 1.0.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 (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +386 -0
  3. package/dist/adapters/adb.d.ts +21 -0
  4. package/dist/adapters/adb.js +75 -0
  5. package/dist/adapters/emulator.d.ts +19 -0
  6. package/dist/adapters/emulator.js +72 -0
  7. package/dist/adapters/gradle.d.ts +20 -0
  8. package/dist/adapters/gradle.js +80 -0
  9. package/dist/adapters/index.d.ts +4 -0
  10. package/dist/adapters/index.js +4 -0
  11. package/dist/adapters/ui-automator.d.ts +23 -0
  12. package/dist/adapters/ui-automator.js +53 -0
  13. package/dist/cli/adb.d.ts +2 -0
  14. package/dist/cli/adb.js +256 -0
  15. package/dist/cli/cache.d.ts +2 -0
  16. package/dist/cli/cache.js +115 -0
  17. package/dist/cli/emulator.d.ts +2 -0
  18. package/dist/cli/emulator.js +181 -0
  19. package/dist/cli/formatter.d.ts +52 -0
  20. package/dist/cli/formatter.js +68 -0
  21. package/dist/cli/gradle.d.ts +2 -0
  22. package/dist/cli/gradle.js +192 -0
  23. package/dist/cli/index.d.ts +6 -0
  24. package/dist/cli/index.js +6 -0
  25. package/dist/cli/ui.d.ts +2 -0
  26. package/dist/cli/ui.js +218 -0
  27. package/dist/cli.d.ts +2 -0
  28. package/dist/cli.js +14 -0
  29. package/dist/index.d.ts +2 -0
  30. package/dist/index.js +6 -0
  31. package/dist/parsers/adb-output.d.ts +4 -0
  32. package/dist/parsers/adb-output.js +32 -0
  33. package/dist/parsers/emulator-output.d.ts +9 -0
  34. package/dist/parsers/emulator-output.js +33 -0
  35. package/dist/parsers/gradle-output.d.ts +30 -0
  36. package/dist/parsers/gradle-output.js +80 -0
  37. package/dist/parsers/index.d.ts +4 -0
  38. package/dist/parsers/index.js +4 -0
  39. package/dist/parsers/ui-dump.d.ts +27 -0
  40. package/dist/parsers/ui-dump.js +142 -0
  41. package/dist/server.d.ts +15 -0
  42. package/dist/server.js +113 -0
  43. package/dist/services/cache-manager.d.ts +22 -0
  44. package/dist/services/cache-manager.js +90 -0
  45. package/dist/services/device-state.d.ts +9 -0
  46. package/dist/services/device-state.js +26 -0
  47. package/dist/services/index.d.ts +3 -0
  48. package/dist/services/index.js +3 -0
  49. package/dist/services/process-runner.d.ts +15 -0
  50. package/dist/services/process-runner.js +62 -0
  51. package/dist/tools/adb-app.d.ts +38 -0
  52. package/dist/tools/adb-app.js +68 -0
  53. package/dist/tools/adb-device.d.ts +31 -0
  54. package/dist/tools/adb-device.js +71 -0
  55. package/dist/tools/adb-logcat.d.ts +54 -0
  56. package/dist/tools/adb-logcat.js +70 -0
  57. package/dist/tools/adb-shell.d.ts +26 -0
  58. package/dist/tools/adb-shell.js +27 -0
  59. package/dist/tools/cache.d.ts +50 -0
  60. package/dist/tools/cache.js +57 -0
  61. package/dist/tools/emulator-device.d.ts +56 -0
  62. package/dist/tools/emulator-device.js +132 -0
  63. package/dist/tools/gradle-build.d.ts +35 -0
  64. package/dist/tools/gradle-build.js +40 -0
  65. package/dist/tools/gradle-get-details.d.ts +32 -0
  66. package/dist/tools/gradle-get-details.js +72 -0
  67. package/dist/tools/gradle-list.d.ts +30 -0
  68. package/dist/tools/gradle-list.js +55 -0
  69. package/dist/tools/gradle-test.d.ts +34 -0
  70. package/dist/tools/gradle-test.js +40 -0
  71. package/dist/tools/index.d.ts +12 -0
  72. package/dist/tools/index.js +12 -0
  73. package/dist/tools/rtfm.d.ts +26 -0
  74. package/dist/tools/rtfm.js +70 -0
  75. package/dist/tools/ui.d.ts +77 -0
  76. package/dist/tools/ui.js +131 -0
  77. package/dist/types/cache.d.ts +24 -0
  78. package/dist/types/cache.js +14 -0
  79. package/dist/types/device.d.ts +11 -0
  80. package/dist/types/device.js +1 -0
  81. package/dist/types/errors.d.ts +31 -0
  82. package/dist/types/errors.js +43 -0
  83. package/dist/types/index.d.ts +3 -0
  84. package/dist/types/index.js +3 -0
  85. package/package.json +64 -0
@@ -0,0 +1,70 @@
1
+ import { z } from "zod";
2
+ import { CACHE_TTLS } from "../types/index.js";
3
+ export const adbLogcatInputSchema = z.object({
4
+ lines: z.number().optional().default(100),
5
+ package: z.string().optional(),
6
+ tags: z.array(z.string()).optional(),
7
+ level: z.enum(["verbose", "debug", "info", "warn", "error"]).optional(),
8
+ rawFilter: z.string().optional(),
9
+ since: z.string().optional(),
10
+ });
11
+ export async function handleAdbLogcatTool(input, context) {
12
+ const deviceId = context.deviceState.requireCurrentDevice().id;
13
+ // Build filter string
14
+ let filter = "";
15
+ if (input.rawFilter) {
16
+ filter = input.rawFilter;
17
+ }
18
+ else if (input.tags || input.level) {
19
+ const levelMap = {
20
+ verbose: "V",
21
+ debug: "D",
22
+ info: "I",
23
+ warn: "W",
24
+ error: "E",
25
+ };
26
+ const levelChar = input.level ? levelMap[input.level] : "V";
27
+ if (input.tags) {
28
+ filter = input.tags.map((tag) => `${tag}:${levelChar}`).join(" ") + " *:S";
29
+ }
30
+ else {
31
+ filter = `*:${levelChar}`;
32
+ }
33
+ }
34
+ const output = await context.adb.logcat(deviceId, {
35
+ lines: input.lines,
36
+ filter: filter || undefined,
37
+ });
38
+ // Cache the full output and return a summary
39
+ const logId = context.cache.generateId("logcat");
40
+ context.cache.set(logId, { output, deviceId, filter }, "logcat", CACHE_TTLS.UI_TREE);
41
+ // Parse log lines
42
+ const lines = output.split("\n").filter(Boolean);
43
+ const errorCount = lines.filter((l) => l.includes(" E ")).length;
44
+ const warnCount = lines.filter((l) => l.includes(" W ")).length;
45
+ return {
46
+ logId,
47
+ summary: {
48
+ lineCount: lines.length,
49
+ errorCount,
50
+ warnCount,
51
+ },
52
+ preview: lines.slice(0, 20).join("\n"),
53
+ deviceId,
54
+ };
55
+ }
56
+ export const adbLogcatToolDefinition = {
57
+ name: "adb-logcat",
58
+ description: "Read device logs. Returns summary with logId for full output.",
59
+ inputSchema: {
60
+ type: "object",
61
+ properties: {
62
+ lines: { type: "number", description: "Number of lines (default: 100)" },
63
+ package: { type: "string", description: "Filter by package name" },
64
+ tags: { type: "array", items: { type: "string" }, description: "Filter by log tags" },
65
+ level: { type: "string", enum: ["verbose", "debug", "info", "warn", "error"] },
66
+ rawFilter: { type: "string", description: "Raw logcat filter string" },
67
+ since: { type: "string", description: "Time filter (e.g., '5m' or ISO timestamp)" },
68
+ },
69
+ },
70
+ };
@@ -0,0 +1,26 @@
1
+ import { z } from "zod";
2
+ import { ServerContext } from "../server.js";
3
+ export declare const adbShellInputSchema: z.ZodObject<{
4
+ command: z.ZodString;
5
+ timeout: z.ZodOptional<z.ZodNumber>;
6
+ }, z.core.$strip>;
7
+ export type AdbShellInput = z.infer<typeof adbShellInputSchema>;
8
+ export declare function handleAdbShellTool(input: AdbShellInput, context: ServerContext): Promise<Record<string, unknown>>;
9
+ export declare const adbShellToolDefinition: {
10
+ name: string;
11
+ description: string;
12
+ inputSchema: {
13
+ type: string;
14
+ properties: {
15
+ command: {
16
+ type: string;
17
+ description: string;
18
+ };
19
+ timeout: {
20
+ type: string;
21
+ description: string;
22
+ };
23
+ };
24
+ required: string[];
25
+ };
26
+ };
@@ -0,0 +1,27 @@
1
+ import { z } from "zod";
2
+ export const adbShellInputSchema = z.object({
3
+ command: z.string(),
4
+ timeout: z.number().optional(),
5
+ });
6
+ export async function handleAdbShellTool(input, context) {
7
+ const deviceId = context.deviceState.requireCurrentDevice().id;
8
+ const result = await context.adb.shell(deviceId, input.command, input.timeout);
9
+ return {
10
+ stdout: result.stdout,
11
+ stderr: result.stderr,
12
+ exitCode: result.exitCode,
13
+ deviceId,
14
+ };
15
+ }
16
+ export const adbShellToolDefinition = {
17
+ name: "adb-shell",
18
+ description: "Execute shell commands with safety guards. Dangerous commands are blocked.",
19
+ inputSchema: {
20
+ type: "object",
21
+ properties: {
22
+ command: { type: "string", description: "Shell command to execute" },
23
+ timeout: { type: "number", description: "Timeout in ms (default: 30s, max: 120s)" },
24
+ },
25
+ required: ["command"],
26
+ },
27
+ };
@@ -0,0 +1,50 @@
1
+ import { z } from "zod";
2
+ import { CacheManager } from "../services/index.js";
3
+ export declare const cacheInputSchema: z.ZodObject<{
4
+ operation: z.ZodEnum<{
5
+ clear: "clear";
6
+ "get-stats": "get-stats";
7
+ "get-config": "get-config";
8
+ "set-config": "set-config";
9
+ }>;
10
+ key: z.ZodOptional<z.ZodString>;
11
+ config: z.ZodOptional<z.ZodObject<{
12
+ maxEntries: z.ZodOptional<z.ZodNumber>;
13
+ maxEntrySizeBytes: z.ZodOptional<z.ZodNumber>;
14
+ defaultTtlMs: z.ZodOptional<z.ZodNumber>;
15
+ }, z.core.$strip>>;
16
+ }, z.core.$strip>;
17
+ export type CacheInput = z.infer<typeof cacheInputSchema>;
18
+ export declare function handleCacheTool(input: CacheInput, cache: CacheManager): Promise<Record<string, unknown>>;
19
+ export declare const cacheToolDefinition: {
20
+ name: string;
21
+ description: string;
22
+ inputSchema: {
23
+ type: string;
24
+ properties: {
25
+ operation: {
26
+ type: string;
27
+ enum: string[];
28
+ };
29
+ key: {
30
+ type: string;
31
+ description: string;
32
+ };
33
+ config: {
34
+ type: string;
35
+ properties: {
36
+ maxEntries: {
37
+ type: string;
38
+ };
39
+ maxEntrySizeBytes: {
40
+ type: string;
41
+ };
42
+ defaultTtlMs: {
43
+ type: string;
44
+ };
45
+ };
46
+ };
47
+ };
48
+ required: string[];
49
+ };
50
+ };
@@ -0,0 +1,57 @@
1
+ import { z } from "zod";
2
+ export const cacheInputSchema = z.object({
3
+ operation: z.enum(["get-stats", "clear", "get-config", "set-config"]),
4
+ key: z.string().optional(),
5
+ config: z.object({
6
+ maxEntries: z.number().optional(),
7
+ maxEntrySizeBytes: z.number().optional(),
8
+ defaultTtlMs: z.number().optional(),
9
+ }).optional(),
10
+ });
11
+ export async function handleCacheTool(input, cache) {
12
+ switch (input.operation) {
13
+ case "get-stats":
14
+ return { stats: cache.getStats() };
15
+ case "clear":
16
+ if (input.key) {
17
+ cache.clear(input.key);
18
+ return { cleared: input.key };
19
+ }
20
+ else {
21
+ cache.clearAll();
22
+ return { cleared: "all" };
23
+ }
24
+ case "get-config":
25
+ return { config: cache.getConfig() };
26
+ case "set-config":
27
+ if (input.config) {
28
+ cache.setConfig(input.config);
29
+ }
30
+ return { config: cache.getConfig() };
31
+ default:
32
+ throw new Error(`Unknown operation: ${input.operation}`);
33
+ }
34
+ }
35
+ export const cacheToolDefinition = {
36
+ name: "cache",
37
+ description: "Manage the cache. Operations: get-stats, clear, get-config, set-config. See rtfm for details.",
38
+ inputSchema: {
39
+ type: "object",
40
+ properties: {
41
+ operation: {
42
+ type: "string",
43
+ enum: ["get-stats", "clear", "get-config", "set-config"],
44
+ },
45
+ key: { type: "string", description: "Specific cache key to clear" },
46
+ config: {
47
+ type: "object",
48
+ properties: {
49
+ maxEntries: { type: "number" },
50
+ maxEntrySizeBytes: { type: "number" },
51
+ defaultTtlMs: { type: "number" },
52
+ },
53
+ },
54
+ },
55
+ required: ["operation"],
56
+ },
57
+ };
@@ -0,0 +1,56 @@
1
+ import { z } from "zod";
2
+ import { ServerContext } from "../server.js";
3
+ export declare const emulatorDeviceInputSchema: z.ZodObject<{
4
+ operation: z.ZodEnum<{
5
+ kill: "kill";
6
+ list: "list";
7
+ create: "create";
8
+ start: "start";
9
+ wipe: "wipe";
10
+ "snapshot-save": "snapshot-save";
11
+ "snapshot-load": "snapshot-load";
12
+ "snapshot-list": "snapshot-list";
13
+ "snapshot-delete": "snapshot-delete";
14
+ }>;
15
+ avdName: z.ZodOptional<z.ZodString>;
16
+ device: z.ZodOptional<z.ZodString>;
17
+ systemImage: z.ZodOptional<z.ZodString>;
18
+ snapshotName: z.ZodOptional<z.ZodString>;
19
+ emulatorId: z.ZodOptional<z.ZodString>;
20
+ }, z.core.$strip>;
21
+ export type EmulatorDeviceInput = z.infer<typeof emulatorDeviceInputSchema>;
22
+ export declare function handleEmulatorDeviceTool(input: EmulatorDeviceInput, context: ServerContext): Promise<Record<string, unknown>>;
23
+ export declare const emulatorDeviceToolDefinition: {
24
+ name: string;
25
+ description: string;
26
+ inputSchema: {
27
+ type: string;
28
+ properties: {
29
+ operation: {
30
+ type: string;
31
+ enum: string[];
32
+ };
33
+ avdName: {
34
+ type: string;
35
+ description: string;
36
+ };
37
+ device: {
38
+ type: string;
39
+ description: string;
40
+ };
41
+ systemImage: {
42
+ type: string;
43
+ description: string;
44
+ };
45
+ snapshotName: {
46
+ type: string;
47
+ description: string;
48
+ };
49
+ emulatorId: {
50
+ type: string;
51
+ description: string;
52
+ };
53
+ };
54
+ required: string[];
55
+ };
56
+ };
@@ -0,0 +1,132 @@
1
+ import { z } from "zod";
2
+ export const emulatorDeviceInputSchema = z.object({
3
+ operation: z.enum([
4
+ "list",
5
+ "create",
6
+ "start",
7
+ "kill",
8
+ "wipe",
9
+ "snapshot-save",
10
+ "snapshot-load",
11
+ "snapshot-list",
12
+ "snapshot-delete",
13
+ ]),
14
+ avdName: z.string().optional(),
15
+ device: z.string().optional(),
16
+ systemImage: z.string().optional(),
17
+ snapshotName: z.string().optional(),
18
+ emulatorId: z.string().optional(),
19
+ });
20
+ export async function handleEmulatorDeviceTool(input, context) {
21
+ switch (input.operation) {
22
+ case "list": {
23
+ const result = await context.emulator.list();
24
+ return {
25
+ available: result.available,
26
+ running: result.running,
27
+ };
28
+ }
29
+ case "create": {
30
+ if (!input.avdName || !input.device || !input.systemImage) {
31
+ throw new Error("avdName, device, and systemImage are required for create");
32
+ }
33
+ await context.emulator.create(input.avdName, input.device, input.systemImage);
34
+ return { created: input.avdName };
35
+ }
36
+ case "start": {
37
+ if (!input.avdName) {
38
+ throw new Error("avdName is required for start");
39
+ }
40
+ const emulatorId = await context.emulator.start(input.avdName);
41
+ // Auto-select the started emulator
42
+ const devices = await context.adb.getDevices();
43
+ const device = devices.find((d) => d.id === emulatorId);
44
+ if (device) {
45
+ context.deviceState.setCurrentDevice(device);
46
+ }
47
+ return { started: input.avdName, emulatorId, autoSelected: true };
48
+ }
49
+ case "kill": {
50
+ const emulatorId = input.emulatorId || context.deviceState.getCurrentDevice()?.id;
51
+ if (!emulatorId) {
52
+ throw new Error("emulatorId is required or select an emulator first");
53
+ }
54
+ await context.emulator.kill(emulatorId);
55
+ // Clear device selection if it was the killed emulator
56
+ if (context.deviceState.getCurrentDevice()?.id === emulatorId) {
57
+ context.deviceState.clearCurrentDevice();
58
+ }
59
+ return { killed: emulatorId };
60
+ }
61
+ case "wipe": {
62
+ if (!input.avdName) {
63
+ throw new Error("avdName is required for wipe");
64
+ }
65
+ await context.emulator.wipe(input.avdName);
66
+ return { wiped: input.avdName };
67
+ }
68
+ case "snapshot-save": {
69
+ const emulatorId = input.emulatorId || context.deviceState.getCurrentDevice()?.id;
70
+ if (!emulatorId || !input.snapshotName) {
71
+ throw new Error("emulatorId and snapshotName are required for snapshot-save");
72
+ }
73
+ await context.emulator.snapshotSave(emulatorId, input.snapshotName);
74
+ return { saved: input.snapshotName, emulatorId };
75
+ }
76
+ case "snapshot-load": {
77
+ const emulatorId = input.emulatorId || context.deviceState.getCurrentDevice()?.id;
78
+ if (!emulatorId || !input.snapshotName) {
79
+ throw new Error("emulatorId and snapshotName are required for snapshot-load");
80
+ }
81
+ await context.emulator.snapshotLoad(emulatorId, input.snapshotName);
82
+ return { loaded: input.snapshotName, emulatorId };
83
+ }
84
+ case "snapshot-list": {
85
+ const emulatorId = input.emulatorId || context.deviceState.getCurrentDevice()?.id;
86
+ if (!emulatorId) {
87
+ throw new Error("emulatorId is required for snapshot-list");
88
+ }
89
+ const snapshots = await context.emulator.snapshotList(emulatorId);
90
+ return { snapshots, emulatorId };
91
+ }
92
+ case "snapshot-delete": {
93
+ const emulatorId = input.emulatorId || context.deviceState.getCurrentDevice()?.id;
94
+ if (!emulatorId || !input.snapshotName) {
95
+ throw new Error("emulatorId and snapshotName are required for snapshot-delete");
96
+ }
97
+ await context.emulator.snapshotDelete(emulatorId, input.snapshotName);
98
+ return { deleted: input.snapshotName, emulatorId };
99
+ }
100
+ default:
101
+ throw new Error(`Unknown operation: ${input.operation}`);
102
+ }
103
+ }
104
+ export const emulatorDeviceToolDefinition = {
105
+ name: "emulator-device",
106
+ description: "Manage Android emulators. Operations: list, create, start, kill, wipe, snapshot-*",
107
+ inputSchema: {
108
+ type: "object",
109
+ properties: {
110
+ operation: {
111
+ type: "string",
112
+ enum: [
113
+ "list",
114
+ "create",
115
+ "start",
116
+ "kill",
117
+ "wipe",
118
+ "snapshot-save",
119
+ "snapshot-load",
120
+ "snapshot-list",
121
+ "snapshot-delete",
122
+ ],
123
+ },
124
+ avdName: { type: "string", description: "AVD name" },
125
+ device: { type: "string", description: "Device profile (e.g., 'pixel_7')" },
126
+ systemImage: { type: "string", description: "System image" },
127
+ snapshotName: { type: "string", description: "Snapshot name" },
128
+ emulatorId: { type: "string", description: "Running emulator ID" },
129
+ },
130
+ required: ["operation"],
131
+ },
132
+ };
@@ -0,0 +1,35 @@
1
+ import { z } from "zod";
2
+ import { ServerContext } from "../server.js";
3
+ export declare const gradleBuildInputSchema: z.ZodObject<{
4
+ operation: z.ZodEnum<{
5
+ assembleDebug: "assembleDebug";
6
+ assembleRelease: "assembleRelease";
7
+ bundle: "bundle";
8
+ }>;
9
+ module: z.ZodOptional<z.ZodString>;
10
+ flavor: z.ZodOptional<z.ZodString>;
11
+ }, z.core.$strip>;
12
+ export type GradleBuildInput = z.infer<typeof gradleBuildInputSchema>;
13
+ export declare function handleGradleBuildTool(input: GradleBuildInput, context: ServerContext): Promise<Record<string, unknown>>;
14
+ export declare const gradleBuildToolDefinition: {
15
+ name: string;
16
+ description: string;
17
+ inputSchema: {
18
+ type: string;
19
+ properties: {
20
+ operation: {
21
+ type: string;
22
+ enum: string[];
23
+ };
24
+ module: {
25
+ type: string;
26
+ description: string;
27
+ };
28
+ flavor: {
29
+ type: string;
30
+ description: string;
31
+ };
32
+ };
33
+ required: string[];
34
+ };
35
+ };
@@ -0,0 +1,40 @@
1
+ import { z } from "zod";
2
+ import { CACHE_TTLS } from "../types/index.js";
3
+ export const gradleBuildInputSchema = z.object({
4
+ operation: z.enum(["assembleDebug", "assembleRelease", "bundle"]),
5
+ module: z.string().optional(),
6
+ flavor: z.string().optional(),
7
+ });
8
+ export async function handleGradleBuildTool(input, context) {
9
+ const { result, fullOutput } = await context.gradle.build(input.operation, input.module, input.flavor);
10
+ // Cache full output for later retrieval
11
+ const buildId = context.cache.generateId("build");
12
+ context.cache.set(buildId, { fullOutput, result, operation: input.operation }, "build", CACHE_TTLS.BUILD_OUTPUT);
13
+ return {
14
+ buildId,
15
+ summary: {
16
+ success: result.success,
17
+ duration: result.duration,
18
+ warnings: result.warnings,
19
+ errors: result.errors,
20
+ apkPath: result.apkPath,
21
+ tasksExecuted: result.tasksExecuted,
22
+ },
23
+ };
24
+ }
25
+ export const gradleBuildToolDefinition = {
26
+ name: "gradle-build",
27
+ description: "Build an Android application. Returns summary with buildId for full logs.",
28
+ inputSchema: {
29
+ type: "object",
30
+ properties: {
31
+ operation: {
32
+ type: "string",
33
+ enum: ["assembleDebug", "assembleRelease", "bundle"],
34
+ },
35
+ module: { type: "string", description: "Module path (e.g., ':app')" },
36
+ flavor: { type: "string", description: "Product flavor" },
37
+ },
38
+ required: ["operation"],
39
+ },
40
+ };
@@ -0,0 +1,32 @@
1
+ import { z } from "zod";
2
+ import { ServerContext } from "../server.js";
3
+ export declare const gradleGetDetailsInputSchema: z.ZodObject<{
4
+ id: z.ZodString;
5
+ detailType: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
6
+ all: "all";
7
+ tasks: "tasks";
8
+ logs: "logs";
9
+ errors: "errors";
10
+ }>>>;
11
+ }, z.core.$strip>;
12
+ export type GradleGetDetailsInput = z.infer<typeof gradleGetDetailsInputSchema>;
13
+ export declare function handleGradleGetDetailsTool(input: GradleGetDetailsInput, context: ServerContext): Promise<Record<string, unknown>>;
14
+ export declare const gradleGetDetailsToolDefinition: {
15
+ name: string;
16
+ description: string;
17
+ inputSchema: {
18
+ type: string;
19
+ properties: {
20
+ id: {
21
+ type: string;
22
+ description: string;
23
+ };
24
+ detailType: {
25
+ type: string;
26
+ enum: string[];
27
+ description: string;
28
+ };
29
+ };
30
+ required: string[];
31
+ };
32
+ };
@@ -0,0 +1,72 @@
1
+ import { z } from "zod";
2
+ import { ReplicantError, ErrorCode } from "../types/index.js";
3
+ export const gradleGetDetailsInputSchema = z.object({
4
+ id: z.string(),
5
+ detailType: z.enum(["logs", "errors", "tasks", "all"]).optional().default("all"),
6
+ });
7
+ export async function handleGradleGetDetailsTool(input, context) {
8
+ const entry = context.cache.get(input.id);
9
+ if (!entry) {
10
+ throw new ReplicantError(ErrorCode.CACHE_MISS, `No cached data found for id: ${input.id}`, "The cache entry may have expired. Re-run the build/test operation.");
11
+ }
12
+ const { fullOutput, result, operation } = entry.data;
13
+ switch (input.detailType) {
14
+ case "logs":
15
+ return {
16
+ id: input.id,
17
+ operation,
18
+ logs: fullOutput,
19
+ };
20
+ case "errors": {
21
+ // Extract error lines
22
+ const lines = fullOutput.split("\n");
23
+ const errorLines = lines.filter((line) => line.includes("error:") ||
24
+ line.includes("Error:") ||
25
+ line.includes("FAILED") ||
26
+ line.startsWith("e:"));
27
+ return {
28
+ id: input.id,
29
+ operation,
30
+ errors: errorLines.join("\n"),
31
+ errorCount: errorLines.length,
32
+ };
33
+ }
34
+ case "tasks": {
35
+ // Extract task execution info
36
+ const lines = fullOutput.split("\n");
37
+ const taskLines = lines.filter((line) => line.startsWith("> Task"));
38
+ return {
39
+ id: input.id,
40
+ operation,
41
+ tasks: taskLines.map((line) => {
42
+ const match = line.match(/> Task (:\S+)(?:\s+(.+))?/);
43
+ return match ? { task: match[1], status: match[2] || "executed" } : null;
44
+ }).filter(Boolean),
45
+ };
46
+ }
47
+ case "all":
48
+ default:
49
+ return {
50
+ id: input.id,
51
+ operation,
52
+ result,
53
+ fullOutput,
54
+ };
55
+ }
56
+ }
57
+ export const gradleGetDetailsToolDefinition = {
58
+ name: "gradle-get-details",
59
+ description: "Fetch full output for a previous build/test by ID.",
60
+ inputSchema: {
61
+ type: "object",
62
+ properties: {
63
+ id: { type: "string", description: "Build or test ID from previous operation" },
64
+ detailType: {
65
+ type: "string",
66
+ enum: ["logs", "errors", "tasks", "all"],
67
+ description: "Type of details to retrieve",
68
+ },
69
+ },
70
+ required: ["id"],
71
+ },
72
+ };
@@ -0,0 +1,30 @@
1
+ import { z } from "zod";
2
+ import { ServerContext } from "../server.js";
3
+ export declare const gradleListInputSchema: z.ZodObject<{
4
+ operation: z.ZodEnum<{
5
+ tasks: "tasks";
6
+ modules: "modules";
7
+ variants: "variants";
8
+ }>;
9
+ module: z.ZodOptional<z.ZodString>;
10
+ }, z.core.$strip>;
11
+ export type GradleListInput = z.infer<typeof gradleListInputSchema>;
12
+ export declare function handleGradleListTool(input: GradleListInput, context: ServerContext): Promise<Record<string, unknown>>;
13
+ export declare const gradleListToolDefinition: {
14
+ name: string;
15
+ description: string;
16
+ inputSchema: {
17
+ type: string;
18
+ properties: {
19
+ operation: {
20
+ type: string;
21
+ enum: string[];
22
+ };
23
+ module: {
24
+ type: string;
25
+ description: string;
26
+ };
27
+ };
28
+ required: string[];
29
+ };
30
+ };