@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.
Files changed (130) hide show
  1. package/README.md +75 -2
  2. package/dist/commands/artifacts.d.ts +47 -18
  3. package/dist/commands/artifacts.js +69 -64
  4. package/dist/commands/cloud.d.ts +228 -88
  5. package/dist/commands/cloud.js +430 -342
  6. package/dist/commands/list.d.ts +39 -38
  7. package/dist/commands/list.js +124 -131
  8. package/dist/commands/live.d.ts +2 -0
  9. package/dist/commands/live.js +520 -0
  10. package/dist/commands/login.d.ts +17 -0
  11. package/dist/commands/login.js +252 -0
  12. package/dist/commands/logout.d.ts +2 -0
  13. package/dist/commands/logout.js +30 -0
  14. package/dist/commands/status.d.ts +23 -42
  15. package/dist/commands/status.js +170 -179
  16. package/dist/commands/switch-org.d.ts +12 -0
  17. package/dist/commands/switch-org.js +76 -0
  18. package/dist/commands/upgrade.d.ts +2 -0
  19. package/dist/commands/upgrade.js +120 -0
  20. package/dist/commands/upload.d.ts +33 -18
  21. package/dist/commands/upload.js +72 -78
  22. package/dist/commands/whoami.d.ts +2 -0
  23. package/dist/commands/whoami.js +31 -0
  24. package/dist/config/environments.d.ts +31 -0
  25. package/dist/config/environments.js +52 -0
  26. package/dist/config/flags/api.flags.d.ts +10 -2
  27. package/dist/config/flags/api.flags.js +13 -14
  28. package/dist/config/flags/binary.flags.d.ts +17 -4
  29. package/dist/config/flags/binary.flags.js +14 -18
  30. package/dist/config/flags/device.flags.d.ts +49 -11
  31. package/dist/config/flags/device.flags.js +43 -38
  32. package/dist/config/flags/environment.flags.d.ts +27 -6
  33. package/dist/config/flags/environment.flags.js +24 -29
  34. package/dist/config/flags/execution.flags.d.ts +35 -8
  35. package/dist/config/flags/execution.flags.js +31 -41
  36. package/dist/config/flags/github.flags.d.ts +23 -5
  37. package/dist/config/flags/github.flags.js +19 -15
  38. package/dist/config/flags/output.flags.d.ts +57 -13
  39. package/dist/config/flags/output.flags.js +48 -47
  40. package/dist/constants.d.ts +218 -51
  41. package/dist/constants.js +17 -20
  42. package/dist/gateways/api-gateway.d.ts +72 -16
  43. package/dist/gateways/api-gateway.js +298 -104
  44. package/dist/gateways/cli-auth-gateway.d.ts +13 -0
  45. package/dist/gateways/cli-auth-gateway.js +54 -0
  46. package/dist/gateways/realtime-gateway.d.ts +32 -0
  47. package/dist/gateways/realtime-gateway.js +103 -0
  48. package/dist/gateways/supabase-gateway.d.ts +11 -11
  49. package/dist/gateways/supabase-gateway.js +20 -48
  50. package/dist/index.d.ts +2 -1
  51. package/dist/index.js +98 -4
  52. package/dist/mcp/context.d.ts +33 -0
  53. package/dist/mcp/context.js +33 -0
  54. package/dist/mcp/helpers.d.ts +16 -0
  55. package/dist/mcp/helpers.js +34 -0
  56. package/dist/mcp/index.d.ts +2 -0
  57. package/dist/mcp/index.js +24 -0
  58. package/dist/mcp/server.d.ts +7 -0
  59. package/dist/mcp/server.js +27 -0
  60. package/dist/mcp/tools/download-artifacts.d.ts +11 -0
  61. package/dist/mcp/tools/download-artifacts.js +84 -0
  62. package/dist/mcp/tools/get-status.d.ts +7 -0
  63. package/dist/mcp/tools/get-status.js +39 -0
  64. package/dist/mcp/tools/list-devices.d.ts +7 -0
  65. package/dist/mcp/tools/list-devices.js +27 -0
  66. package/dist/mcp/tools/list-runs.d.ts +3 -0
  67. package/dist/mcp/tools/list-runs.js +60 -0
  68. package/dist/mcp/tools/run-cloud-test.d.ts +14 -0
  69. package/dist/mcp/tools/run-cloud-test.js +233 -0
  70. package/dist/methods.d.ts +34 -5
  71. package/dist/methods.js +266 -215
  72. package/dist/services/device-validation.service.d.ts +9 -1
  73. package/dist/services/device-validation.service.js +56 -40
  74. package/dist/services/execution-plan.service.js +40 -31
  75. package/dist/services/execution-plan.utils.d.ts +3 -0
  76. package/dist/services/execution-plan.utils.js +25 -55
  77. package/dist/services/flow-paths.d.ts +17 -0
  78. package/dist/services/flow-paths.js +52 -0
  79. package/dist/services/metadata-extractor.service.d.ts +0 -2
  80. package/dist/services/metadata-extractor.service.js +75 -78
  81. package/dist/services/moropo.service.js +33 -34
  82. package/dist/services/report-download.service.d.ts +12 -1
  83. package/dist/services/report-download.service.js +34 -27
  84. package/dist/services/results-polling.service.d.ts +23 -9
  85. package/dist/services/results-polling.service.js +257 -123
  86. package/dist/services/telemetry.service.d.ts +49 -0
  87. package/dist/services/telemetry.service.js +252 -0
  88. package/dist/services/test-submission.service.d.ts +21 -4
  89. package/dist/services/test-submission.service.js +51 -33
  90. package/dist/services/version.service.d.ts +4 -3
  91. package/dist/services/version.service.js +28 -16
  92. package/dist/types/domain/auth.types.d.ts +20 -0
  93. package/dist/types/domain/auth.types.js +1 -0
  94. package/dist/types/domain/device.types.js +8 -11
  95. package/dist/types/domain/live.types.d.ts +76 -0
  96. package/dist/types/domain/live.types.js +3 -0
  97. package/dist/types/generated/schema.types.js +1 -2
  98. package/dist/types/index.d.ts +2 -2
  99. package/dist/types/index.js +2 -18
  100. package/dist/types.js +1 -2
  101. package/dist/utils/auth.d.ts +13 -0
  102. package/dist/utils/auth.js +141 -0
  103. package/dist/utils/ci.d.ts +12 -0
  104. package/dist/utils/ci.js +39 -0
  105. package/dist/utils/cli.d.ts +35 -0
  106. package/dist/utils/cli.js +118 -0
  107. package/dist/utils/compatibility.d.ts +2 -1
  108. package/dist/utils/compatibility.js +6 -8
  109. package/dist/utils/config-store.d.ts +35 -0
  110. package/dist/utils/config-store.js +115 -0
  111. package/dist/utils/connectivity.js +8 -7
  112. package/dist/utils/expo.js +29 -24
  113. package/dist/utils/orgs.d.ts +11 -0
  114. package/dist/utils/orgs.js +36 -0
  115. package/dist/utils/paths.d.ts +11 -0
  116. package/dist/utils/paths.js +21 -0
  117. package/dist/utils/progress.d.ts +13 -0
  118. package/dist/utils/progress.js +47 -0
  119. package/dist/utils/styling.d.ts +42 -36
  120. package/dist/utils/styling.js +78 -82
  121. package/dist/utils/ui.d.ts +41 -0
  122. package/dist/utils/ui.js +95 -0
  123. package/package.json +36 -45
  124. package/bin/dev.cmd +0 -3
  125. package/bin/dev.js +0 -6
  126. package/bin/run.cmd +0 -3
  127. package/bin/run.js +0 -7
  128. package/dist/types/schema.types.d.ts +0 -2702
  129. package/dist/types/schema.types.js +0 -3
  130. package/oclif.manifest.json +0 -884
