testdriverai 5.7.43 → 5.7.44

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/lib/logger.js CHANGED
@@ -2,6 +2,8 @@
2
2
  const winston = require("winston");
3
3
  const os = require("os");
4
4
  const server = require("./ipc");
5
+ const chalk = require("chalk");
6
+ const theme = require("./theme");
5
7
 
6
8
  // simple match for aws instance i-*
7
9
  const shouldLog =
@@ -49,14 +51,233 @@ const logger = winston.createLogger({
49
51
  transports: [new winston.transports.Console()],
50
52
  });
51
53
 
54
+ const plain = (codePart) => codePart;
55
+
52
56
  // marked is a markdown parser
53
57
  // markedTerminal allows us to render markdown in CLI
54
58
  marked.use(
55
- markedTerminal({
56
- width: 58, // 58 is the width of the terminal output on a 16" macbook pro
57
- reflowText: true,
58
- tab: 0,
59
- }),
59
+ markedTerminal(
60
+ {
61
+ width: 58, // 58 is the width of the terminal output on a 16" macbook pro
62
+ reflowText: true,
63
+ tab: 2,
64
+ },
65
+ {
66
+ theme: {
67
+ /**
68
+ * keyword in a regular Algol-style language
69
+ */
70
+ keyword: theme.blue,
71
+
72
+ /**
73
+ * built-in or library object (constant, class, function)
74
+ */
75
+ built_in: theme.cyan,
76
+
77
+ /**
78
+ * user-defined type in a language with first-class syntactically significant types, like
79
+ * Haskell
80
+ */
81
+ type: theme.cyan,
82
+
83
+ /**
84
+ * special identifier for a built-in value ("true", "false", "null")
85
+ */
86
+ literal: theme.blue,
87
+
88
+ /**
89
+ * number, including units and modifiers, if any.
90
+ */
91
+ number: theme.green,
92
+
93
+ /**
94
+ * literal regular expression
95
+ */
96
+ regexp: theme.red,
97
+
98
+ /**
99
+ * literal string, character
100
+ */
101
+ string: theme.green,
102
+
103
+ /**
104
+ * parsed section inside a literal string
105
+ */
106
+ subst: plain,
107
+
108
+ /**
109
+ * symbolic constant, interned string, goto label
110
+ */
111
+ symbol: plain,
112
+
113
+ /**
114
+ * class or class-level declaration (interfaces, traits, modules, etc)
115
+ */
116
+ class: theme.blue,
117
+
118
+ /**
119
+ * function or method declaration
120
+ */
121
+ function: theme.yellow,
122
+
123
+ /**
124
+ * name of a class or a function at the place of declaration
125
+ */
126
+ title: plain,
127
+
128
+ /**
129
+ * block of function arguments (parameters) at the place of declaration
130
+ */
131
+ params: plain,
132
+
133
+ /**
134
+ * comment
135
+ */
136
+ comment: theme.green,
137
+
138
+ /**
139
+ * documentation markup within comments
140
+ */
141
+ doctag: theme.green,
142
+
143
+ /**
144
+ * flags, modifiers, annotations, processing instructions, preprocessor directive, etc
145
+ */
146
+ meta: theme.grey,
147
+
148
+ /**
149
+ * keyword or built-in within meta construct
150
+ */
151
+ "meta-keyword": plain,
152
+
153
+ /**
154
+ * string within meta construct
155
+ */
156
+ "meta-string": plain,
157
+
158
+ /**
159
+ * heading of a section in a config file, heading in text markup
160
+ */
161
+ section: plain,
162
+
163
+ /**
164
+ * XML/HTML tag
165
+ */
166
+ tag: theme.grey,
167
+
168
+ /**
169
+ * name of an XML tag, the first word in an s-expression
170
+ */
171
+ name: theme.blue,
172
+
173
+ /**
174
+ * s-expression name from the language standard library
175
+ */
176
+ "builtin-name": plain,
177
+
178
+ /**
179
+ * name of an attribute with no language defined semantics (keys in JSON, setting names in
180
+ * .ini), also sub-attribute within another highlighted object, like XML tag
181
+ */
182
+ attr: theme.cyan,
183
+
184
+ /**
185
+ * name of an attribute followed by a structured value part, like CSS properties
186
+ */
187
+ attribute: plain,
188
+
189
+ /**
190
+ * variable in a config or a template file, environment var expansion in a script
191
+ */
192
+ variable: plain,
193
+
194
+ /**
195
+ * list item bullet in text markup
196
+ */
197
+ bullet: plain,
198
+
199
+ /**
200
+ * code block in text markup
201
+ */
202
+ code: plain,
203
+
204
+ /**
205
+ * emphasis in text markup
206
+ */
207
+ emphasis: chalk.italic,
208
+
209
+ /**
210
+ * strong emphasis in text markup
211
+ */
212
+ strong: chalk.bold,
213
+
214
+ /**
215
+ * mathematical formula in text markup
216
+ */
217
+ formula: plain,
218
+
219
+ /**
220
+ * hyperlink in text markup
221
+ */
222
+ link: chalk.underline,
223
+
224
+ /**
225
+ * quotation in text markup
226
+ */
227
+ quote: plain,
228
+
229
+ /**
230
+ * tag selector in CSS
231
+ */
232
+ "selector-tag": plain,
233
+
234
+ /**
235
+ * #id selector in CSS
236
+ */
237
+ "selector-id": plain,
238
+
239
+ /**
240
+ * .class selector in CSS
241
+ */
242
+ "selector-class": plain,
243
+
244
+ /**
245
+ * [attr] selector in CSS
246
+ */
247
+ "selector-attr": plain,
248
+
249
+ /**
250
+ * :pseudo selector in CSS
251
+ */
252
+ "selector-pseudo": plain,
253
+
254
+ /**
255
+ * tag of a template language
256
+ */
257
+ "template-tag": plain,
258
+
259
+ /**
260
+ * variable in a template language
261
+ */
262
+ "template-variable": plain,
263
+
264
+ /**
265
+ * added or changed line in a diff
266
+ */
267
+ addition: theme.green,
268
+
269
+ /**
270
+ * deleted line in a diff
271
+ */
272
+ deletion: theme.red,
273
+
274
+ /**
275
+ * things not matched by any token
276
+ */
277
+ default: plain,
278
+ },
279
+ },
280
+ ),
60
281
  );
