@agentarea/cli 0.1.0

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 (110) hide show
  1. package/dist/app.d.ts +7 -0
  2. package/dist/app.d.ts.map +1 -0
  3. package/dist/app.js +32 -0
  4. package/dist/app.js.map +1 -0
  5. package/dist/cli-commands.d.ts +9 -0
  6. package/dist/cli-commands.d.ts.map +1 -0
  7. package/dist/cli-commands.js +62 -0
  8. package/dist/cli-commands.js.map +1 -0
  9. package/dist/cli.d.ts +3 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +66 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/commands/agentsList.d.ts +2 -0
  14. package/dist/commands/agentsList.d.ts.map +1 -0
  15. package/dist/commands/agentsList.js +67 -0
  16. package/dist/commands/agentsList.js.map +1 -0
  17. package/dist/commands/authToken.d.ts +6 -0
  18. package/dist/commands/authToken.d.ts.map +1 -0
  19. package/dist/commands/authToken.js +67 -0
  20. package/dist/commands/authToken.js.map +1 -0
  21. package/dist/commands/connect.d.ts +10 -0
  22. package/dist/commands/connect.d.ts.map +1 -0
  23. package/dist/commands/connect.js +204 -0
  24. package/dist/commands/connect.js.map +1 -0
  25. package/dist/commands/interactiveTUI.d.ts +7 -0
  26. package/dist/commands/interactiveTUI.d.ts.map +1 -0
  27. package/dist/commands/interactiveTUI.js +186 -0
  28. package/dist/commands/interactiveTUI.js.map +1 -0
  29. package/dist/components/ErrorBoundary.d.ts +18 -0
  30. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  31. package/dist/components/ErrorBoundary.js +32 -0
  32. package/dist/components/ErrorBoundary.js.map +1 -0
  33. package/dist/components/InteractiveCLI.d.ts +7 -0
  34. package/dist/components/InteractiveCLI.d.ts.map +1 -0
  35. package/dist/components/InteractiveCLI.js +129 -0
  36. package/dist/components/InteractiveCLI.js.map +1 -0
  37. package/dist/components/REPL.d.ts +7 -0
  38. package/dist/components/REPL.d.ts.map +1 -0
  39. package/dist/components/REPL.js +153 -0
  40. package/dist/components/REPL.js.map +1 -0
  41. package/dist/context/AuthContext.d.ts +28 -0
  42. package/dist/context/AuthContext.d.ts.map +1 -0
  43. package/dist/context/AuthContext.js +14 -0
  44. package/dist/context/AuthContext.js.map +1 -0
  45. package/dist/hooks/useAgent.d.ts +39 -0
  46. package/dist/hooks/useAgent.d.ts.map +1 -0
  47. package/dist/hooks/useAgent.js +125 -0
  48. package/dist/hooks/useAgent.js.map +1 -0
  49. package/dist/hooks/useAuth.d.ts +45 -0
  50. package/dist/hooks/useAuth.d.ts.map +1 -0
  51. package/dist/hooks/useAuth.js +177 -0
  52. package/dist/hooks/useAuth.js.map +1 -0
  53. package/dist/hooks/useSSE.d.ts +32 -0
  54. package/dist/hooks/useSSE.d.ts.map +1 -0
  55. package/dist/hooks/useSSE.js +113 -0
  56. package/dist/hooks/useSSE.js.map +1 -0
  57. package/dist/services/agent.d.ts +13 -0
  58. package/dist/services/agent.d.ts.map +1 -0
  59. package/dist/services/agent.js +114 -0
  60. package/dist/services/agent.js.map +1 -0
  61. package/dist/services/apiClient.d.ts +25 -0
  62. package/dist/services/apiClient.d.ts.map +1 -0
  63. package/dist/services/apiClient.js +258 -0
  64. package/dist/services/apiClient.js.map +1 -0
  65. package/dist/services/auth.d.ts +20 -0
  66. package/dist/services/auth.d.ts.map +1 -0
  67. package/dist/services/auth.js +147 -0
  68. package/dist/services/auth.js.map +1 -0
  69. package/dist/services/sse.d.ts +18 -0
  70. package/dist/services/sse.d.ts.map +1 -0
  71. package/dist/services/sse.js +153 -0
  72. package/dist/services/sse.js.map +1 -0
  73. package/dist/services/task.d.ts +15 -0
  74. package/dist/services/task.d.ts.map +1 -0
  75. package/dist/services/task.js +110 -0
  76. package/dist/services/task.js.map +1 -0
  77. package/dist/tui.d.ts +6 -0
  78. package/dist/tui.d.ts.map +1 -0
  79. package/dist/tui.js +94 -0
  80. package/dist/tui.js.map +1 -0
  81. package/dist/types/index.d.ts +119 -0
  82. package/dist/types/index.d.ts.map +1 -0
  83. package/dist/types/index.js +2 -0
  84. package/dist/types/index.js.map +1 -0
  85. package/dist/utils/config.d.ts +14 -0
  86. package/dist/utils/config.d.ts.map +1 -0
  87. package/dist/utils/config.js +146 -0
  88. package/dist/utils/config.js.map +1 -0
  89. package/dist/utils/error.d.ts +33 -0
  90. package/dist/utils/error.d.ts.map +1 -0
  91. package/dist/utils/error.js +83 -0
  92. package/dist/utils/error.js.map +1 -0
  93. package/dist/utils/formatting.d.ts +18 -0
  94. package/dist/utils/formatting.d.ts.map +1 -0
  95. package/dist/utils/formatting.js +62 -0
  96. package/dist/utils/formatting.js.map +1 -0
  97. package/dist/utils/logger.d.ts +14 -0
  98. package/dist/utils/logger.d.ts.map +1 -0
  99. package/dist/utils/logger.js +49 -0
  100. package/dist/utils/logger.js.map +1 -0
  101. package/dist/utils/signals.d.ts +10 -0
  102. package/dist/utils/signals.d.ts.map +1 -0
  103. package/dist/utils/signals.js +71 -0
  104. package/dist/utils/signals.js.map +1 -0
  105. package/dist/utils/storage.d.ts +11 -0
  106. package/dist/utils/storage.d.ts.map +1 -0
  107. package/dist/utils/storage.js +73 -0
  108. package/dist/utils/storage.js.map +1 -0
  109. package/package.json +103 -0
  110. package/readme.md +229 -0
