@devicecloud.dev/dcd 5.0.0-beta.0 → 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 +35 -0
- package/dist/commands/artifacts.d.ts +28 -28
- package/dist/commands/artifacts.js +20 -23
- package/dist/commands/cloud.d.ts +57 -57
- package/dist/commands/cloud.js +173 -186
- package/dist/commands/list.d.ts +22 -22
- package/dist/commands/list.js +36 -38
- package/dist/commands/live.js +134 -127
- package/dist/commands/login.d.ts +11 -11
- package/dist/commands/login.js +46 -44
- package/dist/commands/logout.js +16 -18
- package/dist/commands/status.d.ts +11 -11
- package/dist/commands/status.js +45 -43
- package/dist/commands/switch-org.d.ts +7 -7
- package/dist/commands/switch-org.js +19 -21
- package/dist/commands/upgrade.js +29 -31
- package/dist/commands/upload.d.ts +10 -10
- package/dist/commands/upload.js +42 -43
- package/dist/commands/whoami.js +17 -20
- package/dist/config/environments.js +6 -12
- package/dist/config/flags/api.flags.js +1 -4
- package/dist/config/flags/binary.flags.js +1 -4
- package/dist/config/flags/device.flags.js +6 -9
- package/dist/config/flags/environment.flags.js +1 -4
- package/dist/config/flags/execution.flags.js +1 -4
- package/dist/config/flags/github.flags.js +1 -4
- package/dist/config/flags/output.flags.js +1 -4
- package/dist/constants.js +15 -18
- package/dist/gateways/api-gateway.d.ts +31 -6
- package/dist/gateways/api-gateway.js +70 -16
- package/dist/gateways/cli-auth-gateway.d.ts +1 -1
- package/dist/gateways/cli-auth-gateway.js +3 -6
- package/dist/gateways/realtime-gateway.d.ts +32 -0
- package/dist/gateways/realtime-gateway.js +103 -0
- package/dist/gateways/supabase-gateway.d.ts +1 -1
- package/dist/gateways/supabase-gateway.js +10 -14
- package/dist/index.js +41 -38
- 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 +32 -1
- package/dist/methods.js +125 -66
- package/dist/services/device-validation.service.d.ts +1 -1
- package/dist/services/device-validation.service.js +1 -5
- package/dist/services/execution-plan.service.js +14 -17
- package/dist/services/execution-plan.utils.js +15 -23
- package/dist/services/flow-paths.d.ts +17 -0
- package/dist/services/flow-paths.js +52 -0
- package/dist/services/metadata-extractor.service.js +22 -25
- package/dist/services/moropo.service.js +18 -20
- package/dist/services/report-download.service.d.ts +1 -1
- package/dist/services/report-download.service.js +5 -9
- package/dist/services/results-polling.service.d.ts +18 -3
- package/dist/services/results-polling.service.js +195 -108
- package/dist/services/telemetry.service.d.ts +10 -1
- package/dist/services/telemetry.service.js +40 -18
- package/dist/services/test-submission.service.d.ts +21 -4
- package/dist/services/test-submission.service.js +51 -34
- package/dist/services/version.service.d.ts +1 -1
- package/dist/services/version.service.js +1 -5
- package/dist/types/domain/auth.types.d.ts +8 -0
- package/dist/types/domain/auth.types.js +1 -2
- package/dist/types/domain/device.types.js +8 -11
- package/dist/types/domain/live.types.js +1 -2
- 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 +1 -1
- package/dist/utils/auth.js +27 -28
- package/dist/utils/ci.d.ts +12 -0
- package/dist/utils/ci.js +39 -0
- package/dist/utils/cli.js +18 -27
- package/dist/utils/compatibility.d.ts +1 -1
- package/dist/utils/compatibility.js +5 -7
- package/dist/utils/config-store.js +33 -43
- package/dist/utils/connectivity.js +1 -4
- package/dist/utils/expo.js +15 -21
- package/dist/utils/orgs.js +8 -12
- package/dist/utils/paths.js +2 -5
- package/dist/utils/progress.js +2 -5
- package/dist/utils/styling.d.ts +35 -37
- package/dist/utils/styling.js +52 -86
- package/dist/utils/ui.d.ts +41 -0
- package/dist/utils/ui.js +95 -0
- package/package.json +27 -24
package/dist/utils/styling.js
CHANGED
|
@@ -1,29 +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.table = table;
|
|
13
|
-
exports.getConsoleUrl = getConsoleUrl;
|
|
14
|
-
const chalk = require("chalk");
|
|
15
|
-
const environments_1 = require("../config/environments");
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { findEnvByApiUrl } from '../config/environments.js';
|
|
16
3
|
/**
|
|
17
4
|
* Centralized styling utilities for CLI output
|
|
18
5
|
* Provides consistent, developer-friendly visual formatting
|
|
19
6
|
*/
|
|
20
7
|
/** Strip ANSI color escape sequences for visible-width calculations. */
|
|
21
8
|
// eslint-disable-next-line no-control-regex -- matches ANSI escape sequences
|
|
22
|
-
const stripAnsi = (s) => s.replace(/\u001B\[[0-9;]*m/g, '');
|
|
9
|
+
export const stripAnsi = (s) => s.replace(/\u001B\[[0-9;]*m/g, '');
|
|
23
10
|
/**
|
|
24
11
|
* Status symbols with associated colors
|
|
25
12
|
*/
|
|
26
|
-
|
|
13
|
+
export const symbols = {
|
|
27
14
|
cancelled: chalk.gray('⊘'),
|
|
28
15
|
error: chalk.red('✗'),
|
|
29
16
|
info: chalk.blue('ℹ'),
|
|
@@ -37,7 +24,7 @@ exports.symbols = {
|
|
|
37
24
|
/**
|
|
38
25
|
* Color utility functions for semantic styling
|
|
39
26
|
*/
|
|
40
|
-
|
|
27
|
+
export const colors = {
|
|
41
28
|
bold: chalk.bold,
|
|
42
29
|
dim: chalk.gray,
|
|
43
30
|
error: chalk.red,
|
|
@@ -48,125 +35,104 @@ exports.colors = {
|
|
|
48
35
|
warning: chalk.yellow,
|
|
49
36
|
};
|
|
50
37
|
/**
|
|
51
|
-
*
|
|
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.
|
|
52
41
|
*/
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
short: chalk.gray('─'.repeat(40)),
|
|
42
|
+
export const glyphs = {
|
|
43
|
+
branch: '⎿',
|
|
44
|
+
section: '⏺',
|
|
57
45
|
};
|
|
58
46
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
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)
|
|
62
51
|
*/
|
|
63
|
-
function
|
|
64
|
-
|
|
65
|
-
switch (statusUpper) {
|
|
52
|
+
export function statusPalette(status) {
|
|
53
|
+
switch (status.toUpperCase()) {
|
|
66
54
|
case 'PASSED': {
|
|
67
|
-
return
|
|
55
|
+
return { color: colors.success, symbol: symbols.success };
|
|
68
56
|
}
|
|
57
|
+
case 'ERROR':
|
|
69
58
|
case 'FAILED': {
|
|
70
|
-
return
|
|
59
|
+
return { color: colors.error, symbol: symbols.error };
|
|
71
60
|
}
|
|
72
61
|
case 'RUNNING': {
|
|
73
|
-
return
|
|
62
|
+
return { color: colors.info, symbol: symbols.running };
|
|
74
63
|
}
|
|
75
64
|
case 'PENDING': {
|
|
76
|
-
return
|
|
65
|
+
return { color: colors.warning, symbol: symbols.pending };
|
|
77
66
|
}
|
|
78
67
|
case 'QUEUED': {
|
|
79
|
-
return
|
|
68
|
+
return { color: colors.dim, symbol: symbols.queued };
|
|
80
69
|
}
|
|
81
70
|
case 'CANCELLED': {
|
|
82
|
-
return
|
|
71
|
+
return { color: colors.dim, symbol: symbols.cancelled };
|
|
83
72
|
}
|
|
84
73
|
default: {
|
|
85
|
-
return
|
|
74
|
+
return { color: colors.dim, symbol: symbols.unknown };
|
|
86
75
|
}
|
|
87
76
|
}
|
|
88
77
|
}
|
|
89
78
|
/**
|
|
90
|
-
* Format a
|
|
91
|
-
*
|
|
92
|
-
* @
|
|
93
|
-
|
|
94
|
-
function sectionHeader(title) {
|
|
95
|
-
return `\n${exports.colors.bold(title)}\n${exports.dividers.light}`;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Format a key-value pair with optional icon
|
|
99
|
-
* @param icon - Icon to display before the key
|
|
100
|
-
* @param key - The key name
|
|
101
|
-
* @param value - The value to display
|
|
102
|
-
* @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
|
|
103
83
|
*/
|
|
104
|
-
function
|
|
105
|
-
|
|
84
|
+
export function formatStatus(status) {
|
|
85
|
+
const { color, symbol } = statusPalette(status);
|
|
86
|
+
return `${symbol} ${color(status.toLowerCase())}`;
|
|
106
87
|
}
|
|
107
88
|
/**
|
|
108
|
-
* Format a
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* @
|
|
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
|
|
112
94
|
*/
|
|
113
|
-
function
|
|
114
|
-
return
|
|
95
|
+
export function sectionHeader(title) {
|
|
96
|
+
return `\n${colors.dim(glyphs.section)} ${colors.bold(title)}`;
|
|
115
97
|
}
|
|
116
98
|
/**
|
|
117
99
|
* Format a URL
|
|
118
100
|
* @param url - The URL to format
|
|
119
101
|
* @returns Formatted URL with styling
|
|
120
102
|
*/
|
|
121
|
-
function formatUrl(url) {
|
|
122
|
-
return
|
|
103
|
+
export function formatUrl(url) {
|
|
104
|
+
return colors.url(url);
|
|
123
105
|
}
|
|
124
106
|
/**
|
|
125
107
|
* Format an ID or identifier
|
|
126
108
|
* @param id - The ID to format
|
|
127
109
|
* @returns Formatted ID with highlighting
|
|
128
110
|
*/
|
|
129
|
-
function formatId(id) {
|
|
130
|
-
return
|
|
111
|
+
export function formatId(id) {
|
|
112
|
+
return colors.highlight(id);
|
|
131
113
|
}
|
|
132
114
|
/**
|
|
133
115
|
* Format a test summary line
|
|
134
116
|
* @param summary - Object containing test counts
|
|
135
117
|
* @returns Formatted summary string
|
|
136
118
|
*/
|
|
137
|
-
function formatTestSummary(summary) {
|
|
119
|
+
export function formatTestSummary(summary) {
|
|
138
120
|
const parts = [
|
|
139
121
|
chalk.bold(`${summary.completed}/${summary.total}`),
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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}`),
|
|
145
127
|
];
|
|
146
128
|
return parts.join(' │ ');
|
|
147
129
|
}
|
|
148
|
-
/**
|
|
149
|
-
* Format a box with content
|
|
150
|
-
* @param content - The content to display in the box
|
|
151
|
-
* @returns Formatted box with borders
|
|
152
|
-
*/
|
|
153
|
-
function box(content) {
|
|
154
|
-
const lines = content.split('\n');
|
|
155
|
-
const visibleLen = (s) => stripAnsi(s).length;
|
|
156
|
-
const maxLength = Math.max(...lines.map((l) => visibleLen(l)));
|
|
157
|
-
const top = chalk.gray('┌' + '─'.repeat(maxLength + 2) + '┐');
|
|
158
|
-
const bottom = chalk.gray('└' + '─'.repeat(maxLength + 2) + '┘');
|
|
159
|
-
const middle = lines
|
|
160
|
-
.map((line) => chalk.gray('│ ') + line + ' '.repeat(Math.max(0, maxLength - visibleLen(line))) + chalk.gray(' │'))
|
|
161
|
-
.join('\n');
|
|
162
|
-
return `${top}\n${middle}\n${bottom}`;
|
|
163
|
-
}
|
|
164
130
|
/**
|
|
165
131
|
* Minimal column table renderer.
|
|
166
132
|
* Columns are defined with a `get(row) => string` accessor and optional header label.
|
|
167
133
|
* Matches the subset of oclif's ux.table used by this CLI.
|
|
168
134
|
*/
|
|
169
|
-
function table(rows, columns, options = {}) {
|
|
135
|
+
export function table(rows, columns, options = {}) {
|
|
170
136
|
const printLine = options.printLine ?? ((line) => {
|
|
171
137
|
// eslint-disable-next-line no-console
|
|
172
138
|
console.log(line);
|
|
@@ -194,8 +160,8 @@ function table(rows, columns, options = {}) {
|
|
|
194
160
|
* @param resultId - The result ID
|
|
195
161
|
* @returns The appropriate console URL
|
|
196
162
|
*/
|
|
197
|
-
function getConsoleUrl(apiUrl, uploadId, resultId) {
|
|
198
|
-
const env =
|
|
163
|
+
export function getConsoleUrl(apiUrl, uploadId, resultId) {
|
|
164
|
+
const env = findEnvByApiUrl(apiUrl);
|
|
199
165
|
const base = env?.frontendUrl ?? 'https://dev.console.devicecloud.dev';
|
|
200
166
|
return `${base}/results?upload=${uploadId}&result=${resultId}`;
|
|
201
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,43 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "devicecloud.dev",
|
|
3
3
|
"bin": {
|
|
4
|
-
"dcd": "dist/index.js"
|
|
4
|
+
"dcd": "dist/index.js",
|
|
5
|
+
"dcd-mcp": "dist/mcp/index.js"
|
|
5
6
|
},
|
|
6
7
|
"dependencies": {
|
|
7
|
-
"@clack/prompts": "^1.
|
|
8
|
-
"@
|
|
8
|
+
"@clack/prompts": "^1.6.0",
|
|
9
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
10
|
+
"@supabase/supabase-js": "^2.108.2",
|
|
9
11
|
"bplist-parser": "^0.3.2",
|
|
10
|
-
"chalk": "
|
|
11
|
-
"citty": "^0.
|
|
12
|
-
"js-yaml": "^
|
|
12
|
+
"chalk": "^5.6.2",
|
|
13
|
+
"citty": "^0.2.2",
|
|
14
|
+
"js-yaml": "^5.0.0",
|
|
13
15
|
"node-apk": "^1.2.1",
|
|
14
16
|
"node-stream-zip": "^1.15.0",
|
|
15
|
-
"plist": "^
|
|
16
|
-
"tar": "^7.5.
|
|
17
|
+
"plist": "^5.0.0",
|
|
18
|
+
"tar": "^7.5.16",
|
|
17
19
|
"tus-js-client": "^4.3.1",
|
|
18
|
-
"yazl": "^3.3.1"
|
|
20
|
+
"yazl": "^3.3.1",
|
|
21
|
+
"zod": "^4.4.3"
|
|
19
22
|
},
|
|
20
|
-
"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.",
|
|
21
24
|
"devDependencies": {
|
|
22
|
-
"@eslint/js": "^
|
|
23
|
-
"@types/chai": "^
|
|
25
|
+
"@eslint/js": "^10.0.1",
|
|
26
|
+
"@types/chai": "^5.2.3",
|
|
24
27
|
"@types/js-yaml": "^4.0.9",
|
|
25
28
|
"@types/mocha": "^10.0.10",
|
|
26
|
-
"@types/node": "^
|
|
27
|
-
"@types/plist": "^3.0.5",
|
|
29
|
+
"@types/node": "^26.0.0",
|
|
28
30
|
"@types/yazl": "^3.3.1",
|
|
29
|
-
"chai": "^
|
|
30
|
-
"eslint": "^
|
|
31
|
+
"chai": "^6.2.2",
|
|
32
|
+
"eslint": "^10.5.0",
|
|
31
33
|
"eslint-config-prettier": "^10.1.8",
|
|
32
34
|
"eslint-plugin-import": "^2.32.0",
|
|
33
|
-
"eslint-plugin-unicorn": "^
|
|
35
|
+
"eslint-plugin-unicorn": "^68.0.0",
|
|
34
36
|
"husky": "^9.1.7",
|
|
35
|
-
"mocha": "^11.7.
|
|
36
|
-
"prettier": "^3.
|
|
37
|
+
"mocha": "^11.7.6",
|
|
38
|
+
"prettier": "^3.8.4",
|
|
37
39
|
"shx": "^0.4.0",
|
|
38
|
-
"tsx": "^4.
|
|
39
|
-
"typescript": "^
|
|
40
|
-
"typescript-eslint": "^8.
|
|
40
|
+
"tsx": "^4.22.4",
|
|
41
|
+
"typescript": "^6.0.3",
|
|
42
|
+
"typescript-eslint": "^8.61.1"
|
|
41
43
|
},
|
|
42
44
|
"engines": {
|
|
43
45
|
"node": ">=22.0.0"
|
|
@@ -50,6 +52,7 @@
|
|
|
50
52
|
"main": "dist/index.js",
|
|
51
53
|
"name": "@devicecloud.dev/dcd",
|
|
52
54
|
"private": false,
|
|
55
|
+
"type": "module",
|
|
53
56
|
"publishConfig": {
|
|
54
57
|
"access": "public"
|
|
55
58
|
},
|
|
@@ -57,7 +60,7 @@
|
|
|
57
60
|
"type": "git",
|
|
58
61
|
"url": "https://devicecloud.dev"
|
|
59
62
|
},
|
|
60
|
-
"version": "5.0.0-beta.
|
|
63
|
+
"version": "5.0.0-beta.1",
|
|
61
64
|
"bugs": {
|
|
62
65
|
"url": "https://discord.gg/gm3mJwcNw8"
|
|
63
66
|
},
|
|
@@ -72,7 +75,7 @@
|
|
|
72
75
|
"types": "dist/index.d.ts",
|
|
73
76
|
"scripts": {
|
|
74
77
|
"dcd": "tsx src/index.ts",
|
|
75
|
-
"build": "shx rm -rf dist && tsc -b && shx chmod +x dist/index.js",
|
|
78
|
+
"build": "shx rm -rf dist && tsc -b && shx chmod +x dist/index.js dist/mcp/index.js",
|
|
76
79
|
"build:binaries": "node scripts/build-binaries.mjs",
|
|
77
80
|
"lint": "eslint src test --ext .ts",
|
|
78
81
|
"test": "node scripts/test-runner.mjs",
|