sdc-build-wp 5.2.0 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/build.js CHANGED
@@ -2,9 +2,20 @@ import { default as project } from './project.js';
2
2
  import * as utils from './utils.js';
3
3
  import log from './logging.js';
4
4
  import chalk from 'chalk';
5
+ import tui from './tui.js';
5
6
 
6
7
 
7
8
  export async function build(watch = false) {
9
+
10
+ if (watch) {
11
+ tui.init();
12
+ tui.setComponents(project.builds, true);
13
+ const commands = `Commands: ${chalk.underline.green('r')}estart, ${chalk.underline.green('c')}lear cache, ${chalk.underline.green('p')}ause/resume, ${chalk.underline.green('n')}ew component, ${chalk.underline.green('q')}uit`;
14
+ tui.setCommands(commands);
15
+ }
16
+
17
+ log('info', `Started sdc-build-wp`);
18
+
8
19
  if (project.builds.includes('cache')) {
9
20
  try {
10
21
  await project.components.cache.init();
@@ -44,15 +55,18 @@ export async function build(watch = false) {
44
55
  }
45
56
 
46
57
  utils.clearScreen();
47
- log('info', `Finished initial build in ${Math.round((performance.now() - initialBuildTimerStart) / 1000)} seconds`);
48
58
 
49
59
  if (watch && project.builds.includes('server')) {
50
60
  project.isRunning = true;
51
61
  project.builds.splice(project.builds.indexOf('server'), 1);
52
62
  project.builds.push('server');
63
+
64
+ log('info', `Finished initial build in ${Math.round((performance.now() - initialBuildTimerStart) / 1000)} seconds`);
53
65
  log('info', `Started watching [${project.builds.join(', ')}]`);
66
+
67
+ tui.setComponents(project.builds, true);
68
+
54
69
  project.components.server.logURLs();
55
- log('info', `${chalk.underline.green('r')}estart, ${chalk.underline.green('c')}lear cache, ${chalk.underline.green('p')}ause/resume, ${chalk.underline.green('n')}ew component, ${chalk.underline.green('q')}uit`);
56
70
 
57
71
  for (let build of project.builds) {
58
72
  try {
@@ -63,6 +77,7 @@ export async function build(watch = false) {
63
77
  }
64
78
  }
65
79
  } else {
80
+ log('info', `Finished initial build in ${Math.round((performance.now() - initialBuildTimerStart) / 1000)} seconds`);
66
81
  process.emit('SIGINT');
67
82
  }
68
83
  }
@@ -2,6 +2,7 @@ import BaseComponent from './base.js';
2
2
  import * as esbuild from 'esbuild';
3
3
  import { ESLint } from 'eslint';
4
4
  import * as eslintConfig from '../../eslint.config.js';
5
+ import tui from '../tui.js';
5
6
 
6
7
  export default class ScriptsComponent extends BaseComponent {
7
8
 
@@ -35,7 +36,11 @@ export default class ScriptsComponent extends BaseComponent {
35
36
  throw thisLint;
36
37
  }
37
38
  } catch (error) {
38
- console.error(error);
39
+ if (tui.isInitialized) {
40
+ tui.log(String(error.stack || error));
41
+ } else {
42
+ console.error(error);
43
+ }
39
44
  this.log('error', `Failed linting ${entry.replace(`${this.project.path}/${this.project.paths.src.src}/${this.project.paths.src.scripts}/`, '')} - See above error.`);
40
45
  return false;
41
46
  }
@@ -72,7 +77,11 @@ export default class ScriptsComponent extends BaseComponent {
72
77
 
73
78
  await this.updateBuildCache(entry, outFile, dependencies);
74
79
  } catch (error) {
75
- console.error(error);
80
+ if (tui.isInitialized) {
81
+ tui.log(String(error.stack || error));
82
+ } else {
83
+ console.error(error);
84
+ }
76
85
  this.log('error', `Failed building ${entryLabel} - See above error.`);
77
86
  return false;
78
87
  }
@@ -103,7 +112,11 @@ export default class ScriptsComponent extends BaseComponent {
103
112
  await this.checkAndRebuildAffectedBlocks(path);
104
113
  }
105
114
  } catch (error) {
106
- console.error(error);
115
+ if (tui.isInitialized) {
116
+ tui.log(String(error.stack || error));
117
+ } else {
118
+ console.error(error);
119
+ }
107
120
  this.log('error', `Failed to process scripts`);
108
121
  }
109
122
  });