@@ -0,0 +1,114 @@
1
+ import { apiClient } from './apiClient.js';
2
+ import { logger } from '../utils/logger.js';
3
+ import { NetworkError } from '../utils/error.js';
4
+ export class AgentService {
5
+ async fetchAgents(skip = 0, limit = 50, status, search) {
6
+ try {
7
+ const params = new URLSearchParams();
8
+ params.append('skip', String(skip));
9
+ params.append('limit', String(limit));
10
+ if (status) {
11
+ params.append('status', status);
12
+ }
13
+ if (search) {
14
+ params.append('search', search);
15
+ }
16
+ // AgentArea API uses /v1/agents endpoint
17
+ const response = await apiClient
18
+ .getClient()
19
+ .get(`/v1/agents?${params.toString()}`);
20
+ const agentList = {
21
+ agents: response.data.agents,
22
+ total: response.data.total,
23
+ timestamp: new Date(response.data.timestamp),
24
+ };
25
+ logger.debug(`Fetched ${agentList.agents.length} agents`);
26
+ return agentList;
27
+ }
28
+ catch (error) {
29
+ logger.error('Failed to fetch agents:', error);
30
+ throw new NetworkError(`Failed to fetch agents: ${error}`);
31
+ }
32
+ }
33
+ async getAgent(agentId) {
34
+ try {
35
+ const response = await apiClient
36
+ .getClient()
37
+ .get(`/v1/agents/${agentId}`);
38
+ logger.debug(`Fetched agent ${agentId}`);
39
+ return response.data;
40
+ }
41
+ catch (error) {
42
+ logger.error(`Failed to fetch agent ${agentId}:`, error);
43
+ throw new NetworkError(`Failed to fetch agent: ${error}`);
44
+ }
45
+ }
46
+ async getAgentCapabilities(agentId) {
47
+ try {
48
+ // Get agent details which includes capabilities
49
+ const agent = await this.getAgent(agentId);
50
+ logger.debug(`Fetched ${agent.capabilities.length} capabilities for agent ${agentId}`);
51
+ return agent.capabilities;
52
+ }
53
+ catch (error) {
54
+ logger.error(`Failed to fetch capabilities for agent ${agentId}:`, error);
55
+ throw new NetworkError(`Failed to fetch agent capabilities: ${error}`);
56
+ }
57
+ }
58
+ filterAgents(agents, status, search) {
59
+ let filtered = agents;
60
+ if (status) {
61
+ filtered = filtered.filter(agent => agent.status === status);
62
+ }
63
+ if (search) {
64
+ const searchLower = search.toLowerCase();
65
+ filtered = filtered.filter(agent => agent.name.toLowerCase().includes(searchLower) ||
66
+ (agent.description?.toLowerCase().includes(searchLower) ?? false));
67
+ }
68
+ return filtered;
69
+ }
70
+ paginateAgents(agents, skip, limit) {
71
+ return agents.slice(skip, skip + limit);
72
+ }
73
+ async searchAgents(query) {
74
+ try {
75
+ const agentList = await this.fetchAgents(0, 100, undefined, query);
76
+ return agentList.agents;
77
+ }
78
+ catch (error) {
79
+ logger.error('Failed to search agents:', error);
80
+ return [];
81
+ }
82
+ }
83
+ getAgentStatusColor(status) {
84
+ switch (status) {
85
+ case 'online':
86
+ return 'green';
87
+ case 'offline':
88
+ return 'gray';
89
+ case 'busy':
90
+ return 'yellow';
91
+ case 'error':
92
+ return 'red';
93
+ default:
94
+ return 'white';
95
+ }
96
+ }
97
+ getAgentStatusIcon(status) {
98
+ switch (status) {
99
+ case 'online':
100
+ return '🟢';
101
+ case 'offline':
102
+ return '⚪';
103
+ case 'busy':
104
+ return '🟡';
105
+ case 'error':
106
+ return '🔴';
107
+ default:
108
+ return '⚪';
109
+ }
110
+ }
111
+ }
112
+ // Export a singleton instance
113
+ export const agentService = new AgentService();
114
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../source/services/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAG/C,MAAM,OAAO,YAAY;IACxB,KAAK,CAAC,WAAW,CAChB,IAAI,GAAG,CAAC,EACR,KAAK,GAAG,EAAE,EACV,MAAoB,EACpB,MAAe;QAEf,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAEtC,IAAI,MAAM,EAAE,CAAC;gBACZ,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACjC,CAAC;YAED,IAAI,MAAM,EAAE,CAAC;gBACZ,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACjC,CAAC;YAED,yCAAyC;YACzC,MAAM,QAAQ,GAAG,MAAM,SAAS;iBAC9B,SAAS,EAAE;iBACX,GAAG,CACH,cAAc,MAAM,CAAC,QAAQ,EAAE,EAAE,CACjC,CAAC;YAEH,MAAM,SAAS,GAAc;gBAC5B,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM;gBAC5B,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK;gBAC1B,SAAS,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;aAC5C,CAAC;YAEF,MAAM,CAAC,KAAK,CAAC,WAAW,SAAS,CAAC,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC;YAC1D,OAAO,SAAS,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;YAC/C,MAAM,IAAI,YAAY,CAAC,2BAA2B,KAAK,EAAE,CAAC,CAAC;QAC5D,CAAC;IACF,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAe;QAC7B,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,MAAM,SAAS;iBAC9B,SAAS,EAAE;iBACX,GAAG,CAAQ,cAAc,OAAO,EAAE,CAAC,CAAC;YAEtC,MAAM,CAAC,KAAK,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;YACzC,OAAO,QAAQ,CAAC,IAAI,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,KAAK,CAAC,yBAAyB,OAAO,GAAG,EAAE,KAAK,CAAC,CAAC;YACzD,MAAM,IAAI,YAAY,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;QAC3D,CAAC;IACF,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,OAAe;QACzC,IAAI,CAAC;YACJ,gDAAgD;YAChD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC3C,MAAM,CAAC,KAAK,CACX,WAAW,KAAK,CAAC,YAAY,CAAC,MAAM,2BAA2B,OAAO,EAAE,CACxE,CAAC;YACF,OAAO,KAAK,CAAC,YAAY,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,KAAK,CAAC,0CAA0C,OAAO,GAAG,EAAE,KAAK,CAAC,CAAC;YAC1E,MAAM,IAAI,YAAY,CAAC,uCAAuC,KAAK,EAAE,CAAC,CAAC;QACxE,CAAC;IACF,CAAC;IAED,YAAY,CACX,MAAe,EACf,MAAoB,EACpB,MAAe;QAEf,IAAI,QAAQ,GAAG,MAAM,CAAC;QAEtB,IAAI,MAAM,EAAE,CAAC;YACZ,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;QAC9D,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACZ,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;YACzC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CACzB,KAAK,CAAC,EAAE,CACP,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAC9C,CAAC,KAAK,CAAC,WAAW,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,CAClE,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,cAAc,CAAC,MAAe,EAAE,IAAY,EAAE,KAAa;QAC1D,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAa;QAC/B,IAAI,CAAC;YACJ,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YACnE,OAAO,SAAS,CAAC,MAAM,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;YAChD,OAAO,EAAE,CAAC;QACX,CAAC;IACF,CAAC;IAED,mBAAmB,CAAC,MAAmB;QACtC,QAAQ,MAAM,EAAE,CAAC;YAChB,KAAK,QAAQ;gBACZ,OAAO,OAAO,CAAC;YAChB,KAAK,SAAS;gBACb,OAAO,MAAM,CAAC;YACf,KAAK,MAAM;gBACV,OAAO,QAAQ,CAAC;YACjB,KAAK,OAAO;gBACX,OAAO,KAAK,CAAC;YACd;gBACC,OAAO,OAAO,CAAC;QACjB,CAAC;IACF,CAAC;IAED,kBAAkB,CAAC,MAAmB;QACrC,QAAQ,MAAM,EAAE,CAAC;YAChB,KAAK,QAAQ;gBACZ,OAAO,IAAI,CAAC;YACb,KAAK,SAAS;gBACb,OAAO,GAAG,CAAC;YACZ,KAAK,MAAM;gBACV,OAAO,IAAI,CAAC;YACb,KAAK,OAAO;gBACX,OAAO,IAAI,CAAC;YACb;gBACC,OAAO,GAAG,CAAC;QACb,CAAC;IACF,CAAC;CACD;AAED,8BAA8B;AAC9B,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC"}
@@ -0,0 +1,25 @@
1
+ import axios, { type AxiosInstance, type AxiosError } from 'axios';
2
+ import { type AuthToken } from '../types/index.js';
3
+ declare class ApiClient {
4
+ private client;
5
+ private currentToken;
6
+ private on401Callback;
7
+ constructor();
8
+ private setupInterceptors;
9
+ initialize(): Promise<void>;
10
+ setToken(token: AuthToken): void;
11
+ login(email: string, password: string): Promise<AuthToken>;
12
+ refreshToken(): Promise<AuthToken>;
13
+ logout(): Promise<void>;
14
+ private extractCsrfToken;
15
+ private extractSessionToken;
16
+ set401Callback(callback: (error: AxiosError) => Promise<void>): void;
17
+ reinitialize(): void;
18
+ getClient(): AxiosInstance;
19
+ getToken(): AuthToken | null;
20
+ hasToken(): boolean;
21
+ clearToken(): void;
22
+ }
23
+ export declare const apiClient: ApiClient;
24
+ export { axios };
25
+ //# sourceMappingURL=apiClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../source/services/apiClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAC,KAAK,aAAa,EAAE,KAAK,UAAU,EAAC,MAAM,OAAO,CAAC;AAKjE,OAAO,EAAC,KAAK,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAEjD,cAAM,SAAS;IACd,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,aAAa,CAAuD;;IAgB5E,OAAO,CAAC,iBAAiB;IA8DnB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BjC,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAK1B,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAuE1D,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC;IA8BlC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB7B,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,mBAAmB;IAgB3B,cAAc,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIpE,YAAY,IAAI,IAAI;IAgBpB,SAAS,IAAI,aAAa;IAI1B,QAAQ,IAAI,SAAS,GAAG,IAAI;IAI5B,QAAQ,IAAI,OAAO;IAInB,UAAU,IAAI,IAAI;CAIlB;AAGD,eAAO,MAAM,SAAS,WAAkB,CAAC;AAGzC,OAAO,EAAC,KAAK,EAAC,CAAC"}
@@ -0,0 +1,258 @@
1
+ import axios from 'axios';
2
+ import { tokenStorage } from '../utils/storage.js';
3
+ import { configManager } from '../utils/config.js';
4
+ import { logger } from '../utils/logger.js';
5
+ import { NetworkError, AuthenticationError } from '../utils/error.js';
6
+ class ApiClient {
7
+ constructor() {
8
+ Object.defineProperty(this, "client", {
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true,
12
+ value: void 0
13
+ });
14
+ Object.defineProperty(this, "currentToken", {
15
+ enumerable: true,
16
+ configurable: true,
17
+ writable: true,
18
+ value: null
19
+ });
20
+ Object.defineProperty(this, "on401Callback", {
21
+ enumerable: true,
22
+ configurable: true,
23
+ writable: true,
24
+ value: null
25
+ });
26
+ const config = configManager.get();
27
+ this.client = axios.create({
28
+ baseURL: config.apiBaseUrl,
29
+ timeout: config.apiTimeout,
30
+ headers: {
31
+ 'Content-Type': 'application/json',
32
+ },
33
+ });
34
+ this.setupInterceptors();
35
+ }
36
+ setupInterceptors() {
37
+ // Add request interceptor to include auth token
38
+ this.client.interceptors.request.use(config => {
39
+ if (this.currentToken) {
40
+ config.headers.Authorization = `${this.currentToken.tokenType} ${this.currentToken.accessToken}`;
41
+ }
42
+ return config;
43
+ }, error => {
44
+ return Promise.reject(error);
45
+ });
46
+ // Add response interceptor to handle token refresh and 401 errors
47
+ this.client.interceptors.response.use(response => response, async (error) => {
48
+ const originalConfig = error.config;
49
+ // Handle 401 Unauthorized
50
+ if (error.response?.status === 401 &&
51
+ originalConfig &&
52
+ !originalConfig._retry) {
53
+ originalConfig._retry = true;
54
+ try {
55
+ if (this.currentToken?.refreshToken) {
56
+ // Try to refresh token if available
57
+ const newToken = await this.refreshToken();
58
+ this.currentToken = newToken;
59
+ await tokenStorage.saveToken(newToken);
60
+ // Retry the original request with new token
61
+ return this.client(originalConfig);
62
+ }
63
+ else {
64
+ // No refresh token available, invoke callback if set
65
+ if (this.on401Callback) {
66
+ await this.on401Callback(error);
67
+ // After callback, retry the request with potentially updated token
68
+ return this.client(originalConfig);
69
+ }
70
+ }
71
+ }
72
+ catch (refreshError) {
73
+ logger.error('Token refresh failed:', refreshError);
74
+ // Token refresh failed, user needs to re-authenticate
75
+ await tokenStorage.clearToken();
76
+ this.currentToken = null;
77
+ throw new AuthenticationError('Session expired. Please login again.');
78
+ }
79
+ }
80
+ return Promise.reject(error);
81
+ });
82
+ }
83
+ async initialize() {
84
+ try {
85
+ // Load stored token if available
86
+ const storedToken = await tokenStorage.getToken();
87
+ if (storedToken) {
88
+ // Check if token needs refresh
89
+ if (tokenStorage.shouldRefreshToken(storedToken)) {
90
+ logger.debug('Refreshing stored token');
91
+ const newToken = await this.refreshToken();
92
+ this.currentToken = newToken;
93
+ await tokenStorage.saveToken(newToken);
94
+ }
95
+ else {
96
+ this.currentToken = storedToken;
97
+ }
98
+ logger.debug('API client initialized with stored token');
99
+ }
100
+ else {
101
+ logger.debug('No stored token found, API client initialized without auth');
102
+ }
103
+ }
104
+ catch (error) {
105
+ logger.error('Failed to initialize API client:', error);
106
+ throw new NetworkError(`Failed to initialize API client: ${error}`);
107
+ }
108
+ }
109
+ setToken(token) {
110
+ this.currentToken = token;
111
+ logger.debug('API client token updated');
112
+ }
113
+ async login(email, password) {
114
+ try {
115
+ const config = configManager.get();
116
+ // Use Kratos for authentication via self-service API
117
+ // 1. Create a login flow
118
+ const flowResponse = await axios.get(`${config.kratosUrl}/self-service/login/api`, {
119
+ withCredentials: true,
120
+ headers: {
121
+ Accept: 'application/json',
122
+ },
123
+ });
124
+ const flowId = flowResponse.data.id;
125
+ if (!flowId) {
126
+ throw new AuthenticationError('Failed to create login flow');
127
+ }
128
+ logger.debug(`Created login flow: ${flowId}`);
129
+ // 2. Submit login credentials to Kratos
130
+ const submitResponse = await axios.post(`${config.kratosUrl}/self-service/login?flow=${flowId}`, {
131
+ csrf_token: this.extractCsrfToken(flowResponse.data),
132
+ method: 'password',
133
+ password,
134
+ identifier: email,
135
+ }, {
136
+ withCredentials: true,
137
+ validateStatus: () => true,
138
+ });
139
+ // Check if login was successful (Kratos redirects on success)
140
+ if (submitResponse.status >= 400) {
141
+ throw new AuthenticationError('Invalid email or password');
142
+ }
143
+ // Extract session token from cookies (Kratos sets ory_kratos_session)
144
+ const sessionToken = this.extractSessionToken(submitResponse.headers);
145
+ if (!sessionToken) {
146
+ throw new AuthenticationError('Failed to obtain session token');
147
+ }
148
+ const token = {
149
+ accessToken: sessionToken,
150
+ tokenType: 'Bearer',
151
+ expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24h default
152
+ };
153
+ this.currentToken = token;
154
+ logger.info('Successfully logged in');
155
+ return token;
156
+ }
157
+ catch (error) {
158
+ logger.error('Login failed:', error);
159
+ if (error instanceof AuthenticationError) {
160
+ throw error;
161
+ }
162
+ throw new NetworkError(`Login failed: ${error}`);
163
+ }
164
+ }
165
+ async refreshToken() {
166
+ try {
167
+ if (!this.currentToken?.refreshToken) {
168
+ throw new AuthenticationError('No refresh token available');
169
+ }
170
+ const response = await this.client.post('/auth/refresh', {
171
+ refreshToken: this.currentToken.refreshToken,
172
+ });
173
+ const token = {
174
+ accessToken: response.data.accessToken,
175
+ refreshToken: this.currentToken.refreshToken,
176
+ tokenType: 'Bearer',
177
+ expiresAt: response.data.expiresIn
178
+ ? new Date(Date.now() + response.data.expiresIn * 1000)
179
+ : undefined,
180
+ };
181
+ logger.debug('Token refreshed successfully');
182
+ return token;
183
+ }
184
+ catch (error) {
185
+ logger.error('Token refresh failed:', error);
186
+ throw new AuthenticationError(`Token refresh failed: ${error}`);
187
+ }
188
+ }
189
+ async logout() {
190
+ try {
191
+ const config = configManager.get();
192
+ // Logout from Kratos
193
+ await axios.get(`${config.kratosUrl}/self-service/logout/browser`, {
194
+ withCredentials: true,
195
+ });
196
+ this.currentToken = null;
197
+ logger.info('Successfully logged out');
198
+ }
199
+ catch (error) {
200
+ logger.warn('Logout failed (may be expected if session already expired):', error);
201
+ // Clear token anyway
202
+ this.currentToken = null;
203
+ }
204
+ }
205
+ extractCsrfToken(html) {
206
+ // Extract CSRF token from Kratos login form HTML
207
+ const match = html.match(/name="csrf_token"\s+value="([^"]+)"/);
208
+ return match ? match[1] : '';
209
+ }
210
+ extractSessionToken(headers) {
211
+ // Extract session token from Set-Cookie header
212
+ const setCookie = headers['set-cookie'];
213
+ if (Array.isArray(setCookie)) {
214
+ for (const cookie of setCookie) {
215
+ if (cookie.includes('ory_kratos_session')) {
216
+ const match = cookie.match(/ory_kratos_session=([^;]+)/);
217
+ if (match) {
218
+ return match[1];
219
+ }
220
+ }
221
+ }
222
+ }
223
+ return null;
224
+ }
225
+ set401Callback(callback) {
226
+ this.on401Callback = callback;
227
+ }
228
+ reinitialize() {
229
+ const config = configManager.get();
230
+ this.client = axios.create({
231
+ baseURL: config.apiBaseUrl,
232
+ timeout: config.apiTimeout,
233
+ headers: {
234
+ 'Content-Type': 'application/json',
235
+ },
236
+ });
237
+ this.setupInterceptors();
238
+ logger.debug('API client reinitialized');
239
+ }
240
+ getClient() {
241
+ return this.client;
242
+ }
243
+ getToken() {
244
+ return this.currentToken;
245
+ }
246
+ hasToken() {
247
+ return this.currentToken !== null;
248
+ }
249
+ clearToken() {
250
+ this.currentToken = null;
251
+ logger.debug('API client token cleared');
252
+ }
253
+ }
254
+ // Export a singleton instance
255
+ export const apiClient = new ApiClient();
256
+ // Make axios error checking available
257
+ export { axios };
258
+ //# sourceMappingURL=apiClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiClient.js","sourceRoot":"","sources":["../../source/services/apiClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type AuthToken, type User } from '../types/index.js';
2
+ export declare class AuthService {
3
+ private currentUser;
4
+ initialize(): Promise<void>;
5
+ login(email: string, password: string): Promise<{
6
+ token: AuthToken;
7
+ user: User;
8
+ }>;
9
+ logout(): Promise<void>;
10
+ refreshToken(): Promise<AuthToken>;
11
+ isAuthenticated(): Promise<boolean>;
12
+ getToken(): Promise<AuthToken | null>;
13
+ getCurrentUser(): User | null;
14
+ setCurrentUser(user: User): void;
15
+ clearCurrentUser(): void;
16
+ private isValidEmail;
17
+ private extractIdFromToken;
18
+ }
19
+ export declare const authService: AuthService;
20
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../source/services/auth.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,KAAK,SAAS,EAAE,KAAK,IAAI,EAAC,MAAM,mBAAmB,CAAC;AAE5D,qBAAa,WAAW;IACvB,OAAO,CAAC,WAAW,CAAqB;IAElC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B,KAAK,CACV,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC;QAAC,KAAK,EAAE,SAAS,CAAC;QAAC,IAAI,EAAE,IAAI,CAAA;KAAC,CAAC;IAmCpC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAevB,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC;IAYlC,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAwBnC,QAAQ,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAS3C,cAAc,IAAI,IAAI,GAAG,IAAI;IAI7B,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAIhC,gBAAgB,IAAI,IAAI;IAIxB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,kBAAkB;CAe1B;AAGD,eAAO,MAAM,WAAW,aAAoB,CAAC"}
@@ -0,0 +1,147 @@
1
+ import { apiClient } from './apiClient.js';
2
+ import { tokenStorage } from '../utils/storage.js';
3
+ import { logger } from '../utils/logger.js';
4
+ import { AuthenticationError } from '../utils/error.js';
5
+ export class AuthService {
6
+ constructor() {
7
+ Object.defineProperty(this, "currentUser", {
8
+ enumerable: true,
9
+ configurable: true,
10
+ writable: true,
11
+ value: null
12
+ });
13
+ }
14
+ async initialize() {
15
+ try {
16
+ await apiClient.initialize();
17
+ // Try to load stored token
18
+ const token = await tokenStorage.getToken();
19
+ if (token) {
20
+ apiClient.setToken(token);
21
+ logger.debug('Auth service initialized with stored token');
22
+ }
23
+ }
24
+ catch (error) {
25
+ logger.error('Failed to initialize auth service:', error);
26
+ }
27
+ }
28
+ async login(email, password) {
29
+ try {
30
+ // Validate input
31
+ if (!email || !password) {
32
+ throw new AuthenticationError('Email and password are required');
33
+ }
34
+ if (!this.isValidEmail(email)) {
35
+ throw new AuthenticationError('Invalid email format');
36
+ }
37
+ // Login via API
38
+ const token = await apiClient.login(email, password);
39
+ // Store token
40
+ await tokenStorage.saveToken(token);
41
+ // Extract user info from token (normally would be in response, but for now using email)
42
+ const user = {
43
+ id: this.extractIdFromToken(token.accessToken),
44
+ email,
45
+ createdAt: new Date(),
46
+ lastLoginAt: new Date(),
47
+ };
48
+ this.currentUser = user;
49
+ logger.info(`User logged in: ${email}`);
50
+ return { token, user };
51
+ }
52
+ catch (error) {
53
+ logger.error('Login failed:', error);
54
+ throw error;
55
+ }
56
+ }
57
+ async logout() {
58
+ try {
59
+ await apiClient.logout();
60
+ await tokenStorage.clearToken();
61
+ this.currentUser = null;
62
+ logger.info('User logged out');
63
+ }
64
+ catch (error) {
65
+ logger.error('Logout failed:', error);
66
+ // Still clear local state even if API call fails
67
+ await tokenStorage.clearToken();
68
+ this.currentUser = null;
69
+ throw error;
70
+ }
71
+ }
72
+ async refreshToken() {
73
+ try {
74
+ const newToken = await apiClient.refreshToken();
75
+ await tokenStorage.saveToken(newToken);
76
+ logger.debug('Token refreshed successfully');
77
+ return newToken;
78
+ }
79
+ catch (error) {
80
+ logger.error('Token refresh failed:', error);
81
+ throw error;
82
+ }
83
+ }
84
+ async isAuthenticated() {
85
+ try {
86
+ const token = await tokenStorage.getToken();
87
+ if (!token) {
88
+ return false;
89
+ }
90
+ if (tokenStorage.isTokenExpired(token)) {
91
+ // Try to refresh
92
+ try {
93
+ await this.refreshToken();
94
+ return true;
95
+ }
96
+ catch {
97
+ return false;
98
+ }
99
+ }
100
+ return true;
101
+ }
102
+ catch (error) {
103
+ logger.error('Error checking authentication:', error);
104
+ return false;
105
+ }
106
+ }
107
+ async getToken() {
108
+ try {
109
+ return await tokenStorage.getToken();
110
+ }
111
+ catch (error) {
112
+ logger.error('Error getting token:', error);
113
+ return null;
114
+ }
115
+ }
116
+ getCurrentUser() {
117
+ return this.currentUser;
118
+ }
119
+ setCurrentUser(user) {
120
+ this.currentUser = user;
121
+ }
122
+ clearCurrentUser() {
123
+ this.currentUser = null;
124
+ }
125
+ isValidEmail(email) {
126
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
127
+ return emailRegex.test(email);
128
+ }
129
+ extractIdFromToken(token) {
130
+ // In a real scenario, you would decode the JWT and extract the user ID
131
+ // For now, we'll use a placeholder
132
+ try {
133
+ const parts = token.split('.');
134
+ if (parts.length === 3) {
135
+ const decoded = JSON.parse(Buffer.from(parts[1], 'base64').toString());
136
+ return decoded.sub || decoded.id || 'unknown';
137
+ }
138
+ }
139
+ catch (error) {
140
+ logger.debug('Could not decode token payload');
141
+ }
142
+ return 'unknown';
143
+ }
144
+ }
145
+ // Export a singleton instance
146
+ export const authService = new AuthService();
147
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../source/services/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { type TaskOutputEvent } from '../types/index.js';
2
+ export type SSEEventHandler = (event: TaskOutputEvent) => void;
3
+ export type SSEErrorHandler = (error: Error) => void;
4
+ export declare class SSEService {
5
+ private eventSources;
6
+ private handlers;
7
+ private reconnectAttempts;
8
+ private maxReconnectAttempts;
9
+ private reconnectDelay;
10
+ connect(taskId: string, onMessage: SSEEventHandler, onError: SSEErrorHandler, token?: string): Promise<void>;
11
+ private handleConnectionError;
12
+ disconnect(taskId: string): void;
13
+ disconnectAll(): void;
14
+ isConnected(taskId: string): boolean;
15
+ getActiveConnections(): string[];
16
+ }
17
+ export declare const sseService: SSEService;
18
+ //# sourceMappingURL=sse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../source/services/sse.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,KAAK,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAEvD,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;AAC/D,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAErD,qBAAa,UAAU;IACtB,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,QAAQ,CAGF;IACd,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,oBAAoB,CAAK;IACjC,OAAO,CAAC,cAAc,CAAQ;IAExB,OAAO,CACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,eAAe,EAC1B,OAAO,EAAE,eAAe,EACxB,KAAK,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC;IAmFhB,OAAO,CAAC,qBAAqB;IAgC7B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAahC,aAAa,IAAI,IAAI;IAYrB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAOpC,oBAAoB,IAAI,MAAM,EAAE;CAGhC;AAGD,eAAO,MAAM,UAAU,YAAmB,CAAC"}