@agentage/cli 0.1.1 → 0.1.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.
Files changed (59) hide show
  1. package/README.md +244 -48
  2. package/dist/cli.js +15 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/cli.test.js +21 -13
  5. package/dist/cli.test.js.map +1 -1
  6. package/dist/commands/init.d.ts +3 -0
  7. package/dist/commands/init.d.ts.map +1 -1
  8. package/dist/commands/init.js +21 -11
  9. package/dist/commands/init.js.map +1 -1
  10. package/dist/commands/init.test.js +28 -23
  11. package/dist/commands/init.test.js.map +1 -1
  12. package/dist/commands/login.d.ts +2 -0
  13. package/dist/commands/login.d.ts.map +1 -0
  14. package/dist/commands/login.js +67 -0
  15. package/dist/commands/login.js.map +1 -0
  16. package/dist/commands/login.test.d.ts +2 -0
  17. package/dist/commands/login.test.d.ts.map +1 -0
  18. package/dist/commands/login.test.js +157 -0
  19. package/dist/commands/login.test.js.map +1 -0
  20. package/dist/commands/logout.d.ts +2 -0
  21. package/dist/commands/logout.d.ts.map +1 -0
  22. package/dist/commands/logout.js +29 -0
  23. package/dist/commands/logout.js.map +1 -0
  24. package/dist/commands/logout.test.d.ts +2 -0
  25. package/dist/commands/logout.test.d.ts.map +1 -0
  26. package/dist/commands/logout.test.js +49 -0
  27. package/dist/commands/logout.test.js.map +1 -0
  28. package/dist/commands/whoami.d.ts +2 -0
  29. package/dist/commands/whoami.d.ts.map +1 -0
  30. package/dist/commands/whoami.js +47 -0
  31. package/dist/commands/whoami.js.map +1 -0
  32. package/dist/commands/whoami.test.d.ts +2 -0
  33. package/dist/commands/whoami.test.d.ts.map +1 -0
  34. package/dist/commands/whoami.test.js +96 -0
  35. package/dist/commands/whoami.test.js.map +1 -0
  36. package/dist/index.d.ts +1 -1
  37. package/dist/index.js +1 -1
  38. package/dist/index.test.js +1 -1
  39. package/dist/services/auth.service.d.ts +10 -0
  40. package/dist/services/auth.service.d.ts.map +1 -0
  41. package/dist/services/auth.service.js +97 -0
  42. package/dist/services/auth.service.js.map +1 -0
  43. package/dist/services/auth.service.test.d.ts +2 -0
  44. package/dist/services/auth.service.test.d.ts.map +1 -0
  45. package/dist/services/auth.service.test.js +215 -0
  46. package/dist/services/auth.service.test.js.map +1 -0
  47. package/dist/types/config.types.d.ts +159 -0
  48. package/dist/types/config.types.d.ts.map +1 -0
  49. package/dist/types/config.types.js +20 -0
  50. package/dist/types/config.types.js.map +1 -0
  51. package/dist/utils/config.d.ts +10 -0
  52. package/dist/utils/config.d.ts.map +1 -0
  53. package/dist/utils/config.js +49 -0
  54. package/dist/utils/config.js.map +1 -0
  55. package/dist/utils/config.test.d.ts +2 -0
  56. package/dist/utils/config.test.d.ts.map +1 -0
  57. package/dist/utils/config.test.js +118 -0
  58. package/dist/utils/config.test.js.map +1 -0
  59. package/package.json +3 -2
