@elizaos/cli 1.0.0-beta.76 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +321 -58
  2. package/dist/assets/{index-BIHsjVvW.js → index-DLCBfFYd.js} +10219 -10388
  3. package/dist/assets/{index-BIHsjVvW.js.map → index-DLCBfFYd.js.map} +1 -1
  4. package/dist/assets/{index-BtftZiId.js → index-DNxLn4OZ.js} +3 -3
  5. package/dist/assets/{index-BtftZiId.js.map → index-DNxLn4OZ.js.map} +1 -1
  6. package/dist/assets/index-ljsW7JJO.css +1 -0
  7. package/dist/assets/index-ljsW7JJO.css.br +0 -0
  8. package/dist/assets/{vendor-BU4KHesT.js → vendor-CFQmvqmR.js} +16 -8
  9. package/dist/assets/vendor-CFQmvqmR.js.map +1 -0
  10. package/dist/{chunk-W4LNCUVN.js → chunk-5J7S2CSH.js} +21 -799
  11. package/dist/{chunk-5EU55Q35.js → chunk-5R4LDP3N.js} +37 -23
  12. package/dist/chunk-CTMXYF6P.js +70 -0
  13. package/dist/{chunk-QXVIZ77H.js → chunk-ENUVIKE2.js} +19 -89
  14. package/dist/chunk-F3WZNGHX.js +124 -0
  15. package/dist/{chunk-3QNEGOV7.js → chunk-MVWWKTRI.js} +66 -70
  16. package/dist/{chunk-WZ2HLKRP.js → chunk-PJJS5DFB.js} +13 -16
  17. package/dist/{chunk-HKPWAGXM.js → chunk-QC5MM66L.js} +69 -92
  18. package/dist/{chunk-Q7IRUYIE.js → chunk-QU55ROKN.js} +164 -100
  19. package/dist/{chunk-FJMBLQVG.js → chunk-SOL3WRAY.js} +3 -5
  20. package/dist/{chunk-IPMXNAUZ.js → chunk-UMDJUAZA.js} +27852 -11475
  21. package/dist/chunk-XF2FQZM2.js +7813 -0
  22. package/dist/{chunk-6FUKON44.js → chunk-XLCI6Y5F.js} +86 -62
  23. package/dist/{chunk-DL5KPHCD.js → chunk-YX7JHUJ5.js} +3 -5
  24. package/dist/commands/agent.js +2 -2
  25. package/dist/commands/create.js +4 -4
  26. package/dist/commands/dev.js +4 -3
  27. package/dist/commands/env.js +3 -3
  28. package/dist/commands/plugins.d.ts +1 -7
  29. package/dist/commands/plugins.js +6 -7
  30. package/dist/commands/publish.js +5 -4
  31. package/dist/commands/setup-monorepo.js +3 -3
  32. package/dist/commands/start.js +6 -6
  33. package/dist/commands/tee.js +2 -4
  34. package/dist/commands/test.js +7 -7
  35. package/dist/commands/update.js +4 -3
  36. package/dist/{eliza-B56L4TAD.js → eliza-J3ANDQXN.js} +1 -1
  37. package/dist/index.html +3 -3
  38. package/dist/index.js +27 -16
  39. package/dist/{registry-RCDD7ELI.js → registry-YU4WBPLU.js} +2 -2
  40. package/package.json +9 -4
  41. package/templates/plugin-starter/README.md +92 -11
  42. package/templates/plugin-starter/e2e/starter-plugin.test.ts +10 -16
  43. package/templates/plugin-starter/package.json +4 -5
  44. package/templates/plugin-starter/src/index.ts +1 -0
  45. package/templates/project-starter/.env.example +130 -24
  46. package/templates/project-starter/__tests__/config.test.ts +8 -7
  47. package/templates/project-starter/__tests__/plugin.test.ts +39 -36
  48. package/templates/project-starter/__tests__/provider.test.ts +33 -29
  49. package/templates/project-starter/__tests__/utils/core-test-utils.ts +24 -11
  50. package/templates/project-starter/e2e/starter-plugin.test.ts +1 -1
  51. package/templates/project-starter/package.json +7 -7
  52. package/templates/project-starter/tsup.config.ts +1 -1
  53. package/dist/assets/index-BtftZiId.js.br +0 -0
  54. package/dist/assets/index-CGLPeoBs.css +0 -1
  55. package/dist/assets/index-CGLPeoBs.css.br +0 -0
  56. package/dist/assets/vendor-BU4KHesT.js.br +0 -0
  57. package/dist/assets/vendor-BU4KHesT.js.map +0 -1
  58. package/dist/chunk-MMXVGVEC.js +0 -818
  59. package/dist/chunk-RZ4QEERU.js +0 -13807
  60. package/dist/chunk-Z23AQP3I.js +0 -20366