@@ -121,7 +134,11 @@ export default class ScriptsComponent extends BaseComponent {
121
134
  affectedBlocks.add(blockPath);
122
135
  }
123
136
  } catch (error) {
124
- console.error(error);
137
+ if (tui.isInitialized) {
138
+ tui.log(String(error.stack || error));
139
+ } else {
140
+ console.error(error);
141
+ }
125
142
  }
126
143
  }
127
144
 
@@ -149,10 +166,25 @@ export default class ScriptsComponent extends BaseComponent {
149
166
  await ESLint.outputFixes(lintresults);
150
167
  const formatter = await eslint.loadFormatter('stylish');
151
168
  const formatterOutput = formatter.format(lintresults);
152
- if (formatterOutput) { console.log(formatterOutput.replace(`${this.project.path}/${this.project.paths.src.src}/${this.project.paths.src.scripts}/`, '')); }
169
+ if (formatterOutput) {
170
+ const cleanedOutput = formatterOutput.replace(`${this.project.path}/${this.project.paths.src.src}/${this.project.paths.src.scripts}/`, '');
171
+ if (tui.isInitialized) {
172
+ cleanedOutput.split('\n').forEach(line => {
173
+ if (line.trim()) {
174
+ tui.log(line);
175
+ }
176
+ });
177
+ } else {
178
+ console.log(cleanedOutput);
179
+ }
180
+ }
153
181
  return true;
154
182
  } catch (error) {
155
- console.error(error);
183
+ if (tui.isInitialized) {
184
+ tui.log(String(error.stack || error));
185
+ } else {
186
+ console.error(error);
187
+ }
156
188
  return error;
157
189
  }
158
190
  }
@@ -4,6 +4,7 @@ import { fileURLToPath } from 'url';
4
4
  import { readFile } from 'fs/promises';
5
5
  import { create } from 'browser-sync';
6
6
  import chalk from 'chalk';
7
+ import tui from '../tui.js';
7
8
 
