@elizaos/cli 1.0.9 → 1.0.10

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 (240) hide show
  1. package/README.md +9 -16
  2. package/dist/assets/{index-CCyz05Yl.js → index-CmuPnu0u.js} +72 -89
  3. package/dist/assets/index-CmuPnu0u.js.br +0 -0
  4. package/dist/assets/index-CmuPnu0u.js.map +1 -0
  5. package/dist/assets/{index-Cxd2b7is.js → index-DDQnwxzL.js} +1318 -13721
  6. package/dist/assets/{index-Cxd2b7is.js.map → index-DDQnwxzL.js.map} +1 -1
  7. package/dist/assets/index-Df1AFSuJ.css +1 -0
  8. package/dist/assets/index-Df1AFSuJ.css.br +0 -0
  9. package/dist/assets/vendor-DSdxb8P-.js.map +1 -1
  10. package/dist/{chunk-Y755OOSP.js → chunk-7HYEGM5V.js} +877 -1550
  11. package/dist/{chunk-HZQCHL3J.js → chunk-B4KJXECB.js} +13 -18
  12. package/dist/{chunk-Z6GVELRX.js → chunk-GWQB7PBK.js} +58 -29
  13. package/dist/{chunk-CVADLFW6.js → chunk-LQ6XHF53.js} +4543 -3043
  14. package/dist/{chunk-JWONHNLD.js → chunk-RIAWNDYI.js} +2 -9
  15. package/dist/{chunk-IEKLJDUU.js → chunk-WS4DWCDZ.js} +54 -32
  16. package/dist/commands/agent/actions/index.d.ts +5 -1
  17. package/dist/commands/agent/actions/index.js +5 -3
  18. package/dist/commands/agent/index.js +3 -3
  19. package/dist/commands/create/actions/index.js +4 -4
  20. package/dist/commands/create/index.js +5 -5
  21. package/dist/{fileFromPath-DCRQMDLJ.js → fileFromPath-KB6XMTJ4.js} +1 -0
  22. package/dist/index.html +2 -2
  23. package/dist/index.js +9351 -102236
  24. package/dist/{migrator-KZLCVEIH.js → migrator-JREQPDN3.js} +42 -220
  25. package/dist/pglite.data +0 -0
  26. package/dist/pglite.wasm +0 -0
  27. package/dist/plugin-creator-T4K2673C.js +910 -0
  28. package/dist/{registry-W7CIK4O2.js → registry-CBMRMYCG.js} +3 -3
  29. package/dist/templates/plugin-starter/README.md +255 -0
  30. package/dist/templates/plugin-starter/bunfig.toml +6 -0
  31. package/dist/templates/plugin-starter/cypress.config.ts +18 -0
  32. package/dist/templates/plugin-starter/index.html +13 -0
  33. package/dist/templates/plugin-starter/package.json +95 -0
  34. package/dist/templates/plugin-starter/postcss.config.js +3 -0
  35. package/dist/templates/plugin-starter/scripts/test-e2e-manual.js +201 -0
  36. package/dist/templates/plugin-starter/src/__tests__/cypress/component/ExampleRoute.cy.tsx +404 -0
  37. package/dist/templates/plugin-starter/src/__tests__/cypress/component/PanelComponent.cy.tsx +287 -0
  38. package/dist/templates/plugin-starter/src/__tests__/cypress/support/commands.ts +38 -0
  39. package/dist/templates/plugin-starter/src/__tests__/cypress/support/component-index.html +11 -0
  40. package/dist/templates/plugin-starter/src/__tests__/cypress/support/component.ts +33 -0
  41. package/dist/templates/plugin-starter/src/__tests__/cypress/support/e2e.ts +11 -0
  42. package/dist/templates/plugin-starter/src/__tests__/cypress/tsconfig.json +10 -0
  43. package/dist/templates/plugin-starter/src/__tests__/e2e/README.md +47 -0
  44. package/dist/templates/plugin-starter/src/__tests__/e2e/starter-plugin.ts +320 -0
  45. package/{templates/plugin-starter → dist/templates/plugin-starter/src}/__tests__/integration.test.ts +22 -17
  46. package/{templates/plugin-starter → dist/templates/plugin-starter/src}/__tests__/plugin.test.ts +8 -8
  47. package/{templates/plugin-starter → dist/templates/plugin-starter/src}/__tests__/test-utils.ts +17 -17
  48. package/dist/templates/plugin-starter/src/frontend/index.css +77 -0
  49. package/dist/templates/plugin-starter/src/frontend/index.tsx +164 -0
  50. package/dist/templates/plugin-starter/src/frontend/utils.ts +6 -0
  51. package/dist/templates/plugin-starter/src/index.ts +274 -0
  52. package/dist/templates/plugin-starter/src/tests.ts +6 -0
  53. package/dist/templates/plugin-starter/tailwind.config.js +62 -0
  54. package/dist/templates/plugin-starter/tsconfig.build.json +11 -0
  55. package/dist/templates/plugin-starter/tsconfig.json +28 -0
  56. package/dist/templates/plugin-starter/tsup.config.ts +20 -0
  57. package/dist/templates/plugin-starter/vite.config.ts +20 -0
  58. package/dist/templates/project-starter/.env.example +153 -0
  59. package/dist/templates/project-starter/README.md +109 -0
  60. package/dist/templates/project-starter/bunfig.toml +6 -0
  61. package/dist/templates/project-starter/cypress.config.ts +31 -0
  62. package/dist/templates/project-starter/index.html +13 -0
  63. package/dist/templates/project-starter/package.json +83 -0
  64. package/dist/templates/project-starter/postcss.config.js +3 -0
  65. package/dist/templates/project-starter/scripts/test-all.sh +101 -0
  66. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/actions.test.ts +6 -6
  67. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/character.test.ts +3 -3
  68. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/config.test.ts +18 -18
  69. package/dist/templates/project-starter/src/__tests__/cypress/component/Accessibility.cy.tsx +271 -0
  70. package/dist/templates/project-starter/src/__tests__/cypress/component/ApiIntegration.cy.tsx +220 -0
  71. package/dist/templates/project-starter/src/__tests__/cypress/component/ExampleRoute.cy.tsx +146 -0
  72. package/dist/templates/project-starter/src/__tests__/cypress/component/PanelComponent.cy.tsx +51 -0
  73. package/dist/templates/project-starter/src/__tests__/cypress/e2e/agent-chat.cy.ts +235 -0
  74. package/dist/templates/project-starter/src/__tests__/cypress/e2e/dashboard.cy.ts +146 -0
  75. package/dist/templates/project-starter/src/__tests__/cypress/e2e/user-workflow.cy.ts +257 -0
  76. package/dist/templates/project-starter/src/__tests__/cypress/support/commands.ts +44 -0
  77. package/dist/templates/project-starter/src/__tests__/cypress/support/component-index.html +11 -0
  78. package/dist/templates/project-starter/src/__tests__/cypress/support/component.ts +33 -0
  79. package/dist/templates/project-starter/src/__tests__/cypress/support/e2e.ts +179 -0
  80. package/dist/templates/project-starter/src/__tests__/e2e/index.ts +14 -0
  81. package/dist/templates/project-starter/src/__tests__/e2e/natural-language.test.ts +246 -0
  82. package/dist/templates/project-starter/src/__tests__/e2e/project.test.ts +155 -0
  83. package/dist/templates/project-starter/src/__tests__/e2e/starter-plugin.test.ts +421 -0
  84. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/env.test.ts +2 -2
  85. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/error-handling.test.ts +17 -17
  86. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/events.test.ts +7 -7
  87. package/dist/templates/project-starter/src/__tests__/file-structure.test.ts +135 -0
  88. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/integration.test.ts +25 -25
  89. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/models.test.ts +6 -6
  90. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/plugin.test.ts +9 -9
  91. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/provider.test.ts +7 -7
  92. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/routes.test.ts +3 -3
  93. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/test-utils.ts +17 -17
  94. package/{templates/project-starter → dist/templates/project-starter/src}/__tests__/utils/core-test-utils.ts +3 -3
  95. package/dist/templates/project-starter/src/frontend/index.css +77 -0
  96. package/dist/templates/project-starter/src/frontend/index.html +19 -0
  97. package/dist/templates/project-starter/src/frontend/index.tsx +98 -0
  98. package/dist/templates/project-starter/src/frontend/utils.ts +6 -0
  99. package/dist/templates/project-starter/src/index.ts +153 -0
  100. package/dist/templates/project-starter/src/plugin.ts +255 -0
  101. package/dist/templates/project-starter/tailwind.config.js +62 -0
  102. package/dist/templates/project-starter/tsconfig.build.json +20 -0
  103. package/dist/templates/project-starter/tsconfig.json +39 -0
  104. package/dist/templates/project-starter/tsup.config.ts +19 -0
  105. package/dist/templates/project-starter/vite.config.ts +39 -0
  106. package/dist/templates/project-tee-starter/.dockerignore +20 -0
  107. package/dist/templates/project-tee-starter/.env.example +55 -0
  108. package/dist/templates/project-tee-starter/Dockerfile +66 -0
  109. package/dist/templates/project-tee-starter/GUIDE.md +235 -0
  110. package/dist/templates/project-tee-starter/README.md +173 -0
  111. package/dist/templates/project-tee-starter/__tests__/actions.test.ts +9 -0
  112. package/dist/templates/project-tee-starter/__tests__/character.test.ts +86 -0
  113. package/dist/templates/project-tee-starter/__tests__/config.test.ts +31 -0
  114. package/dist/templates/project-tee-starter/__tests__/env.test.ts +87 -0
  115. package/dist/templates/project-tee-starter/__tests__/error-handling.test.ts +30 -0
  116. package/dist/templates/project-tee-starter/__tests__/events.test.ts +21 -0
  117. package/{templates/project-starter → dist/templates/project-tee-starter}/__tests__/file-structure.test.ts +6 -6
  118. package/dist/templates/project-tee-starter/__tests__/integration.test.ts +205 -0
  119. package/dist/templates/project-tee-starter/__tests__/models.test.ts +22 -0
  120. package/dist/templates/project-tee-starter/__tests__/plugin.test.ts +38 -0
  121. package/dist/templates/project-tee-starter/__tests__/provider.test.ts +189 -0
  122. package/dist/templates/project-tee-starter/__tests__/routes.test.ts +21 -0
  123. package/dist/templates/project-tee-starter/__tests__/test-utils.ts +121 -0
  124. package/dist/templates/project-tee-starter/__tests__/utils/core-test-utils.ts +167 -0
  125. package/dist/templates/project-tee-starter/assets/mr-tee-portrait.jpg +0 -0
  126. package/dist/templates/project-tee-starter/bunfig.toml +6 -0
  127. package/dist/templates/project-tee-starter/docker-compose.yaml +57 -0
  128. package/dist/templates/project-tee-starter/e2e/project.test.ts +38 -0
  129. package/dist/templates/project-tee-starter/e2e/starter-plugin.test.ts +92 -0
  130. package/dist/templates/project-tee-starter/package.json +74 -0
  131. package/dist/templates/project-tee-starter/src/character.ts +257 -0
  132. package/dist/templates/project-tee-starter/src/index.ts +33 -0
  133. package/dist/templates/project-tee-starter/src/plugin.ts +169 -0
  134. package/dist/templates/project-tee-starter/tsconfig.build.json +13 -0
  135. package/dist/templates/project-tee-starter/tsconfig.json +30 -0
  136. package/dist/templates/project-tee-starter/tsup.config.ts +19 -0
  137. package/dist/{utils-2G2QVMW3.js → utils-TIALZU53.js} +9 -7
  138. package/package.json +28 -9
  139. package/templates/plugin-starter/README.md +38 -13
  140. package/templates/plugin-starter/bunfig.toml +6 -0
  141. package/templates/plugin-starter/cypress.config.ts +18 -0
  142. package/templates/plugin-starter/index.html +13 -0
  143. package/templates/plugin-starter/package.json +19 -7
  144. package/templates/plugin-starter/postcss.config.js +3 -0
  145. package/templates/plugin-starter/scripts/test-e2e-manual.js +201 -0
  146. package/templates/plugin-starter/src/__tests__/cypress/component/ExampleRoute.cy.tsx +404 -0
  147. package/templates/plugin-starter/src/__tests__/cypress/component/PanelComponent.cy.tsx +287 -0
  148. package/templates/plugin-starter/src/__tests__/cypress/support/commands.ts +38 -0
  149. package/templates/plugin-starter/src/__tests__/cypress/support/component-index.html +11 -0
  150. package/templates/plugin-starter/src/__tests__/cypress/support/component.ts +33 -0
  151. package/templates/plugin-starter/src/__tests__/cypress/support/e2e.ts +11 -0
  152. package/templates/plugin-starter/src/__tests__/cypress/tsconfig.json +10 -0
  153. package/templates/plugin-starter/src/__tests__/e2e/README.md +47 -0
  154. package/templates/plugin-starter/src/__tests__/e2e/starter-plugin.ts +320 -0
  155. package/templates/plugin-starter/src/__tests__/integration.test.ts +138 -0
  156. package/templates/plugin-starter/src/__tests__/plugin.test.ts +182 -0
  157. package/templates/plugin-starter/src/__tests__/test-utils.ts +162 -0
  158. package/templates/plugin-starter/src/frontend/index.css +77 -0
  159. package/templates/plugin-starter/src/frontend/index.tsx +164 -0
  160. package/templates/plugin-starter/src/frontend/utils.ts +6 -0
  161. package/templates/plugin-starter/src/index.ts +30 -7
  162. package/templates/plugin-starter/src/tests.ts +6 -0
  163. package/templates/plugin-starter/tailwind.config.js +62 -0
  164. package/templates/plugin-starter/tsconfig.json +8 -8
  165. package/templates/plugin-starter/vite.config.ts +20 -0
  166. package/templates/project-starter/bunfig.toml +6 -0
  167. package/templates/project-starter/cypress.config.ts +31 -0
  168. package/templates/project-starter/index.html +13 -0
  169. package/templates/project-starter/package.json +37 -14
  170. package/templates/project-starter/postcss.config.js +3 -0
  171. package/templates/project-starter/scripts/test-all.sh +101 -0
  172. package/templates/project-starter/src/__tests__/actions.test.ts +155 -0
  173. package/templates/project-starter/src/__tests__/character.test.ts +86 -0
  174. package/templates/project-starter/src/__tests__/config.test.ts +193 -0
  175. package/templates/project-starter/src/__tests__/cypress/component/Accessibility.cy.tsx +271 -0
  176. package/templates/project-starter/src/__tests__/cypress/component/ApiIntegration.cy.tsx +220 -0
  177. package/templates/project-starter/src/__tests__/cypress/component/ExampleRoute.cy.tsx +146 -0
  178. package/templates/project-starter/src/__tests__/cypress/component/PanelComponent.cy.tsx +51 -0
  179. package/templates/project-starter/src/__tests__/cypress/e2e/agent-chat.cy.ts +235 -0
  180. package/templates/project-starter/src/__tests__/cypress/e2e/dashboard.cy.ts +146 -0
  181. package/templates/project-starter/src/__tests__/cypress/e2e/user-workflow.cy.ts +257 -0
  182. package/templates/project-starter/src/__tests__/cypress/support/commands.ts +44 -0
  183. package/templates/project-starter/src/__tests__/cypress/support/component-index.html +11 -0
  184. package/templates/project-starter/src/__tests__/cypress/support/component.ts +33 -0
  185. package/templates/project-starter/src/__tests__/cypress/support/e2e.ts +179 -0
  186. package/templates/project-starter/src/__tests__/e2e/index.ts +14 -0
  187. package/templates/project-starter/src/__tests__/e2e/natural-language.test.ts +246 -0
  188. package/templates/project-starter/src/__tests__/e2e/project.test.ts +155 -0
  189. package/templates/project-starter/src/__tests__/e2e/starter-plugin.test.ts +421 -0
  190. package/templates/project-starter/src/__tests__/env.test.ts +87 -0
  191. package/templates/project-starter/src/__tests__/error-handling.test.ts +177 -0
  192. package/templates/project-starter/src/__tests__/events.test.ts +144 -0
  193. package/templates/project-starter/src/__tests__/file-structure.test.ts +135 -0
  194. package/templates/project-starter/src/__tests__/integration.test.ts +209 -0
  195. package/templates/project-starter/src/__tests__/models.test.ts +152 -0
  196. package/templates/project-starter/src/__tests__/plugin.test.ts +393 -0
  197. package/templates/project-starter/src/__tests__/provider.test.ts +325 -0
  198. package/templates/project-starter/src/__tests__/routes.test.ts +79 -0
  199. package/templates/project-starter/src/__tests__/test-utils.ts +121 -0
  200. package/templates/project-starter/src/__tests__/utils/core-test-utils.ts +180 -0
  201. package/templates/project-starter/src/frontend/index.css +77 -0
  202. package/templates/project-starter/src/frontend/index.html +19 -0
  203. package/templates/project-starter/src/frontend/index.tsx +98 -0
  204. package/templates/project-starter/src/frontend/utils.ts +6 -0
  205. package/templates/project-starter/src/index.ts +3 -0
  206. package/templates/project-starter/tailwind.config.js +62 -0
  207. package/templates/project-starter/tsconfig.build.json +9 -2
  208. package/templates/project-starter/tsconfig.json +15 -6
  209. package/templates/project-starter/tsup.config.ts +1 -1
  210. package/templates/project-starter/vite.config.ts +39 -0
  211. package/templates/project-tee-starter/__tests__/actions.test.ts +1 -1
  212. package/templates/project-tee-starter/__tests__/character.test.ts +1 -1
  213. package/templates/project-tee-starter/__tests__/config.test.ts +1 -1
  214. package/templates/project-tee-starter/__tests__/env.test.ts +2 -2
  215. package/templates/project-tee-starter/__tests__/error-handling.test.ts +1 -1
  216. package/templates/project-tee-starter/__tests__/events.test.ts +1 -1
  217. package/templates/project-tee-starter/__tests__/file-structure.test.ts +5 -5
  218. package/templates/project-tee-starter/__tests__/integration.test.ts +22 -26
  219. package/templates/project-tee-starter/__tests__/models.test.ts +1 -1
  220. package/templates/project-tee-starter/__tests__/plugin.test.ts +6 -12
  221. package/templates/project-tee-starter/__tests__/provider.test.ts +6 -6
  222. package/templates/project-tee-starter/__tests__/routes.test.ts +1 -1
  223. package/templates/project-tee-starter/__tests__/test-utils.ts +15 -15
  224. package/templates/project-tee-starter/__tests__/utils/core-test-utils.ts +3 -3
  225. package/templates/project-tee-starter/bunfig.toml +6 -0
  226. package/templates/project-tee-starter/package.json +10 -12
  227. package/dist/assets/index-CCyz05Yl.js.br +0 -0
  228. package/dist/assets/index-CCyz05Yl.js.map +0 -1
  229. package/dist/assets/index-DeXwJbtm.css +0 -1
  230. package/dist/assets/index-DeXwJbtm.css.br +0 -0
  231. package/dist/chunk-CEE6RKN5.js +0 -2746
  232. package/dist/chunk-TUAYJIF2.js +0 -3649
  233. package/dist/plugin-creator-IK6H4LVZ.js +0 -29165
  234. package/templates/plugin-starter/e2e/starter-plugin.test.ts +0 -171
  235. package/templates/plugin-starter/images/README.md +0 -24
  236. package/templates/plugin-starter/vitest.config.ts +0 -16
  237. package/templates/project-starter/e2e/project.test.ts +0 -34
  238. package/templates/project-starter/e2e/starter-plugin.test.ts +0 -217
  239. package/templates/project-starter/vitest.config.ts +0 -16
  240. package/templates/project-tee-starter/vitest.config.ts +0 -19
