@4xeoz/re-entry 0.2.4 → 0.2.5

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 CHANGED
@@ -27,6 +27,10 @@ npx @4xeoz/re-entry install \
27
27
  --codex-cd /absolute/path/to/your/project
28
28
  ```
29
29
 
30
+ The guided screen stays intentionally small: **Workspace → System check → Connect Re-entry**. It
31
+ shows one clear next command when setup finishes; internal Connector IDs, credential paths, and log
32
+ paths stay out of the normal success screen.
33
+
30
34
  Run this from the Host project directory, your home directory, or another normal working
31
35
  directory—not from a checked-out `runtime/local-connector` package directory. npm can treat that
32
36
  source directory as the package itself and fail to create the temporary executable link.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4xeoz/re-entry",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "type": "module",
5
5
  "description": "Outbound Local Connector process for the Re-entry Core local preview.",
6
6
  "publishConfig": {
@@ -8,7 +8,7 @@ import process from "node:process";
8
8
  export async function waitForEnterToOpenBrowser(options = {}) {
9
9
  const input = options.input ?? process.stdin;
10
10
  const output = options.output ?? process.stdout;
11
- const prompt = options.prompt ?? " Press Enter to open Re-entry in your browser: ";
11
+ const prompt = options.prompt ?? "\n Press Enter to open Re-entry ";
12
12
  const readline = createInterface({ input, output });
13
13
  try {
14
14
  await readline.question(prompt);
package/src/main.mjs CHANGED
@@ -149,9 +149,12 @@ function readConnectorVersion() {
149
149
  }
150
150
 
151
151
  function doctor(flags, ui) {
152
- if (ui.interactive) ui.begin("Check this Mac", "Read-only readiness check");
152
+ if (ui.interactive) {
153
+ ui.begin("System check", "Confirm that this Mac is ready for Re-entry.");
154
+ ui.section("CHECK", "Requirements");
155
+ }
153
156
  const readiness = inspectReadiness(flags);
154
- showReadiness(readiness, ui);
157
+ showReadiness(readiness, ui, { detailed: true });
155
158
  if (!ui.interactive) {
156
159
  process.stdout.write(`${JSON.stringify({
157
160
  event: "connector_ready",
@@ -179,21 +182,26 @@ async function withWorkspaceDirectory(flags, ui) {
179
182
  if (flags["codex-cd"] !== undefined || !ui.interactive) {
180
183
  return { ...flags, "codex-cd": flags["codex-cd"] ?? process.cwd() };
181
184
  }
182
- ui.info("Workspace", "choose the folder Codex will open");
183
185
  const selected = await chooseWorkspaceDirectory({ startDirectory: process.cwd() });
184
186
  if (!selected) throw cliFailure("connector_codex_cd_missing");
185
- ui.success("Workspace", selected);
186
187
  return { ...flags, "codex-cd": selected };
187
188
  }
188
189
 
189
- function showReadiness(readiness, ui) {
190
+ function showReadiness(readiness, ui, options = {}) {
190
191
  if (!ui.interactive) return;
191
- ui.success("Node.js", process.versions.node);
192
- ui.success("Codex", `${readiness.installation.version} · ${readiness.installation.executable}`);
193
- if (readiness.workingDirectory) {
194
- ui.success("Host project", readiness.workingDirectory);
195
- } else {
196
- ui.info("Host project", "not selected; pass --codex-cd when starting Codex");
192
+ ui.success("Node.js", `v${process.versions.node}`);
193
+ ui.success(
194
+ "Codex",
195
+ options.detailed
196
+ ? `${readiness.installation.version} · ${readiness.installation.executable}`
197
+ : "ready",
198
+ );
199
+ if (options.includeWorkspace !== false) {
200
+ if (readiness.workingDirectory) {
201
+ ui.success("Workspace", readiness.workingDirectory);
202
+ } else {
203
+ ui.info("Workspace", "selected automatically when Re-entry starts");
204
+ }
197
205
  }
198
206
  }
199
207
 
@@ -215,18 +223,16 @@ async function pair(flags, ui, options = {}) {
215
223
  if (ui.interactive) ui.wait("Contacting Re-entry…");
216
224
  const credentials = await client.pair({ userCode }, async ({ verificationUri }) => {
217
225
  if (ui.interactive) {
218
- ui.stopWait("Re-entry ready", "approval link created");
219
- ui.step("Browser", "press Enter to open the Re-entry approval page");
220
- ui.info("Open this URL", verificationUri);
226
+ ui.stopWait("Secure link", "ready");
227
+ ui.info("Browser link", verificationUri);
221
228
  await waitForEnterToOpenBrowser();
222
- ui.step("Browser", "opening the Re-entry approval page");
223
- ui.wait("Waiting for you to approve this Mac…");
229
+ ui.wait("Waiting for approval in your browser…");
224
230
  } else {
225
231
  process.stdout.write(`${JSON.stringify({ event: "pairing_waiting", verification_uri: verificationUri })}\n`);
226
232
  }
227
233
  });
228
234
  if (ui.interactive) {
229
- ui.stopWait("Approval received", "the Receiver approved this Connector");
235
+ ui.stopWait("Approved", "this Mac is connected");
230
236
  if (!credentials.browserOpened) {
231
237
  ui.warning("Browser", "did not open automatically; use the URL above");
232
238
  }
@@ -240,7 +246,8 @@ async function pair(flags, ui, options = {}) {
240
246
  connector_expires_at: credentials.connector_expires_at,
241
247
  });
242
248
  if (ui.interactive) {
243
- ui.success("This Mac is paired", `credential saved at ${credentialFile}`);
249
+ ui.complete("Pairing complete", "Re-entry can now deliver approved work to this Mac.");
250
+ ui.next("re-entry start", "Wait for approved work in this terminal.");
244
251
  } else {
245
252
  process.stdout.write(`${JSON.stringify({ event: "connector_paired", connector_id: credentials.connector_id })}\n`);
246
253
  }
@@ -257,8 +264,10 @@ async function connect(flags, ui, options = {}) {
257
264
  const currentIsValid = current && Date.parse(current.connector_expires_at) > Date.now();
258
265
  if (currentIsValid && current.receiver_origin === receiver) {
259
266
  if (ui.interactive) {
260
- ui.success("Already connected", `${current.connector_id} · ${current.receiver_origin}`);
261
- ui.info("Next", "run `re-entry start` to wait for approved work");
267
+ ui.success("Account", "already connected");
268
+ if (!options.guidedInstall) {
269
+ ui.next("re-entry start", "Wait for approved work in this terminal.");
270
+ }
262
271
  } else {
263
272
  process.stdout.write(`${JSON.stringify({
264
273
  event: "connector_already_connected",
@@ -274,8 +283,8 @@ async function connect(flags, ui, options = {}) {
274
283
  }
275
284
 
276
285
  if (ui.interactive) {
277
- ui.step("Re-entry", receiver);
278
- ui.step("This Mac", flags["device-name"] ?? defaultDeviceName());
286
+ if (!options.guidedInstall) ui.info("Re-entry", displayReceiver(receiver));
287
+ ui.info("This Mac", flags["device-name"] ?? defaultDeviceName());
279
288
  }
280
289
  const client = new LocalConnectorPairingClient({
281
290
  baseUrl: receiver,
@@ -286,12 +295,10 @@ async function connect(flags, ui, options = {}) {
286
295
  { deviceName: flags["device-name"] ?? defaultDeviceName() },
287
296
  async ({ verificationUri }) => {
288
297
  if (ui.interactive) {
289
- ui.stopWait("Re-entry ready", "secure approval link created");
290
- ui.step("Browser", "press Enter to open Re-entry sign-in and approval");
291
- ui.info("If it does not open", verificationUri);
298
+ ui.stopWait("Secure link", "ready");
299
+ ui.info("Browser link", verificationUri);
292
300
  await waitForEnterToOpenBrowser();
293
- ui.step("Browser", "opening Re-entry sign-in and approval");
294
- ui.wait("Waiting for you to connect this Mac…");
301
+ ui.wait("Waiting for approval in your browser…");
295
302
  } else {
296
303
  process.stdout.write(`${JSON.stringify({
297
304
  event: "connector_authorization_waiting",
@@ -301,7 +308,7 @@ async function connect(flags, ui, options = {}) {
301
308
  },
302
309
  );
303
310
  if (ui.interactive) {
304
- ui.stopWait("Approved", "Re-entry linked this Mac to your account");
311
+ ui.stopWait("Account", "connected");
305
312
  if (!credentials.browserOpened) {
306
313
  ui.warning("Browser", "did not open automatically; use the URL shown above");
307
314
  }
@@ -315,8 +322,10 @@ async function connect(flags, ui, options = {}) {
315
322
  };
316
323
  await store.save(saved);
317
324
  if (ui.interactive) {
318
- ui.success("Connected", `credential saved at ${credentialFile}`);
319
- ui.info("Next", "run `re-entry start` once; it will keep waiting in the background");
325
+ if (!options.guidedInstall) {
326
+ ui.complete("This Mac is connected", "Re-entry can now route approved work here.");
327
+ ui.next("re-entry start", "Wait for approved work in this terminal.");
328
+ }
320
329
  } else {
321
330
  process.stdout.write(`${JSON.stringify({
322
331
  event: "connector_connected",
@@ -327,22 +336,32 @@ async function connect(flags, ui, options = {}) {
327
336
  }
328
337
 
329
338
  async function status(flags, ui) {
330
- if (ui.interactive) ui.begin("Connector status", "Account, background service, Receiver, and Codex");
339
+ if (ui.interactive) ui.begin("Status", "A quick check of this Mac and Re-entry.");
331
340
  const credentialFile = flags["credential-file"] ?? defaultCredentialFile();
332
341
  const credentials = await new LocalConnectorCredentialStore({ filename: credentialFile }).load();
333
342
  const readiness = inspectReadiness(flags);
334
343
  const service = await inspectMacConnectorService();
335
344
  const receiverReady = credentials ? await inspectReceiver(credentials.receiver_origin) : false;
336
- showReadiness(readiness, ui);
337
345
  const connected = Boolean(credentials && Date.parse(credentials.connector_expires_at) > Date.now());
338
346
  if (ui.interactive) {
339
- if (connected) ui.success("Account", `${credentials.connector_id} · authorized`);
340
- else ui.warning("Re-entry", "not connected; run `re-entry connect`");
341
- if (service.running) ui.success("Background", "running at login");
342
- else if (service.installed) ui.warning("Background", "installed but not running; run `re-entry install`");
343
- else ui.warning("Background", "not installed; run `re-entry install`");
344
- if (connected && receiverReady) ui.success("Receiver", `${credentials.receiver_origin} · reachable`);
345
- else if (connected) ui.warning("Receiver", `${credentials.receiver_origin} · unavailable`);
347
+ ui.section("SYSTEM", "This Mac");
348
+ showReadiness(readiness, ui);
349
+ ui.section("CONNECTION", "Re-entry");
350
+ if (connected) ui.success("Account", "connected");
351
+ else ui.warning("Account", "not connected");
352
+ if (service.running) ui.success("Background", "running");
353
+ else if (service.installed) ui.warning("Background", "stopped");
354
+ else ui.warning("Background", "not installed");
355
+ if (connected && receiverReady) ui.success("Cloud", "online");
356
+ else if (connected) ui.warning("Cloud", "unavailable");
357
+
358
+ if (!connected || !service.running) {
359
+ ui.next("re-entry install", "Finish setup and start Re-entry in the background.");
360
+ } else if (!receiverReady) {
361
+ ui.next("re-entry status", "Check again when the Re-entry Cloud service is available.");
362
+ } else {
363
+ ui.complete("Everything looks good", "Re-entry is ready for approved work.");
364
+ }
346
365
  } else {
347
366
  process.stdout.write(`${JSON.stringify({
348
367
  event: "connector_status",
@@ -366,8 +385,9 @@ async function stop(flags, ui) {
366
385
  const result = await stopMacConnectorService();
367
386
  if (ui.interactive) {
368
387
  if (!result.supported) ui.warning("Platform", "background service control currently supports macOS only");
369
- else if (result.stopped) ui.success("Stopped", "the background Connector is no longer running");
388
+ else if (result.stopped) ui.complete("Re-entry is paused", "Your account connection is still saved.");
370
389
  else ui.info("Already stopped", "no running background Connector was found");
390
+ if (result.supported) ui.next("re-entry install", "Start Re-entry in the background again.");
371
391
  } else {
372
392
  process.stdout.write(`${JSON.stringify({
373
393
  event: "connector_stopped",
@@ -389,8 +409,8 @@ async function uninstall(flags, ui) {
389
409
  credentialFile: flags["credential-file"] ?? defaultCredentialFile(),
390
410
  });
391
411
  if (ui.interactive) {
392
- ui.success("Uninstalled", "local Connector service data was removed");
393
- ui.info("Package", "remove the npm package separately with `npm uninstall --global @4xeoz/re-entry`");
412
+ ui.complete("Removed from this Mac", "The local service, connection, and logs are gone.");
413
+ ui.next("npx @4xeoz/re-entry install", "Connect this Mac again whenever you are ready.");
394
414
  } else {
395
415
  process.stdout.write(`${JSON.stringify({
396
416
  event: "connector_uninstalled",
@@ -401,16 +421,18 @@ async function uninstall(flags, ui) {
401
421
  }
402
422
 
403
423
  async function install(flags, ui) {
404
- if (ui.interactive) {
405
- ui.begin("Install Re-entry", "Check Codex, connect your account, then start at login");
406
- ui.info("Setup", "choose a workspace, approve this Mac, then leave the Connector running");
407
- }
408
424
  const runtimeFlags = await withWorkspaceDirectory(flags, ui);
409
- if (ui.interactive) ui.info("Receiver", runtimeFlags.receiver ?? DEFAULT_RECEIVER_ORIGIN);
410
425
  const readiness = inspectReadiness(runtimeFlags);
411
- showReadiness(readiness, ui);
412
- const credentials = await connect(runtimeFlags, ui, { quietHeader: true });
413
- if (ui.interactive) ui.wait("Installing the background Connector…");
426
+ if (ui.interactive) {
427
+ ui.begin("Set up this Mac", "Three quick steps. You only do this once.");
428
+ ui.section("1 OF 3", "Workspace");
429
+ ui.success("Selected", readiness.workingDirectory);
430
+ ui.section("2 OF 3", "System check");
431
+ showReadiness(readiness, ui, { includeWorkspace: false });
432
+ ui.section("3 OF 3", "Connect Re-entry", "Approve this Mac in your browser.");
433
+ }
434
+ const credentials = await connect(runtimeFlags, ui, { quietHeader: true, guidedInstall: true });
435
+ if (ui.interactive) ui.wait("Starting Re-entry in the background…");
414
436
  const service = await installMacConnectorService({
415
437
  nodeExecutable: process.execPath,
416
438
  entrypoint: fileURLToPath(import.meta.url),
@@ -418,11 +440,9 @@ async function install(flags, ui) {
418
440
  credentialFile: flags["credential-file"] ?? defaultCredentialFile(),
419
441
  });
420
442
  if (ui.interactive) {
421
- ui.stopWait("Installed", "Re-entry will start automatically when you log in");
422
- ui.success("Account", credentials.connector_id);
423
- ui.info("Logs", service.stdoutPath);
424
- ui.info("Commands", "status to inspect · stop to pause · uninstall to remove local setup");
425
- ui.info("You are done", "the Connector now waits in the background");
443
+ ui.stopWait("Background", "running at login");
444
+ ui.complete("You're all set", "Re-entry is connected and waiting for approved work.");
445
+ ui.next("re-entry status", "Check the connection at any time.");
426
446
  } else {
427
447
  process.stdout.write(`${JSON.stringify({
428
448
  event: "connector_service_installed",
@@ -435,12 +455,13 @@ async function install(flags, ui) {
435
455
  }
436
456
 
437
457
  async function start(flags, ui) {
438
- if (ui.interactive) {
439
- ui.begin("Re-entry is starting", "Connect once, then wait quietly for work you approve");
440
- }
441
458
  const runtimeFlags = await withWorkspaceDirectory(flags, ui);
442
459
  const readiness = inspectReadiness(runtimeFlags);
443
- showReadiness(readiness, ui);
460
+ if (ui.interactive) {
461
+ ui.begin("Start Re-entry", "Wait for work you have approved.");
462
+ ui.section("READY", "This Mac");
463
+ showReadiness(readiness, ui);
464
+ }
444
465
  if (!ui.interactive) {
445
466
  process.stdout.write(`${JSON.stringify({
446
467
  event: "connector_ready",
@@ -726,6 +747,14 @@ function defaultDeviceName() {
726
747
  : "This Mac";
727
748
  }
728
749
 
750
+ function displayReceiver(origin) {
751
+ try {
752
+ return new URL(origin).host;
753
+ } catch {
754
+ return origin;
755
+ }
756
+ }
757
+
729
758
  function readBoundedNumber(value, minimum, maximum, code) {
730
759
  const number = typeof value === "number" ? value : Number(value);
731
760
  if (!Number.isSafeInteger(number) || number < minimum || number > maximum) {
@@ -8,19 +8,12 @@ const YELLOW = "\u001b[33m";
8
8
  const RED = "\u001b[31m";
9
9
  const CYAN = "\u001b[36m";
10
10
  const SPINNER_FRAMES = ["·", "✦", "✧", "✦"];
11
- const REENTRY_ASCII = [
12
- " ____ _____ _____ _ _ _____ ____ __ __",
13
- " | _ \\| ____| | ____| \\ | | ____| _ \\ \\ \\ / /",
14
- " | |_) | _| _____ | _| | \\| | _| | |_) | \\ V /",
15
- " | _ <| |__|_____| | |___| |\\ | |___| _ < | |",
16
- " |_| \\_\\_____| |_____|_| \\_|_____|_| \\_\\ |_|",
17
- ];
18
- const REENTRY_PANEL = [
19
- " +-----------------------------------------------+",
20
- " | RE-ENTRY |",
21
- " | LOCAL CONNECTOR |",
22
- " +-----------------------------------------------+",
23
- ];
11
+ const RULE = " ─────────────────────────────────────────────";
12
+
13
+ export const REENTRY_WORDMARK = Object.freeze([
14
+ " █▀█ █▀▀ █▀▀ █▄░█ ▀█▀ █▀█ █▄█",
15
+ " █▀▄ ██▄ ██▄ █░▀█ ░█░ █▀▄ ░█░",
16
+ ]);
24
17
 
25
18
  /**
26
19
  * Small dependency-free terminal presentation for the Local Connector CLI.
@@ -36,7 +29,7 @@ export function createTerminalUi(options = {}) {
36
29
  let spinnerFrame = 0;
37
30
 
38
31
  const style = (value, code) => color ? `${code}${value}${RESET}` : value;
39
- const write = (value) => output.write(`${value}\n`);
32
+ const write = (value = "") => output.write(`${value}\n`);
40
33
  const clearSpinnerLine = () => {
41
34
  if (spinnerTimer === null) return;
42
35
  output.write("\r\u001b[2K");
@@ -44,44 +37,56 @@ export function createTerminalUi(options = {}) {
44
37
  spinnerTimer = null;
45
38
  };
46
39
  const renderSpinner = () => {
47
- output.write(`\r\u001b[2K ${style(SPINNER_FRAMES[spinnerFrame], CYAN)} ${spinnerMessage}`);
40
+ output.write(`\r\u001b[2K ${style(SPINNER_FRAMES[spinnerFrame], CYAN)} ${spinnerMessage}`);
48
41
  spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES.length;
49
42
  };
43
+ const renderState = (symbol, symbolColor, label, detail) => {
44
+ clearSpinnerLine();
45
+ write(` ${style(symbol, symbolColor)} ${style(label, BOLD)}${detail ? ` ${style(detail, DIM)}` : ""}`);
46
+ };
50
47
 
51
48
  return Object.freeze({
52
49
  interactive,
53
50
 
54
51
  begin(title, subtitle) {
55
52
  if (!interactive) return;
56
- write("");
57
- for (const line of REENTRY_ASCII) write(style(line, BOLD));
58
- write("");
59
- for (const line of REENTRY_PANEL) write(style(line, BOLD));
60
- write("");
61
- write(` ${style("RE-ENTRY", BOLD)} ${style("LOCAL CONNECTOR", DIM)}`);
53
+ clearSpinnerLine();
54
+ write();
55
+ for (const line of REENTRY_WORDMARK) write(style(line, `${BOLD}${CYAN}`));
56
+ write(` ${style("LOCAL CONNECTOR", DIM)}`);
57
+ write();
62
58
  write(` ${style(title, BOLD)}`);
63
59
  if (subtitle) write(` ${style(subtitle, DIM)}`);
64
- write("");
60
+ write(RULE);
61
+ },
62
+
63
+ section(step, title, detail) {
64
+ if (!interactive) return;
65
+ clearSpinnerLine();
66
+ write();
67
+ write(` ${style(step, CYAN)} ${style(title, BOLD)}`);
68
+ if (detail) write(` ${style(detail, DIM)}`);
69
+ write();
65
70
  },
66
71
 
67
72
  step(label, detail) {
68
73
  if (!interactive) return;
69
- write(` ${style("→", CYAN)} ${style(label, BOLD)}${detail ? ` ${detail}` : ""}`);
74
+ renderState("→", CYAN, label, detail);
70
75
  },
71
76
 
72
77
  success(label, detail) {
73
78
  if (!interactive) return;
74
- write(` ${style("✓", GREEN)} ${style(label, BOLD)}${detail ? ` ${detail}` : ""}`);
79
+ renderState("✓", GREEN, label, detail);
75
80
  },
76
81
 
77
82
  info(label, detail) {
78
83
  if (!interactive) return;
79
- write(` ${style("·", CYAN)} ${style(label, BOLD)}${detail ? ` ${detail}` : ""}`);
84
+ renderState("·", CYAN, label, detail);
80
85
  },
81
86
 
82
87
  warning(label, detail) {
83
88
  if (!interactive) return;
84
- write(` ${style("!", YELLOW)} ${style(label, BOLD)}${detail ? ` ${detail}` : ""}`);
89
+ renderState("!", YELLOW, label, detail);
85
90
  },
86
91
 
87
92
  wait(message) {
@@ -97,16 +102,38 @@ export function createTerminalUi(options = {}) {
97
102
  stopWait(label, detail, outcome = "success") {
98
103
  if (!interactive) return;
99
104
  clearSpinnerLine();
100
- if (outcome === "warning") this.warning(label, detail);
101
- else if (outcome === "info") this.info(label, detail);
102
- else this.success(label, detail);
105
+ if (outcome === "warning") renderState("!", YELLOW, label, detail);
106
+ else if (outcome === "info") renderState("·", CYAN, label, detail);
107
+ else renderState("✓", GREEN, label, detail);
108
+ },
109
+
110
+ complete(title, detail) {
111
+ if (!interactive) return;
112
+ clearSpinnerLine();
113
+ write();
114
+ write(` ${style("✓", GREEN)} ${style(title, BOLD)}`);
115
+ if (detail) write(` ${style(detail, DIM)}`);
116
+ },
117
+
118
+ next(command, detail) {
119
+ if (!interactive) return;
120
+ clearSpinnerLine();
121
+ write();
122
+ write(` ${style("NEXT", CYAN)}`);
123
+ write(` ${style("$", CYAN)} ${style(command, BOLD)}`);
124
+ if (detail) write(` ${style(detail, DIM)}`);
125
+ write();
103
126
  },
104
127
 
105
128
  error(label, detail, hint) {
106
129
  if (!interactive) return;
107
130
  clearSpinnerLine();
108
- errorOutput.write(` ${style("✕", RED)} ${style(label, BOLD)}${detail ? ` ${detail}` : ""}\n`);
109
- if (hint) errorOutput.write(` ${style("Next:", DIM)} ${hint}\n`);
131
+ errorOutput.write(`\n ${style("✕", RED)} ${style(label, BOLD)}\n`);
132
+ if (detail) errorOutput.write(` ${style(detail, DIM)}\n`);
133
+ if (hint) {
134
+ errorOutput.write(`\n ${style("NEXT", CYAN)}\n`);
135
+ errorOutput.write(` ${style("→", CYAN)} ${hint}\n\n`);
136
+ }
110
137
  },
111
138
 
112
139
  close() {
@@ -4,6 +4,8 @@ import { dirname, join, resolve } from "node:path";
4
4
  import { emitKeypressEvents } from "node:readline";
5
5
  import process from "node:process";
6
6
 
7
+ import { REENTRY_WORDMARK } from "./terminal-ui.mjs";
8
+
7
9
  const MAX_VISIBLE_DIRECTORIES = 12;
8
10
 
9
11
  /**
@@ -77,7 +79,7 @@ export async function chooseWorkspaceDirectory(options = {}) {
77
79
  }
78
80
  } finally {
79
81
  input.setRawMode(wasRaw);
80
- output.write("\n");
82
+ output.write("\u001b[2J\u001b[H");
81
83
  }
82
84
  }
83
85
 
@@ -158,19 +160,22 @@ async function readableDirectories(directory) {
158
160
 
159
161
  function renderPicker(output, { title, current, choices, selected, truncated = false }) {
160
162
  output.write("\u001b[2J\u001b[H");
161
- output.write("RE-ENTRY WORKSPACE\n\n");
162
- output.write(`${title}\n`);
163
- if (current) output.write(`Current folder: ${current}\n`);
163
+ for (const line of REENTRY_WORDMARK) output.write(`${line}\n`);
164
+ output.write(" LOCAL CONNECTOR\n\n");
165
+ output.write(" 1 OF 3 WORKSPACE\n");
166
+ output.write(` ${title}\n`);
167
+ if (current) output.write(` Current: ${current}\n`);
168
+ output.write(" ─────────────────────────────────────────────\n");
164
169
  output.write("\n");
165
170
  for (let index = 0; index < choices.length; index += 1) {
166
171
  const choice = choices[index];
167
- output.write(`${index === selected ? "❯" : " "} ${choice.label}\n`);
168
- if (choice.detail) output.write(` ${choice.detail}\n`);
172
+ output.write(` ${index === selected ? "❯" : " "} ${choice.label}\n`);
173
+ if (choice.detail) output.write(` ${choice.detail}\n`);
169
174
  }
170
175
  if (truncated) {
171
- output.write(`\nShowing the first ${MAX_VISIBLE_DIRECTORIES} folders. Open a folder to continue.\n`);
176
+ output.write(`\n Showing the first ${MAX_VISIBLE_DIRECTORIES} folders.\n`);
172
177
  }
173
- output.write("\n↑/↓ Move Enter Select Esc Cancel");
178
+ output.write("\n ↑↓ Move Enter Select Esc Cancel");
174
179
  }
175
180
 
176
181
  function readKey(input) {