@devicecloud.dev/dcd 4.4.9 → 5.0.0-beta.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 +75 -2
- package/dist/commands/artifacts.d.ts +47 -18
- package/dist/commands/artifacts.js +69 -64
- package/dist/commands/cloud.d.ts +228 -88
- package/dist/commands/cloud.js +430 -342
- package/dist/commands/list.d.ts +39 -38
- package/dist/commands/list.js +124 -131
- package/dist/commands/live.d.ts +2 -0
- package/dist/commands/live.js +520 -0
- package/dist/commands/login.d.ts +17 -0
- package/dist/commands/login.js +252 -0
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.js +30 -0
- package/dist/commands/status.d.ts +23 -42
- package/dist/commands/status.js +170 -179
- package/dist/commands/switch-org.d.ts +12 -0
- package/dist/commands/switch-org.js +76 -0
- package/dist/commands/upgrade.d.ts +2 -0
- package/dist/commands/upgrade.js +120 -0
- package/dist/commands/upload.d.ts +33 -18
- package/dist/commands/upload.js +72 -78
- package/dist/commands/whoami.d.ts +2 -0
- package/dist/commands/whoami.js +31 -0
- package/dist/config/environments.d.ts +31 -0
- package/dist/config/environments.js +52 -0
- package/dist/config/flags/api.flags.d.ts +10 -2
- package/dist/config/flags/api.flags.js +13 -14
- package/dist/config/flags/binary.flags.d.ts +17 -4
- package/dist/config/flags/binary.flags.js +14 -18
- package/dist/config/flags/device.flags.d.ts +49 -11
- package/dist/config/flags/device.flags.js +43 -38
- package/dist/config/flags/environment.flags.d.ts +27 -6
- package/dist/config/flags/environment.flags.js +24 -29
- package/dist/config/flags/execution.flags.d.ts +35 -8
- package/dist/config/flags/execution.flags.js +31 -41
- package/dist/config/flags/github.flags.d.ts +23 -5
- package/dist/config/flags/github.flags.js +19 -15
- package/dist/config/flags/output.flags.d.ts +57 -13
- package/dist/config/flags/output.flags.js +48 -47
- package/dist/constants.d.ts +218 -51
- package/dist/constants.js +17 -20
- package/dist/gateways/api-gateway.d.ts +72 -16
- package/dist/gateways/api-gateway.js +298 -104
- package/dist/gateways/cli-auth-gateway.d.ts +13 -0
- package/dist/gateways/cli-auth-gateway.js +54 -0
- package/dist/gateways/realtime-gateway.d.ts +32 -0
- package/dist/gateways/realtime-gateway.js +103 -0
- package/dist/gateways/supabase-gateway.d.ts +11 -11
- package/dist/gateways/supabase-gateway.js +20 -48
- package/dist/index.d.ts +2 -1
- package/dist/index.js +98 -4
- package/dist/mcp/context.d.ts +33 -0
- package/dist/mcp/context.js +33 -0
- package/dist/mcp/helpers.d.ts +16 -0
- package/dist/mcp/helpers.js +34 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +24 -0
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.js +27 -0
- package/dist/mcp/tools/download-artifacts.d.ts +11 -0
- package/dist/mcp/tools/download-artifacts.js +84 -0
- package/dist/mcp/tools/get-status.d.ts +7 -0
- package/dist/mcp/tools/get-status.js +39 -0
- package/dist/mcp/tools/list-devices.d.ts +7 -0
- package/dist/mcp/tools/list-devices.js +27 -0
- package/dist/mcp/tools/list-runs.d.ts +3 -0
- package/dist/mcp/tools/list-runs.js +60 -0
- package/dist/mcp/tools/run-cloud-test.d.ts +14 -0
- package/dist/mcp/tools/run-cloud-test.js +233 -0
- package/dist/methods.d.ts +34 -5
- package/dist/methods.js +266 -215
- package/dist/services/device-validation.service.d.ts +9 -1
- package/dist/services/device-validation.service.js +56 -40
- package/dist/services/execution-plan.service.js +40 -31
- package/dist/services/execution-plan.utils.d.ts +3 -0
- package/dist/services/execution-plan.utils.js +25 -55
- package/dist/services/flow-paths.d.ts +17 -0
- package/dist/services/flow-paths.js +52 -0
- package/dist/services/metadata-extractor.service.d.ts +0 -2
- package/dist/services/metadata-extractor.service.js +75 -78
- package/dist/services/moropo.service.js +33 -34
- package/dist/services/report-download.service.d.ts +12 -1
- package/dist/services/report-download.service.js +34 -27
- package/dist/services/results-polling.service.d.ts +23 -9
- package/dist/services/results-polling.service.js +257 -123
- package/dist/services/telemetry.service.d.ts +49 -0
- package/dist/services/telemetry.service.js +252 -0
- package/dist/services/test-submission.service.d.ts +21 -4
- package/dist/services/test-submission.service.js +51 -33
- package/dist/services/version.service.d.ts +4 -3
- package/dist/services/version.service.js +28 -16
- package/dist/types/domain/auth.types.d.ts +20 -0
- package/dist/types/domain/auth.types.js +1 -0
- package/dist/types/domain/device.types.js +8 -11
- package/dist/types/domain/live.types.d.ts +76 -0
- package/dist/types/domain/live.types.js +3 -0
- package/dist/types/generated/schema.types.js +1 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +2 -18
- package/dist/types.js +1 -2
- package/dist/utils/auth.d.ts +13 -0
- package/dist/utils/auth.js +141 -0
- package/dist/utils/ci.d.ts +12 -0
- package/dist/utils/ci.js +39 -0
- package/dist/utils/cli.d.ts +35 -0
- package/dist/utils/cli.js +118 -0
- package/dist/utils/compatibility.d.ts +2 -1
- package/dist/utils/compatibility.js +6 -8
- package/dist/utils/config-store.d.ts +35 -0
- package/dist/utils/config-store.js +115 -0
- package/dist/utils/connectivity.js +8 -7
- package/dist/utils/expo.js +29 -24
- package/dist/utils/orgs.d.ts +11 -0
- package/dist/utils/orgs.js +36 -0
- package/dist/utils/paths.d.ts +11 -0
- package/dist/utils/paths.js +21 -0
- package/dist/utils/progress.d.ts +13 -0
- package/dist/utils/progress.js +47 -0
- package/dist/utils/styling.d.ts +42 -36
- package/dist/utils/styling.js +78 -82
- package/dist/utils/ui.d.ts +41 -0
- package/dist/utils/ui.js +95 -0
- package/package.json +36 -45
- package/bin/dev.cmd +0 -3
- package/bin/dev.js +0 -6
- package/bin/run.cmd +0 -3
- package/bin/run.js +0 -7
- package/dist/types/schema.types.d.ts +0 -2702
- package/dist/types/schema.types.js +0 -3
- package/oclif.manifest.json +0 -884
package/dist/utils/styling.js
CHANGED
|
@@ -1,24 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.dividers = exports.colors = exports.symbols = void 0;
|
|
4
|
-
exports.formatStatus = formatStatus;
|
|
5
|
-
exports.sectionHeader = sectionHeader;
|
|
6
|
-
exports.keyValue = keyValue;
|
|
7
|
-
exports.listItem = listItem;
|
|
8
|
-
exports.formatUrl = formatUrl;
|
|
9
|
-
exports.formatId = formatId;
|
|
10
|
-
exports.formatTestSummary = formatTestSummary;
|
|
11
|
-
exports.box = box;
|
|
12
|
-
exports.getConsoleUrl = getConsoleUrl;
|
|
13
|
-
const chalk = require("chalk");
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { findEnvByApiUrl } from '../config/environments.js';
|
|
14
3
|
/**
|
|
15
4
|
* Centralized styling utilities for CLI output
|
|
16
5
|
* Provides consistent, developer-friendly visual formatting
|
|
17
6
|
*/
|
|
7
|
+
/** Strip ANSI color escape sequences for visible-width calculations. */
|
|
8
|
+
// eslint-disable-next-line no-control-regex -- matches ANSI escape sequences
|
|
9
|
+
export const stripAnsi = (s) => s.replace(/\u001B\[[0-9;]*m/g, '');
|
|
18
10
|
/**
|
|
19
11
|
* Status symbols with associated colors
|
|
20
12
|
*/
|
|
21
|
-
|
|
13
|
+
export const symbols = {
|
|
22
14
|
cancelled: chalk.gray('⊘'),
|
|
23
15
|
error: chalk.red('✗'),
|
|
24
16
|
info: chalk.blue('ℹ'),
|
|
@@ -32,7 +24,7 @@ exports.symbols = {
|
|
|
32
24
|
/**
|
|
33
25
|
* Color utility functions for semantic styling
|
|
34
26
|
*/
|
|
35
|
-
|
|
27
|
+
export const colors = {
|
|
36
28
|
bold: chalk.bold,
|
|
37
29
|
dim: chalk.gray,
|
|
38
30
|
error: chalk.red,
|
|
@@ -43,129 +35,133 @@ exports.colors = {
|
|
|
43
35
|
warning: chalk.yellow,
|
|
44
36
|
};
|
|
45
37
|
/**
|
|
46
|
-
*
|
|
38
|
+
* Structural glyphs that give the CLI its tree-shaped layout. `section` marks a
|
|
39
|
+
* top-level heading; `branch` opens the group of detail rows beneath it.
|
|
40
|
+
* See STYLE_GUIDE.md.
|
|
47
41
|
*/
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
short: chalk.gray('─'.repeat(40)),
|
|
42
|
+
export const glyphs = {
|
|
43
|
+
branch: '⎿',
|
|
44
|
+
section: '⏺',
|
|
52
45
|
};
|
|
53
46
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
47
|
+
* The single source of truth mapping a run/test status to its colour and
|
|
48
|
+
* (already-coloured) symbol. Both {@link formatStatus} and the `ui` status
|
|
49
|
+
* helpers build on this, so every status reads identically everywhere.
|
|
50
|
+
* @param status - The status string (case-insensitive)
|
|
57
51
|
*/
|
|
58
|
-
function
|
|
59
|
-
|
|
60
|
-
switch (statusUpper) {
|
|
52
|
+
export function statusPalette(status) {
|
|
53
|
+
switch (status.toUpperCase()) {
|
|
61
54
|
case 'PASSED': {
|
|
62
|
-
return
|
|
55
|
+
return { color: colors.success, symbol: symbols.success };
|
|
63
56
|
}
|
|
57
|
+
case 'ERROR':
|
|
64
58
|
case 'FAILED': {
|
|
65
|
-
return
|
|
59
|
+
return { color: colors.error, symbol: symbols.error };
|
|
66
60
|
}
|
|
67
61
|
case 'RUNNING': {
|
|
68
|
-
return
|
|
62
|
+
return { color: colors.info, symbol: symbols.running };
|
|
69
63
|
}
|
|
70
64
|
case 'PENDING': {
|
|
71
|
-
return
|
|
65
|
+
return { color: colors.warning, symbol: symbols.pending };
|
|
72
66
|
}
|
|
73
67
|
case 'QUEUED': {
|
|
74
|
-
return
|
|
68
|
+
return { color: colors.dim, symbol: symbols.queued };
|
|
75
69
|
}
|
|
76
70
|
case 'CANCELLED': {
|
|
77
|
-
return
|
|
71
|
+
return { color: colors.dim, symbol: symbols.cancelled };
|
|
78
72
|
}
|
|
79
73
|
default: {
|
|
80
|
-
return
|
|
74
|
+
return { color: colors.dim, symbol: symbols.unknown };
|
|
81
75
|
}
|
|
82
76
|
}
|
|
83
77
|
}
|
|
84
78
|
/**
|
|
85
|
-
* Format a
|
|
86
|
-
*
|
|
87
|
-
* @
|
|
88
|
-
|
|
89
|
-
function sectionHeader(title) {
|
|
90
|
-
return `\n${exports.colors.bold(title)}\n${exports.dividers.light}`;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Format a key-value pair with optional icon
|
|
94
|
-
* @param icon - Icon to display before the key
|
|
95
|
-
* @param key - The key name
|
|
96
|
-
* @param value - The value to display
|
|
97
|
-
* @returns Formatted key-value string
|
|
79
|
+
* Format a status as a coloured symbol followed by the lowercased status word,
|
|
80
|
+
* e.g. `✓ passed`.
|
|
81
|
+
* @param status - The status string to format
|
|
82
|
+
* @returns Formatted status string with color and symbol
|
|
98
83
|
*/
|
|
99
|
-
function
|
|
100
|
-
|
|
84
|
+
export function formatStatus(status) {
|
|
85
|
+
const { color, symbol } = statusPalette(status);
|
|
86
|
+
return `${symbol} ${color(status.toLowerCase())}`;
|
|
101
87
|
}
|
|
102
88
|
/**
|
|
103
|
-
* Format a
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* @
|
|
89
|
+
* Format a top-level section header in the tree style: a `⏺` marker followed by
|
|
90
|
+
* the bold title, preceded by a blank line for separation. Detail rows belong
|
|
91
|
+
* underneath in a branch group (see the `ui` helpers).
|
|
92
|
+
* @param title - The title of the section
|
|
93
|
+
* @returns Formatted section header
|
|
107
94
|
*/
|
|
108
|
-
function
|
|
109
|
-
return
|
|
95
|
+
export function sectionHeader(title) {
|
|
96
|
+
return `\n${colors.dim(glyphs.section)} ${colors.bold(title)}`;
|
|
110
97
|
}
|
|
111
98
|
/**
|
|
112
99
|
* Format a URL
|
|
113
100
|
* @param url - The URL to format
|
|
114
101
|
* @returns Formatted URL with styling
|
|
115
102
|
*/
|
|
116
|
-
function formatUrl(url) {
|
|
117
|
-
return
|
|
103
|
+
export function formatUrl(url) {
|
|
104
|
+
return colors.url(url);
|
|
118
105
|
}
|
|
119
106
|
/**
|
|
120
107
|
* Format an ID or identifier
|
|
121
108
|
* @param id - The ID to format
|
|
122
109
|
* @returns Formatted ID with highlighting
|
|
123
110
|
*/
|
|
124
|
-
function formatId(id) {
|
|
125
|
-
return
|
|
111
|
+
export function formatId(id) {
|
|
112
|
+
return colors.highlight(id);
|
|
126
113
|
}
|
|
127
114
|
/**
|
|
128
115
|
* Format a test summary line
|
|
129
116
|
* @param summary - Object containing test counts
|
|
130
117
|
* @returns Formatted summary string
|
|
131
118
|
*/
|
|
132
|
-
function formatTestSummary(summary) {
|
|
119
|
+
export function formatTestSummary(summary) {
|
|
133
120
|
const parts = [
|
|
134
121
|
chalk.bold(`${summary.completed}/${summary.total}`),
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
122
|
+
colors.success(`✓ ${summary.passed}`),
|
|
123
|
+
colors.error(`✗ ${summary.failed}`),
|
|
124
|
+
colors.info(`▶ ${summary.running}`),
|
|
125
|
+
colors.warning(`⏸ ${summary.pending}`),
|
|
126
|
+
colors.dim(`⏳ ${summary.queued}`),
|
|
140
127
|
];
|
|
141
128
|
return parts.join(' │ ');
|
|
142
129
|
}
|
|
143
130
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
131
|
+
* Minimal column table renderer.
|
|
132
|
+
* Columns are defined with a `get(row) => string` accessor and optional header label.
|
|
133
|
+
* Matches the subset of oclif's ux.table used by this CLI.
|
|
147
134
|
*/
|
|
148
|
-
function
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
135
|
+
export function table(rows, columns, options = {}) {
|
|
136
|
+
const printLine = options.printLine ?? ((line) => {
|
|
137
|
+
// eslint-disable-next-line no-console
|
|
138
|
+
console.log(line);
|
|
139
|
+
});
|
|
140
|
+
const keys = Object.keys(columns);
|
|
141
|
+
const headers = keys.map((k) => columns[k].header ?? k);
|
|
142
|
+
const cells = rows.map((row) => keys.map((k) => String(columns[k].get(row) ?? '')));
|
|
143
|
+
const widths = keys.map((_, i) => Math.max(stripAnsi(headers[i]).length, ...cells.map((r) => stripAnsi(r[i]).length)));
|
|
144
|
+
const pad = (s, width) => {
|
|
145
|
+
const visibleLen = stripAnsi(s).length;
|
|
146
|
+
return s + ' '.repeat(Math.max(0, width - visibleLen));
|
|
147
|
+
};
|
|
148
|
+
printLine(headers.map((h, i) => pad(chalk.bold(h), widths[i])).join(' '));
|
|
149
|
+
printLine(widths.map((w) => chalk.gray('─'.repeat(w))).join(' '));
|
|
150
|
+
for (const row of cells) {
|
|
151
|
+
printLine(row.map((c, i) => pad(c, widths[i])).join(' '));
|
|
152
|
+
}
|
|
157
153
|
}
|
|
158
154
|
/**
|
|
159
155
|
* Generate console URL based on API URL
|
|
160
|
-
*
|
|
156
|
+
* Derives the console host from the known environment matching the API URL;
|
|
157
|
+
* unknown API URLs fall back to the dev console (historical behavior).
|
|
161
158
|
* @param apiUrl - The API URL being used
|
|
162
159
|
* @param uploadId - The upload ID
|
|
163
160
|
* @param resultId - The result ID
|
|
164
161
|
* @returns The appropriate console URL
|
|
165
162
|
*/
|
|
166
|
-
function getConsoleUrl(apiUrl, uploadId, resultId) {
|
|
167
|
-
const
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
return `https://${consoleSubdomain}.devicecloud.dev/results?upload=${uploadId}&result=${resultId}`;
|
|
163
|
+
export function getConsoleUrl(apiUrl, uploadId, resultId) {
|
|
164
|
+
const env = findEnvByApiUrl(apiUrl);
|
|
165
|
+
const base = env?.frontendUrl ?? 'https://dev.console.devicecloud.dev';
|
|
166
|
+
return `${base}/results?upload=${uploadId}&result=${resultId}`;
|
|
171
167
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** A `[label, value]` detail row; the value is passed through already styled. */
|
|
2
|
+
export type Field = [label: string, value: string];
|
|
3
|
+
export declare const ui: {
|
|
4
|
+
/**
|
|
5
|
+
* Render detail rows as a branch group beneath the most recent section:
|
|
6
|
+
*
|
|
7
|
+
* ⎿ row one
|
|
8
|
+
* row two
|
|
9
|
+
*
|
|
10
|
+
* Embedded newlines in a row are kept aligned. Returns `''` for no rows.
|
|
11
|
+
*/
|
|
12
|
+
readonly branch: (rows: string[]) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Align `[label, value]` pairs into `label value` rows for use inside a
|
|
15
|
+
* {@link branch} group. Plain labels are dimmed; labels the caller already
|
|
16
|
+
* styled (e.g. `colors.bold(name)`) are left as-is. Padding is measured on
|
|
17
|
+
* visible width so ANSI colours never throw the columns off.
|
|
18
|
+
*/
|
|
19
|
+
readonly fields: (pairs: Field[]) => string[];
|
|
20
|
+
/** `ℹ message` — neutral, standalone information. */
|
|
21
|
+
readonly info: (message: string) => string;
|
|
22
|
+
/** Dimmed secondary text — hints, tips, "you can close this terminal", etc. */
|
|
23
|
+
readonly note: (message: string) => string;
|
|
24
|
+
/** `▶ message` — an action currently in progress. */
|
|
25
|
+
readonly running: (message: string) => string;
|
|
26
|
+
/**
|
|
27
|
+
* A top-level section header — `⏺ Title`, preceded by a blank line. Detail
|
|
28
|
+
* rows belong underneath via {@link branch}.
|
|
29
|
+
*/
|
|
30
|
+
readonly section: (title: string) => string;
|
|
31
|
+
/** A coloured status word + symbol, e.g. `✓ passed`. Delegates to the shared palette. */
|
|
32
|
+
readonly status: (status: string) => string;
|
|
33
|
+
/** The coloured status symbol alone, e.g. green `✓`. */
|
|
34
|
+
readonly statusSymbol: (status: string) => string;
|
|
35
|
+
/** The lowercased status word in its status colour, e.g. green `passed`. */
|
|
36
|
+
readonly statusWord: (status: string) => string;
|
|
37
|
+
/** `✓ message` — a completed action; the message is emphasised. */
|
|
38
|
+
readonly success: (message: string) => string;
|
|
39
|
+
/** `⚠ message` — a non-fatal warning. */
|
|
40
|
+
readonly warn: (message: string) => string;
|
|
41
|
+
};
|
package/dist/utils/ui.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified rendering layer for all CLI command output.
|
|
3
|
+
*
|
|
4
|
+
* Every command composes its output from these helpers so the look stays
|
|
5
|
+
* consistent — a tree of `⏺` section headings with `⎿` branch groups of detail
|
|
6
|
+
* rows beneath them, inspired by Claude Code. See STYLE_GUIDE.md for the rules
|
|
7
|
+
* and worked examples.
|
|
8
|
+
*
|
|
9
|
+
* Functions RETURN strings (never write to stdout themselves) so callers route
|
|
10
|
+
* them through their own logger / `--json` gate and they stay unit-testable.
|
|
11
|
+
*/
|
|
12
|
+
import { colors, formatStatus, glyphs, sectionHeader, statusPalette, stripAnsi, symbols, } from './styling.js';
|
|
13
|
+
/**
|
|
14
|
+
* Indentation under a section. The branch glyph sits two columns in and its
|
|
15
|
+
* content begins at column four; continuation rows align to the same column.
|
|
16
|
+
*
|
|
17
|
+
* ⏺ Title
|
|
18
|
+
* ⎿ first detail row
|
|
19
|
+
* continuation row
|
|
20
|
+
*/
|
|
21
|
+
const BRANCH_PREFIX = ` ${colors.dim(glyphs.branch)} `;
|
|
22
|
+
const CONTINUATION_PREFIX = ' ';
|
|
23
|
+
export const ui = {
|
|
24
|
+
/**
|
|
25
|
+
* Render detail rows as a branch group beneath the most recent section:
|
|
26
|
+
*
|
|
27
|
+
* ⎿ row one
|
|
28
|
+
* row two
|
|
29
|
+
*
|
|
30
|
+
* Embedded newlines in a row are kept aligned. Returns `''` for no rows.
|
|
31
|
+
*/
|
|
32
|
+
branch(rows) {
|
|
33
|
+
const lines = rows.flatMap((row) => row.split('\n'));
|
|
34
|
+
if (lines.length === 0) {
|
|
35
|
+
return '';
|
|
36
|
+
}
|
|
37
|
+
return lines
|
|
38
|
+
.map((line, index) => index === 0 ? `${BRANCH_PREFIX}${line}` : `${CONTINUATION_PREFIX}${line}`)
|
|
39
|
+
.join('\n');
|
|
40
|
+
},
|
|
41
|
+
/**
|
|
42
|
+
* Align `[label, value]` pairs into `label value` rows for use inside a
|
|
43
|
+
* {@link branch} group. Plain labels are dimmed; labels the caller already
|
|
44
|
+
* styled (e.g. `colors.bold(name)`) are left as-is. Padding is measured on
|
|
45
|
+
* visible width so ANSI colours never throw the columns off.
|
|
46
|
+
*/
|
|
47
|
+
fields(pairs) {
|
|
48
|
+
const width = Math.max(0, ...pairs.map(([label]) => stripAnsi(label).length));
|
|
49
|
+
return pairs.map(([label, value]) => {
|
|
50
|
+
const styled = stripAnsi(label) === label ? colors.dim(label) : label;
|
|
51
|
+
const padding = ' '.repeat(Math.max(0, width - stripAnsi(label).length));
|
|
52
|
+
return `${styled}${padding} ${value}`;
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
/** `ℹ message` — neutral, standalone information. */
|
|
56
|
+
info(message) {
|
|
57
|
+
return `${symbols.info} ${message}`;
|
|
58
|
+
},
|
|
59
|
+
/** Dimmed secondary text — hints, tips, "you can close this terminal", etc. */
|
|
60
|
+
note(message) {
|
|
61
|
+
return colors.dim(message);
|
|
62
|
+
},
|
|
63
|
+
/** `▶ message` — an action currently in progress. */
|
|
64
|
+
running(message) {
|
|
65
|
+
return `${symbols.running} ${message}`;
|
|
66
|
+
},
|
|
67
|
+
/**
|
|
68
|
+
* A top-level section header — `⏺ Title`, preceded by a blank line. Detail
|
|
69
|
+
* rows belong underneath via {@link branch}.
|
|
70
|
+
*/
|
|
71
|
+
section(title) {
|
|
72
|
+
return sectionHeader(title);
|
|
73
|
+
},
|
|
74
|
+
/** A coloured status word + symbol, e.g. `✓ passed`. Delegates to the shared palette. */
|
|
75
|
+
status(status) {
|
|
76
|
+
return formatStatus(status);
|
|
77
|
+
},
|
|
78
|
+
/** The coloured status symbol alone, e.g. green `✓`. */
|
|
79
|
+
statusSymbol(status) {
|
|
80
|
+
return statusPalette(status).symbol;
|
|
81
|
+
},
|
|
82
|
+
/** The lowercased status word in its status colour, e.g. green `passed`. */
|
|
83
|
+
statusWord(status) {
|
|
84
|
+
const { color } = statusPalette(status);
|
|
85
|
+
return color(status.toLowerCase());
|
|
86
|
+
},
|
|
87
|
+
/** `✓ message` — a completed action; the message is emphasised. */
|
|
88
|
+
success(message) {
|
|
89
|
+
return `${symbols.success} ${colors.bold(message)}`;
|
|
90
|
+
},
|
|
91
|
+
/** `⚠ message` — a non-fatal warning. */
|
|
92
|
+
warn(message) {
|
|
93
|
+
return `${symbols.warning} ${message}`;
|
|
94
|
+
},
|
|
95
|
+
};
|
package/package.json
CHANGED
|
@@ -1,67 +1,58 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "devicecloud.dev",
|
|
3
3
|
"bin": {
|
|
4
|
-
"dcd": "
|
|
4
|
+
"dcd": "dist/index.js",
|
|
5
|
+
"dcd-mcp": "dist/mcp/index.js"
|
|
5
6
|
},
|
|
6
7
|
"dependencies": {
|
|
7
|
-
"@
|
|
8
|
-
"@
|
|
9
|
-
"@supabase/supabase-js": "^2.
|
|
10
|
-
"app-info-parser": "^1.1.6",
|
|
11
|
-
"archiver": "^7.0.1",
|
|
8
|
+
"@clack/prompts": "^1.6.0",
|
|
9
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
10
|
+
"@supabase/supabase-js": "^2.108.2",
|
|
12
11
|
"bplist-parser": "^0.3.2",
|
|
13
|
-
"chalk": "
|
|
14
|
-
"
|
|
15
|
-
"js-yaml": "^
|
|
12
|
+
"chalk": "^5.6.2",
|
|
13
|
+
"citty": "^0.2.2",
|
|
14
|
+
"js-yaml": "^5.0.0",
|
|
15
|
+
"node-apk": "^1.2.1",
|
|
16
16
|
"node-stream-zip": "^1.15.0",
|
|
17
|
-
"plist": "^
|
|
18
|
-
"tar": "^7.5.
|
|
19
|
-
"tus-js-client": "^4.3.1"
|
|
17
|
+
"plist": "^5.0.0",
|
|
18
|
+
"tar": "^7.5.16",
|
|
19
|
+
"tus-js-client": "^4.3.1",
|
|
20
|
+
"yazl": "^3.3.1",
|
|
21
|
+
"zod": "^4.4.3"
|
|
20
22
|
},
|
|
21
|
-
"description": "
|
|
23
|
+
"description": "Run Maestro mobile UI tests in the cloud — upload an iOS/Android build, execute flows across real devices, and stream results. Ships the dcd CLI and a dcd-mcp MCP server.",
|
|
22
24
|
"devDependencies": {
|
|
23
|
-
"@
|
|
24
|
-
"@oclif/test": "^4.1.16",
|
|
25
|
-
"@types/archiver": "^7.0.0",
|
|
25
|
+
"@eslint/js": "^10.0.1",
|
|
26
26
|
"@types/chai": "^5.2.3",
|
|
27
|
-
"@types/glob-to-regexp": "^0.4.4",
|
|
28
27
|
"@types/js-yaml": "^4.0.9",
|
|
29
28
|
"@types/mocha": "^10.0.10",
|
|
30
|
-
"@types/node": "^
|
|
31
|
-
"@types/
|
|
32
|
-
"@types/tar": "^7.0.87",
|
|
29
|
+
"@types/node": "^26.0.0",
|
|
30
|
+
"@types/yazl": "^3.3.1",
|
|
33
31
|
"chai": "^6.2.2",
|
|
34
|
-
"eslint": "^
|
|
35
|
-
"eslint-config-oclif": "^5.2.2",
|
|
36
|
-
"eslint-config-oclif-typescript": "^3.1.14",
|
|
32
|
+
"eslint": "^10.5.0",
|
|
37
33
|
"eslint-config-prettier": "^10.1.8",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
34
|
+
"eslint-plugin-import": "^2.32.0",
|
|
35
|
+
"eslint-plugin-unicorn": "^68.0.0",
|
|
36
|
+
"husky": "^9.1.7",
|
|
37
|
+
"mocha": "^11.7.6",
|
|
38
|
+
"prettier": "^3.8.4",
|
|
40
39
|
"shx": "^0.4.0",
|
|
41
|
-
"
|
|
42
|
-
"typescript": "^
|
|
40
|
+
"tsx": "^4.22.4",
|
|
41
|
+
"typescript": "^6.0.3",
|
|
42
|
+
"typescript-eslint": "^8.61.1"
|
|
43
43
|
},
|
|
44
44
|
"engines": {
|
|
45
45
|
"node": ">=22.0.0"
|
|
46
46
|
},
|
|
47
47
|
"files": [
|
|
48
|
-
"/
|
|
49
|
-
"/dist",
|
|
50
|
-
"/oclif.manifest.json"
|
|
48
|
+
"/dist"
|
|
51
49
|
],
|
|
52
50
|
"homepage": "https://devicecloud.dev",
|
|
53
51
|
"license": "MIT",
|
|
54
52
|
"main": "dist/index.js",
|
|
55
53
|
"name": "@devicecloud.dev/dcd",
|
|
56
|
-
"oclif": {
|
|
57
|
-
"bin": "dcd",
|
|
58
|
-
"dirname": "dcd",
|
|
59
|
-
"commands": "./dist/commands",
|
|
60
|
-
"plugins": [
|
|
61
|
-
"@oclif/plugin-help"
|
|
62
|
-
]
|
|
63
|
-
},
|
|
64
54
|
"private": false,
|
|
55
|
+
"type": "module",
|
|
65
56
|
"publishConfig": {
|
|
66
57
|
"access": "public"
|
|
67
58
|
},
|
|
@@ -69,7 +60,7 @@
|
|
|
69
60
|
"type": "git",
|
|
70
61
|
"url": "https://devicecloud.dev"
|
|
71
62
|
},
|
|
72
|
-
"version": "
|
|
63
|
+
"version": "5.0.0-beta.1",
|
|
73
64
|
"bugs": {
|
|
74
65
|
"url": "https://discord.gg/gm3mJwcNw8"
|
|
75
66
|
},
|
|
@@ -83,11 +74,11 @@
|
|
|
83
74
|
],
|
|
84
75
|
"types": "dist/index.d.ts",
|
|
85
76
|
"scripts": {
|
|
86
|
-
"dcd": "
|
|
87
|
-
"
|
|
88
|
-
"build": "
|
|
89
|
-
"lint": "eslint
|
|
90
|
-
"
|
|
91
|
-
"
|
|
77
|
+
"dcd": "tsx src/index.ts",
|
|
78
|
+
"build": "shx rm -rf dist && tsc -b && shx chmod +x dist/index.js dist/mcp/index.js",
|
|
79
|
+
"build:binaries": "node scripts/build-binaries.mjs",
|
|
80
|
+
"lint": "eslint src test --ext .ts",
|
|
81
|
+
"test": "node scripts/test-runner.mjs",
|
|
82
|
+
"typecheck": "tsc --noEmit -p tsconfig.test.json"
|
|
92
83
|
}
|
|
93
84
|
}
|
package/bin/dev.cmd
DELETED
package/bin/dev.js
DELETED
package/bin/run.cmd
DELETED