61
282
 
62
283
  const spaceChar = " ";
package/lib/network.js CHANGED
@@ -1,3 +0,0 @@
1
-
2
-
3
-
package/lib/outputs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  let outputs = {};
2
- const {logger} = require('./logger');
2
+ const { logger } = require("./logger");
3
3
 
4
4
  module.exports = {
5
5
  getAll: () => {
package/lib/parser.js CHANGED
@@ -2,35 +2,34 @@
2
2
  const Parser = require("markdown-parser");
3
3
  const yaml = require("js-yaml");
4
4
  const Ajv = require("ajv");
5
+ const theme = require("./theme");
5
6
 
6
7
  let parser = new Parser();
7
8
 
8
- const chalk = require('chalk');
9
-
10
9
  function formatAjvError(error) {
11
-
12
10
  return [
13
- chalk.yellow('❌ Validation Warning (beta)'),
14
- `${chalk.yellow('Path:')} ${chalk.white(error.instancePath)}`,
15
- `${chalk.yellow('Schema:')} ${chalk.cyan(error.schemaPath)}`,
16
- `${chalk.yellow('Keyword:')} ${chalk.magenta(error.keyword)}`,
11
+ theme.yellow("❌ Validation Warning (beta)"),
12
+ `${theme.yellow("Path:")} ${theme.white(error.instancePath)}`,
13
+ `${theme.yellow("Schema:")} ${theme.cyan(error.schemaPath)}`,
14
+ `${theme.yellow("Keyword:")} ${theme.magenta(error.keyword)}`,
17
15
  error.params?.missingProperty
18
- ? `${chalk.yellow('Missing:')} ${chalk.yellow(error.params.missingProperty)}`
19
- : '',
20
- `${chalk.yellow('Message:')} ${chalk.white(error.message)}`,
21
- `\n`
22
- ].filter(Boolean).join('\n');
16
+ ? `${theme.yellow("Missing:")} ${theme.yellow(error.params.missingProperty)}`
17
+ : "",
18
+ `${theme.yellow("Message:")} ${theme.white(error.message)}`,
19
+ `\n`,
20
+ ]
21
+ .filter(Boolean)
22
+ .join("\n");
23
23
  }
24
24
 
25
25
  // use markdown parser to find code blocks within AI response
26
26
  const findCodeBlocks = async function (markdownContent) {
27
-
28
27
  let md = markdownContent.match(/```yaml\n([\s\S]*?)```/);
29
28
 
30
29
  if (md) {
31
- return [{code: md[1]}];
30
+ return [{ code: md[1] }];
32
31
  } else {
33
- return []
32
+ return [];
34
33
  }
35
34
  };
36
35
 
@@ -44,7 +43,6 @@ const findGenerativePrompts = async function (markdownContent) {
44
43
 
45
44
  // parse the markdown content of each code block
46
45
  let codes = result.codes.map((code) => {
47
-
48
46
  return new Promise((resolve2, reject2) => {
49
47
  try {
50
48
  const yamlContent = getYAMLFromCodeBlock(code);
@@ -93,13 +91,12 @@ const parseYAML = async function (inputYaml) {
93
91
  // validate yaml using schema.json in root
94
92
  let schema = require("../schema.json");
95
93
  const validateYAML = async function (yaml) {
96
-
97
- let ajv = new Ajv({allowUnionTypes: true});
94
+ let ajv = new Ajv({ allowUnionTypes: true });
98
95
  let validate = ajv.compile(schema);
99
96
  let valid = validate(await parseYAML(yaml));
100
97
 
101
98
  if (!valid) {
102
- validate.errors.forEach(err => console.log(formatAjvError(err)));
99
+ validate.errors.forEach((err) => console.log(formatAjvError(err)));
103
100
  // throw new Error("Invalid YAML");
104
101
  }
105
102
 
@@ -108,12 +105,14 @@ const validateYAML = async function (yaml) {
108
105
 
109
106
  // Replace ${VAR} with the value from the vars object
110
107
  // Will skip variables that are not in the vars object
111
- // Will skip escaped variables like \${VAR}
112
- function interpolate (yaml, vars) {
113
-
108
+ // Will skip escaped variables like \${VAR}
109
+ function interpolate(yaml, vars) {
114
110
  let newyaml = yaml;
115
111
  Object.keys(vars).forEach((key) => {
116
- newyaml = newyaml.replace(new RegExp(`(?<!\\\\)\\$\\{${key}\\}`, "g"), vars[key]);
112
+ newyaml = newyaml.replace(
113
+ new RegExp(`(?<!\\\\)\\$\\{${key}\\}`, "g"),
114
+ vars[key],
115
+ );
117
116
  });
118
117
  // Replace \$ with $
119
118
  newyaml = newyaml.replace(/\\(\${[^}]+})/g, "$1");
package/lib/redraw.js CHANGED
@@ -3,10 +3,10 @@ const os = require("os");
3
3
  const path = require("path");
4
4
  const { compare } = require("odiff-bin");
5
5
  const logger = require("./logger").logger;
6
+ const theme = require("./theme");
6
7
 
7
8
  // network
8
- const si = require('systeminformation');
9
- const chalk = require('chalk');
9
+ const si = require("systeminformation");
10
10
 
11
11
  const redrawThresholdPercent = 3;
12
12
  const networkUpdateInterval = 2000;
@@ -29,8 +29,7 @@ async function resetState() {
29
29
  screenHasRedrawn = false;
30
30
  }
31
31
 
32
- const parseNetworkStats = (thisRxBytes,thisTxBytes) => {
33
-
32
+ const parseNetworkStats = (thisRxBytes, thisTxBytes) => {
34
33
  diffRxBytes = lastRxBytes !== null ? thisRxBytes - lastRxBytes : 0;
35
34
  diffTxBytes = lastTxBytes !== null ? thisTxBytes - lastTxBytes : 0;
36
35
 
@@ -43,27 +42,34 @@ const parseNetworkStats = (thisRxBytes,thisTxBytes) => {
43
42
  measurements.shift();
44
43
  }
45
44
 
46
- let avgRx = measurements.reduce((acc, m) => acc + m.rx, 0) / measurements.length;
47
- let avgTx = measurements.reduce((acc, m) => acc + m.tx, 0) / measurements.length;
45
+ let avgRx =
46
+ measurements.reduce((acc, m) => acc + m.rx, 0) / measurements.length;
47
+ let avgTx =
48
+ measurements.reduce((acc, m) => acc + m.tx, 0) / measurements.length;
48
49
 
49
- let stdDevRx = Math.sqrt(measurements.reduce((acc, m) => acc + Math.pow(m.rx - avgRx, 2), 0) / measurements.length);
50
- let stdDevTx = Math.sqrt(measurements.reduce((acc, m) => acc + Math.pow(m.tx - avgTx, 2), 0) / measurements.length);
50
+ let stdDevRx = Math.sqrt(
51
+ measurements.reduce((acc, m) => acc + Math.pow(m.rx - avgRx, 2), 0) /
52
+ measurements.length,
53
+ );
54
+ let stdDevTx = Math.sqrt(
55
+ measurements.reduce((acc, m) => acc + Math.pow(m.tx - avgTx, 2), 0) /
56
+ measurements.length,
57
+ );
51
58
 
52
59
  let zIndexRx = stdDevRx !== 0 ? (diffRxBytes - avgRx) / stdDevRx : 0;
53
60
  let zIndexTx = stdDevTx !== 0 ? (diffTxBytes - avgTx) / stdDevTx : 0;
54
61
 
55
- if ((zIndexRx < 0 && zIndexTx < 0) ) {
62
+ if (zIndexRx < 0 && zIndexTx < 0) {
56
63
  networkSettled = true;
57
64
  } else {
58
65
  networkSettled = false;
59
66
  }
60
- }
67
+ };
61
68
 
62
69
  async function updateNetwork() {
63
-
64
- const { exec } = require('child_process');
70
+ const { exec } = require("child_process");
65
71
  const scriptPath = path.join(__dirname, "network.ps1");
66
- if (os.platform() === 'win32') {
72
+ if (os.platform() === "win32") {
67
73
  exec(`powershell -File ${scriptPath}`, (error, stdout, stderr) => {
68
74
  if (error) {
69
75
  logger.error(`Error executing PowerShell script: ${error}`);
@@ -73,7 +79,7 @@ async function updateNetwork() {
73
79
  logger.error(`PowerShell error: ${stderr}`);
74
80
  return;
75
81
  }
76
-
82
+
77
83
  try {
78
84
  // Parse the JSON output
79
85
  const result = JSON.parse(stdout.trim());
@@ -82,15 +88,14 @@ async function updateNetwork() {
82
88
  logger.error(`Error parsing JSON: ${parseError}`);
83
89
  }
84
90
  });
85
- } else if (os.platform() === 'darwin') {
86
- si.networkStats().then(data => {
91
+ } else if (os.platform() === "darwin") {
92
+ si.networkStats().then((data) => {
87
93
  parseNetworkStats(data[0].rx_bytes, data[0].tx_bytes);
88
94
  });
89
95
  }
90
96
  }
91
97
 
92
98
  async function imageDiffPercent(image1Url, image2Url) {
93
-
94
99
  // generate a temporary file path
95
100
  const tmpImage = path.join(os.tmpdir(), `tmp-${Date.now()}.png`);
96
101
 
@@ -100,7 +105,7 @@ async function imageDiffPercent(image1Url, image2Url) {
100
105
  tmpImage,
101
106
  {
102
107
  failOnLayoutDiff: false,
103
- outputDiffMask: false
108
+ outputDiffMask: false,
104
109
  },
105
110
  );
106
111
 
@@ -115,7 +120,6 @@ async function imageDiffPercent(image1Url, image2Url) {
115
120
  }
116
121
  }
117
122
 
118
-
119
123
  let startImage = null;
120
124
 
121
125
  async function start() {
@@ -125,7 +129,7 @@ async function start() {
125
129
  }
126
130
 
127
131
  async function checkCondition(resolve, startTime, timeoutMs) {
128
- let nowImage = await captureScreenPNG(.25, true);
132
+ let nowImage = await captureScreenPNG(0.25, true);
129
133
  let timeElapsed = Date.now() - startTime;
130
134
  let diffPercent = 0;
131
135
  let isTimeout = timeElapsed > timeoutMs;
@@ -133,14 +137,30 @@ async function checkCondition(resolve, startTime, timeoutMs) {
133
137
  if (!screenHasRedrawn) {
134
138
  diffPercent = await imageDiffPercent(startImage, nowImage);
135
139
  screenHasRedrawn = diffPercent > redrawThresholdPercent;
136
- };
137
-
138
- // // log redraw as output
139
- let redrawText = screenHasRedrawn ? chalk.green(`y`) : chalk.dim(`${diffPercent}/${redrawThresholdPercent}%`);
140
- let networkText = networkSettled ? chalk.green(`y`) : chalk.dim(`${Math.trunc((diffRxBytes + diffTxBytes) / networkUpdateInterval)}b/s`);
141
- let timeoutText = isTimeout ? chalk.green(`y`) : chalk.dim(`${Math.floor((timeElapsed)/1000)}/${(timeoutMs / 1000)}s`);
140
+ }
142
141
 
143
- logger.debug(` ` + chalk.dim('redraw=') + redrawText + chalk.dim(' network=') + networkText + chalk.dim(' timeout=') + timeoutText);
142
+ // // log redraw as output
143
+ let redrawText = screenHasRedrawn
144
+ ? theme.green(`y`)
145
+ : theme.dim(`${diffPercent}/${redrawThresholdPercent}%`);
146
+ let networkText = networkSettled
147
+ ? theme.green(`y`)
148
+ : theme.dim(
149
+ `${Math.trunc((diffRxBytes + diffTxBytes) / networkUpdateInterval)}b/s`,
150
+ );
151
+ let timeoutText = isTimeout
152
+ ? theme.green(`y`)
153
+ : theme.dim(`${Math.floor(timeElapsed / 1000)}/${timeoutMs / 1000}s`);
154
+
155
+ logger.debug(
156
+ ` ` +
157
+ theme.dim("redraw=") +
158
+ redrawText +
159
+ theme.dim(" network=") +
160
+ networkText +
161
+ theme.dim(" timeout=") +
162
+ timeoutText,
163
+ );
144
164
 
145
165
  if ((screenHasRedrawn && networkSettled) || isTimeout) {
146
166
  logger.debug(` `);
@@ -5,10 +5,10 @@ steps:
5
5
  commands:
6
6
  - command: exec
7
7
  lang: shell
8
- linux: |
8
+ linux: |
9
9
  jumpapp google-chrome --disable-fre --no-default-browser-check --no-first-run "${TESTDRIVER_WEBSITE}" &
10
10
  exit
11
- mac: |
11
+ mac: |
12
12
  open -na "Google Chrome" --args --disable-fre --no-default-browser-check --no-first-run "${TESTDRIVER_WEBSITE}" &
13
13
  exit
14
14
  windows:
package/lib/sandbox.js CHANGED
@@ -1,5 +1,5 @@
1
- const WebSocket = require('ws');
2
- const config = require('./config');
1
+ const WebSocket = require("ws");
2
+ const config = require("./config");
3
3
 
4
4
  class Sandbox {
5
5
  constructor() {
@@ -11,60 +11,60 @@ class Sandbox {
11
11
  send(message) {
12
12
  let resolvePromise;
13
13
  if (this.socket) {
14
- message.requestId = Math.random().toString(36).substring(7) + new Date().getTime();
14
+ message.requestId =
15
+ Math.random().toString(36).substring(7) + new Date().getTime();
15
16
  let p = new Promise((resolve) => {
16
17
  this.socket.send(JSON.stringify(message));
17
18
  resolvePromise = resolve;
18
19
  });
19
- this.ps[message.requestId] = {promise: p, resolve: resolvePromise};
20
+ this.ps[message.requestId] = { promise: p, resolve: resolvePromise };
20
21
  return p;
21
22
  }
22
23
  }
23
24
 
24
25
  async boot() {
25
26
  return new Promise((resolve, reject) => {
26
-
27
- this.socket = new WebSocket(`${config.TD_API_ROOT.replace('https://', 'wss://')}`);
27
+ this.socket = new WebSocket(
28
+ `${config.TD_API_ROOT.replace("https://", "wss://")}`,
29
+ );
28
30
 
29
31
  // handle errors
30
- this.socket.on('close', () => {
31
- console.log('Socket Closed. Check your API KEY (TD_API_KEY)');
32
+ this.socket.on("close", () => {
33
+ console.log("Socket Closed. Check your API KEY (TD_API_KEY)");
32
34
  clearInterval(this.heartbeat);
33
35
  reject();
34
36
  process.exit(1);
35
- });
37
+ });
36
38
 
37
- this.socket.on('error', (err) => {
38
- console.log('Socket Error');
39
+ this.socket.on("error", (err) => {
40
+ console.log("Socket Error");
39
41
  err && console.log(err);
40
42
  clearInterval(this.heartbeat);
41
43
  throw err;
42
- });
44
+ });
43
45
 
44
- this.socket.on('open', async () => {
45
-
46
+ this.socket.on("open", async () => {
46
47
  this.heartbeat = setInterval(() => {
47
- this.send({type: 'ping'});
48
+ this.send({ type: "ping" });
48
49
  }, 5000);
49
50
 
50
51
  resolve(this);
51
52
  });
52
53
 
53
- this.socket.on('message', (raw) => {
54
+ this.socket.on("message", (raw) => {
54
55
  let message = JSON.parse(raw);
55
56
 
56
- if (message.type === 'error') {
57
+ if (message.type === "error") {
57
58
  console.error(message);
58
- }
59
+ }
59
60
 
60
61
  if (this.ps[message.requestId]) {
61
62
  this.ps[message.requestId].resolve(message);
62
63
  delete this.ps[message.requestId];
63
64
  } else {
64
- console.log('unhandled message', message);
65
+ console.log("unhandled message", message);
65
66
  }
66
67
  });
67
-
68
68
  });
69
69
  }
70
70
  }
package/lib/sdk.js CHANGED
@@ -1,11 +1,11 @@
1
1
  const config = require("./config");
2
- const chalk = require("chalk");
3
2
  const session = require("./session");
4
3
 
5
4
  // get the version from package.json
6
5
  const { version } = require("../package.json");
7
6
  const root = config["TD_API_ROOT"];
8
7
  const axios = require("axios");
8
+ const theme = require("./theme");
9
9
 
10
10
  const { logger } = require("./logger");
11
11
 
@@ -14,7 +14,7 @@ let token = null;
14
14
  const outputError = (error) => {
15
15
  logger.error(
16
16
  "API Error: %s (%s)",
17
- chalk.red(
17
+ theme.red(
18
18
  // HTTP status code from Axios
19
19
  error.status ||
20
20
  // ...or an explicit error `reason` set by Sails
@@ -22,7 +22,7 @@ const outputError = (error) => {
22
22
  // ...or default to the error message
23
23
  error.message,
24
24
  ),
25
- chalk.red(
25
+ theme.red(
26
26
  // e.g. "teamNotExist" from Sails' exits
27
27
  error.response?.data?.raw ||
28
28
  // ...or the status text
@@ -74,7 +74,7 @@ const parseBody = async (response, body) => {
74
74
  }
75
75
  return body;
76
76
  } catch (err) {
77
- logger.error(chalk.red("Parsing Error", err));
77
+ logger.error(theme.red("Parsing Error", err));
78
78
  throw err;
79
79
  }
80
80
  };
package/lib/session.js CHANGED
@@ -5,10 +5,8 @@ module.exports = {
5
5
  return session;
6
6
  },
7
7
  set: (s) => {
8
-
9
8
  if (s && !session) {
10
9
  session = s;
11
10
  }
12
-
13
11
  },
14
12
  };
package/lib/system.js CHANGED
@@ -181,7 +181,7 @@ const activeWin = async () => {
181
181
  windows = await activeWindow?.();
182
182
  } catch (e) {
183
183
  console.error("Error getting active window", e);
184
- return "error getting active window, proceed normally";
184
+ return "error getting active window, proceed normally";
185
185
  }
186
186
  return windows;
187
187
  }
package/lib/theme.js ADDED
@@ -0,0 +1,13 @@
1
+ const chalk = require("chalk");
2
+
3
+ module.exports = {
4
+ green: chalk.hex("#b3d334"),
5
+ blue: chalk.hex("#34a3d3"),
6
+ red: chalk.hex("#d33434"),
7
+ yellow: chalk.hex("#ced334"),
8
+ magenta: chalk.hex("#d334b3"),
9
+ cyan: chalk.hex("#34d3d3"),
10
+ dim: chalk.dim,
11
+ gray: chalk.gray,
12
+ white: chalk.white,
13
+ };
@@ -57,7 +57,7 @@ module.exports = async () => {
57
57
  try {
58
58
  const cmd = `gh secret set ${key} --body "${value}"`;
59
59
  execSync(cmd, { stdio: "inherit" });
60
- // eslint-disable-next-line no-unused-vars
60
+ // eslint-disable-next-line no-unused-vars
61
61
  } catch (err) {
62
62
  console.error(`❌ Failed to upload ${key}`);
63
63
  }