osai-agent 4.2.32 → 4.2.33

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": "osai-agent",
3
- "version": "4.2.32",
3
+ "version": "4.2.33",
4
4
  "type": "module",
5
5
  "description": "OS AI Agent - YOUR AI AGENT",
6
6
  "main": "src/index.js",
@@ -92,12 +92,15 @@ export const deleteAccount = async ({ server: serverArg }) => {
92
92
 
93
93
  spinner.succeed('Account deleted successfully');
94
94
 
95
+ const note = chalk.hex('#ff9e64')('\n\n Note: Your OS AI Chat account is separate.\n Delete it at: https://osaix.vercel.app/account');
96
+
95
97
  console.log(boxen(
96
98
  chalk.hex('#7aa2f7').bold(' Account Deleted') +
97
99
  chalk.hex('#c0caf5')('\n\n All your data has been permanently removed.') +
98
100
  chalk.hex('#9aa5ce')('\n You will be able to create a new account') +
99
101
  chalk.hex('#9aa5ce')('\n with the same email or from this machine') +
100
- chalk.hex('#9aa5ce')('\n after 24 hours.'),
102
+ chalk.hex('#9aa5ce')('\n after 24 hours.') +
103
+ note,
101
104
  { padding: 2, borderStyle: 'round', borderColor: '#4a9eff', textAlignment: 'center' }
102
105
  ));
103
106
  } catch (err) {
@@ -1,38 +1,12 @@
1
- import pkg from 'node-machine-id';
2
- const { machineIdSync } = pkg;
3
1
  import chalk from 'chalk';
4
2
  import Conf from 'conf';
5
- import inquirer from 'inquirer';
6
3
  import ora from 'ora';
7
- import { ExitPromptError } from '@inquirer/core';
4
+ import { execSync } from 'node:child_process';
8
5
  import { printAuthHeader, printError, printSuccess, clearScreen } from '../ui/terminal.js';
9
- import { DEFAULT_SERVER_URL, toHttpUrl, toWsUrl, toDisplayUrl } from '../services/server-url.js';
6
+ import { DEFAULT_SERVER_URL, toHttpUrl, toWsUrl } from '../services/server-url.js';
10
7
  import { run } from './run.js';
11
8
 
12
- const attemptLogin = async (email, password, serverInput, config) => {
13
- const server = toWsUrl(serverInput);
14
- const machineId = machineIdSync();
15
- const spinner = ora('Connecting to server...').start();
16
-
17
- try {
18
- const response = await fetch(`${toHttpUrl(server)}/auth/login`, {
19
- method: 'POST',
20
- headers: { 'Content-Type': 'application/json' },
21
- body: JSON.stringify({ email, password, machineId })
22
- });
23
- const data = await response.json();
24
- if (!response.ok) { spinner.fail('Login refused'); printError(data.error || 'Connection error'); return 'auth_error'; }
25
- config.set({ token: data.token, userId: data.user.id, plan: data.user.plan, server });
26
- spinner.succeed('Session started');
27
- printSuccess('Connected');
28
- console.log(chalk.gray(` Plan: ${data.user.plan}`));
29
- console.log(chalk.gray(` Use: osai-agent connect\n`));
30
- return 'success';
31
- } catch {
32
- spinner.fail('Unable to connect');
33
- return 'network_error';
34
- }
35
- };
9
+ const sleep = (ms) => new Promise(r => setTimeout(r, ms));
36
10
 
37
11
  export const login = async ({ server: serverOverride } = {}) => {
38
12
  const config = new Conf({ projectName: 'osai-agent' });
@@ -41,37 +15,70 @@ export const login = async ({ server: serverOverride } = {}) => {
41
15
  console.log(chalk.yellow('Already logged in. Use osai-agent logout first.'));
42
16
  return;
43
17
  }
44
- const prefixTheme = { idle: chalk.hex('#7aa2f7')('▸'), done: chalk.hex('#7aa2f7')('▸') };
18
+
19
+ const serverInput = serverOverride || config.get('server') || DEFAULT_SERVER_URL;
20
+ const server = toWsUrl(serverInput);
21
+ const httpUrl = toHttpUrl(server);
22
+
45
23
  clearScreen();
46
24
  console.log();
47
- printAuthHeader(chalk.white('Welcome Back'), 'Sign in to OS AI Agent to continue.');
25
+ printAuthHeader(chalk.white('Welcome Back'), 'Sign in with Google or GitHub to continue.');
48
26
  console.log();
49
27
 
50
- let serverInput = serverOverride || config.get('server') || DEFAULT_SERVER_URL;
28
+ const spinner = ora('Preparing authentication...').start();
51
29
 
52
- let email, password;
53
30
  try {
54
- ({ email, password } = await inquirer.prompt([
55
- { type: 'input', name: 'email', message: 'Email \u203A', theme: { prefix: prefixTheme }, validate: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) || 'Invalid email' },
56
- { type: 'password', name: 'password', message: 'Password \u203A', theme: { prefix: prefixTheme }, mask: '*' },
57
- ]));
58
- } catch (err) {
59
- if (err instanceof ExitPromptError) process.exit(0);
60
- throw err;
61
- }
31
+ const initRes = await fetch(`${httpUrl}/auth/cli/init-challenge`, { method: 'POST' });
32
+ const initData = await initRes.json();
33
+ if (!initRes.ok) { spinner.fail('Failed to init'); printError(initData.error); return; }
62
34
 
63
- const result = await attemptLogin(email, password, serverInput, config);
64
- if (result === 'success') { await run({}); return; }
65
- if (result !== 'network_error') return;
35
+ const { challenge } = initData;
36
+ const authUrl = `${httpUrl}/auth/cli-login?challenge=${challenge}`;
66
37
 
67
- try {
68
- const { serverInput: retryServer } = await inquirer.prompt([
69
- { type: 'input', name: 'serverInput', message: 'Server \u203A', theme: { prefix: prefixTheme }, default: toDisplayUrl(serverInput) }
70
- ]);
71
- const result2 = await attemptLogin(email, password, retryServer, config);
72
- if (result2 === 'success') await run({});
38
+ const platform = process.platform;
39
+ let openCmd;
40
+ if (platform === 'darwin') openCmd = 'open';
41
+ else if (platform === 'win32') openCmd = 'start';
42
+ else openCmd = 'xdg-open';
43
+
44
+ try {
45
+ execSync(`${openCmd} "${authUrl}"`, { timeout: 5000, stdio: 'ignore' });
46
+ spinner.succeed('Browser opened');
47
+ } catch {
48
+ spinner.succeed('Authentication URL');
49
+ console.log(` ${chalk.gray('Open this URL in your browser:')}`);
50
+ console.log(` ${chalk.cyan(authUrl)}`);
51
+ }
52
+
53
+ console.log(` ${chalk.gray('Waiting for authentication...')}`);
54
+
55
+ const pollSpinner = ora('Waiting for sign-in...').start();
56
+ const maxAttempts = 150;
57
+ let attempts = 0;
58
+
59
+ while (attempts < maxAttempts) {
60
+ await sleep(2000);
61
+ try {
62
+ const pollRes = await fetch(`${httpUrl}/auth/cli/poll?challenge=${challenge}`);
63
+ const pollData = await pollRes.json();
64
+
65
+ if (pollData.token) {
66
+ config.set({ token: pollData.token, userId: pollData.user.id, plan: pollData.user.plan, server });
67
+ pollSpinner.succeed('Authenticated');
68
+ printSuccess('Connected');
69
+ console.log(chalk.gray(` Plan: ${pollData.user.plan}`));
70
+ console.log(chalk.gray(` Use: osai-agent connect\n`));
71
+ await run({});
72
+ return;
73
+ }
74
+ } catch {}
75
+ attempts++;
76
+ }
77
+
78
+ pollSpinner.fail('Authentication timed out');
79
+ printError('Did not complete within 5 minutes. Please try again.');
73
80
  } catch (err) {
74
- if (err instanceof ExitPromptError) process.exit(0);
75
- throw err;
81
+ spinner.fail('Connection error');
82
+ printError(err.message);
76
83
  }
77
84
  };