@@ -0,0 +1,320 @@
1
+ import { type Content, type HandlerCallback } from '@elizaos/core';
2
+
3
+ /**
4
+ * E2E (End-to-End) Test Suite for ElizaOS Plugins
5
+ * ================================================
6
+ *
7
+ * This file contains end-to-end tests that run within a real ElizaOS runtime environment.
8
+ * Unlike unit tests that test individual components in isolation, e2e tests validate
9
+ * the entire plugin behavior in a production-like environment.
10
+ *
11
+ * NOTE: The tests are properly structured and included in the plugin build.
12
+ * If the test runner is not detecting these tests, it may be looking at the wrong
13
+ * plugin name or there may be a test runner configuration issue. The tests are
14
+ * exported correctly through src/tests.ts and included in the plugin's tests array.
15
+ *
16
+ * HOW E2E TESTS WORK:
17
+ * -------------------
18
+ * 1. Tests are executed by the ElizaOS test runner using `elizaos test e2e`
19
+ * 2. Each test receives a real runtime instance with the plugin loaded
20
+ * 3. Tests can interact with the runtime just like in production
21
+ * 4. Tests throw errors to indicate failure (no assertion library needed)
22
+ *
23
+ * WRITING NEW E2E TESTS:
24
+ * ----------------------
25
+ * 1. Add a new test object to the `tests` array below
26
+ * 2. Each test must have:
27
+ * - `name`: A unique identifier for the test
28
+ * - `fn`: An async function that receives the runtime and performs the test
29
+ *
30
+ * Example structure:
31
+ * ```typescript
32
+ * {
33
+ * name: 'my_new_test',
34
+ * fn: async (runtime) => {
35
+ * // Your test logic here
36
+ * if (someCondition !== expected) {
37
+ * throw new Error('Test failed: reason');
38
+ * }
39
+ * }
40
+ * }
41
+ * ```
42
+ *
43
+ * BEST PRACTICES:
44
+ * ---------------
45
+ * - Test real user scenarios, not implementation details
46
+ * - Use descriptive test names that explain what's being tested
47
+ * - Include clear error messages that help diagnose failures
48
+ * - Test both success and failure paths
49
+ * - Clean up any resources created during tests
50
+ *
51
+ * AVAILABLE RUNTIME METHODS:
52
+ * --------------------------
53
+ * - runtime.getService(type): Get a service instance
54
+ * - runtime.character: Access character configuration
55
+ * - runtime.models: Access AI models
56
+ * - runtime.db: Access database methods
57
+ * - runtime.actions: Access registered actions
58
+ * - runtime.providers: Access registered providers
59
+ *
60
+ * For more details, see the ElizaOS documentation.
61
+ */
62
+
63
+ // Define a minimal TestSuite interface that matches what's needed
64
+ interface TestSuite {
65
+ name: string;
66
+ description?: string;
67
+ tests: Array<{
68
+ name: string;
69
+ fn: (runtime: any) => Promise<any>;
70
+ }>;
71
+ }
72
+
73
+ // Define minimal interfaces for the types we need
74
+ type UUID = `${string}-${string}-${string}-${string}-${string}`;
75
+
76
+ interface Memory {
77
+ entityId: UUID;
78
+ roomId: UUID;
79
+ content: {
80
+ text: string;
81
+ source: string;
82
+ actions?: string[];
83
+ };
84
+ }
85
+
86
+ interface State {
87
+ values: Record<string, any>;
88
+ data: Record<string, any>;
89
+ text: string;
90
+ }
91
+
92
+ export const StarterPluginTestSuite: TestSuite = {
93
+ name: 'plugin_starter_test_suite',
94
+ description: 'E2E tests for the starter plugin',
95
+
96
+ tests: [
97
+ /**
98
+ * Basic Plugin Verification Test
99
+ * ------------------------------
100
+ * This test verifies that the plugin is properly loaded and initialized
101
+ * within the runtime environment.
102
+ */
103
+ {
104
+ name: 'example_test',
105
+ fn: async (runtime) => {
106
+ // Test the character name
107
+ if (runtime.character.name !== 'Eliza') {
108
+ throw new Error(
109
+ `Expected character name to be "Eliza" but got "${runtime.character.name}"`
110
+ );
111
+ }
112
+ // Verify the plugin is loaded properly
113
+ const service = runtime.getService('starter');
114
+ if (!service) {
115
+ throw new Error('Starter service not found');
116
+ }
117
+ },
118
+ },
119
+
120
+ /**
121
+ * Action Registration Test
122
+ * ------------------------
123
+ * Verifies that custom actions are properly registered with the runtime.
124
+ * This is important to ensure actions are available for the agent to use.
125
+ */
126
+ {
127
+ name: 'should_have_hello_world_action',
128
+ fn: async (runtime) => {
129
+ // Access actions through runtime.actions instead of getPlugin
130
+ const actionExists = runtime.actions?.some((a) => a.name === 'HELLO_WORLD');
131
+ if (!actionExists) {
132
+ throw new Error('Hello world action not found in runtime actions');
133
+ }
134
+ },
135
+ },
136
+
137
+ /**
138
+ * Hello World Action Response Test
139
+ * ---------------------------------
140
+ * This test demonstrates a complete scenario where:
141
+ * 1. The agent is asked to say "hello"
142
+ * 2. The HELLO_WORLD action is triggered
143
+ * 3. The agent responds with text containing "hello world"
144
+ *
145
+ * This is a key pattern for testing agent behaviors - you simulate
146
+ * a user message and verify the agent's response.
147
+ */
148
+ {
149
+ name: 'hello_world_action_test',
150
+ fn: async (runtime) => {
151
+ // Create a test message asking the agent to say hello
152
+ const testMessage: Memory = {
153
+ entityId: '12345678-1234-1234-1234-123456789012' as UUID,
154
+ roomId: '12345678-1234-1234-1234-123456789012' as UUID,
155
+ content: {
156
+ text: 'Can you say hello?',
157
+ source: 'test',
158
+ actions: ['HELLO_WORLD'], // Specify which action we expect to trigger
159
+ },
160
+ };
161
+
162
+ // Create a test state (can include context if needed)
163
+ const testState: State = {
164
+ values: {},
165
+ data: {},
166
+ text: '',
167
+ };
168
+
169
+ let responseText = '';
170
+ let responseReceived = false;
171
+
172
+ // Find the hello world action in runtime.actions
173
+ const helloWorldAction = runtime.actions?.find((a) => a.name === 'HELLO_WORLD');
174
+ if (!helloWorldAction) {
175
+ throw new Error('Hello world action not found in runtime actions');
176
+ }
177
+
178
+ // Create a callback that captures the agent's response
179
+ // This simulates how the runtime would handle the action's response
180
+ const callback: HandlerCallback = async (response: Content) => {
181
+ responseReceived = true;
182
+ responseText = response.text || '';
183
+
184
+ // Verify the response includes the expected action
185
+ if (!response.actions?.includes('HELLO_WORLD')) {
186
+ throw new Error('Response did not include HELLO_WORLD action');
187
+ }
188
+
189
+ // Return Promise<Memory[]> as required by the HandlerCallback interface
190
+ return Promise.resolve([]);
191
+ };
192
+
193
+ // Execute the action - this simulates the runtime calling the action
194
+ await helloWorldAction.handler(runtime, testMessage, testState, {}, callback);
195
+
196
+ // Verify we received a response
197
+ if (!responseReceived) {
198
+ throw new Error('Hello world action did not produce a response');
199
+ }
200
+
201
+ // Verify the response contains "hello world" (case-insensitive)
202
+ if (!responseText.toLowerCase().includes('hello world')) {
203
+ throw new Error(`Expected response to contain "hello world" but got: "${responseText}"`);
204
+ }
205
+
206
+ // Success! The agent responded with "hello world" as expected
207
+ },
208
+ },
209
+
210
+ /**
211
+ * Provider Functionality Test
212
+ * ---------------------------
213
+ * Tests that providers can supply data to the agent when needed.
214
+ * Providers are used to fetch external data or compute values.
215
+ */
216
+ {
217
+ name: 'hello_world_provider_test',
218
+ fn: async (runtime) => {
219
+ // Create a test message
220
+ const testMessage: Memory = {
221
+ entityId: '12345678-1234-1234-1234-123456789012' as UUID,
222
+ roomId: '12345678-1234-1234-1234-123456789012' as UUID,
223
+ content: {
224
+ text: 'What can you provide?',
225
+ source: 'test',
226
+ },
227
+ };
228
+
229
+ // Create a test state
230
+ const testState: State = {
231
+ values: {},
232
+ data: {},
233
+ text: '',
234
+ };
235
+
236
+ // Find the hello world provider in runtime.providers
237
+ const helloWorldProvider = runtime.providers?.find(
238
+ (p) => p.name === 'HELLO_WORLD_PROVIDER'
239
+ );
240
+ if (!helloWorldProvider) {
241
+ throw new Error('Hello world provider not found in runtime providers');
242
+ }
243
+
244
+ // Test the provider
245
+ const result = await helloWorldProvider.get(runtime, testMessage, testState);
246
+
247
+ if (result.text !== 'I am a provider') {
248
+ throw new Error(`Expected provider to return "I am a provider", got "${result.text}"`);
249
+ }
250
+ },
251
+ },
252
+
253
+ /**
254
+ * Service Lifecycle Test
255
+ * ----------------------
256
+ * Verifies that services can be started, accessed, and stopped properly.
257
+ * Services run background tasks or manage long-lived resources.
258
+ */
259
+ {
260
+ name: 'starter_service_test',
261
+ fn: async (runtime) => {
262
+ // Get the service from the runtime
263
+ const service = runtime.getService('starter');
264
+ if (!service) {
265
+ throw new Error('Starter service not found');
266
+ }
267
+
268
+ // Check service capability description
269
+ if (
270
+ service.capabilityDescription !==
271
+ 'This is a starter service which is attached to the agent through the starter plugin.'
272
+ ) {
273
+ throw new Error('Incorrect service capability description');
274
+ }
275
+
276
+ // Test service stop method
277
+ await service.stop();
278
+ },
279
+ },
280
+
281
+ /**
282
+ * ADD YOUR CUSTOM TESTS HERE
283
+ * --------------------------
284
+ * To add a new test:
285
+ *
286
+ * 1. Copy this template:
287
+ * ```typescript
288
+ * {
289
+ * name: 'your_test_name',
290
+ * fn: async (runtime) => {
291
+ * // Setup: Create any test data needed
292
+ *
293
+ * // Action: Perform the operation you want to test
294
+ *
295
+ * // Assert: Check the results
296
+ * if (result !== expected) {
297
+ * throw new Error(`Expected ${expected} but got ${result}`);
298
+ * }
299
+ * }
300
+ * }
301
+ * ```
302
+ *
303
+ * 2. Common test patterns:
304
+ * - Test action responses to specific prompts
305
+ * - Verify provider data under different conditions
306
+ * - Check service behavior during lifecycle events
307
+ * - Validate plugin configuration handling
308
+ * - Test error cases and edge conditions
309
+ *
310
+ * 3. Tips:
311
+ * - Use meaningful variable names
312
+ * - Include helpful error messages
313
+ * - Test one thing per test
314
+ * - Consider both success and failure scenarios
315
+ */
316
+ ],
317
+ };
318
+
319
+ // Export a default instance of the test suite for the E2E test runner
320
+ export default StarterPluginTestSuite;
@@ -0,0 +1,138 @@
1
+ import { describe, expect, it, spyOn, beforeEach, afterAll, beforeAll } from 'bun:test';
2
+ import { starterPlugin, StarterService } from '../index';
3
+ import { createMockRuntime, setupLoggerSpies, MockRuntime } from './test-utils';
4
+ import { HandlerCallback, IAgentRuntime, Memory, State, UUID, logger } from '@elizaos/core';
5
+
6
+ /**
7
+ * Integration tests demonstrate how multiple components of the plugin work together.
8
+ * Unlike unit tests that test individual functions in isolation, integration tests
9
+ * examine how components interact with each other.
10
+ *
11
+ * For example, this file shows how the HelloWorld action and HelloWorld provider
12
+ * interact with the StarterService and the plugin's core functionality.
13
+ */
14
+
15
+ // Set up spies on logger
16
+ beforeAll(() => {
17
+ setupLoggerSpies();
18
+ });
19
+
20
+ afterAll(() => {
21
+ // No global restore needed in bun:test
22
+ });
23
+
24
+ describe('Integration: HelloWorld Action with StarterService', () => {
25
+ let mockRuntime: MockRuntime;
26
+
27
+ beforeEach(() => {
28
+ // Create a service mock that will be returned by getService
29
+ const mockService = {
30
+ capabilityDescription:
31
+ 'This is a starter service which is attached to the agent through the starter plugin.',
32
+ stop: () => Promise.resolve(),
33
+ };
34
+
35
+ // Create a mock runtime with a spied getService method
36
+ const getServiceImpl = (serviceType) => {
37
+ if (serviceType === 'starter') {
38
+ return mockService;
39
+ }
40
+ return null;
41
+ };
42
+
43
+ mockRuntime = createMockRuntime({
44
+ getService: getServiceImpl,
45
+ });
46
+ });
47
+
48
+ it('should handle HelloWorld action with StarterService available', async () => {
49
+ // Find the HelloWorld action
50
+ const helloWorldAction = starterPlugin.actions?.find((action) => action.name === 'HELLO_WORLD');
51
+ expect(helloWorldAction).toBeDefined();
52
+
53
+ // Create a mock message and state
54
+ const mockMessage: Memory = {
55
+ id: '12345678-1234-1234-1234-123456789012' as UUID,
56
+ roomId: '12345678-1234-1234-1234-123456789012' as UUID,
57
+ entityId: '12345678-1234-1234-1234-123456789012' as UUID,
58
+ agentId: '12345678-1234-1234-1234-123456789012' as UUID,
59
+ content: {
60
+ text: 'Hello world',
61
+ source: 'test',
62
+ },
63
+ createdAt: Date.now(),
64
+ };
65
+
66
+ const mockState: State = {
67
+ values: {},
68
+ data: {},
69
+ text: '',
70
+ };
71
+
72
+ // Create a mock callback to capture the response
73
+ const callbackCalls = [];
74
+ const callbackFn = (...args) => {
75
+ callbackCalls.push(args);
76
+ };
77
+
78
+ // Execute the action
79
+ await helloWorldAction?.handler(
80
+ mockRuntime as unknown as IAgentRuntime,
81
+ mockMessage,
82
+ mockState,
83
+ {},
84
+ callbackFn as HandlerCallback,
85
+ []
86
+ );
87
+
88
+ // Verify the callback was called with expected response
89
+ expect(callbackCalls.length).toBeGreaterThan(0);
90
+ if (callbackCalls.length > 0) {
91
+ expect(callbackCalls[0][0]).toMatchObject({
92
+ text: 'hello world!',
93
+ actions: ['HELLO_WORLD'],
94
+ });
95
+ }
96
+
97
+ // Get the service to ensure integration
98
+ const service = mockRuntime.getService('starter');
99
+ expect(service).toBeDefined();
100
+ expect(service?.capabilityDescription).toContain('starter service');
101
+ });
102
+ });
103
+
104
+ describe('Integration: Plugin initialization and service registration', () => {
105
+ it('should initialize the plugin and register the service', async () => {
106
+ // Create a fresh mock runtime with mocked registerService for testing initialization flow
107
+ const mockRuntime = createMockRuntime();
108
+
109
+ // Create and install a mock registerService
110
+ const registerServiceCalls = [];
111
+ mockRuntime.registerService = (type, service) => {
112
+ registerServiceCalls.push({ type, service });
113
+ };
114
+
115
+ // Run a minimal simulation of the plugin initialization process
116
+ if (starterPlugin.init) {
117
+ await starterPlugin.init(
118
+ { EXAMPLE_PLUGIN_VARIABLE: 'test-value' },
119
+ mockRuntime as unknown as IAgentRuntime
120
+ );
121
+
122
+ // Directly mock the service registration that happens during initialization
123
+ // because unit tests don't run the full agent initialization flow
124
+ if (starterPlugin.services) {
125
+ const StarterServiceClass = starterPlugin.services[0];
126
+ const serviceInstance = await StarterServiceClass.start(
127
+ mockRuntime as unknown as IAgentRuntime
128
+ );
129
+
130
+ // Register the Service class to match the core API
131
+ mockRuntime.registerService(StarterServiceClass);
132
+ }
133
+
134
+ // Now verify the service was registered with the runtime
135
+ expect(registerServiceCalls.length).toBeGreaterThan(0);
136
+ }
137
+ });
138
+ });
@@ -0,0 +1,182 @@
1
+ import { describe, expect, it, spyOn, beforeEach, afterEach, beforeAll, afterAll } from 'bun:test';
2
+ import { starterPlugin, StarterService } from '../index';
3
+ import { ModelType, logger } from '@elizaos/core';
4
+ import dotenv from 'dotenv';
5
+
6
+ // Setup environment variables
7
+ dotenv.config();
8
+
9
+ // Need to spy on logger for documentation
10
+ beforeAll(() => {
11
+ spyOn(logger, 'info');
12
+ spyOn(logger, 'error');
13
+ spyOn(logger, 'warn');
14
+ spyOn(logger, 'debug');
15
+ });
16
+
17
+ afterAll(() => {
18
+ // No global restore needed in bun:test
19
+ });
20
+
21
+ // Create a real runtime for testing
22
+ function createRealRuntime() {
23
+ const services = new Map();
24
+
25
+ // Create a real service instance if needed
26
+ const createService = (serviceType: string) => {
27
+ if (serviceType === StarterService.serviceType) {
28
+ return new StarterService({
29
+ character: {
30
+ name: 'Test Character',
31
+ system: 'You are a helpful assistant for testing.',
32
+ },
33
+ } as any);
34
+ }
35
+ return null;
36
+ };
37
+
38
+ return {
39
+ character: {
40
+ name: 'Test Character',
41
+ system: 'You are a helpful assistant for testing.',
42
+ plugins: [],
43
+ settings: {},
44
+ },
45
+ getSetting: (key: string) => null,
46
+ models: starterPlugin.models,
47
+ db: {
48
+ get: async (key: string) => null,
49
+ set: async (key: string, value: any) => true,
50
+ delete: async (key: string) => true,
51
+ getKeys: async (pattern: string) => [],
52
+ },
53
+ getService: (serviceType: string) => {
54
+ // Log the service request for debugging
55
+ logger.debug(`Requesting service: ${serviceType}`);
56
+
57
+ // Get from cache or create new
58
+ if (!services.has(serviceType)) {
59
+ logger.debug(`Creating new service: ${serviceType}`);
60
+ services.set(serviceType, createService(serviceType));
61
+ }
62
+
63
+ return services.get(serviceType);
64
+ },
65
+ registerService: (serviceType: string, service: any) => {
66
+ logger.debug(`Registering service: ${serviceType}`);
67
+ services.set(serviceType, service);
68
+ },
69
+ };
70
+ }
71
+
72
+ describe('Plugin Configuration', () => {
73
+ it('should have correct plugin metadata', () => {
74
+ expect(starterPlugin.name).toBe('plugin-starter');
75
+ expect(starterPlugin.description).toBe('Plugin starter for elizaOS');
76
+ expect(starterPlugin.config).toBeDefined();
77
+ });
78
+
79
+ it('should include the EXAMPLE_PLUGIN_VARIABLE in config', () => {
80
+ expect(starterPlugin.config).toHaveProperty('EXAMPLE_PLUGIN_VARIABLE');
81
+ });
82
+
83
+ it('should initialize properly', async () => {
84
+ const originalEnv = process.env.EXAMPLE_PLUGIN_VARIABLE;
85
+
86
+ try {
87
+ process.env.EXAMPLE_PLUGIN_VARIABLE = 'test-value';
88
+
89
+ // Initialize with config - using real runtime
90
+ const runtime = createRealRuntime();
91
+
92
+ if (starterPlugin.init) {
93
+ await starterPlugin.init({ EXAMPLE_PLUGIN_VARIABLE: 'test-value' }, runtime as any);
94
+ expect(true).toBe(true); // If we got here, init succeeded
95
+ }
96
+ } finally {
97
+ process.env.EXAMPLE_PLUGIN_VARIABLE = originalEnv;
98
+ }
99
+ });
100
+
101
+ it('should have a valid config', () => {
102
+ expect(starterPlugin.config).toBeDefined();
103
+ if (starterPlugin.config) {
104
+ // Check if the config has expected EXAMPLE_PLUGIN_VARIABLE property
105
+ expect(Object.keys(starterPlugin.config)).toContain('EXAMPLE_PLUGIN_VARIABLE');
106
+ }
107
+ });
108
+ });
109
+
110
+ describe('Plugin Models', () => {
111
+ it('should have TEXT_SMALL model defined', () => {
112
+ expect(starterPlugin.models?.[ModelType.TEXT_SMALL]).toBeDefined();
113
+ if (starterPlugin.models) {
114
+ expect(typeof starterPlugin.models[ModelType.TEXT_SMALL]).toBe('function');
115
+ }
116
+ });
117
+
118
+ it('should have TEXT_LARGE model defined', () => {
119
+ expect(starterPlugin.models?.[ModelType.TEXT_LARGE]).toBeDefined();
120
+ if (starterPlugin.models) {
121
+ expect(typeof starterPlugin.models[ModelType.TEXT_LARGE]).toBe('function');
122
+ }
123
+ });
124
+
125
+ it('should return a response from TEXT_SMALL model', async () => {
126
+ if (starterPlugin.models?.[ModelType.TEXT_SMALL]) {
127
+ const runtime = createRealRuntime();
128
+ const result = await starterPlugin.models[ModelType.TEXT_SMALL](runtime as any, {
129
+ prompt: 'test',
130
+ });
131
+
132
+ // Check that we get a non-empty string response
133
+ expect(result).toBeTruthy();
134
+ expect(typeof result).toBe('string');
135
+ expect(result.length).toBeGreaterThan(10);
136
+ }
137
+ });
138
+ });
139
+
140
+ describe('StarterService', () => {
141
+ it('should start the service', async () => {
142
+ const runtime = createRealRuntime();
143
+ const startResult = await StarterService.start(runtime as any);
144
+
145
+ expect(startResult).toBeDefined();
146
+ expect(startResult.constructor.name).toBe('StarterService');
147
+
148
+ // Test real functionality - check stop method is available
149
+ expect(typeof startResult.stop).toBe('function');
150
+ });
151
+
152
+ it('should stop the service', async () => {
153
+ const runtime = createRealRuntime();
154
+
155
+ // Register a real service first
156
+ const service = new StarterService(runtime as any);
157
+ runtime.registerService(StarterService.serviceType, service);
158
+
159
+ // Spy on the real service's stop method
160
+ const stopSpy = spyOn(service, 'stop');
161
+
162
+ // Call the static stop method
163
+ await StarterService.stop(runtime as any);
164
+
165
+ // Verify the service's stop method was called
166
+ expect(stopSpy).toHaveBeenCalled();
167
+ });
168
+
169
+ it('should throw an error when stopping a non-existent service', async () => {
170
+ const runtime = createRealRuntime();
171
+ // Don't register a service, so getService will return null
172
+
173
+ // We'll patch the getService function to ensure it returns null
174
+ const originalGetService = runtime.getService;
175
+ runtime.getService = () => null;
176
+
177
+ await expect(StarterService.stop(runtime as any)).rejects.toThrow('Starter service not found');
178
+
179
+ // Restore original getService function
180
+ runtime.getService = originalGetService;
181
+ });
182
+ });