@@ -76,33 +76,113 @@ export default new StarterPluginTestSuite();
76
76
 
77
77
  The test utilities in `__tests__/test-utils.ts` provide mock objects and setup functions to simplify writing tests.
78
78
 
79
- ## Publishing
79
+ ## Publishing & Continuous Development
80
80
 
81
- Before publishing your plugin to the ElizaOS registry, ensure you meet these requirements:
81
+ ### Initial Setup
82
82
 
83
- 1. **GitHub Repository**
83
+ Before publishing your plugin, ensure you meet these requirements:
84
+
85
+ 1. **npm Authentication**
86
+
87
+ ```bash
88
+ npm login
89
+ ```
90
+
91
+ 2. **GitHub Repository**
84
92
 
85
93
  - Create a public GitHub repository for this plugin
86
94
  - Add the 'elizaos-plugins' topic to the repository
87
95
  - Use 'main' as the default branch
88
96
 
89
- 2. **Required Assets**
90
-
97
+ 3. **Required Assets**
91
98
  - Add images to the `images/` directory:
92
99
  - `logo.jpg` (400x400px square, <500KB)
93
100
  - `banner.jpg` (1280x640px, <1MB)
94
101
 
95
- 3. **Publishing Process**
102
+ ### Initial Publishing
103
+
104
+ ```bash
105
+ # Test your plugin meets all requirements
106
+ elizaos publish --test
107
+
108
+ # Publish to npm + GitHub + registry (recommended)
109
+ elizaos publish
110
+ ```
111
+
112
+ This command will:
113
+
114
+ - Publish your plugin to npm for easy installation
115
+ - Create/update your GitHub repository
116
+ - Submit your plugin to the ElizaOS registry for discoverability
117
+
118
+ ### Continuous Development & Updates
119
+
120
+ **Important**: After your initial publish with `elizaos publish`, all future updates should be done using standard npm and git workflows, not the ElizaOS CLI.
121
+
122
+ #### Standard Update Workflow
123
+
124
+ 1. **Make Changes**
125
+
126
+ ```bash
127
+ # Edit your plugin code
128
+ npm run dev # Test locally with hot-reload
129
+ ```
130
+
131
+ 2. **Test Your Changes**
96
132
 
97
133
  ```bash
98
- # Check if your plugin meets all registry requirements
99
- npx elizaos publish --test
134
+ # Run all tests
135
+ elizaos test
100
136
 
101
- # Publish to the registry
102
- npx elizaos publish
137
+ # Run specific test types if needed
138
+ elizaos test component # Component tests only
139
+ elizaos test e2e # E2E tests only
103
140
  ```
104
141
 
