@autifyhq/aximo-cli 0.15.0 → 0.16.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/README.md +19 -1
- package/dist/commands/device/device-config.d.ts +2 -2
- package/dist/commands/device/device-config.js +5 -8
- package/dist/commands/device/index.js +2 -1
- package/dist/commands/device/paths.d.ts +4 -0
- package/dist/commands/device/paths.js +12 -0
- package/dist/commands/device/reset.d.ts +1 -0
- package/dist/commands/device/reset.js +18 -3
- package/dist/commands/device/reset.test.js +13 -0
- package/dist/commands/device/testbox/box.d.ts +90 -0
- package/dist/commands/device/testbox/box.js +379 -0
- package/dist/commands/device/testbox/box.test.d.ts +1 -0
- package/dist/commands/device/testbox/box.test.js +815 -0
- package/dist/commands/device/testbox/container.d.ts +58 -0
- package/dist/commands/device/testbox/container.js +289 -0
- package/dist/commands/device/testbox/docker.d.ts +31 -0
- package/dist/commands/device/testbox/docker.js +78 -0
- package/dist/commands/device/testbox/docker.test.d.ts +1 -0
- package/dist/commands/device/testbox/docker.test.js +82 -0
- package/dist/commands/device/testbox/down.d.ts +7 -0
- package/dist/commands/device/testbox/down.js +14 -0
- package/dist/commands/device/testbox/errors.d.ts +4 -0
- package/dist/commands/device/testbox/errors.js +7 -0
- package/dist/commands/device/testbox/fake-docker.d.ts +25 -0
- package/dist/commands/device/testbox/fake-docker.js +35 -0
- package/dist/commands/device/testbox/index.d.ts +2 -0
- package/dist/commands/device/testbox/index.js +16 -0
- package/dist/commands/device/testbox/logs.d.ts +15 -0
- package/dist/commands/device/testbox/logs.js +43 -0
- package/dist/commands/device/testbox/prune.d.ts +11 -0
- package/dist/commands/device/testbox/prune.js +17 -0
- package/dist/commands/device/testbox/registration.d.ts +9 -0
- package/dist/commands/device/testbox/registration.js +56 -0
- package/dist/commands/device/testbox/reset.d.ts +7 -0
- package/dist/commands/device/testbox/reset.js +14 -0
- package/dist/commands/device/testbox/result.d.ts +8 -0
- package/dist/commands/device/testbox/result.js +23 -0
- package/dist/commands/device/testbox/result.test.d.ts +1 -0
- package/dist/commands/device/testbox/result.test.js +34 -0
- package/dist/commands/device/testbox/self-command.d.ts +12 -0
- package/dist/commands/device/testbox/self-command.js +36 -0
- package/dist/commands/device/testbox/self-command.test.d.ts +1 -0
- package/dist/commands/device/testbox/self-command.test.js +58 -0
- package/dist/commands/device/testbox/status.d.ts +7 -0
- package/dist/commands/device/testbox/status.js +11 -0
- package/dist/commands/device/testbox/up.d.ts +47 -0
- package/dist/commands/device/testbox/up.js +76 -0
- package/dist/commands/device/testbox/up.test.d.ts +1 -0
- package/dist/commands/device/testbox/up.test.js +52 -0
- package/dist/commands/device/testbox/url.d.ts +7 -0
- package/dist/commands/device/testbox/url.js +20 -0
- package/dist/commands/device/user-devices.d.ts +4 -0
- package/dist/commands/device/user-devices.js +18 -0
- package/dist/commands/mcp/server.d.ts +2 -2
- package/dist/commands/mcp/server.test.js +6 -2
- package/dist/commands/mcp/testbox-tools.test.d.ts +1 -0
- package/dist/commands/mcp/testbox-tools.test.js +278 -0
- package/dist/commands/mcp/tools.d.ts +8 -1
- package/dist/commands/mcp/tools.js +151 -18
- package/dist/commands/mcp/tools.test.js +27 -2
- package/dist/commands/schema.js +4 -0
- package/dist/commands/session/cancel.d.ts +20 -0
- package/dist/commands/session/cancel.js +39 -0
- package/dist/commands/session/index.js +1 -0
- package/dist/commands/session/session.test.js +38 -0
- package/dist/errors.d.ts +2 -0
- package/dist/errors.js +5 -0
- package/dist/errors.test.js +6 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/types.d.ts +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -73,6 +73,7 @@ Run `aximo <command> --help` for detailed usage. `aximo schema [command.path]` r
|
|
|
73
73
|
| `aximo project list` | List organization projects |
|
|
74
74
|
| `aximo session create` | Create and queue a test session |
|
|
75
75
|
| `aximo session get` | Get session status |
|
|
76
|
+
| `aximo session cancel` | Cancel a queued or running session |
|
|
76
77
|
| `aximo session export` | Download a session result as a PDF or a screenshot ZIP |
|
|
77
78
|
| `aximo session save-as-case` | Save a finished session as a reusable test case |
|
|
78
79
|
| `aximo case create` | Create a test case |
|
|
@@ -106,6 +107,7 @@ Run `aximo <command> --help` for detailed usage. `aximo schema [command.path]` r
|
|
|
106
107
|
| `aximo device logs` | Show the BYOD agent log |
|
|
107
108
|
| `aximo device unregister` | Remove a BYOD device server-side + clear local creds |
|
|
108
109
|
| `aximo device reset` | Remove BYOD local state (Python, deps, credentials) |
|
|
110
|
+
| `aximo device testbox` | Sandboxed Chromium in Docker as a local device (up/down/...) |
|
|
109
111
|
| `aximo mobile list` | List physically-connected phones (Android adb, iOS devicectl) |
|
|
110
112
|
| `aximo mobile setup` | Install the Appium drivers used to drive phones |
|
|
111
113
|
| `aximo mobile doctor` | Diagnose prerequisites (adb/Xcode/devicectl, signing, driver) |
|
|
@@ -147,6 +149,8 @@ aximo session create --title <t> --prompt <p> --project-id <id> \
|
|
|
147
149
|
|
|
148
150
|
aximo session get <sessionId>
|
|
149
151
|
|
|
152
|
+
aximo session cancel <sessionId> [--dry-run]
|
|
153
|
+
|
|
150
154
|
aximo session export <sessionId> [--format pdf|screenshots] [--output <path>] [--locale en|ja|ko]
|
|
151
155
|
```
|
|
152
156
|
|
|
@@ -360,6 +364,20 @@ aximo device unregister --device-id DEVICE_ID # unregister an orphaned device (
|
|
|
360
364
|
|
|
361
365
|
`device ping` returns what the server knows, including `lastSeenAgoSeconds` and the HTTP round-trip `latencyMs`. It does **not** round-trip through the relay, so a passing ping tells you "the server thinks this device is online," not "the local agent is responding right now."
|
|
362
366
|
|
|
367
|
+
### The testbox: a local device that is not your screen
|
|
368
|
+
|
|
369
|
+
Registering your laptop hands Aximo your mouse and keyboard for the whole run. The testbox is the alternative for apps on `localhost`: one Chromium on a virtual display inside a Docker container, registered as its own local device, with a live view you can watch (and type a password into) from a browser tab. Requires Docker; macOS and Linux (Windows untested).
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
aximo device testbox up --ports 3000 # pull once, register, start, connect; prints the live-view link
|
|
373
|
+
aximo device testbox status # container, agent, device online?, which ports answer
|
|
374
|
+
aximo device testbox url # the live-view link again (password included)
|
|
375
|
+
aximo device testbox down # stop; keeps the browser profile and the registration
|
|
376
|
+
aximo device testbox prune # remove everything, including the device on the server
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Use the printed `userDeviceId` as the local device for `session create`, cases and plans, and put the `http://localhost:<port>` URL in the prompt. `--block-hosts prod.example.com` makes the browser refuse production; it is a browser rule matched by name, not a network boundary, and the box can reach whatever your machine can. `--name qa` runs a second box as a second device. The API key never enters the container: the host CLI registers the box and injects only the device token over stdin. MCP agents drive the same box through `aximo_start_testbox` / `aximo_get_testbox` / `aximo_stop_testbox`.
|
|
380
|
+
|
|
363
381
|
### Re-registering
|
|
364
382
|
|
|
365
383
|
`aximo device register` refuses to overwrite an existing local registration. To move a registration to a different device name:
|
|
@@ -675,7 +693,7 @@ claude mcp add aximo -- aximo mcp
|
|
|
675
693
|
|
|
676
694
|
VS Code (Copilot agent mode) uses the same entry under a `servers` key in `.vscode/mcp.json`.
|
|
677
695
|
|
|
678
|
-
The server exposes
|
|
696
|
+
The server exposes 40 tools: 18 read-only ones for inspecting sessions, cases, plans, plan runs, devices, and uploads (`aximo_get_session_timeline` is the load-bearing one for Playwright export; `aximo_wait_for_session` polls a run; `aximo_list_plans` and `aximo_get_plan` cover plan discovery; `aximo_list_plan_runs` and `aximo_get_plan_run` cover run-status polling; `aximo_list_devices`, `aximo_list_user_devices`, and `aximo_list_uploads` supply the device and upload tokens that case configs and run overrides take), 2 that export a session result to a local file (`aximo_export_session_pdf` for the test result report, `aximo_export_session_screenshots` for a ZIP of the step screenshots), 13 that author content (create, update, archive, restore, and delete cases — including a case's per-target device configuration — create, update, archive, restore, and delete plans, add or remove a plan's cases, save a session as a case), 3 that start runs (`aximo_run_case` starts a case run and returns the `sessionId`; `aximo_create_session` starts a session from a prompt with no saved case; `aximo_run_plan` starts a plan run and returns the `planRunId` — all spend organization credits, and the case and plan runs require `apiEnabled`), 1 that stops one (`aximo_cancel_session` cancels a queued or running session), and 3 that manage the local testbox (`aximo_start_testbox`, `aximo_get_testbox`, `aximo_stop_testbox`: a sandboxed Chromium in Docker, registered as a local device, so an agent can test an app on localhost without taking over your screen; see `aximo device testbox`). See the [MCP reference](./skills/aximo-cli/references/mcp.md) for per-client config paths, the full tool table, the Playwright export prompt, and a no-client smoke test.
|
|
679
697
|
|
|
680
698
|
## Agent Skills
|
|
681
699
|
|
|
@@ -9,6 +9,6 @@ export interface DeviceConfig {
|
|
|
9
9
|
* Read and validate the local device registration (~/.aximo/device.json).
|
|
10
10
|
* Returns null when the file is missing, unreadable, or malformed.
|
|
11
11
|
*/
|
|
12
|
-
export declare function readDeviceConfig(): DeviceConfig | null;
|
|
12
|
+
export declare function readDeviceConfig(path?: string): DeviceConfig | null;
|
|
13
13
|
/** Persist the local device registration with owner-only permissions. */
|
|
14
|
-
export declare function writeDeviceConfig(config: DeviceConfig): void;
|
|
14
|
+
export declare function writeDeviceConfig(config: DeviceConfig, path?: string): void;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
-
import {
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { getDeviceConfigPath } from "./paths.js";
|
|
3
4
|
/**
|
|
4
5
|
* Read and validate the local device registration (~/.aximo/device.json).
|
|
5
6
|
* Returns null when the file is missing, unreadable, or malformed.
|
|
6
7
|
*/
|
|
7
|
-
export function readDeviceConfig() {
|
|
8
|
-
const path = getDeviceConfigPath();
|
|
8
|
+
export function readDeviceConfig(path = getDeviceConfigPath()) {
|
|
9
9
|
if (!existsSync(path))
|
|
10
10
|
return null;
|
|
11
11
|
try {
|
|
@@ -31,11 +31,8 @@ export function readDeviceConfig() {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
/** Persist the local device registration with owner-only permissions. */
|
|
34
|
-
export function writeDeviceConfig(config) {
|
|
35
|
-
|
|
36
|
-
if (!existsSync(dir))
|
|
37
|
-
mkdirSync(dir, { recursive: true });
|
|
38
|
-
const path = getDeviceConfigPath();
|
|
34
|
+
export function writeDeviceConfig(config, path = getDeviceConfigPath()) {
|
|
35
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
39
36
|
writeFileSync(path, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
40
37
|
try {
|
|
41
38
|
chmodSync(path, 0o600);
|
|
@@ -2,7 +2,7 @@ import { defineCommand } from "citty";
|
|
|
2
2
|
export default defineCommand({
|
|
3
3
|
meta: {
|
|
4
4
|
name: "device",
|
|
5
|
-
description: "BYOD device commands (register/connect/status/...); 'device list' lists Device Farm mobile devices",
|
|
5
|
+
description: "BYOD device commands (register/connect/status/...); 'device testbox' runs a sandboxed browser in Docker; 'device list' lists Device Farm mobile devices",
|
|
6
6
|
},
|
|
7
7
|
subCommands: {
|
|
8
8
|
list: () => import("./list.js").then((m) => m.default),
|
|
@@ -15,5 +15,6 @@ export default defineCommand({
|
|
|
15
15
|
logs: () => import("./logs.js").then((m) => m.default),
|
|
16
16
|
reset: () => import("./reset.js").then((m) => m.default),
|
|
17
17
|
ping: () => import("./ping.js").then((m) => m.default),
|
|
18
|
+
testbox: () => import("./testbox/index.js").then((m) => m.default),
|
|
18
19
|
},
|
|
19
20
|
});
|
|
@@ -10,4 +10,8 @@ export declare function getAgentDir(): string;
|
|
|
10
10
|
export declare function getAgentScriptPath(): string;
|
|
11
11
|
export declare function getAgentRequirementsPath(): string;
|
|
12
12
|
export declare function getAgentManifestPath(): string;
|
|
13
|
+
export declare function getTestboxDir(): string;
|
|
14
|
+
export declare function getTestboxConfigPath(name: string): string;
|
|
15
|
+
export declare function getTestboxStatePath(name: string): string;
|
|
16
|
+
export declare function getTestboxLogPath(name: string): string;
|
|
13
17
|
export declare function getEmbeddedPythonBinary(): string;
|
|
@@ -36,6 +36,18 @@ export function getAgentRequirementsPath() {
|
|
|
36
36
|
export function getAgentManifestPath() {
|
|
37
37
|
return join(getAgentDir(), "manifest.json");
|
|
38
38
|
}
|
|
39
|
+
export function getTestboxDir() {
|
|
40
|
+
return join(getAximoDir(), "testbox");
|
|
41
|
+
}
|
|
42
|
+
export function getTestboxConfigPath(name) {
|
|
43
|
+
return join(getTestboxDir(), `${name}.json`);
|
|
44
|
+
}
|
|
45
|
+
export function getTestboxStatePath(name) {
|
|
46
|
+
return join(getTestboxDir(), `${name}.state.json`);
|
|
47
|
+
}
|
|
48
|
+
export function getTestboxLogPath(name) {
|
|
49
|
+
return join(getTestboxDir(), `${name}.log`);
|
|
50
|
+
}
|
|
39
51
|
export function getEmbeddedPythonBinary() {
|
|
40
52
|
return platform() === "win32"
|
|
41
53
|
? join(getPythonDir(), "python.exe")
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { defineCommand } from "citty";
|
|
2
|
-
import { existsSync, rmSync } from "node:fs";
|
|
2
|
+
import { existsSync, readdirSync, rmSync } from "node:fs";
|
|
3
3
|
import { formatError, formatSuccess, printResult } from "../../output.js";
|
|
4
|
-
import { getAximoDir, getCacheDir, getDepsMarkerPath, getDeviceConfigPath, getPythonDir, getPythonMarkerPath, getRemoteLogPath, } from "./paths.js";
|
|
4
|
+
import { getAximoDir, getCacheDir, getDepsMarkerPath, getDeviceConfigPath, getPythonDir, getPythonMarkerPath, getRemoteLogPath, getTestboxDir, } from "./paths.js";
|
|
5
5
|
function removeIfExists(path, removed, opts = {}) {
|
|
6
6
|
if (!existsSync(path))
|
|
7
7
|
return;
|
|
8
8
|
rmSync(path, { recursive: opts.recursive ?? false, force: true });
|
|
9
9
|
removed.push(path);
|
|
10
10
|
}
|
|
11
|
+
function listTestboxes() {
|
|
12
|
+
const dir = getTestboxDir();
|
|
13
|
+
if (!existsSync(dir))
|
|
14
|
+
return [];
|
|
15
|
+
return readdirSync(dir)
|
|
16
|
+
.filter((f) => f.endsWith(".json") && !f.endsWith(".state.json"))
|
|
17
|
+
.map((f) => f.slice(0, -".json".length));
|
|
18
|
+
}
|
|
11
19
|
export function runDeviceReset(options = {}) {
|
|
12
20
|
const { python, deps, device, all } = options;
|
|
13
21
|
if (!python && !deps && !device && !all) {
|
|
@@ -16,8 +24,12 @@ export function runDeviceReset(options = {}) {
|
|
|
16
24
|
const removed = [];
|
|
17
25
|
try {
|
|
18
26
|
if (all) {
|
|
27
|
+
const orphanedTestboxes = listTestboxes();
|
|
19
28
|
removeIfExists(getAximoDir(), removed, { recursive: true });
|
|
20
|
-
return formatSuccess({
|
|
29
|
+
return formatSuccess({
|
|
30
|
+
removed,
|
|
31
|
+
...(orphanedTestboxes.length > 0 ? { orphanedTestboxes } : {}),
|
|
32
|
+
});
|
|
21
33
|
}
|
|
22
34
|
if (python) {
|
|
23
35
|
removeIfExists(getPythonDir(), removed, { recursive: true });
|
|
@@ -60,6 +72,9 @@ export default defineCommand({
|
|
|
60
72
|
all: Boolean(args.all),
|
|
61
73
|
});
|
|
62
74
|
printResult(result);
|
|
75
|
+
if (result.ok && result.data.orphanedTestboxes) {
|
|
76
|
+
console.error(`\nNote: testbox registrations for ${result.data.orphanedTestboxes.join(", ")} were removed locally only; their device rows remain on the server. Delete them in Settings > Devices, or run \`aximo device testbox prune\` before \`reset --all\` next time.`);
|
|
77
|
+
}
|
|
63
78
|
if (result.ok && args.device) {
|
|
64
79
|
console.error("\nNote: this only removed local credentials. The device row on the Aximo server still exists —\nrun `aximo device unregister` first if you want to delete it server-side.");
|
|
65
80
|
}
|
|
@@ -65,5 +65,18 @@ describe("runDeviceReset", () => {
|
|
|
65
65
|
const result = runDeviceReset({ all: true });
|
|
66
66
|
expect(result.ok).toBe(true);
|
|
67
67
|
expect(existsSync(tempHome)).toBe(false);
|
|
68
|
+
if (result.ok)
|
|
69
|
+
expect(result.data.orphanedTestboxes).toBeUndefined();
|
|
70
|
+
});
|
|
71
|
+
it("--all names the testbox registrations it leaves orphaned on the server", () => {
|
|
72
|
+
seedAll();
|
|
73
|
+
mkdirSync(join(tempHome, "testbox"), { recursive: true });
|
|
74
|
+
writeFileSync(join(tempHome, "testbox", "default.json"), "{}");
|
|
75
|
+
writeFileSync(join(tempHome, "testbox", "qa.json"), "{}");
|
|
76
|
+
writeFileSync(join(tempHome, "testbox", "qa.state.json"), "{}");
|
|
77
|
+
const result = runDeviceReset({ all: true });
|
|
78
|
+
expect(result.ok).toBe(true);
|
|
79
|
+
if (result.ok)
|
|
80
|
+
expect(result.data.orphanedTestboxes).toEqual(["default", "qa"]);
|
|
68
81
|
});
|
|
69
82
|
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { type ClientDeps } from "../../../client.js";
|
|
2
|
+
import { type WaitClock } from "../../mcp/wait.js";
|
|
3
|
+
import { type TestboxConfig } from "./container.js";
|
|
4
|
+
import { type DockerRunner } from "./docker.js";
|
|
5
|
+
export interface TestboxDeps extends ClientDeps {
|
|
6
|
+
docker?: DockerRunner;
|
|
7
|
+
clock?: WaitClock;
|
|
8
|
+
fetchAgent?: (deps: ClientDeps) => Promise<{
|
|
9
|
+
scriptPath: string;
|
|
10
|
+
requirementsPath: string;
|
|
11
|
+
}>;
|
|
12
|
+
hostName?: () => string;
|
|
13
|
+
}
|
|
14
|
+
export interface UpOptions {
|
|
15
|
+
name?: string;
|
|
16
|
+
ports?: string;
|
|
17
|
+
blockHosts?: string[];
|
|
18
|
+
startUrl?: string;
|
|
19
|
+
novncPort?: number;
|
|
20
|
+
screen?: string;
|
|
21
|
+
image?: string;
|
|
22
|
+
wait?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export type TestboxState = "down" | "pulling" | "starting" | "connecting" | "online" | "error";
|
|
25
|
+
export interface TestboxStatus {
|
|
26
|
+
name: string;
|
|
27
|
+
state: TestboxState;
|
|
28
|
+
container: "running" | "stopped" | "absent";
|
|
29
|
+
config?: TestboxConfig;
|
|
30
|
+
device?: {
|
|
31
|
+
userDeviceId: string;
|
|
32
|
+
name: string;
|
|
33
|
+
status: string;
|
|
34
|
+
};
|
|
35
|
+
agent?: "running" | "stopped";
|
|
36
|
+
agentStatus?: string;
|
|
37
|
+
ports?: {
|
|
38
|
+
port: number;
|
|
39
|
+
reachable: boolean;
|
|
40
|
+
}[];
|
|
41
|
+
liveViewUrl?: string;
|
|
42
|
+
lastError?: string;
|
|
43
|
+
}
|
|
44
|
+
interface StateFile {
|
|
45
|
+
phase: "pulling" | "starting" | "connecting" | "error";
|
|
46
|
+
startedAt: string;
|
|
47
|
+
pid: number;
|
|
48
|
+
lastError?: string;
|
|
49
|
+
}
|
|
50
|
+
export declare function readState(name: string): StateFile | null;
|
|
51
|
+
export declare function clearState(name: string): void;
|
|
52
|
+
/** The detached `up` still working on this box, if any. */
|
|
53
|
+
export declare function pendingUp(name: string, clock?: WaitClock): StateFile | null;
|
|
54
|
+
export interface UpResult {
|
|
55
|
+
name: string;
|
|
56
|
+
container: string;
|
|
57
|
+
userDeviceId: string;
|
|
58
|
+
deviceName: string;
|
|
59
|
+
state: TestboxState;
|
|
60
|
+
config: TestboxConfig;
|
|
61
|
+
liveViewUrl?: string;
|
|
62
|
+
notes: string[];
|
|
63
|
+
}
|
|
64
|
+
export declare function upTestbox(options: UpOptions, deps?: TestboxDeps): Promise<UpResult>;
|
|
65
|
+
export declare function statusTestbox(nameInput: string | undefined, deps?: TestboxDeps): Promise<TestboxStatus>;
|
|
66
|
+
/** Status now, or once the box is online or has stopped trying, whichever comes first. */
|
|
67
|
+
export declare function waitForTestbox(name: string | undefined, timeoutSeconds: number, deps?: TestboxDeps): Promise<TestboxStatus>;
|
|
68
|
+
export declare function downTestbox(nameInput: string | undefined, deps?: TestboxDeps): Promise<{
|
|
69
|
+
name: string;
|
|
70
|
+
removed: boolean;
|
|
71
|
+
}>;
|
|
72
|
+
export declare function resetTestbox(nameInput: string | undefined, deps?: TestboxDeps): Promise<{
|
|
73
|
+
profileDropped: boolean;
|
|
74
|
+
name: string;
|
|
75
|
+
removed: boolean;
|
|
76
|
+
}>;
|
|
77
|
+
export declare function pruneTestbox(nameInput: string | undefined, options?: {
|
|
78
|
+
keepImage?: boolean;
|
|
79
|
+
}, deps?: TestboxDeps): Promise<{
|
|
80
|
+
name: string;
|
|
81
|
+
removed: boolean;
|
|
82
|
+
deviceId: string | undefined;
|
|
83
|
+
serverDeleted: boolean;
|
|
84
|
+
}>;
|
|
85
|
+
export declare function agentLog(nameInput: string | undefined, lines: number, deps?: TestboxDeps): Promise<{
|
|
86
|
+
name: string;
|
|
87
|
+
lines: string[];
|
|
88
|
+
}>;
|
|
89
|
+
export declare function agentLogFollowArgs(name: string | undefined, lines: number): string[];
|
|
90
|
+
export {};
|