@elizaos/cli 1.0.2 → 1.0.3

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 (73) hide show
  1. package/README.md +1 -0
  2. package/dist/assets/{index-BQEpBB33.js → index-BaWElBml.js} +65713 -67371
  3. package/dist/assets/{index-BQEpBB33.js.map → index-BaWElBml.js.map} +1 -1
  4. package/dist/assets/{index-eRnFTOEM.js → index-Bs4IloEa.js} +2 -2
  5. package/dist/assets/index-Bs4IloEa.js.br +0 -0
  6. package/dist/assets/{index-eRnFTOEM.js.map → index-Bs4IloEa.js.map} +1 -1
  7. package/dist/{chunk-QC5MM66L.js → chunk-246Q3Y5O.js} +3 -3
  8. package/dist/chunk-2GXSCVA2.js +2057 -0
  9. package/dist/chunk-67L4I5S7.js +80 -0
  10. package/dist/chunk-7HDCC22V.js +771 -0
  11. package/dist/{chunk-F3WZNGHX.js → chunk-BZIUA2KE.js} +6 -0
  12. package/dist/{chunk-QU55ROKN.js → chunk-GE5HMHU5.js} +12 -6
  13. package/dist/{chunk-URANH3OS.js → chunk-JT3O6PBU.js} +3867 -529
  14. package/dist/{chunk-XVN7DK3U.js → chunk-KNZMV4HH.js} +4 -4
  15. package/dist/{chunk-QPXAVEMR.js → chunk-NQ5HAYUQ.js} +40 -2
  16. package/dist/{chunk-XF2FQZM2.js → chunk-OF5WHPTG.js} +105 -798
  17. package/dist/{chunk-ENUVIKE2.js → chunk-OG4OJUNA.js} +2 -2
  18. package/dist/{chunk-SOL3WRAY.js → chunk-OJMVYUOU.js} +1 -1
  19. package/dist/{chunk-XLCI6Y5F.js → chunk-QGZZVGE5.js} +2 -2
  20. package/dist/{chunk-PJJS5DFB.js → chunk-WAJ5RHPK.js} +1 -1
  21. package/dist/commands/agent.js +2 -1
  22. package/dist/commands/create.js +4 -3
  23. package/dist/commands/dev.js +4 -3
  24. package/dist/commands/env.js +3 -2
  25. package/dist/commands/plugins.js +4 -3
  26. package/dist/commands/publish.js +5 -4
  27. package/dist/commands/setup-monorepo.js +3 -2
  28. package/dist/commands/start.js +7 -5
  29. package/dist/commands/test.js +8 -6
  30. package/dist/commands/update.js +4 -3
  31. package/dist/fileFromPath-DCRQMDLJ.js +132 -0
  32. package/dist/index.html +1 -1
  33. package/dist/index.js +14 -12
  34. package/dist/migrator-7EYGXTDW.js +29035 -0
  35. package/dist/{registry-YU4WBPLU.js → registry-RGSXW4LO.js} +2 -1
  36. package/package.json +10 -4
  37. package/templates/plugin-starter/package.json +1 -1
  38. package/templates/project-starter/.env.example +1 -0
  39. package/templates/project-starter/package.json +4 -4
  40. package/templates/project-tee-starter/.dockerignore +20 -0
  41. package/templates/project-tee-starter/.env.example +55 -0
  42. package/templates/project-tee-starter/Dockerfile +66 -0
  43. package/templates/project-tee-starter/GUIDE.md +235 -0
  44. package/templates/project-tee-starter/README.md +173 -0
  45. package/templates/project-tee-starter/__tests__/actions.test.ts +9 -0
  46. package/templates/project-tee-starter/__tests__/character.test.ts +86 -0
  47. package/templates/project-tee-starter/__tests__/config.test.ts +31 -0
  48. package/templates/project-tee-starter/__tests__/env.test.ts +87 -0
  49. package/templates/project-tee-starter/__tests__/error-handling.test.ts +30 -0
  50. package/templates/project-tee-starter/__tests__/events.test.ts +21 -0
  51. package/templates/project-tee-starter/__tests__/file-structure.test.ts +135 -0
  52. package/templates/project-tee-starter/__tests__/integration.test.ts +209 -0
  53. package/templates/project-tee-starter/__tests__/models.test.ts +22 -0
  54. package/templates/project-tee-starter/__tests__/plugin.test.ts +44 -0
  55. package/templates/project-tee-starter/__tests__/provider.test.ts +189 -0
  56. package/templates/project-tee-starter/__tests__/routes.test.ts +21 -0
  57. package/templates/project-tee-starter/__tests__/test-utils.ts +121 -0
  58. package/templates/project-tee-starter/__tests__/utils/core-test-utils.ts +167 -0
  59. package/templates/project-tee-starter/assets/mr-tee-portrait.jpg +0 -0
  60. package/templates/project-tee-starter/docker-compose.yaml +57 -0
  61. package/templates/project-tee-starter/e2e/project.test.ts +38 -0
  62. package/templates/project-tee-starter/e2e/starter-plugin.test.ts +92 -0
  63. package/templates/project-tee-starter/package.json +76 -0
  64. package/templates/project-tee-starter/src/character.ts +257 -0
  65. package/templates/project-tee-starter/src/index.ts +33 -0
  66. package/templates/project-tee-starter/src/plugin.ts +169 -0
  67. package/templates/project-tee-starter/tsconfig.build.json +13 -0
  68. package/templates/project-tee-starter/tsconfig.json +30 -0
  69. package/templates/project-tee-starter/tsup.config.ts +19 -0
  70. package/templates/project-tee-starter/vitest.config.ts +19 -0
  71. package/dist/assets/index-eRnFTOEM.js.br +0 -0
  72. package/dist/eliza-J3ANDQXN.js +0 -13
  73. /package/dist/{chunk-YX7JHUJ5.js → chunk-BDPGXNHU.js} +0 -0