@@ -0,0 +1,67 @@
1
+ import chalk from 'chalk';
2
+ import { AuthError, pollForToken, requestDeviceCode, } from '../services/auth.service.js';
3
+ import { getRegistryUrl, loadConfig, saveConfig } from '../utils/config.js';
4
+ export const loginCommand = async () => {
5
+ try {
6
+ const config = await loadConfig();
7
+ if (config.auth?.token) {
8
+ console.log(chalk.yellow('⚠️ Already logged in.'), 'Run', chalk.cyan('agent logout'), 'first to switch accounts.');
9
+ return;
10
+ }
11
+ const registryUrl = await getRegistryUrl();
12
+ console.log(chalk.blue('🔐 Logging in to'), chalk.cyan(registryUrl));
13
+ console.log();
14
+ console.log(chalk.gray('Requesting authentication code...'));
15
+ const deviceCode = await requestDeviceCode();
16
+ console.log();
17
+ console.log(chalk.bold('To complete login:'));
18
+ console.log();
19
+ console.log(' 1. Open:', chalk.cyan.underline(deviceCode.verification_uri));
20
+ console.log(' 2. Enter code:', chalk.bold.yellow(deviceCode.user_code));
21
+ console.log();
22
+ try {
23
+ const open = await import('open');
24
+ await open.default(deviceCode.verification_uri);
25
+ console.log(chalk.gray('(Browser opened automatically)'));
26
+ }
27
+ catch {
28
+ console.log(chalk.gray('(Could not open browser automatically - please open manually)'));
29
+ }
30
+ console.log();
31
+ console.log(chalk.gray('Waiting for authentication...'));
32
+ const tokenResponse = await pollForToken(deviceCode.device_code, deviceCode.interval, deviceCode.expires_in);
33
+ await saveConfig({
34
+ ...config,
35
+ auth: {
36
+ token: tokenResponse.access_token,
37
+ user: tokenResponse.user,
38
+ expiresAt: tokenResponse.expires_in
39
+ ? new Date(Date.now() + tokenResponse.expires_in * 1000).toISOString()
40
+ : undefined,
41
+ },
42
+ });
43
+ console.log();
44
+ if (tokenResponse.user?.name) {
45
+ console.log(chalk.green('✅ Logged in as'), chalk.bold(tokenResponse.user.name));
46
+ }
47
+ else if (tokenResponse.user?.email) {
48
+ console.log(chalk.green('✅ Logged in as'), chalk.bold(tokenResponse.user.email));
49
+ }
50
+ else {
51
+ console.log(chalk.green('✅ Login successful!'));
52
+ }
53
+ }
54
+ catch (error) {
55
+ if (error instanceof AuthError) {
56
+ console.error(chalk.red('❌ Login failed:'), error.message);
57
+ if (error.code === 'expired_token') {
58
+ console.log(chalk.gray('Run'), chalk.cyan('agent login'), chalk.gray('to try again.'));
59
+ }
60
+ }
61
+ else {
62
+ console.error(chalk.red('❌ Login failed:'), error.message);
63
+ }
64
+ process.exit(1);
65
+ }
66
+ };
67
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=login.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.test.d.ts","sourceRoot":"","sources":["../../src/commands/login.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,157 @@
1
+ import * as authService from '../services/auth.service.js';
2
+ import { AuthError } from '../services/auth.service.js';
3
+ import * as configUtils from '../utils/config.js';
4
+ import { loginCommand } from './login.js';
5
+ jest.mock('../services/auth.service.js', () => {
6
+ const original = jest.requireActual('../services/auth.service.js');
7
+ return {
8
+ ...original,
9
+ requestDeviceCode: jest.fn(),
10
+ pollForToken: jest.fn(),
11
+ };
12
+ });
13
+ jest.mock('../utils/config.js');
14
+ jest.mock('open', () => ({
15
+ default: jest.fn(),
16
+ }));
17
+ const mockRequestDeviceCode = authService.requestDeviceCode;
18
+ const mockPollForToken = authService.pollForToken;
19
+ const mockLoadConfig = configUtils.loadConfig;
20
+ const mockSaveConfig = configUtils.saveConfig;
21
+ const mockGetRegistryUrl = configUtils.getRegistryUrl;
22
+ describe('loginCommand', () => {
23
+ let consoleSpy;
24
+ let consoleErrorSpy;
25
+ let processExitSpy;
26
+ beforeEach(() => {
27
+ jest.clearAllMocks();
28
+ consoleSpy = jest.spyOn(console, 'log').mockImplementation();
29
+ consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
30
+ processExitSpy = jest.spyOn(process, 'exit').mockImplementation(() => {
31
+ throw new Error('process.exit called');
32
+ });
33
+ mockGetRegistryUrl.mockResolvedValue('https://dev.agentage.io');
34
+ });
35
+ afterEach(() => {
36
+ consoleSpy.mockRestore();
37
+ consoleErrorSpy.mockRestore();
38
+ processExitSpy.mockRestore();
39
+ });
40
+ it('shows message when already logged in', async () => {
41
+ mockLoadConfig.mockResolvedValue({
42
+ auth: { token: 'existing-token' },
43
+ });
44
+ await loginCommand();
45
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Already logged in'), expect.any(String), expect.any(String), expect.any(String));
46
+ });
47
+ it('completes login flow successfully', async () => {
48
+ mockLoadConfig.mockResolvedValue({});
49
+ mockRequestDeviceCode.mockResolvedValue({
50
+ device_code: 'device123',
51
+ user_code: 'ABCD-1234',
52
+ verification_uri: 'https://dev.agentage.io/device',
53
+ expires_in: 900,
54
+ interval: 5,
55
+ });
56
+ mockPollForToken.mockResolvedValue({
57
+ access_token: 'new-token',
58
+ token_type: 'Bearer',
59
+ user: { id: '1', email: 'test@example.com', name: 'Test User' },
60
+ });
61
+ mockSaveConfig.mockResolvedValue(undefined);
62
+ await loginCommand();
63
+ expect(mockRequestDeviceCode).toHaveBeenCalled();
64
+ expect(mockPollForToken).toHaveBeenCalledWith('device123', 5, 900);
65
+ expect(mockSaveConfig).toHaveBeenCalledWith({
66
+ auth: {
67
+ token: 'new-token',
68
+ user: { id: '1', email: 'test@example.com', name: 'Test User' },
69
+ expiresAt: undefined,
70
+ },
71
+ });
72
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Logged in as'), expect.stringContaining('Test User'));
73
+ });
74
+ it('handles login errors', async () => {
75
+ mockLoadConfig.mockResolvedValue({});
76
+ mockRequestDeviceCode.mockRejectedValue(new AuthError('Failed', 'request_failed'));
77
+ await expect(loginCommand()).rejects.toThrow('process.exit called');
78
+ expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Login failed'), 'Failed');
79
+ });
80
+ it('handles expired token error with hint', async () => {
81
+ mockLoadConfig.mockResolvedValue({});
82
+ mockRequestDeviceCode.mockResolvedValue({
83
+ device_code: 'device123',
84
+ user_code: 'ABCD-1234',
85
+ verification_uri: 'https://dev.agentage.io/device',
86
+ expires_in: 900,
87
+ interval: 5,
88
+ });
89
+ mockPollForToken.mockRejectedValue(new AuthError('Login timed out', 'expired_token'));
90
+ await expect(loginCommand()).rejects.toThrow('process.exit called');
91
+ expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Login failed'), 'Login timed out');
92
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Run'), expect.stringContaining('agent login'), expect.stringContaining('to try again'));
93
+ });
94
+ it('handles non-AuthError errors', async () => {
95
+ mockLoadConfig.mockResolvedValue({});
96
+ mockRequestDeviceCode.mockRejectedValue(new Error('Network error'));
97
+ await expect(loginCommand()).rejects.toThrow('process.exit called');
98
+ expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Login failed'), 'Network error');
99
+ });
100
+ it('shows email when user has no name', async () => {
101
+ mockLoadConfig.mockResolvedValue({});
102
+ mockRequestDeviceCode.mockResolvedValue({
103
+ device_code: 'device123',
104
+ user_code: 'ABCD-1234',
105
+ verification_uri: 'https://dev.agentage.io/device',
106
+ expires_in: 900,
107
+ interval: 5,
108
+ });
109
+ mockPollForToken.mockResolvedValue({
110
+ access_token: 'new-token',
111
+ token_type: 'Bearer',
112
+ user: { id: '1', email: 'test@example.com' },
113
+ });
114
+ mockSaveConfig.mockResolvedValue(undefined);
115
+ await loginCommand();
116
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Logged in as'), expect.stringContaining('test@example.com'));
117
+ });
118
+ it('shows generic success when no user info', async () => {
119
+ mockLoadConfig.mockResolvedValue({});
120
+ mockRequestDeviceCode.mockResolvedValue({
121
+ device_code: 'device123',
122
+ user_code: 'ABCD-1234',
123
+ verification_uri: 'https://dev.agentage.io/device',
124
+ expires_in: 900,
125
+ interval: 5,
126
+ });
127
+ mockPollForToken.mockResolvedValue({
128
+ access_token: 'new-token',
129
+ token_type: 'Bearer',
130
+ });
131
+ mockSaveConfig.mockResolvedValue(undefined);
132
+ await loginCommand();
133
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Login successful'));
134
+ });
135
+ it('handles browser open failure gracefully', async () => {
136
+ jest.doMock('open', () => ({
137
+ default: jest.fn().mockRejectedValue(new Error('Cannot open browser')),
138
+ }));
139
+ mockLoadConfig.mockResolvedValue({});
140
+ mockRequestDeviceCode.mockResolvedValue({
141
+ device_code: 'device123',
142
+ user_code: 'ABCD-1234',
143
+ verification_uri: 'https://dev.agentage.io/device',
144
+ expires_in: 900,
145
+ interval: 5,
146
+ });
147
+ mockPollForToken.mockResolvedValue({
148
+ access_token: 'new-token',
149
+ token_type: 'Bearer',
150
+ user: { id: '1', email: 'test@example.com', name: 'Test User' },
151
+ });
152
+ mockSaveConfig.mockResolvedValue(undefined);
153
+ await loginCommand();
154
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Logged in as'), expect.stringContaining('Test User'));
155
+ });
156
+ });
157
+ //# sourceMappingURL=login.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.test.js","sourceRoot":"","sources":["../../src/commands/login.test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,KAAK,WAAW,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,IAAI,CAAC,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,6BAA6B,CAAC,CAAC;IACnE,OAAO;QACL,GAAG,QAAQ;QACX,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC5B,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;KACxB,CAAC;AACJ,CAAC,CAAC,CAAC;AACH,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;AAChC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACvB,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;CACnB,CAAC,CAAC,CAAC;AAEJ,MAAM,qBAAqB,GACzB,WAAW,CAAC,iBAEX,CAAC;AACJ,MAAM,gBAAgB,GAAG,WAAW,CAAC,YAEpC,CAAC;AACF,MAAM,cAAc,GAAG,WAAW,CAAC,UAElC,CAAC;AACF,MAAM,cAAc,GAAG,WAAW,CAAC,UAElC,CAAC;AACF,MAAM,kBAAkB,GAAG,WAAW,CAAC,cAEtC,CAAC;AAEF,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAI,UAA4B,CAAC;IACjC,IAAI,eAAiC,CAAC;IACtC,IAAI,cAAgC,CAAC;IAErC,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,EAAE,CAAC;QAC7D,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,kBAAkB,EAAE,CAAC;QACpE,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE;YACnE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QACH,kBAAkB,CAAC,iBAAiB,CAAC,yBAAyB,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,UAAU,CAAC,WAAW,EAAE,CAAC;QACzB,eAAe,CAAC,WAAW,EAAE,CAAC;QAC9B,cAAc,CAAC,WAAW,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,cAAc,CAAC,iBAAiB,CAAC;YAC/B,IAAI,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE;SAClC,CAAC,CAAC;QAEH,MAAM,YAAY,EAAE,CAAC;QAErB,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CACrC,MAAM,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,EAC5C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAClB,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAClB,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CACnB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,cAAc,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACrC,qBAAqB,CAAC,iBAAiB,CAAC;YACtC,WAAW,EAAE,WAAW;YACxB,SAAS,EAAE,WAAW;YACtB,gBAAgB,EAAE,gCAAgC;YAClD,UAAU,EAAE,GAAG;YACf,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;QACH,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,YAAY,EAAE,WAAW;YACzB,UAAU,EAAE,QAAQ;YACpB,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,WAAW,EAAE;SAChE,CAAC,CAAC;QACH,cAAc,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE5C,MAAM,YAAY,EAAE,CAAC;QAErB,MAAM,CAAC,qBAAqB,CAAC,CAAC,gBAAgB,EAAE,CAAC;QACjD,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAAC,WAAW,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QACnE,MAAM,CAAC,cAAc,CAAC,CAAC,oBAAoB,CAAC;YAC1C,IAAI,EAAE;gBACJ,KAAK,EAAE,WAAW;gBAClB,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,WAAW,EAAE;gBAC/D,SAAS,EAAE,SAAS;aACrB;SACF,CAAC,CAAC;QACH,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CACrC,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,EACvC,MAAM,CAAC,gBAAgB,CAAC,WAAW,CAAC,CACrC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACpC,cAAc,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACrC,qBAAqB,CAAC,iBAAiB,CACrC,IAAI,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAC1C,CAAC;QAEF,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;QAEpE,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAC1C,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,EACvC,QAAQ,CACT,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,cAAc,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACrC,qBAAqB,CAAC,iBAAiB,CAAC;YACtC,WAAW,EAAE,WAAW;YACxB,SAAS,EAAE,WAAW;YACtB,gBAAgB,EAAE,gCAAgC;YAClD,UAAU,EAAE,GAAG;YACf,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;QACH,gBAAgB,CAAC,iBAAiB,CAChC,IAAI,SAAS,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAClD,CAAC;QAEF,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;QAEpE,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAC1C,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,EACvC,iBAAiB,CAClB,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CACrC,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAC9B,MAAM,CAAC,gBAAgB,CAAC,aAAa,CAAC,EACtC,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,CACxC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,cAAc,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACrC,qBAAqB,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;QAEpE,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;QAEpE,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAC1C,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,EACvC,eAAe,CAChB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,cAAc,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACrC,qBAAqB,CAAC,iBAAiB,CAAC;YACtC,WAAW,EAAE,WAAW;YACxB,SAAS,EAAE,WAAW;YACtB,gBAAgB,EAAE,gCAAgC;YAClD,UAAU,EAAE,GAAG;YACf,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;QACH,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,YAAY,EAAE,WAAW;YACzB,UAAU,EAAE,QAAQ;YACpB,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,kBAAkB,EAAE;SAC7C,CAAC,CAAC;QACH,cAAc,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE5C,MAAM,YAAY,EAAE,CAAC;QAErB,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CACrC,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,EACvC,MAAM,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAC5C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,cAAc,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACrC,qBAAqB,CAAC,iBAAiB,CAAC;YACtC,WAAW,EAAE,WAAW;YACxB,SAAS,EAAE,WAAW;YACtB,gBAAgB,EAAE,gCAAgC;YAClD,UAAU,EAAE,GAAG;YACf,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;QACH,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,YAAY,EAAE,WAAW;YACzB,UAAU,EAAE,QAAQ;SACrB,CAAC,CAAC;QACH,cAAc,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE5C,MAAM,YAAY,EAAE,CAAC;QAErB,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CACrC,MAAM,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAC5C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QAEvD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACzB,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;SACvE,CAAC,CAAC,CAAC;QAEJ,cAAc,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACrC,qBAAqB,CAAC,iBAAiB,CAAC;YACtC,WAAW,EAAE,WAAW;YACxB,SAAS,EAAE,WAAW;YACtB,gBAAgB,EAAE,gCAAgC;YAClD,UAAU,EAAE,GAAG;YACf,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;QACH,gBAAgB,CAAC,iBAAiB,CAAC;YACjC,YAAY,EAAE,WAAW;YACzB,UAAU,EAAE,QAAQ;YACpB,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,WAAW,EAAE;SAChE,CAAC,CAAC;QACH,cAAc,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE5C,MAAM,YAAY,EAAE,CAAC;QAErB,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CACrC,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,EACvC,MAAM,CAAC,gBAAgB,CAAC,WAAW,CAAC,CACrC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const logoutCommand: () => Promise<void>;
2
+ //# sourceMappingURL=logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,IAAI,CAmClD,CAAC"}
@@ -0,0 +1,29 @@
1
+ import chalk from 'chalk';
2
+ import { logout as logoutApi } from '../services/auth.service.js';
3
+ import { clearConfig, loadConfig } from '../utils/config.js';
4
+ export const logoutCommand = async () => {
5
+ try {
6
+ const config = await loadConfig();
7
+ if (!config.auth?.token) {
8
+ console.log(chalk.yellow('Not logged in.'));
9
+ return;
10
+ }
11
+ const userName = config.auth.user?.name || config.auth.user?.email;
12
+ console.log(chalk.gray('Logging out...'));
13
+ await logoutApi();
14
+ await clearConfig();
15
+ console.log();
16
+ if (userName) {
17
+ console.log(chalk.green('✅ Logged out from'), chalk.bold(userName));
18
+ }
19
+ else {
20
+ console.log(chalk.green('✅ Logged out successfully.'));
21
+ }
22
+ }
23
+ catch {
24
+ await clearConfig();
25
+ console.log(chalk.green('✅ Logged out locally.'));
26
+ console.log(chalk.gray('(Server logout may have failed, but local credentials cleared)'));
27
+ }
28
+ };
29
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAK7D,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,IAAmB,EAAE;IACrD,IAAI,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC;YAC5C,OAAO;QACT,CAAC;QAGD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC;QAGnE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC1C,MAAM,SAAS,EAAE,CAAC;QAGlB,MAAM,WAAW,EAAE,CAAC;QAEpB,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QAEP,MAAM,WAAW,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CACR,gEAAgE,CACjE,CACF,CAAC;IACJ,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=logout.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.test.d.ts","sourceRoot":"","sources":["../../src/commands/logout.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ import * as authService from '../services/auth.service.js';
2
+ import * as configUtils from '../utils/config.js';
3
+ import { logoutCommand } from './logout.js';
4
+ jest.mock('../services/auth.service.js');
5
+ jest.mock('../utils/config.js');
6
+ const mockLogout = authService.logout;
7
+ const mockLoadConfig = configUtils.loadConfig;
8
+ const mockClearConfig = configUtils.clearConfig;
9
+ describe('logoutCommand', () => {
10
+ let consoleSpy;
11
+ beforeEach(() => {
12
+ jest.clearAllMocks();
13
+ consoleSpy = jest.spyOn(console, 'log').mockImplementation();
14
+ });
15
+ afterEach(() => {
16
+ consoleSpy.mockRestore();
17
+ });
18
+ it('shows message when not logged in', async () => {
19
+ mockLoadConfig.mockResolvedValue({});
20
+ await logoutCommand();
21
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Not logged in'));
22
+ expect(mockClearConfig).not.toHaveBeenCalled();
23
+ });
24
+ it('clears credentials and shows success', async () => {
25
+ mockLoadConfig.mockResolvedValue({
26
+ auth: {
27
+ token: 'test-token',
28
+ user: { id: '1', email: 'test@example.com', name: 'Test User' },
29
+ },
30
+ });
31
+ mockLogout.mockResolvedValue(undefined);
32
+ mockClearConfig.mockResolvedValue(undefined);
33
+ await logoutCommand();
34
+ expect(mockLogout).toHaveBeenCalled();
35
+ expect(mockClearConfig).toHaveBeenCalled();
36
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Logged out from'), expect.stringContaining('Test User'));
37
+ });
38
+ it('clears credentials even when server logout fails', async () => {
39
+ mockLoadConfig.mockResolvedValue({
40
+ auth: { token: 'test-token' },
41
+ });
42
+ mockLogout.mockRejectedValue(new Error('Network error'));
43
+ mockClearConfig.mockResolvedValue(undefined);
44
+ await logoutCommand();
45
+ expect(mockClearConfig).toHaveBeenCalled();
46
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Logged out locally'));
47
+ });
48
+ });
49
+ //# sourceMappingURL=logout.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.test.js","sourceRoot":"","sources":["../../src/commands/logout.test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,WAAW,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;AACzC,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;AAEhC,MAAM,UAAU,GAAG,WAAW,CAAC,MAE9B,CAAC;AACF,MAAM,cAAc,GAAG,WAAW,CAAC,UAElC,CAAC;AACF,MAAM,eAAe,GAAG,WAAW,CAAC,WAEnC,CAAC;AAEF,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAI,UAA4B,CAAC;IAEjC,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,EAAE,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,UAAU,CAAC,WAAW,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,cAAc,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAErC,MAAM,aAAa,EAAE,CAAC;QAEtB,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CACrC,MAAM,CAAC,gBAAgB,CAAC,eAAe,CAAC,CACzC,CAAC;QACF,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,cAAc,CAAC,iBAAiB,CAAC;YAC/B,IAAI,EAAE;gBACJ,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,WAAW,EAAE;aAChE;SACF,CAAC,CAAC;QACH,UAAU,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACxC,eAAe,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE7C,MAAM,aAAa,EAAE,CAAC;QAEtB,MAAM,CAAC,UAAU,CAAC,CAAC,gBAAgB,EAAE,CAAC;QACtC,MAAM,CAAC,eAAe,CAAC,CAAC,gBAAgB,EAAE,CAAC;QAC3C,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CACrC,MAAM,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,EAC1C,MAAM,CAAC,gBAAgB,CAAC,WAAW,CAAC,CACrC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,cAAc,CAAC,iBAAiB,CAAC;YAC/B,IAAI,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE;SAC9B,CAAC,CAAC;QACH,UAAU,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;QACzD,eAAe,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE7C,MAAM,aAAa,EAAE,CAAC;QAEtB,MAAM,CAAC,eAAe,CAAC,CAAC,gBAAgB,EAAE,CAAC;QAC3C,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CACrC,MAAM,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAC9C,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const whoamiCommand: () => Promise<void>;
2
+ //# sourceMappingURL=whoami.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,IAAI,CA0ClD,CAAC"}
@@ -0,0 +1,47 @@
1
+ import chalk from 'chalk';
2
+ import { AuthError, getMe } from '../services/auth.service.js';
3
+ import { getRegistryUrl, loadConfig } from '../utils/config.js';
4
+ export const whoamiCommand = async () => {
5
+ try {
6
+ const config = await loadConfig();
7
+ if (!config.auth?.token) {
8
+ console.log(chalk.yellow('Not logged in.'));
9
+ console.log('Run', chalk.cyan('agent login'), 'to authenticate.');
10
+ return;
11
+ }
12
+ console.log(chalk.gray('Checking authentication...'));
13
+ const user = await getMe();
14
+ const registryUrl = await getRegistryUrl();
15
+ console.log();
16
+ console.log(chalk.green('✅ Logged in to'), chalk.cyan(registryUrl));
17
+ console.log();
18
+ console.log(chalk.bold('User Information:'));
19
+ console.log();
20
+ if (user.name) {
21
+ console.log(' Name: ', chalk.bold(user.name));
22
+ }
23
+ console.log(' Email:', chalk.bold(user.email));
24
+ console.log(' ID: ', chalk.gray(user.id));
25
+ console.log();
26
+ }
27
+ catch (error) {
28
+ if (error instanceof AuthError) {
29
+ if (error.code === 'not_authenticated') {
30
+ console.log(chalk.yellow('Not logged in.'));
31
+ console.log('Run', chalk.cyan('agent login'), 'to authenticate.');
32
+ }
33
+ else if (error.code === 'session_expired') {
34
+ console.log(chalk.yellow('⚠️ Session expired.'));
35
+ console.log('Run', chalk.cyan('agent login'), 'to authenticate again.');
36
+ }
37
+ else {
38
+ console.error(chalk.red('❌ Error:'), error.message);
39
+ }
40
+ }
41
+ else {
42
+ console.error(chalk.red('❌ Error:'), error.message);
43
+ }
44
+ process.exit(1);
45
+ }
46
+ };
47
+ //# sourceMappingURL=whoami.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=whoami.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.test.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,96 @@
1
+ import * as authService from '../services/auth.service.js';
2
+ import { AuthError } from '../services/auth.service.js';
3
+ import * as configUtils from '../utils/config.js';
4
+ import { whoamiCommand } from './whoami.js';
5
+ jest.mock('../services/auth.service.js', () => {
6
+ const original = jest.requireActual('../services/auth.service.js');
7
+ return {
8
+ ...original,
9
+ getMe: jest.fn(),
10
+ };
11
+ });
12
+ jest.mock('../utils/config.js');
13
+ const mockGetMe = authService.getMe;
14
+ const mockLoadConfig = configUtils.loadConfig;
15
+ const mockGetRegistryUrl = configUtils.getRegistryUrl;
16
+ describe('whoamiCommand', () => {
17
+ let consoleSpy;
18
+ let consoleErrorSpy;
19
+ let processExitSpy;
20
+ beforeEach(() => {
21
+ jest.clearAllMocks();
22
+ consoleSpy = jest.spyOn(console, 'log').mockImplementation();
23
+ consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
24
+ processExitSpy = jest.spyOn(process, 'exit').mockImplementation(() => {
25
+ throw new Error('process.exit called');
26
+ });
27
+ mockGetRegistryUrl.mockResolvedValue('https://dev.agentage.io');
28
+ });
29
+ afterEach(() => {
30
+ consoleSpy.mockRestore();
31
+ consoleErrorSpy.mockRestore();
32
+ processExitSpy.mockRestore();
33
+ });
34
+ it('shows not logged in when no token', async () => {
35
+ mockLoadConfig.mockResolvedValue({});
36
+ await whoamiCommand();
37
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Not logged in'));
38
+ });
39
+ it('displays user info when authenticated', async () => {
40
+ mockLoadConfig.mockResolvedValue({
41
+ auth: { token: 'test-token' },
42
+ });
43
+ mockGetMe.mockResolvedValue({
44
+ id: '123',
45
+ email: 'test@example.com',
46
+ name: 'Test User',
47
+ });
48
+ await whoamiCommand();
49
+ expect(mockGetMe).toHaveBeenCalled();
50
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Logged in to'), expect.any(String));
51
+ });
52
+ it('handles session expired error', async () => {
53
+ mockLoadConfig.mockResolvedValue({
54
+ auth: { token: 'expired-token' },
55
+ });
56
+ mockGetMe.mockRejectedValue(new AuthError('Session expired', 'session_expired'));
57
+ await expect(whoamiCommand()).rejects.toThrow('process.exit called');
58
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Session expired'));
59
+ });
60
+ it('handles not_authenticated error', async () => {
61
+ mockLoadConfig.mockResolvedValue({
62
+ auth: { token: 'test-token' },
63
+ });
64
+ mockGetMe.mockRejectedValue(new AuthError('Not authenticated', 'not_authenticated'));
65
+ await expect(whoamiCommand()).rejects.toThrow('process.exit called');
66
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Not logged in'));
67
+ });
68
+ it('handles other AuthError errors', async () => {
69
+ mockLoadConfig.mockResolvedValue({
70
+ auth: { token: 'test-token' },
71
+ });
72
+ mockGetMe.mockRejectedValue(new AuthError('Server error', 'server_error'));
73
+ await expect(whoamiCommand()).rejects.toThrow('process.exit called');
74
+ expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Error'), 'Server error');
75
+ });
76
+ it('handles non-AuthError errors', async () => {
77
+ mockLoadConfig.mockResolvedValue({
78
+ auth: { token: 'test-token' },
79
+ });
80
+ mockGetMe.mockRejectedValue(new Error('Network error'));
81
+ await expect(whoamiCommand()).rejects.toThrow('process.exit called');
82
+ expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Error'), 'Network error');
83
+ });
84
+ it('displays user without name', async () => {
85
+ mockLoadConfig.mockResolvedValue({
86
+ auth: { token: 'test-token' },
87
+ });
88
+ mockGetMe.mockResolvedValue({
89
+ id: '123',
90
+ email: 'test@example.com',
91
+ });
92
+ await whoamiCommand();
93
+ expect(consoleSpy).toHaveBeenCalledWith(' Email:', expect.stringContaining('test@example.com'));
94
+ });
95
+ });
96
+ //# sourceMappingURL=whoami.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.test.js","sourceRoot":"","sources":["../../src/commands/whoami.test.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export declare const version = "0.1.1";
1
+ export declare const version = "0.1.2";
2
2
  export declare const greet: () => string;
