@elizaos/cli 1.4.2 → 1.4.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 (29) hide show
  1. package/dist/{chunk-SMZBJQJR.js → chunk-HOC6B3QV.js} +1 -1
  2. package/dist/{chunk-D3QSET5H.js → chunk-N5G5XSGP.js} +29 -5
  3. package/dist/{chunk-FSSUAWXQ.js → chunk-NSNXXD3I.js} +2 -2
  4. package/dist/commands/agent/actions/index.js +1 -1
  5. package/dist/commands/agent/index.js +1 -1
  6. package/dist/commands/create/actions/index.js +2 -2
  7. package/dist/commands/create/index.js +3 -3
  8. package/dist/index.js +16 -7
  9. package/dist/{registry-RF6PW3EN.js → registry-ELONUC44.js} +1 -1
  10. package/dist/templates/plugin-quick-starter/package.json +2 -2
  11. package/dist/templates/plugin-starter/package.json +2 -2
  12. package/dist/templates/project-starter/package.json +4 -4
  13. package/dist/templates/project-starter/src/__tests__/config.test.ts +6 -15
  14. package/dist/templates/project-starter/src/__tests__/error-handling.test.ts +4 -18
  15. package/dist/templates/project-starter/src/__tests__/events.test.ts +27 -23
  16. package/dist/templates/project-tee-starter/package.json +4 -4
  17. package/dist/templates/project-tee-starter/src/__tests__/config.test.ts +40 -0
  18. package/dist/templates/project-tee-starter/src/plugin.ts +21 -19
  19. package/dist/{utils-5HPZSIF6.js → utils-X6UXPLKD.js} +1 -1
  20. package/package.json +6 -7
  21. package/templates/plugin-quick-starter/package.json +2 -2
  22. package/templates/plugin-starter/package.json +2 -2
  23. package/templates/project-starter/package.json +4 -4
  24. package/templates/project-starter/src/__tests__/config.test.ts +6 -15
  25. package/templates/project-starter/src/__tests__/error-handling.test.ts +4 -18
  26. package/templates/project-starter/src/__tests__/events.test.ts +27 -23
  27. package/templates/project-tee-starter/package.json +4 -4
  28. package/templates/project-tee-starter/src/__tests__/config.test.ts +40 -0
  29. package/templates/project-tee-starter/src/plugin.ts +21 -19
@@ -15,7 +15,7 @@ import {
15
15
  promptAndStorePostgresUrl,
16
16
  runTasks,
17
17
  setupPgLite
18
- } from "./chunk-D3QSET5H.js";
18
+ } from "./chunk-N5G5XSGP.js";
19
19
 
20
20
  // src/characters/eliza.ts
21
21
  var baseCharacter = {
@@ -2757,7 +2757,7 @@ async function getGitHubCredentials() {
2757
2757
  }
2758
2758
  logger10.warn("Invalid GitHub token found in environment variables");
2759
2759
  }
2760
- const { getGitHubToken: getGitHubToken2 } = await import("./registry-RF6PW3EN.js");
2760
+ const { getGitHubToken: getGitHubToken2 } = await import("./registry-ELONUC44.js");
2761
2761
  const token = await getGitHubToken2() || void 0;
2762
2762
  if (token) {
2763
2763
  const isValid2 = await validateGitHubToken(token);
@@ -2863,10 +2863,16 @@ async function ensureDirectory(token, repo, path22, branch) {
2863
2863
  } catch (error) {
2864
2864
  logger10.info(`Directory ${path22} doesn't exist, creating it`);
2865
2865
  }
2866
+ const [owner, repoName] = repo.split("/");
2867
+ if (!owner || !repoName) {
2868
+ logger10.error(`Invalid repository format: ${repo}. Expected format: owner/repo`);
2869
+ return false;
2870
+ }
2866
2871
  const placeholderPath = `${path22}/.gitkeep`;
2867
2872
  const result = await updateFile(
2868
2873
  token,
2869
- repo,
2874
+ owner,
2875
+ repoName,
2870
2876
  placeholderPath,
2871
2877
  "",
2872
2878
  // Empty content for placeholder
@@ -4615,7 +4621,7 @@ async function testPublishToGitHub(packageJson, username) {
4615
4621
  logger20.info("[\u2713] Can create and update files");
4616
4622
  return true;
4617
4623
  } catch (error) {
4618
- logger20.error("Test failed:", error);
4624
+ logger20.error({ error }, "Test failed:");
4619
4625
  return false;
4620
4626
  }
4621
4627
  }
@@ -4756,7 +4762,7 @@ async function publishToGitHub(cwd, packageJson, username, skipRegistry = false,
4756
4762
  insertIndex = i;
4757
4763
  break;
4758
4764
  }
4759
- const match = line.match(/^\s*"(@[^"]+)"/);
4765
+ const match = line.match(/^\s*"([^"]+)"/);
4760
4766
  if (match) {
4761
4767
  const existingPackage = match[1];
4762
4768
  if (registryPackageName < existingPackage) {
@@ -4777,7 +4783,25 @@ async function publishToGitHub(cwd, packageJson, username, skipRegistry = false,
4777
4783
  logger20.error("Could not find insertion point in index.json");
4778
4784
  return false;
4779
4785
  }
4780
- lines.splice(insertIndex, 0, newEntry);
4786
+ const isLastEntry = lines[insertIndex].trim() === "}";
4787
+ if (isLastEntry) {
4788
+ let prevLineIndex = insertIndex - 1;
4789
+ while (prevLineIndex >= 0 && lines[prevLineIndex].trim() === "") {
4790
+ prevLineIndex--;
4791
+ }
4792
+ if (prevLineIndex >= 0) {
4793
+ const prevLine = lines[prevLineIndex];
4794
+ const prevTrim = prevLine.trim();
4795
+ const isEntryLine = /^"[^"]+"\s*:/.test(prevTrim);
4796
+ if (isEntryLine && !prevTrim.endsWith(",")) {
4797
+ lines[prevLineIndex] = prevLine.trimEnd() + ",";
4798
+ }
4799
+ }
4800
+ const newEntryWithoutComma = newEntry.replace(/,\s*$/, "");
4801
+ lines.splice(insertIndex, 0, newEntryWithoutComma);
4802
+ } else {
4803
+ lines.splice(insertIndex, 0, newEntry);
4804
+ }
4781
4805
  const updatedContent = lines.join("\n");
4782
4806
  const indexUpdated = await updateFile(
4783
4807
  token,
@@ -9,11 +9,11 @@ import {
9
9
  selectEmbeddingModel,
10
10
  validateCreateOptions,
11
11
  validateProjectName
12
- } from "./chunk-SMZBJQJR.js";
12
+ } from "./chunk-HOC6B3QV.js";
13
13
  import {
14
14
  displayBanner,
15
15
  handleError
16
- } from "./chunk-D3QSET5H.js";
16
+ } from "./chunk-N5G5XSGP.js";
17
17
 