105
- After publishing, your plugin will be submitted as a pull request to the ElizaOS registry for review.
142
+ 3. **Update Version**
143
+
144
+ ```bash
145
+ # Patch version (bug fixes): 1.0.0 → 1.0.1
146
+ npm version patch
147
+
148
+ # Minor version (new features): 1.0.1 → 1.1.0
149
+ npm version minor
150
+
151
+ # Major version (breaking changes): 1.1.0 → 2.0.0
152
+ npm version major
153
+ ```
154
+
155
+ 4. **Publish to npm**
156
+
157
+ ```bash
158
+ npm publish
159
+ ```
160
+
161
+ 5. **Push to GitHub**
162
+ ```bash
163
+ git push origin main
164
+ git push --tags # Push version tags
165
+ ```
166
+
167
+ #### Why Use Standard Workflows?
168
+
169
+ - **npm publish**: Directly updates your package on npm registry
170
+ - **git push**: Updates your GitHub repository with latest code
171
+ - **Automatic registry updates**: The ElizaOS registry automatically syncs with npm, so no manual registry updates needed
172
+ - **Standard tooling**: Uses familiar npm/git commands that work with all development tools
173
+
174
+ ### Alternative Publishing Options (Initial Only)
175
+
176
+ ```bash
177
+ # Publish to npm only (skip GitHub and registry)
178
+ elizaos publish --npm
179
+
180
+ # Publish but skip registry submission
181
+ elizaos publish --skip-registry
182
+
183
+ # Generate registry files locally without publishing
184
+ elizaos publish --dry-run
185
+ ```
106
186
 
107
187
  ## Configuration
108
188
 
@@ -130,3 +210,4 @@ Provide clear documentation about:
130
210
  - How to use it
131
211
  - Required API keys or credentials
132
212
  - Example usage
213
+ - Version history and changelog
@@ -1,5 +1,5 @@
1
- import { starterPlugin } from '../src/index';
2
- import { Content as CoreContent, HandlerCallback } from '@elizaos/core';
1
+ import { starterPlugin } from '../dist/index.js';
2
+ import { type Content, type HandlerCallback } from '@elizaos/core';
3
3
 
4
4
  // Define a minimal TestSuite interface that matches what's needed
5
5
  interface TestSuite {
@@ -30,17 +30,11 @@ interface State {
30
30
  text: string;
31
31
  }
32
32
 
33
- interface Content {
34
- text: string;
35
- source?: string;
36
- actions?: string[];
37
- }
33
+ export const StarterPluginTestSuite: TestSuite = {
34
+ name: 'plugin_starter_test_suite',
35
+ description: 'E2E tests for the starter plugin',
38
36
 
39
- export class StarterPluginTestSuite implements TestSuite {
40
- name = 'plugin_starter_test_suite';
41
- description = 'E2E tests for the starter plugin';
42
-
43
- tests = [
37
+ tests: [
44
38
  {
45
39
  name: 'example_test',
46
40
  fn: async (runtime) => {
@@ -97,7 +91,7 @@ export class StarterPluginTestSuite implements TestSuite {
97
91
  }
98
92
 
99
93
  // Create a callback that meets the HandlerCallback interface
100
- const callback: HandlerCallback = async (response: CoreContent) => {
94
+ const callback: HandlerCallback = async (response: Content) => {
101
95
  if (response.text && response.actions?.includes('HELLO_WORLD')) {
102
96
  responseReceived = true;
103
97
  }
@@ -170,8 +164,8 @@ export class StarterPluginTestSuite implements TestSuite {
170
164
  await service.stop();
171
165
  },
172
166
  },
173
- ];
174
- }
167
+ ],
168
+ };
175
169
 
176
170
  // Export a default instance of the test suite for the E2E test runner
177
- export default new StarterPluginTestSuite();
171
+ export default StarterPluginTestSuite;
@@ -36,13 +36,12 @@
36
36
  "dist"
37
37
  ],
38
38
  "dependencies": {
39
+ "@elizaos/core": "^1.0.0",
39
40
  "zod": "3.24.2"
40
41
  },
41
- "peerDependencies": {
42
- "@elizaos/core": "beta"
43
- },
42
+ "peerDependencies": {},
44
43
  "devDependencies": {
45
- "@elizaos/cli": "beta",
44
+ "@elizaos/cli": "^1.0.0",
46
45
  "dotenv": "16.4.5",
47
46
  "prettier": "3.5.3",
48
47
  "tsup": "8.4.0",
@@ -77,4 +76,4 @@
77
76
  }
78
77
  },
79
78
  "gitHead": "d5bd5c43bfebeb7ac02f9e029f924cb6cd5c2ec7"
80
- }
79
+ }
@@ -245,6 +245,7 @@ export const starterPlugin: Plugin = {
245
245
  services: [StarterService],
246
246
  actions: [helloWorldAction],
247
247
  providers: [helloWorldProvider],
248
+ dependencies: ['@elizaos/plugin-knowledge'],
248
249
  };
