@elizaos/cli 1.3.1 → 1.4.2

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 (198) hide show
  1. package/README.md +47 -1
  2. package/dist/{bun-exec-6CQHTS4F.js → bun-exec-ULMPAIQC.js} +1 -1
  3. package/dist/{chunk-2ALAPQLV.js → chunk-D3QSET5H.js} +342 -360
  4. package/dist/{chunk-FDEDLANP.js → chunk-FQYWRHLX.js} +1 -1
  5. package/dist/{chunk-RM6LUTKD.js → chunk-FSSUAWXQ.js} +3 -3
  6. package/dist/chunk-GXWWPFBO.js +39 -0
  7. package/dist/{chunk-D3Q2UZLZ.js → chunk-I4L4T7QX.js} +1 -1
  8. package/dist/{chunk-KDNV7EA5.js → chunk-SMZBJQJR.js} +1 -1
  9. package/dist/commands/agent/actions/index.d.ts +5 -0
  10. package/dist/commands/agent/actions/index.js +4 -4
  11. package/dist/commands/agent/index.d.ts +2 -2
  12. package/dist/commands/agent/index.js +4 -4
  13. package/dist/commands/create/actions/index.js +5 -5
  14. package/dist/commands/create/index.js +6 -6
  15. package/dist/commands/shared/index.d.ts +11 -28
  16. package/dist/commands/shared/index.js +7 -3
  17. package/dist/index.js +599 -483
  18. package/dist/{plugin-creator-H26ZLR6H.js → plugin-creator-TCUFII32.js} +2 -2
  19. package/dist/{registry-N626N4VG.js → registry-RF6PW3EN.js} +4 -4
  20. package/dist/templates/plugin-quick-starter/README.md +52 -10
  21. package/dist/templates/plugin-quick-starter/package.json +10 -3
  22. package/dist/templates/plugin-quick-starter/src/__tests__/e2e/README.md +140 -0
  23. package/dist/templates/plugin-quick-starter/src/__tests__/e2e/plugin-quick-starter.e2e.ts +339 -0
  24. package/dist/templates/plugin-quick-starter/src/__tests__/plugin.test.ts +537 -146
  25. package/dist/templates/plugin-quick-starter/src/__tests__/test-utils.ts +316 -115
  26. package/dist/templates/plugin-quick-starter/src/plugin.ts +20 -26
  27. package/dist/templates/plugin-starter/README.md +124 -49
  28. package/dist/templates/plugin-starter/package.json +10 -3
  29. package/dist/templates/plugin-starter/src/__tests__/e2e/README.md +44 -9
  30. package/{templates/plugin-starter/src/__tests__/e2e/starter-plugin.ts → dist/templates/plugin-starter/src/__tests__/e2e/plugin-starter.e2e.ts} +13 -20
  31. package/dist/templates/plugin-starter/src/__tests__/integration.test.ts +13 -13
  32. package/dist/templates/plugin-starter/src/__tests__/plugin.test.ts +556 -129
  33. package/dist/templates/plugin-starter/src/__tests__/test-utils.ts +347 -115
  34. package/dist/templates/plugin-starter/src/plugin.ts +21 -27
  35. package/dist/templates/project-starter/README.md +25 -12
  36. package/dist/templates/project-starter/package.json +4 -4
  37. package/dist/templates/project-starter/src/__tests__/actions.test.ts +2 -2
  38. package/dist/templates/project-starter/src/__tests__/e2e/README.md +103 -0
  39. package/dist/templates/project-starter/src/__tests__/e2e/project-starter.e2e.ts +575 -0
  40. package/dist/templates/project-starter/src/__tests__/env.test.ts +3 -1
  41. package/dist/templates/project-starter/src/__tests__/file-structure.test.ts +3 -2
  42. package/dist/templates/project-starter/src/__tests__/integration.test.ts +2 -2
  43. package/dist/templates/project-starter/src/__tests__/models.test.ts +3 -3
  44. package/dist/templates/project-starter/src/__tests__/plugin.test.ts +3 -3
  45. package/dist/templates/project-starter/src/__tests__/provider.test.ts +2 -2
  46. package/dist/templates/project-starter/src/index.ts +4 -3
  47. package/dist/templates/project-starter/src/plugin.ts +5 -5
  48. package/dist/templates/project-starter/tsup.config.ts +2 -1
  49. package/dist/templates/project-tee-starter/.dockerignore +64 -14
  50. package/dist/templates/project-tee-starter/Dockerfile +9 -5
  51. package/dist/templates/project-tee-starter/GUIDE.md +103 -42
  52. package/dist/templates/project-tee-starter/README.md +83 -24
  53. package/dist/templates/project-tee-starter/docker-compose.yaml +5 -2
  54. package/dist/templates/{plugin-starter/dist → project-tee-starter}/index.html +3 -3
  55. package/dist/templates/project-tee-starter/package.json +34 -14
  56. package/dist/templates/project-tee-starter/postcss.config.js +3 -0
  57. package/dist/templates/project-tee-starter/scripts/install-test-deps.js +52 -0
  58. package/dist/templates/project-tee-starter/scripts/test-all.sh +82 -0
  59. package/dist/templates/project-tee-starter/src/__tests__/build-order.test.ts +62 -0
  60. package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/character.test.ts +20 -18
  61. package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/config.test.ts +11 -4
  62. package/dist/templates/project-tee-starter/src/__tests__/e2e/README.md +128 -0
  63. package/dist/templates/project-tee-starter/src/__tests__/e2e/project-tee-starter.e2e.ts +280 -0
  64. package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/env.test.ts +3 -2
  65. package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/error-handling.test.ts +2 -2
  66. package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/events.test.ts +1 -1
  67. package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/file-structure.test.ts +16 -5
  68. package/dist/templates/project-tee-starter/src/__tests__/frontend.test.ts +459 -0
  69. package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/integration.test.ts +2 -2
  70. package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/models.test.ts +1 -1
  71. package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/plugin.test.ts +5 -3
  72. package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/provider.test.ts +2 -2
  73. package/dist/templates/project-tee-starter/src/__tests__/routes.test.ts +30 -0
  74. package/dist/templates/project-tee-starter/src/__tests__/tee-validation.test.ts +295 -0
  75. package/{templates/project-tee-starter → dist/templates/project-tee-starter/src}/__tests__/test-utils.ts +2 -2
  76. package/dist/templates/project-tee-starter/src/__tests__/vite-config-utils.ts +51 -0
  77. package/dist/templates/project-tee-starter/src/frontend/index.css +106 -0
  78. package/dist/templates/project-tee-starter/src/frontend/index.html +20 -0
  79. package/dist/templates/project-tee-starter/src/frontend/index.tsx +370 -0
  80. package/dist/templates/project-tee-starter/src/frontend/panels.tsx +17 -0
  81. package/dist/templates/project-tee-starter/src/frontend/utils.ts +6 -0
  82. package/dist/templates/project-tee-starter/src/index.ts +8 -6
  83. package/dist/templates/project-tee-starter/src/plugin.ts +223 -61
  84. package/dist/templates/project-tee-starter/tailwind.config.js +62 -0
  85. package/dist/templates/project-tee-starter/tsconfig.build.json +2 -2
  86. package/dist/templates/project-tee-starter/tsconfig.json +8 -5
  87. package/dist/templates/project-tee-starter/tsup.config.ts +3 -2
  88. package/dist/templates/project-tee-starter/vite.config.ts +39 -0
  89. package/dist/url-utils-CKc_Ebt_.d.ts +35 -0
  90. package/dist/{utils-H66532NB.js → utils-5HPZSIF6.js} +4 -4
  91. package/package.json +7 -6
  92. package/templates/plugin-quick-starter/README.md +52 -10
  93. package/templates/plugin-quick-starter/package.json +10 -3
  94. package/templates/plugin-quick-starter/src/__tests__/e2e/README.md +140 -0
  95. package/templates/plugin-quick-starter/src/__tests__/e2e/plugin-quick-starter.e2e.ts +339 -0
  96. package/templates/plugin-quick-starter/src/__tests__/plugin.test.ts +537 -146
  97. package/templates/plugin-quick-starter/src/__tests__/test-utils.ts +316 -115
  98. package/templates/plugin-quick-starter/src/plugin.ts +20 -26
  99. package/templates/plugin-starter/README.md +124 -49
  100. package/templates/plugin-starter/package.json +10 -3
  101. package/templates/plugin-starter/src/__tests__/e2e/README.md +44 -9
  102. package/{dist/templates/plugin-starter/src/__tests__/e2e/starter-plugin.ts → templates/plugin-starter/src/__tests__/e2e/plugin-starter.e2e.ts} +13 -20
  103. package/templates/plugin-starter/src/__tests__/integration.test.ts +13 -13
  104. package/templates/plugin-starter/src/__tests__/plugin.test.ts +556 -129
  105. package/templates/plugin-starter/src/__tests__/test-utils.ts +347 -115
  106. package/templates/plugin-starter/src/plugin.ts +21 -27
  107. package/templates/project-starter/README.md +25 -12
  108. package/templates/project-starter/package.json +4 -4
  109. package/templates/project-starter/src/__tests__/actions.test.ts +2 -2
  110. package/templates/project-starter/src/__tests__/e2e/README.md +103 -0
  111. package/templates/project-starter/src/__tests__/e2e/project-starter.e2e.ts +575 -0
  112. package/templates/project-starter/src/__tests__/env.test.ts +3 -1
  113. package/templates/project-starter/src/__tests__/file-structure.test.ts +3 -2
  114. package/templates/project-starter/src/__tests__/integration.test.ts +2 -2
  115. package/templates/project-starter/src/__tests__/models.test.ts +3 -3
  116. package/templates/project-starter/src/__tests__/plugin.test.ts +3 -3
  117. package/templates/project-starter/src/__tests__/provider.test.ts +2 -2
  118. package/templates/project-starter/src/index.ts +4 -3
  119. package/templates/project-starter/src/plugin.ts +5 -5
  120. package/templates/project-starter/tsup.config.ts +2 -1
  121. package/templates/project-tee-starter/.dockerignore +64 -14
  122. package/templates/project-tee-starter/Dockerfile +9 -5
  123. package/templates/project-tee-starter/GUIDE.md +103 -42
  124. package/templates/project-tee-starter/README.md +83 -24
  125. package/templates/project-tee-starter/docker-compose.yaml +5 -2
  126. package/templates/{plugin-starter/dist → project-tee-starter}/index.html +3 -3
  127. package/templates/project-tee-starter/package.json +34 -14
  128. package/templates/project-tee-starter/postcss.config.js +3 -0
  129. package/templates/project-tee-starter/scripts/install-test-deps.js +52 -0
  130. package/templates/project-tee-starter/scripts/test-all.sh +82 -0
  131. package/templates/project-tee-starter/src/__tests__/build-order.test.ts +62 -0
  132. package/templates/project-tee-starter/{__tests__ → src/__tests__}/character.test.ts +20 -18
  133. package/templates/project-tee-starter/{__tests__ → src/__tests__}/config.test.ts +11 -4
  134. package/templates/project-tee-starter/src/__tests__/e2e/README.md +128 -0
  135. package/templates/project-tee-starter/src/__tests__/e2e/project-tee-starter.e2e.ts +280 -0
  136. package/templates/project-tee-starter/{__tests__ → src/__tests__}/env.test.ts +3 -2
  137. package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/error-handling.test.ts +2 -2
  138. package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/events.test.ts +1 -1
  139. package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/file-structure.test.ts +16 -5
  140. package/templates/project-tee-starter/src/__tests__/frontend.test.ts +459 -0
  141. package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/integration.test.ts +2 -2
  142. package/templates/project-tee-starter/{__tests__ → src/__tests__}/models.test.ts +1 -1
  143. package/templates/project-tee-starter/{__tests__ → src/__tests__}/plugin.test.ts +5 -3
  144. package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/provider.test.ts +2 -2
  145. package/templates/project-tee-starter/src/__tests__/routes.test.ts +30 -0
  146. package/templates/project-tee-starter/src/__tests__/tee-validation.test.ts +295 -0
  147. package/{dist/templates/project-tee-starter → templates/project-tee-starter/src}/__tests__/test-utils.ts +2 -2
  148. package/templates/project-tee-starter/src/__tests__/vite-config-utils.ts +51 -0
  149. package/templates/project-tee-starter/src/frontend/index.css +106 -0
  150. package/templates/project-tee-starter/src/frontend/index.html +20 -0
  151. package/templates/project-tee-starter/src/frontend/index.tsx +370 -0
  152. package/templates/project-tee-starter/src/frontend/panels.tsx +17 -0
  153. package/templates/project-tee-starter/src/frontend/utils.ts +6 -0
  154. package/templates/project-tee-starter/src/index.ts +8 -6
  155. package/templates/project-tee-starter/src/plugin.ts +223 -61
  156. package/templates/project-tee-starter/tailwind.config.js +62 -0
  157. package/templates/project-tee-starter/tsconfig.build.json +2 -2
  158. package/templates/project-tee-starter/tsconfig.json +8 -5
  159. package/templates/project-tee-starter/tsup.config.ts +3 -2
  160. package/templates/project-tee-starter/vite.config.ts +39 -0
  161. package/dist/chunk-4O6EZU37.js +0 -14
  162. package/dist/migration-guides/advanced-migration-guide.md +0 -459
  163. package/dist/migration-guides/completion-requirements.md +0 -379
  164. package/dist/migration-guides/integrated-migration-loop.md +0 -392
  165. package/dist/migration-guides/migration-guide.md +0 -712
  166. package/dist/migration-guides/prompt-and-generation-guide.md +0 -702
  167. package/dist/migration-guides/state-and-providers-guide.md +0 -544
  168. package/dist/migration-guides/testing-guide.md +0 -1021
  169. package/dist/templates/plugin-starter/dist/assets/index-CgkejLs_.css +0 -1
  170. package/dist/templates/plugin-starter/dist/assets/index-D1cHX53P.js +0 -49
  171. package/dist/templates/plugin-starter/dist/index.js +0 -387
  172. package/dist/templates/plugin-starter/dist/index.js.map +0 -1
  173. package/dist/templates/plugin-starter/src/tests.ts +0 -6
  174. package/dist/templates/project-starter/src/__tests__/e2e/index.ts +0 -14
  175. package/dist/templates/project-starter/src/__tests__/e2e/natural-language.test.ts +0 -246
  176. package/dist/templates/project-starter/src/__tests__/e2e/project.test.ts +0 -155
  177. package/dist/templates/project-starter/src/__tests__/e2e/starter-plugin.test.ts +0 -421
  178. package/dist/templates/project-tee-starter/__tests__/routes.test.ts +0 -21
  179. package/dist/templates/project-tee-starter/e2e/project.test.ts +0 -38
  180. package/dist/templates/project-tee-starter/e2e/starter-plugin.test.ts +0 -92
  181. package/templates/plugin-starter/dist/.vite/manifest.json +0 -11
  182. package/templates/plugin-starter/dist/assets/index-CgkejLs_.css +0 -1
  183. package/templates/plugin-starter/dist/assets/index-D1cHX53P.js +0 -49
  184. package/templates/plugin-starter/dist/index.d.ts +0 -14
  185. package/templates/plugin-starter/dist/index.js +0 -387
  186. package/templates/plugin-starter/dist/index.js.map +0 -1
  187. package/templates/plugin-starter/src/tests.ts +0 -6
  188. package/templates/project-starter/src/__tests__/e2e/index.ts +0 -14
  189. package/templates/project-starter/src/__tests__/e2e/natural-language.test.ts +0 -246
  190. package/templates/project-starter/src/__tests__/e2e/project.test.ts +0 -155
  191. package/templates/project-starter/src/__tests__/e2e/starter-plugin.test.ts +0 -421
  192. package/templates/project-tee-starter/__tests__/routes.test.ts +0 -21
  193. package/templates/project-tee-starter/e2e/project.test.ts +0 -38
  194. package/templates/project-tee-starter/e2e/starter-plugin.test.ts +0 -92
  195. /package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/actions.test.ts +0 -0
  196. /package/dist/templates/project-tee-starter/{__tests__ → src/__tests__}/utils/core-test-utils.ts +0 -0
  197. /package/templates/project-tee-starter/{__tests__ → src/__tests__}/actions.test.ts +0 -0
  198. /package/templates/project-tee-starter/{__tests__ → src/__tests__}/utils/core-test-utils.ts +0 -0
