@vibescore/tracker 0.2.5 → 0.2.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibescore/tracker",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "Codex CLI token usage tracker (macOS-first, notify-driven).",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -34,14 +34,11 @@ const {
34
34
  CYAN,
35
35
  RESET,
36
36
  color,
37
- underline,
38
- renderBox,
39
37
  isInteractive,
40
38
  promptMenu,
41
- promptEnter,
42
- createSpinner,
43
- formatSummaryLine
39
+ createSpinner
44
40
  } = require('../lib/cli-ui');
41
+ const { renderLocalReport, renderAuthTransition, renderSuccessBox } = require('../lib/init-flow');
45
42
 
46
43
  const ASCII_LOGO = [
47
44
  '██╗ ██╗██╗██████╗ ███████╗███████╗ ██████╗ ██████╗ ██████╗ ███████╗',
@@ -80,11 +77,12 @@ async function cmdInit(argv) {
80
77
 
81
78
  if (isInteractive() && !opts.yes && !opts.dryRun) {
82
79
  const choice = await promptMenu({
83
- message: '? How would you like to proceed?',
84
- options: ['Start Setup (Recommended)', 'Exit'],
80
+ message: '? Proceed with installation?',
81
+ options: ['Yes, configure my environment', 'No, exit'],
85
82
  defaultIndex: 0
86
83
  });
87
- if (choice.toLowerCase().startsWith('exit')) {
84
+ const normalizedChoice = String(choice || '').trim().toLowerCase();
85
+ if (normalizedChoice.startsWith('no') || normalizedChoice.includes('exit')) {
88
86
  process.stdout.write('Setup cancelled.\n');
89
87
  return;
90
88
  }
@@ -98,7 +96,7 @@ async function cmdInit(argv) {
98
96
  configPath,
99
97
  notifyPath
100
98
  });
101
- renderTransparencyReport({ summary: preview.summary, isDryRun: true });
99
+ renderLocalReport({ summary: preview.summary, isDryRun: true });
102
100
  if (preview.pendingBrowserAuth) {
103
101
  process.stdout.write('Account linking would be required for full setup.\n');
104
102
  } else if (!preview.deviceToken) {
@@ -130,11 +128,7 @@ async function cmdInit(argv) {
130
128
  }
131
129
  spinner.stop();
132
130
 
133
- renderTransparencyReport({
134
- summary: setup.summary,
135
- isDryRun: false,
136
- includeDivider: setup.pendingBrowserAuth
137
- });
131
+ renderLocalReport({ summary: setup.summary, isDryRun: false });
138
132
 
139
133
  let deviceToken = setup.deviceToken;
140
134
  let deviceId = setup.deviceId;
@@ -144,10 +138,7 @@ async function cmdInit(argv) {
144
138
  if (!dashboardUrl) dashboardUrl = await detectLocalDashboardUrl();
145
139
  const flow = await beginBrowserAuth({ baseUrl, dashboardUrl, timeoutMs: 10 * 60_000, open: false });
146
140
  const canAutoOpen = !opts.noOpen;
147
- renderFinalStep({ authUrl: flow.authUrl, canAutoOpen });
148
- if (canAutoOpen && isInteractive()) {
149
- await promptEnter('');
150
- }
141
+ renderAuthTransition({ authUrl: flow.authUrl, canAutoOpen });
151
142
  if (canAutoOpen) {
152
143
  if (isInteractive()) await sleep(250);
153
144
  openInBrowser(flow.authUrl);
@@ -158,9 +149,12 @@ async function cmdInit(argv) {
158
149
  deviceId = issued.deviceId;
159
150
  await writeJson(configPath, { baseUrl, deviceToken, deviceId, installedAt: setup.installedAt });
160
151
  await chmod600IfPossible(configPath);
161
- renderSuccessBox({ deviceId, configPath });
152
+ const resolvedDashboardUrl = dashboardUrl || null;
153
+ renderSuccessBox({ configPath, dashboardUrl: resolvedDashboardUrl });
162
154
  } else if (deviceToken) {
163
- renderSuccessBox({ deviceId, configPath });
155
+ if (!dashboardUrl) dashboardUrl = await detectLocalDashboardUrl();
156
+ const resolvedDashboardUrl = dashboardUrl || null;
157
+ renderSuccessBox({ configPath, dashboardUrl: resolvedDashboardUrl });
164
158
  } else {
165
159
  renderAccountNotLinked();
166
160
  }
@@ -194,39 +188,6 @@ function renderWelcome() {
194
188
  );
195
189
  }
196
190
 
197
- function renderTransparencyReport({ summary, isDryRun, includeDivider = false }) {
198
- const header = isDryRun ? 'Dry run complete. Preview only; no changes were applied.' : 'Local setup complete.';
199
- const lines = [header, '', "We've integrated VibeScore with:"];
200
- for (const item of summary) lines.push(formatSummaryLine(item));
201
- if (includeDivider) lines.push('', DIVIDER, '');
202
- process.stdout.write(`${lines.join('\n')}\n`);
203
- }
204
-
205
- function renderFinalStep({ authUrl, canAutoOpen }) {
206
- const lines = [
207
- 'Final Step: Link your account',
208
- '',
209
- canAutoOpen ? 'Press [Enter] to open your browser and sign in.' : 'Open the link below to sign in.'
210
- ];
211
- if (authUrl) lines.push(`(Or visit: ${underline(authUrl)})`);
212
- lines.push('');
213
- process.stdout.write(lines.join('\n'));
214
- }
215
-
216
- function renderSuccessBox({ deviceId, configPath }) {
217
- const identityLine = deviceId ? `Device ID: ${deviceId}` : 'Account linked.';
218
- const lines = [
219
- 'You are all set!',
220
- '',
221
- identityLine,
222
- `Token saved to: ${configPath}`,
223
- '',
224
- 'VibeScore is now running in the background.',
225
- 'You can close this terminal window.'
226
- ];
227
- process.stdout.write(`${renderBox(lines)}\n`);
228
- }
229
-
230
191
  function renderAccountNotLinked({ context } = {}) {
231
192
  if (context === 'dry-run') {
232
193
  process.stdout.write(['', 'Account not linked (dry run).', 'Run init without --dry-run to link your account.', ''].join('\n'));
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+
3
+ const { formatSummaryLine, renderBox, underline } = require('./cli-ui');
4
+
5
+ const DIVIDER = '----------------------------------------------';
6
+
7
+ function renderLocalReport({ summary, isDryRun }) {
8
+ const header = isDryRun
9
+ ? 'Dry run complete. Preview only; no changes were applied.'
10
+ : 'Local configuration complete.';
11
+ const lines = [header, '', 'Integration Status:'];
12
+ for (const item of summary || []) lines.push(formatSummaryLine(item));
13
+ process.stdout.write(`${lines.join('\n')}\n`);
14
+ }
15
+
16
+ function renderAuthTransition({ authUrl, canAutoOpen }) {
17
+ const lines = ['', DIVIDER, '', 'Next: Registering device...'];
18
+ if (canAutoOpen) {
19
+ lines.push('Opening your browser to link account...');
20
+ if (authUrl) lines.push(`If it does not open, visit: ${underline(authUrl)}`);
21
+ } else {
22
+ lines.push('Open the link below to sign in.');
23
+ if (authUrl) lines.push(`Visit: ${underline(authUrl)}`);
24
+ }
25
+ lines.push('');
26
+ process.stdout.write(`${lines.join('\n')}\n`);
27
+ }
28
+
29
+ function renderSuccessBox({ configPath, dashboardUrl }) {
30
+ const identityLine = 'Account linked.';
31
+ const lines = [
32
+ 'You are all set!',
33
+ '',
34
+ identityLine,
35
+ `Token saved to: ${configPath}`,
36
+ ''
37
+ ];
38
+ if (dashboardUrl) lines.push(`View your stats at: ${dashboardUrl}`);
39
+ lines.push('You can close this terminal window.');
40
+ process.stdout.write(`${renderBox(lines)}\n`);
41
+ }
42
+
43
+ module.exports = {
44
+ DIVIDER,
45
+ renderLocalReport,
46
+ renderAuthTransition,
47
+ renderSuccessBox
48
+ };