18
18
  // src/commands/create/index.ts
19
19
  import { Command } from "commander";
@@ -5,7 +5,7 @@ import {
5
5
  setAgentConfig,
6
6
  startAgent,
7
7
  stopAgent
8
- } from "../../../chunk-D3QSET5H.js";
8
+ } from "../../../chunk-N5G5XSGP.js";
9
9
  import "../../../chunk-FQYWRHLX.js";
10
10
  import "../../../chunk-GXWWPFBO.js";
11
11
  import "../../../chunk-I4L4T7QX.js";
@@ -2,7 +2,7 @@ import {
2
2
  agent,
3
3
  getAgents,
4
4
  resolveAgentId
5
- } from "../../chunk-D3QSET5H.js";
5
+ } from "../../chunk-N5G5XSGP.js";
6
6
  import "../../chunk-FQYWRHLX.js";
7
7
  import {
8
8
  getAgentRuntimeUrl,
@@ -8,8 +8,8 @@ import {
8
8
  setupAIModelConfig,
9
9
  setupEmbeddingModelConfig,
10
10
  setupProjectEnvironment
11
- } from "../../../chunk-SMZBJQJR.js";
12
- import "../../../chunk-D3QSET5H.js";
11
+ } from "../../../chunk-HOC6B3QV.js";
12
+ import "../../../chunk-N5G5XSGP.js";
13
13
  import "../../../chunk-FQYWRHLX.js";
14
14
  import "../../../chunk-GXWWPFBO.js";
15
15
  import "../../../chunk-I4L4T7QX.js";
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  create
3
- } from "../../chunk-FSSUAWXQ.js";
4
- import "../../chunk-SMZBJQJR.js";
5
- import "../../chunk-D3QSET5H.js";
3
+ } from "../../chunk-NSNXXD3I.js";
4
+ import "../../chunk-HOC6B3QV.js";
5
+ import "../../chunk-N5G5XSGP.js";
6
6
  import "../../chunk-FQYWRHLX.js";
7
7
  import "../../chunk-GXWWPFBO.js";
8
8
  import "../../chunk-I4L4T7QX.js";
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env bun
2
2
  import {
3
3
  create
4
- } from "./chunk-FSSUAWXQ.js";
4
+ } from "./chunk-NSNXXD3I.js";
5
5
  import {
6
6
  getElizaCharacter
7
- } from "./chunk-SMZBJQJR.js";
7
+ } from "./chunk-HOC6B3QV.js";
8
8
  import {
9
9
  TestRunner,
10
10
  UserEnvironment,
@@ -44,7 +44,7 @@ import {
44
44
  testPublishToNpm,
45
45
  tryDelegateToLocalCli,
46
46
  validateDataDir
47
- } from "./chunk-D3QSET5H.js";
47
+ } from "./chunk-N5G5XSGP.js";
48
48
  import {
49
49
  configureEmojis,
50
50
  emoji,
@@ -2422,13 +2422,13 @@ var SimpleMigrationAgent = class extends EventTarget {
2422
2422
  if (eventHandlers.has(handler)) {
2423
2423
  return this;
2424
2424
  }
2425
- const wrappedHandler = (e) => {
2425
+ const wrappedHandler = ((e) => {
2426
2426
  if (e instanceof CustomEvent) {
2427
2427
  handler(e.detail);
2428
2428
  } else {
2429
2429
  handler(void 0);
2430
2430
  }
2431
- };
2431
+ });
2432
2432
  eventHandlers.set(handler, wrappedHandler);
2433
2433
  this.addEventListener(event, wrappedHandler);
2434
2434
  return this;
@@ -3535,7 +3535,8 @@ async function generatePackageMetadata(packageJson, cliVersion, username) {
3535
3535
  // node, browser, or universal
3536
3536
  runtimeVersion: cliVersion,
3537
3537
  // Compatible CLI/runtime version
3538
- repository: packageJson.repository?.url || "",
3538
+ ...packageJson.repository?.url && { repository: packageJson.repository.url },
3539
+ // Only include if present
3539
3540
  maintainers: packageJson.maintainers || [username],
3540
3541
  publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
3541
3542
  publishedBy: username,
@@ -4186,6 +4187,14 @@ var publish = new Command5().name("publish").description("Publish a plugin to np
4186
4187
  replacement.replace();
4187
4188
  }
4188
4189
  });
4190
+ if (opts.npm && packageJson.repository) {
4191
+ delete packageJson.repository;
4192
+ console.info("Removed repository field for npm-only publishing");
4193
+ }
4194
+ if (opts.npm && packageJson.bugs) {
4195
+ delete packageJson.bugs;
4196
+ console.info("Removed bugs field for npm-only publishing");
4197
+ }
4189
4198
  const finalPluginName = packageJson.name.startsWith("@") ? packageJson.name.split("/")[1] : packageJson.name;
4190
4199
  await fs9.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf-8");
4191
4200
  await validatePluginRequirements(cwd, packageJson);
@@ -5124,7 +5133,7 @@ async function installPluginDependencies(projectInfo) {
5124
5133
  };
5125
5134
  await fs12.promises.writeFile(packageJsonPath, JSON.stringify(packageJsonContent, null, 2));
5126
5135
  }