@@ -0,0 +1,459 @@
1
+ import { describe, test, expect, beforeEach, afterEach, mock } from 'bun:test';
2
+ import * as React from 'react';
3
+
4
+ // Setup DOM environment for testing
5
+ import { JSDOM } from 'jsdom';
6
+ const dom = new JSDOM('<!DOCTYPE html><html><body><div id="root"></div></body></html>', {
7
+ url: 'http://localhost',
8
+ pretendToBeVisual: true,
9
+ resources: 'usable',
10
+ });
11
+
12
+ // Setup global objects
13
+ global.window = dom.window as any;
14
+ global.document = dom.window.document;
15
+ global.navigator = dom.window.navigator;
16
+ global.HTMLElement = dom.window.HTMLElement;
17
+ global.Element = dom.window.Element;
18
+
19
+ // Extend Window interface for TypeScript
20
+ declare global {
21
+ interface Window {
22
+ ELIZA_CONFIG?: {
23
+ agentId: string;
24
+ apiBase: string;
25
+ };
26
+ }
27
+ }
28
+
29
+ // Mock the frontend components
30
+ const mockFetch = mock() as any;
31
+ global.fetch = mockFetch;
32
+
33
+ // Mock window.ELIZA_CONFIG
34
+ Object.defineProperty(global.window, 'ELIZA_CONFIG', {
35
+ value: {
36
+ agentId: 'test-agent-123',
37
+ apiBase: 'http://localhost:3000',
38
+ },
39
+ writable: true,
40
+ });
41
+
42
+ // Mock document.getElementById for React rendering
43
+ const mockRoot = {
44
+ render: mock(),
45
+ };
46
+
47
+ Object.defineProperty(global.document, 'getElementById', {
48
+ value: mock(() => mockRoot),
49
+ writable: true,
50
+ });
51
+
52
+ // Mock createRoot
53
+ mock.module('react-dom/client', () => ({
54
+ createRoot: mock(() => mockRoot),
55
+ }));
56
+
57
+ describe('TEE Frontend Components', () => {
58
+ beforeEach(() => {
59
+ mockFetch.mockClear();
60
+ });
61
+
62
+ afterEach(() => {
63
+ // Cleanup if needed
64
+ });
65
+
66
+ describe('TEE Status API Response Handling', () => {
67
+ test('should handle successful TEE status response', async () => {
68
+ const mockResponse = {
69
+ message: 'Mr. TEE is operational, fool!',
70
+ tee_mode: 'development',
71
+ tee_vendor: 'intel',
72
+ timestamp: '2024-01-01T00:00:00.000Z',
73
+ };
74
+
75
+ mockFetch.mockResolvedValueOnce({
76
+ ok: true,
77
+ json: async () => mockResponse,
78
+ });
79
+
80
+ // Test the fetch logic directly
81
+ const response = await fetch('/mr-tee-status');
82
+ const data = await response.json();
83
+
84
+ expect(fetch).toHaveBeenCalledWith('/mr-tee-status');
85
+ expect(data).toEqual(mockResponse);
86
+ expect(data.tee_mode).toBe('development');
87
+ expect(data.tee_vendor).toBe('intel');
88
+ });
89
+
90
+ test('should handle network failure with proper error categorization', async () => {
91
+ const networkError = new Error('Failed to fetch');
92
+ networkError.name = 'NetworkError';
93
+
94
+ mockFetch.mockRejectedValueOnce(networkError);
95
+
96
+ try {
97
+ await fetch('/mr-tee-status');
98
+ } catch (error) {
99
+ expect(error).toBeInstanceOf(Error);
100
+ expect((error as Error).name).toBe('NetworkError');
101
+ }
102
+ });
103
+
104
+ test('should handle timeout errors', async () => {
105
+ const timeoutError = new Error('Request timeout');
106
+ timeoutError.name = 'AbortError';
107
+
108
+ mockFetch.mockRejectedValueOnce(timeoutError);
109
+
110
+ try {
111
+ await fetch('/mr-tee-status');
112
+ } catch (error) {
113
+ expect(error).toBeInstanceOf(Error);
114
+ expect((error as Error).name).toBe('AbortError');
115
+ }
116
+ });
117
+
118
+ test('should handle server errors (5xx)', async () => {
119
+ mockFetch.mockResolvedValueOnce({
120
+ ok: false,
121
+ status: 500,
122
+ statusText: 'Internal Server Error',
123
+ });
124
+
125
+ const response = await fetch('/mr-tee-status');
126
+ expect(response.ok).toBe(false);
127
+ expect(response.status).toBe(500);
128
+ });
129
+ });
130
+
131
+ describe('TEE Error Classification', () => {
132
+ // Test the error classification logic from the frontend
133
+ const createNetworkError = (error: Error) => {
134
+ // Network failure detection
135
+ if (error.name === 'NetworkError' || error.message.includes('Failed to fetch')) {
136
+ return {
137
+ type: 'network',
138
+ message: 'Network connection failed',
139
+ details: 'Unable to reach the TEE service. Please check your connection.',
140
+ retryable: true,
141
+ };
142
+ }
143
+
144
+ // Timeout detection
145
+ if (error.name === 'AbortError' || error.message.includes('timeout')) {
146
+ return {
147
+ type: 'timeout',
148
+ message: 'Request timeout',
149
+ details: 'The TEE service is taking too long to respond.',
150
+ retryable: true,
151
+ };
152
+ }
153
+
154
+ // Server error detection
155
+ if (error.message.includes('5')) {
156
+ return {
157
+ type: 'server',
158
+ message: 'Server error',
159
+ details: 'The TEE service encountered an internal error.',
160
+ retryable: true,
161
+ };
162
+ }
163
+
164
+ return {
165
+ type: 'unknown',
166
+ message: error.message || 'An unknown error occurred',
167
+ details: 'Please try again or contact support if the problem persists.',
168
+ retryable: true,
169
+ };
170
+ };
171
+
172
+ test('should classify network errors correctly', () => {
173
+ const networkError = new Error('Failed to fetch');
174
+ networkError.name = 'NetworkError';
175
+
176
+ const classified = createNetworkError(networkError);
177
+
178
+ expect(classified.type).toBe('network');
179
+ expect(classified.retryable).toBe(true);
180
+ expect(classified.message).toBe('Network connection failed');
181
+ });
182
+
183
+ test('should classify timeout errors correctly', () => {
184
+ const timeoutError = new Error('Request timeout');
185
+ timeoutError.name = 'AbortError';
186
+
187
+ const classified = createNetworkError(timeoutError);
188
+
189
+ expect(classified.type).toBe('timeout');
190
+ expect(classified.retryable).toBe(true);
191
+ expect(classified.message).toBe('Request timeout');
192
+ });
193
+
194
+ test('should classify server errors correctly', () => {
195
+ const serverError = new Error('HTTP 500: Internal Server Error');
196
+
197
+ const classified = createNetworkError(serverError);
198
+
199
+ expect(classified.type).toBe('server');
200
+ expect(classified.retryable).toBe(true);
201
+ expect(classified.message).toBe('Server error');
202
+ });
203
+
204
+ test('should classify unknown errors correctly', () => {
205
+ const unknownError = new Error('Something unexpected happened');
206
+
207
+ const classified = createNetworkError(unknownError);
208
+
209
+ expect(classified.type).toBe('unknown');
210
+ expect(classified.retryable).toBe(true);
211
+ expect(classified.message).toBe('Something unexpected happened');
212
+ });
213
+ });
214
+
215
+ describe('Fetch with Retry Logic', () => {
216
+ const fetchWithRetry = async (
217
+ url: string,
218
+ options: { timeout?: number; retries?: number } = {}
219
+ ) => {
220
+ const { timeout = 10000, retries = 3 } = options;
221
+
222
+ for (let attempt = 1; attempt <= retries; attempt++) {
223
+ try {
224
+ const controller = new AbortController();
225
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
226
+
227
+ const response = await fetch(url, {
228
+ ...options,
229
+ signal: controller.signal,
230
+ });
231
+
232
+ clearTimeout(timeoutId);
233
+
234
+ if (!response.ok) {
235
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
236
+ }
237
+
238
+ return response;
239
+ } catch (error) {
240
+ if (attempt === retries) {
241
+ throw error;
242
+ }
243
+
244
+ // Wait before retry (exponential backoff)
245
+ await new Promise((resolve) => setTimeout(resolve, Math.pow(2, attempt - 1) * 10)); // Shortened for tests
246
+ }
247
+ }
248
+
249
+ throw new Error('Max retries exceeded');
250
+ };
251
+
252
+ test('should succeed on first attempt when response is ok', async () => {
253
+ mockFetch.mockResolvedValueOnce({
254
+ ok: true,
255
+ json: async () => ({ status: 'success' }),
256
+ });
257
+
258
+ const response = await fetchWithRetry('/mr-tee-status');
259
+ expect(response.ok).toBe(true);
260
+ expect(mockFetch).toHaveBeenCalledTimes(1);
261
+ });
262
+
263
+ test('should retry on failure and succeed on second attempt', async () => {
264
+ mockFetch.mockRejectedValueOnce(new Error('Network error')).mockResolvedValueOnce({
265
+ ok: true,
266
+ json: async () => ({ status: 'success' }),
267
+ });
268
+
269
+ const response = await fetchWithRetry('/mr-tee-status', { retries: 2 });
270
+ expect(response.ok).toBe(true);
271
+ expect(mockFetch).toHaveBeenCalledTimes(2);
272
+ });
273
+
274
+ test('should fail after max retries', async () => {
275
+ mockFetch.mockRejectedValue(new Error('Persistent network error'));
276
+
277
+ await expect(fetchWithRetry('/mr-tee-status', { retries: 2 })).rejects.toThrow(
278
+ 'Persistent network error'
279
+ );
280
+
281
+ expect(mockFetch).toHaveBeenCalledTimes(2);
282
+ });
283
+
284
+ test('should handle HTTP error status codes', async () => {
285
+ mockFetch.mockResolvedValue({
286
+ ok: false,
287
+ status: 500,
288
+ statusText: 'Internal Server Error',
289
+ });
290
+
291
+ await expect(fetchWithRetry('/mr-tee-status', { retries: 1 })).rejects.toThrow(
292
+ 'HTTP 500: Internal Server Error'
293
+ );
294
+ });
295
+ });
296
+
297
+ describe('TEE Status State Management', () => {
298
+ test('should initialize with loading state', () => {
299
+ const initialState = {
300
+ connected: false,
301
+ loading: true,
302
+ };
303
+
304
+ expect(initialState.loading).toBe(true);
305
+ expect(initialState.connected).toBe(false);
306
+ });
307
+
308
+ test('should transition to connected state on successful fetch', () => {
309
+ const successState = {
310
+ connected: true,
311
+ loading: false,
312
+ mode: 'development',
313
+ vendor: 'intel',
314
+ lastUpdated: '2024-01-01T00:00:00.000Z',
315
+ };
316
+
317
+ expect(successState.connected).toBe(true);
318
+ expect(successState.loading).toBe(false);
319
+ expect(successState.mode).toBe('development');
320
+ expect(successState.vendor).toBe('intel');
321
+ });
322
+
323
+ test('should transition to error state on fetch failure', () => {
324
+ const errorState = {
325
+ connected: false,
326
+ loading: false,
327
+ error: {
328
+ type: 'network' as const,
329
+ message: 'Network connection failed',
330
+ retryable: true,
331
+ },
332
+ lastUpdated: '2024-01-01T00:00:00.000Z',
333
+ };
334
+
335
+ expect(errorState.connected).toBe(false);
336
+ expect(errorState.loading).toBe(false);
337
+ expect(errorState.error?.type).toBe('network');
338
+ expect(errorState.error?.retryable).toBe(true);
339
+ });
340
+ });
341
+
342
+ describe('Component Integration', () => {
343
+ test('should have valid ELIZA_CONFIG configuration', () => {
344
+ expect(global.window.ELIZA_CONFIG).toBeDefined();
345
+ expect(global.window.ELIZA_CONFIG?.agentId).toBe('test-agent-123');
346
+ expect(global.window.ELIZA_CONFIG?.apiBase).toBe('http://localhost:3000');
347
+ });
348
+
349
+ test('should handle missing agentId gracefully', () => {
350
+ const originalConfig = global.window.ELIZA_CONFIG;
351
+
352
+ // Temporarily remove agentId
353
+ Object.defineProperty(global.window, 'ELIZA_CONFIG', {
354
+ value: { apiBase: 'http://localhost:3000' },
355
+ writable: true,
356
+ });
357
+
358
+ expect(global.window.ELIZA_CONFIG?.agentId).toBeUndefined();
359
+
360
+ // Restore original config
361
+ Object.defineProperty(global.window, 'ELIZA_CONFIG', {
362
+ value: originalConfig,
363
+ writable: true,
364
+ });
365
+ });
366
+
367
+ test('should apply dark mode class on component mount', () => {
368
+ // Mock document.documentElement
369
+ const mockClassList = {
370
+ add: mock(),
371
+ remove: mock(),
372
+ contains: mock(),
373
+ toggle: mock(),
374
+ };
375
+
376
+ Object.defineProperty(global.document.documentElement, 'classList', {
377
+ value: mockClassList,
378
+ writable: true,
379
+ });
380
+
381
+ // In a real component, this would be called automatically
382
+ global.document.documentElement.classList.add('dark');
383
+
384
+ expect(mockClassList.add).toHaveBeenCalledWith('dark');
385
+ });
386
+ });
387
+
388
+ describe('Panel Configuration', () => {
389
+ test('should export valid panel configuration', () => {
390
+ const panels = [
391
+ {
392
+ name: 'TEE Status',
393
+ path: 'tee-status',
394
+ component: 'TEEStatusPanel', // In actual code this would be the component
395
+ icon: 'Shield',
396
+ public: false,
397
+ shortLabel: 'TEE',
398
+ },
399
+ ];
400
+
401
+ expect(panels).toHaveLength(1);
402
+ expect(panels[0].name).toBe('TEE Status');
403
+ expect(panels[0].path).toBe('tee-status');
404
+ expect(panels[0].public).toBe(false);
405
+ expect(panels[0].shortLabel).toBe('TEE');
406
+ });
407
+ });
408
+ });
409
+
410
+ describe('TEE Frontend Performance', () => {
411
+ test('should handle multiple rapid status updates', async () => {
412
+ const responses = [
413
+ { tee_mode: 'development', tee_vendor: 'intel' },
414
+ { tee_mode: 'production', tee_vendor: 'amd' },
415
+ { tee_mode: 'test', tee_vendor: 'arm' },
416
+ ];
417
+
418
+ for (const response of responses) {
419
+ mockFetch.mockResolvedValueOnce({
420
+ ok: true,
421
+ json: async () => response,
422
+ });
423
+
424
+ const result = await fetch('/mr-tee-status');
425
+ const data = await result.json();
426
+
427
+ expect(data.tee_mode).toBe(response.tee_mode);
428
+ expect(data.tee_vendor).toBe(response.tee_vendor);
429
+ }
430
+
431
+ expect(mockFetch).toHaveBeenCalledTimes(3);
432
+ });
433
+
434
+ test('should handle concurrent requests gracefully', async () => {
435
+ const mockResponse = {
436
+ tee_mode: 'development',
437
+ tee_vendor: 'intel',
438
+ timestamp: new Date().toISOString(),
439
+ };
440
+
441
+ mockFetch.mockResolvedValue({
442
+ ok: true,
443
+ json: async () => mockResponse,
444
+ });
445
+
446
+ // Simulate concurrent requests
447
+ const requests = Array(5)
448
+ .fill(null)
449
+ .map(() => fetch('/mr-tee-status').then((r) => r.json()));
450
+
451
+ const results = await Promise.all(requests);
452
+
453
+ expect(results).toHaveLength(5);
454
+ results.forEach((result) => {
455
+ expect(result.tee_mode).toBe('development');
456
+ expect(result.tee_vendor).toBe('intel');
457
+ });
458
+ });
459
+ });
@@ -2,8 +2,8 @@ import { describe, expect, it, spyOn, beforeAll, afterAll } from 'bun:test';
2
2
  import * as fs from 'node:fs';