249
250
 
250
251
  export default starterPlugin;
@@ -1,46 +1,152 @@
1
- # OpenAI Configuration (required if using the Openai LLM Plugin)
1
+ ### elizaOS Environment Variables ###
2
+ # To get started, copy this file to .env, or make a .env and add the settings you'd like to override
3
+ # Please read the comments for each of the configurations
4
+
5
+ # The only thing you ABSOLUTELY NEED to get up and running is one of the model provider keys,
6
+ # i.e. OPENAI_API_KEY or ANTHROPIC_API_KEY, or setup the local-ai plugin
7
+ # Everything else is optional, and most settings and secrets can be configured in your agent or through the GUI
8
+ # For multi-agent, each agent will need keys for the various services it is connected to
9
+ # You can use the .env or environment variables generally for shared keys, such as to model providers,
10
+ # database, etc, with scoped keys for services such as Telegram, Discord, etc
11
+
12
+ ### MODEL PROVIDER KEYS ###
13
+ # Eliza is compatible with a wide array of model providers. Many have OpenAI compatible APIs,
14
+ # and you can use them by overriding the base URL
15
+
16
+ # NOTE: You will need a provider that provides embeddings. So even if you use Claude, you will
17
+ # need to get embeddings using another provider, for example openai or our local-ai plugin
18
+
19
+ # OpenAI Configuration
2
20
  OPENAI_API_KEY=
21
+ # Use this to override the openai endpoint, for example for using together.ai, fireworks or other providers
22
+ # OPENAI_BASE_URL=
3
23
 
4
- # Anthropic Configuration (required if using the Anthropic LLM Plugin)
24
+ # Anthropic Configuration
25
+ # By default in most of our starter kits, Anthropic will take precedence over OpenAI in handling requests
26
+ # Anthropic does not handle embeddings, so you may wish to use OpenAI for that, even while Claude is handling text generation
5
27
  ANTHROPIC_API_KEY=
6
28
 
7
- # Fill these out if you want to use Discord (required if using the Discord plugin)
8
- DISCORD_APPLICATION_ID=
9
- DISCORD_API_TOKEN=
29
+ # Cloudflare AI
30
+ CLOUDFLARE_GW_ENABLED=
31
+ CLOUDFLARE_AI_ACCOUNT_ID=
32
+ CLOUDFLARE_AI_GATEWAY_ID=
33
+
34
+ ### LOCAL AI CONFIGURATION ###
35
+ USE_LOCAL_AI=
36
+ USE_STUDIOLM_TEXT_MODELS=
37
+ USE_OLLAMA_TEXT_MODELS=
10
38
 
11
- # Fill these out if you want to use Postgres (required if using custom postgres url like neon db or railways)
39
+ # Ollama Configuration
40
+ OLLAMA_API_ENDPOINT=
41
+ OLLAMA_MODEL=
42
+ USE_OLLAMA_EMBEDDING=
43
+ OLLAMA_EMBEDDING_MODEL=
44
+ OLLAMA_SMALL_MODEL=
45
+ OLLAMA_MEDIUM_MODEL=
46
+ OLLAMA_LARGE_MODEL=
47
+
48
+ # StudioLM Configuration
49
+ STUDIOLM_SERVER_URL=
50
+ STUDIOLM_SMALL_MODEL=
51
+ STUDIOLM_MEDIUM_MODEL=
52
+ STUDIOLM_EMBEDDING_MODEL=
53
+
54
+ ### DATABASE ###
55
+ # By default, Eliza will use a local pglite instance
56
+ # If you fill out POSTGRES_URL, the agent will connect to your postgres instance instead of using the local path
57
+
58
+ # You can override the pglite data directory
59
+ # PGLITE_DATA_DIR=/Users/UserName/eliza/packages/.pglite/
60
+
61
+ # Fill this out if you want to use Postgres
12
62
  POSTGRES_URL=