8
9
  export default class ServerComponent extends BaseComponent {
9
10
 
@@ -115,9 +116,14 @@ export default class ServerComponent extends BaseComponent {
115
116
  if (this.usedOptions.proxy) {
116
117
  localURL = localURL.replace('localhost', this.usedOptions.proxy.url.host);
117
118
  }
118
- this.log('info', `Local server: ${chalk.green(localURL)} (${this.usedOptions.urls.local})`);
119
- if (this.usedOptions.urls.external) {
120
- this.log('info', `External server: ${chalk.green(this.usedOptions.urls.external)}`);
119
+
120
+ if (tui.isInitialized) {
121
+ tui.setURLs(localURL, this.usedOptions.urls.external || '');
122
+ } else {
123
+ this.log('info', `Local server: ${chalk.green(localURL)} (${this.usedOptions.urls.local})`);
124
+ if (this.usedOptions.urls.external) {
125
+ this.log('info', `External server: ${chalk.green(this.usedOptions.urls.external)}`);
126
+ }
121
127
  }
122
128
  }
123
129
 
package/lib/logging.js CHANGED
@@ -2,59 +2,45 @@
2
2
  // https://github.com/callmenick/node-pretty-log
3
3
  import chalk from 'chalk';
4
4
  import { default as project } from './project.js';
5
+ import tui from './tui.js';
5
6
 
6
7
  function getTime() {
7
8
  return new Date().toLocaleTimeString('en-US');
8
9
  }
9
10
 
10
11
  function log(type, ...messages) {
12
+ let icon, time, prefix = '';
13
+
11
14
  switch (type) {
12
15
  case 'success':
13
- console.log.call(
14
- console,
15
- chalk.green('✔'),
16
- chalk.gray(getTime()),
17
- ...messages
18
- );
16
+ icon = chalk.green('✔');
17
+ time = chalk.gray(getTime());
19
18
  break;
20
19
  case 'error':
21
- console.log.call(
22
- console,
23
- chalk.red('✖'),
24
- chalk.bgRed.gray(getTime()),
25
- ...messages
26
- );
20
+ icon = chalk.red('✖');
21
+ time = chalk.bgRed.gray(getTime());
27
22
  if (project.builds.includes('server') && project.isRunning) {
28
23
  project.components.server.server.notify('ERROR', 2500);
29
24
  }
30
25
  break;
31
26
  case 'warn':
32
- console.log.call(
33
- console,
34
- chalk.yellow('⚠'),
35
- chalk.bgYellow.gray(getTime()),
36
- ...messages
37
- );
27
+ icon = chalk.yellow('⚠');
28
+ time = chalk.bgYellow.gray(getTime());
38
29
  break;
39
30
  case 'php':
40
- console.log.call(
41
- console,
42
- chalk.blue(''),
43
- chalk.gray(getTime()),
44
- chalk.gray('PHP: '),
45
- ...messages
46
- );
31
+ icon = chalk.blue('ℹ');
32
+ time = chalk.gray(getTime());
33
+ prefix = chalk.gray('PHP: ');
47
34
  break;
48
35
  case 'info':
49
36
  default:
50
- console.log.call(
51
- console,
52
- chalk.blue('ℹ'),
53
- chalk.bgBlue.gray(getTime()),
54
- ...messages
55
- );
37
+ icon = chalk.blue('ℹ');
38
+ time = chalk.bgBlue.gray(getTime());
56
39
  break;
57
40
  }
41
+
42
+ const logMessage = [icon, time, prefix, ...messages].filter(Boolean).join(' ');
43
+ tui.log(logMessage);
58
44
  }
59
45
 
60
46
  export default log;
package/lib/project.js CHANGED
@@ -11,7 +11,7 @@ import log from './logging.js';
11
11
  import * as LibComponents from './components/index.js';
12
12
  import help from './help.js';
13
13
  import { validateConfig, mergeWithDefaults } from './config-validator.js';
14
- import { input, select } from '@inquirer/prompts';
14
+ import tui from './tui.js';
15
15
 
16
16
  let project = {
17
17
  config: {},
@@ -163,12 +163,19 @@ export async function init() {
163
163
  await project.configWatcher.close();
164
164
  project.configWatcher = null;
165
165
  }
166
+ tui.destroy();
167
+ if (tui.getLogHistory) {
168
+ const logDump = tui.getLogHistory();
169
+ if (logDump && logDump.trim()) {
170
+ console.log(logDump);
171
+ }
172
+ }
166
173
  log('info', `Exited sdc-build-wp`);
167
174
  if (process.stdin.isTTY) {
168
175
  process.stdin.setRawMode(false);
169
176
  process.stdin.pause();
170
177
  }
171
- process.exit(0);
178
+ setTimeout(() => process.exit(0), 100);
172
179
  });
173
180
 
174
181
  }