@@ -1,24 +1,16 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
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
- exports.symbols = {
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
- exports.colors = {
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
- * Dividers for visual separation
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
- exports.dividers = {
49
- heavy: chalk.gray(''.repeat(80)),
50
- light: chalk.gray(''.repeat(80)),
51
- short: chalk.gray('─'.repeat(40)),
42
+ export const glyphs = {
43
+ branch: '',
44
+ section: '',
52
45
  };
53
46
  /**
54
- * Format a status with appropriate symbol and color
55
- * @param status - The status string to format
56
- * @returns Formatted status string with color and symbol
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 formatStatus(status) {
59
- const statusUpper = status.toUpperCase();
60
- switch (statusUpper) {
52
+ export function statusPalette(status) {
53
+ switch (status.toUpperCase()) {
61
54
  case 'PASSED': {
62
- return `${exports.symbols.success} ${exports.colors.success(status)}`;
55
+ return { color: colors.success, symbol: symbols.success };
63
56
  }
57
+ case 'ERROR':
64
58
  case 'FAILED': {
65
- return `${exports.symbols.error} ${exports.colors.error(status)}`;
59
+ return { color: colors.error, symbol: symbols.error };
66
60
  }
67
61
  case 'RUNNING': {
68
- return `${exports.symbols.running} ${exports.colors.info(status)}`;
62
+ return { color: colors.info, symbol: symbols.running };
69
63
  }
70
64
  case 'PENDING': {
71
- return `${exports.symbols.pending} ${exports.colors.warning(status)}`;
65
+ return { color: colors.warning, symbol: symbols.pending };
72
66
  }
73
67
  case 'QUEUED': {
74
- return `${exports.symbols.queued} ${exports.colors.dim(status)}`;
68
+ return { color: colors.dim, symbol: symbols.queued };
75
69
  }
76
70
  case 'CANCELLED': {
77
- return `${exports.symbols.cancelled} ${exports.colors.dim(status)}`;
71
+ return { color: colors.dim, symbol: symbols.cancelled };
78
72
  }
79
73
  default: {
80
- return `${exports.symbols.unknown} ${exports.colors.dim(status)}`;
74
+ return { color: colors.dim, symbol: symbols.unknown };
81
75
  }
82
76
  }
83
77
  }
84
78
  /**
85
- * Format a section header
86
- * @param title - The title of the section
87
- * @returns Formatted section header
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 keyValue(icon, key, value) {
100
- return `${icon} ${exports.colors.dim(key + ':')} ${exports.colors.highlight(value)}`;
84
+ export function formatStatus(status) {
85
+ const { color, symbol } = statusPalette(status);
86
+ return `${symbol} ${color(status.toLowerCase())}`;
101
87
  }
102
88
  /**
103
- * Format a list item
104
- * @param text - The text of the list item
105
- * @param prefix - The prefix character (default: '•')
106
- * @returns Formatted list item
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 listItem(text, prefix = '•') {
109
- return `${exports.colors.dim(prefix)} ${text}`;
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 exports.colors.url(url);
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 exports.colors.highlight(id);
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
- exports.colors.success(`✓ ${summary.passed}`),
136
- exports.colors.error(`✗ ${summary.failed}`),
137
- exports.colors.info(`▶ ${summary.running}`),
138
- exports.colors.warning(`⏸ ${summary.pending}`),
139
- exports.colors.dim(`⏳ ${summary.queued}`),
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
- * Format a box with content
145
- * @param content - The content to display in the box
146
- * @returns Formatted box with borders
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 box(content) {
149
- const lines = content.split('\n');
150
- const maxLength = Math.max(...lines.map((l) => l.length));
151
- const top = chalk.gray('┌' + '─'.repeat(maxLength + 2) + '┐');
152
- const bottom = chalk.gray('└' + '─'.repeat(maxLength + 2) + '┘');
153
- const middle = lines
154
- .map((line) => chalk.gray('│ ') + line.padEnd(maxLength) + chalk.gray(' │'))
155
- .join('\n');
156
- return `${top}\n${middle}\n${bottom}`;
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
- * If a non-default API URL is used, prepends "dev." to the console subdomain
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 DEFAULT_API_URL = 'https://api.devicecloud.dev';
168
- const isDefaultApi = apiUrl === DEFAULT_API_URL;
169
- const consoleSubdomain = isDefaultApi ? 'console' : 'dev.console';
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
+ };
@@ -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": "bin/run.js"
4
+ "dcd": "dist/index.js",
5
+ "dcd-mcp": "dist/mcp/index.js"
5
6
  },
6
7
  "dependencies": {
7
- "@oclif/core": "^3.27.0",
8
- "@oclif/plugin-help": "^6.2.37",
9
- "@supabase/supabase-js": "^2.99.1",
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": "4.1.2",
14
- "glob": "^13.0.6",
15
- "js-yaml": "^4.1.1",
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": "^3.1.0",
18
- "tar": "^7.5.11",
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": "Better cloud maestro testing",
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
- "@oclif/prettier-config": "^0.2.1",
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": "^25.4.0",
31
- "@types/plist": "^3.0.5",
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": "^8.57.1",
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
- "mocha": "^11.7.5",
39
- "oclif": "^4.22.96",
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
- "ts-node": "^10.9.2",
42
- "typescript": "^5.9.3"
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
- "/bin",
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": "4.4.9",
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": "./bin/dev.js",
87
- "prod": "./bin/run.js",
88
- "build": "shx rm -rf dist && tsc -b",
89
- "lint": "eslint . --ext .ts",
90
- "version": "oclif readme && git add README.md",
91
- "test": "node scripts/test-runner.mjs"
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
@@ -1,3 +0,0 @@
1
- @echo off
2
-
3
- node "%~dp0\dev" %*
package/bin/dev.js DELETED
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env node_modules/.bin/ts-node
2
- // eslint-disable-next-line node/shebang, unicorn/prefer-top-level-await
3
- ;(async () => {
4
- const oclif = await import('@oclif/core')
5
- await oclif.execute({development: true, dir: __dirname})
6
- })()
package/bin/run.cmd DELETED
@@ -1,3 +0,0 @@
1
- @echo off
2
-
3
- node "%~dp0\run" %*
package/bin/run.js DELETED
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // eslint-disable-next-line unicorn/prefer-top-level-await
4
- (async () => {
5
- const oclif = await import('@oclif/core');
6
- await oclif.execute({ development: false, dir: __dirname });
7
- })();