@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 +1 -1
- package/src/commands/init.js +14 -53
- package/src/lib/init-flow.js +48 -0
package/package.json
CHANGED
package/src/commands/init.js
CHANGED
|
@@ -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
|
-
|
|
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: '?
|
|
84
|
-
options: ['
|
|
80
|
+
message: '? Proceed with installation?',
|
|
81
|
+
options: ['Yes, configure my environment', 'No, exit'],
|
|
85
82
|
defaultIndex: 0
|
|
86
83
|
});
|
|
87
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
152
|
+
const resolvedDashboardUrl = dashboardUrl || null;
|
|
153
|
+
renderSuccessBox({ configPath, dashboardUrl: resolvedDashboardUrl });
|
|
162
154
|
} else if (deviceToken) {
|
|
163
|
-
|
|
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
|
+
};
|