@@ -0,0 +1,86 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { mrTeeCharacter as character } from '../src/character';
3
+ import * as dotenv from 'dotenv';
4
+ import * as path from 'node:path';
5
+
6
+ dotenv.config({ path: path.resolve(__dirname, '../../.env') });
7
+
8
+ describe('Mr. TEE Character Configuration', () => {
9
+ it('should have all required fields for Mr. TEE', () => {
10
+ expect(character).toBeDefined();
11
+ expect(character.name).toBe('Mr. TEE');
12
+ expect(character.plugins).toBeDefined();
13
+ expect(character.settings).toBeDefined();
14
+ expect(character.system).toBeDefined();
15
+ expect(character.bio).toBeDefined();
16
+ expect(character.messageExamples).toBeDefined();
17
+ expect(character.postExamples).toBeDefined();
18
+ expect(character.style).toBeDefined();
19
+ expect(character.settings?.avatar).toContain('data:image/jpeg;base64');
20
+ expect(character.settings).toHaveProperty('secrets');
21
+ });
22
+
23
+ it('should include TEE specific plugins', () => {
24
+ expect(character.plugins).toContain('@elizaos/plugin-tee');
25
+ expect(character.plugins).toContain('@elizaos/plugin-sql');
26
+ expect(character.plugins).toContain('@elizaos/plugin-openai');
27
+ expect(character.plugins).toContain('@elizaos/plugin-discord');
28
+ expect(character.plugins).toContain('@elizaos/plugin-bootstrap');
29
+ });
30
+
31
+ it("should have a system prompt embodying Mr. TEE's persona", () => {
32
+ expect(character.system).toContain('Mr. TEE');
33
+ expect(character.system).toContain('drill sergeant');
34
+ expect(character.system).toContain('Trusted Execution Environment');
35
+ expect(character.system).toContain('I pity the fool');
36
+ });
37
+
38
+ it("should have bio entries reflecting Mr. TEE's background", () => {
39
+ const bioText = Array.isArray(character.bio) ? character.bio.join(' ').toLowerCase() : '';
40
+ expect(bioText).toContain('tee security enforcer');
41
+ expect(bioText).toContain('attestation authority');
42
+ expect(bioText).toContain('hardware security');
43
+ });
44
+
45
+ it('should have TEE-related message examples', () => {
46
+ let foundTeeExample = false;
47
+ for (const ex of character.messageExamples) {
48
+ const dialogue = ex.map((msg) => msg.content.text.toLowerCase()).join(' ');
49
+ if (
50
+ dialogue.includes('attestation') ||
51
+ dialogue.includes('enclave') ||
52
+ dialogue.includes('tee')
53
+ ) {
54
+ foundTeeExample = true;
55
+ const mrTeeResponse = ex.find((msg) => msg.name === 'Mr. TEE');
56
+ expect(mrTeeResponse).toBeDefined();
57
+ if (mrTeeResponse) {
58
+ expect(mrTeeResponse.content.text.length).toBeGreaterThan(10);
59
+ if (mrTeeResponse.content.actions) {
60
+ expect(Array.isArray(mrTeeResponse.content.actions)).toBe(true);
61
+ }
62
+ }
63
+ break;
64
+ }
65
+ }
66
+ expect(foundTeeExample, 'Expected at least one TEE-related message example').toBe(true);
67
+ });
68
+
69
+ it('should have TEE-related post examples', () => {
70
+ const postText = character.postExamples?.join(' ').toLowerCase() || '';
71
+ expect(postText).toContain('#teesecurity');
72
+ expect(postText).toContain('enclave');
73
+ expect(postText).toContain('attestation');
74
+ });
75
+
76
+ it('should have specific style guidelines for Mr. TEE', () => {
77
+ expect(character.style?.all).toContain('Direct and commanding');
78
+ expect(character.style?.chat).toContain('Respond to all security questions with authority');
79
+ expect(character.style?.post).toContain('TEE evangelism with attitude');
80
+ });
81
+
82
+ it('should have TEE related settings in secrets', () => {
83
+ expect(character.settings?.secrets).toHaveProperty('TEE_MODE');
84
+ expect(character.settings?.secrets).toHaveProperty('TEE_VENDOR');
85
+ });
86
+ });
@@ -0,0 +1,31 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import teeStarterPlugin from '../src/plugin';
3
+
4
+ describe('Plugin Configuration', () => {
5
+ it('should not have custom configuration (relies on character settings)', () => {
6
+ // Our plugin has config properties for TEE_MODE and WALLET_SECRET_SALT
7
+ expect(teeStarterPlugin.config).toBeDefined();
8
+ expect(teeStarterPlugin.config?.TEE_MODE).toBe(process.env.TEE_MODE);
9
+ expect(teeStarterPlugin.config?.WALLET_SECRET_SALT).toBe(process.env.WALLET_SECRET_SALT);
10
+ expect(teeStarterPlugin.init).toBeDefined();
11
+ });
12
+
13
+ it('should have correct plugin metadata', () => {
14
+ expect(teeStarterPlugin).toBeDefined();
15
+ expect(teeStarterPlugin.name).toBe('mr-tee-starter-plugin');
16
+ expect(teeStarterPlugin.description).toBe(
17
+ "Mr. TEE's starter plugin - using plugin-tee for attestation"
18
+ );
19
+ });
20
+
21
+ it('should be a minimal plugin focused on character definition', () => {
22
+ // Verify arrays exist but are empty (except routes and events)
23
+ expect(teeStarterPlugin.actions).toEqual([]);
24
+ expect(teeStarterPlugin.providers).toEqual([]);
25
+ expect(teeStarterPlugin.evaluators).toBeUndefined();
26
+ expect(teeStarterPlugin.services).toEqual([]);
27
+ expect(teeStarterPlugin.routes).toBeDefined();
28
+ expect(teeStarterPlugin.routes?.length).toBeGreaterThan(0);
29
+ expect(teeStarterPlugin.events).toBeDefined();
30
+ });
31
+ });
@@ -0,0 +1,87 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { describe, expect, it } from 'vitest';
4
+
5
+ describe('Environment Setup', () => {
6
+ it('should verify configuration files exist', () => {
7
+ const requiredFiles = [
8
+ 'package.json',
9
+ 'tsconfig.json',
10
+ 'tsconfig.build.json',
11
+ 'tsup.config.ts',
12
+ 'vitest.config.ts',
13
+ ];
14
+
15
+ for (const file of requiredFiles) {
16
+ const filePath = path.join(process.cwd(), file);
17
+ expect(fs.existsSync(filePath)).toBe(true);
18
+ }
19
+ });
20
+
21
+ it('should have proper src directory structure', () => {
22
+ const srcDir = path.join(process.cwd(), 'src');
23
+ expect(fs.existsSync(srcDir)).toBe(true);
24
+
25
+ const requiredSrcFiles = ['index.ts', 'plugin.ts'];
26
+
27
+ for (const file of requiredSrcFiles) {
28
+ const filePath = path.join(srcDir, file);
29
+ expect(fs.existsSync(filePath)).toBe(true);
30
+ }
31
+ });
32
+
33
+ it('should have a valid package.json with required fields', () => {
34
+ const packageJsonPath = path.join(process.cwd(), 'package.json');
35
+ expect(fs.existsSync(packageJsonPath)).toBe(true);
36
+
37
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
38
+ expect(packageJson).toHaveProperty('name', '@elizaos/project-tee-starter');
39
+ expect(packageJson).toHaveProperty('version');
40
+ expect(packageJson).toHaveProperty('type', 'module');
41
+ expect(packageJson).toHaveProperty('main');
42
+ expect(packageJson).toHaveProperty('module');
43
+ expect(packageJson).toHaveProperty('types');
44
+ expect(packageJson).toHaveProperty('dependencies');
45
+ expect(packageJson).toHaveProperty('devDependencies');
46
+ expect(packageJson).toHaveProperty('scripts');
47
+
48
+ // Check for required dependencies
49
+ expect(packageJson.dependencies).toHaveProperty('@elizaos/core');
50
+
51
+ // Check for required scripts
52
+ expect(packageJson.scripts).toHaveProperty('build');
53
+ expect(packageJson.scripts).toHaveProperty('test');
54
+ });
55
+
56
+ it('should have a valid tsconfig.json with required configuration', () => {
57
+ const tsconfigPath = path.join(process.cwd(), 'tsconfig.json');
58
+ expect(fs.existsSync(tsconfigPath)).toBe(true);
59
+
60
+ const tsconfig = JSON.parse(fs.readFileSync(tsconfigPath, 'utf8'));
61
+ expect(tsconfig).toHaveProperty('compilerOptions');
62
+
63
+ // Check compiler options
64
+ expect(tsconfig.compilerOptions).toHaveProperty('target');
65
+ expect(tsconfig.compilerOptions).toHaveProperty('module');
66
+ expect(tsconfig.compilerOptions).toHaveProperty('moduleResolution');
67
+ expect(tsconfig.compilerOptions).toHaveProperty('esModuleInterop');
68
+ });
69
+
70
+ it('should have a valid tsup.config.ts for building', () => {
71
+ const tsupConfigPath = path.join(process.cwd(), 'tsup.config.ts');
72
+ expect(fs.existsSync(tsupConfigPath)).toBe(true);
73
+
74
+ const tsupConfig = fs.readFileSync(tsupConfigPath, 'utf8');
75
+ expect(tsupConfig).toContain('defineConfig');
76
+ expect(tsupConfig).toContain('entry:');
77
+ expect(tsupConfig).toContain('src/index.ts');
78
+ });
79
+
80
+ it('should have a valid README.md file', () => {
81
+ const readmePath = path.join(process.cwd(), 'README.md');
82
+ expect(fs.existsSync(readmePath)).toBe(true);
83
+
84
+ const readme = fs.readFileSync(readmePath, 'utf8');
85
+ expect(readme).toContain('# Project Starter');
86
+ });
87
+ });
@@ -0,0 +1,30 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import teeStarterPlugin from '../src/plugin';
3
+ import { mrTeeCharacter } from '../src/character';
4
+
5
+ describe('Error Handling', () => {
6
+ describe('Plugin Error Handling', () => {
7
+ it('should handle missing dependencies gracefully', () => {
8
+ // Our plugin has no dependencies, so it should always be valid
9
+ expect(teeStarterPlugin).toBeDefined();
10
+ expect(teeStarterPlugin.actions).toEqual([]);
11
+ expect(teeStarterPlugin.providers).toEqual([]);
12
+ });
13
+
14
+ it('should handle runtime errors gracefully', async () => {
15
+ // Test that the plugin can be used even without initialization
16
+ expect(teeStarterPlugin.name).toBe('mr-tee-starter-plugin');
17
+ expect(teeStarterPlugin.description).toBe(
18
+ "Mr. TEE's starter plugin - using plugin-tee for attestation"
19
+ );
20
+ });
21
+ });
22
+
23
+ describe('Character Error Handling', () => {
24
+ it('should have valid character configuration', () => {
25
+ expect(mrTeeCharacter).toBeDefined();
26
+ expect(mrTeeCharacter.name).toBe('Mr. TEE');
27
+ expect(mrTeeCharacter.plugins).toContain('@elizaos/plugin-tee');
28
+ });
29
+ });
30
+ });
@@ -0,0 +1,21 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import teeStarterPlugin from '../src/plugin';
3
+
4
+ describe('Plugin Events', () => {
5
+ it('should not have custom events (relies on plugin-tee for TEE events)', () => {
6
+ // Our plugin actually has events defined for logging
7
+ expect(teeStarterPlugin.events).toBeDefined();
8
+ expect(teeStarterPlugin.events?.MESSAGE_RECEIVED).toBeDefined();
9
+ expect(teeStarterPlugin.events?.VOICE_MESSAGE_RECEIVED).toBeDefined();
10
+ expect(teeStarterPlugin.events?.WORLD_CONNECTED).toBeDefined();
11
+ expect(teeStarterPlugin.events?.WORLD_JOINED).toBeDefined();
12
+ });
13
+
14
+ it('should have correct plugin configuration', () => {
15
+ expect(teeStarterPlugin).toBeDefined();
16
+ expect(teeStarterPlugin.name).toBe('mr-tee-starter-plugin');
17
+ expect(teeStarterPlugin.description).toBe(
18
+ "Mr. TEE's starter plugin - using plugin-tee for attestation"
19
+ );
20
+ });
21
+ });
@@ -0,0 +1,135 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import { logger } from '@elizaos/core';
5
+
6
+ // Helper function to check if a file exists
7
+ function fileExists(filePath: string): boolean {
8
+ return fs.existsSync(filePath);
9
+ }
10
+
11
+ // Helper function to check if a directory exists
12
+ function directoryExists(dirPath: string): boolean {
13
+ return fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();
14
+ }
15
+
16
+ describe('Project Structure Validation', () => {
17
+ const rootDir = path.resolve(__dirname, '..');
18
+
19
+ describe('Directory Structure', () => {
20
+ it('should have the expected directory structure', () => {
21
+ expect(directoryExists(path.join(rootDir, 'src'))).toBe(true);
22
+ expect(directoryExists(path.join(rootDir, '__tests__'))).toBe(true);
23
+ });
24
+
25
+ it('should have a dist directory after building', () => {
26
+ // This test assumes the build has been run before testing
27
+ expect(directoryExists(path.join(rootDir, 'dist'))).toBe(true);
28
+ });
29
+ });
30
+
31
+ describe('Source Files', () => {
32
+ it('should contain the required source files', () => {
33
+ expect(fileExists(path.join(rootDir, 'src', 'index.ts'))).toBe(true);
34
+ expect(fileExists(path.join(rootDir, 'src', 'plugin.ts'))).toBe(true);
35
+ });
36
+
37
+ it('should have properly structured main files', () => {
38
+ // Check index.ts contains character definition
39
+ const indexContent = fs.readFileSync(path.join(rootDir, 'src', 'index.ts'), 'utf8');
40
+ expect(indexContent).toContain('character');
41
+ expect(indexContent).toContain('plugin');
42
+
43
+ // Check plugin.ts contains plugin definition
44
+ const pluginContent = fs.readFileSync(path.join(rootDir, 'src', 'plugin.ts'), 'utf8');
45
+ expect(pluginContent).toContain('export default');
46
+ expect(pluginContent).toContain('actions');
47
+ });
48
+ });
49
+
50
+ describe('Configuration Files', () => {
51
+ it('should have the required configuration files', () => {
52
+ expect(fileExists(path.join(rootDir, 'package.json'))).toBe(true);
53
+ expect(fileExists(path.join(rootDir, 'tsconfig.json'))).toBe(true);
54
+ expect(fileExists(path.join(rootDir, 'tsconfig.build.json'))).toBe(true);
55
+ expect(fileExists(path.join(rootDir, 'tsup.config.ts'))).toBe(true);
56
+ expect(fileExists(path.join(rootDir, 'vitest.config.ts'))).toBe(true);
57
+ });
58
+
59
+ it('should have the correct package.json configuration', () => {
60
+ const packageJson = JSON.parse(fs.readFileSync(path.join(rootDir, 'package.json'), 'utf8'));
61
+
62
+ // Check package name
63
+ expect(packageJson.name).toBe('@elizaos/project-tee-starter');
64
+
65
+ // Check scripts
66
+ expect(packageJson.scripts).toHaveProperty('build');
67
+ expect(packageJson.scripts).toHaveProperty('test');
68
+ expect(packageJson.scripts).toHaveProperty('test:coverage');
69
+
70
+ // Check dependencies
71
+ expect(packageJson.dependencies).toHaveProperty('@elizaos/core');
72
+
73
+ // Check dev dependencies - adjusted for actual dev dependencies
74
+ expect(packageJson.devDependencies).toBeTruthy();
75
+ expect(packageJson.devDependencies).toHaveProperty('vitest');
76
+ expect(packageJson.devDependencies).toHaveProperty('tsup');
77
+ });
78
+
79
+ it('should have proper TypeScript configuration', () => {
80
+ const tsConfig = JSON.parse(fs.readFileSync(path.join(rootDir, 'tsconfig.json'), 'utf8'));
81
+
82
+ // Check essential compiler options
83
+ expect(tsConfig).toHaveProperty('compilerOptions');
84
+ expect(tsConfig.compilerOptions).toHaveProperty('target');
85
+ expect(tsConfig.compilerOptions).toHaveProperty('module');
86
+
87
+ // Check paths inclusion
88
+ expect(tsConfig).toHaveProperty('include');
89
+ });
90
+ });
91
+
92
+ describe('Build Output', () => {
93
+ it('should check for expected build output structure', () => {
94
+ // Instead of checking specific files, check that the dist directory exists
95
+ // and contains at least some files
96
+ if (directoryExists(path.join(rootDir, 'dist'))) {
97
+ const files = fs.readdirSync(path.join(rootDir, 'dist'));
98
+ expect(files.length).toBeGreaterThan(0);
99
+
100
+ // Check for common output patterns rather than specific files
101
+ const hasJsFiles = files.some((file) => file.endsWith('.js'));
102
+ expect(hasJsFiles).toBe(true);
103
+ } else {
104
+ // Skip test if dist directory doesn't exist yet
105
+ logger.warn('Dist directory not found, skipping build output tests');
106
+ }
107
+ });
108
+
109
+ it('should verify the build process can be executed', () => {
110
+ // Check that the build script exists in package.json
111
+ const packageJson = JSON.parse(fs.readFileSync(path.join(rootDir, 'package.json'), 'utf8'));
112
+ expect(packageJson.scripts).toHaveProperty('build');
113
+
114
+ // Check that tsup.config.ts exists and contains proper configuration
115
+ const tsupConfig = fs.readFileSync(path.join(rootDir, 'tsup.config.ts'), 'utf8');
116
+ expect(tsupConfig).toContain('export default');
117
+ expect(tsupConfig).toContain('entry');
118
+ });
119
+ });
120
+
121
+ describe('Documentation', () => {
122
+ it('should have README files', () => {
123
+ expect(fileExists(path.join(rootDir, 'README.md'))).toBe(true);
124
+ });
125
+
126
+ it('should have appropriate documentation content', () => {
127
+ const readmeContent = fs.readFileSync(path.join(rootDir, 'README.md'), 'utf8');
128
+ expect(readmeContent).toContain('Project Starter');
129
+
130
+ // Testing key sections exist without requiring specific keywords
131
+ expect(readmeContent).toContain('Development');
132
+ expect(readmeContent).toContain('Testing');
133
+ });
134
+ });
135
+ });
@@ -0,0 +1,209 @@
1
+ import { describe, expect, it, vi, beforeAll, afterAll } from 'vitest';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import { logger, IAgentRuntime, Plugin } from '@elizaos/core';
5
+ import { character } from '../src/index';
6
+ import plugin from '../src/plugin';
7
+ import { createMockRuntime } from './test-utils';
8
+ import * as os from 'os';
9
+
10
+ // Set up spies on logger
11
+ beforeAll(() => {
12
+ vi.spyOn(logger, 'info').mockImplementation(() => {});
13
+ vi.spyOn(logger, 'error').mockImplementation(() => {});
14
+ vi.spyOn(logger, 'warn').mockImplementation(() => {});
15
+ vi.spyOn(logger, 'debug').mockImplementation(() => {});
16
+ });
17
+
18
+ afterAll(() => {
19
+ vi.restoreAllMocks();
20
+ });
21
+
22
+ // Skip in CI environments or when running automated tests without interaction
23
+ const isCI = Boolean(process.env.CI) || process.env.NODE_ENV === 'test';
24
+
25
+ /**
26
+ * Integration tests demonstrate how multiple components of the project work together.
27
+ * Unlike unit tests that test individual functions in isolation, integration tests
28
+ * examine how components interact with each other.
29
+ */
30
+ describe('Integration: Project Structure and Components', () => {
31
+ it('should have a valid package structure', () => {
32
+ const srcDir = path.join(process.cwd(), 'src');
33
+ expect(fs.existsSync(srcDir)).toBe(true);
34
+
35
+ // Check for required source files - only checking core files
36
+ const srcFiles = [path.join(srcDir, 'index.ts'), path.join(srcDir, 'plugin.ts')];
37
+
38
+ srcFiles.forEach((file) => {
39
+ expect(fs.existsSync(file)).toBe(true);
40
+ });
41
+ });
42
+
43
+ it('should have dist directory for build outputs', () => {
44
+ const distDir = path.join(process.cwd(), 'dist');
45
+
46
+ // Skip directory content validation if dist doesn't exist yet
47
+ if (!fs.existsSync(distDir)) {
48
+ logger.warn('Dist directory does not exist yet. Build the project first.');
49
+ return;
50
+ }
51
+
52
+ expect(fs.existsSync(distDir)).toBe(true);
53
+ });
54
+ });
55
+
56
+ describe('Integration: Character and Plugin', () => {
57
+ it('should have character with required properties', () => {
58
+ // Verify character has required properties
59
+ expect(character).toHaveProperty('name');
60
+ expect(character).toHaveProperty('plugins');
61
+ expect(character).toHaveProperty('bio');
62
+ expect(character).toHaveProperty('system');
63
+ expect(character).toHaveProperty('messageExamples');
64
+
65
+ // Verify plugins is an array
66
+ expect(Array.isArray(character.plugins)).toBe(true);
67
+ });
68
+
69
+ it('should configure plugin correctly', () => {
70
+ // Verify plugin has necessary components that character will use
71
+ expect(plugin).toHaveProperty('name');
72
+ expect(plugin).toHaveProperty('description');
73
+ expect(plugin).toHaveProperty('init');
74
+
75
+ // Check if plugin has actions, models, providers, etc. that character might use
76
+ const components = ['models', 'actions', 'providers', 'services', 'routes', 'events'];
77
+ components.forEach((component) => {
78
+ if (plugin[component]) {
79
+ // Just verify if these exist, we don't need to test their functionality here
80
+ // Those tests belong in plugin.test.ts, actions.test.ts, etc.
81
+ expect(
82
+ Array.isArray(plugin[component]) || typeof plugin[component] === 'object'
83
+ ).toBeTruthy();
84
+ }
85
+ });
86
+ });
87
+ });
88
+
89
+ describe('Integration: Runtime Initialization', () => {
90
+ it('should create a mock runtime with character and plugin', async () => {
91
+ // Create a custom mock runtime for this test
92
+ const customMockRuntime = {
93
+ character: { ...character },
94
+ plugins: [],
95
+ registerPlugin: vi.fn().mockImplementation((plugin: Plugin) => {
96
+ // In a real runtime, registering the plugin would call its init method,
97
+ // but since we're testing init itself, we just need to record the call
98
+ return Promise.resolve();
99
+ }),
100
+ initialize: vi.fn(),
101
+ getService: vi.fn(),
102
+ getSetting: vi.fn().mockReturnValue(null),
103
+ useModel: vi.fn().mockResolvedValue('Test model response'),
104
+ getProviderResults: vi.fn().mockResolvedValue([]),
105
+ evaluateProviders: vi.fn().mockResolvedValue([]),
106
+ evaluate: vi.fn().mockResolvedValue([]),
107
+ } as unknown as IAgentRuntime;
108
+
109
+ // Ensure we're testing safely - to avoid parallel test race conditions
110
+ const originalInit = plugin.init;
111
+ let initCalled = false;
112
+
113
+ // Mock the plugin.init method using vi.fn instead of direct assignment
114
+ if (plugin.init) {
115
+ plugin.init = vi.fn(async (config, runtime) => {
116
+ // Set flag to indicate our wrapper was called
117
+ initCalled = true;
118
+
119
+ // Call original if it exists
120
+ if (originalInit) {
121
+ await originalInit(config, runtime);
122
+ }
123
+
124
+ // Register plugin
125
+ await runtime.registerPlugin(plugin);
126
+ });
127
+ }
128
+
129
+ try {
130
+ // Initialize plugin in runtime
131
+ if (plugin.init) {
132
+ await plugin.init({ EXAMPLE_PLUGIN_VARIABLE: 'test-value' }, customMockRuntime);
133
+ }
134
+
135
+ // Verify our wrapper was called
136
+ expect(initCalled).toBe(true);
137
+
138
+ // Check if registerPlugin was called
139
+ expect(customMockRuntime.registerPlugin).toHaveBeenCalled();
140
+ } catch (error) {
141
+ console.error('Error initializing plugin:', error);
142
+ throw error;
143
+ } finally {
144
+ // Restore the original init method to avoid affecting other tests
145
+ plugin.init = originalInit;
146
+ }
147
+ });
148
+ });
149
+
150
+ // Skip scaffolding tests in CI environments as they modify the filesystem
151
+ const describeScaffolding = isCI ? describe.skip : describe;
152
+ describeScaffolding('Integration: Project Scaffolding', () => {
153
+ // Create a temp directory for testing the scaffolding
154
+ const TEST_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'eliza-test-'));
155
+
156
+ beforeAll(() => {
157
+ // Create test directory if it doesn't exist
158
+ if (!fs.existsSync(TEST_DIR)) {
159
+ fs.mkdirSync(TEST_DIR, { recursive: true });
160
+ }
161
+ });
162
+
163
+ afterAll(() => {
164
+ // Clean up test directory
165
+ if (fs.existsSync(TEST_DIR)) {
166
+ fs.rmSync(TEST_DIR, { recursive: true, force: true });
167
+ }
168
+ });
169
+
170
+ it('should scaffold a new project correctly', () => {
171
+ try {
172
+ // This is a simple simulation of the scaffolding process
173
+ // In a real scenario, you'd use the CLI or API to scaffold
174
+
175
+ // Copy essential files to test directory
176
+ const srcFiles = ['index.ts', 'plugin.ts', 'character.ts'];
177
+
178
+ for (const file of srcFiles) {
179
+ const sourceFilePath = path.join(process.cwd(), 'src', file);
180
+ const targetFilePath = path.join(TEST_DIR, file);
181
+
182
+ if (fs.existsSync(sourceFilePath)) {
183
+ fs.copyFileSync(sourceFilePath, targetFilePath);
184
+ }
185
+ }
186
+
187
+ // Create package.json in test directory
188
+ const packageJson = {
189
+ name: 'test-project',
190
+ version: '1.0.0',
191
+ type: 'module',
192
+ dependencies: {
193
+ '@elizaos/core': 'workspace:*',
194
+ },
195
+ };
196
+
197
+ fs.writeFileSync(path.join(TEST_DIR, 'package.json'), JSON.stringify(packageJson, null, 2));
198
+
199
+ // Verify files exist
200
+ expect(fs.existsSync(path.join(TEST_DIR, 'index.ts'))).toBe(true);
201
+ expect(fs.existsSync(path.join(TEST_DIR, 'plugin.ts'))).toBe(true);
202
+ expect(fs.existsSync(path.join(TEST_DIR, 'character.ts'))).toBe(true);
203
+ expect(fs.existsSync(path.join(TEST_DIR, 'package.json'))).toBe(true);
204
+ } catch (error) {
205
+ logger.error('Error in scaffolding test:', error);
206
+ throw error;
207
+ }
208
+ });
209
+ });
@@ -0,0 +1,22 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import teeStarterPlugin from '../src/plugin';
3
+
4
+ describe('Plugin Models', () => {
5
+ it('should not have custom models (using plugin-tee and other plugins for model handling)', () => {
6
+ // Our simplified plugin doesn't define custom models
7
+ // Model handling is done by other plugins (openai, etc.)
8
+ expect(teeStarterPlugin.models).toBeUndefined();
9
+ });
10
+
11
+ it('should rely on other plugins for model functionality', () => {
12
+ // Verify the plugin is configured correctly
13
+ expect(teeStarterPlugin.name).toBe('mr-tee-starter-plugin');
14
+ expect(teeStarterPlugin.description).toBe(
15
+ "Mr. TEE's starter plugin - using plugin-tee for attestation"
16
+ );
17
+
18
+ // Model functionality comes from character plugins
19
+ expect(teeStarterPlugin.actions).toEqual([]);
20
+ expect(teeStarterPlugin.providers).toEqual([]);
21
+ });
22
+ });
@@ -0,0 +1,44 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import teeStarterPlugin from '../src/plugin';
3
+ import { logger } from '@elizaos/core';
4
+
5
+ // Spy on logger to capture logs
6
+ vi.spyOn(logger, 'info');
7
+ vi.spyOn(logger, 'error');
8
+ vi.spyOn(logger, 'warn');
9
+
10
+ // Mock the character import to avoid file system dependencies
11
+ vi.mock('../src/character', () => ({
12
+ mrTeeCharacter: {
13
+ name: 'Mr. TEE',
14
+ plugins: ['@elizaos/plugin-tee'],
15
+ },
16
+ }));
17
+
18
+ describe('TEE Starter Plugin', () => {
19
+ it('should have the correct name', () => {
20
+ expect(teeStarterPlugin.name).toBe('mr-tee-starter-plugin');
21
+ });
22
+
23
+ it('should have the correct description', () => {
24
+ expect(teeStarterPlugin.description).toBe(
25
+ "Mr. TEE's starter plugin - using plugin-tee for attestation"
26
+ );
27
+ });
28
+
29
+ it('should have no custom actions (using plugin-tee instead)', () => {
30
+ expect(teeStarterPlugin.actions).toEqual([]);
31
+ });
32
+
33
+ it('should have no custom providers', () => {
34
+ expect(teeStarterPlugin.providers).toEqual([]);
35
+ });
36
+
37
+ it('should have no custom evaluators', () => {
38
+ expect(teeStarterPlugin.evaluators).toBeUndefined();
39
+ });
40
+
41
+ it('should have no custom services', () => {
42
+ expect(teeStarterPlugin.services).toEqual([]);
43
+ });
44
+ });