13
63
 
14
- # Fill these out if you want to use Telegram (required if using the Telegram plugin)
64
+ ### LOGGING CONFIGURATION ###
65
+ # Logging Configuration (supported: fatal, error, warn, info, debug, trace | default: info)
66
+ LOG_LEVEL=
67
+
68
+ # Sentry Configuration
69
+ SENTRY_LOGGING=true
70
+ SENTRY_DSN=
71
+ SENTRY_ENVIRONMENT=
72
+ SENTRY_TRACES_SAMPLE_RATE=
73
+ SENTRY_SEND_DEFAULT_PII=
74
+
75
+ ### API KEYS ###
76
+ # Many services require API keys to function
77
+ # Most plugins will indicate what is needed in their README.md and throw helpful errors if they are missing
78
+ BIRDEYE_API_KEY=
79
+ JUPITER_API_KEY=
80
+ HELIUS_API_KEY=
81
+ COINMARKETCAP_API_KEY=
82
+ ZEROEX_API_KEY=
83
+ COINGECKO_API_KEY=
84
+
85
+ ### SINGLE AGENT VARIABLES ###
86
+ # If you are running multiple agents, you will need to configure these variables in the agent secrets
87
+ # (available in the GUI) OR you can namespace the secrets and connect them up in your character definition
88
+
89
+ # Example:
90
+ # settings: {
91
+ # process.env.COMMUNITY_MANAGER_DISCORD_API_TOKEN
92
+ # }
93
+
94
+ # Note: See below for multi-agent examples
95
+
96
+ # Discord Configuration
97
+ DISCORD_APPLICATION_ID=
98
+ DISCORD_API_TOKEN=
99
+
100
+ # Telegram Configuration
15
101
  TELEGRAM_BOT_TOKEN=
16
102
 
17
- # Fill these out if you want to use Twitter (required if using the Twitter plugin)
103
+ # Twitter Configuration
18
104
  TWITTER_USERNAME=
19
105
  TWITTER_PASSWORD=
20
106
  TWITTER_EMAIL=
21
107
  TWITTER_ENABLE_POST_GENERATION=
108
+ TWITTER_INTERACTION_ENABLE=
109
+ TWITTER_TIMELINE_ENABLE=
110
+ TWITTER_SPACES_ENABLE=
111
+ TWITTER_TIMELINE_MODE=
112
+ TWITTER_TIMELINE_POLL_INTERVAL=
22
113
 
23
- # Fill these out if you want to use EVM (required if using any wallet plugin)
114
+ # EVM Configuration
24
115
  EVM_PRIVATE_KEY=
25
116
  EVM_CHAINS=mainnet,sepolia,base,arbitrum,polygon
26
117
  EVM_PROVIDER_URL=
27
118
 
28
- # Fill these out if you want to use Solana
119
+ # Solana Configuration
29
120
  SOLANA_PUBLIC_KEY=
30
121
  SOLANA_PRIVATE_KEY=
31
- BIRDEYE_API_KEY=
32
122
 
33
- # Ollama Configuration (required if using the OLLAMA plugin)
34
- OLLAMA_API_ENDPOINT=
35
- OLLAMA_MODEL=
36
- USE_OLLAMA_EMBEDDING=
37
- OLLAMA_EMBEDDING_MODEL=
38
- OLLAMA_SMALL_MODEL=
39
- OLLAMA_MEDIUM_MODEL=
40
- OLLAMA_LARGE_MODEL=
123
+ ### MULTI-AGENT CONFIGURATION ###
124
+ # Settings for The Org
125
+ # The Org is an example of a multi-agent swarm
126
+ # Available here: https://github.com/elizaOS/the-org
127
+ # This is an example of how environment variables can be scoped per-project
41
128
 
