the-android-mcp 3.24.0 → 3.24.1
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/README.md +9 -2
- package/dist/web-ui.d.ts.map +1 -1
- package/dist/web-ui.js +303 -72
- package/dist/web-ui.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,11 +40,14 @@ sequenceDiagram
|
|
|
40
40
|
|
|
41
41
|
## Web UI v3 (Local 50000)
|
|
42
42
|
|
|
43
|
-
The local web cockpit is now
|
|
43
|
+
The local web cockpit is now English-first and beginner-first, with advanced controls hidden behind an explicit toggle.
|
|
44
44
|
|
|
45
45
|
- URL: `http://127.0.0.1:50000`
|
|
46
46
|
- Start command: `the-android-mcp-web-ui --serve --host 127.0.0.1 --port 50000`
|
|
47
|
-
- UX direction: plain-language actions, large guided cards,
|
|
47
|
+
- UX direction: plain-language actions, large guided cards, and clearer operational feedback.
|
|
48
|
+
- Structure: `Simple Mode` for daily actions, `Expert Area` for full controls.
|
|
49
|
+
- Expert Area: large control sets are grouped into collapsible modules with `Expand All Modules` / `Collapse All Modules`.
|
|
50
|
+
- Startup safety: schedule auto-resume is disabled by default; enable with `THE_ANDROID_MCP_RESUME_SCHEDULES_ON_START=1`.
|
|
48
51
|
|
|
49
52
|
### Screenshots
|
|
50
53
|
|
|
@@ -284,6 +287,10 @@ gemini mcp add the-android-mcp npx the-android-mcp
|
|
|
284
287
|
### Codex
|
|
285
288
|
On install, the package auto-adds the server to `~/.codex/config.toml` if the file exists.
|
|
286
289
|
To skip auto-setup, set `THE_ANDROID_MCP_NO_CODEX_SETUP=1`.
|
|
290
|
+
To skip Web UI auto-start on install, set `THE_ANDROID_MCP_NO_WEB_UI_AUTOSTART=1`.
|
|
291
|
+
|
|
292
|
+
Web UI schedule auto-resume on startup is disabled by default to prevent unintended background device actions.
|
|
293
|
+
To explicitly restore active schedules on startup, set `THE_ANDROID_MCP_RESUME_SCHEDULES_ON_START=1`.
|
|
287
294
|
|
|
288
295
|
If you need to add it manually, use:
|
|
289
296
|
```toml
|
package/dist/web-ui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-ui.d.ts","sourceRoot":"","sources":["../src/web-ui.ts"],"names":[],"mappings":";AAKA,OAAO,IAAyC,MAAM,MAAM,CAAC;AAgB7D,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAC/C,eAAO,MAAM,mBAAmB,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"web-ui.d.ts","sourceRoot":"","sources":["../src/web-ui.ts"],"names":[],"mappings":";AAKA,OAAO,IAAyC,MAAM,MAAM,CAAC;AAgB7D,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAC/C,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAkidzC,wBAAgB,gBAAgB,CAAC,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,IAAI,CAAC,MAAM,CAgC5F;AAED,wBAAsB,qBAAqB,CAAC,OAAO,GAAE;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACV,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAiBhF"}
|
package/dist/web-ui.js
CHANGED
|
@@ -41,6 +41,7 @@ const OPS_MISSION_POLICY_FILE = path_1.default.join(APP_STATE_DIR, 'web-ui-ops-m
|
|
|
41
41
|
const OPS_MISSION_RUNS_FILE = path_1.default.join(APP_STATE_DIR, 'web-ui-ops-mission-runs.json');
|
|
42
42
|
const OPS_MISSION_COMMAND_AUDIT_FILE = path_1.default.join(APP_STATE_DIR, 'web-ui-ops-mission-command-audit.json');
|
|
43
43
|
const OPS_MISSION_COMMAND_SNAPSHOTS_FILE = path_1.default.join(APP_STATE_DIR, 'web-ui-ops-mission-command-snapshots.json');
|
|
44
|
+
const RESUME_SCHEDULES_ON_START_ENV = 'THE_ANDROID_MCP_RESUME_SCHEDULES_ON_START';
|
|
44
45
|
const SNAPSHOT_KINDS = [
|
|
45
46
|
'radio',
|
|
46
47
|
'display',
|
|
@@ -120,6 +121,14 @@ function ensureAppStateDir() {
|
|
|
120
121
|
fs_1.default.mkdirSync(APP_STATE_DIR, { recursive: true });
|
|
121
122
|
}
|
|
122
123
|
}
|
|
124
|
+
function shouldResumeSchedulesOnStart() {
|
|
125
|
+
const raw = process.env[RESUME_SCHEDULES_ON_START_ENV];
|
|
126
|
+
if (!raw) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
const normalized = raw.trim().toLowerCase();
|
|
130
|
+
return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';
|
|
131
|
+
}
|
|
123
132
|
function appendSessionEvent(event) {
|
|
124
133
|
try {
|
|
125
134
|
ensureAppStateDir();
|
|
@@ -2967,11 +2976,28 @@ function ensureSchedulesInitialized() {
|
|
|
2967
2976
|
return;
|
|
2968
2977
|
}
|
|
2969
2978
|
loadSchedules();
|
|
2979
|
+
const resumeOnStart = shouldResumeSchedulesOnStart();
|
|
2980
|
+
let deactivated = 0;
|
|
2970
2981
|
for (const task of Object.values(schedules)) {
|
|
2971
2982
|
if (task.active) {
|
|
2972
|
-
|
|
2983
|
+
if (resumeOnStart) {
|
|
2984
|
+
startSchedule(task.id);
|
|
2985
|
+
}
|
|
2986
|
+
else {
|
|
2987
|
+
task.active = false;
|
|
2988
|
+
task.updatedAt = nowIso();
|
|
2989
|
+
deactivated += 1;
|
|
2990
|
+
}
|
|
2973
2991
|
}
|
|
2974
2992
|
}
|
|
2993
|
+
if (!resumeOnStart && deactivated > 0) {
|
|
2994
|
+
saveSchedules();
|
|
2995
|
+
pushEvent('schedule-autoresume-skipped', 'Schedule auto-resume skipped on startup', {
|
|
2996
|
+
deactivated,
|
|
2997
|
+
env: RESUME_SCHEDULES_ON_START_ENV,
|
|
2998
|
+
});
|
|
2999
|
+
console.warn(`[web-ui] schedule auto-resume disabled; deactivated ${deactivated} schedule(s). Set ${RESUME_SCHEDULES_ON_START_ENV}=1 to re-enable.`);
|
|
3000
|
+
}
|
|
2975
3001
|
schedulesInitialized = true;
|
|
2976
3002
|
}
|
|
2977
3003
|
function recorderSessionsList() {
|
|
@@ -5386,11 +5412,28 @@ function ensureOpsMissionSchedulesInitialized() {
|
|
|
5386
5412
|
return;
|
|
5387
5413
|
}
|
|
5388
5414
|
loadOpsMissionSchedules();
|
|
5415
|
+
const resumeOnStart = shouldResumeSchedulesOnStart();
|
|
5416
|
+
let deactivated = 0;
|
|
5389
5417
|
for (const schedule of Object.values(opsMissionSchedules)) {
|
|
5390
5418
|
if (schedule.active) {
|
|
5391
|
-
|
|
5419
|
+
if (resumeOnStart) {
|
|
5420
|
+
startOpsMissionSchedule(schedule.id);
|
|
5421
|
+
}
|
|
5422
|
+
else {
|
|
5423
|
+
schedule.active = false;
|
|
5424
|
+
schedule.updatedAt = nowIso();
|
|
5425
|
+
deactivated += 1;
|
|
5426
|
+
}
|
|
5392
5427
|
}
|
|
5393
5428
|
}
|
|
5429
|
+
if (!resumeOnStart && deactivated > 0) {
|
|
5430
|
+
saveOpsMissionSchedules();
|
|
5431
|
+
pushEvent('ops-mission-schedule-autoresume-skipped', 'Ops mission schedule auto-resume skipped on startup', {
|
|
5432
|
+
deactivated,
|
|
5433
|
+
env: RESUME_SCHEDULES_ON_START_ENV,
|
|
5434
|
+
});
|
|
5435
|
+
console.warn(`[web-ui] ops mission schedule auto-resume disabled; deactivated ${deactivated} schedule(s). Set ${RESUME_SCHEDULES_ON_START_ENV}=1 to re-enable.`);
|
|
5436
|
+
}
|
|
5394
5437
|
opsMissionSchedulesInitialized = true;
|
|
5395
5438
|
}
|
|
5396
5439
|
function createOpsMissionSchedule(body) {
|
|
@@ -8934,21 +8977,21 @@ const INDEX_HTML = String.raw `<!doctype html>
|
|
|
8934
8977
|
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
8935
8978
|
<style>
|
|
8936
8979
|
:root {
|
|
8937
|
-
--bg0: #
|
|
8938
|
-
--bg1: #
|
|
8939
|
-
--bg2: #
|
|
8940
|
-
--card: #
|
|
8941
|
-
--card-strong: #
|
|
8942
|
-
--line: #
|
|
8943
|
-
--line-soft: #
|
|
8944
|
-
--text: #
|
|
8945
|
-
--muted: #
|
|
8946
|
-
--ok: #
|
|
8947
|
-
--err: #
|
|
8948
|
-
--acc0: #
|
|
8949
|
-
--acc1: #
|
|
8950
|
-
--acc2: #
|
|
8951
|
-
--warn: #
|
|
8980
|
+
--bg0: #0a151f;
|
|
8981
|
+
--bg1: #102334;
|
|
8982
|
+
--bg2: #183a53;
|
|
8983
|
+
--card: #122436e6;
|
|
8984
|
+
--card-strong: #152c41f2;
|
|
8985
|
+
--line: #3f6076b8;
|
|
8986
|
+
--line-soft: #4b71895c;
|
|
8987
|
+
--text: #edf7ff;
|
|
8988
|
+
--muted: #a9c5d8;
|
|
8989
|
+
--ok: #86f2ca;
|
|
8990
|
+
--err: #ff9cab;
|
|
8991
|
+
--acc0: #02c9a4;
|
|
8992
|
+
--acc1: #1ea7ff;
|
|
8993
|
+
--acc2: #8be8ff;
|
|
8994
|
+
--warn: #ffc06f;
|
|
8952
8995
|
}
|
|
8953
8996
|
* { box-sizing: border-box; }
|
|
8954
8997
|
body {
|
|
@@ -8957,21 +9000,19 @@ const INDEX_HTML = String.raw `<!doctype html>
|
|
|
8957
9000
|
color: var(--text);
|
|
8958
9001
|
min-height: 100vh;
|
|
8959
9002
|
background:
|
|
8960
|
-
|
|
8961
|
-
|
|
9003
|
+
radial-gradient(circle at 10% 10%, #1c3f5f8a 0%, #0a1724 32%, #07131d 65%, #060f16 100%),
|
|
9004
|
+
linear-gradient(180deg, #0a1622, #061019);
|
|
8962
9005
|
padding: 16px;
|
|
8963
9006
|
}
|
|
8964
9007
|
.app { max-width: 1600px; margin: 0 auto; display: grid; gap: 14px; }
|
|
8965
9008
|
.hero {
|
|
8966
9009
|
border: 1px solid var(--line);
|
|
8967
9010
|
border-radius: 20px;
|
|
8968
|
-
background:
|
|
8969
|
-
linear-gradient(125deg, #0d2538d8, #10263bd1),
|
|
8970
|
-
url('https://images.unsplash.com/photo-1498050108023-c5249f4df085?auto=format&fit=crop&w=1800&q=80') center/cover;
|
|
9011
|
+
background: linear-gradient(135deg, #11283c, #0d1f2f 42%, #14324a);
|
|
8971
9012
|
box-shadow: 0 20px 60px #02090f8c;
|
|
8972
|
-
padding:
|
|
9013
|
+
padding: 18px;
|
|
8973
9014
|
display: grid;
|
|
8974
|
-
gap:
|
|
9015
|
+
gap: 10px;
|
|
8975
9016
|
}
|
|
8976
9017
|
.hero h1 { margin: 0; font-size: 1.55rem; letter-spacing: 0.01em; }
|
|
8977
9018
|
.hero-badge {
|
|
@@ -9009,7 +9050,7 @@ const INDEX_HTML = String.raw `<!doctype html>
|
|
|
9009
9050
|
.easy-mode {
|
|
9010
9051
|
border: 1px solid var(--line);
|
|
9011
9052
|
border-radius: 20px;
|
|
9012
|
-
background: linear-gradient(
|
|
9053
|
+
background: linear-gradient(150deg, #11263aef, #11293fef 45%, #142f46eb);
|
|
9013
9054
|
backdrop-filter: blur(7px);
|
|
9014
9055
|
padding: 14px;
|
|
9015
9056
|
display: grid;
|
|
@@ -9041,11 +9082,7 @@ const INDEX_HTML = String.raw `<!doctype html>
|
|
|
9041
9082
|
border: 1px solid var(--line-soft);
|
|
9042
9083
|
border-radius: 14px;
|
|
9043
9084
|
padding: 10px;
|
|
9044
|
-
background:
|
|
9045
|
-
linear-gradient(145deg, #0f2232e8, #0c1d2be8),
|
|
9046
|
-
var(--easy-bg, none);
|
|
9047
|
-
background-size: cover;
|
|
9048
|
-
background-position: center;
|
|
9085
|
+
background: linear-gradient(145deg, #102435f2, #0e1f2ef2);
|
|
9049
9086
|
display: grid;
|
|
9050
9087
|
gap: 7px;
|
|
9051
9088
|
}
|
|
@@ -9110,10 +9147,37 @@ const INDEX_HTML = String.raw `<!doctype html>
|
|
|
9110
9147
|
min-width: 240px;
|
|
9111
9148
|
border-radius: 999px;
|
|
9112
9149
|
}
|
|
9150
|
+
.advanced-head {
|
|
9151
|
+
grid-column: 1 / -1;
|
|
9152
|
+
border: 1px solid var(--line);
|
|
9153
|
+
border-radius: 14px;
|
|
9154
|
+
background: linear-gradient(140deg, #112537eb, #102132ef);
|
|
9155
|
+
padding: 12px;
|
|
9156
|
+
display: grid;
|
|
9157
|
+
gap: 10px;
|
|
9158
|
+
}
|
|
9159
|
+
.advanced-head h2 {
|
|
9160
|
+
margin: 0;
|
|
9161
|
+
font-size: 1.02rem;
|
|
9162
|
+
}
|
|
9163
|
+
.advanced-head p {
|
|
9164
|
+
margin: 0;
|
|
9165
|
+
color: var(--muted);
|
|
9166
|
+
font-size: 12px;
|
|
9167
|
+
}
|
|
9168
|
+
.advanced-head-actions {
|
|
9169
|
+
display: flex;
|
|
9170
|
+
flex-wrap: wrap;
|
|
9171
|
+
gap: 8px;
|
|
9172
|
+
}
|
|
9173
|
+
.advanced-head-actions button {
|
|
9174
|
+
width: auto;
|
|
9175
|
+
min-width: 200px;
|
|
9176
|
+
}
|
|
9113
9177
|
.grid {
|
|
9114
9178
|
display: grid;
|
|
9115
9179
|
gap: 10px;
|
|
9116
|
-
grid-template-columns:
|
|
9180
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
9117
9181
|
}
|
|
9118
9182
|
.grid.hidden {
|
|
9119
9183
|
display: none;
|
|
@@ -9184,15 +9248,45 @@ const INDEX_HTML = String.raw `<!doctype html>
|
|
|
9184
9248
|
.muted { margin: 0; color: var(--muted); font-size: 12px; }
|
|
9185
9249
|
.ok { color: var(--ok); }
|
|
9186
9250
|
.err { color: var(--err); }
|
|
9251
|
+
.ops-group {
|
|
9252
|
+
border: 1px solid var(--line-soft);
|
|
9253
|
+
border-radius: 12px;
|
|
9254
|
+
background: #0d1d2be8;
|
|
9255
|
+
overflow: hidden;
|
|
9256
|
+
}
|
|
9257
|
+
.ops-group + .ops-group {
|
|
9258
|
+
margin-top: 8px;
|
|
9259
|
+
}
|
|
9260
|
+
.ops-group > summary {
|
|
9261
|
+
list-style: none;
|
|
9262
|
+
cursor: pointer;
|
|
9263
|
+
padding: 10px 12px;
|
|
9264
|
+
font-size: 12px;
|
|
9265
|
+
font-weight: 700;
|
|
9266
|
+
letter-spacing: 0.01em;
|
|
9267
|
+
background: linear-gradient(140deg, #122a3e, #102435);
|
|
9268
|
+
}
|
|
9269
|
+
.ops-group > summary::-webkit-details-marker {
|
|
9270
|
+
display: none;
|
|
9271
|
+
}
|
|
9272
|
+
.ops-group[open] > summary {
|
|
9273
|
+
border-bottom: 1px solid var(--line-soft);
|
|
9274
|
+
}
|
|
9275
|
+
.ops-group-body {
|
|
9276
|
+
display: grid;
|
|
9277
|
+
gap: 8px;
|
|
9278
|
+
padding: 10px;
|
|
9279
|
+
}
|
|
9187
9280
|
@media (max-width: 1300px) {
|
|
9188
9281
|
.easy-grid { grid-template-columns: 1fr 1fr; }
|
|
9189
9282
|
.easy-stats { grid-template-columns: 1fr 1fr; }
|
|
9190
9283
|
}
|
|
9191
|
-
@media (max-width: 1200px) { .grid { grid-template-columns: 1fr
|
|
9284
|
+
@media (max-width: 1200px) { .grid { grid-template-columns: 1fr; } }
|
|
9192
9285
|
@media (max-width: 900px) {
|
|
9193
9286
|
.grid { grid-template-columns: 1fr; }
|
|
9194
9287
|
.easy-grid { grid-template-columns: 1fr; }
|
|
9195
9288
|
.easy-ops { grid-template-columns: 1fr; }
|
|
9289
|
+
.advanced-head-actions button { width: 100%; min-width: 0; }
|
|
9196
9290
|
}
|
|
9197
9291
|
</style>
|
|
9198
9292
|
</head>
|
|
@@ -9208,58 +9302,67 @@ const INDEX_HTML = String.raw `<!doctype html>
|
|
|
9208
9302
|
<span class="pill" id="queue-pill">queue: 0</span>
|
|
9209
9303
|
<span class="pill">port: 50000</span>
|
|
9210
9304
|
</div>
|
|
9211
|
-
<span class="hero-badge">
|
|
9212
|
-
<h1>the-android-mcp v${package_json_1.default.version}
|
|
9213
|
-
<p class="muted">
|
|
9305
|
+
<span class="hero-badge">Clear Control Mode</span>
|
|
9306
|
+
<h1>the-android-mcp v${package_json_1.default.version} Control Room</h1>
|
|
9307
|
+
<p class="muted">Start in simple mode. Expert tools are available below in structured, collapsible modules.</p>
|
|
9214
9308
|
</section>
|
|
9215
9309
|
|
|
9216
9310
|
<section class="easy-mode">
|
|
9217
9311
|
<div class="easy-head">
|
|
9218
|
-
<h2>
|
|
9219
|
-
<p class="easy-note">
|
|
9312
|
+
<h2>Simple Mode: Quick Actions</h2>
|
|
9313
|
+
<p class="easy-note">For everyday use and quick checks: enter a URL, run an action, and read the status.</p>
|
|
9220
9314
|
</div>
|
|
9221
9315
|
<div class="easy-grid">
|
|
9222
|
-
<article class="easy-card"
|
|
9223
|
-
<h3>
|
|
9316
|
+
<article class="easy-card">
|
|
9317
|
+
<h3>1. Open a website on your device</h3>
|
|
9224
9318
|
<input id="easy-url-input" type="url" value="https://www.wikipedia.org" />
|
|
9225
9319
|
<div class="easy-ops">
|
|
9226
|
-
<button class="easy-btn" id="easy-open-btn">Website
|
|
9227
|
-
<button class="easy-btn alt" id="easy-smoke-btn">
|
|
9320
|
+
<button class="easy-btn" id="easy-open-btn">Open Website</button>
|
|
9321
|
+
<button class="easy-btn alt" id="easy-smoke-btn">Run Quick Check</button>
|
|
9228
9322
|
</div>
|
|
9229
|
-
<div class="easy-hint" id="easy-last-action">
|
|
9323
|
+
<div class="easy-hint" id="easy-last-action">No action executed yet.</div>
|
|
9230
9324
|
</article>
|
|
9231
|
-
<article class="easy-card"
|
|
9232
|
-
<h3>
|
|
9325
|
+
<article class="easy-card">
|
|
9326
|
+
<h3>2. Stabilize and recover</h3>
|
|
9233
9327
|
<div class="easy-ops">
|
|
9234
|
-
<button class="easy-btn alt" id="easy-autofix-btn">Auto-Fix
|
|
9235
|
-
<button class="easy-btn" id="easy-strategy-btn">Turbo
|
|
9328
|
+
<button class="easy-btn alt" id="easy-autofix-btn">Run Auto-Fix</button>
|
|
9329
|
+
<button class="easy-btn" id="easy-strategy-btn">Run Turbo Strategy</button>
|
|
9236
9330
|
</div>
|
|
9237
|
-
<button class="easy-btn warn" id="easy-panic-btn">
|
|
9331
|
+
<button class="easy-btn warn" id="easy-panic-btn">Emergency Stabilization</button>
|
|
9238
9332
|
</article>
|
|
9239
9333
|
<article class="easy-card">
|
|
9240
|
-
<h3>Status
|
|
9334
|
+
<h3>Status Summary</h3>
|
|
9241
9335
|
<div class="easy-stats">
|
|
9242
|
-
<div class="easy-stat"><strong id="easy-risk">-</strong><span>
|
|
9243
|
-
<div class="easy-stat"><strong id="easy-mode">-</strong><span>
|
|
9244
|
-
<div class="easy-stat"><strong id="easy-device">-</strong><span>
|
|
9336
|
+
<div class="easy-stat"><strong id="easy-risk">-</strong><span>Risk</span></div>
|
|
9337
|
+
<div class="easy-stat"><strong id="easy-mode">-</strong><span>Mode</span></div>
|
|
9338
|
+
<div class="easy-stat"><strong id="easy-device">-</strong><span>Devices</span></div>
|
|
9245
9339
|
<div class="easy-stat"><strong id="easy-jobs">-</strong><span>Jobs</span></div>
|
|
9246
9340
|
</div>
|
|
9247
|
-
<div class="easy-hint" id="easy-recommendation">
|
|
9341
|
+
<div class="easy-hint" id="easy-recommendation">Loading recommendation ...</div>
|
|
9248
9342
|
</article>
|
|
9249
9343
|
</div>
|
|
9250
9344
|
<div class="advanced-toggle-wrap">
|
|
9251
|
-
<button class="s advanced-toggle-btn" id="easy-toggle-advanced-btn">
|
|
9345
|
+
<button class="s advanced-toggle-btn" id="easy-toggle-advanced-btn">Show Expert Area</button>
|
|
9252
9346
|
</div>
|
|
9253
9347
|
</section>
|
|
9254
9348
|
|
|
9255
9349
|
<section class="grid hidden" id="advanced-grid">
|
|
9350
|
+
<div class="advanced-head">
|
|
9351
|
+
<h2>Expert Area</h2>
|
|
9352
|
+
<p>All features remain available. Larger tool collections are grouped into thematic, collapsible modules.</p>
|
|
9353
|
+
<div class="advanced-head-actions">
|
|
9354
|
+
<button class="s" id="advanced-expand-all-btn">Expand All Modules</button>
|
|
9355
|
+
<button class="s" id="advanced-collapse-all-btn">Collapse All Modules</button>
|
|
9356
|
+
</div>
|
|
9357
|
+
</div>
|
|
9256
9358
|
<article class="card stack">
|
|
9257
|
-
<h2>Device
|
|
9359
|
+
<h2>Direct Device Control</h2>
|
|
9360
|
+
<p class="muted">Run direct actions on the currently connected device.</p>
|
|
9258
9361
|
<select id="device-select"></select>
|
|
9259
9362
|
<input id="url-input" type="url" value="https://www.wikipedia.org" />
|
|
9260
9363
|
<div class="split">
|
|
9261
9364
|
<button class="p" id="open-url-btn">Open URL</button>
|
|
9262
|
-
<button class="p" id="suite-btn">Run
|
|
9365
|
+
<button class="p" id="suite-btn">Run Diagnostic Suite</button>
|
|
9263
9366
|
</div>
|
|
9264
9367
|
<div class="quick">
|
|
9265
9368
|
<button class="s quick-url" data-url="https://www.wikipedia.org">Wikipedia</button>
|
|
@@ -9268,14 +9371,15 @@ const INDEX_HTML = String.raw `<!doctype html>
|
|
|
9268
9371
|
<button class="s quick-url" data-url="https://www.youtube.com">YouTube</button>
|
|
9269
9372
|
</div>
|
|
9270
9373
|
<div class="split">
|
|
9271
|
-
<button class="s" id="profile-btn">Device
|
|
9272
|
-
<button class="s" id="profiles-btn">Profiles
|
|
9374
|
+
<button class="s" id="profile-btn">Load Device Profile</button>
|
|
9375
|
+
<button class="s" id="profiles-btn">Profiles for All Devices</button>
|
|
9273
9376
|
</div>
|
|
9274
9377
|
<p class="muted">Update hint: <code>npm install -g the-android-mcp@latest</code></p>
|
|
9275
9378
|
</article>
|
|
9276
9379
|
|
|
9277
9380
|
<article class="card stack">
|
|
9278
|
-
<h2>
|
|
9381
|
+
<h2>Diagnostics & Stress Testing</h2>
|
|
9382
|
+
<p class="muted">Capture snapshots, compare deltas, and run URL loop tests.</p>
|
|
9279
9383
|
<select id="snapshot-kind">
|
|
9280
9384
|
<option value="radio">radio</option>
|
|
9281
9385
|
<option value="display">display</option>
|
|
@@ -9298,7 +9402,8 @@ https://developer.android.com</textarea>
|
|
|
9298
9402
|
</article>
|
|
9299
9403
|
|
|
9300
9404
|
<article class="card stack">
|
|
9301
|
-
<h2>
|
|
9405
|
+
<h2>Manage Workflows</h2>
|
|
9406
|
+
<p class="muted">Save, run, and export multi-step flows.</p>
|
|
9302
9407
|
<select id="workflow-select"></select>
|
|
9303
9408
|
<input id="workflow-name" placeholder="workflow name" />
|
|
9304
9409
|
<textarea id="workflow-steps">[
|
|
@@ -9318,7 +9423,8 @@ https://developer.android.com</textarea>
|
|
|
9318
9423
|
</article>
|
|
9319
9424
|
|
|
9320
9425
|
<article class="card stack">
|
|
9321
|
-
<h2>
|
|
9426
|
+
<h2>Jobs & Queue</h2>
|
|
9427
|
+
<p class="muted">Queue single jobs or batch jobs.</p>
|
|
9322
9428
|
<select id="job-type">
|
|
9323
9429
|
<option value="open_url">open_url</option>
|
|
9324
9430
|
<option value="snapshot_suite">snapshot_suite</option>
|
|
@@ -9342,13 +9448,15 @@ https://developer.android.com</textarea>
|
|
|
9342
9448
|
</article>
|
|
9343
9449
|
|
|
9344
9450
|
<article class="card stack">
|
|
9345
|
-
<h2>
|
|
9451
|
+
<h2>Live Status & Events</h2>
|
|
9452
|
+
<p class="muted">Current lanes and event feed in realtime.</p>
|
|
9346
9453
|
<div id="lanes" class="lanes"></div>
|
|
9347
9454
|
<div id="events" class="events"></div>
|
|
9348
9455
|
</article>
|
|
9349
9456
|
|
|
9350
9457
|
<article class="card stack">
|
|
9351
|
-
<h2>
|
|
9458
|
+
<h2>Advanced Control</h2>
|
|
9459
|
+
<p class="muted">Autopilot, policies, schedules, and missions grouped into modules.</p>
|
|
9352
9460
|
<div class="split">
|
|
9353
9461
|
<button class="w" id="pause-all-lanes-btn">Pause all lanes</button>
|
|
9354
9462
|
<button class="p" id="resume-all-lanes-btn">Resume all lanes</button>
|
|
@@ -9747,7 +9855,7 @@ https://developer.android.com</textarea>
|
|
|
9747
9855
|
</article>
|
|
9748
9856
|
|
|
9749
9857
|
<article class="card stack">
|
|
9750
|
-
<h2>
|
|
9858
|
+
<h2>Metriken & Sitzung</h2>
|
|
9751
9859
|
<div id="metrics" class="metrics"></div>
|
|
9752
9860
|
<div class="split">
|
|
9753
9861
|
<button class="s" id="refresh-state-btn">Refresh state</button>
|
|
@@ -9897,6 +10005,8 @@ https://developer.android.com</textarea>
|
|
|
9897
10005
|
const $easyLastAction = document.getElementById('easy-last-action');
|
|
9898
10006
|
const $advancedGrid = document.getElementById('advanced-grid');
|
|
9899
10007
|
const $easyToggleAdvancedBtn = document.getElementById('easy-toggle-advanced-btn');
|
|
10008
|
+
const $advancedExpandAllBtn = document.getElementById('advanced-expand-all-btn');
|
|
10009
|
+
const $advancedCollapseAllBtn = document.getElementById('advanced-collapse-all-btn');
|
|
9900
10010
|
|
|
9901
10011
|
function setMessage(text, isError) {
|
|
9902
10012
|
$message.textContent = text;
|
|
@@ -10766,46 +10876,152 @@ https://developer.android.com</textarea>
|
|
|
10766
10876
|
async function easyOpenWebsiteUi() {
|
|
10767
10877
|
const url = ($easyUrlInput && $easyUrlInput.value ? $easyUrlInput.value : $urlInput.value || '').trim();
|
|
10768
10878
|
if (!url) {
|
|
10769
|
-
throw new Error('
|
|
10879
|
+
throw new Error('Please enter a URL.');
|
|
10770
10880
|
}
|
|
10771
10881
|
$urlInput.value = url;
|
|
10772
10882
|
await openUrl(url);
|
|
10773
|
-
setEasyLastAction('Website
|
|
10883
|
+
setEasyLastAction('Website opened: ' + url, false);
|
|
10774
10884
|
await loadEasyOverview();
|
|
10775
10885
|
}
|
|
10776
10886
|
|
|
10777
10887
|
async function easySmokeUi() {
|
|
10778
10888
|
await runDeviceSmoke();
|
|
10779
10889
|
await runSuite();
|
|
10780
|
-
setEasyLastAction('
|
|
10890
|
+
setEasyLastAction('Quick check completed.', false);
|
|
10781
10891
|
await loadEasyOverview();
|
|
10782
10892
|
}
|
|
10783
10893
|
|
|
10784
10894
|
async function easyAutoFixUi() {
|
|
10785
10895
|
await runOpsMissionCommandQuickFixUi();
|
|
10786
|
-
setEasyLastAction('Auto-
|
|
10896
|
+
setEasyLastAction('Auto-fix executed.', false);
|
|
10787
10897
|
await loadEasyOverview();
|
|
10788
10898
|
}
|
|
10789
10899
|
|
|
10790
10900
|
async function easyStrategyUi() {
|
|
10791
10901
|
await executeOpsMissionCommandStrategyUi();
|
|
10792
|
-
setEasyLastAction('Turbo
|
|
10902
|
+
setEasyLastAction('Turbo strategy completed.', false);
|
|
10793
10903
|
await loadEasyOverview();
|
|
10794
10904
|
}
|
|
10795
10905
|
|
|
10796
10906
|
async function easyPanicUi() {
|
|
10797
10907
|
await runOpsStabilizeUi();
|
|
10798
10908
|
await runWatchdogUi();
|
|
10799
|
-
setEasyLastAction('
|
|
10909
|
+
setEasyLastAction('Emergency stabilization completed.', false);
|
|
10800
10910
|
await loadEasyOverview();
|
|
10801
10911
|
}
|
|
10802
10912
|
|
|
10913
|
+
let advancedUiStructured = false;
|
|
10914
|
+
|
|
10915
|
+
function structureAdvancedUi() {
|
|
10916
|
+
if (advancedUiStructured || !$advancedGrid) {
|
|
10917
|
+
return;
|
|
10918
|
+
}
|
|
10919
|
+
|
|
10920
|
+
const cards = Array.from($advancedGrid.querySelectorAll('article.card.stack'));
|
|
10921
|
+
const opsCard = cards.find(function (card) {
|
|
10922
|
+
const title = card.querySelector('h2');
|
|
10923
|
+
const text = title && title.textContent ? title.textContent.trim().toLowerCase() : '';
|
|
10924
|
+
return text.includes('erweiterte steuerung') || text.includes('queue control');
|
|
10925
|
+
});
|
|
10926
|
+
|
|
10927
|
+
if (!opsCard) {
|
|
10928
|
+
advancedUiStructured = true;
|
|
10929
|
+
return;
|
|
10930
|
+
}
|
|
10931
|
+
|
|
10932
|
+
const titleNode = opsCard.querySelector('h2');
|
|
10933
|
+
if (!titleNode) {
|
|
10934
|
+
advancedUiStructured = true;
|
|
10935
|
+
return;
|
|
10936
|
+
}
|
|
10937
|
+
|
|
10938
|
+
const allChildren = Array.from(opsCard.children);
|
|
10939
|
+
const contentNodes = allChildren.filter(function (node) {
|
|
10940
|
+
return node !== titleNode && !(node instanceof HTMLElement && node.tagName.toLowerCase() === 'p' && node.classList.contains('muted'));
|
|
10941
|
+
});
|
|
10942
|
+
|
|
10943
|
+
const groups = [];
|
|
10944
|
+
let current = [];
|
|
10945
|
+
for (const node of contentNodes) {
|
|
10946
|
+
if (node instanceof HTMLElement && node.tagName.toLowerCase() === 'hr') {
|
|
10947
|
+
if (current.length > 0) {
|
|
10948
|
+
groups.push(current);
|
|
10949
|
+
current = [];
|
|
10950
|
+
}
|
|
10951
|
+
continue;
|
|
10952
|
+
}
|
|
10953
|
+
current.push(node);
|
|
10954
|
+
}
|
|
10955
|
+
if (current.length > 0) {
|
|
10956
|
+
groups.push(current);
|
|
10957
|
+
}
|
|
10958
|
+
|
|
10959
|
+
const labels = [
|
|
10960
|
+
'Immediate Actions: Queue, Smoke, Autopilot',
|
|
10961
|
+
'Recorder: Capture & Replay',
|
|
10962
|
+
'Presets & Heatmap',
|
|
10963
|
+
'Policy, Runbook & Transactions',
|
|
10964
|
+
'Queue Board & Schedules',
|
|
10965
|
+
'Alert Rules',
|
|
10966
|
+
'Import/Export, Baselines, Campaigns',
|
|
10967
|
+
'Stabilization & Control Room',
|
|
10968
|
+
'Policy Presets',
|
|
10969
|
+
'Watchdog Profiles',
|
|
10970
|
+
'Ops Action Queue',
|
|
10971
|
+
'Gate Checks',
|
|
10972
|
+
'Missions',
|
|
10973
|
+
'Mission Schedules & Analytics',
|
|
10974
|
+
'Mission Policy',
|
|
10975
|
+
'Additional Tools',
|
|
10976
|
+
];
|
|
10977
|
+
|
|
10978
|
+
for (const node of contentNodes) {
|
|
10979
|
+
if (node.parentNode === opsCard) {
|
|
10980
|
+
opsCard.removeChild(node);
|
|
10981
|
+
}
|
|
10982
|
+
}
|
|
10983
|
+
|
|
10984
|
+
for (let index = 0; index < groups.length; index += 1) {
|
|
10985
|
+
const details = document.createElement('details');
|
|
10986
|
+
details.className = 'ops-group';
|
|
10987
|
+
details.open = index < 2;
|
|
10988
|
+
|
|
10989
|
+
const summary = document.createElement('summary');
|
|
10990
|
+
summary.textContent = labels[index] || ('Module ' + String(index + 1));
|
|
10991
|
+
details.appendChild(summary);
|
|
10992
|
+
|
|
10993
|
+
const body = document.createElement('div');
|
|
10994
|
+
body.className = 'ops-group-body';
|
|
10995
|
+
for (const node of groups[index]) {
|
|
10996
|
+
body.appendChild(node);
|
|
10997
|
+
}
|
|
10998
|
+
|
|
10999
|
+
details.appendChild(body);
|
|
11000
|
+
opsCard.appendChild(details);
|
|
11001
|
+
}
|
|
11002
|
+
|
|
11003
|
+
advancedUiStructured = true;
|
|
11004
|
+
}
|
|
11005
|
+
|
|
11006
|
+
function setOpsGroupsOpen(open) {
|
|
11007
|
+
if (!$advancedGrid) {
|
|
11008
|
+
return;
|
|
11009
|
+
}
|
|
11010
|
+
const groups = $advancedGrid.querySelectorAll('.ops-group');
|
|
11011
|
+
for (const group of groups) {
|
|
11012
|
+
group.open = open;
|
|
11013
|
+
}
|
|
11014
|
+
}
|
|
11015
|
+
|
|
10803
11016
|
function toggleAdvancedUi() {
|
|
10804
11017
|
if (!$advancedGrid || !$easyToggleAdvancedBtn) {
|
|
10805
11018
|
return;
|
|
10806
11019
|
}
|
|
10807
11020
|
const hidden = $advancedGrid.classList.toggle('hidden');
|
|
10808
|
-
|
|
11021
|
+
if (!hidden) {
|
|
11022
|
+
structureAdvancedUi();
|
|
11023
|
+
}
|
|
11024
|
+
$easyToggleAdvancedBtn.textContent = hidden ? 'Show Expert Area' : 'Hide Expert Area';
|
|
10809
11025
|
}
|
|
10810
11026
|
|
|
10811
11027
|
function connectRealtime() {
|
|
@@ -10865,7 +11081,7 @@ https://developer.android.com</textarea>
|
|
|
10865
11081
|
if ($easyUrlInput) {
|
|
10866
11082
|
$easyUrlInput.value = url;
|
|
10867
11083
|
}
|
|
10868
|
-
setEasyLastAction('Website
|
|
11084
|
+
setEasyLastAction('Website opened: ' + url, false);
|
|
10869
11085
|
setMessage('URL opened', false);
|
|
10870
11086
|
}
|
|
10871
11087
|
|
|
@@ -13062,6 +13278,20 @@ https://developer.android.com</textarea>
|
|
|
13062
13278
|
toggleAdvancedUi();
|
|
13063
13279
|
});
|
|
13064
13280
|
}
|
|
13281
|
+
if ($advancedExpandAllBtn) {
|
|
13282
|
+
$advancedExpandAllBtn.addEventListener('click', function () {
|
|
13283
|
+
structureAdvancedUi();
|
|
13284
|
+
setOpsGroupsOpen(true);
|
|
13285
|
+
setMessage('Expanded all expert modules', false);
|
|
13286
|
+
});
|
|
13287
|
+
}
|
|
13288
|
+
if ($advancedCollapseAllBtn) {
|
|
13289
|
+
$advancedCollapseAllBtn.addEventListener('click', function () {
|
|
13290
|
+
structureAdvancedUi();
|
|
13291
|
+
setOpsGroupsOpen(false);
|
|
13292
|
+
setMessage('Collapsed all expert modules', false);
|
|
13293
|
+
});
|
|
13294
|
+
}
|
|
13065
13295
|
|
|
13066
13296
|
document.getElementById('open-url-btn').addEventListener('click', async function () {
|
|
13067
13297
|
try { await openUrl($urlInput.value); } catch (error) { setMessage(String(error), true); }
|
|
@@ -13494,13 +13724,14 @@ https://developer.android.com</textarea>
|
|
|
13494
13724
|
|
|
13495
13725
|
async function init() {
|
|
13496
13726
|
try {
|
|
13727
|
+
structureAdvancedUi();
|
|
13497
13728
|
ensureOpsMissionCommandCenterUi();
|
|
13498
13729
|
await refreshCore();
|
|
13499
13730
|
if ($easyUrlInput && !$easyUrlInput.value) {
|
|
13500
13731
|
$easyUrlInput.value = $urlInput.value || 'https://www.wikipedia.org';
|
|
13501
13732
|
}
|
|
13502
13733
|
await loadEasyOverview();
|
|
13503
|
-
setEasyLastAction('
|
|
13734
|
+
setEasyLastAction('Ready. Choose an action in Simple Mode above.', false);
|
|
13504
13735
|
const history = await api('/api/history?limit=45');
|
|
13505
13736
|
const events = Array.isArray(history.events) ? history.events : [];
|
|
13506
13737
|
for (let i = events.length - 1; i >= 0; i -= 1) {
|