5127
- const { installPlugin: installPlugin2 } = await import("./utils-5HPZSIF6.js");
5136
+ const { installPlugin: installPlugin2 } = await import("./utils-X6UXPLKD.js");
5128
5137
  for (const dependency of project.pluginModule.dependencies) {
5129
5138
  await installPlugin2(dependency, pluginsDir);
5130
5139
  const dependencyPath = path26.join(pluginsDir, "node_modules", dependency);
@@ -24,7 +24,7 @@ import {
24
24
  setEnvVar,
25
25
  setGitHubToken,
26
26
  validateDataDir
27
- } from "./chunk-D3QSET5H.js";
27
+ } from "./chunk-N5G5XSGP.js";
28
28
  import "./chunk-FQYWRHLX.js";
29
29
  import "./chunk-GXWWPFBO.js";
30
30
  import "./chunk-I4L4T7QX.js";
@@ -41,11 +41,11 @@
41
41
  "tsup.config.ts"
42
42
  ],
43
43
  "dependencies": {
44
- "@elizaos/core": "1.4.2",
44
+ "@elizaos/core": "1.4.3",
45
45
  "zod": "^3.24.4"
46
46
  },
47
47
  "devDependencies": {
48
- "@elizaos/cli": "1.4.2",
48
+ "@elizaos/cli": "1.4.3",
49
49
  "dotenv": "16.4.5",
50
50
  "prettier": "3.5.3",
51
51
  "tsup": "8.5.0",
@@ -41,7 +41,7 @@
41
41
  "tsup.config.ts"
42
42
  ],
43
43
  "dependencies": {
44
- "@elizaos/core": "1.4.2",
44
+ "@elizaos/core": "1.4.3",
45
45
  "@tanstack/react-query": "^5.80.7",
46
46
  "clsx": "^2.1.1",
47
47
  "tailwind-merge": "^3.3.1",
@@ -50,7 +50,7 @@
50
50
  "zod": "3.24.2"
51
51
  },
52
52
  "devDependencies": {
53
- "@elizaos/cli": "1.4.2",
53
+ "@elizaos/cli": "1.4.3",
54
54
  "@tailwindcss/vite": "^4.1.10",
55
55
  "@vitejs/plugin-react-swc": "^3.10.2",
56
56
  "dotenv": "16.4.5",
@@ -28,10 +28,10 @@
28
28
  "dist"
29
29
  ],