42
- # StudioLM Configuration (required if using the StudioLM plugin)
43
- STUDIOLM_SERVER_URL=
44
- STUDIOLM_SMALL_MODEL=
45
- STUDIOLM_MEDIUM_MODEL=
46
- STUDIOLM_EMBEDDING_MODEL=
129
+ # Community Manager
130
+ COMMUNITY_MANAGER_DISCORD_APPLICATION_ID=
131
+ COMMUNITY_MANAGER_DISCORD_API_TOKEN=
132
+
133
+ # Social Media Manager
134
+ SOCIAL_MEDIA_MANAGER_DISCORD_APPLICATION_ID=
135
+ SOCIAL_MEDIA_MANAGER_DISCORD_API_TOKEN=
136
+
137
+ # Liaison
138
+ LIAISON_DISCORD_APPLICATION_ID=
139
+ LIAISON_DISCORD_API_TOKEN=
140
+
141
+ # Project Manager
142
+ PROJECT_MANAGER_DISCORD_APPLICATION_ID=
143
+ PROJECT_MANAGER_DISCORD_API_TOKEN=
144
+
145
+ # Developer Relations
146
+ DEV_REL_DISCORD_APPLICATION_ID=
147
+ DEV_REL_DISCORD_API_TOKEN=
148
+ DEVREL_IMPORT_KNOWLEDGE=true
149
+
150
+ # Investment Manager
151
+ INVESTMENT_MANAGER_DISCORD_APPLICATION_ID=
152
+ INVESTMENT_MANAGER_DISCORD_API_TOKEN=
@@ -1,6 +1,7 @@
1
1
  import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
2
2
  import plugin from '../src/plugin';
3
3
  import { z } from 'zod';
4
+ import { createMockRuntime } from './utils/core-test-utils';
4
5
 
5
6
  // Mock logger
