@elizaos/cli 1.0.15 → 1.0.17
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/dist/assets/{index-TE3LspKB.js → index-D8r_Vfdr.js} +3506 -3277
- package/dist/assets/index-D8r_Vfdr.js.br +0 -0
- package/dist/assets/{index-TE3LspKB.js.map → index-D8r_Vfdr.js.map} +1 -1
- package/dist/assets/{index-CYy-fwbh.js → index-DHpmOGa_.js} +3 -3
- package/dist/assets/index-DHpmOGa_.js.br +0 -0
- package/dist/assets/{index-CYy-fwbh.js.map → index-DHpmOGa_.js.map} +1 -1
- package/dist/assets/index-vV3utthf.css +1 -0
- package/dist/assets/index-vV3utthf.css.br +0 -0
- package/dist/assets/{vendor-DSdxb8P-.js → vendor-DS2z8upE.js} +2 -2
- package/dist/assets/vendor-DS2z8upE.js.br +0 -0
- package/dist/assets/{vendor-DSdxb8P-.js.map → vendor-DS2z8upE.js.map} +1 -1
- package/dist/{chunk-AZUBN22B.js → chunk-OK5O2MHJ.js} +503 -705
- package/dist/{chunk-OXZUNMVC.js → chunk-PRO6QOLZ.js} +175 -48
- package/dist/{chunk-BRDZOULQ.js → chunk-UVBNT4WP.js} +19 -6
- package/dist/{chunk-KB3JDWUI.js → chunk-W4NJVJQV.js} +43 -1
- package/dist/commands/agent/actions/index.js +2 -3
- package/dist/commands/agent/index.js +2 -3
- package/dist/commands/create/actions/index.d.ts +3 -0
- package/dist/commands/create/actions/index.js +3 -4
- package/dist/commands/create/index.js +4 -5
- package/dist/elizaos-avatar.png +0 -0
- package/dist/index.html +3 -3
- package/dist/index.js +1682 -381
- package/dist/migration-guides/advanced-migration-guide.md +459 -0
- package/dist/migration-guides/completion-requirements.md +379 -0
- package/dist/migration-guides/integrated-migration-loop.md +392 -0
- package/dist/migration-guides/migration-guide.md +712 -0
- package/dist/migration-guides/prompt-and-generation-guide.md +702 -0
- package/dist/migration-guides/state-and-providers-guide.md +544 -0
- package/dist/migration-guides/testing-guide.md +1021 -0
- package/dist/{plugin-creator-TLQLTQIB.js → plugin-creator-ZCOZ3UCT.js} +1 -2
- package/dist/{registry-BQSPZS3F.js → registry-FBPEGL2T.js} +2 -3
- package/dist/templates/project-starter/package.json +4 -4
- package/dist/templates/project-tee-starter/package.json +3 -3
- package/dist/{utils-BROS5JZQ.js → utils-I3EA43DE.js} +6 -19
- package/package.json +8 -6
- package/templates/project-starter/package.json +4 -4
- package/templates/project-tee-starter/package.json +3 -3
- package/dist/assets/index-CYy-fwbh.js.br +0 -0
- package/dist/assets/index-DzLbKTxV.css +0 -1
- package/dist/assets/index-DzLbKTxV.css.br +0 -0
- package/dist/assets/index-TE3LspKB.js.br +0 -0
- package/dist/assets/vendor-DSdxb8P-.js.br +0 -0
- package/dist/chunk-RIAWNDYI.js +0 -49
- package/dist/migrator-UQ4XFYE5.js +0 -744
package/dist/index.js
CHANGED
|
@@ -5,10 +5,10 @@ const require = createRequire(import.meta.url);
|
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
create
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-UVBNT4WP.js";
|
|
9
9
|
import {
|
|
10
10
|
getElizaCharacter
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-PRO6QOLZ.js";
|
|
12
12
|
import {
|
|
13
13
|
TestRunner,
|
|
14
14
|
UserEnvironment,
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
buildProject,
|
|
17
17
|
checkAndShowUpdateNotification,
|
|
18
18
|
configureDatabaseSettings,
|
|
19
|
+
createEnvFileService,
|
|
19
20
|
detectDirectoryType,
|
|
20
21
|
detectPluginContext,
|
|
21
22
|
displayBanner,
|
|
@@ -38,7 +39,6 @@ import {
|
|
|
38
39
|
logHeader,
|
|
39
40
|
migrateCliToBun,
|
|
40
41
|
normalizePluginName,
|
|
41
|
-
promptForEnvVars,
|
|
42
42
|
provideLocalPluginGuidance,
|
|
43
43
|
publishToGitHub,
|
|
44
44
|
resolvePgliteDir,
|
|
@@ -46,14 +46,12 @@ import {
|
|
|
46
46
|
testPublishToGitHub,
|
|
47
47
|
testPublishToNpm,
|
|
48
48
|
validateDataDir
|
|
49
|
-
} from "./chunk-
|
|
50
|
-
import {
|
|
51
|
-
runBunCommand
|
|
52
|
-
} from "./chunk-RIAWNDYI.js";
|
|
49
|
+
} from "./chunk-OK5O2MHJ.js";
|
|
53
50
|
import {
|
|
54
51
|
configureEmojis,
|
|
55
|
-
emoji
|
|
56
|
-
|
|
52
|
+
emoji,
|
|
53
|
+
runBunCommand
|
|
54
|
+
} from "./chunk-W4NJVJQV.js";
|
|
57
55
|
import "./chunk-F24MS2YR.js";
|
|
58
56
|
import "./chunk-AQ6OMR2A.js";
|
|
59
57
|
|
|
@@ -412,51 +410,30 @@ import { existsSync as existsSync4 } from "fs";
|
|
|
412
410
|
import path4 from "path";
|
|
413
411
|
|
|
414
412
|
// src/commands/env/utils/file-operations.ts
|
|
415
|
-
import dotenv from "dotenv";
|
|
416
413
|
import { existsSync as existsSync3 } from "fs";
|
|
417
|
-
import fs from "fs/promises";
|
|
418
414
|
import path3 from "path";
|
|
419
415
|
async function getLocalEnvPath() {
|
|
420
416
|
const localEnvPath = path3.join(process.cwd(), ".env");
|
|
421
417
|
return existsSync3(localEnvPath) ? localEnvPath : null;
|
|
422
418
|
}
|
|
423
419
|
async function parseEnvFile(filePath) {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
return {};
|
|
427
|
-
}
|
|
428
|
-
const content = await fs.readFile(filePath, "utf-8");
|
|
429
|
-
if (content.trim() === "") {
|
|
430
|
-
return {};
|
|
431
|
-
}
|
|
432
|
-
return dotenv.parse(content);
|
|
433
|
-
} catch (error) {
|
|
434
|
-
console.error(
|
|
435
|
-
`Error parsing .env file: ${error instanceof Error ? error.message : String(error)}`
|
|
436
|
-
);
|
|
437
|
-
return {};
|
|
438
|
-
}
|
|
420
|
+
const service = createEnvFileService(filePath);
|
|
421
|
+
return service.read();
|
|
439
422
|
}
|
|
440
423
|
async function writeEnvFile(filePath, envVars) {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
const content = Object.entries(envVars).map(([key, value]) => `${key}=${value}`).join("\n");
|
|
447
|
-
await fs.writeFile(filePath, content);
|
|
448
|
-
} catch (error) {
|
|
449
|
-
console.error(
|
|
450
|
-
`Error writing .env file: ${error instanceof Error ? error.message : String(error)}`
|
|
451
|
-
);
|
|
452
|
-
}
|
|
424
|
+
const service = createEnvFileService(filePath);
|
|
425
|
+
await service.write(envVars, {
|
|
426
|
+
preserveComments: true,
|
|
427
|
+
updateProcessEnv: true
|
|
428
|
+
});
|
|
453
429
|
}
|
|
454
430
|
async function resetEnvFile(filePath) {
|
|
455
431
|
try {
|
|
456
432
|
if (!existsSync3(filePath)) {
|
|
457
433
|
return false;
|
|
458
434
|
}
|
|
459
|
-
const
|
|
435
|
+
const service = createEnvFileService(filePath);
|
|
436
|
+
const envVars = await service.read();
|
|
460
437
|
if (Object.keys(envVars).length === 0) {
|
|
461
438
|
return false;
|
|
462
439
|
}
|
|
@@ -464,7 +441,11 @@ async function resetEnvFile(filePath) {
|
|
|
464
441
|
acc[key] = "";
|
|
465
442
|
return acc;
|
|
466
443
|
}, {});
|
|
467
|
-
await
|
|
444
|
+
await service.write(resetVars, {
|
|
445
|
+
preserveComments: true,
|
|
446
|
+
updateProcessEnv: false
|
|
447
|
+
// Don't update process.env with empty values
|
|
448
|
+
});
|
|
468
449
|
return true;
|
|
469
450
|
} catch (error) {
|
|
470
451
|
console.error(
|
|
@@ -584,7 +565,7 @@ async function editEnvVars(options, fromMainMenu = false) {
|
|
|
584
565
|
console.log(`\u2713 Updated ${selection}`);
|
|
585
566
|
}
|
|
586
567
|
} else if (action === "delete") {
|
|
587
|
-
let
|
|
568
|
+
let confirm9 = true;
|
|
588
569
|
if (!yes) {
|
|
589
570
|
const resp = await clack.confirm({
|
|
590
571
|
message: `Are you sure you want to delete ${selection}?`,
|
|
@@ -594,9 +575,9 @@ async function editEnvVars(options, fromMainMenu = false) {
|
|
|
594
575
|
clack.cancel("Operation cancelled.");
|
|
595
576
|
process.exit(0);
|
|
596
577
|
}
|
|
597
|
-
|
|
578
|
+
confirm9 = resp;
|
|
598
579
|
}
|
|
599
|
-
if (
|
|
580
|
+
if (confirm9) {
|
|
600
581
|
delete envVars[selection];
|
|
601
582
|
await writeEnvFile(localEnvPath, envVars);
|
|
602
583
|
console.log(`\u2713 Removed ${selection}`);
|
|
@@ -810,15 +791,15 @@ async function resetEnv(options) {
|
|
|
810
791
|
const item = resetItems.find((item2) => item2.value === value);
|
|
811
792
|
console.log(` \u2022 ${item?.title || value}`);
|
|
812
793
|
}
|
|
813
|
-
const
|
|
794
|
+
const confirm9 = await clack2.confirm({
|
|
814
795
|
message: "Are you sure you want to reset the selected items?",
|
|
815
796
|
initialValue: false
|
|
816
797
|
});
|
|
817
|
-
if (clack2.isCancel(
|
|
798
|
+
if (clack2.isCancel(confirm9)) {
|
|
818
799
|
clack2.cancel("Operation cancelled.");
|
|
819
800
|
process.exit(0);
|
|
820
801
|
}
|
|
821
|
-
if (!
|
|
802
|
+
if (!confirm9) {
|
|
822
803
|
console.log("Reset cancelled.");
|
|
823
804
|
return;
|
|
824
805
|
}
|
|
@@ -996,21 +977,70 @@ var extractPackageName = (pluginInput) => {
|
|
|
996
977
|
|
|
997
978
|
// src/commands/plugins/utils/env-vars.ts
|
|
998
979
|
import { logger } from "@elizaos/core";
|
|
999
|
-
import { existsSync as existsSync8, readFileSync,
|
|
980
|
+
import { existsSync as existsSync8, readFileSync, readdirSync as readdirSync2 } from "fs";
|
|
1000
981
|
import path7 from "path";
|
|
1001
982
|
import * as clack4 from "@clack/prompts";
|
|
1002
983
|
var extractPluginEnvRequirements = async (packageName, cwd) => {
|
|
1003
984
|
try {
|
|
1004
|
-
const
|
|
1005
|
-
|
|
1006
|
-
|
|
985
|
+
const possiblePaths = [
|
|
986
|
+
// Direct path
|
|
987
|
+
path7.join(cwd, "node_modules", packageName, "package.json"),
|
|
988
|
+
// Scoped package path (e.g., @elizaos/plugin-discord)
|
|
989
|
+
path7.join(cwd, "node_modules", packageName.replace("/", path7.sep), "package.json")
|
|
990
|
+
];
|
|
991
|
+
if (!packageName.startsWith("@elizaos/")) {
|
|
992
|
+
possiblePaths.push(
|
|
993
|
+
path7.join(cwd, "node_modules", "@elizaos", packageName, "package.json"),
|
|
994
|
+
path7.join(cwd, "node_modules", "@elizaos", `plugin-${packageName}`, "package.json")
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
let currentDir = cwd;
|
|
998
|
+
for (let i = 0; i < 5; i++) {
|
|
999
|
+
const parentNodeModules = path7.join(currentDir, "node_modules");
|
|
1000
|
+
if (existsSync8(parentNodeModules)) {
|
|
1001
|
+
possiblePaths.push(
|
|
1002
|
+
path7.join(parentNodeModules, packageName, "package.json"),
|
|
1003
|
+
path7.join(parentNodeModules, packageName.replace("/", path7.sep), "package.json")
|
|
1004
|
+
);
|
|
1005
|
+
}
|
|
1006
|
+
const parentDir = path7.dirname(currentDir);
|
|
1007
|
+
if (parentDir === currentDir) break;
|
|
1008
|
+
currentDir = parentDir;
|
|
1009
|
+
}
|
|
1010
|
+
let packageJsonPath = null;
|
|
1011
|
+
for (const possiblePath of possiblePaths) {
|
|
1012
|
+
if (existsSync8(possiblePath)) {
|
|
1013
|
+
packageJsonPath = possiblePath;
|
|
1014
|
+
logger.debug(`Found plugin package.json at: ${packageJsonPath}`);
|
|
1015
|
+
break;
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
if (!packageJsonPath) {
|
|
1019
|
+
const nodeModulesPath = path7.join(cwd, "node_modules");
|
|
1020
|
+
if (existsSync8(nodeModulesPath)) {
|
|
1021
|
+
const packages = readdirSync2(nodeModulesPath);
|
|
1022
|
+
for (const pkg of packages) {
|
|
1023
|
+
if (pkg.includes(packageName.replace("@elizaos/", "").replace("plugin-", ""))) {
|
|
1024
|
+
const pkgJsonPath = path7.join(nodeModulesPath, pkg, "package.json");
|
|
1025
|
+
if (existsSync8(pkgJsonPath)) {
|
|
1026
|
+
packageJsonPath = pkgJsonPath;
|
|
1027
|
+
logger.debug(`Found matching plugin package.json at: ${packageJsonPath}`);
|
|
1028
|
+
break;
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
if (!packageJsonPath) {
|
|
1035
|
+
logger.debug(`Plugin package.json not found for: ${packageName}`);
|
|
1036
|
+
logger.debug(`Searched paths: ${possiblePaths.join(", ")}`);
|
|
1007
1037
|
return {};
|
|
1008
1038
|
}
|
|
1009
|
-
const packageJsonContent = readFileSync(
|
|
1039
|
+
const packageJsonContent = readFileSync(packageJsonPath, "utf-8");
|
|
1010
1040
|
const packageJson = JSON.parse(packageJsonContent);
|
|
1011
1041
|
const agentConfig = packageJson.agentConfig;
|
|
1012
1042
|
if (!agentConfig || !agentConfig.pluginParameters) {
|
|
1013
|
-
logger.debug(`No agentConfig.pluginParameters found in ${packageName}`);
|
|
1043
|
+
logger.debug(`No agentConfig.pluginParameters found in ${packageName} at ${packageJsonPath}`);
|
|
1014
1044
|
return {};
|
|
1015
1045
|
}
|
|
1016
1046
|
logger.debug(
|
|
@@ -1024,17 +1054,10 @@ var extractPluginEnvRequirements = async (packageName, cwd) => {
|
|
|
1024
1054
|
return {};
|
|
1025
1055
|
}
|
|
1026
1056
|
};
|
|
1027
|
-
var readEnvFile = (cwd) => {
|
|
1028
|
-
const envPath = path7.join(cwd, ".env");
|
|
1029
|
-
try {
|
|
1030
|
-
return readFileSync(envPath, "utf-8");
|
|
1031
|
-
} catch (error) {
|
|
1032
|
-
return "";
|
|
1033
|
-
}
|
|
1034
|
-
};
|
|
1035
|
-
var writeEnvFile2 = (cwd, content) => {
|
|
1057
|
+
var readEnvFile = async (cwd) => {
|
|
1036
1058
|
const envPath = path7.join(cwd, ".env");
|
|
1037
|
-
|
|
1059
|
+
const envService = createEnvFileService(envPath);
|
|
1060
|
+
return envService.read();
|
|
1038
1061
|
};
|
|
1039
1062
|
var extractDefaultFromDescription = (description) => {
|
|
1040
1063
|
const patterns = [
|
|
@@ -1057,40 +1080,158 @@ var extractDefaultFromDescription = (description) => {
|
|
|
1057
1080
|
};
|
|
1058
1081
|
var promptForEnvVar = async (varName, config2) => {
|
|
1059
1082
|
const {
|
|
1083
|
+
type = "string",
|
|
1060
1084
|
description = "No description available",
|
|
1061
1085
|
default: explicitDefault,
|
|
1062
|
-
sensitive = false
|
|
1086
|
+
sensitive = false,
|
|
1087
|
+
required = true
|
|
1088
|
+
// Default to true for backwards compatibility
|
|
1063
1089
|
} = config2;
|
|
1064
1090
|
const defaultValue = explicitDefault || extractDefaultFromDescription(description);
|
|
1065
1091
|
const isSecret = sensitive !== void 0 ? sensitive : varName.toLowerCase().includes("key") || varName.toLowerCase().includes("token") || varName.toLowerCase().includes("secret") || varName.toLowerCase().includes("password");
|
|
1066
|
-
const message = defaultValue ? `Enter ${varName} (default: ${defaultValue})` : `Enter ${varName}`;
|
|
1067
|
-
const placeholder = isSecret ? "Your secret key/token..." : defaultValue || "Enter value...";
|
|
1068
1092
|
if (description && description !== "No description available") {
|
|
1069
1093
|
clack4.note(`${description}`, `${varName} Info`);
|
|
1070
1094
|
}
|
|
1095
|
+
if (type === "boolean") {
|
|
1096
|
+
const defaultBool = defaultValue === "true" || String(explicitDefault).toLowerCase() === "true";
|
|
1097
|
+
const response2 = await clack4.confirm({
|
|
1098
|
+
message: required ? `Enable ${varName}?` : `Enable ${varName}? (optional)`,
|
|
1099
|
+
initialValue: defaultBool
|
|
1100
|
+
});
|
|
1101
|
+
if (clack4.isCancel(response2)) {
|
|
1102
|
+
clack4.cancel("Operation cancelled.");
|
|
1103
|
+
process.exit(0);
|
|
1104
|
+
}
|
|
1105
|
+
if (!required && response2 === void 0) {
|
|
1106
|
+
return "";
|
|
1107
|
+
}
|
|
1108
|
+
return String(response2);
|
|
1109
|
+
}
|
|
1110
|
+
if (type === "number") {
|
|
1111
|
+
const message2 = defaultValue ? `Enter ${varName} (default: ${String(defaultValue)})` : required ? `Enter ${varName}` : `Enter ${varName} (press Enter to skip)`;
|
|
1112
|
+
const promptConfig2 = {
|
|
1113
|
+
message: message2,
|
|
1114
|
+
placeholder: required ? String(defaultValue || "Enter a number") : String(defaultValue || "Press Enter to skip"),
|
|
1115
|
+
initialValue: defaultValue ? String(defaultValue) : void 0,
|
|
1116
|
+
validate: (input) => {
|
|
1117
|
+
if ((!input || input.trim() === "") && !required) {
|
|
1118
|
+
return void 0;
|
|
1119
|
+
}
|
|
1120
|
+
if ((!input || input.trim() === "") && required && !defaultValue) {
|
|
1121
|
+
return "This field cannot be empty. Press Ctrl+C to cancel.";
|
|
1122
|
+
}
|
|
1123
|
+
const trimmed = input.trim();
|
|
1124
|
+
if (trimmed && isNaN(Number(trimmed))) {
|
|
1125
|
+
return "Please enter a valid number";
|
|
1126
|
+
}
|
|
1127
|
+
return void 0;
|
|
1128
|
+
}
|
|
1129
|
+
};
|
|
1130
|
+
const response2 = await clack4.text(promptConfig2);
|
|
1131
|
+
if (clack4.isCancel(response2)) {
|
|
1132
|
+
clack4.cancel("Operation cancelled.");
|
|
1133
|
+
process.exit(0);
|
|
1134
|
+
}
|
|
1135
|
+
const finalValue2 = response2 && response2.trim() || defaultValue || "";
|
|
1136
|
+
return finalValue2.trim();
|
|
1137
|
+
}
|
|
1138
|
+
if (type === "array") {
|
|
1139
|
+
const message2 = defaultValue ? `Enter ${varName} (comma-separated, default: ${String(defaultValue)})` : required ? `Enter ${varName} (comma-separated values)` : `Enter ${varName} (comma-separated values, press Enter to skip)`;
|
|
1140
|
+
const promptConfig2 = {
|
|
1141
|
+
message: message2,
|
|
1142
|
+
placeholder: required ? String(defaultValue || "value1,value2,value3") : String(defaultValue || "Press Enter to skip"),
|
|
1143
|
+
initialValue: defaultValue ? String(defaultValue) : void 0,
|
|
1144
|
+
validate: (input) => {
|
|
1145
|
+
if ((!input || input.trim() === "") && !required) {
|
|
1146
|
+
return void 0;
|
|
1147
|
+
}
|
|
1148
|
+
if ((!input || input.trim() === "") && required && !defaultValue) {
|
|
1149
|
+
return "This field cannot be empty. Press Ctrl+C to cancel.";
|
|
1150
|
+
}
|
|
1151
|
+
return void 0;
|
|
1152
|
+
}
|
|
1153
|
+
};
|
|
1154
|
+
const response2 = await clack4.text(promptConfig2);
|
|
1155
|
+
if (clack4.isCancel(response2)) {
|
|
1156
|
+
clack4.cancel("Operation cancelled.");
|
|
1157
|
+
process.exit(0);
|
|
1158
|
+
}
|
|
1159
|
+
const finalValue2 = response2 && response2.trim() || defaultValue || "";
|
|
1160
|
+
if (finalValue2) {
|
|
1161
|
+
return finalValue2.split(",").map((v) => v.trim()).filter((v) => v).join(",");
|
|
1162
|
+
}
|
|
1163
|
+
return finalValue2;
|
|
1164
|
+
}
|
|
1165
|
+
if (type === "json") {
|
|
1166
|
+
clack4.log.info("Enter a JSON object. For multi-line input, use the editor.");
|
|
1167
|
+
const message2 = defaultValue ? `Enter ${varName} JSON (default: ${String(defaultValue)})` : required ? `Enter ${varName} JSON` : `Enter ${varName} JSON (press Enter to skip)`;
|
|
1168
|
+
const promptConfig2 = {
|
|
1169
|
+
message: message2,
|
|
1170
|
+
placeholder: required ? String(defaultValue || '{"key": "value"}') : String(defaultValue || "Press Enter to skip"),
|
|
1171
|
+
initialValue: defaultValue ? String(defaultValue) : void 0,
|
|
1172
|
+
validate: (input) => {
|
|
1173
|
+
if ((!input || input.trim() === "") && !required) {
|
|
1174
|
+
return void 0;
|
|
1175
|
+
}
|
|
1176
|
+
if ((!input || input.trim() === "") && required && !defaultValue) {
|
|
1177
|
+
return "This field cannot be empty. Press Ctrl+C to cancel.";
|
|
1178
|
+
}
|
|
1179
|
+
if (input && input.trim()) {
|
|
1180
|
+
try {
|
|
1181
|
+
JSON.parse(input.trim());
|
|
1182
|
+
} catch (error) {
|
|
1183
|
+
return "Please enter valid JSON format";
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
return void 0;
|
|
1187
|
+
}
|
|
1188
|
+
};
|
|
1189
|
+
const response2 = await clack4.text(promptConfig2);
|
|
1190
|
+
if (clack4.isCancel(response2)) {
|
|
1191
|
+
clack4.cancel("Operation cancelled.");
|
|
1192
|
+
process.exit(0);
|
|
1193
|
+
}
|
|
1194
|
+
const finalValue2 = response2 && response2.trim() || defaultValue || "";
|
|
1195
|
+
if (finalValue2) {
|
|
1196
|
+
try {
|
|
1197
|
+
const parsed = JSON.parse(finalValue2);
|
|
1198
|
+
return JSON.stringify(parsed);
|
|
1199
|
+
} catch {
|
|
1200
|
+
return finalValue2;
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
return finalValue2;
|
|
1204
|
+
}
|
|
1205
|
+
const message = defaultValue ? `Enter ${varName} (default: ${String(defaultValue)})` : required ? `Enter ${varName}` : `Enter ${varName} (press Enter to skip)`;
|
|
1206
|
+
const placeholder = isSecret ? "Your secret key/token..." : required ? String(defaultValue || "Required value") : String(defaultValue || "Press Enter to skip");
|
|
1071
1207
|
const promptFn = isSecret ? clack4.password : clack4.text;
|
|
1072
1208
|
const promptConfig = {
|
|
1073
1209
|
message,
|
|
1074
1210
|
placeholder,
|
|
1075
1211
|
validate: (input) => {
|
|
1076
|
-
if ((!input || input.trim() === "") && !defaultValue) {
|
|
1212
|
+
if ((!input || input.trim() === "") && required && !defaultValue) {
|
|
1077
1213
|
return "This field cannot be empty. Press Ctrl+C to cancel.";
|
|
1078
1214
|
}
|
|
1215
|
+
if ((!input || input.trim() === "") && !required) {
|
|
1216
|
+
return void 0;
|
|
1217
|
+
}
|
|
1079
1218
|
if (varName.includes("URL") || varName.includes("ENDPOINT")) {
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1219
|
+
if (input && input.trim()) {
|
|
1220
|
+
try {
|
|
1221
|
+
new URL(input.trim());
|
|
1222
|
+
} catch {
|
|
1223
|
+
return "Please enter a valid URL (e.g., https://api.example.com)";
|
|
1224
|
+
}
|
|
1084
1225
|
}
|
|
1085
1226
|
}
|
|
1086
|
-
if (varName.includes("API_KEY") && input.trim().length < 5) {
|
|
1227
|
+
if (varName.includes("API_KEY") && input.trim().length > 0 && input.trim().length < 5) {
|
|
1087
1228
|
return "API key seems too short. Please verify you entered the complete key.";
|
|
1088
1229
|
}
|
|
1089
1230
|
return void 0;
|
|
1090
1231
|
}
|
|
1091
1232
|
};
|
|
1092
1233
|
if (defaultValue && !isSecret) {
|
|
1093
|
-
promptConfig.initialValue = defaultValue;
|
|
1234
|
+
promptConfig.initialValue = String(defaultValue);
|
|
1094
1235
|
}
|
|
1095
1236
|
const response = await promptFn(promptConfig);
|
|
1096
1237
|
if (clack4.isCancel(response)) {
|
|
@@ -1100,37 +1241,54 @@ var promptForEnvVar = async (varName, config2) => {
|
|
|
1100
1241
|
const finalValue = response && response.trim() || defaultValue || "";
|
|
1101
1242
|
return finalValue.trim();
|
|
1102
1243
|
};
|
|
1103
|
-
var updateEnvFile = (cwd, varName, value) => {
|
|
1104
|
-
const
|
|
1105
|
-
const
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
}
|
|
1110
|
-
if (envContent && !envContent.endsWith("\n")) {
|
|
1111
|
-
lines.push("");
|
|
1112
|
-
}
|
|
1113
|
-
lines.push(`${varName}=${value}`);
|
|
1114
|
-
}
|
|
1115
|
-
writeEnvFile2(cwd, lines.join("\n"));
|
|
1244
|
+
var updateEnvFile = async (cwd, varName, value) => {
|
|
1245
|
+
const envPath = path7.join(cwd, ".env");
|
|
1246
|
+
const envService = createEnvFileService(envPath);
|
|
1247
|
+
await envService.update(varName, value, {
|
|
1248
|
+
preserveComments: true,
|
|
1249
|
+
updateProcessEnv: true
|
|
1250
|
+
});
|
|
1116
1251
|
};
|
|
1117
1252
|
var promptForPluginEnvVars = async (packageName, cwd) => {
|
|
1118
|
-
|
|
1253
|
+
let envRequirements = await extractPluginEnvRequirements(packageName, cwd);
|
|
1254
|
+
if (Object.keys(envRequirements).length === 0 && !packageName.startsWith("@elizaos/")) {
|
|
1255
|
+
const elizaosPackageName = `@elizaos/${packageName.replace("plugin-", "")}`;
|
|
1256
|
+
envRequirements = await extractPluginEnvRequirements(elizaosPackageName, cwd);
|
|
1257
|
+
if (Object.keys(envRequirements).length === 0) {
|
|
1258
|
+
const elizaosPluginPackageName = `@elizaos/plugin-${packageName.replace("plugin-", "")}`;
|
|
1259
|
+
envRequirements = await extractPluginEnvRequirements(elizaosPluginPackageName, cwd);
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1119
1262
|
if (Object.keys(envRequirements).length === 0) {
|
|
1120
|
-
|
|
1121
|
-
|
|
1263
|
+
const nodeModulesPath = path7.join(cwd, "node_modules");
|
|
1264
|
+
const possiblePackages = [
|
|
1265
|
+
packageName,
|
|
1266
|
+
`@elizaos/${packageName.replace("plugin-", "")}`,
|
|
1267
|
+
`@elizaos/plugin-${packageName.replace("plugin-", "")}`
|
|
1268
|
+
];
|
|
1269
|
+
let packageFound = false;
|
|
1270
|
+
for (const pkg of possiblePackages) {
|
|
1271
|
+
const pkgPath = path7.join(nodeModulesPath, ...pkg.split("/"));
|
|
1272
|
+
if (existsSync8(path7.join(pkgPath, "package.json"))) {
|
|
1273
|
+
packageFound = true;
|
|
1274
|
+
break;
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
if (packageFound) {
|
|
1278
|
+
logger.debug(`Package ${packageName} found but has no environment variables defined`);
|
|
1279
|
+
clack4.log.success(`No environment variables required for ${packageName}`);
|
|
1280
|
+
} else {
|
|
1281
|
+
logger.debug(`Package ${packageName} not found in node_modules`);
|
|
1282
|
+
clack4.log.warn(
|
|
1283
|
+
`Could not find ${packageName} in node_modules. Environment variables may need to be configured manually.`
|
|
1284
|
+
);
|
|
1285
|
+
}
|
|
1122
1286
|
return;
|
|
1123
1287
|
}
|
|
1124
1288
|
await new Promise((resolve2) => setTimeout(resolve2, 100));
|
|
1125
1289
|
clack4.intro(`Setting up ${packageName} Plugin`);
|
|
1126
|
-
const
|
|
1127
|
-
const existingVars =
|
|
1128
|
-
envContent.split("\n").forEach((line) => {
|
|
1129
|
-
const match = line.match(/^([^=]+)=(.*)$/);
|
|
1130
|
-
if (match) {
|
|
1131
|
-
existingVars[match[1]] = match[2];
|
|
1132
|
-
}
|
|
1133
|
-
});
|
|
1290
|
+
const envVars = await readEnvFile(cwd);
|
|
1291
|
+
const existingVars = envVars;
|
|
1134
1292
|
const missingVars = [];
|
|
1135
1293
|
const existingConfigured = [];
|
|
1136
1294
|
Object.entries(envRequirements).forEach(([varName, config2]) => {
|
|
@@ -1183,7 +1341,7 @@ ${optionalVars.map(([name]) => ` - ${name}`).join("\n")}
|
|
|
1183
1341
|
const value = await promptForEnvVar(varName, config2);
|
|
1184
1342
|
if (value) {
|
|
1185
1343
|
spinner2.start(`Saving ${varName} to .env file...`);
|
|
1186
|
-
updateEnvFile(cwd, varName, value);
|
|
1344
|
+
await updateEnvFile(cwd, varName, value);
|
|
1187
1345
|
spinner2.stop(`${varName} configured successfully`);
|
|
1188
1346
|
newlyConfigured++;
|
|
1189
1347
|
configuredCount++;
|
|
@@ -1302,7 +1460,7 @@ async function installPluginFromGitHub(plugin, cwd, opts) {
|
|
|
1302
1460
|
if (success) {
|
|
1303
1461
|
logger3.info(`Successfully installed ${pluginNameForPostInstall} from ${githubSpecifier}.`);
|
|
1304
1462
|
if (!opts.skipEnvPrompt) {
|
|
1305
|
-
await new Promise((resolve2) => setTimeout(resolve2,
|
|
1463
|
+
await new Promise((resolve2) => setTimeout(resolve2, 500));
|
|
1306
1464
|
const packageName = extractPackageName(plugin);
|
|
1307
1465
|
console.log(`
|
|
1308
1466
|
\u{1F527} Checking environment variables for ${packageName}...`);
|
|
@@ -1341,7 +1499,7 @@ async function installPluginFromRegistry(plugin, cwd, opts) {
|
|
|
1341
1499
|
if (registryInstallResult) {
|
|
1342
1500
|
console.log(`Successfully installed ${targetName}`);
|
|
1343
1501
|
if (!opts.skipEnvPrompt) {
|
|
1344
|
-
await new Promise((resolve2) => setTimeout(resolve2,
|
|
1502
|
+
await new Promise((resolve2) => setTimeout(resolve2, 500));
|
|
1345
1503
|
const updatedDependencies = getDependenciesFromDirectory(cwd);
|
|
1346
1504
|
const actualPackageName = findPluginPackageName(targetName, updatedDependencies || {}) || targetName;
|
|
1347
1505
|
console.log(`
|
|
@@ -1566,78 +1724,1216 @@ async function listInstalledPlugins() {
|
|
|
1566
1724
|
}
|
|
1567
1725
|
|
|
1568
1726
|
// src/commands/plugins/actions/upgrade.ts
|
|
1569
|
-
import { logger as
|
|
1727
|
+
import { logger as logger8 } from "@elizaos/core";
|
|
1728
|
+
import path11 from "path";
|
|
1729
|
+
import { existsSync as existsSync11 } from "fs";
|
|
1730
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1731
|
+
import fs from "fs-extra";
|
|
1732
|
+
|
|
1733
|
+
// src/utils/upgrade/simple-migration-agent.ts
|
|
1734
|
+
import { query } from "@anthropic-ai/claude-code";
|
|
1735
|
+
import { EventEmitter } from "events";
|
|
1736
|
+
|
|
1737
|
+
// src/utils/upgrade/migration-guide-loader.ts
|
|
1738
|
+
import { existsSync as existsSync10, readFileSync as readFileSync3 } from "fs";
|
|
1570
1739
|
import path10 from "path";
|
|
1740
|
+
import { fileURLToPath } from "url";
|
|
1741
|
+
import { logger as logger6 } from "@elizaos/core";
|
|
1742
|
+
var MigrationGuideLoader = class {
|
|
1743
|
+
guides = [];
|
|
1744
|
+
guidesDir;
|
|
1745
|
+
constructor(projectRoot) {
|
|
1746
|
+
this.guidesDir = this.findGuidesDirectory(projectRoot);
|
|
1747
|
+
this.loadGuides();
|
|
1748
|
+
}
|
|
1749
|
+
findGuidesDirectory(projectRoot) {
|
|
1750
|
+
if (projectRoot) {
|
|
1751
|
+
const guidesPath = path10.join(projectRoot, "packages/docs/docs/plugins/migration/claude-code");
|
|
1752
|
+
if (existsSync10(guidesPath)) {
|
|
1753
|
+
return guidesPath;
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
let currentRoot = process.cwd();
|
|
1757
|
+
let previousRoot = "";
|
|
1758
|
+
while (currentRoot !== previousRoot && !existsSync10(path10.join(currentRoot, "packages/docs"))) {
|
|
1759
|
+
previousRoot = currentRoot;
|
|
1760
|
+
currentRoot = path10.dirname(currentRoot);
|
|
1761
|
+
}
|
|
1762
|
+
const monorepoGuidesPath = path10.join(
|
|
1763
|
+
currentRoot,
|
|
1764
|
+
"packages/docs/docs/plugins/migration/claude-code"
|
|
1765
|
+
);
|
|
1766
|
+
if (existsSync10(monorepoGuidesPath)) {
|
|
1767
|
+
return monorepoGuidesPath;
|
|
1768
|
+
}
|
|
1769
|
+
const workingDirGuides = path10.join(process.cwd(), "migration-guides");
|
|
1770
|
+
if (existsSync10(workingDirGuides)) {
|
|
1771
|
+
return workingDirGuides;
|
|
1772
|
+
}
|
|
1773
|
+
const currentFileUrl = import.meta.url;
|
|
1774
|
+
const currentFilePath = fileURLToPath(currentFileUrl);
|
|
1775
|
+
const cliPackageRoot = path10.dirname(path10.dirname(path10.dirname(path10.dirname(currentFilePath))));
|
|
1776
|
+
const bundledGuidesPath = path10.join(cliPackageRoot, "migration-guides");
|
|
1777
|
+
if (existsSync10(bundledGuidesPath)) {
|
|
1778
|
+
return bundledGuidesPath;
|
|
1779
|
+
}
|
|
1780
|
+
return "";
|
|
1781
|
+
}
|
|
1782
|
+
loadGuides() {
|
|
1783
|
+
const guideConfigs = [
|
|
1784
|
+
{
|
|
1785
|
+
name: "migration-guide.md",
|
|
1786
|
+
category: "basic",
|
|
1787
|
+
keywords: [
|
|
1788
|
+
"import",
|
|
1789
|
+
"path",
|
|
1790
|
+
"action",
|
|
1791
|
+
"provider",
|
|
1792
|
+
"basic",
|
|
1793
|
+
"core",
|
|
1794
|
+
"elizaLogger",
|
|
1795
|
+
"logger",
|
|
1796
|
+
"IAgentRuntime",
|
|
1797
|
+
"AgentRuntime",
|
|
1798
|
+
"Account",
|
|
1799
|
+
"Entity",
|
|
1800
|
+
"composeContext",
|
|
1801
|
+
"generateObject",
|
|
1802
|
+
"package.json",
|
|
1803
|
+
"dependencies",
|
|
1804
|
+
"scripts",
|
|
1805
|
+
"build"
|
|
1806
|
+
]
|
|
1807
|
+
},
|
|
1808
|
+
{
|
|
1809
|
+
name: "state-and-providers-guide.md",
|
|
1810
|
+
category: "basic",
|
|
1811
|
+
keywords: [
|
|
1812
|
+
"state",
|
|
1813
|
+
"provider",
|
|
1814
|
+
"ProviderResult",
|
|
1815
|
+
"context",
|
|
1816
|
+
"memory",
|
|
1817
|
+
"runtime",
|
|
1818
|
+
"world",
|
|
1819
|
+
"room",
|
|
1820
|
+
"entityId",
|
|
1821
|
+
"userId",
|
|
1822
|
+
"optional"
|
|
1823
|
+
]
|
|
1824
|
+
},
|
|
1825
|
+
{
|
|
1826
|
+
name: "prompt-and-generation-guide.md",
|
|
1827
|
+
category: "basic",
|
|
1828
|
+
keywords: [
|
|
1829
|
+
"template",
|
|
1830
|
+
"prompt",
|
|
1831
|
+
"generation",
|
|
1832
|
+
"XML",
|
|
1833
|
+
"JSON",
|
|
1834
|
+
"useModel",
|
|
1835
|
+
"generateText",
|
|
1836
|
+
"messages",
|
|
1837
|
+
"format"
|
|
1838
|
+
]
|
|
1839
|
+
},
|
|
1840
|
+
{
|
|
1841
|
+
name: "advanced-migration-guide.md",
|
|
1842
|
+
category: "advanced",
|
|
1843
|
+
keywords: [
|
|
1844
|
+
"service",
|
|
1845
|
+
"evaluator",
|
|
1846
|
+
"settings",
|
|
1847
|
+
"singleton",
|
|
1848
|
+
"lifecycle",
|
|
1849
|
+
"initialize",
|
|
1850
|
+
"start",
|
|
1851
|
+
"stop",
|
|
1852
|
+
"client",
|
|
1853
|
+
"complex"
|
|
1854
|
+
]
|
|
1855
|
+
},
|
|
1856
|
+
{
|
|
1857
|
+
name: "testing-guide.md",
|
|
1858
|
+
category: "testing",
|
|
1859
|
+
keywords: [
|
|
1860
|
+
"test",
|
|
1861
|
+
"coverage",
|
|
1862
|
+
"vitest",
|
|
1863
|
+
"bun",
|
|
1864
|
+
"mock",
|
|
1865
|
+
"unit",
|
|
1866
|
+
"integration",
|
|
1867
|
+
"error",
|
|
1868
|
+
"edge",
|
|
1869
|
+
"performance",
|
|
1870
|
+
"test-utils"
|
|
1871
|
+
]
|
|
1872
|
+
},
|
|
1873
|
+
{
|
|
1874
|
+
name: "completion-requirements.md",
|
|
1875
|
+
category: "completion",
|
|
1876
|
+
keywords: [
|
|
1877
|
+
"release",
|
|
1878
|
+
"workflow",
|
|
1879
|
+
"npm",
|
|
1880
|
+
"deploy",
|
|
1881
|
+
"gitignore",
|
|
1882
|
+
"npmignore",
|
|
1883
|
+
"license",
|
|
1884
|
+
"prettier",
|
|
1885
|
+
"final",
|
|
1886
|
+
"validation"
|
|
1887
|
+
]
|
|
1888
|
+
}
|
|
1889
|
+
];
|
|
1890
|
+
if (!this.guidesDir || !existsSync10(this.guidesDir)) {
|
|
1891
|
+
logger6.info("Using embedded migration guidance (external CLI mode)");
|
|
1892
|
+
this.createEmbeddedGuides(guideConfigs);
|
|
1893
|
+
return;
|
|
1894
|
+
}
|
|
1895
|
+
for (const config2 of guideConfigs) {
|
|
1896
|
+
const guidePath = path10.join(this.guidesDir, config2.name);
|
|
1897
|
+
if (existsSync10(guidePath)) {
|
|
1898
|
+
try {
|
|
1899
|
+
const content = readFileSync3(guidePath, "utf-8");
|
|
1900
|
+
this.guides.push({
|
|
1901
|
+
name: config2.name,
|
|
1902
|
+
path: guidePath,
|
|
1903
|
+
content,
|
|
1904
|
+
category: config2.category,
|
|
1905
|
+
keywords: config2.keywords
|
|
1906
|
+
});
|
|
1907
|
+
} catch (error) {
|
|
1908
|
+
logger6.warn(`Failed to load migration guide: ${config2.name}`, error);
|
|
1909
|
+
}
|
|
1910
|
+
} else {
|
|
1911
|
+
logger6.warn(`Migration guide not found: ${guidePath}`);
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
logger6.info(`Loaded ${this.guides.length} migration guides from ${this.guidesDir}`);
|
|
1915
|
+
}
|
|
1916
|
+
createEmbeddedGuides(guideConfigs) {
|
|
1917
|
+
const embeddedGuides = {
|
|
1918
|
+
"migration-guide.md": this.getEmbeddedMigrationGuide(),
|
|
1919
|
+
"testing-guide.md": this.getEmbeddedTestingGuide(),
|
|
1920
|
+
"completion-requirements.md": this.getEmbeddedCompletionGuide()
|
|
1921
|
+
};
|
|
1922
|
+
for (const config2 of guideConfigs) {
|
|
1923
|
+
const embeddedContent = embeddedGuides[config2.name];
|
|
1924
|
+
if (embeddedContent) {
|
|
1925
|
+
this.guides.push({
|
|
1926
|
+
name: config2.name,
|
|
1927
|
+
path: `embedded:${config2.name}`,
|
|
1928
|
+
content: embeddedContent,
|
|
1929
|
+
category: config2.category,
|
|
1930
|
+
keywords: config2.keywords
|
|
1931
|
+
});
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
getEmbeddedMigrationGuide() {
|
|
1936
|
+
return `# ElizaOS Plugin Migration Guide - Essential Steps
|
|
1937
|
+
|
|
1938
|
+
## Core Migration Requirements
|
|
1939
|
+
|
|
1940
|
+
### 1. Import Path Updates
|
|
1941
|
+
- elizaLogger \u2192 logger
|
|
1942
|
+
- IAgentRuntime \u2192 AgentRuntime
|
|
1943
|
+
- Account \u2192 Entity
|
|
1944
|
+
- userId \u2192 entityId
|
|
1945
|
+
|
|
1946
|
+
### 2. Package.json Updates
|
|
1947
|
+
- Update to @elizaos/core ^1.0.0
|
|
1948
|
+
- Update scripts to use bun
|
|
1949
|
+
- Add proper exports and types
|
|
1950
|
+
|
|
1951
|
+
### 3. Action Migration
|
|
1952
|
+
- Replace composeContext with new patterns
|
|
1953
|
+
- Convert JSON templates to XML
|
|
1954
|
+
- Update generateObject to runtime.useModel
|
|
1955
|
+
- Fix handler patterns
|
|
1956
|
+
|
|
1957
|
+
### 4. Provider Migration
|
|
1958
|
+
- Add name property
|
|
1959
|
+
- Return ProviderResult
|
|
1960
|
+
- Make state parameter required
|
|
1961
|
+
|
|
1962
|
+
### 5. Testing Requirements
|
|
1963
|
+
- Use bun test framework
|
|
1964
|
+
- Achieve 95%+ coverage
|
|
1965
|
+
- Test all components thoroughly
|
|
1966
|
+
|
|
1967
|
+
For complete details, refer to the comprehensive guides in the ElizaOS documentation.`;
|
|
1968
|
+
}
|
|
1969
|
+
getEmbeddedTestingGuide() {
|
|
1970
|
+
return `# ElizaOS Testing Guide - Essential Requirements
|
|
1971
|
+
|
|
1972
|
+
## Test Framework
|
|
1973
|
+
- Use bun test (not vitest)
|
|
1974
|
+
- Achieve 95%+ code coverage
|
|
1975
|
+
- Test all actions, providers, evaluators
|
|
1976
|
+
|
|
1977
|
+
## Test Structure
|
|
1978
|
+
\`\`\`
|
|
1979
|
+
src/__tests__/
|
|
1980
|
+
\u251C\u2500\u2500 test-utils.ts
|
|
1981
|
+
\u251C\u2500\u2500 actions/
|
|
1982
|
+
\u251C\u2500\u2500 providers/
|
|
1983
|
+
\u2514\u2500\u2500 evaluators/
|
|
1984
|
+
\`\`\`
|
|
1985
|
+
|
|
1986
|
+
## Coverage Requirements
|
|
1987
|
+
- All components must be tested
|
|
1988
|
+
- Error cases must be covered
|
|
1989
|
+
- Edge cases must be handled
|
|
1990
|
+
- Integration tests required
|
|
1991
|
+
|
|
1992
|
+
## Common Issues
|
|
1993
|
+
- Mock all async dependencies
|
|
1994
|
+
- Clean up after each test
|
|
1995
|
+
- Use proper test isolation
|
|
1996
|
+
|
|
1997
|
+
Run: bun test --coverage`;
|
|
1998
|
+
}
|
|
1999
|
+
getEmbeddedCompletionGuide() {
|
|
2000
|
+
return `# ElizaOS Completion Requirements
|
|
2001
|
+
|
|
2002
|
+
## Required Files
|
|
2003
|
+
- .gitignore
|
|
2004
|
+
- .npmignore
|
|
2005
|
+
- LICENSE
|
|
2006
|
+
- .prettierrc
|
|
2007
|
+
- .github/workflows/npm-deploy.yml
|
|
2008
|
+
|
|
2009
|
+
## Final Validation
|
|
2010
|
+
\`\`\`bash
|
|
2011
|
+
bun run build # Must pass
|
|
2012
|
+
bun test # Must pass
|
|
2013
|
+
bunx tsc --noEmit # Must pass
|
|
2014
|
+
\`\`\`
|
|
2015
|
+
|
|
2016
|
+
## Package.json Requirements
|
|
2017
|
+
- Correct name format
|
|
2018
|
+
- Version 1.0.0
|
|
2019
|
+
- Proper exports
|
|
2020
|
+
- Build scripts
|
|
2021
|
+
- Test scripts
|
|
2022
|
+
|
|
2023
|
+
## Release Workflow
|
|
2024
|
+
- GitHub workflow for npm publish
|
|
2025
|
+
- Automated testing
|
|
2026
|
+
- Version management`;
|
|
2027
|
+
}
|
|
2028
|
+
/**
|
|
2029
|
+
* Search for relevant guides based on keywords or content
|
|
2030
|
+
*/
|
|
2031
|
+
searchGuides(query2, limit = 3) {
|
|
2032
|
+
const queryLower = query2.toLowerCase();
|
|
2033
|
+
const queryWords = queryLower.split(/\s+/).filter((word) => word.length > 2);
|
|
2034
|
+
const results = [];
|
|
2035
|
+
for (const guide of this.guides) {
|
|
2036
|
+
let relevanceScore = 0;
|
|
2037
|
+
const matchedKeywords = [];
|
|
2038
|
+
for (const keyword of guide.keywords) {
|
|
2039
|
+
if (queryWords.some((word) => keyword.toLowerCase().includes(word))) {
|
|
2040
|
+
relevanceScore += 2;
|
|
2041
|
+
matchedKeywords.push(keyword);
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
const contentLower = guide.content.toLowerCase();
|
|
2045
|
+
for (const word of queryWords) {
|
|
2046
|
+
const matches = (contentLower.match(new RegExp(word, "g")) || []).length;
|
|
2047
|
+
relevanceScore += matches * 0.5;
|
|
2048
|
+
}
|
|
2049
|
+
if (queryLower.includes("import") && guide.name === "migration-guide.md") {
|
|
2050
|
+
relevanceScore += 3;
|
|
2051
|
+
}
|
|
2052
|
+
if (queryLower.includes("test") && guide.name === "testing-guide.md") {
|
|
2053
|
+
relevanceScore += 3;
|
|
2054
|
+
}
|
|
2055
|
+
if (queryLower.includes("state") && guide.name === "state-and-providers-guide.md") {
|
|
2056
|
+
relevanceScore += 3;
|
|
2057
|
+
}
|
|
2058
|
+
if (relevanceScore > 0) {
|
|
2059
|
+
results.push({
|
|
2060
|
+
guide,
|
|
2061
|
+
relevanceScore,
|
|
2062
|
+
matchedKeywords
|
|
2063
|
+
});
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
return results.sort((a, b) => b.relevanceScore - a.relevanceScore).slice(0, limit);
|
|
2067
|
+
}
|
|
2068
|
+
/**
|
|
2069
|
+
* Get a specific guide by name
|
|
2070
|
+
*/
|
|
2071
|
+
getGuide(name) {
|
|
2072
|
+
return this.guides.find((guide) => guide.name === name) || null;
|
|
2073
|
+
}
|
|
2074
|
+
/**
|
|
2075
|
+
* Get all guides of a specific category
|
|
2076
|
+
*/
|
|
2077
|
+
getGuidesByCategory(category) {
|
|
2078
|
+
return this.guides.filter((guide) => guide.category === category);
|
|
2079
|
+
}
|
|
2080
|
+
/**
|
|
2081
|
+
* Get guides that are most relevant for common migration issues
|
|
2082
|
+
*/
|
|
2083
|
+
getRelevantGuidesForIssue(issue) {
|
|
2084
|
+
const issueMap = {
|
|
2085
|
+
import_error: ["import", "path", "elizaLogger", "logger"],
|
|
2086
|
+
build_error: ["build", "typescript", "package.json", "dependencies"],
|
|
2087
|
+
type_error: ["typescript", "type", "IAgentRuntime", "AgentRuntime"],
|
|
2088
|
+
action_migration: ["action", "composeContext", "generateObject", "handler"],
|
|
2089
|
+
provider_migration: ["provider", "ProviderResult", "state", "context"],
|
|
2090
|
+
test_failure: ["test", "coverage", "mock", "unit"],
|
|
2091
|
+
service_migration: ["service", "lifecycle", "initialize", "singleton"],
|
|
2092
|
+
template_migration: ["template", "XML", "JSON", "prompt"],
|
|
2093
|
+
release_setup: ["release", "workflow", "npm", "deploy"]
|
|
2094
|
+
};
|
|
2095
|
+
const keywords = issueMap[issue];
|
|
2096
|
+
if (!keywords) {
|
|
2097
|
+
return this.searchGuides(issue);
|
|
2098
|
+
}
|
|
2099
|
+
return this.searchGuides(keywords.join(" "));
|
|
2100
|
+
}
|
|
2101
|
+
/**
|
|
2102
|
+
* Generate a comprehensive migration context for Claude
|
|
2103
|
+
*/
|
|
2104
|
+
generateMigrationContext() {
|
|
2105
|
+
const context = [
|
|
2106
|
+
"# ELIZAOS PLUGIN MIGRATION GUIDE REFERENCES",
|
|
2107
|
+
"",
|
|
2108
|
+
"You have access to the following comprehensive migration guides:",
|
|
2109
|
+
""
|
|
2110
|
+
];
|
|
2111
|
+
for (const guide of this.guides) {
|
|
2112
|
+
context.push(`## ${guide.name.replace(".md", "").toUpperCase()}`);
|
|
2113
|
+
context.push(`Category: ${guide.category}`);
|
|
2114
|
+
context.push(`Keywords: ${guide.keywords.join(", ")}`);
|
|
2115
|
+
context.push("");
|
|
2116
|
+
const preview = guide.content.substring(0, 500).replace(/\n/g, " ");
|
|
2117
|
+
context.push(`Preview: ${preview}...`);
|
|
2118
|
+
context.push("");
|
|
2119
|
+
context.push("---");
|
|
2120
|
+
context.push("");
|
|
2121
|
+
}
|
|
2122
|
+
context.push("## GUIDE USAGE INSTRUCTIONS");
|
|
2123
|
+
context.push("");
|
|
2124
|
+
context.push("- Reference specific guides for detailed migration steps");
|
|
2125
|
+
context.push("- Use migration-guide.md for basic actions and providers");
|
|
2126
|
+
context.push("- Use advanced-migration-guide.md for services and evaluators");
|
|
2127
|
+
context.push("- Use testing-guide.md for comprehensive test coverage");
|
|
2128
|
+
context.push("- Use completion-requirements.md for final release preparation");
|
|
2129
|
+
context.push("");
|
|
2130
|
+
return context.join("\n");
|
|
2131
|
+
}
|
|
2132
|
+
/**
|
|
2133
|
+
* Get full content of all guides for RAG embedding
|
|
2134
|
+
*/
|
|
2135
|
+
getAllGuidesContent() {
|
|
2136
|
+
const content = [
|
|
2137
|
+
"# COMPLETE ELIZAOS MIGRATION KNOWLEDGE BASE",
|
|
2138
|
+
"",
|
|
2139
|
+
"This contains all migration guides and their complete content for reference.",
|
|
2140
|
+
""
|
|
2141
|
+
];
|
|
2142
|
+
for (const guide of this.guides) {
|
|
2143
|
+
content.push(`# GUIDE: ${guide.name}`);
|
|
2144
|
+
content.push(`Category: ${guide.category}`);
|
|
2145
|
+
content.push(`Keywords: ${guide.keywords.join(", ")}`);
|
|
2146
|
+
content.push("");
|
|
2147
|
+
content.push("## CONTENT:");
|
|
2148
|
+
content.push("");
|
|
2149
|
+
content.push(guide.content);
|
|
2150
|
+
content.push("");
|
|
2151
|
+
content.push("---");
|
|
2152
|
+
content.push("");
|
|
2153
|
+
}
|
|
2154
|
+
return content.join("\n");
|
|
2155
|
+
}
|
|
2156
|
+
};
|
|
2157
|
+
function createMigrationGuideLoader(projectRoot) {
|
|
2158
|
+
return new MigrationGuideLoader(projectRoot);
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
// src/utils/upgrade/simple-migration-agent.ts
|
|
2162
|
+
import { logger as logger7 } from "@elizaos/core";
|
|
2163
|
+
var SimpleMigrationAgent = class extends EventEmitter {
|
|
2164
|
+
repoPath;
|
|
2165
|
+
abortController;
|
|
2166
|
+
verbose;
|
|
2167
|
+
guideLoader;
|
|
2168
|
+
spinnerInterval = null;
|
|
2169
|
+
spinnerFrame = 0;
|
|
2170
|
+
spinnerFrames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
2171
|
+
// Token and cost tracking
|
|
2172
|
+
totalInputTokens = 0;
|
|
2173
|
+
totalOutputTokens = 0;
|
|
2174
|
+
totalCost = 0;
|
|
2175
|
+
lastTokenUpdate = Date.now();
|
|
2176
|
+
lastCostSummary = Date.now();
|
|
2177
|
+
constructor(repoPath, options = {}) {
|
|
2178
|
+
super();
|
|
2179
|
+
this.repoPath = repoPath;
|
|
2180
|
+
this.abortController = new AbortController();
|
|
2181
|
+
this.verbose = options.verbose || false;
|
|
2182
|
+
try {
|
|
2183
|
+
this.guideLoader = createMigrationGuideLoader();
|
|
2184
|
+
if (this.verbose) {
|
|
2185
|
+
logger7.info("Migration guide loader initialized successfully");
|
|
2186
|
+
}
|
|
2187
|
+
} catch (error) {
|
|
2188
|
+
logger7.warn("Failed to initialize migration guide loader", error);
|
|
2189
|
+
throw new Error("Cannot initialize migration system without guide access");
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
isImportantUpdate(text3) {
|
|
2193
|
+
const importantPatterns = [
|
|
2194
|
+
/GATE \d+/i,
|
|
2195
|
+
/analysis/i,
|
|
2196
|
+
/migration/i,
|
|
2197
|
+
/complete/i,
|
|
2198
|
+
/success/i,
|
|
2199
|
+
/error/i,
|
|
2200
|
+
/building/i,
|
|
2201
|
+
/testing/i,
|
|
2202
|
+
/upgrading/i,
|
|
2203
|
+
/validating/i,
|
|
2204
|
+
/fixing/i,
|
|
2205
|
+
/installing/i,
|
|
2206
|
+
/processing/i,
|
|
2207
|
+
/checking/i,
|
|
2208
|
+
/updating/i,
|
|
2209
|
+
/✓|✗|🎉|🚀|📊|⚡|🔍|🔨|🧪|📝|📖|✏️|📄/,
|
|
2210
|
+
/^(Starting|Finishing|Completed)/i,
|
|
2211
|
+
/^[A-Z][a-z]+ (plugin|package|file|test)/i
|
|
2212
|
+
// Actions on specific items
|
|
2213
|
+
];
|
|
2214
|
+
return importantPatterns.some((pattern) => pattern.test(text3)) && text3.length < 300;
|
|
2215
|
+
}
|
|
2216
|
+
formatProgressUpdate(text3) {
|
|
2217
|
+
text3 = text3.trim();
|
|
2218
|
+
const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
|
|
2219
|
+
hour12: false,
|
|
2220
|
+
hour: "2-digit",
|
|
2221
|
+
minute: "2-digit",
|
|
2222
|
+
second: "2-digit"
|
|
2223
|
+
});
|
|
2224
|
+
if (text3.includes("GATE")) {
|
|
2225
|
+
return `
|
|
2226
|
+
\u{1F3AF} [${timestamp}] ${text3}`;
|
|
2227
|
+
} else if (text3.includes("complete") || text3.includes("\u2713") || text3.includes("success")) {
|
|
2228
|
+
return `\u2705 [${timestamp}] ${text3}`;
|
|
2229
|
+
} else if (text3.includes("error") || text3.includes("\u2717") || text3.includes("failed")) {
|
|
2230
|
+
return `\u274C [${timestamp}] ${text3}`;
|
|
2231
|
+
} else if (text3.includes("analyzing") || text3.includes("analysis")) {
|
|
2232
|
+
return `\u{1F50D} [${timestamp}] ${text3}`;
|
|
2233
|
+
} else if (text3.includes("migrating") || text3.includes("migration") || text3.includes("upgrading")) {
|
|
2234
|
+
return `\u{1F504} [${timestamp}] ${text3}`;
|
|
2235
|
+
} else if (text3.includes("building") || text3.includes("compile")) {
|
|
2236
|
+
return `\u{1F528} [${timestamp}] ${text3}`;
|
|
2237
|
+
} else if (text3.includes("testing") || text3.includes("test")) {
|
|
2238
|
+
return `\u{1F9EA} [${timestamp}] ${text3}`;
|
|
2239
|
+
} else if (text3.includes("installing") || text3.includes("install")) {
|
|
2240
|
+
return `\u{1F4E6} [${timestamp}] ${text3}`;
|
|
2241
|
+
} else if (text3.includes("validating") || text3.includes("validation")) {
|
|
2242
|
+
return `\u2714\uFE0F [${timestamp}] ${text3}`;
|
|
2243
|
+
} else if (text3.includes("fixing") || text3.includes("fix")) {
|
|
2244
|
+
return `\u{1F527} [${timestamp}] ${text3}`;
|
|
2245
|
+
} else if (text3.includes("Starting") || text3.includes("Initializing")) {
|
|
2246
|
+
return `\u{1F680} [${timestamp}] ${text3}`;
|
|
2247
|
+
} else if (text3.includes("Finishing") || text3.includes("Completed")) {
|
|
2248
|
+
return `\u{1F3C1} [${timestamp}] ${text3}`;
|
|
2249
|
+
}
|
|
2250
|
+
return `\u{1F4AD} [${timestamp}] ${text3}`;
|
|
2251
|
+
}
|
|
2252
|
+
startSpinner(message) {
|
|
2253
|
+
if (this.spinnerInterval) {
|
|
2254
|
+
this.stopSpinner();
|
|
2255
|
+
}
|
|
2256
|
+
process.stdout.write(`${message} `);
|
|
2257
|
+
this.spinnerInterval = setInterval(() => {
|
|
2258
|
+
process.stdout.write(`\r${message} ${this.spinnerFrames[this.spinnerFrame]}`);
|
|
2259
|
+
this.spinnerFrame = (this.spinnerFrame + 1) % this.spinnerFrames.length;
|
|
2260
|
+
}, 100);
|
|
2261
|
+
}
|
|
2262
|
+
stopSpinner(completionMessage) {
|
|
2263
|
+
if (this.spinnerInterval) {
|
|
2264
|
+
clearInterval(this.spinnerInterval);
|
|
2265
|
+
this.spinnerInterval = null;
|
|
2266
|
+
if (completionMessage) {
|
|
2267
|
+
process.stdout.write(`\r${completionMessage}
|
|
2268
|
+
`);
|
|
2269
|
+
} else {
|
|
2270
|
+
process.stdout.write("\r");
|
|
2271
|
+
process.stdout.clearLine(0);
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
updateTokenTracking(usage) {
|
|
2276
|
+
if (usage.input_tokens) {
|
|
2277
|
+
this.totalInputTokens += usage.input_tokens;
|
|
2278
|
+
}
|
|
2279
|
+
if (usage.output_tokens) {
|
|
2280
|
+
this.totalOutputTokens += usage.output_tokens;
|
|
2281
|
+
}
|
|
2282
|
+
const inputCostPer1k = 3e-3;
|
|
2283
|
+
const outputCostPer1k = 0.015;
|
|
2284
|
+
if (usage.input_tokens) {
|
|
2285
|
+
this.totalCost += usage.input_tokens / 1e3 * inputCostPer1k;
|
|
2286
|
+
}
|
|
2287
|
+
if (usage.output_tokens) {
|
|
2288
|
+
this.totalCost += usage.output_tokens / 1e3 * outputCostPer1k;
|
|
2289
|
+
}
|
|
2290
|
+
this.lastTokenUpdate = Date.now();
|
|
2291
|
+
}
|
|
2292
|
+
formatTokenDisplay() {
|
|
2293
|
+
if (this.totalInputTokens === 0 && this.totalOutputTokens === 0) {
|
|
2294
|
+
return "";
|
|
2295
|
+
}
|
|
2296
|
+
const totalTokens = this.totalInputTokens + this.totalOutputTokens;
|
|
2297
|
+
const costDisplay = this.totalCost > 0 ? ` ($${this.totalCost.toFixed(4)})` : "";
|
|
2298
|
+
return ` | \u{1F3A9} ${totalTokens.toLocaleString()} tokens${costDisplay}`;
|
|
2299
|
+
}
|
|
2300
|
+
getSimplifiedToolName(toolName) {
|
|
2301
|
+
const toolMap = {
|
|
2302
|
+
TodoWrite: "\u{1F4DD} Planning",
|
|
2303
|
+
TodoRead: "\u{1F4CB} Checking",
|
|
2304
|
+
Bash: "\u26A1 Running",
|
|
2305
|
+
Read: "\u{1F4D6} Reading",
|
|
2306
|
+
Edit: "\u270F\uFE0F Editing",
|
|
2307
|
+
MultiEdit: "\u{1F4DD} Batch editing",
|
|
2308
|
+
Write: "\u{1F4C4} Writing",
|
|
2309
|
+
LS: "\u{1F50D} Exploring",
|
|
2310
|
+
Glob: "\u{1F50E} Pattern matching",
|
|
2311
|
+
Grep: "\u{1F50D} Searching",
|
|
2312
|
+
Task: "\u{1F527} Processing",
|
|
2313
|
+
WebFetch: "\u{1F310} Fetching",
|
|
2314
|
+
WebSearch: "\u{1F50D} Web searching",
|
|
2315
|
+
NotebookRead: "\u{1F4D3} Notebook reading",
|
|
2316
|
+
NotebookEdit: "\u{1F4DD} Notebook editing"
|
|
2317
|
+
};
|
|
2318
|
+
return toolMap[toolName] || `\u{1F6E0}\uFE0F ${toolName}`;
|
|
2319
|
+
}
|
|
2320
|
+
async migrate() {
|
|
2321
|
+
const startTime = Date.now();
|
|
2322
|
+
let messageCount = 0;
|
|
2323
|
+
try {
|
|
2324
|
+
process.env.CLAUDE_CODE_ENABLE_TELEMETRY = "0";
|
|
2325
|
+
process.env.OTEL_LOGS_EXPORTER = "";
|
|
2326
|
+
process.env.OTEL_LOG_USER_PROMPTS = "0";
|
|
2327
|
+
process.env.OTEL_METRICS_EXPORTER = "";
|
|
2328
|
+
console.log("Claude is analyzing and migrating your plugin...\n");
|
|
2329
|
+
this.emit("start");
|
|
2330
|
+
this.startSpinner("\u{1F50E} Initializing Claude Code SDK...");
|
|
2331
|
+
console.log(`Starting migration in directory: ${this.repoPath}`);
|
|
2332
|
+
const migrationContext = this.guideLoader.getAllGuidesContent();
|
|
2333
|
+
const guideReferences = this.guideLoader.generateMigrationContext();
|
|
2334
|
+
const migrationPrompt = `You are about to help migrate an ElizaOS plugin from 0.x to 1.x format.
|
|
2335
|
+
|
|
2336
|
+
CRITICAL: You must follow the INTEGRATED EXECUTION PROTOCOL exactly as specified in the CLAUDE.md file.
|
|
2337
|
+
|
|
2338
|
+
This is a GATED PROCESS with 9 gates (0-8). You CANNOT skip steps.
|
|
2339
|
+
|
|
2340
|
+
COMPREHENSIVE MIGRATION KNOWLEDGE BASE:
|
|
2341
|
+
${migrationContext}
|
|
2342
|
+
|
|
2343
|
+
GUIDE REFERENCE SYSTEM:
|
|
2344
|
+
${guideReferences}
|
|
2345
|
+
|
|
2346
|
+
REFERENCE GUIDES are in migration-guides/ directory:
|
|
2347
|
+
- migration-guide.md (basic migration steps)
|
|
2348
|
+
- state-and-providers-guide.md (state & providers migration)
|
|
2349
|
+
- prompt-and-generation-guide.md (templates & generation)
|
|
2350
|
+
- advanced-migration-guide.md (services, settings, evaluators)
|
|
2351
|
+
- testing-guide.md (comprehensive testing requirements)
|
|
2352
|
+
- completion-requirements.md (final validation and release preparation)
|
|
2353
|
+
|
|
2354
|
+
ENHANCED RAG CAPABILITIES:
|
|
2355
|
+
You have access to the complete content of all migration guides above. Use this knowledge to:
|
|
2356
|
+
1. Provide specific, detailed migration steps
|
|
2357
|
+
2. Reference exact sections from the appropriate guides
|
|
2358
|
+
3. Troubleshoot specific issues with targeted solutions
|
|
2359
|
+
4. Ensure comprehensive coverage of all migration requirements
|
|
2360
|
+
|
|
2361
|
+
CRITICAL TEST VALIDATION REQUIREMENTS - ABSOLUTE REQUIREMENTS
|
|
2362
|
+
|
|
2363
|
+
MIGRATION CANNOT BE COMPLETED UNTIL ALL TESTS PASS
|
|
2364
|
+
|
|
2365
|
+
Throughout the migration process, you MUST validate these requirements and loop until they pass:
|
|
2366
|
+
|
|
2367
|
+
1. MANDATORY TEST VALIDATION LOOP: After every significant code change, run:
|
|
2368
|
+
- bun run test - ALL tests must pass (100% success rate, ZERO failures)
|
|
2369
|
+
- bunx tsc --noEmit - ZERO TypeScript errors in src/ directory
|
|
2370
|
+
- Only test files can have type errors, src/ must be error-free
|
|
2371
|
+
|
|
2372
|
+
2. CONTINUOUS VALIDATION LOOP: If ANY of these fail:
|
|
2373
|
+
- Analyze the errors thoroughly
|
|
2374
|
+
- Fix all issues identified
|
|
2375
|
+
- Re-run the validation commands
|
|
2376
|
+
- Repeat until BOTH commands succeed with zero errors
|
|
2377
|
+
- DO NOT PROCEED until validation passes
|
|
2378
|
+
|
|
2379
|
+
3. COVERAGE VS TEST CONFLICTS: If tests conflict with 95% coverage requirements:
|
|
2380
|
+
- Prioritize making tests pass over coverage percentage
|
|
2381
|
+
- Use workarounds like test mocks, stubs, or simplified implementations
|
|
2382
|
+
- Lower coverage if necessary - tests passing is more important
|
|
2383
|
+
- Add // @ts-ignore comments if needed for test compatibility
|
|
2384
|
+
|
|
2385
|
+
4. RELEASE WORKFLOW REQUIREMENT: The .github/workflows/release.yml requires bun run test to pass before npm publish. Migration is NOT complete until all tests pass.
|
|
2386
|
+
|
|
2387
|
+
5. ABSOLUTE REQUIREMENTS - NO EXCEPTIONS:
|
|
2388
|
+
- bun run test MUST show 0 failing tests
|
|
2389
|
+
- If ANY test fails, the migration is INCOMPLETE
|
|
2390
|
+
- Do not declare success until bun run test passes completely
|
|
2391
|
+
- Work around any test issues rather than leaving them failing
|
|
2392
|
+
|
|
2393
|
+
START WITH GATE 0: Create 1.x branch
|
|
2394
|
+
Execute: git checkout -b 1.x
|
|
2395
|
+
Gate Check: git branch --show-current must output "1.x"
|
|
2396
|
+
|
|
2397
|
+
THEN GATE 1: Complete analysis following the exact format in the integrated-migration-loop.md
|
|
2398
|
+
|
|
2399
|
+
DO NOT PROCEED until each gate check passes AND all validation requirements are met.
|
|
2400
|
+
|
|
2401
|
+
Remember: You must grind on test failures and TypeScript errors until they are 100% resolved. The release workflow will fail if tests don't pass.
|
|
2402
|
+
|
|
2403
|
+
FINAL VALIDATION REQUIREMENTS (GATE 8+) - ABSOLUTELY MANDATORY
|
|
2404
|
+
|
|
2405
|
+
THE MIGRATION IS NOT COMPLETE UNTIL EVERY SINGLE TEST PASSES
|
|
2406
|
+
|
|
2407
|
+
After completing all 9 gates, you MUST perform final validation and loop until both pass:
|
|
2408
|
+
|
|
2409
|
+
FINAL VALIDATION LOOP - REPEAT UNTIL SUCCESS:
|
|
2410
|
+
1. Run: bun run test
|
|
2411
|
+
- MUST pass 100% - this is required for npm release workflow
|
|
2412
|
+
- If ANY tests fail, analyze and fix them, then retry
|
|
2413
|
+
- Use workarounds, mocks, simplified implementations if needed
|
|
2414
|
+
- Lower coverage requirements if tests conflict with coverage
|
|
2415
|
+
- Do NOT declare migration complete until this shows ZERO failures
|
|
2416
|
+
|
|
2417
|
+
2. Run: bunx tsc --noEmit
|
|
2418
|
+
- MUST have ZERO errors in src/ directory
|
|
2419
|
+
- Test files can have type errors as exception, but fix if possible
|
|
2420
|
+
- If any src/ errors exist, fix them and retry
|
|
2421
|
+
|
|
2422
|
+
3. REPEAT FINAL VALIDATION LOOP until both commands succeed with zero errors
|
|
2423
|
+
- Keep trying different approaches
|
|
2424
|
+
- Simplify tests if needed
|
|
2425
|
+
- Use test mocks and stubs
|
|
2426
|
+
- Do whatever it takes to make tests pass
|
|
2427
|
+
|
|
2428
|
+
4. Only AFTER both final validations pass with ZERO failures, declare migration complete
|
|
2429
|
+
|
|
2430
|
+
ABSOLUTE REQUIREMENT: The migration is NOT complete until bun run test shows zero failures. The release workflow will fail otherwise. NO EXCEPTIONS.`;
|
|
2431
|
+
let queryGenerator;
|
|
2432
|
+
try {
|
|
2433
|
+
queryGenerator = query({
|
|
2434
|
+
prompt: migrationPrompt,
|
|
2435
|
+
abortController: this.abortController,
|
|
2436
|
+
options: {
|
|
2437
|
+
cwd: this.repoPath,
|
|
2438
|
+
model: "opus",
|
|
2439
|
+
permissionMode: "bypassPermissions"
|
|
2440
|
+
}
|
|
2441
|
+
});
|
|
2442
|
+
} catch (queryError) {
|
|
2443
|
+
const errorMessage = queryError instanceof Error ? queryError.message : String(queryError);
|
|
2444
|
+
throw new Error(`Failed to initialize Claude Code SDK query: ${errorMessage}`);
|
|
2445
|
+
}
|
|
2446
|
+
let currentToolName = null;
|
|
2447
|
+
let toolStartTime = null;
|
|
2448
|
+
let lastProgressUpdate = Date.now();
|
|
2449
|
+
for await (const message of queryGenerator) {
|
|
2450
|
+
messageCount++;
|
|
2451
|
+
try {
|
|
2452
|
+
if (message.type === "assistant") {
|
|
2453
|
+
if (message.message && message.message.content) {
|
|
2454
|
+
const content = message.message.content;
|
|
2455
|
+
if (Array.isArray(content)) {
|
|
2456
|
+
for (const block of content) {
|
|
2457
|
+
if (block.type === "text") {
|
|
2458
|
+
const text3 = block.text;
|
|
2459
|
+
if (this.isImportantUpdate(text3)) {
|
|
2460
|
+
if (currentToolName) {
|
|
2461
|
+
process.stdout.write(" \u2713\n");
|
|
2462
|
+
currentToolName = null;
|
|
2463
|
+
}
|
|
2464
|
+
let formattedText = this.formatProgressUpdate(text3);
|
|
2465
|
+
if (text3.includes("GATE") && (this.totalInputTokens > 0 || this.totalOutputTokens > 0)) {
|
|
2466
|
+
const tokenInfo = this.formatTokenDisplay();
|
|
2467
|
+
formattedText += tokenInfo;
|
|
2468
|
+
}
|
|
2469
|
+
console.log(formattedText);
|
|
2470
|
+
} else if (this.verbose && text3.length > 10 && text3.length < 100) {
|
|
2471
|
+
console.log(`\u{1F4AC} ${text3.trim()}`);
|
|
2472
|
+
}
|
|
2473
|
+
} else if (block.type === "tool_use") {
|
|
2474
|
+
const toolName = this.getSimplifiedToolName(block.name);
|
|
2475
|
+
if (toolName) {
|
|
2476
|
+
if (currentToolName) {
|
|
2477
|
+
const duration = toolStartTime ? Date.now() - toolStartTime : 0;
|
|
2478
|
+
process.stdout.write(` \u2713 (${Math.round(duration / 1e3)}s)
|
|
2479
|
+
`);
|
|
2480
|
+
}
|
|
2481
|
+
process.stdout.write(`${toolName}...`);
|
|
2482
|
+
currentToolName = toolName;
|
|
2483
|
+
toolStartTime = Date.now();
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
} else if (typeof content === "string") {
|
|
2488
|
+
if (this.isImportantUpdate(content)) {
|
|
2489
|
+
if (currentToolName) {
|
|
2490
|
+
process.stdout.write(" \u2713\n");
|
|
2491
|
+
currentToolName = null;
|
|
2492
|
+
}
|
|
2493
|
+
console.log(this.formatProgressUpdate(content));
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
if ("type" in message && message.type === "tool_result") {
|
|
2499
|
+
if (currentToolName) {
|
|
2500
|
+
const duration = toolStartTime ? Date.now() - toolStartTime : 0;
|
|
2501
|
+
process.stdout.write(` \u2713 (${Math.round(duration / 1e3)}s)
|
|
2502
|
+
`);
|
|
2503
|
+
currentToolName = null;
|
|
2504
|
+
toolStartTime = null;
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2507
|
+
if (message.type === "result") {
|
|
2508
|
+
if (currentToolName) {
|
|
2509
|
+
process.stdout.write(" \u2713\n");
|
|
2510
|
+
currentToolName = null;
|
|
2511
|
+
}
|
|
2512
|
+
console.log(`
|
|
2513
|
+
|
|
2514
|
+
\u{1F4CA} Migration Summary:`);
|
|
2515
|
+
console.log(`\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
|
|
2516
|
+
console.log(`Status: ${message.subtype === "success" ? "\u2705 Completed" : "\u274C Failed"}`);
|
|
2517
|
+
const finalCost = message.total_cost_usd || this.totalCost;
|
|
2518
|
+
if (finalCost > 0) {
|
|
2519
|
+
console.log(`\u{1F4B0} Total Cost: $${finalCost.toFixed(4)}`);
|
|
2520
|
+
}
|
|
2521
|
+
if (this.totalInputTokens > 0 || this.totalOutputTokens > 0) {
|
|
2522
|
+
console.log(
|
|
2523
|
+
`\u{1F3A9} Token Usage: \u2192${this.totalInputTokens.toLocaleString()} in, \u2190${this.totalOutputTokens.toLocaleString()} out (${(this.totalInputTokens + this.totalOutputTokens).toLocaleString()} total)`
|
|
2524
|
+
);
|
|
2525
|
+
}
|
|
2526
|
+
if (message.duration_ms)
|
|
2527
|
+
console.log(`\u23F1\uFE0F Duration: ${Math.round(message.duration_ms / 1e3)}s`);
|
|
2528
|
+
if (message.num_turns) console.log(`\u{1F916} AI Operations: ${message.num_turns}`);
|
|
2529
|
+
console.log(`\u{1F4EC} Total Messages: ${messageCount}`);
|
|
2530
|
+
console.log("");
|
|
2531
|
+
}
|
|
2532
|
+
if (message.type === "system" && message.subtype === "init") {
|
|
2533
|
+
this.stopSpinner("\u{1F680} Migration session started");
|
|
2534
|
+
console.log("");
|
|
2535
|
+
}
|
|
2536
|
+
} catch (messageError) {
|
|
2537
|
+
if (this.verbose) {
|
|
2538
|
+
const errorMessage = messageError instanceof Error ? messageError.message : String(messageError);
|
|
2539
|
+
console.log(`
|
|
2540
|
+
\u26A0\uFE0F Message processing error: ${errorMessage}`);
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
const now = Date.now();
|
|
2544
|
+
if (messageCount % 15 === 0 && now - lastProgressUpdate > 5e3) {
|
|
2545
|
+
if (currentToolName) {
|
|
2546
|
+
process.stdout.write("\n");
|
|
2547
|
+
}
|
|
2548
|
+
const tokenInfo = this.formatTokenDisplay();
|
|
2549
|
+
console.log(
|
|
2550
|
+
`
|
|
2551
|
+
\u23F3 Processing... (${messageCount} operations, ${Math.round((now - startTime) / 1e3)}s elapsed${tokenInfo})
|
|
2552
|
+
`
|
|
2553
|
+
);
|
|
2554
|
+
this.emit("progress", messageCount);
|
|
2555
|
+
lastProgressUpdate = now;
|
|
2556
|
+
if (currentToolName) {
|
|
2557
|
+
process.stdout.write(`${currentToolName}...`);
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
if (message.type === "assistant" && "usage" in message) {
|
|
2561
|
+
this.updateTokenTracking(message.usage);
|
|
2562
|
+
const timeSinceCostSummary = now - this.lastCostSummary;
|
|
2563
|
+
if (timeSinceCostSummary > 3e4 && this.totalInputTokens > 0) {
|
|
2564
|
+
if (currentToolName) {
|
|
2565
|
+
process.stdout.write("\n");
|
|
2566
|
+
}
|
|
2567
|
+
console.log(
|
|
2568
|
+
`\u{1F4B0} Cost Update: $${this.totalCost.toFixed(4)} | \u{1F3A9} ${(this.totalInputTokens + this.totalOutputTokens).toLocaleString()} tokens used`
|
|
2569
|
+
);
|
|
2570
|
+
this.lastCostSummary = now;
|
|
2571
|
+
if (currentToolName) {
|
|
2572
|
+
process.stdout.write(`${currentToolName}...`);
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
this.stopSpinner();
|
|
2578
|
+
if (currentToolName) {
|
|
2579
|
+
process.stdout.write(" \u2713\n");
|
|
2580
|
+
}
|
|
2581
|
+
console.log("\n\u{1F389} Migration completed successfully!");
|
|
2582
|
+
console.log(`\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
|
|
2583
|
+
const guidesUsed = this.guideLoader.getGuidesByCategory("basic").concat(this.guideLoader.getGuidesByCategory("advanced")).concat(this.guideLoader.getGuidesByCategory("testing")).concat(this.guideLoader.getGuidesByCategory("completion")).map((guide) => guide.name);
|
|
2584
|
+
return {
|
|
2585
|
+
success: true,
|
|
2586
|
+
repoPath: this.repoPath,
|
|
2587
|
+
duration: Date.now() - startTime,
|
|
2588
|
+
messageCount,
|
|
2589
|
+
guidesUsed
|
|
2590
|
+
};
|
|
2591
|
+
} catch (error) {
|
|
2592
|
+
console.log("\n\u274C Migration failed");
|
|
2593
|
+
console.log(`\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
|
|
2594
|
+
if (error instanceof Error) {
|
|
2595
|
+
console.log(`\u{1F4DC} Error Type: ${error.name}`);
|
|
2596
|
+
console.log(`\u{1F4AC} Error Message: ${error.message}`);
|
|
2597
|
+
if (error.message.includes("API key")) {
|
|
2598
|
+
console.log("\n\u{1F511} API Key Issue Detected:");
|
|
2599
|
+
console.log(" \u2022 Verify ANTHROPIC_API_KEY is set correctly");
|
|
2600
|
+
console.log(' \u2022 Ensure the key starts with "sk-ant-"');
|
|
2601
|
+
console.log(" \u2022 Check your key has sufficient credits");
|
|
2602
|
+
} else if (error.message.includes("timeout") || error.message.includes("network")) {
|
|
2603
|
+
console.log("\n\u{1F310} Network Issue Detected:");
|
|
2604
|
+
console.log(" \u2022 Check your internet connection");
|
|
2605
|
+
console.log(" \u2022 Try again in a few moments");
|
|
2606
|
+
console.log(" \u2022 Consider using --timeout option for slower connections");
|
|
2607
|
+
} else if (error.message.includes("permission") || error.message.includes("access")) {
|
|
2608
|
+
console.log("\n\u{1F512} Permission Issue Detected:");
|
|
2609
|
+
console.log(" \u2022 Ensure you have write access to the plugin directory");
|
|
2610
|
+
console.log(" \u2022 Check file permissions");
|
|
2611
|
+
console.log(" \u2022 Try running from a directory you own");
|
|
2612
|
+
}
|
|
2613
|
+
if (this.verbose) {
|
|
2614
|
+
console.log(`
|
|
2615
|
+
\u{1F50E} Full Stack Trace:`);
|
|
2616
|
+
console.log(error.stack || "No stack trace available");
|
|
2617
|
+
}
|
|
2618
|
+
} else {
|
|
2619
|
+
console.log(`\u{1F4AC} Error Details:`, error);
|
|
2620
|
+
}
|
|
2621
|
+
console.log("\n\u{1F527} Recovery Options:");
|
|
2622
|
+
console.log(" 1. Check git status and stash/commit changes if needed");
|
|
2623
|
+
console.log(" 2. Verify plugin structure follows ElizaOS standards");
|
|
2624
|
+
console.log(" 3. Try running with --verbose for detailed output");
|
|
2625
|
+
console.log(" 4. Check network connectivity and API key validity");
|
|
2626
|
+
console.log(' 5. Ensure all dependencies are installed with "bun install"');
|
|
2627
|
+
return {
|
|
2628
|
+
success: false,
|
|
2629
|
+
repoPath: this.repoPath,
|
|
2630
|
+
duration: Date.now() - startTime,
|
|
2631
|
+
messageCount,
|
|
2632
|
+
error
|
|
2633
|
+
};
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
abort() {
|
|
2637
|
+
this.stopSpinner();
|
|
2638
|
+
console.log("\n\u2639\uFE0F Migration aborted by user");
|
|
2639
|
+
if (this.totalInputTokens > 0 || this.totalOutputTokens > 0) {
|
|
2640
|
+
console.log(
|
|
2641
|
+
`\u{1F4B0} Partial cost: $${this.totalCost.toFixed(4)} | \u{1F3A9} ${(this.totalInputTokens + this.totalOutputTokens).toLocaleString()} tokens used`
|
|
2642
|
+
);
|
|
2643
|
+
}
|
|
2644
|
+
console.log(`\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
|
|
2645
|
+
console.log("\u{1F5FA}\uFE0F What happened:");
|
|
2646
|
+
console.log(" \u2022 Migration process was interrupted");
|
|
2647
|
+
console.log(" \u2022 Plugin files may be in partial state");
|
|
2648
|
+
console.log(" \u2022 Some changes may have been applied");
|
|
2649
|
+
console.log("\n\u{1F527} Recommended next steps:");
|
|
2650
|
+
console.log(" 1. Check git status to see what changed");
|
|
2651
|
+
console.log(' 2. Use "git checkout ." to revert uncommitted changes if needed');
|
|
2652
|
+
console.log(" 3. Review any migration-guides/ directory that may have been created");
|
|
2653
|
+
console.log(' 4. Clean up with "rm -rf migration-guides/" if present');
|
|
2654
|
+
console.log(" 5. Try migration again when ready");
|
|
2655
|
+
this.abortController.abort();
|
|
2656
|
+
this.emit("aborted");
|
|
2657
|
+
}
|
|
2658
|
+
/**
|
|
2659
|
+
* Get migration help for specific issues
|
|
2660
|
+
*/
|
|
2661
|
+
getMigrationHelp(issue) {
|
|
2662
|
+
try {
|
|
2663
|
+
const results = this.guideLoader.getRelevantGuidesForIssue(issue);
|
|
2664
|
+
if (results.length === 0) {
|
|
2665
|
+
return `No specific guidance found for: ${issue}
|
|
2666
|
+
Check the basic migration-guide.md for general steps.`;
|
|
2667
|
+
}
|
|
2668
|
+
const help = [
|
|
2669
|
+
`MIGRATION GUIDANCE FOR: ${issue.toUpperCase()}`,
|
|
2670
|
+
"",
|
|
2671
|
+
"Relevant guides found:",
|
|
2672
|
+
""
|
|
2673
|
+
];
|
|
2674
|
+
for (const result of results) {
|
|
2675
|
+
help.push(`## ${result.guide.name}`);
|
|
2676
|
+
help.push(`Relevance Score: ${result.relevanceScore.toFixed(1)}`);
|
|
2677
|
+
help.push(`Matched Keywords: ${result.matchedKeywords.join(", ")}`);
|
|
2678
|
+
help.push(`Category: ${result.guide.category}`);
|
|
2679
|
+
help.push("");
|
|
2680
|
+
}
|
|
2681
|
+
return help.join("\n");
|
|
2682
|
+
} catch (error) {
|
|
2683
|
+
return `Error getting migration help: ${error instanceof Error ? error.message : String(error)}`;
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
/**
|
|
2687
|
+
* Search guides for specific content
|
|
2688
|
+
*/
|
|
2689
|
+
searchGuides(query2, limit = 3) {
|
|
2690
|
+
try {
|
|
2691
|
+
const results = this.guideLoader.searchGuides(query2, limit);
|
|
2692
|
+
if (results.length === 0) {
|
|
2693
|
+
return `No guides found matching: ${query2}`;
|
|
2694
|
+
}
|
|
2695
|
+
const searchResults = [
|
|
2696
|
+
`SEARCH RESULTS FOR: ${query2}`,
|
|
2697
|
+
"",
|
|
2698
|
+
`Found ${results.length} relevant guide(s):`,
|
|
2699
|
+
""
|
|
2700
|
+
];
|
|
2701
|
+
for (const result of results) {
|
|
2702
|
+
searchResults.push(`## ${result.guide.name}`);
|
|
2703
|
+
searchResults.push(`Score: ${result.relevanceScore.toFixed(1)}`);
|
|
2704
|
+
searchResults.push(`Keywords: ${result.matchedKeywords.join(", ")}`);
|
|
2705
|
+
searchResults.push(`Path: ${result.guide.path}`);
|
|
2706
|
+
searchResults.push("");
|
|
2707
|
+
}
|
|
2708
|
+
return searchResults.join("\n");
|
|
2709
|
+
} catch (error) {
|
|
2710
|
+
return `Error searching guides: ${error instanceof Error ? error.message : String(error)}`;
|
|
2711
|
+
}
|
|
2712
|
+
}
|
|
2713
|
+
/**
|
|
2714
|
+
* Get complete migration context for debugging
|
|
2715
|
+
*/
|
|
2716
|
+
getFullMigrationContext() {
|
|
2717
|
+
try {
|
|
2718
|
+
return this.guideLoader.getAllGuidesContent();
|
|
2719
|
+
} catch (error) {
|
|
2720
|
+
return `Error getting migration context: ${error instanceof Error ? error.message : String(error)}`;
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
};
|
|
2724
|
+
|
|
2725
|
+
// src/commands/plugins/actions/upgrade.ts
|
|
2726
|
+
import chalk from "chalk";
|
|
1571
2727
|
async function upgradePlugin(pluginPath, opts) {
|
|
1572
2728
|
try {
|
|
1573
|
-
const { PluginMigrator } = await import("./migrator-UQ4XFYE5.js");
|
|
1574
2729
|
if (opts.apiKey) {
|
|
1575
2730
|
process.env.ANTHROPIC_API_KEY = opts.apiKey;
|
|
1576
2731
|
}
|
|
1577
2732
|
if (!process.env.ANTHROPIC_API_KEY) {
|
|
1578
|
-
|
|
2733
|
+
logger8.error("ANTHROPIC_API_KEY is required for plugin upgrade.");
|
|
1579
2734
|
console.log("\nPlease set ANTHROPIC_API_KEY environment variable or use --api-key option.");
|
|
2735
|
+
console.log("Get your API key from: https://console.anthropic.com/");
|
|
1580
2736
|
process.exit(1);
|
|
1581
2737
|
}
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
2738
|
+
if (!process.env.ANTHROPIC_API_KEY.startsWith("sk-ant-")) {
|
|
2739
|
+
logger8.error("Invalid ANTHROPIC_API_KEY format.");
|
|
2740
|
+
console.log('\nThe API key should start with "sk-ant-"');
|
|
2741
|
+
console.log("Get your API key from: https://console.anthropic.com/");
|
|
2742
|
+
process.exit(1);
|
|
2743
|
+
}
|
|
2744
|
+
try {
|
|
2745
|
+
await import("@anthropic-ai/claude-code");
|
|
2746
|
+
if (opts.debug) {
|
|
2747
|
+
console.log("\u2713 Claude Code SDK ready");
|
|
2748
|
+
}
|
|
2749
|
+
} catch (importError) {
|
|
2750
|
+
console.log(chalk.red("\u2717 Claude Code SDK not available"));
|
|
2751
|
+
console.log(
|
|
2752
|
+
chalk.red(
|
|
2753
|
+
`Error: ${importError instanceof Error ? importError.message : String(importError)}`
|
|
2754
|
+
)
|
|
2755
|
+
);
|
|
2756
|
+
console.log("\nInstall the SDK: bun add @anthropic-ai/claude-code");
|
|
2757
|
+
process.exit(1);
|
|
2758
|
+
}
|
|
2759
|
+
const workingDir = path11.resolve(pluginPath);
|
|
2760
|
+
if (!existsSync11(workingDir)) {
|
|
2761
|
+
throw new Error(`Plugin directory not found: ${workingDir}`);
|
|
2762
|
+
}
|
|
2763
|
+
console.log(chalk.cyan("\u{1F527} Setting up migration environment..."));
|
|
2764
|
+
let projectRoot = process.cwd();
|
|
2765
|
+
let guidesSource;
|
|
2766
|
+
let previousRoot = "";
|
|
2767
|
+
while (projectRoot !== previousRoot && !existsSync11(path11.join(projectRoot, "packages/docs"))) {
|
|
2768
|
+
previousRoot = projectRoot;
|
|
2769
|
+
projectRoot = path11.dirname(projectRoot);
|
|
2770
|
+
}
|
|
2771
|
+
const monorepoGuidesPath = path11.join(
|
|
2772
|
+
projectRoot,
|
|
2773
|
+
"packages/docs/docs/plugins/migration/claude-code"
|
|
2774
|
+
);
|
|
2775
|
+
if (existsSync11(monorepoGuidesPath)) {
|
|
2776
|
+
guidesSource = monorepoGuidesPath;
|
|
2777
|
+
} else {
|
|
2778
|
+
const currentFileUrl = import.meta.url;
|
|
2779
|
+
const currentFilePath = fileURLToPath2(currentFileUrl);
|
|
2780
|
+
const cliPackageRoot = path11.dirname(
|
|
2781
|
+
path11.dirname(path11.dirname(path11.dirname(currentFilePath)))
|
|
2782
|
+
);
|
|
2783
|
+
const bundledGuidesPath = path11.join(cliPackageRoot, "migration-guides");
|
|
2784
|
+
if (existsSync11(bundledGuidesPath)) {
|
|
2785
|
+
guidesSource = bundledGuidesPath;
|
|
2786
|
+
} else {
|
|
2787
|
+
guidesSource = "";
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
const guidesTarget = path11.join(workingDir, "migration-guides");
|
|
2791
|
+
await fs.ensureDir(guidesTarget);
|
|
2792
|
+
if (guidesSource && existsSync11(guidesSource)) {
|
|
2793
|
+
await fs.copy(guidesSource, guidesTarget, { overwrite: true });
|
|
2794
|
+
if (opts.debug) {
|
|
2795
|
+
console.log(chalk.gray(`Copied guides from: ${guidesSource}`));
|
|
2796
|
+
}
|
|
2797
|
+
} else {
|
|
2798
|
+
if (opts.debug) {
|
|
2799
|
+
console.log(chalk.yellow("Migration guides not found, using embedded guidance"));
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
console.log(chalk.green("\u2705 Environment ready"));
|
|
2803
|
+
console.log(chalk.bold("\nElizaOS Plugin Migration (0.x \u2192 1.x)"));
|
|
2804
|
+
console.log(chalk.gray("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
2805
|
+
console.log("\u2022 Enhanced AI-powered migration with comprehensive guide integration");
|
|
2806
|
+
console.log("\u2022 9-gate progressive validation system with RAG search");
|
|
2807
|
+
console.log("\u2022 Automated analysis and migration with 95%+ test coverage");
|
|
2808
|
+
console.log("\u2022 Zero-failure release preparation with full validation");
|
|
2809
|
+
if (opts.debug) {
|
|
2810
|
+
console.log(chalk.gray(`
|
|
2811
|
+
Plugin: ${pluginPath}`));
|
|
2812
|
+
console.log(chalk.gray(`Working directory: ${workingDir}`));
|
|
2813
|
+
}
|
|
2814
|
+
if (!opts.skipConfirmation) {
|
|
2815
|
+
console.log(chalk.yellow("\n\u26A0\uFE0F This will modify files in the plugin directory."));
|
|
2816
|
+
console.log(chalk.yellow("Ensure your changes are committed first.\n"));
|
|
2817
|
+
console.log("Starting in 3 seconds... (Press Ctrl+C to cancel)");
|
|
2818
|
+
await new Promise((resolve2) => setTimeout(resolve2, 3e3));
|
|
2819
|
+
}
|
|
2820
|
+
const agent2 = new SimpleMigrationAgent(workingDir, {
|
|
2821
|
+
verbose: opts.verbose || opts.debug
|
|
1585
2822
|
});
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
2823
|
+
let messageCount = 0;
|
|
2824
|
+
agent2.on("progress", (count) => {
|
|
2825
|
+
messageCount = count;
|
|
2826
|
+
});
|
|
2827
|
+
const result = await agent2.migrate();
|
|
2828
|
+
try {
|
|
2829
|
+
if (existsSync11(guidesTarget)) {
|
|
2830
|
+
await fs.remove(guidesTarget);
|
|
2831
|
+
if (opts.debug) {
|
|
2832
|
+
console.log(chalk.gray("Cleaned up migration guides"));
|
|
2833
|
+
}
|
|
2834
|
+
}
|
|
2835
|
+
} catch (cleanupError) {
|
|
2836
|
+
if (opts.debug) {
|
|
2837
|
+
console.log(chalk.yellow(`Warning: Could not clean up guides: ${cleanupError}`));
|
|
2838
|
+
}
|
|
2839
|
+
}
|
|
1590
2840
|
if (result.success) {
|
|
1591
|
-
console.log(
|
|
1592
|
-
|
|
1593
|
-
console.log(`
|
|
1594
|
-
console.log(`
|
|
1595
|
-
console.log(`
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
console.log(
|
|
2841
|
+
console.log(chalk.green("\nMigration completed successfully!"));
|
|
2842
|
+
console.log(chalk.gray("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
2843
|
+
console.log(`Location: ${chalk.cyan(path11.basename(result.repoPath))}`);
|
|
2844
|
+
console.log(`Duration: ${chalk.yellow(Math.round(result.duration / 1e3) + "s")}`);
|
|
2845
|
+
console.log(`AI Operations: ${chalk.blue(result.messageCount)}`);
|
|
2846
|
+
if (result.guidesUsed && result.guidesUsed.length > 0) {
|
|
2847
|
+
console.log(`Migration Guides Used: ${chalk.magenta(result.guidesUsed.length)}`);
|
|
2848
|
+
if (opts.debug) {
|
|
2849
|
+
console.log(` ${chalk.gray(result.guidesUsed.join(", "))}`);
|
|
2850
|
+
}
|
|
2851
|
+
}
|
|
2852
|
+
console.log(chalk.bold("\nNext Steps:"));
|
|
2853
|
+
console.log(`${chalk.gray("1.")} cd ${chalk.cyan(path11.basename(result.repoPath))}`);
|
|
2854
|
+
console.log(
|
|
2855
|
+
`${chalk.gray("2.")} git checkout 1.x ${chalk.gray("# Review the migrated code")}`
|
|
2856
|
+
);
|
|
2857
|
+
console.log(`${chalk.gray("3.")} bun test ${chalk.gray("# Verify all tests pass")}`);
|
|
2858
|
+
console.log(`${chalk.gray("4.")} bun run build ${chalk.gray("# Verify the build")}`);
|
|
2859
|
+
console.log(`${chalk.gray("5.")} Test in a real project`);
|
|
2860
|
+
console.log(`${chalk.gray("6.")} Merge to main and publish
|
|
2861
|
+
`);
|
|
1603
2862
|
} else {
|
|
1604
|
-
|
|
2863
|
+
console.log(chalk.red("\n\u274C Migration failed"));
|
|
2864
|
+
console.log(chalk.gray("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
2865
|
+
if (result.error) {
|
|
2866
|
+
const errorMsg = result.error.message || String(result.error);
|
|
2867
|
+
console.log(chalk.red(`\u{1F4A5} ${errorMsg}`));
|
|
2868
|
+
if (opts.debug || opts.verbose) {
|
|
2869
|
+
console.log(chalk.gray("\nDetailed error:"));
|
|
2870
|
+
console.log(chalk.gray(result.error.stack || result.error.message));
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
console.log(chalk.yellow("\n\u{1F527} Quick fixes:"));
|
|
2874
|
+
console.log("\u2022 Check plugin structure follows ElizaOS standards");
|
|
2875
|
+
console.log("\u2022 Verify ANTHROPIC_API_KEY is valid");
|
|
2876
|
+
console.log("\u2022 Try with --debug for detailed output");
|
|
2877
|
+
console.log("\u2022 Ensure all dependencies are installed\n");
|
|
1605
2878
|
process.exit(1);
|
|
1606
2879
|
}
|
|
1607
2880
|
} catch (error) {
|
|
2881
|
+
try {
|
|
2882
|
+
const guidesTarget = path11.join(path11.resolve(pluginPath), "migration-guides");
|
|
2883
|
+
if (existsSync11(guidesTarget)) {
|
|
2884
|
+
await fs.remove(guidesTarget);
|
|
2885
|
+
if (opts.debug) {
|
|
2886
|
+
console.log(chalk.gray("Cleaned up migration guides after error"));
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2889
|
+
} catch (cleanupError) {
|
|
2890
|
+
}
|
|
2891
|
+
console.log("\n" + chalk.red("\u2717 Plugin upgrade failed!"));
|
|
2892
|
+
if (opts.debug || opts.verbose) {
|
|
2893
|
+
console.log("\n" + chalk.bold("Detailed Error Information:"));
|
|
2894
|
+
console.log(chalk.red(error instanceof Error ? error.stack : String(error)));
|
|
2895
|
+
} else {
|
|
2896
|
+
console.log(chalk.red(`
|
|
2897
|
+
Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
2898
|
+
}
|
|
2899
|
+
console.log("\n" + chalk.yellow("Troubleshooting Tips:"));
|
|
2900
|
+
console.log("1. Check that your plugin follows standard ElizaOS structure");
|
|
2901
|
+
console.log("2. Ensure all dependencies are installed");
|
|
2902
|
+
console.log("3. Try running with --verbose or --debug for more details");
|
|
2903
|
+
console.log("4. Verify your ANTHROPIC_API_KEY is valid");
|
|
1608
2904
|
handleError(error);
|
|
1609
2905
|
process.exit(1);
|
|
1610
2906
|
}
|
|
1611
2907
|
}
|
|
1612
2908
|
|
|
1613
2909
|
// src/commands/plugins/actions/generate.ts
|
|
1614
|
-
import { logger as
|
|
1615
|
-
import { readFileSync as
|
|
1616
|
-
import
|
|
2910
|
+
import { logger as logger9 } from "@elizaos/core";
|
|
2911
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
2912
|
+
import path12 from "path";
|
|
1617
2913
|
async function generatePlugin(opts) {
|
|
1618
2914
|
try {
|
|
1619
|
-
const { PluginCreator } = await import("./plugin-creator-
|
|
2915
|
+
const { PluginCreator } = await import("./plugin-creator-ZCOZ3UCT.js");
|
|
1620
2916
|
if (opts.apiKey) {
|
|
1621
2917
|
process.env.ANTHROPIC_API_KEY = opts.apiKey;
|
|
1622
2918
|
}
|
|
1623
2919
|
if (!process.env.ANTHROPIC_API_KEY) {
|
|
1624
|
-
|
|
2920
|
+
logger9.error("ANTHROPIC_API_KEY is required for plugin generation.");
|
|
1625
2921
|
console.log("\nPlease set ANTHROPIC_API_KEY environment variable or use --api-key option.");
|
|
1626
2922
|
process.exit(1);
|
|
1627
2923
|
}
|
|
1628
2924
|
let spec = void 0;
|
|
1629
2925
|
if (opts.specFile) {
|
|
1630
2926
|
try {
|
|
1631
|
-
const specContent =
|
|
2927
|
+
const specContent = readFileSync4(opts.specFile, "utf-8");
|
|
1632
2928
|
spec = JSON.parse(specContent);
|
|
1633
2929
|
} catch (error) {
|
|
1634
|
-
|
|
2930
|
+
logger9.error(
|
|
1635
2931
|
`Failed to read or parse spec file: ${error instanceof Error ? error.message : String(error)}`
|
|
1636
2932
|
);
|
|
1637
2933
|
process.exit(1);
|
|
1638
2934
|
}
|
|
1639
2935
|
} else if (opts.skipPrompts) {
|
|
1640
|
-
|
|
2936
|
+
logger9.error("--skip-prompts requires --spec-file to be provided");
|
|
1641
2937
|
process.exit(1);
|
|
1642
2938
|
}
|
|
1643
2939
|
const creator = new PluginCreator({
|
|
@@ -1659,12 +2955,12 @@ ${emoji.success("Plugin successfully generated!")}`);
|
|
|
1659
2955
|
The plugin has been created in your current directory.`);
|
|
1660
2956
|
console.log(`
|
|
1661
2957
|
Next steps:`);
|
|
1662
|
-
console.log(`1. cd ${
|
|
2958
|
+
console.log(`1. cd ${path12.basename(result.pluginPath ?? "")}`);
|
|
1663
2959
|
console.log(`2. Review the generated code`);
|
|
1664
2960
|
console.log(`3. Test the plugin: bun test`);
|
|
1665
2961
|
console.log(`4. Add to your ElizaOS project`);
|
|
1666
2962
|
} else {
|
|
1667
|
-
|
|
2963
|
+
logger9.error(`Plugin generation failed: ${result.error?.message}`);
|
|
1668
2964
|
process.exit(1);
|
|
1669
2965
|
}
|
|
1670
2966
|
} catch (error) {
|
|
@@ -1711,7 +3007,9 @@ plugins.command("remove").aliases(["delete", "del", "rm"]).description("Remove a
|
|
|
1711
3007
|
process.exit(1);
|
|
1712
3008
|
}
|
|
1713
3009
|
});
|
|
1714
|
-
plugins.command("upgrade").description(
|
|
3010
|
+
plugins.command("upgrade").description(
|
|
3011
|
+
"Upgrade a plugin from version 0.x to 1.x using AI-powered migration (requires Claude Code CLI)"
|
|
3012
|
+
).argument("<path>", "GitHub repository URL or local folder path").option("--api-key <key>", "Anthropic API key (or use ANTHROPIC_API_KEY env var)").option("--skip-tests", "Skip test validation loop").option("--skip-validation", "Skip production readiness validation").option("--quiet", "Suppress progress display").option("--verbose", "Show detailed information").option("--debug", "Show debug information").option("--skip-confirmation", "Skip user confirmation").action(async (pluginPath, opts) => {
|
|
1715
3013
|
await upgradePlugin(pluginPath, opts);
|
|
1716
3014
|
});
|
|
1717
3015
|
plugins.command("generate").description("Generate a new plugin using AI-powered code generation").option("--api-key <key>", "Anthropic API key (or use ANTHROPIC_API_KEY env var)").option("--skip-tests", "Skip test validation loop").option("--skip-validation", "Skip production readiness validation").option("--skip-prompts", "Skip interactive prompts (requires --spec-file)").option("--spec-file <path>", "Path to JSON file containing plugin specification").action(async (opts) => {
|
|
@@ -1721,19 +3019,19 @@ plugins.command("generate").description("Generate a new plugin using AI-powered
|
|
|
1721
3019
|
// src/commands/publish/index.ts
|
|
1722
3020
|
import { Command as Command5 } from "commander";
|
|
1723
3021
|
import { promises as fs8 } from "fs";
|
|
1724
|
-
import
|
|
3022
|
+
import path18 from "path";
|
|
1725
3023
|
import * as clack9 from "@clack/prompts";
|
|
1726
3024
|
|
|
1727
3025
|
// src/commands/publish/actions/npm-publish.ts
|
|
1728
3026
|
import { execa as execa2 } from "execa";
|
|
1729
3027
|
import { promises as fs2 } from "fs";
|
|
1730
|
-
import
|
|
3028
|
+
import path13 from "path";
|
|
1731
3029
|
async function publishToNpm(cwd, packageJson, npmUsername) {
|
|
1732
3030
|
console.info(`Publishing as npm user: ${npmUsername}`);
|
|
1733
3031
|
if (!packageJson.npmPackage || packageJson.npmPackage === "${NPM_PACKAGE}") {
|
|
1734
3032
|
packageJson.npmPackage = packageJson.name;
|
|
1735
3033
|
console.info(`Set npmPackage to: ${packageJson.npmPackage}`);
|
|
1736
|
-
const packageJsonPath =
|
|
3034
|
+
const packageJsonPath = path13.join(cwd, "package.json");
|
|
1737
3035
|
await fs2.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf-8");
|
|
1738
3036
|
}
|
|
1739
3037
|
console.info("Building package...");
|
|
@@ -1764,16 +3062,16 @@ async function publishToGitHubAction(cwd, packageJson, credentials, skipRegistry
|
|
|
1764
3062
|
|
|
1765
3063
|
// src/commands/publish/actions/registry-publish.ts
|
|
1766
3064
|
import { promises as fs3 } from "fs";
|
|
1767
|
-
import
|
|
3065
|
+
import path14 from "path";
|
|
1768
3066
|
var REGISTRY_PACKAGES_PATH = "packages";
|
|
1769
3067
|
var LOCAL_REGISTRY_PATH = "packages/registry";
|
|
1770
3068
|
async function updateRegistryIndex(packageMetadata, dryRun = false) {
|
|
1771
3069
|
try {
|
|
1772
|
-
const indexPath = dryRun ?
|
|
3070
|
+
const indexPath = dryRun ? path14.join(process.cwd(), LOCAL_REGISTRY_PATH, "index.json") : path14.join(process.cwd(), "temp-registry", "index.json");
|
|
1773
3071
|
try {
|
|
1774
|
-
await fs3.access(
|
|
3072
|
+
await fs3.access(path14.dirname(indexPath));
|
|
1775
3073
|
} catch {
|
|
1776
|
-
await fs3.mkdir(
|
|
3074
|
+
await fs3.mkdir(path14.dirname(indexPath), { recursive: true });
|
|
1777
3075
|
try {
|
|
1778
3076
|
await fs3.access(indexPath);
|
|
1779
3077
|
} catch {
|
|
@@ -1838,8 +3136,8 @@ async function updateRegistryIndex(packageMetadata, dryRun = false) {
|
|
|
1838
3136
|
}
|
|
1839
3137
|
async function savePackageToRegistry(packageMetadata, dryRun = false) {
|
|
1840
3138
|
try {
|
|
1841
|
-
const packageDir = dryRun ?
|
|
1842
|
-
const metadataPath =
|
|
3139
|
+
const packageDir = dryRun ? path14.join(process.cwd(), LOCAL_REGISTRY_PATH, REGISTRY_PACKAGES_PATH, packageMetadata.name) : path14.join(process.cwd(), "temp-registry", REGISTRY_PACKAGES_PATH, packageMetadata.name);
|
|
3140
|
+
const metadataPath = path14.join(packageDir, `${packageMetadata.version}.json`);
|
|
1843
3141
|
await fs3.mkdir(packageDir, { recursive: true });
|
|
1844
3142
|
await fs3.writeFile(metadataPath, JSON.stringify(packageMetadata, null, 2));
|
|
1845
3143
|
console.info(`Package metadata ${dryRun ? "(dry run) " : ""}saved to ${metadataPath}`);
|
|
@@ -1855,7 +3153,7 @@ async function savePackageToRegistry(packageMetadata, dryRun = false) {
|
|
|
1855
3153
|
|
|
1856
3154
|
// src/commands/publish/utils/validation.ts
|
|
1857
3155
|
import { promises as fs4 } from "fs";
|
|
1858
|
-
import
|
|
3156
|
+
import path15 from "path";
|
|
1859
3157
|
import * as clack5 from "@clack/prompts";
|
|
1860
3158
|
async function validatePluginRequirements(cwd, packageJson) {
|
|
1861
3159
|
const errors = [];
|
|
@@ -1866,16 +3164,16 @@ async function validatePluginRequirements(cwd, packageJson) {
|
|
|
1866
3164
|
'Plugin name must start with "plugin-". Please update your package name and try again.'
|
|
1867
3165
|
);
|
|
1868
3166
|
}
|
|
1869
|
-
const pluginDirName =
|
|
3167
|
+
const pluginDirName = path15.basename(cwd);
|
|
1870
3168
|
const expectedDefaultDesc = `ElizaOS plugin for ${pluginDirName.replace("plugin-", "")}`;
|
|
1871
3169
|
if (packageJson.description === expectedDefaultDesc || packageJson.description === "${PLUGINDESCRIPTION}") {
|
|
1872
3170
|
warnings.push(
|
|
1873
3171
|
"Description appears to be the default generated description. Consider writing a custom description."
|
|
1874
3172
|
);
|
|
1875
3173
|
}
|
|
1876
|
-
const imagesDir =
|
|
1877
|
-
const logoPath =
|
|
1878
|
-
const bannerPath =
|
|
3174
|
+
const imagesDir = path15.join(cwd, "images");
|
|
3175
|
+
const logoPath = path15.join(imagesDir, "logo.jpg");
|
|
3176
|
+
const bannerPath = path15.join(imagesDir, "banner.jpg");
|
|
1879
3177
|
try {
|
|
1880
3178
|
await fs4.access(logoPath);
|
|
1881
3179
|
} catch {
|
|
@@ -2023,20 +3321,20 @@ async function getNpmUsername() {
|
|
|
2023
3321
|
// src/commands/publish/utils/version-check.ts
|
|
2024
3322
|
import { execa as execa7 } from "execa";
|
|
2025
3323
|
import { promises as fs7 } from "fs";
|
|
2026
|
-
import
|
|
2027
|
-
import { fileURLToPath } from "url";
|
|
3324
|
+
import path17 from "path";
|
|
3325
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2028
3326
|
import * as clack8 from "@clack/prompts";
|
|
2029
3327
|
|
|
2030
3328
|
// src/commands/update/index.ts
|
|
2031
|
-
import { logger as
|
|
3329
|
+
import { logger as logger13 } from "@elizaos/core";
|
|
2032
3330
|
import { Command as Command4 } from "commander";
|
|
2033
3331
|
|
|
2034
3332
|
// src/commands/update/actions/cli-update.ts
|
|
2035
|
-
import { logger as
|
|
3333
|
+
import { logger as logger11 } from "@elizaos/core";
|
|
2036
3334
|
import { execa as execa5 } from "execa";
|
|
2037
3335
|
|
|
2038
3336
|
// src/commands/update/utils/version-utils.ts
|
|
2039
|
-
import { logger as
|
|
3337
|
+
import { logger as logger10 } from "@elizaos/core";
|
|
2040
3338
|
import { execa as execa4 } from "execa";
|
|
2041
3339
|
import * as semver from "semver";
|
|
2042
3340
|
var SPECIAL_VERSION_TAGS = ["latest", "next", "canary", "rc", "dev", "nightly", "alpha"];
|
|
@@ -2047,7 +3345,7 @@ async function getVersion2() {
|
|
|
2047
3345
|
const envInfo = await UserEnvironment.getInstance().getInfo();
|
|
2048
3346
|
return envInfo.cli.version;
|
|
2049
3347
|
} catch (error) {
|
|
2050
|
-
|
|
3348
|
+
logger10.error("Error getting CLI version:", error);
|
|
2051
3349
|
return FALLBACK_VERSION;
|
|
2052
3350
|
}
|
|
2053
3351
|
}
|
|
@@ -2087,10 +3385,10 @@ async function fetchLatestVersion(packageName) {
|
|
|
2087
3385
|
env: { NODE_ENV: "production" }
|
|
2088
3386
|
});
|
|
2089
3387
|
const version = stdout.trim();
|
|
2090
|
-
|
|
3388
|
+
logger10.debug(`Latest version of ${packageName} from npm: ${version}`);
|
|
2091
3389
|
return version;
|
|
2092
3390
|
} catch (error) {
|
|
2093
|
-
|
|
3391
|
+
logger10.error(
|
|
2094
3392
|
`Failed to fetch version for ${packageName}: ${error instanceof Error ? error.message : String(error)}`
|
|
2095
3393
|
);
|
|
2096
3394
|
return null;
|
|
@@ -2121,14 +3419,14 @@ async function performCliUpdate(options = {}) {
|
|
|
2121
3419
|
if (!options.skipBunMigration) {
|
|
2122
3420
|
const npmInstallation = await isCliInstalledViaNpm();
|
|
2123
3421
|
if (npmInstallation) {
|
|
2124
|
-
|
|
3422
|
+
logger11.info("Detected npm installation, migrating to bun...");
|
|
2125
3423
|
try {
|
|
2126
3424
|
await migrateCliToBun(latestVersion);
|
|
2127
3425
|
console.log(`CLI updated successfully to version ${latestVersion} [\u2713]`);
|
|
2128
3426
|
return true;
|
|
2129
3427
|
} catch (migrationError) {
|
|
2130
|
-
|
|
2131
|
-
|
|
3428
|
+
logger11.warn("Migration to bun failed, falling back to npm update...");
|
|
3429
|
+
logger11.debug(
|
|
2132
3430
|
"Migration error:",
|
|
2133
3431
|
migrationError instanceof Error ? migrationError.message : String(migrationError)
|
|
2134
3432
|
);
|
|
@@ -2158,12 +3456,12 @@ async function performCliUpdate(options = {}) {
|
|
|
2158
3456
|
// src/commands/update/actions/dependency-update.ts
|
|
2159
3457
|
import * as clack7 from "@clack/prompts";
|
|
2160
3458
|
import { promises as fs6 } from "fs";
|
|
2161
|
-
import * as
|
|
3459
|
+
import * as path16 from "path";
|
|
2162
3460
|
|
|
2163
3461
|
// src/commands/update/utils/package-utils.ts
|
|
2164
3462
|
import fs5 from "fs/promises";
|
|
2165
3463
|
import { execa as execa6 } from "execa";
|
|
2166
|
-
import { logger as
|
|
3464
|
+
import { logger as logger12 } from "@elizaos/core";
|
|
2167
3465
|
async function checkForUpdates(dependencies) {
|
|
2168
3466
|
const updates = {};
|
|
2169
3467
|
const elizaPackages = Object.entries(dependencies).filter(([pkg]) => pkg.startsWith(ELIZAOS_ORG)).filter(([, version]) => !isWorkspaceVersion(version));
|
|
@@ -2174,7 +3472,7 @@ async function checkForUpdates(dependencies) {
|
|
|
2174
3472
|
if (needsUpdate) {
|
|
2175
3473
|
updates[pkg] = { current: currentVersion, latest: latestVersion };
|
|
2176
3474
|
} else if (error) {
|
|
2177
|
-
|
|
3475
|
+
logger12.debug(`${pkg}: ${error}`);
|
|
2178
3476
|
}
|
|
2179
3477
|
}
|
|
2180
3478
|
return { hasUpdates: Object.keys(updates).length > 0, updates };
|
|
@@ -2222,7 +3520,7 @@ async function installDependencies(cwd) {
|
|
|
2222
3520
|
// src/commands/update/actions/dependency-update.ts
|
|
2223
3521
|
async function updateDependencies(cwd, isPlugin2, options = {}) {
|
|
2224
3522
|
const { dryRun = false, skipBuild = false } = options;
|
|
2225
|
-
const packageJsonPath =
|
|
3523
|
+
const packageJsonPath = path16.join(cwd, "package.json");
|
|
2226
3524
|
const content = await fs6.readFile(packageJsonPath, "utf8");
|
|
2227
3525
|
const packageJson = JSON.parse(content);
|
|
2228
3526
|
const allDependencies = {
|
|
@@ -2293,7 +3591,7 @@ var update = new Command4().name("update").description("Update ElizaOS CLI and p
|
|
|
2293
3591
|
try {
|
|
2294
3592
|
await displayBanner();
|
|
2295
3593
|
} catch {
|
|
2296
|
-
|
|
3594
|
+
logger13.debug("Banner display failed, continuing with update");
|
|
2297
3595
|
}
|
|
2298
3596
|
}).action(async (options) => {
|
|
2299
3597
|
try {
|
|
@@ -2326,7 +3624,7 @@ var update = new Command4().name("update").description("Update ElizaOS CLI and p
|
|
|
2326
3624
|
console.info("To create a new ElizaOS project, use: elizaos create <project-name>");
|
|
2327
3625
|
return;
|
|
2328
3626
|
}
|
|
2329
|
-
|
|
3627
|
+
logger13.debug(`Detected ${directoryInfo.type}`);
|
|
2330
3628
|
if (!isValidForUpdates(directoryInfo)) {
|
|
2331
3629
|
handleInvalidDirectory(directoryInfo);
|
|
2332
3630
|
return;
|
|
@@ -2363,8 +3661,8 @@ var update = new Command4().name("update").description("Update ElizaOS CLI and p
|
|
|
2363
3661
|
// src/commands/publish/utils/version-check.ts
|
|
2364
3662
|
async function checkCliVersion() {
|
|
2365
3663
|
try {
|
|
2366
|
-
const cliPackageJsonPath =
|
|
2367
|
-
|
|
3664
|
+
const cliPackageJsonPath = path17.resolve(
|
|
3665
|
+
path17.dirname(fileURLToPath3(import.meta.url)),
|
|
2368
3666
|
"../package.json"
|
|
2369
3667
|
);
|
|
2370
3668
|
const cliPackageJsonContent = await fs7.readFile(cliPackageJsonPath, "utf-8");
|
|
@@ -2425,7 +3723,7 @@ var publish = new Command5().name("publish").description("Publish a plugin to np
|
|
|
2425
3723
|
process.exit(1);
|
|
2426
3724
|
}
|
|
2427
3725
|
const cliVersion = await checkCliVersion();
|
|
2428
|
-
const pluginDirName =
|
|
3726
|
+
const pluginDirName = path18.basename(process.cwd());
|
|
2429
3727
|
if (!pluginDirName.startsWith("plugin-")) {
|
|
2430
3728
|
console.error("This command must be run from a plugin directory (plugin-*)");
|
|
2431
3729
|
process.exit(1);
|
|
@@ -2451,7 +3749,7 @@ var publish = new Command5().name("publish").description("Publish a plugin to np
|
|
|
2451
3749
|
}
|
|
2452
3750
|
}
|
|
2453
3751
|
}
|
|
2454
|
-
const packageJsonPath =
|
|
3752
|
+
const packageJsonPath = path18.join(cwd, "package.json");
|
|
2455
3753
|
const packageJsonContent = await fs8.readFile(packageJsonPath, "utf-8");
|
|
2456
3754
|
const packageJson = JSON.parse(packageJsonContent);
|
|
2457
3755
|
if (!packageJson.name || !packageJson.version) {
|
|
@@ -2718,8 +4016,8 @@ import { Command as Command6 } from "commander";
|
|
|
2718
4016
|
|
|
2719
4017
|
// src/commands/monorepo/actions/clone.ts
|
|
2720
4018
|
import { execa as execa8 } from "execa";
|
|
2721
|
-
import { existsSync as
|
|
2722
|
-
import
|
|
4019
|
+
import { existsSync as existsSync12, readdirSync as readdirSync3, mkdirSync } from "fs";
|
|
4020
|
+
import path19 from "path";
|
|
2723
4021
|
async function cloneRepository(repo, branch, destination) {
|
|
2724
4022
|
try {
|
|
2725
4023
|
const repoUrl = `https://github.com/${repo}`;
|
|
@@ -2745,9 +4043,9 @@ For a complete list of branches, visit: https://github.com/elizaOS/eliza/branche
|
|
|
2745
4043
|
}
|
|
2746
4044
|
}
|
|
2747
4045
|
function prepareDestination(dir) {
|
|
2748
|
-
const destinationDir =
|
|
2749
|
-
if (
|
|
2750
|
-
const files =
|
|
4046
|
+
const destinationDir = path19.resolve(process.cwd(), dir);
|
|
4047
|
+
if (existsSync12(destinationDir)) {
|
|
4048
|
+
const files = readdirSync3(destinationDir);
|
|
2751
4049
|
if (files.length > 0) {
|
|
2752
4050
|
throw new Error(`Destination directory ${destinationDir} already exists and is not empty`);
|
|
2753
4051
|
}
|
|
@@ -2764,7 +4062,7 @@ async function cloneMonorepo(cloneInfo) {
|
|
|
2764
4062
|
}
|
|
2765
4063
|
|
|
2766
4064
|
// src/commands/monorepo/utils/setup-instructions.ts
|
|
2767
|
-
import
|
|
4065
|
+
import path20 from "path";
|
|
2768
4066
|
function getBunInstallInstructions() {
|
|
2769
4067
|
const platform = process.platform;
|
|
2770
4068
|
if (platform === "win32") {
|
|
@@ -2819,7 +4117,7 @@ ${emoji.rocket("If you don't have Bun installed:")}`);
|
|
|
2819
4117
|
console.log(" After installation, restart your terminal");
|
|
2820
4118
|
}
|
|
2821
4119
|
function displayNextSteps(targetDir) {
|
|
2822
|
-
const cdPath =
|
|
4120
|
+
const cdPath = path20.relative(process.cwd(), targetDir);
|
|
2823
4121
|
displayBasicSteps(cdPath);
|
|
2824
4122
|
displayPrerequisites();
|
|
2825
4123
|
displayBunInstructions();
|
|
@@ -2849,11 +4147,11 @@ import { loadCharacterTryPath as loadCharacterTryPath2 } from "@elizaos/server";
|
|
|
2849
4147
|
|
|
2850
4148
|
// src/project.ts
|
|
2851
4149
|
import {
|
|
2852
|
-
logger as
|
|
4150
|
+
logger as logger14
|
|
2853
4151
|
} from "@elizaos/core";
|
|
2854
4152
|
import { stringToUuid } from "@elizaos/core";
|
|
2855
4153
|
import * as fs9 from "fs";
|
|
2856
|
-
import
|
|
4154
|
+
import path21 from "path";
|
|
2857
4155
|
function isPlugin(module) {
|
|
2858
4156
|
if (module && typeof module === "object" && typeof module.name === "string" && typeof module.description === "string") {
|
|
2859
4157
|
return true;
|
|
@@ -2888,10 +4186,10 @@ async function loadProject(dir) {
|
|
|
2888
4186
|
if (!dirInfo.hasPackageJson) {
|
|
2889
4187
|
throw new Error(`No package.json found in ${dir}`);
|
|
2890
4188
|
}
|
|
2891
|
-
const packageJson = JSON.parse(fs9.readFileSync(
|
|
4189
|
+
const packageJson = JSON.parse(fs9.readFileSync(path21.join(dir, "package.json"), "utf8"));
|
|
2892
4190
|
const main2 = packageJson.main;
|
|
2893
4191
|
if (!main2) {
|
|
2894
|
-
|
|
4192
|
+
logger14.warn("No main field found in package.json, using default character");
|
|
2895
4193
|
const defaultCharacterName = "Eliza (Default)";
|
|
2896
4194
|
const elizaCharacter = getElizaCharacter();
|
|
2897
4195
|
const defaultAgent = {
|
|
@@ -2901,7 +4199,7 @@ async function loadProject(dir) {
|
|
|
2901
4199
|
name: defaultCharacterName
|
|
2902
4200
|
},
|
|
2903
4201
|
init: async () => {
|
|
2904
|
-
|
|
4202
|
+
logger14.info("Initializing default Eliza character");
|
|
2905
4203
|
}
|
|
2906
4204
|
};
|
|
2907
4205
|
return {
|
|
@@ -2910,32 +4208,32 @@ async function loadProject(dir) {
|
|
|
2910
4208
|
};
|
|
2911
4209
|
}
|
|
2912
4210
|
const entryPoints = [
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
4211
|
+
path21.join(dir, main2),
|
|
4212
|
+
path21.join(dir, "dist/index.js"),
|
|
4213
|
+
path21.join(dir, "src/index.ts"),
|
|
4214
|
+
path21.join(dir, "src/index.js"),
|
|
4215
|
+
path21.join(dir, "index.ts"),
|
|
4216
|
+
path21.join(dir, "index.js")
|
|
2919
4217
|
];
|
|
2920
4218
|
let projectModule = null;
|
|
2921
4219
|
for (const entryPoint of entryPoints) {
|
|
2922
4220
|
if (fs9.existsSync(entryPoint)) {
|
|
2923
4221
|
try {
|
|
2924
|
-
const importPath =
|
|
4222
|
+
const importPath = path21.resolve(entryPoint);
|
|
2925
4223
|
const importUrl = process.platform === "win32" ? "file:///" + importPath.replace(/\\/g, "/") : "file://" + importPath;
|
|
2926
4224
|
projectModule = await import(importUrl);
|
|
2927
|
-
|
|
4225
|
+
logger14.info(`Loaded project from ${entryPoint}`);
|
|
2928
4226
|
const exportKeys = Object.keys(projectModule);
|
|
2929
|
-
|
|
4227
|
+
logger14.debug(`Module exports: ${exportKeys.join(", ")}`);
|
|
2930
4228
|
if (exportKeys.includes("default")) {
|
|
2931
|
-
|
|
4229
|
+
logger14.debug(`Default export type: ${typeof projectModule.default}`);
|
|
2932
4230
|
if (typeof projectModule.default === "object" && projectModule.default !== null) {
|
|
2933
|
-
|
|
4231
|
+
logger14.debug(`Default export keys: ${Object.keys(projectModule.default).join(", ")}`);
|
|
2934
4232
|
}
|
|
2935
4233
|
}
|
|
2936
4234
|
break;
|
|
2937
4235
|
} catch (error) {
|
|
2938
|
-
|
|
4236
|
+
logger14.warn(`Failed to import project from ${entryPoint}:`, error);
|
|
2939
4237
|
}
|
|
2940
4238
|
}
|
|
2941
4239
|
}
|
|
@@ -2943,13 +4241,13 @@ async function loadProject(dir) {
|
|
|
2943
4241
|
throw new Error("Could not find project entry point");
|
|
2944
4242
|
}
|
|
2945
4243
|
const moduleIsPlugin = isPlugin(projectModule);
|
|
2946
|
-
|
|
4244
|
+
logger14.debug(`Is this a plugin? ${moduleIsPlugin}`);
|
|
2947
4245
|
if (moduleIsPlugin) {
|
|
2948
|
-
|
|
4246
|
+
logger14.info("Detected plugin module instead of project");
|
|
2949
4247
|
try {
|
|
2950
4248
|
const plugin = extractPlugin(projectModule);
|
|
2951
|
-
|
|
2952
|
-
|
|
4249
|
+
logger14.debug(`Found plugin: ${plugin.name} - ${plugin.description}`);
|
|
4250
|
+
logger14.debug(`Plugin has the following properties: ${Object.keys(plugin).join(", ")}`);
|
|
2953
4251
|
const completePlugin = {
|
|
2954
4252
|
// Copy all other properties from the original plugin first
|
|
2955
4253
|
...plugin,
|
|
@@ -2957,7 +4255,7 @@ async function loadProject(dir) {
|
|
|
2957
4255
|
name: plugin.name || "unknown-plugin",
|
|
2958
4256
|
description: plugin.description || "No description",
|
|
2959
4257
|
init: plugin.init || (async () => {
|
|
2960
|
-
|
|
4258
|
+
logger14.info(`Dummy init for plugin: ${plugin.name}`);
|
|
2961
4259
|
})
|
|
2962
4260
|
};
|
|
2963
4261
|
const characterName = "Eliza (Test Mode)";
|
|
@@ -2968,13 +4266,13 @@ async function loadProject(dir) {
|
|
|
2968
4266
|
name: characterName,
|
|
2969
4267
|
system: `${elizaCharacter.system} Testing the plugin: ${completePlugin.name}.`
|
|
2970
4268
|
};
|
|
2971
|
-
|
|
4269
|
+
logger14.info(`Using Eliza character as test agent for plugin: ${completePlugin.name}`);
|
|
2972
4270
|
const testAgent = {
|
|
2973
4271
|
character: testCharacter,
|
|
2974
4272
|
plugins: [completePlugin],
|
|
2975
4273
|
// Only include the plugin being tested
|
|
2976
4274
|
init: async () => {
|
|
2977
|
-
|
|
4275
|
+
logger14.info(`Initializing Eliza test agent for plugin: ${completePlugin.name}`);
|
|
2978
4276
|
}
|
|
2979
4277
|
};
|
|
2980
4278
|
return {
|
|
@@ -2984,24 +4282,24 @@ async function loadProject(dir) {
|
|
|
2984
4282
|
pluginModule: completePlugin
|
|
2985
4283
|
};
|
|
2986
4284
|
} catch (error) {
|
|
2987
|
-
|
|
4285
|
+
logger14.error("Error extracting plugin from module:", error);
|
|
2988
4286
|
throw error;
|
|
2989
4287
|
}
|
|
2990
4288
|
}
|
|
2991
4289
|
const agents = [];
|
|
2992
4290
|
if (projectModule.default && typeof projectModule.default === "object" && Array.isArray(projectModule.default.agents)) {
|
|
2993
4291
|
agents.push(...projectModule.default.agents);
|
|
2994
|
-
|
|
4292
|
+
logger14.debug(`Found ${agents.length} agents in default export's agents array`);
|
|
2995
4293
|
} else {
|
|
2996
4294
|
for (const [key, value] of Object.entries(projectModule)) {
|
|
2997
4295
|
if (key === "default" && value && typeof value === "object") {
|
|
2998
4296
|
if (value.character && value.init) {
|
|
2999
4297
|
agents.push(value);
|
|
3000
|
-
|
|
4298
|
+
logger14.debug(`Found agent in default export (single agent)`);
|
|
3001
4299
|
}
|
|
3002
4300
|
} else if (value && typeof value === "object" && value.character && value.init) {
|
|
3003
4301
|
agents.push(value);
|
|
3004
|
-
|
|
4302
|
+
logger14.debug(`Found agent in named export: ${key}`);
|
|
3005
4303
|
}
|
|
3006
4304
|
}
|
|
3007
4305
|
}
|
|
@@ -3014,52 +4312,79 @@ async function loadProject(dir) {
|
|
|
3014
4312
|
};
|
|
3015
4313
|
return project;
|
|
3016
4314
|
} catch (error) {
|
|
3017
|
-
|
|
4315
|
+
logger14.error("Error loading project:", error);
|
|
3018
4316
|
throw error;
|
|
3019
4317
|
}
|
|
3020
4318
|
}
|
|
3021
4319
|
|
|
3022
4320
|
// src/commands/start/index.ts
|
|
3023
|
-
import { logger as
|
|
4321
|
+
import { logger as logger19 } from "@elizaos/core";
|
|
3024
4322
|
import { Command as Command7 } from "commander";
|
|
3025
4323
|
|
|
3026
4324
|
// src/commands/start/actions/server-start.ts
|
|
3027
4325
|
import { AgentServer, jsonToCharacter, loadCharacterTryPath } from "@elizaos/server";
|
|
3028
|
-
import { logger as
|
|
4326
|
+
import { logger as logger18 } from "@elizaos/core";
|
|
3029
4327
|
|
|
3030
4328
|
// src/commands/start/actions/agent-start.ts
|
|
3031
4329
|
import {
|
|
3032
4330
|
AgentRuntime as AgentRuntime2,
|
|
3033
4331
|
encryptedCharacter,
|
|
3034
|
-
logger as
|
|
4332
|
+
logger as logger17,
|
|
3035
4333
|
stringToUuid as stringToUuid2
|
|
3036
4334
|
} from "@elizaos/core";
|
|
3037
4335
|
import { plugin as sqlPlugin } from "@elizaos/plugin-sql";
|
|
3038
4336
|
|
|
3039
4337
|
// src/commands/start/utils/config-utils.ts
|
|
3040
|
-
import
|
|
4338
|
+
import dotenv from "dotenv";
|
|
3041
4339
|
async function loadEnvConfig() {
|
|
3042
4340
|
const envInfo = await UserEnvironment.getInstanceInfo();
|
|
3043
4341
|
if (envInfo.paths.envFilePath) {
|
|
3044
|
-
|
|
4342
|
+
dotenv.config({ path: envInfo.paths.envFilePath });
|
|
3045
4343
|
}
|
|
3046
4344
|
return process.env;
|
|
3047
4345
|
}
|
|
4346
|
+
function hasCharacterSecrets(character) {
|
|
4347
|
+
return character?.settings?.secrets && Object.keys(character.settings.secrets).length > 0;
|
|
4348
|
+
}
|
|
4349
|
+
function ensureCharacterSettings(character) {
|
|
4350
|
+
if (!character.settings) {
|
|
4351
|
+
character.settings = {};
|
|
4352
|
+
}
|
|
4353
|
+
}
|
|
4354
|
+
async function loadLocalEnvSecrets() {
|
|
4355
|
+
const envPath = await getLocalEnvPath();
|
|
4356
|
+
if (!envPath) {
|
|
4357
|
+
return null;
|
|
4358
|
+
}
|
|
4359
|
+
return await parseEnvFile(envPath);
|
|
4360
|
+
}
|
|
4361
|
+
async function setDefaultSecretsFromEnv(character) {
|
|
4362
|
+
ensureCharacterSettings(character);
|
|
4363
|
+
if (hasCharacterSecrets(character)) {
|
|
4364
|
+
return false;
|
|
4365
|
+
}
|
|
4366
|
+
const envSecrets = await loadLocalEnvSecrets();
|
|
4367
|
+
if (!envSecrets) {
|
|
4368
|
+
return false;
|
|
4369
|
+
}
|
|
4370
|
+
character.settings.secrets = envSecrets;
|
|
4371
|
+
return true;
|
|
4372
|
+
}
|
|
3048
4373
|
|
|
3049
4374
|
// src/commands/start/utils/dependency-resolver.ts
|
|
3050
|
-
import { logger as
|
|
4375
|
+
import { logger as logger15 } from "@elizaos/core";
|
|
3051
4376
|
function resolvePluginDependencies(availablePlugins, isTestMode = false) {
|
|
3052
4377
|
const resolutionOrder = [];
|
|
3053
4378
|
const visited = /* @__PURE__ */ new Set();
|
|
3054
4379
|
const visiting = /* @__PURE__ */ new Set();
|
|
3055
4380
|
function visit(pluginName) {
|
|
3056
4381
|
if (!availablePlugins.has(pluginName)) {
|
|
3057
|
-
|
|
4382
|
+
logger15.warn(`Plugin dependency "${pluginName}" not found and will be skipped.`);
|
|
3058
4383
|
return;
|
|
3059
4384
|
}
|
|
3060
4385
|
if (visited.has(pluginName)) return;
|
|
3061
4386
|
if (visiting.has(pluginName)) {
|
|
3062
|
-
|
|
4387
|
+
logger15.error(`Circular dependency detected involving plugin: ${pluginName}`);
|
|
3063
4388
|
return;
|
|
3064
4389
|
}
|
|
3065
4390
|
visiting.add(pluginName);
|
|
@@ -3083,12 +4408,12 @@ function resolvePluginDependencies(availablePlugins, isTestMode = false) {
|
|
|
3083
4408
|
}
|
|
3084
4409
|
}
|
|
3085
4410
|
const finalPlugins = resolutionOrder.map((name) => availablePlugins.get(name)).filter((p) => p);
|
|
3086
|
-
|
|
4411
|
+
logger15.info(`Final plugins being loaded: ${finalPlugins.map((p) => p.name).join(", ")}`);
|
|
3087
4412
|
return finalPlugins;
|
|
3088
4413
|
}
|
|
3089
4414
|
|
|
3090
4415
|
// src/commands/start/utils/plugin-utils.ts
|
|
3091
|
-
import { logger as
|
|
4416
|
+
import { logger as logger16 } from "@elizaos/core";
|
|
3092
4417
|
function isValidPluginShape(obj) {
|
|
3093
4418
|
if (!obj || typeof obj !== "object" || !obj.name) {
|
|
3094
4419
|
return false;
|
|
@@ -3103,12 +4428,12 @@ async function loadAndPreparePlugin(pluginName) {
|
|
|
3103
4428
|
try {
|
|
3104
4429
|
pluginModule = await loadPluginModule(pluginName);
|
|
3105
4430
|
if (!pluginModule) {
|
|
3106
|
-
|
|
4431
|
+
logger16.error(`Failed to load local plugin ${pluginName}.`);
|
|
3107
4432
|
provideLocalPluginGuidance(pluginName, context);
|
|
3108
4433
|
return null;
|
|
3109
4434
|
}
|
|
3110
4435
|
} catch (error) {
|
|
3111
|
-
|
|
4436
|
+
logger16.error(`Error loading local plugin ${pluginName}: ${error}`);
|
|
3112
4437
|
provideLocalPluginGuidance(pluginName, context);
|
|
3113
4438
|
return null;
|
|
3114
4439
|
}
|
|
@@ -3116,17 +4441,17 @@ async function loadAndPreparePlugin(pluginName) {
|
|
|
3116
4441
|
try {
|
|
3117
4442
|
pluginModule = await loadPluginModule(pluginName);
|
|
3118
4443
|
if (!pluginModule) {
|
|
3119
|
-
|
|
4444
|
+
logger16.info(`Plugin ${pluginName} not available, installing...`);
|
|
3120
4445
|
await installPlugin(pluginName, process.cwd(), version);
|
|
3121
4446
|
pluginModule = await loadPluginModule(pluginName);
|
|
3122
4447
|
}
|
|
3123
4448
|
} catch (error) {
|
|
3124
|
-
|
|
4449
|
+
logger16.error(`Failed to process plugin ${pluginName}: ${error}`);
|
|
3125
4450
|
return null;
|
|
3126
4451
|
}
|
|
3127
4452
|
}
|
|
3128
4453
|
if (!pluginModule) {
|
|
3129
|
-
|
|
4454
|
+
logger16.error(`Failed to load module for plugin ${pluginName}.`);
|
|
3130
4455
|
return null;
|
|
3131
4456
|
}
|
|
3132
4457
|
const expectedFunctionName = `${pluginName.replace(/^@elizaos\/plugin-/, "").replace(/^@elizaos\//, "").replace(/-./g, (match) => match[1].toUpperCase())}Plugin`;
|
|
@@ -3140,13 +4465,16 @@ async function loadAndPreparePlugin(pluginName) {
|
|
|
3140
4465
|
return potentialPlugin;
|
|
3141
4466
|
}
|
|
3142
4467
|
}
|
|
3143
|
-
|
|
4468
|
+
logger16.warn(`Could not find a valid plugin export in ${pluginName}.`);
|
|
3144
4469
|
return null;
|
|
3145
4470
|
}
|
|
3146
4471
|
|
|
3147
4472
|
// src/commands/start/actions/agent-start.ts
|
|
3148
4473
|
async function startAgent(character, server, init, plugins2 = [], options = {}) {
|
|
3149
4474
|
character.id ??= stringToUuid2(character.name);
|
|
4475
|
+
if (!hasCharacterSecrets(character)) {
|
|
4476
|
+
await setDefaultSecretsFromEnv(character);
|
|
4477
|
+
}
|
|
3150
4478
|
const loadedPlugins = /* @__PURE__ */ new Map();
|
|
3151
4479
|
loadedPlugins.set(sqlPlugin.name, sqlPlugin);
|
|
3152
4480
|
const pluginsToLoad = new Set(character.plugins || []);
|
|
@@ -3189,26 +4517,26 @@ async function startAgent(character, server, init, plugins2 = [], options = {})
|
|
|
3189
4517
|
try {
|
|
3190
4518
|
const migrationService = runtime.getService("database_migration");
|
|
3191
4519
|
if (migrationService) {
|
|
3192
|
-
|
|
4520
|
+
logger17.info("Discovering plugin schemas for dynamic migration...");
|
|
3193
4521
|
migrationService.discoverAndRegisterPluginSchemas(finalPlugins);
|
|
3194
|
-
|
|
4522
|
+
logger17.info("Running all plugin migrations...");
|
|
3195
4523
|
await migrationService.runAllPluginMigrations();
|
|
3196
|
-
|
|
4524
|
+
logger17.info("All plugin migrations completed successfully");
|
|
3197
4525
|
} else {
|
|
3198
|
-
|
|
4526
|
+
logger17.warn("DatabaseMigrationService not found - plugin schema migrations skipped");
|
|
3199
4527
|
}
|
|
3200
4528
|
} catch (error) {
|
|
3201
|
-
|
|
4529
|
+
logger17.error("Failed to run plugin migrations:", error);
|
|
3202
4530
|
throw error;
|
|
3203
4531
|
}
|
|
3204
4532
|
server.registerAgent(runtime);
|
|
3205
|
-
|
|
4533
|
+
logger17.log(`Started ${runtime.character.name} as ${runtime.agentId}`);
|
|
3206
4534
|
return runtime;
|
|
3207
4535
|
}
|
|
3208
4536
|
async function stopAgent(runtime, server) {
|
|
3209
4537
|
await runtime.close();
|
|
3210
4538
|
server.unregisterAgent(runtime.agentId);
|
|
3211
|
-
|
|
4539
|
+
logger17.success(`Agent ${runtime.character.name} stopped successfully!`);
|
|
3212
4540
|
}
|
|
3213
4541
|
|
|
3214
4542
|
// src/commands/start/actions/server-start.ts
|
|
@@ -3225,7 +4553,7 @@ async function startAgents(options) {
|
|
|
3225
4553
|
const desiredPort = options.port || Number.parseInt(process.env.SERVER_PORT || "3000");
|
|
3226
4554
|
const serverPort = await findNextAvailablePort(desiredPort);
|
|
3227
4555
|
if (serverPort !== desiredPort) {
|
|
3228
|
-
|
|
4556
|
+
logger18.warn(`Port ${desiredPort} is in use, using port ${serverPort} instead`);
|
|
3229
4557
|
}
|
|
3230
4558
|
process.env.SERVER_PORT = serverPort.toString();
|
|
3231
4559
|
server.start(serverPort);
|
|
@@ -3250,7 +4578,7 @@ async function startAgents(options) {
|
|
|
3250
4578
|
|
|
3251
4579
|
// src/commands/start/index.ts
|
|
3252
4580
|
import * as fs10 from "fs";
|
|
3253
|
-
import * as
|
|
4581
|
+
import * as path22 from "path";
|
|
3254
4582
|
var start = new Command7().name("start").description("Start the Eliza agent server").option("-c, --configure", "Reconfigure services and AI models").option("-p, --port <port>", "Port to listen on", validatePort).option("--character <paths...>", "Character file(s) to use").hook("preAction", async () => {
|
|
3255
4583
|
await displayBanner();
|
|
3256
4584
|
}).action(async (options) => {
|
|
@@ -3260,24 +4588,24 @@ var start = new Command7().name("start").description("Start the Eliza agent serv
|
|
|
3260
4588
|
let projectAgents = [];
|
|
3261
4589
|
if (options.character && options.character.length > 0) {
|
|
3262
4590
|
for (const charPath of options.character) {
|
|
3263
|
-
const resolvedPath =
|
|
4591
|
+
const resolvedPath = path22.resolve(charPath);
|
|
3264
4592
|
if (!fs10.existsSync(resolvedPath)) {
|
|
3265
|
-
|
|
4593
|
+
logger19.error(`Character file not found: ${resolvedPath}`);
|
|
3266
4594
|
throw new Error(`Character file not found: ${resolvedPath}`);
|
|
3267
4595
|
}
|
|
3268
4596
|
try {
|
|
3269
4597
|
const character = await loadCharacterTryPath2(resolvedPath);
|
|
3270
4598
|
if (character) {
|
|
3271
4599
|
characters.push(character);
|
|
3272
|
-
|
|
4600
|
+
logger19.info(`Successfully loaded character: ${character.name}`);
|
|
3273
4601
|
} else {
|
|
3274
|
-
|
|
4602
|
+
logger19.error(
|
|
3275
4603
|
`Failed to load character from ${resolvedPath}: Invalid or empty character file`
|
|
3276
4604
|
);
|
|
3277
4605
|
throw new Error(`Invalid character file: ${resolvedPath}`);
|
|
3278
4606
|
}
|
|
3279
4607
|
} catch (e) {
|
|
3280
|
-
|
|
4608
|
+
logger19.error(`Failed to load character from ${resolvedPath}:`, e);
|
|
3281
4609
|
throw new Error(`Invalid character file: ${resolvedPath}`);
|
|
3282
4610
|
}
|
|
3283
4611
|
}
|
|
@@ -3286,20 +4614,20 @@ var start = new Command7().name("start").description("Start the Eliza agent serv
|
|
|
3286
4614
|
const cwd = process.cwd();
|
|
3287
4615
|
const dirInfo = detectDirectoryType(cwd);
|
|
3288
4616
|
if (dirInfo.hasPackageJson && dirInfo.type !== "non-elizaos-dir") {
|
|
3289
|
-
|
|
4617
|
+
logger19.info("No character files specified, attempting to load project agents...");
|
|
3290
4618
|
const project = await loadProject(cwd);
|
|
3291
4619
|
if (project.agents && project.agents.length > 0) {
|
|
3292
|
-
|
|
4620
|
+
logger19.info(`Found ${project.agents.length} agent(s) in project configuration`);
|
|
3293
4621
|
projectAgents = project.agents;
|
|
3294
4622
|
for (const agent2 of project.agents) {
|
|
3295
4623
|
if (agent2.character) {
|
|
3296
|
-
|
|
4624
|
+
logger19.info(`Loaded character: ${agent2.character.name}`);
|
|
3297
4625
|
}
|
|
3298
4626
|
}
|
|
3299
4627
|
}
|
|
3300
4628
|
}
|
|
3301
4629
|
} catch (e) {
|
|
3302
|
-
|
|
4630
|
+
logger19.debug("Failed to load project agents, will use default character:", e);
|
|
3303
4631
|
}
|
|
3304
4632
|
}
|
|
3305
4633
|
await startAgents({ ...options, characters, projectAgents });
|
|
@@ -3378,18 +4706,18 @@ ${emoji.error("Error: Failed to run Phala CLI")}`);
|
|
|
3378
4706
|
var teeCommand = new Command9("tee").description("Manage TEE deployments").addCommand(phalaCliCommand);
|
|
3379
4707
|
|
|
3380
4708
|
// src/commands/test/index.ts
|
|
3381
|
-
import { logger as
|
|
4709
|
+
import { logger as logger26 } from "@elizaos/core";
|
|
3382
4710
|
import { Command as Command10, Option as Option2 } from "commander";
|
|
3383
4711
|
|
|
3384
4712
|
// src/commands/test/actions/run-all-tests.ts
|
|
3385
|
-
import { logger as
|
|
4713
|
+
import { logger as logger24 } from "@elizaos/core";
|
|
3386
4714
|
|
|
3387
4715
|
// src/commands/test/utils/project-utils.ts
|
|
3388
|
-
import { logger as
|
|
4716
|
+
import { logger as logger20 } from "@elizaos/core";
|
|
3389
4717
|
import * as fs11 from "fs";
|
|
3390
|
-
import
|
|
4718
|
+
import path23 from "path";
|
|
3391
4719
|
function getProjectType(testPath) {
|
|
3392
|
-
const targetPath = testPath ?
|
|
4720
|
+
const targetPath = testPath ? path23.resolve(process.cwd(), testPath) : process.cwd();
|
|
3393
4721
|
return detectDirectoryType(targetPath);
|
|
3394
4722
|
}
|
|
3395
4723
|
function processFilterName(name) {
|
|
@@ -3408,11 +4736,11 @@ async function installPluginDependencies(projectInfo) {
|
|
|
3408
4736
|
}
|
|
3409
4737
|
const project = await loadProject(process.cwd());
|
|
3410
4738
|
if (project.isPlugin && project.pluginModule?.dependencies && project.pluginModule.dependencies.length > 0) {
|
|
3411
|
-
const pluginsDir =
|
|
4739
|
+
const pluginsDir = path23.join(process.cwd(), ".eliza", "plugins");
|
|
3412
4740
|
if (!fs11.existsSync(pluginsDir)) {
|
|
3413
4741
|
await fs11.promises.mkdir(pluginsDir, { recursive: true });
|
|
3414
4742
|
}
|
|
3415
|
-
const packageJsonPath =
|
|
4743
|
+
const packageJsonPath = path23.join(pluginsDir, "package.json");
|
|
3416
4744
|
if (!fs11.existsSync(packageJsonPath)) {
|
|
3417
4745
|
const packageJsonContent = {
|
|
3418
4746
|
name: "test-plugin-dependencies",
|
|
@@ -3422,15 +4750,15 @@ async function installPluginDependencies(projectInfo) {
|
|
|
3422
4750
|
};
|
|
3423
4751
|
await fs11.promises.writeFile(packageJsonPath, JSON.stringify(packageJsonContent, null, 2));
|
|
3424
4752
|
}
|
|
3425
|
-
const { installPlugin: installPlugin2 } = await import("./utils-
|
|
4753
|
+
const { installPlugin: installPlugin2 } = await import("./utils-I3EA43DE.js");
|
|
3426
4754
|
for (const dependency of project.pluginModule.dependencies) {
|
|
3427
4755
|
await installPlugin2(dependency, pluginsDir);
|
|
3428
|
-
const dependencyPath =
|
|
4756
|
+
const dependencyPath = path23.join(pluginsDir, "node_modules", dependency);
|
|
3429
4757
|
if (fs11.existsSync(dependencyPath)) {
|
|
3430
4758
|
try {
|
|
3431
4759
|
await runBunCommand(["install"], dependencyPath);
|
|
3432
4760
|
} catch (error) {
|
|
3433
|
-
|
|
4761
|
+
logger20.warn(
|
|
3434
4762
|
`[Test Command] Failed to install devDependencies for ${dependency}: ${error}`
|
|
3435
4763
|
);
|
|
3436
4764
|
}
|
|
@@ -3440,18 +4768,18 @@ async function installPluginDependencies(projectInfo) {
|
|
|
3440
4768
|
}
|
|
3441
4769
|
|
|
3442
4770
|
// src/commands/test/actions/component-tests.ts
|
|
3443
|
-
import { logger as
|
|
4771
|
+
import { logger as logger22 } from "@elizaos/core";
|
|
3444
4772
|
import { spawn as spawn3 } from "child_process";
|
|
3445
|
-
import
|
|
4773
|
+
import path25 from "path";
|
|
3446
4774
|
|
|
3447
4775
|
// src/utils/testing/tsc-validator.ts
|
|
3448
|
-
import { logger as
|
|
4776
|
+
import { logger as logger21 } from "@elizaos/core";
|
|
3449
4777
|
import { execa as execa9 } from "execa";
|
|
3450
|
-
import
|
|
3451
|
-
import { existsSync as
|
|
4778
|
+
import path24 from "path";
|
|
4779
|
+
import { existsSync as existsSync16 } from "fs";
|
|
3452
4780
|
async function runTypeCheck(projectPath, strict = true) {
|
|
3453
|
-
const tsconfigPath =
|
|
3454
|
-
if (!
|
|
4781
|
+
const tsconfigPath = path24.join(projectPath, "tsconfig.json");
|
|
4782
|
+
if (!existsSync16(tsconfigPath)) {
|
|
3455
4783
|
return {
|
|
3456
4784
|
success: false,
|
|
3457
4785
|
errors: [`No tsconfig.json found at ${tsconfigPath}`],
|
|
@@ -3474,7 +4802,7 @@ async function runTypeCheck(projectPath, strict = true) {
|
|
|
3474
4802
|
warnings: stderr.includes("warning") ? [stderr] : []
|
|
3475
4803
|
};
|
|
3476
4804
|
} catch (error) {
|
|
3477
|
-
|
|
4805
|
+
logger21.error("TypeScript validation failed:", error);
|
|
3478
4806
|
return {
|
|
3479
4807
|
success: false,
|
|
3480
4808
|
errors: [`TypeScript validation error: ${error.message}`],
|
|
@@ -3488,37 +4816,39 @@ async function runComponentTests(testPath, options, projectInfo) {
|
|
|
3488
4816
|
const cwd = process.cwd();
|
|
3489
4817
|
const isPlugin2 = projectInfo.type === "elizaos-plugin";
|
|
3490
4818
|
if (!options.skipTypeCheck) {
|
|
3491
|
-
|
|
4819
|
+
logger22.info("Running TypeScript validation...");
|
|
3492
4820
|
const typeCheckResult = await runTypeCheck(cwd, true);
|
|
3493
4821
|
if (!typeCheckResult.success) {
|
|
3494
|
-
|
|
3495
|
-
typeCheckResult.errors.forEach((error) =>
|
|
4822
|
+
logger22.error("TypeScript validation failed:");
|
|
4823
|
+
typeCheckResult.errors.forEach((error) => logger22.error(error));
|
|
3496
4824
|
return { failed: true };
|
|
3497
4825
|
}
|
|
3498
|
-
|
|
4826
|
+
logger22.success("TypeScript validation passed");
|
|
3499
4827
|
}
|
|
3500
4828
|
if (!options.skipBuild) {
|
|
3501
4829
|
try {
|
|
3502
|
-
|
|
4830
|
+
logger22.info(`Building ${isPlugin2 ? "plugin" : "project"}...`);
|
|
3503
4831
|
await buildProject(cwd, isPlugin2);
|
|
3504
|
-
|
|
4832
|
+
logger22.success(`Build completed successfully`);
|
|
3505
4833
|
} catch (buildError) {
|
|
3506
|
-
|
|
4834
|
+
logger22.error(`Build failed: ${buildError}`);
|
|
3507
4835
|
return { failed: true };
|
|
3508
4836
|
}
|
|
3509
4837
|
}
|
|
3510
|
-
|
|
4838
|
+
logger22.info("Running component tests...");
|
|
3511
4839
|
return new Promise((resolve2) => {
|
|
3512
4840
|
const args = ["test", "--passWithNoTests"];
|
|
3513
4841
|
if (options.name) {
|
|
3514
4842
|
const baseName = processFilterName(options.name);
|
|
3515
4843
|
if (baseName) {
|
|
3516
|
-
|
|
4844
|
+
logger22.info(`Using test filter: ${baseName}`);
|
|
3517
4845
|
args.push("-t", baseName);
|
|
3518
4846
|
}
|
|
3519
4847
|
}
|
|
3520
|
-
const
|
|
3521
|
-
|
|
4848
|
+
const monorepoRoot = UserEnvironment.getInstance().findMonorepoRoot(process.cwd());
|
|
4849
|
+
const baseDir = monorepoRoot ?? process.cwd();
|
|
4850
|
+
const targetPath = testPath ? path25.resolve(baseDir, testPath) : process.cwd();
|
|
4851
|
+
logger22.info(`Executing: bun ${args.join(" ")} in ${targetPath}`);
|
|
3522
4852
|
const child = spawn3("bun", args, {
|
|
3523
4853
|
stdio: "inherit",
|
|
3524
4854
|
shell: false,
|
|
@@ -3532,11 +4862,11 @@ async function runComponentTests(testPath, options, projectInfo) {
|
|
|
3532
4862
|
}
|
|
3533
4863
|
});
|
|
3534
4864
|
child.on("close", (code) => {
|
|
3535
|
-
|
|
4865
|
+
logger22.info("Component tests completed");
|
|
3536
4866
|
resolve2({ failed: code !== 0 });
|
|
3537
4867
|
});
|
|
3538
4868
|
child.on("error", (error) => {
|
|
3539
|
-
|
|
4869
|
+
logger22.error("Error running component tests:", error);
|
|
3540
4870
|
resolve2({ failed: true });
|
|
3541
4871
|
});
|
|
3542
4872
|
});
|
|
@@ -3544,31 +4874,31 @@ async function runComponentTests(testPath, options, projectInfo) {
|
|
|
3544
4874
|
|
|
3545
4875
|
// src/commands/test/actions/e2e-tests.ts
|
|
3546
4876
|
import { AgentServer as AgentServer2, jsonToCharacter as jsonToCharacter2, loadCharacterTryPath as loadCharacterTryPath3 } from "@elizaos/server";
|
|
3547
|
-
import { logger as
|
|
3548
|
-
import * as
|
|
4877
|
+
import { logger as logger23 } from "@elizaos/core";
|
|
4878
|
+
import * as dotenv2 from "dotenv";
|
|
3549
4879
|
import * as fs12 from "fs";
|
|
3550
|
-
import
|
|
4880
|
+
import path26 from "path";
|
|
3551
4881
|
async function runE2eTests(testPath, options, projectInfo) {
|
|
3552
4882
|
if (!options.skipBuild) {
|
|
3553
4883
|
try {
|
|
3554
4884
|
const cwd = process.cwd();
|
|
3555
4885
|
const isPlugin2 = projectInfo.type === "elizaos-plugin";
|
|
3556
|
-
|
|
4886
|
+
logger23.info(`Building ${isPlugin2 ? "plugin" : "project"}...`);
|
|
3557
4887
|
await buildProject(cwd, isPlugin2);
|
|
3558
|
-
|
|
4888
|
+
logger23.info(`Build completed successfully`);
|
|
3559
4889
|
} catch (buildError) {
|
|
3560
|
-
|
|
3561
|
-
|
|
4890
|
+
logger23.error(`Build error: ${buildError}`);
|
|
4891
|
+
logger23.warn(`Attempting to continue with tests despite build error`);
|
|
3562
4892
|
}
|
|
3563
4893
|
}
|
|
3564
4894
|
let server;
|
|
3565
4895
|
try {
|
|
3566
4896
|
const runtimes = [];
|
|
3567
4897
|
const projectAgents = [];
|
|
3568
|
-
const elizaDir =
|
|
3569
|
-
const packageName =
|
|
4898
|
+
const elizaDir = path26.join(process.cwd(), ".eliza");
|
|
4899
|
+
const packageName = path26.basename(process.cwd());
|
|
3570
4900
|
const timestamp = Date.now();
|
|
3571
|
-
const uniqueDbDir =
|
|
4901
|
+
const uniqueDbDir = path26.join(process.cwd(), ".elizadb-test", `${packageName}-${timestamp}`);
|
|
3572
4902
|
const elizaDbDir = uniqueDbDir;
|
|
3573
4903
|
const envInfo = await UserEnvironment.getInstanceInfo();
|
|
3574
4904
|
const envFilePath = envInfo.paths.envFilePath;
|
|
@@ -3592,91 +4922,73 @@ async function runE2eTests(testPath, options, projectInfo) {
|
|
|
3592
4922
|
process.env.PGLITE_DATA_DIR = elizaDbDir;
|
|
3593
4923
|
console.info(`Set PGLITE_DATA_DIR to: ${elizaDbDir}`);
|
|
3594
4924
|
if (fs12.existsSync(envFilePath)) {
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
4925
|
+
logger23.info(`Loading environment variables from: ${envFilePath}`);
|
|
4926
|
+
dotenv2.config({ path: envFilePath });
|
|
4927
|
+
logger23.info("Environment variables loaded");
|
|
3598
4928
|
} else {
|
|
3599
|
-
|
|
3600
|
-
}
|
|
3601
|
-
try {
|
|
3602
|
-
logger21.info("Configuring database...");
|
|
3603
|
-
await promptForEnvVars("pglite");
|
|
3604
|
-
logger21.info("Database configuration completed");
|
|
3605
|
-
} catch (error) {
|
|
3606
|
-
logger21.error("Error configuring database:", error);
|
|
3607
|
-
if (error instanceof Error) {
|
|
3608
|
-
logger21.error("Error details:", error.message);
|
|
3609
|
-
logger21.error("Stack trace:", error.stack);
|
|
3610
|
-
}
|
|
3611
|
-
throw error;
|
|
4929
|
+
logger23.warn(`Environment file not found: ${envFilePath}`);
|
|
3612
4930
|
}
|
|
3613
4931
|
const postgresUrl = process.env.POSTGRES_URL;
|
|
3614
|
-
|
|
4932
|
+
logger23.info(
|
|
3615
4933
|
`PostgreSQL URL for e2e tests: ${postgresUrl ? "found" : "not found (will use PGlite)"}`
|
|
3616
4934
|
);
|
|
3617
|
-
|
|
4935
|
+
logger23.info("Creating server instance...");
|
|
3618
4936
|
server = new AgentServer2();
|
|
3619
|
-
|
|
3620
|
-
|
|
4937
|
+
logger23.info("Server instance created");
|
|
4938
|
+
logger23.info("Initializing server...");
|
|
3621
4939
|
try {
|
|
3622
4940
|
await server.initialize({
|
|
3623
4941
|
dataDir: elizaDbDir,
|
|
3624
4942
|
postgresUrl
|
|
3625
4943
|
});
|
|
3626
|
-
|
|
4944
|
+
logger23.info("Server initialized successfully");
|
|
3627
4945
|
} catch (initError) {
|
|
3628
|
-
|
|
4946
|
+
logger23.error("Server initialization failed:", initError);
|
|
3629
4947
|
throw initError;
|
|
3630
4948
|
}
|
|
3631
4949
|
let project;
|
|
3632
4950
|
try {
|
|
3633
|
-
|
|
4951
|
+
logger23.info("Attempting to load project or plugin...");
|
|
3634
4952
|
const monorepoRoot = UserEnvironment.getInstance().findMonorepoRoot(process.cwd());
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
"Could not find monorepo root. Make sure to run tests from within the Eliza project."
|
|
3638
|
-
);
|
|
3639
|
-
}
|
|
3640
|
-
const targetPath = testPath ? path25.resolve(monorepoRoot, testPath) : process.cwd();
|
|
4953
|
+
const baseDir = monorepoRoot ?? process.cwd();
|
|
4954
|
+
const targetPath = testPath ? path26.resolve(baseDir, testPath) : process.cwd();
|
|
3641
4955
|
project = await loadProject(targetPath);
|
|
3642
4956
|
if (!project || !project.agents || project.agents.length === 0) {
|
|
3643
4957
|
throw new Error("No agents found in project configuration");
|
|
3644
4958
|
}
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
);
|
|
3648
|
-
logger21.info("Setting up server properties...");
|
|
4959
|
+
logger23.info(`Found ${project.agents.length} agents`);
|
|
4960
|
+
logger23.info("Setting up server properties...");
|
|
3649
4961
|
server.startAgent = async (character) => {
|
|
3650
|
-
|
|
4962
|
+
logger23.info(`Starting agent for character ${character.name}`);
|
|
3651
4963
|
return startAgent(character, server, void 0, [], { isTestMode: true });
|
|
3652
4964
|
};
|
|
3653
4965
|
server.loadCharacterTryPath = loadCharacterTryPath3;
|
|
3654
4966
|
server.jsonToCharacter = jsonToCharacter2;
|
|
3655
|
-
|
|
4967
|
+
logger23.info("Server properties set up");
|
|
3656
4968
|
const desiredPort = options.port || Number.parseInt(process.env.SERVER_PORT || "3000");
|
|
3657
4969
|
const serverPort = await findNextAvailablePort(desiredPort);
|
|
3658
4970
|
if (serverPort !== desiredPort) {
|
|
3659
|
-
|
|
4971
|
+
logger23.warn(`Port ${desiredPort} is in use for testing, using port ${serverPort} instead.`);
|
|
3660
4972
|
}
|
|
3661
|
-
|
|
4973
|
+
logger23.info("Starting server...");
|
|
3662
4974
|
try {
|
|
3663
4975
|
await server.start(serverPort);
|
|
3664
|
-
|
|
4976
|
+
logger23.info("Server started successfully on port", serverPort);
|
|
3665
4977
|
} catch (error) {
|
|
3666
|
-
|
|
4978
|
+
logger23.error("Error starting server:", error);
|
|
3667
4979
|
if (error instanceof Error) {
|
|
3668
|
-
|
|
3669
|
-
|
|
4980
|
+
logger23.error("Error details:", error.message);
|
|
4981
|
+
logger23.error("Stack trace:", error.stack);
|
|
3670
4982
|
}
|
|
3671
4983
|
throw error;
|
|
3672
4984
|
}
|
|
3673
4985
|
try {
|
|
3674
|
-
|
|
4986
|
+
logger23.info(
|
|
3675
4987
|
`Found ${project.agents.length} agents in ${project.isPlugin ? "plugin" : "project"}`
|
|
3676
4988
|
);
|
|
3677
4989
|
if (project.isPlugin || project.agents.length === 0) {
|
|
3678
4990
|
process.env.ELIZA_TESTING_PLUGIN = "true";
|
|
3679
|
-
|
|
4991
|
+
logger23.info("Using default Eliza character as test agent");
|
|
3680
4992
|
try {
|
|
3681
4993
|
const pluginUnderTest = project.pluginModule;
|
|
3682
4994
|
if (!pluginUnderTest) {
|
|
@@ -3699,16 +5011,16 @@ async function runE2eTests(testPath, options, projectInfo) {
|
|
|
3699
5011
|
plugins: runtime.plugins
|
|
3700
5012
|
// Pass all plugins, not just the one under test
|
|
3701
5013
|
});
|
|
3702
|
-
|
|
5014
|
+
logger23.info("Default test agent started successfully");
|
|
3703
5015
|
} catch (pluginError) {
|
|
3704
|
-
|
|
5016
|
+
logger23.error(`Error starting plugin test agent: ${pluginError}`);
|
|
3705
5017
|
throw pluginError;
|
|
3706
5018
|
}
|
|
3707
5019
|
} else {
|
|
3708
5020
|
for (const agent2 of project.agents) {
|
|
3709
5021
|
try {
|
|
3710
5022
|
const originalCharacter = { ...agent2.character };
|
|
3711
|
-
|
|
5023
|
+
logger23.debug(`Starting agent: ${originalCharacter.name}`);
|
|
3712
5024
|
const runtime = await startAgent(
|
|
3713
5025
|
originalCharacter,
|
|
3714
5026
|
server,
|
|
@@ -3721,28 +5033,28 @@ async function runE2eTests(testPath, options, projectInfo) {
|
|
|
3721
5033
|
projectAgents.push(agent2);
|
|
3722
5034
|
await new Promise((resolve2) => setTimeout(resolve2, 1e3));
|
|
3723
5035
|
} catch (agentError) {
|
|
3724
|
-
|
|
5036
|
+
logger23.error(`Error starting agent ${agent2.character.name}:`, agentError);
|
|
3725
5037
|
if (agentError instanceof Error) {
|
|
3726
|
-
|
|
3727
|
-
|
|
5038
|
+
logger23.error("Error details:", agentError.message);
|
|
5039
|
+
logger23.error("Stack trace:", agentError.stack);
|
|
3728
5040
|
}
|
|
3729
|
-
|
|
5041
|
+
logger23.warn(`Skipping agent ${agent2.character.name} due to startup error`);
|
|
3730
5042
|
}
|
|
3731
5043
|
}
|
|
3732
5044
|
}
|
|
3733
5045
|
if (runtimes.length === 0) {
|
|
3734
5046
|
throw new Error("Failed to start any agents from project");
|
|
3735
5047
|
}
|
|
3736
|
-
|
|
5048
|
+
logger23.debug(`Successfully started ${runtimes.length} agents for testing`);
|
|
3737
5049
|
let totalFailed = 0;
|
|
3738
5050
|
let anyTestsFound = false;
|
|
3739
5051
|
for (let i = 0; i < runtimes.length; i++) {
|
|
3740
5052
|
const runtime = runtimes[i];
|
|
3741
5053
|
const projectAgent = projectAgents[i];
|
|
3742
5054
|
if (project.isPlugin) {
|
|
3743
|
-
|
|
5055
|
+
logger23.debug(`Running tests for plugin: ${project.pluginModule?.name}`);
|
|
3744
5056
|
} else {
|
|
3745
|
-
|
|
5057
|
+
logger23.debug(`Running tests for agent: ${runtime.character.name}`);
|
|
3746
5058
|
}
|
|
3747
5059
|
const testRunner = new TestRunner(runtime, projectAgent);
|
|
3748
5060
|
const currentDirInfo = projectInfo;
|
|
@@ -3763,17 +5075,17 @@ async function runE2eTests(testPath, options, projectInfo) {
|
|
|
3763
5075
|
}
|
|
3764
5076
|
return { failed: anyTestsFound ? totalFailed > 0 : false };
|
|
3765
5077
|
} catch (error) {
|
|
3766
|
-
|
|
5078
|
+
logger23.error("Error in runE2eTests:", error);
|
|
3767
5079
|
if (error instanceof Error) {
|
|
3768
|
-
|
|
3769
|
-
|
|
5080
|
+
logger23.error("Error details:", error.message);
|
|
5081
|
+
logger23.error("Stack trace:", error.stack);
|
|
3770
5082
|
} else {
|
|
3771
|
-
|
|
3772
|
-
|
|
5083
|
+
logger23.error("Unknown error type:", typeof error);
|
|
5084
|
+
logger23.error("Error value:", error);
|
|
3773
5085
|
try {
|
|
3774
|
-
|
|
5086
|
+
logger23.error("Stringified error:", JSON.stringify(error, null, 2));
|
|
3775
5087
|
} catch (e) {
|
|
3776
|
-
|
|
5088
|
+
logger23.error("Could not stringify error:", e);
|
|
3777
5089
|
}
|
|
3778
5090
|
}
|
|
3779
5091
|
return { failed: true };
|
|
@@ -3787,7 +5099,7 @@ async function runE2eTests(testPath, options, projectInfo) {
|
|
|
3787
5099
|
fs12.rmSync(elizaDbDir, { recursive: true, force: true });
|
|
3788
5100
|
console.info(`Successfully cleaned up test database directory`);
|
|
3789
5101
|
}
|
|
3790
|
-
const testDir =
|
|
5102
|
+
const testDir = path26.dirname(elizaDbDir);
|
|
3791
5103
|
if (fs12.existsSync(testDir) && fs12.readdirSync(testDir).length === 0) {
|
|
3792
5104
|
fs12.rmSync(testDir, { recursive: true, force: true });
|
|
3793
5105
|
}
|
|
@@ -3796,33 +5108,33 @@ async function runE2eTests(testPath, options, projectInfo) {
|
|
|
3796
5108
|
}
|
|
3797
5109
|
}
|
|
3798
5110
|
} catch (error) {
|
|
3799
|
-
|
|
5111
|
+
logger23.error("Error in runE2eTests:", error);
|
|
3800
5112
|
if (error instanceof Error) {
|
|
3801
|
-
|
|
3802
|
-
|
|
5113
|
+
logger23.error("Error details:", error.message);
|
|
5114
|
+
logger23.error("Stack trace:", error.stack);
|
|
3803
5115
|
} else {
|
|
3804
|
-
|
|
3805
|
-
|
|
5116
|
+
logger23.error("Unknown error type:", typeof error);
|
|
5117
|
+
logger23.error("Error value:", error);
|
|
3806
5118
|
try {
|
|
3807
|
-
|
|
5119
|
+
logger23.error("Stringified error:", JSON.stringify(error, null, 2));
|
|
3808
5120
|
} catch (e) {
|
|
3809
|
-
|
|
5121
|
+
logger23.error("Could not stringify error:", e);
|
|
3810
5122
|
}
|
|
3811
5123
|
}
|
|
3812
5124
|
return { failed: true };
|
|
3813
5125
|
}
|
|
3814
5126
|
} catch (error) {
|
|
3815
|
-
|
|
5127
|
+
logger23.error("Error in runE2eTests:", error);
|
|
3816
5128
|
if (error instanceof Error) {
|
|
3817
|
-
|
|
3818
|
-
|
|
5129
|
+
logger23.error("Error details:", error.message);
|
|
5130
|
+
logger23.error("Stack trace:", error.stack);
|
|
3819
5131
|
} else {
|
|
3820
|
-
|
|
3821
|
-
|
|
5132
|
+
logger23.error("Unknown error type:", typeof error);
|
|
5133
|
+
logger23.error("Error value:", error);
|
|
3822
5134
|
try {
|
|
3823
|
-
|
|
5135
|
+
logger23.error("Stringified error:", JSON.stringify(error, null, 2));
|
|
3824
5136
|
} catch (e) {
|
|
3825
|
-
|
|
5137
|
+
logger23.error("Could not stringify error:", e);
|
|
3826
5138
|
}
|
|
3827
5139
|
}
|
|
3828
5140
|
return { failed: true };
|
|
@@ -3835,15 +5147,15 @@ async function runAllTests(testPath, options) {
|
|
|
3835
5147
|
if (!options.skipBuild) {
|
|
3836
5148
|
const componentResult = await runComponentTests(testPath, options, projectInfo);
|
|
3837
5149
|
if (componentResult.failed) {
|
|
3838
|
-
|
|
5150
|
+
logger24.error("Component tests failed. Continuing to e2e tests...");
|
|
3839
5151
|
}
|
|
3840
5152
|
}
|
|
3841
5153
|
const e2eResult = await runE2eTests(testPath, options, projectInfo);
|
|
3842
5154
|
if (e2eResult.failed) {
|
|
3843
|
-
|
|
5155
|
+
logger24.error("E2E tests failed.");
|
|
3844
5156
|
process.exit(1);
|
|
3845
5157
|
}
|
|
3846
|
-
|
|
5158
|
+
logger24.success("All tests passed successfully!");
|
|
3847
5159
|
process.exit(0);
|
|
3848
5160
|
}
|
|
3849
5161
|
|
|
@@ -3851,9 +5163,9 @@ async function runAllTests(testPath, options) {
|
|
|
3851
5163
|
import * as net from "net";
|
|
3852
5164
|
|
|
3853
5165
|
// src/commands/test/utils/plugin-utils.ts
|
|
3854
|
-
import { logger as
|
|
5166
|
+
import { logger as logger25 } from "@elizaos/core";
|
|
3855
5167
|
import * as fs13 from "fs";
|
|
3856
|
-
import
|
|
5168
|
+
import path27 from "path";
|
|
3857
5169
|
|
|
3858
5170
|
// src/commands/test/index.ts
|
|
3859
5171
|
var test = new Command10().name("test").description("Run tests for the current project or a specified plugin").argument("[path]", "Optional path to the project or plugin to test").addOption(
|
|
@@ -3863,31 +5175,31 @@ var test = new Command10().name("test").description("Run tests for the current p
|
|
|
3863
5175
|
const projectInfo = getProjectType(testPath);
|
|
3864
5176
|
await installPluginDependencies(projectInfo);
|
|
3865
5177
|
}).action(async (testPath, options) => {
|
|
3866
|
-
|
|
5178
|
+
logger26.info("Starting tests...");
|
|
3867
5179
|
try {
|
|
3868
5180
|
const projectInfo = getProjectType(testPath);
|
|
3869
5181
|
switch (options.type) {
|
|
3870
5182
|
case "component":
|
|
3871
|
-
|
|
5183
|
+
logger26.info("Running component tests only...");
|
|
3872
5184
|
const componentResult = await runComponentTests(testPath, options, projectInfo);
|
|
3873
5185
|
if (componentResult.failed) {
|
|
3874
|
-
|
|
5186
|
+
logger26.error("Component tests failed.");
|
|
3875
5187
|
process.exit(1);
|
|
3876
5188
|
}
|
|
3877
|
-
|
|
5189
|
+
logger26.success("Component tests passed successfully!");
|
|
3878
5190
|
break;
|
|
3879
5191
|
case "e2e":
|
|
3880
|
-
|
|
5192
|
+
logger26.info("Running e2e tests only...");
|
|
3881
5193
|
const e2eResult = await runE2eTests(testPath, options, projectInfo);
|
|
3882
5194
|
if (e2eResult.failed) {
|
|
3883
|
-
|
|
5195
|
+
logger26.error("E2E tests failed.");
|
|
3884
5196
|
process.exit(1);
|
|
3885
5197
|
}
|
|
3886
|
-
|
|
5198
|
+
logger26.success("E2E tests passed successfully!");
|
|
3887
5199
|
break;
|
|
3888
5200
|
case "all":
|
|
3889
5201
|
default:
|
|
3890
|
-
|
|
5202
|
+
logger26.info("Running all tests...");
|
|
3891
5203
|
await runAllTests(testPath, options);
|
|
3892
5204
|
break;
|
|
3893
5205
|
}
|
|
@@ -3898,11 +5210,8 @@ var test = new Command10().name("test").description("Run tests for the current p
|
|
|
3898
5210
|
});
|
|
3899
5211
|
|
|
3900
5212
|
// src/index.ts
|
|
3901
|
-
import { logger as
|
|
5213
|
+
import { logger as logger27 } from "@elizaos/core";
|
|
3902
5214
|
import { Command as Command11 } from "commander";
|
|
3903
|
-
import { existsSync as existsSync17, readFileSync as readFileSync5 } from "fs";
|
|
3904
|
-
import path27, { dirname } from "path";
|
|
3905
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3906
5215
|
process.env.NODE_OPTIONS = "--no-deprecation";
|
|
3907
5216
|
process.env.NODE_NO_WARNINGS = "1";
|
|
3908
5217
|
process.on("SIGINT", () => process.exit(0));
|
|
@@ -3914,15 +5223,7 @@ async function main() {
|
|
|
3914
5223
|
if (process.argv.includes("--no-auto-install")) {
|
|
3915
5224
|
process.env.ELIZA_NO_AUTO_INSTALL = "true";
|
|
3916
5225
|
}
|
|
3917
|
-
const
|
|
3918
|
-
const __dirname = dirname(__filename);
|
|
3919
|
-
const packageJsonPath = path27.resolve(__dirname, "../package.json");
|
|
3920
|
-
let version = "0.0.0";
|
|
3921
|
-
if (!existsSync17(packageJsonPath)) {
|
|
3922
|
-
} else {
|
|
3923
|
-
const packageJson = JSON.parse(readFileSync5(packageJsonPath, "utf-8"));
|
|
3924
|
-
version = packageJson.version;
|
|
3925
|
-
}
|
|
5226
|
+
const version = getVersion();
|
|
3926
5227
|
const args = process.argv.slice(2);
|
|
3927
5228
|
const isUpdateCommand = args.includes("update");
|
|
3928
5229
|
const willShowBanner = args.length === 0;
|
|
@@ -3938,6 +5239,6 @@ async function main() {
|
|
|
3938
5239
|
await program.parseAsync();
|
|
3939
5240
|
}
|
|
3940
5241
|
main().catch((error) => {
|
|
3941
|
-
|
|
5242
|
+
logger27.error("An error occurred:", error);
|
|
3942
5243
|
process.exit(1);
|
|
3943
5244
|
});
|