@@ -22,7 +22,8 @@ export const logout = () => {
22
22
  console.log(boxen(
23
23
  chalk.hex('#7aa2f7').bold(' OS AI Agent') +
24
24
  chalk.hex('#c0caf5')('\n See you soon!') +
25
- chalk.hex('#565f89').dim('\n You have been logged out.'),
25
+ chalk.hex('#565f89').dim('\n You have been logged out.') +
26
+ chalk.hex('#565f89').dim('\n Note: Your OS AI Chat session is unaffected.'),
26
27
  { padding: 1, borderStyle: 'round', borderColor: '#4a9eff' }
27
28
  ));
28
29
 
@@ -1,35 +1,12 @@
1
1
  import chalk from 'chalk';
2
2
  import Conf from 'conf';
3
- import inquirer from 'inquirer';
4
3
  import ora from 'ora';
5
- import { ExitPromptError } from '@inquirer/core';
6
- import { printAuthHeader, printError, clearScreen } from '../ui/terminal.js';
7
- import { DEFAULT_SERVER_URL, toHttpUrl, toWsUrl, toDisplayUrl } from '../services/server-url.js';
4
+ import { execSync } from 'node:child_process';
5
+ import { printAuthHeader, printError, printSuccess, clearScreen } from '../ui/terminal.js';
6
+ import { DEFAULT_SERVER_URL, toHttpUrl, toWsUrl } from '../services/server-url.js';
8
7
  import { run } from './run.js';
9
- import pkg from 'node-machine-id';
10
- const { machineIdSync } = pkg;
11
8
 
12
- const attemptRegister = async (email, password, serverInput, config) => {
13
- const server = toWsUrl(serverInput);
14
- const machineId = machineIdSync();
15
- const spinner = ora('Creating account...').start();
16
-
17
- try {
18
- const response = await fetch(`${toHttpUrl(server)}/auth/register`, {
19
- method: 'POST',
20
- headers: { 'Content-Type': 'application/json' },
21
- body: JSON.stringify({ email, password, machineId })
22
- });
23
- const data = await response.json();
24
- if (!response.ok) { spinner.fail('Creation refused'); printError(data.error || 'Error during registration'); return 'auth_error'; }
25
- config.set({ token: data.token, userId: data.user.id, plan: data.user.plan, server });
26
- spinner.succeed('Account created');
27
- return 'success';
28
- } catch {
29
- spinner.fail('Unable to create account');
30
- return 'network_error';
31
- }
32
- };
9
+ const sleep = (ms) => new Promise(r => setTimeout(r, ms));
33
10
 
34
11
  export const register = async ({ server: serverOverride } = {}) => {
35
12
  const config = new Conf({ projectName: 'osai-agent' });
@@ -38,37 +15,70 @@ export const register = async ({ server: serverOverride } = {}) => {
38
15
  console.log(chalk.yellow('Already logged in. Use osai-agent logout first.'));
39
16
  return;
40
17
  }
41
- const prefixTheme = { idle: chalk.hex('#7aa2f7')('▸'), done: chalk.hex('#7aa2f7')('▸') };
18
+
19
+ const serverInput = serverOverride || config.get('server') || DEFAULT_SERVER_URL;
20
+ const server = toWsUrl(serverInput);
21
+ const httpUrl = toHttpUrl(server);
22
+
42
23
  clearScreen();
43
24
  console.log();
44
- printAuthHeader(chalk.white('Create Your Account'), 'Join OS AI Agent and get started with AI-powered automation.');
25
+ printAuthHeader(chalk.white('Create Your Account'), 'Sign in with Google or GitHub to get started.');
45
26
  console.log();
46
27
 
47
- let serverInput = serverOverride || config.get('server') || DEFAULT_SERVER_URL;
28
+ const spinner = ora('Preparing authentication...').start();
48
29
 
49
- let email, password;
50
30
  try {
51
- ({ email, password } = await inquirer.prompt([
52
- { type: 'input', name: 'email', message: 'Email \u203A', theme: { prefix: prefixTheme }, validate: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) || 'Invalid email' },
53
- { type: 'password', name: 'password', message: 'Password \u203A', theme: { prefix: prefixTheme }, mask: '*', validate: (value) => value.length >= 8 || 'Minimum 8 characters' },
54
- ]));
55
- } catch (err) {
56
- if (err instanceof ExitPromptError) process.exit(0);
57
- throw err;
58
- }
31
+ const initRes = await fetch(`${httpUrl}/auth/cli/init-challenge`, { method: 'POST' });
32
+ const initData = await initRes.json();
33
+ if (!initRes.ok) { spinner.fail('Failed to init'); printError(initData.error); return; }
59
34
 
60
- const result = await attemptRegister(email, password, serverInput, config);
61
- if (result === 'success') { await run({}); return; }
62
- if (result !== 'network_error') return;
35
+ const { challenge } = initData;
36
+ const authUrl = `${httpUrl}/auth/cli-login?challenge=${challenge}`;
63
37
 
64
- try {
65
- const { serverInput: retryServer } = await inquirer.prompt([
66
- { type: 'input', name: 'serverInput', message: 'Server \u203A', theme: { prefix: prefixTheme }, default: toDisplayUrl(serverInput) }
67
- ]);
68
- const result2 = await attemptRegister(email, password, retryServer, config);
69
- if (result2 === 'success') await run({});
38
+ const platform = process.platform;
39
+ let openCmd;
40
+ if (platform === 'darwin') openCmd = 'open';
41
+ else if (platform === 'win32') openCmd = 'start';
42
+ else openCmd = 'xdg-open';
43
+
44
+ try {
45
+ execSync(`${openCmd} "${authUrl}"`, { timeout: 5000, stdio: 'ignore' });
46
+ spinner.succeed('Browser opened');
47
+ } catch {
48
+ spinner.succeed('Authentication URL');
49
+ console.log(` ${chalk.gray('Open this URL in your browser:')}`);
50
+ console.log(` ${chalk.cyan(authUrl)}`);
51
+ }
52
+
53
+ console.log(` ${chalk.gray('Waiting for authentication...')}`);
54
+
55
+ const pollSpinner = ora('Waiting for sign-in...').start();
56
+ const maxAttempts = 150;
57
+ let attempts = 0;
58
+
59
+ while (attempts < maxAttempts) {
60
+ await sleep(2000);
61
+ try {
62
+ const pollRes = await fetch(`${httpUrl}/auth/cli/poll?challenge=${challenge}`);
63
+ const pollData = await pollRes.json();
64
+
65
+ if (pollData.token) {
66
+ config.set({ token: pollData.token, userId: pollData.user.id, plan: pollData.user.plan, server });
67
+ pollSpinner.succeed('Authenticated');
68
+ printSuccess('Connected');
69
+ console.log(chalk.gray(` Plan: ${pollData.user.plan}`));
70
+ console.log(chalk.gray(` Use: osai-agent connect\n`));
71
+ await run({});
72
+ return;
73
+ }
74
+ } catch {}
75
+ attempts++;
76
+ }
77
+
78
+ pollSpinner.fail('Authentication timed out');
79
+ printError('Did not complete within 5 minutes. Please try again.');
70
80
  } catch (err) {
71
- if (err instanceof ExitPromptError) process.exit(0);
72
- throw err;
81
+ spinner.fail('Connection error');
82
+ printError(err.message);
73
83
  }
74
84
  };