6
7
  vi.mock('@elizaos/core', async () => {
@@ -41,7 +42,7 @@ describe('Plugin Configuration Schema', () => {
41
42
  if (initPlugin) {
42
43
  let error = null;
43
44
  try {
44
- await initPlugin(validConfig);
45
+ await initPlugin(validConfig, createMockRuntime());
45
46
  } catch (e) {
46
47
  error = e;
47
48
  }
@@ -55,7 +56,7 @@ describe('Plugin Configuration Schema', () => {
55
56
  if (initPlugin) {
56
57
  let error = null;
57
58
  try {
58
- await initPlugin(emptyConfig);
59
+ await initPlugin(emptyConfig, createMockRuntime());
59
60
  } catch (e) {
60
61
  error = e;
61
62
  }
@@ -72,7 +73,7 @@ describe('Plugin Configuration Schema', () => {
72
73
  if (initPlugin) {
73
74
  let error = null;
74
75
  try {
75
- await initPlugin(configWithExtra);
76
+ await initPlugin(configWithExtra, createMockRuntime());
76
77
  } catch (e) {
77
78
  error = e;
78
79
  }
@@ -88,7 +89,7 @@ describe('Plugin Configuration Schema', () => {
88
89
  if (initPlugin) {
89
90
  let error = null;
90
91
  try {
91
- await initPlugin(invalidConfig);
92
+ await initPlugin(invalidConfig, createMockRuntime());
92
93
  } catch (e) {
93
94
  error = e;
94
95
  }
@@ -106,7 +107,7 @@ describe('Plugin Configuration Schema', () => {
106
107
  delete process.env.EXAMPLE_PLUGIN_VARIABLE;
107
108
 
108
109
  // Initialize with config
109
- await initPlugin(testConfig);
110
+ await initPlugin(testConfig, createMockRuntime());
110
111
 
111
112
  // Verify environment variable was set
112
113
  expect(process.env.EXAMPLE_PLUGIN_VARIABLE).toBe('test-value');
@@ -118,11 +119,11 @@ describe('Plugin Configuration Schema', () => {
118
119
  process.env.EXAMPLE_PLUGIN_VARIABLE = 'pre-existing-value';
119
120
 
120
121
  const testConfig = {
121
- EXAMPLE_PLUGIN_VARIABLE: undefined,
122
+ // Omit the variable to test that existing env vars aren't overridden
122
123
  };
123
124
 
124
125
  if (initPlugin) {
125
- await initPlugin(testConfig);
126
+ await initPlugin(testConfig, createMockRuntime());
126
127
 
127
128
  // Verify environment variable was not changed
128
129
  expect(process.env.EXAMPLE_PLUGIN_VARIABLE).toBe('pre-existing-value');
@@ -21,24 +21,37 @@ afterAll(() => {
21
21
 
22
22
  // Helper function to document test results
23
23
  function documentTestResult(testName: string, result: any, error: Error | null = null) {
24
- logger.info(`TEST: ${testName}`);
24
+ // Clean, useful test documentation for developers
25
+ logger.info(`✓ Testing: ${testName}`);
26
+
27
+ if (error) {
28
+ logger.error(`✗ Error: ${error.message}`);
29
+ if (error.stack) {
30
+ logger.error(`Stack: ${error.stack}`);
31
+ }
32
+ return;
33
+ }
34
+
25
35
  if (result) {
26
36
  if (typeof result === 'string') {
27
- logger.info(`RESULT: ${result.substring(0, 100)}${result.length > 100 ? '...' : ''}`);
28
- } else {
37
+ if (result.trim() && result.length > 0) {
38
+ const preview = result.length > 60 ? `${result.substring(0, 60)}...` : result;
39
+ logger.info(` → ${preview}`);
40
+ }
41
+ } else if (typeof result === 'object') {
29
42
  try {
30
- logger.info(`RESULT: ${JSON.stringify(result, null, 2).substring(0, 200)}...`);
43
+ // Show key information in a clean format
44
+ const keys = Object.keys(result);
45
+ if (keys.length > 0) {
46
+ const preview = keys.slice(0, 3).join(', ');
47
+ const more = keys.length > 3 ? ` +${keys.length - 3} more` : '';
48
+ logger.info(` → {${preview}${more}}`);
49
+ }
31
50
  } catch (e) {
32
- logger.info(`RESULT: [Complex object that couldn't be stringified]`);
51
+ logger.info(` [Complex object]`);
33
52
  }
34
53
  }
35
54
  }
36
- if (error) {
37
- logger.error(`ERROR: ${error.message}`);
38
- if (error.stack) {
39
- logger.error(`STACK: ${error.stack}`);
40
- }
41
- }
42
55
  }
43
56
 
44
57
  // Create a real runtime for testing
@@ -74,19 +87,14 @@ function createRealRuntime() {
74
87
  getKeys: async (pattern: string) => [],
75
88
  },
76
89
  getService: (serviceType: string) => {
77
- // Log the service request for debugging
78
- logger.debug(`Requesting service: ${serviceType}`);
79
-
80
90
  // Get from cache or create new
81
91
  if (!services.has(serviceType)) {
82
- logger.debug(`Creating new service: ${serviceType}`);
83
92
  services.set(serviceType, createService(serviceType));
84
93
  }
85
94
 
86
95
  return services.get(serviceType);
87
96
  },
88
97
  registerService: (serviceType: string, service: any) => {
89
- logger.debug(`Registering service: ${serviceType}`);
90
98
  services.set(serviceType, service);
91
99
  },
92
100
  };
@@ -109,7 +117,7 @@ describe('Plugin Configuration', () => {
109
117
  expect(plugin.config).toHaveProperty('EXAMPLE_PLUGIN_VARIABLE');
110
118
 
111
119
  documentTestResult('Plugin config check', {
112
- hasExampleVariable: 'EXAMPLE_PLUGIN_VARIABLE' in plugin.config,
120
+ hasExampleVariable: plugin.config ? 'EXAMPLE_PLUGIN_VARIABLE' in plugin.config : false,
113
121
  configKeys: Object.keys(plugin.config || {}),
114
122
  });
115
123
  });
@@ -123,7 +131,7 @@ describe('Plugin Configuration', () => {
123
131
  // Initialize with config - using real runtime
124
132
  const runtime = createRealRuntime();
125
133
 
126
- let error = null;
134
+ let error: Error | null = null;
127
135
  try {
128
136
  await plugin.init?.({ EXAMPLE_PLUGIN_VARIABLE: 'test-value' }, runtime as any);
129
137
  expect(true).toBe(true); // If we got here, init succeeded
@@ -149,7 +157,7 @@ describe('Plugin Configuration', () => {
149
157
  // Test with empty string (less than min length 1)
150
158
  if (plugin.init) {
151
159
  const runtime = createRealRuntime();
152
- let error = null;
160
+ let error: Error | null = null;
153
161
 
154
162
  try {
155
163
  await plugin.init({ EXAMPLE_PLUGIN_VARIABLE: '' }, runtime as any);
@@ -165,7 +173,7 @@ describe('Plugin Configuration', () => {
165
173
  'Plugin invalid config',
166
174
  {
167
175
  errorThrown: !!error,
168
- errorMessage: error?.message,
176
+ errorMessage: error?.message || 'No error message',
169
177
  },
170
178
  error
171
179
  );
@@ -235,10 +243,10 @@ describe('StarterService', () => {
235
243
  it('should start the service', async () => {
236
244
  const runtime = createRealRuntime();
237
245
  let startResult;
238
- let error = null;
246
+ let error: Error | null = null;
239
247
 
240
248
  try {
241
- logger.info('Starting StarterService');
249
+ logger.info('Using OpenAI for TEXT_SMALL model');
242
250
  startResult = await StarterService.start(runtime as any);
243
251
 
244
252
  expect(startResult).toBeDefined();
@@ -268,14 +276,14 @@ describe('StarterService', () => {
268
276
  const result1 = await StarterService.start(runtime as any);
269
277
  expect(result1).toBeTruthy();
270
278
 
271
- let startupError: Error | unknown = null;
279
+ let startupError: Error | null = null;
272
280
 
273
281
  try {
274
282
  // Second registration should fail
275
283
  await StarterService.start(runtime as any);
276
284
  expect(true).toBe(false); // Should not reach here
277
285
  } catch (e) {
278
- startupError = e;
286
+ startupError = e as Error;
279
287
  expect(e).toBeTruthy();
280
288
  }
281
289
 
@@ -283,15 +291,15 @@ describe('StarterService', () => {
283
291
  'StarterService double start',
284
292
  {
285
293
  errorThrown: !!startupError,
286
- errorMessage: startupError instanceof Error ? startupError.message : String(startupError),
294
+ errorMessage: startupError?.message || 'No error message',
287
295
  },
288
- startupError instanceof Error ? startupError : null
296
+ startupError
289
297
  );
290
298
  });
291
299
 
292
300
  it('should stop the service', async () => {
293
301
  const runtime = createRealRuntime();
294
- let error = null;
302
+ let error: Error | null = null;
295
303
 
296
304
  try {
297
305
  // Register a real service first
@@ -324,7 +332,7 @@ describe('StarterService', () => {
324
332
  const runtime = createRealRuntime();
325
333
  // Don't register a service, so getService will return null
326
334
 
327
- let error: Error | unknown = null;
335
+ let error: Error | null = null;
328
336
 
329
337
  try {
330
338
  // We'll patch the getService function to ensure it returns null
@@ -335,26 +343,21 @@ describe('StarterService', () => {
335
343
  // Should not reach here
336
344
  expect(true).toBe(false);
337
345
  } catch (e) {
338
- error = e;
346
+ error = e as Error;
339
347
  // This is expected - verify it's the right error
340
348
  expect(error).toBeTruthy();
341
349
  if (error instanceof Error) {
342
350
  expect(error.message).toContain('Starter service not found');
343
351
  }
344
- } finally {
345
- // Restore original getService function if needed
346
- if ('getService' in runtime && typeof runtime.getService !== 'function') {
347
- delete runtime.getService;
348
- }
349
352
  }
350
353
 
351
354
  documentTestResult(
352
355
  'StarterService non-existent stop',
353
356
  {
354
357
  errorThrown: !!error,
355
- errorMessage: error instanceof Error ? error.message : String(error),
358
+ errorMessage: error?.message || 'No error message',
356
359
  },
357
- error instanceof Error ? error : null
360
+ error
358
361
  );
359
362
  });
360
363