@@ -180,7 +187,9 @@ export function keypressListen() {
180
187
 
181
188
  const installRaw = () => {
182
189
  if (!process.stdin.isTTY) return;
183
- try { process.stdin.setRawMode(true); } catch {}
190
+ if (!tui.isInitialized) {
191
+ try { process.stdin.setRawMode(true); } catch {}
192
+ }
184
193
  process.stdin.resume();
185
194
  process.stdin.setEncoding('utf8');
186
195
  };
@@ -202,8 +211,10 @@ export function keypressListen() {
202
211
  utils.clearScreen();
203
212
  if (project.isRunning) {
204
213
  log('success', 'Resumed build process');
214
+ tui.setPaused(false);
205
215
  } else {
206
216
  log('warn', 'Paused build process');
217
+ tui.setPaused(true);
207
218
  }
208
219
  break;
209
220
  case 'c':
@@ -216,8 +227,8 @@ export function keypressListen() {
216
227
  case 'n': // New menu
217
228
  isPrompting = true;
218
229
  process.stdin.removeListener('data', handler);
230
+
219
231
  try {
220
- try { process.stdin.setRawMode(false); } catch {}
221
232
  await handleCreateNew();
222
233
  } finally {
223
234
  isPrompting = false;
@@ -235,28 +246,21 @@ async function handleCreateNew() {
235
246
  if (!project.isRunning) {
236
247
  log('warn', 'Build process paused. Press [p] to resume if needed. Continuing creation.');
237
248
  }
238
- let typeKey;
239
- try {
240
- typeKey = await select({
241
- message: 'Create new:',
242
- choices: [
243
- { name: 'Block', value: 'b' },
244
- { name: 'Pattern', value: 'p' },
245
- { name: 'Style variation', value: 's' },
246
- { name: 'Cancel', value: 'cancel' }
247
- ]
248
- });
249
- } catch (error) {
250
- return;
251
- }
252
- if (typeKey === 'cancel') { return; }
249
+
250
+
251
+ const menuOptions = ['Block', 'Pattern', 'Style variation', 'Cancel'];
252
+ const menuMap = { Block: 'b', Pattern: 'p', 'Style variation': 's', Cancel: 'cancel' };
253
+ const menuPrompt = 'Create new:';
254
+ const blockPrompt = 'Block name:';
255
+ const patternPrompt = 'Pattern name:';
256
+ const stylePrompt = 'Style variation name:';
257
+
258
+ let menuResult = await tui.showMenu(menuOptions, menuPrompt);
259
+ if (!menuResult || menuMap[menuResult.value] === 'cancel') return;
260
+ let typeKey = menuMap[menuResult.value];
261
+
253
262
  if (typeKey === 'b') {
254
- let name;
255
- try {
256
- name = await input({ message: 'Block name:' });
257
- } catch (error) {
258
- return;
259
- }
263
+ let name = await tui.showInput(blockPrompt);
260
264
  if (!name) { log('warn', 'No name provided.'); return; }
261
265
  const slug = utils.slugify(name);
262
266
  const blockDir = `${project.path}/blocks/${slug}`;
@@ -290,8 +294,7 @@ async function handleCreateNew() {
290
294
  log('error', `Failed to scaffold block`);
291
295
  }
292
296
  } else if (typeKey === 'p') {
293
- let name;
294
- try { name = await input({ message: 'Pattern name:' }); } catch (error) { return; }
297
+ let name = await tui.showInput(patternPrompt);
295
298
  if (!name) { log('warn', 'No name provided.'); return; }
296
299
  const slug = utils.slugify(name);
297
300
  const patternsDir = `${project.path}/patterns`;
@@ -322,8 +325,7 @@ async function handleCreateNew() {
322
325
  log('error', `Failed to create pattern`);
323
326
  }
324
327
  } else if (typeKey === 's') {
325
- let name;
326
- try { name = await input({ message: 'Style variation name:' }); } catch (error) { return; }
328
+ let name = await tui.showInput(stylePrompt);
327
329
  if (!name) { log('warn', 'No name provided.'); return; }
328
330
  const slug = utils.slugify(name);
329
331
  const stylesDir = `${project.path}/styles`;
@@ -334,7 +336,7 @@ async function handleCreateNew() {
334
336
  log('warn', `Style variation ${slug}.json already exists.`);
335
337
  return;
336
338
  } catch (error) {
337
-
339
+ //
338
340
  }
339
341
  try {
340
342
  const libDir = path.dirname(fileURLToPath(import.meta.url));
package/lib/tui.js ADDED
@@ -0,0 +1,344 @@
1
+ import blessed from 'blessed';
2
+ import chalk from 'chalk';
3
+
4
+ class TUI {
5
+ constructor() {
6
+ this.screen = null;
7
+ this.headerBox = null;
8
+ this.logBox = null;
9
+ this.isInitialized = false;
10
+ this.urls = {
11
+ local: '',
12
+ external: ''
13
+ };
14
+ this.commands = '';
15
+ this.components = [];
16
+ this.watchMode = false;
17
+ this.isPaused = false;
18
+ this._logHistory = [];
19
+ }
20
+
21
+ init() {
22
+ if (this.isInitialized) {
23
+ return;
24
+ }
25
+
26
+ this.screen = blessed.screen({
27
+ smartCSR: true,
28
+ fullUnicode: true,
29
+ title: 'SDC Build WP',
30
+ input: process.stdin,
31
+ output: process.stdout
32
+ });
33
+
34
+ this.headerBox = blessed.box({
35
+ top: 0,
36
+ left: 0,
37
+ width: '100%',
38
+ height: 5,
39
+ content: '',
40
+ tags: true,
41
+ style: {
42
+ fg: 'white',
43
+ bg: 'black',
44
+ border: {
45
+ fg: 'blue'
46
+ }
47
+ },
48
+ border: {
49
+ type: 'line',
50
+ bottom: true
51
+ },
52
+ shrink: false,
53
+ scrollable: false
54
+ });
55
+
56
+ this.logBox = blessed.log({
57
+ top: 5,
58
+ left: 0,
59
+ width: '100%',
60
+ height: '100%-5',
61
+ tags: true,
62
+ scrollable: true,
63
+ alwaysScroll: true,
64
+ scrollbar: {
65
+ ch: ' ',
66
+ track: {
67
+ bg: 'blue'
68
+ },
69
+ style: {
70
+ inverse: true
71
+ }
72
+ },
73
+ mouse: true,
74
+ keys: true,
75
+ vi: true,
76
+ style: {
77
+ fg: 'white',
78
+ bg: 'black'
79
+ }
80
+ });
81
+
82
+ this.screen.append(this.logBox);
83
+ this.screen.append(this.headerBox);
84
+
85
+ this.screen.on('resize', () => {
86
+ this.updateHeader();
87
+ this.screen.render();
88
+ });
89
+
90
+ this.screen.key(['escape', 'q', 'C-c'], () => {
91
+ return false;
92
+ });
93
+
94
+ this.screen.key(['enter', 'return'], () => {
95
+ this.logBox.log('');
96
+ this.screen.render();
97
+ });
98
+
99
+ this.screen.key(['down'], () => {
100
+ this.logBox.scroll(1);
101
+ this.screen.render();
102
+ });
103
+
104
+ this.screen.key(['up'], () => {
105
+ this.logBox.scroll(-1);
106
+ this.screen.render();
107
+ });
108
+
109
+ this.screen.key(['pagedown'], () => {
110
+ this.logBox.scroll(this.logBox.height);
111
+ this.screen.render();
112
+ });
113
+
114
+ this.screen.key(['pageup'], () => {
115
+ this.logBox.scroll(-this.logBox.height);
116
+ this.screen.render();
117
+ });
118
+
119
+ this.updateHeader();
120
+ this.screen.render();
121
+
122
+ this.isInitialized = true;
123
+ }
124
+
125
+ updateHeader() {
126
+ if (!this.isInitialized) {
127
+ return;
128
+ }
129
+
130
+ const lines = [];
131
+
132
+ let titleLine = ' ' + chalk.bold.blue('SDC Build WP');
133
+ if (this.watchMode) {
134
+ titleLine += chalk.gray(' (watch mode)');
135
+ }
136
+ if (this.isPaused) {
137
+ titleLine += chalk.bold.yellow(' [PAUSED]');
138
+ }
139
+ if (this.components.length > 0) {
140
+ titleLine += chalk.gray(' [') + chalk.cyan(this.components.join(', ')) + chalk.gray(']');
141
+ }
142
+ lines.push(titleLine);
143
+
144
+ if (this.urls.local || this.urls.external) {
145
+ let urlLine = ' ';
146
+ if (this.urls.local) {
147
+ urlLine += `Local: ${chalk.green(this.urls.local)}`;
148
+ }
149
+ if (this.urls.external) {
150
+ if (urlLine.length > 1) urlLine += ' ';
151
+ urlLine += `External: ${chalk.green(this.urls.external)}`;
152
+ }
153
+ lines.push(urlLine);
154
+ } else {
155
+ lines.push(' ');
156
+ }
157
+
158
+ if (this.commands) {
159
+ lines.push(' ' + this.commands);
160
+ } else {
161
+ lines.push(' ');
162
+ }
163
+
164
+ lines.push(' ');
165
+
166
+ this.headerBox.setContent(lines.join('\n'));
167
+ }
168
+
169
+ setURLs(local, external) {
170
+ this.urls.local = local;
171
+ this.urls.external = external;
172
+ this.updateHeader();
173
+ this.render();
174
+ }
175
+
176
+ setCommands(commands) {
177
+ this.commands = commands;
178
+ this.updateHeader();
179
+ this.render();
180
+ }
181
+
182
+ setPaused(isPaused) {
183
+ this.isPaused = isPaused;
184
+ this.updateHeader();
185
+ this.render();
186
+ }
187
+
188
+ setComponents(components, watchMode = false) {
189
+ this.components = components;
190
+ this.watchMode = watchMode;
191
+ this.updateHeader();
192
+ this.render();
193
+ }
194
+
195
+ log(message) {
196
+ this._logHistory.push(message);
197
+ if (!this.isInitialized) {
198
+ console.log(message);
199
+ return;
200
+ }
201
+ this.logBox.log(message);
202
+ this.render();
203
+ }
204
+
205
+ getLogHistory() {
206
+ return this._logHistory.join('\n');
207
+ }
208
+
209
+ render() {
210
+ if (this.isInitialized && this.screen) {
211
+ this.screen.render();
212
+ }
213
+ }
214
+
215
+ async showMenu(options, prompt = 'Choose an option:') {
216
+ return new Promise((resolve) => {
217
+ const menu = blessed.list({
218
+ parent: this.screen,
219
+ top: 'center',
220
+ left: 'center',
221
+ width: '50%',
222
+ height: options.length + 4,
223
+ label: ` ${prompt} `,
224
+ items: options,
225
+ keys: true,
226
+ mouse: true,
227
+ border: 'line',
228
+ style: {
229
+ fg: 'white',
230
+ bg: 'black',
231
+ border: { fg: 'blue' },
232
+ selected: { bg: 'blue', fg: 'white' }
233
+ }
234
+ });
235
+ menu.focus();
236
+ const stopLogScroll = (ch, key) => {
237
+ if (['up', 'down', 'pagedown', 'pageup'].includes(key.name)) {
238
+ return false;
239
+ }
240
+ };
241
+ this.logBox.ignoreKeys = true;
242
+ menu.on('detach', () => {
243
+ this.logBox.ignoreKeys = false;
244
+ });
245
+ menu.on('keypress', stopLogScroll);
246
+ this.screen.render();
247
+ menu.on('select', (item, idx) => {
248
+ menu.destroy();
249
+ this.screen.render();
250
+ resolve({ value: item.getText(), index: idx });
251
+ });
252
+ menu.on('cancel', () => {
253
+ menu.destroy();
254
+ this.screen.render();
255
+ resolve(null);
256
+ });
257
+ menu.key(['escape', 'q'], () => {
258
+ menu.emit('cancel');
259
+ });
260
+ });
261
+ }
262
+
263
+ async showInput(prompt = 'Enter value:') {
264
+ return new Promise((resolve) => {
265
+ const box = blessed.box({
266
+ parent: this.screen,
267
+ top: 'center',
268
+ left: 'center',
269
+ width: '50%',
270
+ height: 5,
271
+ label: ` ${prompt} `,
272
+ border: 'line',
273
+ style: {
274
+ fg: 'white',
275
+ bg: 'black',
276
+ border: { fg: 'blue' }
277
+ }
278
+ });
279
+ const input = blessed.textbox({
280
+ parent: box,
281
+ top: 2,
282
+ left: 2,
283
+ width: '90%',
284
+ height: 1,
285
+ inputOnFocus: true,
286
+ style: {
287
+ fg: 'white',
288
+ bg: 'black',
289
+ focus: { bg: 'blue' }
290
+ }
291
+ });
292
+ input.focus();
293
+ this.screen.render();
294
+ input.on('submit', (value) => {
295
+ box.destroy();
296
+ this.screen.render();
297
+ resolve(value);
298
+ });
299
+ input.on('cancel', () => {
300
+ box.destroy();
301
+ this.screen.render();
302
+ resolve(null);
303
+ });
304
+ input.key(['escape', 'q'], () => {
305
+ input.emit('cancel');
306
+ });
307
+ });
308
+ }
309
+
310
+ getState() {
311
+ return {
312
+ urls: { ...this.urls },
313
+ commands: this.commands,
314
+ components: [...this.components],
315
+ watchMode: this.watchMode,
316
+ isPaused: this.isPaused
317
+ };
318
+ }
319
+
320
+ setState(state) {
321
+ if (state) {
322
+ this.urls = { ...state.urls };
323
+ this.commands = state.commands;
324
+ this.components = [...state.components];
325
+ this.watchMode = state.watchMode;
326
+ this.isPaused = state.isPaused;
327
+ this.updateHeader();
328
+ this.render();
329
+ }
330
+ }
331
+
332
+ destroy() {
333
+ if (this.isInitialized && this.screen) {
334
+ this.screen.destroy();
335
+ this.isInitialized = false;
336
+ this.screen = null;
337
+ this.headerBox = null;
338
+ this.logBox = null;
339
+ }
340
+ }
341
+ }
342
+
343
+ const tui = new TUI();
344
+ export default tui;
package/lib/utils.js CHANGED
@@ -4,6 +4,7 @@ import { readdir } from 'node:fs/promises';
4
4
  import { fileURLToPath } from 'url';
5
5
  import project from './project.js';
6
6
  import log from './logging.js';
7
+ import tui from './tui.js';
7
8
 
8
9
  export async function getThisPackageVersion() {
9
10
  return JSON.parse(await fs.readFile(path.join(path.dirname(fileURLToPath(import.meta.url)), '../package.json'))).version
@@ -11,6 +12,7 @@ export async function getThisPackageVersion() {
11
12
 
12
13
  export function clearScreen() {
13
14
  if (!process.stdout.isTTY) { return; }
15
+ if (tui.isInitialized) { return; }
14
16
  process.stdout.write('\x1B[2J\x1B[0f');
15
17
  }
16
18
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sdc-build-wp",
3
- "version": "5.2.0",
3
+ "version": "5.3.0",
4
4
  "description": "Custom WordPress build process.",
5
5
  "engines": {
6
6
  "node": ">=22"
@@ -22,13 +22,13 @@
22
22
  "sdc-build-wp": "./index.js"
23
23
  },
24
24
  "dependencies": {
25
- "@inquirer/prompts": "^7.9.0",
26
25
  "@stylistic/eslint-plugin": "^5.4.0",
27
26
  "@stylistic/stylelint-plugin": "^4.0.0",
28
27
  "@typescript-eslint/eslint-plugin": "^8.46.1",
29
28
  "@typescript-eslint/parser": "^8.46.1",
30
29
  "@wordpress/scripts": "^30.25.0",
31
30
  "autoprefixer": "^10.4.21",
31
+ "blessed": "^0.1.81",
32
32
  "browser-sync": "^3.0.4",
33
33
  "chalk": "^5.6.2",
34
34
  "chokidar": "^4.0.3",