30
30
  "dependencies": {
31
- "@elizaos/cli": "1.4.2",
32
- "@elizaos/core": "1.4.2",
33
- "@elizaos/plugin-bootstrap": "1.4.2",
34
- "@elizaos/plugin-sql": "1.4.2",
31
+ "@elizaos/cli": "1.4.3",
32
+ "@elizaos/core": "1.4.3",
33
+ "@elizaos/plugin-bootstrap": "1.4.3",
34
+ "@elizaos/plugin-sql": "1.4.3",
35
35
  "@tanstack/react-query": "^5.29.0",
36
36
  "clsx": "^2.1.1",
37
37
  "react": "^18.3.1",
@@ -1,20 +1,8 @@
1
- import { describe, expect, it, beforeEach, afterEach, mock } from 'bun:test';
1
+ import { describe, expect, it, beforeEach, afterEach, mock, spyOn } from 'bun:test';
2
2
  import plugin from '../plugin';
3
3
  import { z } from 'zod';
4
4
  import { createMockRuntime } from './utils/core-test-utils';
5
-
6
- // Mock logger
7
- mock.module('@elizaos/core', () => {
8
- const actual = require('@elizaos/core');
9
- return {
10
- ...actual,
11
- logger: {
12
- info: mock(),
13
- error: mock(),
14
- warn: mock(),
15
- },
16
- };
17
- });
5
+ import { logger } from '@elizaos/core';
18
6
 
19
7
  // Access the plugin's init function
20
8
  const initPlugin = plugin.init;
@@ -24,7 +12,10 @@ describe('Plugin Configuration Schema', () => {
24
12
  const originalEnv = { ...process.env };
25
13
 
26
14
  beforeEach(() => {
27
- mock.restore();
15
+ // Use spyOn for logger methods
16
+ spyOn(logger, 'info');
17
+ spyOn(logger, 'error');
18
+ spyOn(logger, 'warn');
28
19
  // Reset environment variables before each test
29
20
  process.env = { ...originalEnv };
30
21
  });
@@ -5,26 +5,12 @@ import { logger } from '@elizaos/core';
5
5
  import type { IAgentRuntime, Memory, State } from '@elizaos/core';
6
6
  import { v4 as uuidv4 } from 'uuid';
7
7
 
8
- // Mock logger
9
- mock.module('@elizaos/core', () => {
10
- const actual = require('@elizaos/core');
11
- return {
12
- ...actual,
13
- logger: {
14
- info: mock(),
15
- error: mock(),
16
- warn: mock(),
17
- },
18
- };
19
- });
20
-
21
8
  describe('Error Handling', () => {
22
9
  beforeEach(() => {
23
- mock.restore();
24
- });
25
-
26
- afterEach(() => {
27
- // No global restore needed in bun:test;
10
+ // Use spyOn for logger methods
11
+ spyOn(logger, 'info');
12
+ spyOn(logger, 'error');
13
+ spyOn(logger, 'warn');
28
14
  });
29
15
 
30
16
  describe('HELLO_WORLD Action Error Handling', () => {
@@ -1,22 +1,14 @@
1
- import { describe, expect, it, beforeEach, mock } from 'bun:test';
1
+ import { describe, expect, it, beforeAll, afterAll, spyOn } from 'bun:test';
2
2
  import plugin from '../plugin';
3
3
  import { logger } from '@elizaos/core';
4
4
 
5
- // Mock logger
6
- mock.module('@elizaos/core', () => {
7
- const actual = require('@elizaos/core');
8
- return {
9
- ...actual,
10
- logger: {
11
- info: mock(),
12
- error: mock(),
13
- },
14
- };
15
- });
16
-
17
5
  describe('Plugin Events', () => {
18
- beforeEach(() => {
19
- mock.restore();
6
+ // Use spyOn like all other tests in the codebase
7
+ beforeAll(() => {
8
+ spyOn(logger, 'info');
9
+ spyOn(logger, 'error');
10
+ spyOn(logger, 'warn');
11
+ spyOn(logger, 'debug');
20
12
  });
21
13
 
22
14
  it('should have events defined', () => {
@@ -47,9 +39,12 @@ describe('Plugin Events', () => {
47
39
  // Call the event handler
48
40
  await messageHandler(mockParams);
49
41
 
50
- // Verify log was called
42
+ // Verify logger was called with correct Pino-style structured logging
51
43
  expect(logger.info).toHaveBeenCalledWith('MESSAGE_RECEIVED event received');
52
- expect(logger.info).toHaveBeenCalledWith(expect.any(Array));
44
+ expect(logger.info).toHaveBeenCalledWith(
45
+ { keys: expect.any(Array) },
46
+ 'MESSAGE_RECEIVED param keys'
47
+ );
53
48
  }
54
49
  });
55
50
 
@@ -74,9 +69,12 @@ describe('Plugin Events', () => {
74
69
  // Call the event handler
75
70
  await voiceHandler(mockParams);
76
71
 
77
- // Verify log was called
72
+ // Verify logger was called with correct Pino-style structured logging
78
73
  expect(logger.info).toHaveBeenCalledWith('VOICE_MESSAGE_RECEIVED event received');
79
- expect(logger.info).toHaveBeenCalledWith(expect.any(Array));
74
+ expect(logger.info).toHaveBeenCalledWith(
75
+ { keys: expect.any(Array) },
76
+ 'VOICE_MESSAGE_RECEIVED param keys'
77
+ );
80
78
  }
81
79
  });
82
80
 
@@ -103,9 +101,12 @@ describe('Plugin Events', () => {
103
101
  // Call the event handler
104
102
  await connectedHandler(mockParams);
105
103
 
106
- // Verify log was called
104
+ // Verify logger was called with correct Pino-style structured logging
107
105
  expect(logger.info).toHaveBeenCalledWith('WORLD_CONNECTED event received');
108
- expect(logger.info).toHaveBeenCalledWith(expect.any(Array));
106
+ expect(logger.info).toHaveBeenCalledWith(
107
+ { keys: expect.any(Array) },
108
+ 'WORLD_CONNECTED param keys'
109
+ );
109
110
  }
110
111
  });
111
112
 
@@ -136,9 +137,12 @@ describe('Plugin Events', () => {
136
137
  // Call the event handler
137
138
  await joinedHandler(mockParams);
138
139
 
139
- // Verify log was called
140
+ // Verify logger was called with correct Pino-style structured logging
140
141
  expect(logger.info).toHaveBeenCalledWith('WORLD_JOINED event received');
141
- expect(logger.info).toHaveBeenCalledWith(expect.any(Array));
142
+ expect(logger.info).toHaveBeenCalledWith(
143
+ { keys: expect.any(Array) },
144
+ 'WORLD_JOINED param keys'
145
+ );
142
146
  }
143
147
  });
144
148
  });
@@ -33,11 +33,11 @@
33
33
  "GUIDE.md"
34
34
  ],
35
35
  "dependencies": {
36
- "@elizaos/cli": "1.4.2",
37
- "@elizaos/core": "1.4.2",
38
- "@elizaos/plugin-bootstrap": "1.4.2",
36
+ "@elizaos/cli": "1.4.3",
37
+ "@elizaos/core": "1.4.3",
38
+ "@elizaos/plugin-bootstrap": "1.4.3",
39
39
  "@elizaos/plugin-redpill": "1.2.1",
40
- "@elizaos/plugin-sql": "1.4.2",
40
+ "@elizaos/plugin-sql": "1.4.3",
41
41
  "@phala/dstack-sdk": "0.1.11",
42
42
  "@solana/web3.js": "1.98.2",
43
43
  "@tanstack/react-query": "^5.29.0",
@@ -18,6 +18,46 @@ describe('Plugin Configuration', () => {
18
18
  );
19
19
  });
20
20
 
21
+ it('should parse and validate config during initialization', async () => {
22
+ // Mock runtime for testing
23
+ const mockRuntime = {
24
+ logger: {
25
+ info: () => {},
26
+ warn: () => {},
27
+ debug: () => {},
28
+ error: () => {},
29
+ },
30
+ } as any;
31
+
32
+ // Test that config parsing happens during init, not at import time
33
+ const originalEnv = {
34
+ NODE_ENV: process.env.NODE_ENV,
35
+ TEE_MODE: process.env.TEE_MODE,
36
+ WALLET_SECRET_SALT: process.env.WALLET_SECRET_SALT,
37
+ };
38
+
39
+ try {
40
+ // Set test environment with valid defaults
41
+ process.env.NODE_ENV = 'test';
42
+ process.env.TEE_MODE = 'OFF';
43
+ process.env.WALLET_SECRET_SALT = 'test_salt_12345';
44
+
45
+ // Config should be parsed and validated during init without throwing
46
+ await expect(teeStarterPlugin.init({}, mockRuntime)).resolves.toBeUndefined();
47
+
48
+ // Test with invalid config should fail validation during init
49
+ const invalidConfig = { TEE_MODE: 'INVALID_MODE' };
50
+ await expect(teeStarterPlugin.init(invalidConfig, mockRuntime)).rejects.toThrow(
51
+ 'Invalid plugin configuration'
52
+ );
53
+ } finally {
54
+ // Restore original environment
55
+ process.env.NODE_ENV = originalEnv.NODE_ENV;
56
+ process.env.TEE_MODE = originalEnv.TEE_MODE;
57
+ process.env.WALLET_SECRET_SALT = originalEnv.WALLET_SECRET_SALT;
58
+ }
59
+ });
60
+
21
61
  it('should be a TEE-focused plugin with appropriate components', () => {
22
62
  // Verify plugin has TEE-specific components
23
63
  expect(teeStarterPlugin.actions).toEqual([]);
@@ -213,34 +213,36 @@ export class StarterService extends Service {
213
213
  const teeStarterPlugin: Plugin = {
214
214
  name: 'mr-tee-starter-plugin',
215
215
  description: "Mr. TEE's starter plugin - using plugin-tee for attestation",
216
- config: {
217
- TEE_MODE: process.env.TEE_MODE,
218
- TEE_VENDOR: process.env.TEE_VENDOR,
219
- WALLET_SECRET_SALT: process.env.WALLET_SECRET_SALT,
220
- },
216
+ // Use dynamic getters so tests/CI always see current env values
217
+ config: Object.defineProperties(
218
+ {},
219
+ {
220
+ TEE_MODE: {
221
+ get: () => process.env.TEE_MODE,
222
+ enumerable: true,
223
+ },
224
+ TEE_VENDOR: {
225
+ get: () => process.env.TEE_VENDOR,
226
+ enumerable: true,
227
+ },
228
+ WALLET_SECRET_SALT: {
229
+ get: () => process.env.WALLET_SECRET_SALT,
230
+ enumerable: true,
231
+ },
232
+ }
233
+ ) as Record<string, string>,
221
234
  async init(config: Record<string, string>, runtime: IAgentRuntime) {
222
235
  logger.info('*** Initializing Mr. TEE plugin ***');
223
236
  try {
224
237
  // Merge process.env values with config, config takes precedence
225
- const mergedConfig = {
238
+ const rawConfig = {
226
239
  TEE_MODE: config.TEE_MODE ?? process.env.TEE_MODE,
227
240
  TEE_VENDOR: config.TEE_VENDOR ?? process.env.TEE_VENDOR,
228
241
  WALLET_SECRET_SALT: config.WALLET_SECRET_SALT ?? process.env.WALLET_SECRET_SALT,
229
242
  };
230
243
 
231
- // Apply test defaults if in test environment
232
- const isTestEnvironment = process.env.NODE_ENV === 'test' || process.argv.includes('test');
233
-
234
- if (isTestEnvironment) {
235
- // Apply test-only defaults - NEVER use these in production
236
- mergedConfig.TEE_MODE = mergedConfig.TEE_MODE || 'OFF';
237
- mergedConfig.TEE_VENDOR = mergedConfig.TEE_VENDOR || 'phala';
238
- // Test salt - this is ONLY for test environments and should NEVER be used in production
239
- mergedConfig.WALLET_SECRET_SALT =
240
- mergedConfig.WALLET_SECRET_SALT || 'test_default_salt_12345';
241
- }
242
-
243
- const validatedConfig = await configSchema.parseAsync(mergedConfig);
244
+ // Parse and validate configuration with schema (includes test defaults)
245
+ const validatedConfig = configSchema.parse(rawConfig);
244
246
 
245
247
  // Production safety check - ensure test defaults aren't used in production
246
248
  if (
@@ -116,7 +116,7 @@ import {
116
116
  updateFile,
117
117
  validateGitHubToken,
118
118
  writeEnvFile
119
- } from "./chunk-D3QSET5H.js";
119
+ } from "./chunk-N5G5XSGP.js";
120
120
  import {
121
121
  runBunCommand
122
122
  } from "./chunk-FQYWRHLX.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elizaos/cli",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
4
4
  "description": "elizaOS CLI - Manage your AI agents and plugins",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -64,7 +64,6 @@
64
64
  "@types/node": "^24.0.3",
65
65
  "@types/prompts": "^2.4.2",
66
66
  "@types/semver": "^7.5.8",
67
- "bats-assert": "^2.0.0",
68
67
  "bats-support": "^0.3.0",
69
68
  "cross-env": "^7.0.3",
70
69
  "esbuild-plugin-copy": "^2.1.1",
@@ -73,15 +72,15 @@
73
72
  "typescript": "5.8.3",
74
73
  "vite": "^6.3.5"
75
74
  },
76
- "gitHead": "f60dd270910361decc4d4e879e8b2f33c5ddfee2",
75
+ "gitHead": "966e28250672a7a0c5f934defd995c51b94c4622",
77
76
  "dependencies": {
78
77
  "@anthropic-ai/claude-code": "^1.0.35",
79
78
  "@anthropic-ai/sdk": "^0.54.0",
80
79
  "@clack/prompts": "^0.11.0",
81
- "@elizaos/api-client": "1.4.2",
82
- "@elizaos/core": "1.4.2",
83
- "@elizaos/plugin-sql": "1.4.2",
84
- "@elizaos/server": "1.4.2",
80
+ "@elizaos/api-client": "1.4.3",
81
+ "@elizaos/core": "1.4.3",
82
+ "@elizaos/plugin-sql": "1.4.3",
83
+ "@elizaos/server": "1.4.3",
85
84
  "bun": "^1.2.17",
86
85
  "chalk": "^5.3.0",
87
86
  "chokidar": "^4.0.3",
@@ -41,11 +41,11 @@
41
41
  "tsup.config.ts"
42
42
  ],
43
43
  "dependencies": {
44
- "@elizaos/core": "1.4.2",
44
+ "@elizaos/core": "1.4.3",
45
45
  "zod": "^3.24.4"
46
46
  },
47
47
  "devDependencies": {
48
- "@elizaos/cli": "1.4.2",
48
+ "@elizaos/cli": "1.4.3",
49
49
  "dotenv": "16.4.5",
50
50
  "prettier": "3.5.3",
51
51
  "tsup": "8.5.0",
@@ -41,7 +41,7 @@
41
41
  "tsup.config.ts"
42
42
  ],
43
43
  "dependencies": {
44
- "@elizaos/core": "1.4.2",
44
+ "@elizaos/core": "1.4.3",
45
45
  "@tanstack/react-query": "^5.80.7",
46
46
  "clsx": "^2.1.1",
47
47
  "tailwind-merge": "^3.3.1",
@@ -50,7 +50,7 @@
50
50
  "zod": "3.24.2"
51
51
  },
52
52
  "devDependencies": {
53
- "@elizaos/cli": "1.4.2",
53
+ "@elizaos/cli": "1.4.3",
54
54
  "@tailwindcss/vite": "^4.1.10",
55
55
  "@vitejs/plugin-react-swc": "^3.10.2",
56
56
  "dotenv": "16.4.5",
@@ -28,10 +28,10 @@
28
28
  "dist"
29
29
  ],
30
30
  "dependencies": {
31
- "@elizaos/cli": "1.4.2",
32
- "@elizaos/core": "1.4.2",
33
- "@elizaos/plugin-bootstrap": "1.4.2",
34
- "@elizaos/plugin-sql": "1.4.2",
31
+ "@elizaos/cli": "1.4.3",
32
+ "@elizaos/core": "1.4.3",
33
+ "@elizaos/plugin-bootstrap": "1.4.3",
34
+ "@elizaos/plugin-sql": "1.4.3",
35
35
  "@tanstack/react-query": "^5.29.0",
36
36
  "clsx": "^2.1.1",
37
37
  "react": "^18.3.1",
@@ -1,20 +1,8 @@
1
- import { describe, expect, it, beforeEach, afterEach, mock } from 'bun:test';
1
+ import { describe, expect, it, beforeEach, afterEach, mock, spyOn } from 'bun:test';
2
2
  import plugin from '../plugin';
3
3
  import { z } from 'zod';
4
4
  import { createMockRuntime } from './utils/core-test-utils';
5
-
6
- // Mock logger
7
- mock.module('@elizaos/core', () => {
8
- const actual = require('@elizaos/core');
9
- return {
10
- ...actual,
11
- logger: {
12
- info: mock(),
13
- error: mock(),
14
- warn: mock(),
15
- },
16
- };
17
- });
5
+ import { logger } from '@elizaos/core';
18
6
 
19
7
  // Access the plugin's init function
20
8
  const initPlugin = plugin.init;
@@ -24,7 +12,10 @@ describe('Plugin Configuration Schema', () => {
24
12
  const originalEnv = { ...process.env };
25
13
 
26
14
  beforeEach(() => {
27
- mock.restore();
15
+ // Use spyOn for logger methods
16
+ spyOn(logger, 'info');
17
+ spyOn(logger, 'error');
18
+ spyOn(logger, 'warn');
28
19
  // Reset environment variables before each test
29
20
  process.env = { ...originalEnv };
30
21
  });
@@ -5,26 +5,12 @@ import { logger } from '@elizaos/core';
5
5
  import type { IAgentRuntime, Memory, State } from '@elizaos/core';
6
6
  import { v4 as uuidv4 } from 'uuid';
7
7
 
8
- // Mock logger
9
- mock.module('@elizaos/core', () => {
10
- const actual = require('@elizaos/core');
11
- return {
12
- ...actual,
13
- logger: {
14
- info: mock(),
15
- error: mock(),
16
- warn: mock(),
17
- },
18
- };
19
- });
20
-
21
8
  describe('Error Handling', () => {
22
9
  beforeEach(() => {
23
- mock.restore();
24
- });
25
-
26
- afterEach(() => {
27
- // No global restore needed in bun:test;
10
+ // Use spyOn for logger methods
11
+ spyOn(logger, 'info');
12
+ spyOn(logger, 'error');
13
+ spyOn(logger, 'warn');
28
14
  });
29
15
 
30
16
  describe('HELLO_WORLD Action Error Handling', () => {
@@ -1,22 +1,14 @@
1
- import { describe, expect, it, beforeEach, mock } from 'bun:test';
1
+ import { describe, expect, it, beforeAll, afterAll, spyOn } from 'bun:test';
2
2
  import plugin from '../plugin';
3
3
  import { logger } from '@elizaos/core';
4
4
 
5
- // Mock logger
6
- mock.module('@elizaos/core', () => {
7
- const actual = require('@elizaos/core');
8
- return {
9
- ...actual,
10
- logger: {
11
- info: mock(),
12
- error: mock(),
13
- },
14
- };
15
- });
16
-
17
5
  describe('Plugin Events', () => {
18
- beforeEach(() => {
19
- mock.restore();
6
+ // Use spyOn like all other tests in the codebase
7
+ beforeAll(() => {
8
+ spyOn(logger, 'info');
9
+ spyOn(logger, 'error');
10
+ spyOn(logger, 'warn');
11
+ spyOn(logger, 'debug');
20
12
  });
21
13
 
22
14
  it('should have events defined', () => {
@@ -47,9 +39,12 @@ describe('Plugin Events', () => {
47
39
  // Call the event handler
48
40
  await messageHandler(mockParams);
49
41
 
50
- // Verify log was called
42
+ // Verify logger was called with correct Pino-style structured logging
51
43
  expect(logger.info).toHaveBeenCalledWith('MESSAGE_RECEIVED event received');
52
- expect(logger.info).toHaveBeenCalledWith(expect.any(Array));
44
+ expect(logger.info).toHaveBeenCalledWith(
45
+ { keys: expect.any(Array) },
46
+ 'MESSAGE_RECEIVED param keys'
47
+ );
53
48
  }
54
49
  });
55
50
 
@@ -74,9 +69,12 @@ describe('Plugin Events', () => {
74
69
  // Call the event handler
75
70
  await voiceHandler(mockParams);
76
71
 
77
- // Verify log was called
72
+ // Verify logger was called with correct Pino-style structured logging
78
73
  expect(logger.info).toHaveBeenCalledWith('VOICE_MESSAGE_RECEIVED event received');
79
- expect(logger.info).toHaveBeenCalledWith(expect.any(Array));
74
+ expect(logger.info).toHaveBeenCalledWith(
75
+ { keys: expect.any(Array) },
76
+ 'VOICE_MESSAGE_RECEIVED param keys'
77
+ );
80
78
  }
81
79
  });
82
80
 
@@ -103,9 +101,12 @@ describe('Plugin Events', () => {
103
101
  // Call the event handler
104
102
  await connectedHandler(mockParams);
105
103
 
106
- // Verify log was called
104
+ // Verify logger was called with correct Pino-style structured logging
107
105
  expect(logger.info).toHaveBeenCalledWith('WORLD_CONNECTED event received');
108
- expect(logger.info).toHaveBeenCalledWith(expect.any(Array));
106
+ expect(logger.info).toHaveBeenCalledWith(
107
+ { keys: expect.any(Array) },
108
+ 'WORLD_CONNECTED param keys'
109
+ );
109
110
  }
110
111
  });
111
112
 
@@ -136,9 +137,12 @@ describe('Plugin Events', () => {
136
137
  // Call the event handler
137
138
  await joinedHandler(mockParams);
138
139
 
139
- // Verify log was called
140
+ // Verify logger was called with correct Pino-style structured logging
140
141
  expect(logger.info).toHaveBeenCalledWith('WORLD_JOINED event received');
141
- expect(logger.info).toHaveBeenCalledWith(expect.any(Array));
142
+ expect(logger.info).toHaveBeenCalledWith(
143
+ { keys: expect.any(Array) },
144
+ 'WORLD_JOINED param keys'
145
+ );
142
146
  }
143
147
  });
144
148
  });
@@ -33,11 +33,11 @@
33
33
  "GUIDE.md"
34
34
  ],
35
35
  "dependencies": {
36
- "@elizaos/cli": "1.4.2",
37
- "@elizaos/core": "1.4.2",
38
- "@elizaos/plugin-bootstrap": "1.4.2",
36
+ "@elizaos/cli": "1.4.3",
37
+ "@elizaos/core": "1.4.3",
38
+ "@elizaos/plugin-bootstrap": "1.4.3",
39
39
  "@elizaos/plugin-redpill": "1.2.1",
40
- "@elizaos/plugin-sql": "1.4.2",
40
+ "@elizaos/plugin-sql": "1.4.3",
41
41
  "@phala/dstack-sdk": "0.1.11",
42
42
  "@solana/web3.js": "1.98.2",
43
43
  "@tanstack/react-query": "^5.29.0",
@@ -18,6 +18,46 @@ describe('Plugin Configuration', () => {
18
18
  );
19
19
  });
20
20
 
21
+ it('should parse and validate config during initialization', async () => {
22
+ // Mock runtime for testing
23
+ const mockRuntime = {
24
+ logger: {
25
+ info: () => {},
26
+ warn: () => {},
27
+ debug: () => {},
28
+ error: () => {},
29
+ },
30
+ } as any;
31
+
32
+ // Test that config parsing happens during init, not at import time
33
+ const originalEnv = {
34
+ NODE_ENV: process.env.NODE_ENV,
35
+ TEE_MODE: process.env.TEE_MODE,
36
+ WALLET_SECRET_SALT: process.env.WALLET_SECRET_SALT,
37
+ };
38
+
39
+ try {
40
+ // Set test environment with valid defaults
41
+ process.env.NODE_ENV = 'test';
42
+ process.env.TEE_MODE = 'OFF';
43
+ process.env.WALLET_SECRET_SALT = 'test_salt_12345';
44
+
45
+ // Config should be parsed and validated during init without throwing
46
+ await expect(teeStarterPlugin.init({}, mockRuntime)).resolves.toBeUndefined();
47
+
48
+ // Test with invalid config should fail validation during init
49
+ const invalidConfig = { TEE_MODE: 'INVALID_MODE' };
50
+ await expect(teeStarterPlugin.init(invalidConfig, mockRuntime)).rejects.toThrow(
51
+ 'Invalid plugin configuration'
52
+ );
53
+ } finally {
54
+ // Restore original environment
55
+ process.env.NODE_ENV = originalEnv.NODE_ENV;
56
+ process.env.TEE_MODE = originalEnv.TEE_MODE;
57
+ process.env.WALLET_SECRET_SALT = originalEnv.WALLET_SECRET_SALT;
58
+ }
59
+ });
60
+
21
61
  it('should be a TEE-focused plugin with appropriate components', () => {
22
62
  // Verify plugin has TEE-specific components
23
63
  expect(teeStarterPlugin.actions).toEqual([]);
@@ -213,34 +213,36 @@ export class StarterService extends Service {
213
213
  const teeStarterPlugin: Plugin = {
214
214
  name: 'mr-tee-starter-plugin',
215
215
  description: "Mr. TEE's starter plugin - using plugin-tee for attestation",
216
- config: {
217
- TEE_MODE: process.env.TEE_MODE,
218
- TEE_VENDOR: process.env.TEE_VENDOR,
219
- WALLET_SECRET_SALT: process.env.WALLET_SECRET_SALT,
220
- },
216
+ // Use dynamic getters so tests/CI always see current env values
217
+ config: Object.defineProperties(
218
+ {},
219
+ {
220
+ TEE_MODE: {
221
+ get: () => process.env.TEE_MODE,
222
+ enumerable: true,
223
+ },
224
+ TEE_VENDOR: {
225
+ get: () => process.env.TEE_VENDOR,
226
+ enumerable: true,
227
+ },
228
+ WALLET_SECRET_SALT: {
229
+ get: () => process.env.WALLET_SECRET_SALT,
230
+ enumerable: true,
231
+ },
232
+ }
233
+ ) as Record<string, string>,
221
234
  async init(config: Record<string, string>, runtime: IAgentRuntime) {
222
235
  logger.info('*** Initializing Mr. TEE plugin ***');
223
236
  try {
224
237
  // Merge process.env values with config, config takes precedence
225
- const mergedConfig = {
238
+ const rawConfig = {
226
239
  TEE_MODE: config.TEE_MODE ?? process.env.TEE_MODE,
227
240
  TEE_VENDOR: config.TEE_VENDOR ?? process.env.TEE_VENDOR,
228
241
  WALLET_SECRET_SALT: config.WALLET_SECRET_SALT ?? process.env.WALLET_SECRET_SALT,
229
242
  };
230
243
 
231
- // Apply test defaults if in test environment
232
- const isTestEnvironment = process.env.NODE_ENV === 'test' || process.argv.includes('test');
233
-
234
- if (isTestEnvironment) {
235
- // Apply test-only defaults - NEVER use these in production
236
- mergedConfig.TEE_MODE = mergedConfig.TEE_MODE || 'OFF';
237
- mergedConfig.TEE_VENDOR = mergedConfig.TEE_VENDOR || 'phala';
238
- // Test salt - this is ONLY for test environments and should NEVER be used in production
239
- mergedConfig.WALLET_SECRET_SALT =
240
- mergedConfig.WALLET_SECRET_SALT || 'test_default_salt_12345';
241
- }
242
-
243
- const validatedConfig = await configSchema.parseAsync(mergedConfig);
244
+ // Parse and validate configuration with schema (includes test defaults)
245
+ const validatedConfig = configSchema.parse(rawConfig);
244
246
 
245
247
  // Production safety check - ensure test defaults aren't used in production
246
248
  if (