426e9eeabd
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Waiting to run
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Waiting to run
Build Agent Image / build-and-push (push) Waiting to run
Chat shell gestures / Chat shell gesture + parity e2e (push) Waiting to run
ci / test (push) Waiting to run
ci / lint-and-format (push) Waiting to run
ci / build (push) Waiting to run
ci / dev-startup (push) Waiting to run
Cloud Gateway Discord / Test (push) Waiting to run
Cloud Gateway Webhook / Test (push) Waiting to run
Cloud Tests / lint-and-types (push) Waiting to run
Cloud Tests / unit-tests (push) Waiting to run
Cloud Tests / integration-tests (push) Waiting to run
Cloud Tests / e2e-tests (push) Blocked by required conditions
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Apps Worker (Product 2) / Determine environment (push) Waiting to run
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Blocked by required conditions
Deploy Eliza Provisioning Worker / Determine environment (push) Waiting to run
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Blocked by required conditions
Dev Smoke / Classify changed paths (push) Waiting to run
Dev Smoke / bun run dev onboarding chat (push) Blocked by required conditions
Dev Smoke / Vite HMR dependency-level smoke (push) Blocked by required conditions
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Waiting to run
gitleaks / gitleaks (push) Waiting to run
Markdown Links / Relative Markdown Links (push) Waiting to run
Publish @elizaos/example-code / check_npm (push) Waiting to run
Publish @elizaos/example-code / publish_npm (push) Blocked by required conditions
Publish @elizaos/plugin-elizacloud / verify_version (push) Waiting to run
Publish @elizaos/plugin-elizacloud / publish_npm (push) Blocked by required conditions
Quality (Extended) / Homepage Build (PR smoke) (push) Waiting to run
Quality (Extended) / Comment-only diff guard (push) Waiting to run
Quality (Extended) / Format + Type Safety Ratchet (push) Waiting to run
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Waiting to run
Quality (Extended) / Develop Gate (lint) (push) Waiting to run
Sandbox Live Smoke / Sandbox live smoke (push) Waiting to run
Snap Build & Test / Build Snap (amd64) (push) Waiting to run
Snap Build & Test / Build Snap (arm64) (push) Waiting to run
supply-chain / sbom (push) Waiting to run
supply-chain / vulnerability-scan (push) Waiting to run
Build, Push & Deploy to Phala Cloud / build-and-push (push) Waiting to run
Test Packaging / Validate Packaging Configs (push) Waiting to run
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Waiting to run
Test Packaging / Pack & Test JS Tarballs (push) Waiting to run
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Waiting to run
UI Fixture E2E / ui-fixture-e2e (push) Waiting to run
UI Fixture E2E / fixture-e2e (push) Waiting to run
UI Story Gate / story-gate (push) Waiting to run
vault-ci / test (macos-latest) (push) Waiting to run
vault-ci / test (ubuntu-latest) (push) Waiting to run
vault-ci / test (windows-latest) (push) Waiting to run
vault-ci / app-core wiring tests (push) Waiting to run
verify-patches / verify patches/CHECKSUMS.sha256 (push) Waiting to run
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Waiting to run
Voice Benchmark Smoke / voice bench smoke summary (push) Blocked by required conditions
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Waiting to run
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Waiting to run
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Waiting to run
Test Packaging / Build & Test PyPI Package (push) Waiting to run
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
426 lines
12 KiB
TypeScript
426 lines
12 KiB
TypeScript
/** Defines app-core eliza package paths ts behavior for dashboard host and runtime integration. */
|
|
import { existsSync } from "node:fs";
|
|
import { createRequire } from "node:module";
|
|
import path from "node:path";
|
|
import { pathToFileURL } from "node:url";
|
|
|
|
const skipLocalUpstreams =
|
|
process.env.ELIZA_SKIP_LOCAL_UPSTREAMS === "1" ||
|
|
process.env.ELIZA_SKIP_LOCAL_UPSTREAMS === "1";
|
|
|
|
function getRepoLocalWorkspaceRoot(
|
|
packageName: string,
|
|
repoRoot: string,
|
|
): string | undefined {
|
|
if (skipLocalUpstreams) {
|
|
return undefined;
|
|
}
|
|
|
|
if (packageName === "@elizaos/core") {
|
|
return getRepoLocalElizaCoreRoot(packageName, repoRoot);
|
|
}
|
|
|
|
const relativeRoots: Record<string, string[]> = {
|
|
"@elizaos/agent": [
|
|
"packages/agent",
|
|
"eliza/packages/agent",
|
|
"../eliza/packages/agent",
|
|
],
|
|
"@elizaos/app-core": [
|
|
"packages/app-core",
|
|
"eliza/packages/app-core",
|
|
"../eliza/packages/app-core",
|
|
],
|
|
"@elizaos/shared": [
|
|
"packages/shared",
|
|
"eliza/packages/shared",
|
|
"../eliza/packages/shared",
|
|
],
|
|
"@elizaos/ui": ["packages/ui", "eliza/packages/ui", "../eliza/packages/ui"],
|
|
};
|
|
|
|
for (const relativeRoot of relativeRoots[packageName] ?? []) {
|
|
const candidate = path.resolve(repoRoot, relativeRoot);
|
|
if (existsSync(path.join(candidate, "package.json"))) {
|
|
return candidate;
|
|
}
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
/**
|
|
* Return the repo-local eliza core workspace root when it is checked out as
|
|
* part of the Eliza repo. This avoids relying on node_modules symlinks which
|
|
* Bun can rewrite differently across fresh CI installs.
|
|
*/
|
|
function getRepoLocalElizaCoreRoot(
|
|
packageName: string,
|
|
repoRoot: string,
|
|
): string | undefined {
|
|
if (packageName !== "@elizaos/core" || skipLocalUpstreams) {
|
|
return undefined;
|
|
}
|
|
|
|
const elizaRoots = [
|
|
path.resolve(repoRoot),
|
|
path.resolve(repoRoot, "eliza"),
|
|
path.resolve(repoRoot, "..", "eliza"),
|
|
];
|
|
|
|
for (const elizaRoot of elizaRoots) {
|
|
if (!existsSync(path.join(elizaRoot, "package.json"))) {
|
|
continue;
|
|
}
|
|
|
|
const candidate = path.join(elizaRoot, "packages", "core");
|
|
if (!existsSync(path.join(candidate, "package.json"))) {
|
|
continue;
|
|
}
|
|
|
|
// Require both a source entry AND installed dependencies. CI checks out the
|
|
// submodule (submodules: recursive) but skips its dependency install
|
|
// (ELIZA_SKIP_LOCAL_UPSTREAMS=1), so the source exists but imports of
|
|
// transitive deps like 'dedent' or 'adze' fail at runtime.
|
|
const hasSource =
|
|
existsSync(path.join(candidate, "dist", "node", "index.node.js")) ||
|
|
existsSync(path.join(candidate, "dist", "index.js")) ||
|
|
existsSync(path.join(candidate, "src", "index.node.ts")) ||
|
|
existsSync(path.join(candidate, "src", "index.ts")) ||
|
|
existsSync(path.join(candidate, "index.node.ts")) ||
|
|
existsSync(path.join(candidate, "index.ts"));
|
|
const hasDeps = existsSync(path.join(candidate, "node_modules"));
|
|
|
|
if (hasSource && hasDeps) {
|
|
return candidate;
|
|
}
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
function isRepoLocalElizaCorePackageRoot(
|
|
packageName: string,
|
|
packageRoot: string,
|
|
repoRoot: string,
|
|
): boolean {
|
|
if (packageName !== "@elizaos/core") {
|
|
return false;
|
|
}
|
|
|
|
const localRoot = getRepoLocalElizaCoreRoot(packageName, repoRoot);
|
|
if (!localRoot) {
|
|
return false;
|
|
}
|
|
|
|
return path.resolve(packageRoot) === path.resolve(localRoot);
|
|
}
|
|
|
|
const MODULE_EXTENSIONS = [
|
|
".ts",
|
|
".tsx",
|
|
".mts",
|
|
".js",
|
|
".jsx",
|
|
".mjs",
|
|
".cjs",
|
|
];
|
|
const require = createRequire(import.meta.url);
|
|
|
|
type ModuleNamespace = Record<string, unknown> & {
|
|
default?: Record<string, unknown>;
|
|
};
|
|
|
|
function getRequireFor(baseDir?: string) {
|
|
if (!baseDir) {
|
|
return require;
|
|
}
|
|
|
|
return createRequire(path.join(baseDir, "package.json"));
|
|
}
|
|
|
|
function firstExistingPath(
|
|
candidates: Array<string | undefined>,
|
|
): string | undefined {
|
|
return candidates.find(
|
|
(candidate): candidate is string =>
|
|
typeof candidate === "string" && existsSync(candidate),
|
|
);
|
|
}
|
|
|
|
export function resolveModuleEntry(basePath: string): string {
|
|
if (existsSync(basePath)) {
|
|
return basePath;
|
|
}
|
|
|
|
const withExtension = firstExistingPath(
|
|
MODULE_EXTENSIONS.map((extension) => `${basePath}${extension}`),
|
|
);
|
|
|
|
return withExtension ?? basePath;
|
|
}
|
|
|
|
export function getInstalledPackageRoot(
|
|
packageName: string,
|
|
fromDir?: string,
|
|
): string | undefined {
|
|
if (fromDir) {
|
|
const localPackage = getRepoLocalWorkspaceRoot(packageName, fromDir);
|
|
if (localPackage) return localPackage;
|
|
}
|
|
|
|
const scopedRequire = getRequireFor(fromDir);
|
|
|
|
try {
|
|
return path.dirname(scopedRequire.resolve(`${packageName}/package.json`));
|
|
} catch {
|
|
try {
|
|
const entryPath = scopedRequire.resolve(packageName);
|
|
return path.dirname(entryPath);
|
|
} catch {
|
|
return undefined;
|
|
}
|
|
}
|
|
}
|
|
|
|
export function getInstalledPackageEntry(
|
|
packageName: string,
|
|
repoRoot: string,
|
|
subpath?: "node",
|
|
): string | undefined {
|
|
const packageRoot = getInstalledPackageRoot(packageName, repoRoot);
|
|
if (!packageRoot) {
|
|
return undefined;
|
|
}
|
|
|
|
const preferSource = isRepoLocalElizaCorePackageRoot(
|
|
packageName,
|
|
packageRoot,
|
|
repoRoot,
|
|
);
|
|
const candidates = preferSource
|
|
? subpath === "node"
|
|
? [
|
|
path.join(packageRoot, "src", "index.node"),
|
|
path.join(packageRoot, "src", "index"),
|
|
path.join(packageRoot, "dist", "node", "index.node"),
|
|
path.join(packageRoot, "dist", "index"),
|
|
path.join(packageRoot, "index.node"),
|
|
path.join(packageRoot, "index"),
|
|
]
|
|
: [
|
|
path.join(packageRoot, "src", "index.node"),
|
|
path.join(packageRoot, "src", "index"),
|
|
path.join(packageRoot, "dist", "node", "index.node"),
|
|
path.join(packageRoot, "dist", "index"),
|
|
path.join(packageRoot, "index.node"),
|
|
path.join(packageRoot, "index"),
|
|
]
|
|
: subpath === "node"
|
|
? [
|
|
path.join(packageRoot, "dist", "node", "index.node"),
|
|
path.join(packageRoot, "index.node"),
|
|
path.join(packageRoot, "src", "index.node"),
|
|
path.join(packageRoot, "src", "index"),
|
|
path.join(packageRoot, "index"),
|
|
]
|
|
: [
|
|
path.join(packageRoot, "dist", "node", "index.node"),
|
|
path.join(packageRoot, "dist", "index"),
|
|
path.join(packageRoot, "src", "index"),
|
|
path.join(packageRoot, "index.node"),
|
|
path.join(packageRoot, "index"),
|
|
];
|
|
|
|
const resolvedCandidate = candidates
|
|
.map((candidate) => resolveModuleEntry(candidate))
|
|
.find((candidate) => existsSync(candidate));
|
|
|
|
return resolvedCandidate ?? resolveModuleEntry(candidates[0]);
|
|
}
|
|
|
|
function getNamedExport<T>(
|
|
moduleNamespace: ModuleNamespace,
|
|
exportName: string,
|
|
): T | undefined {
|
|
if (exportName in moduleNamespace) {
|
|
return moduleNamespace[exportName] as T;
|
|
}
|
|
|
|
const defaultNamespace = moduleNamespace.default;
|
|
if (
|
|
defaultNamespace &&
|
|
typeof defaultNamespace === "object" &&
|
|
exportName in defaultNamespace
|
|
) {
|
|
return defaultNamespace[exportName] as T;
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
async function tryImportNamedExport<T>(
|
|
specifier: string,
|
|
exportName: string,
|
|
): Promise<{ value?: T; error?: string }> {
|
|
try {
|
|
const moduleNamespace = (await import(specifier)) as ModuleNamespace;
|
|
const value = getNamedExport<T>(moduleNamespace, exportName);
|
|
if (value !== undefined) {
|
|
return { value };
|
|
}
|
|
|
|
return {
|
|
error: `${specifier}: missing export ${exportName}`,
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
error: `${specifier}: ${error instanceof Error ? error.message : String(error)}`,
|
|
};
|
|
}
|
|
}
|
|
|
|
export async function getInstalledPackageNamedExport<T>(
|
|
packageName: string,
|
|
exportName: string,
|
|
repoRoot: string,
|
|
subpath?: "node",
|
|
): Promise<T> {
|
|
const attempts: string[] = [];
|
|
const specifiers = subpath
|
|
? [`${packageName}/${subpath}`, packageName]
|
|
: [packageName];
|
|
|
|
for (const specifier of specifiers) {
|
|
const result = await tryImportNamedExport<T>(specifier, exportName);
|
|
if (result.value !== undefined) {
|
|
return result.value;
|
|
}
|
|
if (result.error) {
|
|
attempts.push(result.error);
|
|
}
|
|
}
|
|
|
|
const entry = getInstalledPackageEntry(packageName, repoRoot, subpath);
|
|
if (entry) {
|
|
const result = await tryImportNamedExport<T>(
|
|
pathToFileURL(entry).href,
|
|
exportName,
|
|
);
|
|
if (result.value !== undefined) {
|
|
return result.value;
|
|
}
|
|
if (result.error) {
|
|
attempts.push(result.error);
|
|
}
|
|
}
|
|
|
|
throw new TypeError(
|
|
`${exportName} export not found in ${packageName}. Tried: ${attempts.join(" | ")}`,
|
|
);
|
|
}
|
|
|
|
export function getElizaCoreEntry(repoRoot: string): string | undefined {
|
|
const packageRoot = getInstalledPackageRoot("@elizaos/core", repoRoot);
|
|
if (!packageRoot) {
|
|
return undefined;
|
|
}
|
|
|
|
const candidates = isRepoLocalElizaCorePackageRoot(
|
|
"@elizaos/core",
|
|
packageRoot,
|
|
repoRoot,
|
|
)
|
|
? [
|
|
path.join(packageRoot, "src", "index.node"),
|
|
path.join(packageRoot, "src", "index"),
|
|
path.join(packageRoot, "dist", "node", "index.node"),
|
|
path.join(packageRoot, "dist", "index"),
|
|
path.join(packageRoot, "index.node"),
|
|
path.join(packageRoot, "index"),
|
|
]
|
|
: [
|
|
path.join(packageRoot, "dist", "node", "index.node"),
|
|
path.join(packageRoot, "dist", "index"),
|
|
path.join(packageRoot, "src", "index.node"),
|
|
path.join(packageRoot, "src", "index"),
|
|
path.join(packageRoot, "index.node"),
|
|
path.join(packageRoot, "index"),
|
|
];
|
|
|
|
const resolvedCandidate = candidates
|
|
.map((candidate) => resolveModuleEntry(candidate))
|
|
.find((candidate) => existsSync(candidate));
|
|
|
|
return resolvedCandidate ?? resolveModuleEntry(candidates[0]);
|
|
}
|
|
|
|
export function getAutonomousSourceRoot(repoRoot: string): string | undefined {
|
|
const packageRoot =
|
|
getInstalledPackageRoot("@elizaos/agent", repoRoot) ??
|
|
getInstalledPackageRoot("@elizaos/agent", repoRoot);
|
|
|
|
if (!packageRoot) {
|
|
return undefined;
|
|
}
|
|
|
|
if (path.basename(packageRoot) === "src") {
|
|
return packageRoot;
|
|
}
|
|
|
|
const directSrc = path.join(packageRoot, "src");
|
|
if (existsSync(directSrc)) {
|
|
return directSrc;
|
|
}
|
|
|
|
return path.join(packageRoot, "packages", "agent", "src");
|
|
}
|
|
|
|
export function getAppCoreSourceRoot(repoRoot: string): string | undefined {
|
|
const packageRoot =
|
|
getInstalledPackageRoot("@elizaos/app-core", repoRoot) ??
|
|
getInstalledPackageRoot("@elizaos/app-core", repoRoot);
|
|
if (!packageRoot) {
|
|
return undefined;
|
|
}
|
|
|
|
if (path.basename(packageRoot) === "src") {
|
|
return packageRoot;
|
|
}
|
|
|
|
const sourceRoot = path.join(packageRoot, "src");
|
|
return existsSync(sourceRoot) ? sourceRoot : packageRoot;
|
|
}
|
|
|
|
export function getSharedSourceRoot(repoRoot: string): string | undefined {
|
|
const packageRoot =
|
|
getInstalledPackageRoot("@elizaos/shared", repoRoot) ??
|
|
getInstalledPackageRoot("@elizaos/shared", repoRoot);
|
|
if (!packageRoot) {
|
|
return undefined;
|
|
}
|
|
|
|
if (path.basename(packageRoot) === "src") {
|
|
return packageRoot;
|
|
}
|
|
|
|
const sourceRoot = path.join(packageRoot, "src");
|
|
return existsSync(sourceRoot) ? sourceRoot : packageRoot;
|
|
}
|
|
|
|
export function getUiSourceRoot(repoRoot: string): string | undefined {
|
|
const packageRoot = getInstalledPackageRoot("@elizaos/ui", repoRoot);
|
|
if (!packageRoot) {
|
|
return undefined;
|
|
}
|
|
|
|
if (path.basename(packageRoot) === "src") {
|
|
return packageRoot;
|
|
}
|
|
|
|
const sourceRoot = path.join(packageRoot, "src");
|
|
return existsSync(path.join(sourceRoot, "index.ts"))
|
|
? sourceRoot
|
|
: packageRoot;
|
|
}
|