3
3
  import * as path from 'node:path';
4
4
  import { logger, IAgentRuntime, Plugin } from '@elizaos/core';
5
- import { character } from '../src/index';
6
- import plugin from '../src/plugin';
5
+ import { character } from '../index';
6
+ import plugin from '../plugin';
7
7
  import { createMockRuntime } from './test-utils';
8
8
  import * as os from 'node:os';
9
9
 
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from 'bun:test';
2
- import teeStarterPlugin from '../src/plugin';
2
+ import teeStarterPlugin from '../plugin';
3
3
 
4
4
  describe('Plugin Models', () => {
5
5
  it('should not have custom models (using plugin-tee and other plugins for model handling)', () => {
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, spyOn, mock } from 'bun:test';
2
- import teeStarterPlugin from '../src/plugin';
2
+ import teeStarterPlugin from '../plugin';
3
3
  import { logger } from '@elizaos/core';
4
4
 
5
5
  // Spy on logger to capture logs
@@ -32,7 +32,9 @@ describe('TEE Starter Plugin', () => {
32
32
  expect(teeStarterPlugin.evaluators).toBeUndefined();
33
33
  });
34
34
 
35
- it('should have no custom services', () => {
36
- expect(teeStarterPlugin.services).toEqual([]);
35
+ it('should have the StarterService for TEE functionality', () => {
36
+ expect(teeStarterPlugin.services).toBeDefined();
37
+ expect(teeStarterPlugin.services?.length).toBe(1);
38
+ expect(teeStarterPlugin.services?.[0].name).toBe('StarterService');
37
39
  });
38
40
  });
@@ -1,10 +1,10 @@
1
1
  import { describe, expect, it, spyOn, beforeAll, afterAll } from 'bun:test';
2
- import plugin from '../src/plugin';
2
+ import plugin from '../plugin';
3
3
  import type { IAgentRuntime, Memory, State, Provider } from '@elizaos/core';
4
4
  import { logger } from '@elizaos/core';
5
5
  import { v4 as uuidv4 } from 'uuid';
6
6
  import dotenv from 'dotenv';
7
- import teeStarterPlugin from '../src/plugin';
7
+ import teeStarterPlugin from '../plugin';
8
8
 
9
9
  // Setup environment variables
10
10
  dotenv.config();
@@ -0,0 +1,30 @@
1
+ import { describe, it, expect } from 'bun:test';
2
+ import teeStarterPlugin from '../plugin';
3
+
4
+ describe('Plugin Routes', () => {
5
+ it('should have TEE-specific routes for status and frontend', () => {
6
+ // Our plugin has routes for TEE status and frontend panels
7
+ expect(teeStarterPlugin.routes).toBeDefined();
8
+ expect(teeStarterPlugin.routes?.length).toBe(2);
9
+
10
+ // Check for mr-tee-status route
11
+ const statusRoute = teeStarterPlugin.routes?.find((r) => r.name === 'mr-tee-status-route');
12
+ expect(statusRoute).toBeDefined();
13
+ expect(statusRoute?.path).toBe('/mr-tee-status');
14
+ expect(statusRoute?.type).toBe('GET');
15
+
16
+ // Check for TEE Status panel route
17
+ const panelRoute = teeStarterPlugin.routes?.find((r) => r.name === 'TEE Status');
18
+ expect(panelRoute).toBeDefined();
19
+ expect(panelRoute?.path).toBe('/public/tee-status');
20
+ expect(panelRoute?.type).toBe('GET');
21
+ });
22
+
23
+ it('should have correct plugin configuration', () => {
24
+ expect(teeStarterPlugin).toBeDefined();
25
+ expect(teeStarterPlugin.name).toBe('mr-tee-starter-plugin');
26
+ expect(teeStarterPlugin.description).toBe(
27
+ "Mr. TEE's starter plugin - using plugin-tee for attestation"
28
+ );
29
+ });
30
+ });