deepadb 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.
- package/LICENSE +21 -0
- package/README.md +631 -0
- package/build/bridge/adb-bridge.d.ts +65 -0
- package/build/bridge/adb-bridge.d.ts.map +1 -0
- package/build/bridge/adb-bridge.js +164 -0
- package/build/bridge/adb-bridge.js.map +1 -0
- package/build/bridge/device-manager.d.ts +41 -0
- package/build/bridge/device-manager.d.ts.map +1 -0
- package/build/bridge/device-manager.js +109 -0
- package/build/bridge/device-manager.js.map +1 -0
- package/build/bridge/local-bridge.d.ts +92 -0
- package/build/bridge/local-bridge.d.ts.map +1 -0
- package/build/bridge/local-bridge.js +345 -0
- package/build/bridge/local-bridge.js.map +1 -0
- package/build/config/config.d.ts +39 -0
- package/build/config/config.d.ts.map +1 -0
- package/build/config/config.js +84 -0
- package/build/config/config.js.map +1 -0
- package/build/graphql-api.d.ts +36 -0
- package/build/graphql-api.d.ts.map +1 -0
- package/build/graphql-api.js +296 -0
- package/build/graphql-api.js.map +1 -0
- package/build/http-transport.d.ts +26 -0
- package/build/http-transport.d.ts.map +1 -0
- package/build/http-transport.js +105 -0
- package/build/http-transport.js.map +1 -0
- package/build/index.d.ts +14 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +66 -0
- package/build/index.js.map +1 -0
- package/build/middleware/chipset.d.ts +29 -0
- package/build/middleware/chipset.d.ts.map +1 -0
- package/build/middleware/chipset.js +123 -0
- package/build/middleware/chipset.js.map +1 -0
- package/build/middleware/cleanup.d.ts +24 -0
- package/build/middleware/cleanup.d.ts.map +1 -0
- package/build/middleware/cleanup.js +53 -0
- package/build/middleware/cleanup.js.map +1 -0
- package/build/middleware/fetch-utils.d.ts +19 -0
- package/build/middleware/fetch-utils.d.ts.map +1 -0
- package/build/middleware/fetch-utils.js +64 -0
- package/build/middleware/fetch-utils.js.map +1 -0
- package/build/middleware/logger.d.ts +17 -0
- package/build/middleware/logger.d.ts.map +1 -0
- package/build/middleware/logger.js +38 -0
- package/build/middleware/logger.js.map +1 -0
- package/build/middleware/output-processor.d.ts +57 -0
- package/build/middleware/output-processor.d.ts.map +1 -0
- package/build/middleware/output-processor.js +162 -0
- package/build/middleware/output-processor.js.map +1 -0
- package/build/middleware/sanitize.d.ts +30 -0
- package/build/middleware/sanitize.d.ts.map +1 -0
- package/build/middleware/sanitize.js +46 -0
- package/build/middleware/sanitize.js.map +1 -0
- package/build/middleware/security.d.ts +52 -0
- package/build/middleware/security.d.ts.map +1 -0
- package/build/middleware/security.js +123 -0
- package/build/middleware/security.js.map +1 -0
- package/build/middleware/ui-dump.d.ts +23 -0
- package/build/middleware/ui-dump.d.ts.map +1 -0
- package/build/middleware/ui-dump.js +59 -0
- package/build/middleware/ui-dump.js.map +1 -0
- package/build/server.d.ts +18 -0
- package/build/server.d.ts.map +1 -0
- package/build/server.js +133 -0
- package/build/server.js.map +1 -0
- package/build/tool-context.d.ts +22 -0
- package/build/tool-context.d.ts.map +1 -0
- package/build/tool-context.js +9 -0
- package/build/tool-context.js.map +1 -0
- package/build/tools/accessibility.d.ts +10 -0
- package/build/tools/accessibility.d.ts.map +1 -0
- package/build/tools/accessibility.js +259 -0
- package/build/tools/accessibility.js.map +1 -0
- package/build/tools/at-commands.d.ts +20 -0
- package/build/tools/at-commands.d.ts.map +1 -0
- package/build/tools/at-commands.js +378 -0
- package/build/tools/at-commands.js.map +1 -0
- package/build/tools/baseband.d.ts +15 -0
- package/build/tools/baseband.d.ts.map +1 -0
- package/build/tools/baseband.js +323 -0
- package/build/tools/baseband.js.map +1 -0
- package/build/tools/build.d.ts +6 -0
- package/build/tools/build.d.ts.map +1 -0
- package/build/tools/build.js +80 -0
- package/build/tools/build.js.map +1 -0
- package/build/tools/ci.d.ts +9 -0
- package/build/tools/ci.d.ts.map +1 -0
- package/build/tools/ci.js +163 -0
- package/build/tools/ci.js.map +1 -0
- package/build/tools/control.d.ts +10 -0
- package/build/tools/control.d.ts.map +1 -0
- package/build/tools/control.js +197 -0
- package/build/tools/control.js.map +1 -0
- package/build/tools/device-farm.d.ts +10 -0
- package/build/tools/device-farm.d.ts.map +1 -0
- package/build/tools/device-farm.js +140 -0
- package/build/tools/device-farm.js.map +1 -0
- package/build/tools/device-profiles.d.ts +16 -0
- package/build/tools/device-profiles.d.ts.map +1 -0
- package/build/tools/device-profiles.js +272 -0
- package/build/tools/device-profiles.js.map +1 -0
- package/build/tools/device.d.ts +6 -0
- package/build/tools/device.d.ts.map +1 -0
- package/build/tools/device.js +72 -0
- package/build/tools/device.js.map +1 -0
- package/build/tools/diagnostics.d.ts +7 -0
- package/build/tools/diagnostics.d.ts.map +1 -0
- package/build/tools/diagnostics.js +153 -0
- package/build/tools/diagnostics.js.map +1 -0
- package/build/tools/emulator.d.ts +9 -0
- package/build/tools/emulator.d.ts.map +1 -0
- package/build/tools/emulator.js +223 -0
- package/build/tools/emulator.js.map +1 -0
- package/build/tools/files.d.ts +6 -0
- package/build/tools/files.d.ts.map +1 -0
- package/build/tools/files.js +78 -0
- package/build/tools/files.js.map +1 -0
- package/build/tools/firmware-analysis.d.ts +24 -0
- package/build/tools/firmware-analysis.d.ts.map +1 -0
- package/build/tools/firmware-analysis.js +623 -0
- package/build/tools/firmware-analysis.js.map +1 -0
- package/build/tools/forwarding.d.ts +7 -0
- package/build/tools/forwarding.d.ts.map +1 -0
- package/build/tools/forwarding.js +64 -0
- package/build/tools/forwarding.js.map +1 -0
- package/build/tools/health.d.ts +7 -0
- package/build/tools/health.d.ts.map +1 -0
- package/build/tools/health.js +112 -0
- package/build/tools/health.js.map +1 -0
- package/build/tools/logcat-watch.d.ts +11 -0
- package/build/tools/logcat-watch.d.ts.map +1 -0
- package/build/tools/logcat-watch.js +209 -0
- package/build/tools/logcat-watch.js.map +1 -0
- package/build/tools/logs.d.ts +6 -0
- package/build/tools/logs.d.ts.map +1 -0
- package/build/tools/logs.js +83 -0
- package/build/tools/logs.js.map +1 -0
- package/build/tools/mirroring.d.ts +14 -0
- package/build/tools/mirroring.d.ts.map +1 -0
- package/build/tools/mirroring.js +243 -0
- package/build/tools/mirroring.js.map +1 -0
- package/build/tools/multi-device.d.ts +9 -0
- package/build/tools/multi-device.d.ts.map +1 -0
- package/build/tools/multi-device.js +138 -0
- package/build/tools/multi-device.js.map +1 -0
- package/build/tools/network-capture.d.ts +10 -0
- package/build/tools/network-capture.d.ts.map +1 -0
- package/build/tools/network-capture.js +143 -0
- package/build/tools/network-capture.js.map +1 -0
- package/build/tools/network-discovery.d.ts +21 -0
- package/build/tools/network-discovery.d.ts.map +1 -0
- package/build/tools/network-discovery.js +284 -0
- package/build/tools/network-discovery.js.map +1 -0
- package/build/tools/ota-monitor.d.ts +16 -0
- package/build/tools/ota-monitor.d.ts.map +1 -0
- package/build/tools/ota-monitor.js +211 -0
- package/build/tools/ota-monitor.js.map +1 -0
- package/build/tools/packages.d.ts +6 -0
- package/build/tools/packages.d.ts.map +1 -0
- package/build/tools/packages.js +237 -0
- package/build/tools/packages.js.map +1 -0
- package/build/tools/plugins.d.ts +22 -0
- package/build/tools/plugins.d.ts.map +1 -0
- package/build/tools/plugins.js +118 -0
- package/build/tools/plugins.js.map +1 -0
- package/build/tools/prompts.d.ts +9 -0
- package/build/tools/prompts.d.ts.map +1 -0
- package/build/tools/prompts.js +94 -0
- package/build/tools/prompts.js.map +1 -0
- package/build/tools/qemu.d.ts +18 -0
- package/build/tools/qemu.d.ts.map +1 -0
- package/build/tools/qemu.js +791 -0
- package/build/tools/qemu.js.map +1 -0
- package/build/tools/registry.d.ts +13 -0
- package/build/tools/registry.d.ts.map +1 -0
- package/build/tools/registry.js +221 -0
- package/build/tools/registry.js.map +1 -0
- package/build/tools/regression.d.ts +10 -0
- package/build/tools/regression.d.ts.map +1 -0
- package/build/tools/regression.js +215 -0
- package/build/tools/regression.js.map +1 -0
- package/build/tools/resources.d.ts +10 -0
- package/build/tools/resources.d.ts.map +1 -0
- package/build/tools/resources.js +77 -0
- package/build/tools/resources.js.map +1 -0
- package/build/tools/ril-intercept.d.ts +24 -0
- package/build/tools/ril-intercept.d.ts.map +1 -0
- package/build/tools/ril-intercept.js +273 -0
- package/build/tools/ril-intercept.js.map +1 -0
- package/build/tools/screen-record.d.ts +9 -0
- package/build/tools/screen-record.d.ts.map +1 -0
- package/build/tools/screen-record.js +95 -0
- package/build/tools/screen-record.js.map +1 -0
- package/build/tools/screenshot-diff.d.ts +13 -0
- package/build/tools/screenshot-diff.d.ts.map +1 -0
- package/build/tools/screenshot-diff.js +370 -0
- package/build/tools/screenshot-diff.js.map +1 -0
- package/build/tools/selinux-audit.d.ts +17 -0
- package/build/tools/selinux-audit.d.ts.map +1 -0
- package/build/tools/selinux-audit.js +301 -0
- package/build/tools/selinux-audit.js.map +1 -0
- package/build/tools/shell.d.ts +6 -0
- package/build/tools/shell.d.ts.map +1 -0
- package/build/tools/shell.js +63 -0
- package/build/tools/shell.js.map +1 -0
- package/build/tools/snapshot.d.ts +9 -0
- package/build/tools/snapshot.d.ts.map +1 -0
- package/build/tools/snapshot.js +192 -0
- package/build/tools/snapshot.js.map +1 -0
- package/build/tools/split-apk.d.ts +13 -0
- package/build/tools/split-apk.d.ts.map +1 -0
- package/build/tools/split-apk.js +229 -0
- package/build/tools/split-apk.js.map +1 -0
- package/build/tools/test-gen.d.ts +14 -0
- package/build/tools/test-gen.d.ts.map +1 -0
- package/build/tools/test-gen.js +252 -0
- package/build/tools/test-gen.js.map +1 -0
- package/build/tools/testing.d.ts +9 -0
- package/build/tools/testing.d.ts.map +1 -0
- package/build/tools/testing.js +144 -0
- package/build/tools/testing.js.map +1 -0
- package/build/tools/thermal-power.d.ts +19 -0
- package/build/tools/thermal-power.d.ts.map +1 -0
- package/build/tools/thermal-power.js +330 -0
- package/build/tools/thermal-power.js.map +1 -0
- package/build/tools/ui.d.ts +6 -0
- package/build/tools/ui.d.ts.map +1 -0
- package/build/tools/ui.js +266 -0
- package/build/tools/ui.js.map +1 -0
- package/build/tools/wireless.d.ts +7 -0
- package/build/tools/wireless.d.ts.map +1 -0
- package/build/tools/wireless.js +78 -0
- package/build/tools/wireless.js.map +1 -0
- package/build/tools/workflow-market.d.ts +17 -0
- package/build/tools/workflow-market.d.ts.map +1 -0
- package/build/tools/workflow-market.js +237 -0
- package/build/tools/workflow-market.js.map +1 -0
- package/build/tools/workflow.d.ts +32 -0
- package/build/tools/workflow.d.ts.map +1 -0
- package/build/tools/workflow.js +374 -0
- package/build/tools/workflow.js.map +1 -0
- package/build/ws-transport.d.ts +30 -0
- package/build/ws-transport.d.ts.map +1 -0
- package/build/ws-transport.js +133 -0
- package/build/ws-transport.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Orchestration Engine — Declarative multi-step tool sequences.
|
|
3
|
+
*
|
|
4
|
+
* Executes JSON-defined workflows that chain device operations into
|
|
5
|
+
* repeatable, parameterized sequences with variable capture, conditional
|
|
6
|
+
* steps, and loop support. Workflows run entirely server-side through
|
|
7
|
+
* direct bridge calls.
|
|
8
|
+
*
|
|
9
|
+
* Supported step actions: shell, root_shell, install, screenshot,
|
|
10
|
+
* logcat, getprop, sleep. Each action maps directly to ADB bridge
|
|
11
|
+
* operations — no MCP tool re-invocation overhead.
|
|
12
|
+
*
|
|
13
|
+
* Workflow files are stored in {tempDir}/workflows/.
|
|
14
|
+
*
|
|
15
|
+
* Example workflow JSON:
|
|
16
|
+
* {
|
|
17
|
+
* "name": "restart-and-verify",
|
|
18
|
+
* "description": "Restart an app and verify it launched correctly",
|
|
19
|
+
* "variables": { "pkg": "com.example.app" },
|
|
20
|
+
* "steps": [
|
|
21
|
+
* { "name": "stop", "action": "shell", "command": "am force-stop {{pkg}}" },
|
|
22
|
+
* { "name": "pause", "action": "sleep", "ms": 1000 },
|
|
23
|
+
* { "name": "start", "action": "shell", "command": "monkey -p {{pkg}} -c android.intent.category.LAUNCHER 1" },
|
|
24
|
+
* { "name": "wait", "action": "sleep", "ms": 2000 },
|
|
25
|
+
* { "name": "check", "action": "shell", "command": "dumpsys activity activities | grep mResumedActivity", "capture": "activity" },
|
|
26
|
+
* { "name": "screenshot", "action": "screenshot" }
|
|
27
|
+
* ]
|
|
28
|
+
* }
|
|
29
|
+
*/
|
|
30
|
+
import { z } from "zod";
|
|
31
|
+
import { join } from "path";
|
|
32
|
+
import { readFileSync, existsSync, readdirSync } from "fs";
|
|
33
|
+
import { OutputProcessor } from "../middleware/output-processor.js";
|
|
34
|
+
import { validateShellArg, shellEscape } from "../middleware/sanitize.js";
|
|
35
|
+
import { isOnDevice } from "../config/config.js";
|
|
36
|
+
function getWorkflowDir(tempDir) {
|
|
37
|
+
return join(tempDir, "workflows");
|
|
38
|
+
}
|
|
39
|
+
/** Maximum iterations per step to prevent runaway loops. */
|
|
40
|
+
const MAX_REPEAT = 100;
|
|
41
|
+
/** Maximum steps per workflow to prevent resource exhaustion. */
|
|
42
|
+
const MAX_STEPS = 200;
|
|
43
|
+
/** Maximum sleep duration per step in ms (5 minutes). */
|
|
44
|
+
const MAX_SLEEP_MS = 300_000;
|
|
45
|
+
/** Substitute {{variable}} references in a string. */
|
|
46
|
+
function substituteVars(text, vars) {
|
|
47
|
+
return text.replace(/\{\{(\w+)\}\}/g, (_, key) => vars[key] ?? `{{${key}}}`);
|
|
48
|
+
}
|
|
49
|
+
/** Evaluate a simple conditional expression. */
|
|
50
|
+
function evaluateCondition(expr, vars) {
|
|
51
|
+
const resolved = substituteVars(expr, vars);
|
|
52
|
+
// "value == value"
|
|
53
|
+
const eqMatch = resolved.match(/^(.+?)\s*==\s*(.+)$/);
|
|
54
|
+
if (eqMatch)
|
|
55
|
+
return eqMatch[1].trim() === eqMatch[2].trim();
|
|
56
|
+
// "value != value"
|
|
57
|
+
const neqMatch = resolved.match(/^(.+?)\s*!=\s*(.+)$/);
|
|
58
|
+
if (neqMatch)
|
|
59
|
+
return neqMatch[1].trim() !== neqMatch[2].trim();
|
|
60
|
+
// "value contains value"
|
|
61
|
+
const containsMatch = resolved.match(/^(.+?)\s+contains\s+(.+)$/);
|
|
62
|
+
if (containsMatch)
|
|
63
|
+
return containsMatch[1].trim().includes(containsMatch[2].trim());
|
|
64
|
+
// Non-empty string is truthy
|
|
65
|
+
return resolved.trim().length > 0;
|
|
66
|
+
}
|
|
67
|
+
/** Validate a workflow definition and return errors. */
|
|
68
|
+
function validateWorkflow(def) {
|
|
69
|
+
const errors = [];
|
|
70
|
+
if (!def || typeof def !== "object") {
|
|
71
|
+
errors.push("Workflow must be a JSON object.");
|
|
72
|
+
return errors;
|
|
73
|
+
}
|
|
74
|
+
const w = def;
|
|
75
|
+
if (!w.name || typeof w.name !== "string")
|
|
76
|
+
errors.push("Missing or invalid 'name' field.");
|
|
77
|
+
if (!Array.isArray(w.steps)) {
|
|
78
|
+
errors.push("Missing or invalid 'steps' array.");
|
|
79
|
+
return errors;
|
|
80
|
+
}
|
|
81
|
+
if (w.steps.length > MAX_STEPS) {
|
|
82
|
+
errors.push(`Too many steps: ${w.steps.length} (maximum ${MAX_STEPS}).`);
|
|
83
|
+
return errors;
|
|
84
|
+
}
|
|
85
|
+
const validActions = ["shell", "root_shell", "install", "screenshot", "logcat", "getprop", "sleep"];
|
|
86
|
+
for (let i = 0; i < w.steps.length; i++) {
|
|
87
|
+
const step = w.steps[i];
|
|
88
|
+
if (!step || typeof step !== "object") {
|
|
89
|
+
errors.push(`Step ${i}: not an object.`);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (!step.name || typeof step.name !== "string")
|
|
93
|
+
errors.push(`Step ${i}: missing 'name'.`);
|
|
94
|
+
if (!step.action || typeof step.action !== "string") {
|
|
95
|
+
errors.push(`Step ${i}: missing 'action'.`);
|
|
96
|
+
}
|
|
97
|
+
else if (!validActions.includes(step.action)) {
|
|
98
|
+
errors.push(`Step ${i}: unknown action '${step.action}'. Valid: ${validActions.join(", ")}`);
|
|
99
|
+
}
|
|
100
|
+
const action = step.action;
|
|
101
|
+
if ((action === "shell" || action === "root_shell") && (!step.command || typeof step.command !== "string")) {
|
|
102
|
+
errors.push(`Step ${i} (${action}): requires 'command' string.`);
|
|
103
|
+
}
|
|
104
|
+
if (action === "install" && (!step.apkPath || typeof step.apkPath !== "string")) {
|
|
105
|
+
errors.push(`Step ${i} (install): requires 'apkPath' string.`);
|
|
106
|
+
}
|
|
107
|
+
if (action === "getprop" && (!step.key || typeof step.key !== "string")) {
|
|
108
|
+
errors.push(`Step ${i} (getprop): requires 'key' string.`);
|
|
109
|
+
}
|
|
110
|
+
if (action === "sleep" && (step.ms === undefined || typeof step.ms !== "number")) {
|
|
111
|
+
errors.push(`Step ${i} (sleep): requires 'ms' number.`);
|
|
112
|
+
}
|
|
113
|
+
if (action === "sleep" && typeof step.ms === "number" && step.ms > MAX_SLEEP_MS) {
|
|
114
|
+
errors.push(`Step ${i} (sleep): ms=${step.ms} exceeds maximum of ${MAX_SLEEP_MS}ms (${MAX_SLEEP_MS / 1000}s).`);
|
|
115
|
+
}
|
|
116
|
+
if (typeof step.repeat === "number" && step.repeat > MAX_REPEAT) {
|
|
117
|
+
errors.push(`Step ${i}: repeat=${step.repeat} exceeds maximum of ${MAX_REPEAT}.`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return errors;
|
|
121
|
+
}
|
|
122
|
+
export function registerWorkflowTools(ctx) {
|
|
123
|
+
ctx.server.tool("adb_workflow_run", "Execute a workflow — a JSON-defined sequence of device operations with variable substitution, conditional steps, and loop support. Supported actions: shell, root_shell, install, screenshot, logcat, getprop, sleep. Pass the workflow as a JSON string or provide a saved workflow name.", {
|
|
124
|
+
workflow: z.string().describe("Workflow JSON string, or the name of a saved workflow file"),
|
|
125
|
+
variables: z.record(z.string()).optional().describe("Override workflow variables (merged with defaults)"),
|
|
126
|
+
device: z.string().optional().describe("Device serial"),
|
|
127
|
+
dryRun: z.boolean().optional().default(false).describe("Validate and show execution plan without running"),
|
|
128
|
+
}, async ({ workflow, variables, device, dryRun }) => {
|
|
129
|
+
try {
|
|
130
|
+
const resolved = await ctx.deviceManager.resolveDevice(device);
|
|
131
|
+
const serial = resolved.serial;
|
|
132
|
+
// Parse workflow — either inline JSON or saved file name
|
|
133
|
+
let def;
|
|
134
|
+
try {
|
|
135
|
+
if (workflow.trimStart().startsWith("{")) {
|
|
136
|
+
def = JSON.parse(workflow);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
const dir = getWorkflowDir(ctx.config.tempDir);
|
|
140
|
+
const safeName = workflow.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
141
|
+
const filePath = join(dir, `${safeName}.json`);
|
|
142
|
+
if (!existsSync(filePath)) {
|
|
143
|
+
return { content: [{ type: "text", text: `Workflow "${workflow}" not found. Use adb_workflow_list to see available workflows.` }], isError: true };
|
|
144
|
+
}
|
|
145
|
+
def = JSON.parse(readFileSync(filePath, "utf-8"));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
return { content: [{ type: "text", text: `Invalid workflow JSON: ${err instanceof Error ? err.message : err}` }], isError: true };
|
|
150
|
+
}
|
|
151
|
+
// Validate
|
|
152
|
+
const errors = validateWorkflow(def);
|
|
153
|
+
if (errors.length > 0) {
|
|
154
|
+
return { content: [{ type: "text", text: `Workflow validation failed:\n${errors.join("\n")}` }], isError: true };
|
|
155
|
+
}
|
|
156
|
+
// Merge variables
|
|
157
|
+
const vars = { ...(def.variables ?? {}), ...(variables ?? {}) };
|
|
158
|
+
const output = [];
|
|
159
|
+
output.push(`=== Workflow: ${def.name} ===`);
|
|
160
|
+
if (def.description)
|
|
161
|
+
output.push(def.description);
|
|
162
|
+
output.push(`Device: ${serial}`);
|
|
163
|
+
output.push(`Steps: ${def.steps.length}`);
|
|
164
|
+
if (Object.keys(vars).length > 0) {
|
|
165
|
+
output.push(`Variables: ${Object.entries(vars).map(([k, v]) => `${k}="${v}"`).join(", ")}`);
|
|
166
|
+
}
|
|
167
|
+
output.push("");
|
|
168
|
+
if (dryRun) {
|
|
169
|
+
output.push("--- DRY RUN (no commands executed) ---\n");
|
|
170
|
+
for (let i = 0; i < def.steps.length; i++) {
|
|
171
|
+
const step = def.steps[i];
|
|
172
|
+
const condStr = step.if ? ` [if: ${step.if}]` : "";
|
|
173
|
+
const repeatStr = step.repeat ? ` [repeat: ${step.repeat}]` : "";
|
|
174
|
+
const captureStr = step.capture ? ` → $${step.capture}` : "";
|
|
175
|
+
let detail = step.action;
|
|
176
|
+
if (step.command)
|
|
177
|
+
detail += `: ${substituteVars(step.command, vars)}`;
|
|
178
|
+
if (step.key)
|
|
179
|
+
detail += `: ${substituteVars(step.key, vars)}`;
|
|
180
|
+
if (step.ms)
|
|
181
|
+
detail += `: ${step.ms}ms`;
|
|
182
|
+
output.push(` [${i + 1}] ${step.name} — ${detail}${condStr}${repeatStr}${captureStr}`);
|
|
183
|
+
}
|
|
184
|
+
return { content: [{ type: "text", text: output.join("\n") }] };
|
|
185
|
+
}
|
|
186
|
+
// Execute
|
|
187
|
+
const startTime = Date.now();
|
|
188
|
+
let stepsRun = 0;
|
|
189
|
+
let stepsFailed = 0;
|
|
190
|
+
for (let i = 0; i < def.steps.length; i++) {
|
|
191
|
+
const step = def.steps[i];
|
|
192
|
+
const iterations = Math.min(step.repeat ?? 1, MAX_REPEAT);
|
|
193
|
+
// Conditional check
|
|
194
|
+
if (step.if) {
|
|
195
|
+
if (!evaluateCondition(step.if, vars)) {
|
|
196
|
+
output.push(`[${i + 1}] ${step.name} — SKIPPED (condition false: ${step.if})`);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
for (let iter = 0; iter < iterations; iter++) {
|
|
201
|
+
const iterLabel = iterations > 1 ? ` (${iter + 1}/${iterations})` : "";
|
|
202
|
+
stepsRun++;
|
|
203
|
+
try {
|
|
204
|
+
let result = "";
|
|
205
|
+
switch (step.action) {
|
|
206
|
+
case "shell": {
|
|
207
|
+
const cmd = substituteVars(step.command, vars);
|
|
208
|
+
const blocked = ctx.security.checkCommand(cmd, serial);
|
|
209
|
+
if (blocked) {
|
|
210
|
+
output.push(`[${i + 1}] ${step.name}${iterLabel} — BLOCKED: ${blocked}`);
|
|
211
|
+
stepsFailed++;
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
const r = await ctx.bridge.shell(cmd, { device: serial, ignoreExitCode: true });
|
|
215
|
+
result = r.stdout.trim();
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
case "root_shell": {
|
|
219
|
+
const cmd = substituteVars(step.command, vars);
|
|
220
|
+
const blocked = ctx.security.checkCommand(`su: ${cmd}`, serial);
|
|
221
|
+
if (blocked) {
|
|
222
|
+
output.push(`[${i + 1}] ${step.name}${iterLabel} — BLOCKED: ${blocked}`);
|
|
223
|
+
stepsFailed++;
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
const r = await ctx.bridge.rootShell(cmd, { device: serial, ignoreExitCode: true });
|
|
227
|
+
result = r.stdout.trim();
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
case "install": {
|
|
231
|
+
const apk = substituteVars(step.apkPath, vars);
|
|
232
|
+
const r = await ctx.bridge.exec(["install", "-r", apk], { device: serial, timeout: 120000 });
|
|
233
|
+
result = r.stdout.trim();
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
case "screenshot": {
|
|
237
|
+
const fname = `workflow_${Date.now()}.png`;
|
|
238
|
+
const remoteDir = isOnDevice() ? "/data/local/tmp" : "/sdcard";
|
|
239
|
+
const remotePath = `${remoteDir}/${fname}`;
|
|
240
|
+
const localPath = join(ctx.config.tempDir, fname);
|
|
241
|
+
try {
|
|
242
|
+
await ctx.bridge.shell(`screencap -p '${shellEscape(remotePath)}'`, { device: serial, timeout: 15000 });
|
|
243
|
+
await ctx.bridge.exec(["pull", remotePath, localPath], { device: serial, timeout: 30000 });
|
|
244
|
+
}
|
|
245
|
+
finally {
|
|
246
|
+
await ctx.bridge.shell(`rm '${shellEscape(remotePath)}'`, { device: serial, ignoreExitCode: true }).catch(() => { });
|
|
247
|
+
}
|
|
248
|
+
result = localPath;
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
case "logcat": {
|
|
252
|
+
const lines = step.lines ?? 100;
|
|
253
|
+
let cmd = `logcat -d -t ${lines}`;
|
|
254
|
+
if (step.tag) {
|
|
255
|
+
const resolvedTag = substituteVars(step.tag, vars);
|
|
256
|
+
const tagErr = validateShellArg(resolvedTag, "tag");
|
|
257
|
+
if (tagErr) {
|
|
258
|
+
output.push(`[${i + 1}] ${step.name}${iterLabel} — BLOCKED: ${tagErr}`);
|
|
259
|
+
stepsFailed++;
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
cmd += ` -s ${resolvedTag}:V`;
|
|
263
|
+
}
|
|
264
|
+
const r = await ctx.bridge.shell(cmd, { device: serial, timeout: 10000, ignoreExitCode: true });
|
|
265
|
+
result = r.stdout.trim();
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
case "getprop": {
|
|
269
|
+
const key = substituteVars(step.key, vars);
|
|
270
|
+
const keyErr = validateShellArg(key, "key");
|
|
271
|
+
if (keyErr) {
|
|
272
|
+
output.push(`[${i + 1}] ${step.name}${iterLabel} — BLOCKED: ${keyErr}`);
|
|
273
|
+
stepsFailed++;
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
const r = await ctx.bridge.shell(`getprop ${key}`, { device: serial });
|
|
277
|
+
result = r.stdout.trim();
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
case "sleep": {
|
|
281
|
+
await new Promise((r) => setTimeout(r, step.ms));
|
|
282
|
+
result = `(waited ${step.ms}ms)`;
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// Capture result into variable
|
|
287
|
+
if (step.capture) {
|
|
288
|
+
vars[step.capture] = result;
|
|
289
|
+
}
|
|
290
|
+
// Truncate long results for output
|
|
291
|
+
const displayResult = result.length > 200 ? result.substring(0, 200) + "..." : result;
|
|
292
|
+
output.push(`[${i + 1}] ${step.name}${iterLabel} — OK${displayResult ? ": " + displayResult : ""}`);
|
|
293
|
+
}
|
|
294
|
+
catch (err) {
|
|
295
|
+
stepsFailed++;
|
|
296
|
+
output.push(`[${i + 1}] ${step.name}${iterLabel} — ERROR: ${err instanceof Error ? err.message : err}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
301
|
+
output.push("");
|
|
302
|
+
output.push(`=== Workflow complete: ${stepsRun} steps run, ${stepsFailed} failed, ${elapsed}s ===`);
|
|
303
|
+
return { content: [{ type: "text", text: OutputProcessor.process(output.join("\n")) }] };
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
ctx.server.tool("adb_workflow_validate", "Validate a workflow JSON definition without executing it. Reports structural errors and shows the execution plan.", {
|
|
310
|
+
workflow: z.string().describe("Workflow JSON string to validate"),
|
|
311
|
+
}, async ({ workflow }) => {
|
|
312
|
+
try {
|
|
313
|
+
let def;
|
|
314
|
+
try {
|
|
315
|
+
def = JSON.parse(workflow);
|
|
316
|
+
}
|
|
317
|
+
catch (err) {
|
|
318
|
+
return { content: [{ type: "text", text: `Invalid JSON: ${err instanceof Error ? err.message : err}` }], isError: true };
|
|
319
|
+
}
|
|
320
|
+
const errors = validateWorkflow(def);
|
|
321
|
+
if (errors.length > 0) {
|
|
322
|
+
return { content: [{ type: "text", text: `Validation FAILED:\n${errors.join("\n")}` }], isError: true };
|
|
323
|
+
}
|
|
324
|
+
const w = def;
|
|
325
|
+
const lines = [`Validation PASSED: ${w.name}`];
|
|
326
|
+
if (w.description)
|
|
327
|
+
lines.push(w.description);
|
|
328
|
+
lines.push(`Steps: ${w.steps.length}`);
|
|
329
|
+
if (w.variables) {
|
|
330
|
+
lines.push(`Variables: ${Object.keys(w.variables).join(", ")}`);
|
|
331
|
+
}
|
|
332
|
+
lines.push("");
|
|
333
|
+
for (let i = 0; i < w.steps.length; i++) {
|
|
334
|
+
const s = w.steps[i];
|
|
335
|
+
lines.push(` [${i + 1}] ${s.name} — ${s.action}${s.capture ? ` → $${s.capture}` : ""}${s.if ? ` [if]` : ""}${s.repeat ? ` [×${s.repeat}]` : ""}`);
|
|
336
|
+
}
|
|
337
|
+
// Offer to save
|
|
338
|
+
lines.push(`\nUse adb_workflow_run with this JSON to execute, or save to a file in ${getWorkflowDir(ctx.config.tempDir)}.`);
|
|
339
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
340
|
+
}
|
|
341
|
+
catch (error) {
|
|
342
|
+
return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
ctx.server.tool("adb_workflow_list", "List saved workflow files in the workflows directory.", {}, async () => {
|
|
346
|
+
try {
|
|
347
|
+
const dir = getWorkflowDir(ctx.config.tempDir);
|
|
348
|
+
if (!existsSync(dir)) {
|
|
349
|
+
return { content: [{ type: "text", text: `No workflows directory. Save .json files to: ${dir}` }] };
|
|
350
|
+
}
|
|
351
|
+
const files = readdirSync(dir).filter((f) => f.endsWith(".json")).sort();
|
|
352
|
+
if (files.length === 0) {
|
|
353
|
+
return { content: [{ type: "text", text: `No workflow files found in ${dir}` }] };
|
|
354
|
+
}
|
|
355
|
+
const lines = [`${files.length} workflow(s):\n`];
|
|
356
|
+
for (const file of files) {
|
|
357
|
+
try {
|
|
358
|
+
const def = JSON.parse(readFileSync(join(dir, file), "utf-8"));
|
|
359
|
+
const name = file.replace(".json", "");
|
|
360
|
+
lines.push(`${name} — ${def.description ?? "(no description)"} (${def.steps.length} steps)`);
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
lines.push(`${file} — (invalid JSON)`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
lines.push(`\nDirectory: ${dir}`);
|
|
367
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
//# sourceMappingURL=workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../src/tools/workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket Transport — Bidirectional streaming MCP transport.
|
|
3
|
+
*
|
|
4
|
+
* Alternative to stdio and HTTP/SSE for MCP clients that benefit from
|
|
5
|
+
* true bidirectional communication. Lower latency than SSE polling and
|
|
6
|
+
* better compatibility with modern web frameworks.
|
|
7
|
+
*
|
|
8
|
+
* Requires the `ws` npm package as an optional peer dependency:
|
|
9
|
+
* npm install ws @types/ws
|
|
10
|
+
*
|
|
11
|
+
* Set DA_WS_PORT to enable (separate from DA_HTTP_PORT).
|
|
12
|
+
* Can run alongside stdio or HTTP/SSE transport.
|
|
13
|
+
*
|
|
14
|
+
* Endpoints:
|
|
15
|
+
* ws://host:port/ws — WebSocket MCP transport
|
|
16
|
+
* GET /health — HTTP health check (always available)
|
|
17
|
+
*/
|
|
18
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
19
|
+
import { Logger } from "./middleware/logger.js";
|
|
20
|
+
export interface WsTransportOptions {
|
|
21
|
+
port: number;
|
|
22
|
+
host?: string;
|
|
23
|
+
version?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Start a WebSocket transport server for MCP.
|
|
27
|
+
* Requires the `ws` npm package to be installed.
|
|
28
|
+
*/
|
|
29
|
+
export declare function startWsTransport(server: McpServer, options: WsTransportOptions, logger: Logger): Promise<void>;
|
|
30
|
+
//# sourceMappingURL=ws-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-transport.d.ts","sourceRoot":"","sources":["../src/ws-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAYhD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAoDD;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,kBAAkB,EAC3B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAgFf"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket Transport — Bidirectional streaming MCP transport.
|
|
3
|
+
*
|
|
4
|
+
* Alternative to stdio and HTTP/SSE for MCP clients that benefit from
|
|
5
|
+
* true bidirectional communication. Lower latency than SSE polling and
|
|
6
|
+
* better compatibility with modern web frameworks.
|
|
7
|
+
*
|
|
8
|
+
* Requires the `ws` npm package as an optional peer dependency:
|
|
9
|
+
* npm install ws @types/ws
|
|
10
|
+
*
|
|
11
|
+
* Set DA_WS_PORT to enable (separate from DA_HTTP_PORT).
|
|
12
|
+
* Can run alongside stdio or HTTP/SSE transport.
|
|
13
|
+
*
|
|
14
|
+
* Endpoints:
|
|
15
|
+
* ws://host:port/ws — WebSocket MCP transport
|
|
16
|
+
* GET /health — HTTP health check (always available)
|
|
17
|
+
*/
|
|
18
|
+
import { createServer as createHttpServer } from "http";
|
|
19
|
+
/**
|
|
20
|
+
* Minimal WebSocket transport that bridges the `ws` WebSocket library
|
|
21
|
+
* to the MCP SDK's Transport interface.
|
|
22
|
+
*/
|
|
23
|
+
class WebSocketMcpTransport {
|
|
24
|
+
ws; // WebSocket instance from `ws` library
|
|
25
|
+
onclose;
|
|
26
|
+
onerror;
|
|
27
|
+
onmessage;
|
|
28
|
+
constructor(ws) {
|
|
29
|
+
this.ws = ws;
|
|
30
|
+
const socket = ws;
|
|
31
|
+
socket.on("message", (data) => {
|
|
32
|
+
try {
|
|
33
|
+
const text = typeof data === "string" ? data : data.toString("utf-8");
|
|
34
|
+
const message = JSON.parse(text);
|
|
35
|
+
this.onmessage?.(message);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
this.onerror?.(err instanceof Error ? err : new Error(String(err)));
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
socket.on("close", () => {
|
|
42
|
+
this.onclose?.();
|
|
43
|
+
});
|
|
44
|
+
socket.on("error", (err) => {
|
|
45
|
+
this.onerror?.(err instanceof Error ? err : new Error(String(err)));
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async start() {
|
|
49
|
+
// Already started via constructor
|
|
50
|
+
}
|
|
51
|
+
async close() {
|
|
52
|
+
const socket = this.ws;
|
|
53
|
+
socket.close();
|
|
54
|
+
}
|
|
55
|
+
async send(message) {
|
|
56
|
+
const socket = this.ws;
|
|
57
|
+
if (socket.readyState === 1) { // OPEN
|
|
58
|
+
socket.send(JSON.stringify(message));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Start a WebSocket transport server for MCP.
|
|
64
|
+
* Requires the `ws` npm package to be installed.
|
|
65
|
+
*/
|
|
66
|
+
export async function startWsTransport(server, options, logger) {
|
|
67
|
+
const host = options.host ?? "127.0.0.1";
|
|
68
|
+
// Dynamic import of ws — optional dependency.
|
|
69
|
+
// Use a variable to prevent TypeScript from resolving the module at compile time.
|
|
70
|
+
let WebSocketServer;
|
|
71
|
+
try {
|
|
72
|
+
const wsModuleName = "ws";
|
|
73
|
+
const wsModule = await import(/* webpackIgnore: true */ wsModuleName);
|
|
74
|
+
WebSocketServer = wsModule.WebSocketServer ?? wsModule.default?.WebSocketServer;
|
|
75
|
+
if (!WebSocketServer) {
|
|
76
|
+
throw new Error("WebSocketServer not found in ws module");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
logger.error("WebSocket transport requires the 'ws' npm package.\n" +
|
|
81
|
+
"Install with: npm install ws\n" +
|
|
82
|
+
"For TypeScript types: npm install -D @types/ws\n" +
|
|
83
|
+
"Then restart DeepADB with DA_WS_PORT set.");
|
|
84
|
+
throw new Error("Optional dependency 'ws' not installed. Run: npm install ws");
|
|
85
|
+
}
|
|
86
|
+
// Create HTTP server for health check endpoint
|
|
87
|
+
const httpServer = createHttpServer((req, res) => {
|
|
88
|
+
// CORS
|
|
89
|
+
const allowedOrigin = process.env.DA_WS_CORS_ORIGIN ?? "";
|
|
90
|
+
if (allowedOrigin) {
|
|
91
|
+
res.setHeader("Access-Control-Allow-Origin", allowedOrigin);
|
|
92
|
+
}
|
|
93
|
+
if (req.url === "/health" && req.method === "GET") {
|
|
94
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
95
|
+
res.end(JSON.stringify({ status: "ok", transport: "websocket", version: options.version ?? "unknown" }));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
res.writeHead(426, { "Content-Type": "application/json" });
|
|
99
|
+
res.end(JSON.stringify({ error: "Upgrade to WebSocket required. Connect to ws://host:port/ws" }));
|
|
100
|
+
});
|
|
101
|
+
// Create WebSocket server attached to the HTTP server
|
|
102
|
+
const WssConstructor = WebSocketServer;
|
|
103
|
+
const wss = new WssConstructor({ server: httpServer, path: "/ws" });
|
|
104
|
+
wss.on("connection", async (ws, req) => {
|
|
105
|
+
const remoteAddr = req.socket.remoteAddress;
|
|
106
|
+
logger.info(`WebSocket client connected from ${remoteAddr}`);
|
|
107
|
+
const transport = new WebSocketMcpTransport(ws);
|
|
108
|
+
try {
|
|
109
|
+
// Cast — our McpTransport is structurally compatible with the SDK's Transport interface
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
111
|
+
await server.connect(transport);
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
logger.error(`WebSocket transport connection error: ${err instanceof Error ? err.message : err}`);
|
|
115
|
+
}
|
|
116
|
+
const socket = ws;
|
|
117
|
+
socket.on("close", () => {
|
|
118
|
+
logger.info(`WebSocket client disconnected: ${remoteAddr}`);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
return new Promise((resolve, reject) => {
|
|
122
|
+
httpServer.on("error", (err) => {
|
|
123
|
+
logger.error(`WebSocket transport failed to start: ${err.message}`);
|
|
124
|
+
reject(err);
|
|
125
|
+
});
|
|
126
|
+
httpServer.listen(options.port, host, () => {
|
|
127
|
+
logger.info(`WebSocket transport listening on ws://${host}:${options.port}/ws`);
|
|
128
|
+
logger.info(` Health check: http://${host}:${options.port}/health`);
|
|
129
|
+
resolve();
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=ws-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-transport.js","sourceRoot":"","sources":["../src/ws-transport.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "deepadb",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "DeepADB — the deepest Android Debug Bridge MCP server. 147 tools across 41 modules for device inspection from UI to baseband.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"deepadb": "build/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"watch": "tsc --watch",
|
|
12
|
+
"start": "node build/index.js",
|
|
13
|
+
"test": "node tests/run-all.mjs",
|
|
14
|
+
"inspector": "npx @modelcontextprotocol/inspector build/index.js"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"build"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"adb",
|
|
22
|
+
"android",
|
|
23
|
+
"claude"
|
|
24
|
+
],
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=22.0.0"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@modelcontextprotocol/sdk": "^1.24.0",
|
|
31
|
+
"zod": "^3.25.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^22.0.0",
|
|
35
|
+
"typescript": "^5.7.0"
|
|
36
|
+
}
|
|
37
|
+
}
|