3
3
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export const version = '0.1.1';
1
+ export const version = '0.1.2';
2
2
  export const greet = () => 'Hello from AgentKit CLI!';
3
3
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  import { greet, version } from './index.js';
2
2
  describe('CLI Package', () => {
3
3
  test('version is defined', () => {
4
- expect(version).toBe('0.1.1');
4
+ expect(version).toBe('0.1.2');
5
5
  });
6
6
  test('greet returns correct message', () => {
7
7
  expect(greet()).toBe('Hello from AgentKit CLI!');
@@ -0,0 +1,10 @@
1
+ import { DeviceCodeResponse, TokenResponse, User } from '../types/config.types.js';
2
+ export declare class AuthError extends Error {
3
+ code: string;
4
+ constructor(message: string, code: string);
5
+ }
6
+ export declare const requestDeviceCode: () => Promise<DeviceCodeResponse>;
7
+ export declare const pollForToken: (deviceCode: string, interval: number, expiresIn: number) => Promise<TokenResponse>;
8
+ export declare const getMe: () => Promise<User>;
9
+ export declare const logout: () => Promise<void>;
10
+ //# sourceMappingURL=auth.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.service.d.ts","sourceRoot":"","sources":["../../src/services/auth.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kBAAkB,EAClB,aAAa,EACb,IAAI,EACL,MAAM,0BAA0B,CAAC;AAMlC,qBAAa,SAAU,SAAQ,KAAK;IACE,IAAI,EAAE,MAAM;gBAApC,OAAO,EAAE,MAAM,EAAS,IAAI,EAAE,MAAM;CAIjD;AAKD,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,kBAAkB,CAkBpE,CAAC;AAKF,eAAO,MAAM,YAAY,GACvB,YAAY,MAAM,EAClB,UAAU,MAAM,EAChB,WAAW,MAAM,KAChB,OAAO,CAAC,aAAa,CA6CvB,CAAC;AAYF,eAAO,MAAM,KAAK,QAAa,OAAO,CAAC,IAAI,CA8B1C,CAAC;AAKF,eAAO,MAAM,MAAM,QAAa,OAAO,CAAC,IAAI,CAkB3C,CAAC"}