@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.
- package/README.md +1 -0
- package/dist/assets/{index-BQEpBB33.js → index-BaWElBml.js} +65713 -67371
- package/dist/assets/{index-BQEpBB33.js.map → index-BaWElBml.js.map} +1 -1
- package/dist/assets/{index-eRnFTOEM.js → index-Bs4IloEa.js} +2 -2
- package/dist/assets/index-Bs4IloEa.js.br +0 -0
- package/dist/assets/{index-eRnFTOEM.js.map → index-Bs4IloEa.js.map} +1 -1
- package/dist/{chunk-QC5MM66L.js → chunk-246Q3Y5O.js} +3 -3
- package/dist/chunk-2GXSCVA2.js +2057 -0
- package/dist/chunk-67L4I5S7.js +80 -0
- package/dist/chunk-7HDCC22V.js +771 -0
- package/dist/{chunk-F3WZNGHX.js → chunk-BZIUA2KE.js} +6 -0
- package/dist/{chunk-QU55ROKN.js → chunk-GE5HMHU5.js} +12 -6
- package/dist/{chunk-URANH3OS.js → chunk-JT3O6PBU.js} +3867 -529
- package/dist/{chunk-XVN7DK3U.js → chunk-KNZMV4HH.js} +4 -4
- package/dist/{chunk-QPXAVEMR.js → chunk-NQ5HAYUQ.js} +40 -2
- package/dist/{chunk-XF2FQZM2.js → chunk-OF5WHPTG.js} +105 -798
- package/dist/{chunk-ENUVIKE2.js → chunk-OG4OJUNA.js} +2 -2
- package/dist/{chunk-SOL3WRAY.js → chunk-OJMVYUOU.js} +1 -1
- package/dist/{chunk-XLCI6Y5F.js → chunk-QGZZVGE5.js} +2 -2
- package/dist/{chunk-PJJS5DFB.js → chunk-WAJ5RHPK.js} +1 -1
- package/dist/commands/agent.js +2 -1
- package/dist/commands/create.js +4 -3
- package/dist/commands/dev.js +4 -3
- package/dist/commands/env.js +3 -2
- package/dist/commands/plugins.js +4 -3
- package/dist/commands/publish.js +5 -4
- package/dist/commands/setup-monorepo.js +3 -2
- package/dist/commands/start.js +7 -5
- package/dist/commands/test.js +8 -6
- package/dist/commands/update.js +4 -3
- package/dist/fileFromPath-DCRQMDLJ.js +132 -0
- package/dist/index.html +1 -1
- package/dist/index.js +14 -12
- package/dist/migrator-7EYGXTDW.js +29035 -0
- package/dist/{registry-YU4WBPLU.js → registry-RGSXW4LO.js} +2 -1
- package/package.json +10 -4
- package/templates/plugin-starter/package.json +1 -1
- package/templates/project-starter/.env.example +1 -0
- package/templates/project-starter/package.json +4 -4
- package/templates/project-tee-starter/.dockerignore +20 -0
- package/templates/project-tee-starter/.env.example +55 -0
- package/templates/project-tee-starter/Dockerfile +66 -0
- package/templates/project-tee-starter/GUIDE.md +235 -0
- package/templates/project-tee-starter/README.md +173 -0
- package/templates/project-tee-starter/__tests__/actions.test.ts +9 -0
- package/templates/project-tee-starter/__tests__/character.test.ts +86 -0
- package/templates/project-tee-starter/__tests__/config.test.ts +31 -0
- package/templates/project-tee-starter/__tests__/env.test.ts +87 -0
- package/templates/project-tee-starter/__tests__/error-handling.test.ts +30 -0
- package/templates/project-tee-starter/__tests__/events.test.ts +21 -0
- package/templates/project-tee-starter/__tests__/file-structure.test.ts +135 -0
- package/templates/project-tee-starter/__tests__/integration.test.ts +209 -0
- package/templates/project-tee-starter/__tests__/models.test.ts +22 -0
- package/templates/project-tee-starter/__tests__/plugin.test.ts +44 -0
- package/templates/project-tee-starter/__tests__/provider.test.ts +189 -0
- package/templates/project-tee-starter/__tests__/routes.test.ts +21 -0
- package/templates/project-tee-starter/__tests__/test-utils.ts +121 -0
- package/templates/project-tee-starter/__tests__/utils/core-test-utils.ts +167 -0
- package/templates/project-tee-starter/assets/mr-tee-portrait.jpg +0 -0
- package/templates/project-tee-starter/docker-compose.yaml +57 -0
- package/templates/project-tee-starter/e2e/project.test.ts +38 -0
- package/templates/project-tee-starter/e2e/starter-plugin.test.ts +92 -0
- package/templates/project-tee-starter/package.json +76 -0
- package/templates/project-tee-starter/src/character.ts +257 -0
- package/templates/project-tee-starter/src/index.ts +33 -0
- package/templates/project-tee-starter/src/plugin.ts +169 -0
- package/templates/project-tee-starter/tsconfig.build.json +13 -0
- package/templates/project-tee-starter/tsconfig.json +30 -0
- package/templates/project-tee-starter/tsup.config.ts +19 -0
- package/templates/project-tee-starter/vitest.config.ts +19 -0
- package/dist/assets/index-eRnFTOEM.js.br +0 -0
- package/dist/eliza-J3ANDQXN.js +0 -13
- /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
|
+
});
|