miladyai 2.0.0-alpha.27
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/_virtual/_rolldown/runtime.js +7 -0
- package/dist/actions/emote.js +64 -0
- package/dist/actions/restart.js +81 -0
- package/dist/actions/send-message.js +152 -0
- package/dist/agent-admin-routes.js +82 -0
- package/dist/agent-lifecycle-routes.js +79 -0
- package/dist/agent-transfer-routes.js +102 -0
- package/dist/api/agent-admin-routes.js +82 -0
- package/dist/api/agent-lifecycle-routes.js +79 -0
- package/dist/api/agent-transfer-routes.js +102 -0
- package/dist/api/apps-hyperscape-routes.js +58 -0
- package/dist/api/apps-routes.js +114 -0
- package/dist/api/auth-routes.js +56 -0
- package/dist/api/autonomy-routes.js +44 -0
- package/dist/api/bug-report-routes.js +111 -0
- package/dist/api/character-routes.js +195 -0
- package/dist/api/cloud-routes.js +330 -0
- package/dist/api/cloud-status-routes.js +155 -0
- package/dist/api/compat-utils.js +111 -0
- package/dist/api/database.js +735 -0
- package/dist/api/diagnostics-routes.js +205 -0
- package/dist/api/drop-service.js +134 -0
- package/dist/api/early-logs.js +86 -0
- package/dist/api/http-helpers.js +131 -0
- package/dist/api/knowledge-routes.js +534 -0
- package/dist/api/memory-bounds.js +71 -0
- package/dist/api/models-routes.js +28 -0
- package/dist/api/og-tracker.js +36 -0
- package/dist/api/permissions-routes.js +109 -0
- package/dist/api/plugin-validation.js +198 -0
- package/dist/api/provider-switch-config.js +41 -0
- package/dist/api/registry-routes.js +86 -0
- package/dist/api/registry-service.js +164 -0
- package/dist/api/sandbox-routes.js +1112 -0
- package/dist/api/server.js +7949 -0
- package/dist/api/subscription-routes.js +172 -0
- package/dist/api/terminal-run-limits.js +24 -0
- package/dist/api/training-routes.js +158 -0
- package/dist/api/trajectory-routes.js +300 -0
- package/dist/api/trigger-routes.js +246 -0
- package/dist/api/twitter-verify.js +134 -0
- package/dist/api/tx-service.js +108 -0
- package/dist/api/wallet-routes.js +266 -0
- package/dist/api/wallet.js +568 -0
- package/dist/api/whatsapp-routes.js +182 -0
- package/dist/api/zip-utils.js +109 -0
- package/dist/apps-hyperscape-routes.js +58 -0
- package/dist/apps-routes.js +114 -0
- package/dist/ascii.js +20 -0
- package/dist/auth/anthropic.js +44 -0
- package/dist/auth/apply-stealth.js +41 -0
- package/dist/auth/claude-code-stealth.js +78 -0
- package/dist/auth/credentials.js +156 -0
- package/dist/auth/index.js +5 -0
- package/dist/auth/openai-codex.js +66 -0
- package/dist/auth/types.js +9 -0
- package/dist/auth-routes.js +56 -0
- package/dist/autonomy-routes.js +44 -0
- package/dist/bug-report-routes.js +111 -0
- package/dist/build-info.json +6 -0
- package/dist/character-routes.js +195 -0
- package/dist/cli/argv.js +63 -0
- package/dist/cli/banner.js +34 -0
- package/dist/cli/cli-name.js +21 -0
- package/dist/cli/cli-utils.js +16 -0
- package/dist/cli/git-commit.js +78 -0
- package/dist/cli/parse-duration.js +15 -0
- package/dist/cli/plugins-cli.js +590 -0
- package/dist/cli/profile-utils.js +9 -0
- package/dist/cli/profile.js +95 -0
- package/dist/cli/program/build-program.js +17 -0
- package/dist/cli/program/command-registry.js +23 -0
- package/dist/cli/program/help.js +47 -0
- package/dist/cli/program/preaction.js +33 -0
- package/dist/cli/program/register.config.js +106 -0
- package/dist/cli/program/register.configure.js +20 -0
- package/dist/cli/program/register.dashboard.js +124 -0
- package/dist/cli/program/register.models.js +23 -0
- package/dist/cli/program/register.setup.js +36 -0
- package/dist/cli/program/register.start.js +22 -0
- package/dist/cli/program/register.subclis.js +70 -0
- package/dist/cli/program/register.tui.js +163 -0
- package/dist/cli/program/register.update.js +154 -0
- package/dist/cli/program.js +3 -0
- package/dist/cli/run-main.js +37 -0
- package/dist/cli/version.js +7 -0
- package/dist/cloud/validate-url.js +93 -0
- package/dist/cloud-routes.js +330 -0
- package/dist/cloud-status-routes.js +155 -0
- package/dist/compat-utils.js +111 -0
- package/dist/config/config.js +69 -0
- package/dist/config/env-vars.js +19 -0
- package/dist/config/includes.js +121 -0
- package/dist/config/object-utils.js +7 -0
- package/dist/config/paths.js +38 -0
- package/dist/config/plugin-auto-enable.js +231 -0
- package/dist/config/schema.js +864 -0
- package/dist/config/telegram-custom-commands.js +76 -0
- package/dist/config/zod-schema.agent-runtime.js +519 -0
- package/dist/config/zod-schema.core.js +538 -0
- package/dist/config/zod-schema.hooks.js +103 -0
- package/dist/config/zod-schema.js +488 -0
- package/dist/config/zod-schema.providers-core.js +785 -0
- package/dist/config/zod-schema.session.js +73 -0
- package/dist/core-plugins.js +37 -0
- package/dist/custom-actions.js +250 -0
- package/dist/database.js +735 -0
- package/dist/diagnostics/integration-observability.js +57 -0
- package/dist/diagnostics-routes.js +205 -0
- package/dist/drop-service.js +134 -0
- package/dist/early-logs.js +24 -0
- package/dist/eliza.js +2061 -0
- package/dist/emotes/catalog.js +271 -0
- package/dist/entry.js +40 -0
- package/dist/hooks/discovery.js +167 -0
- package/dist/hooks/eligibility.js +64 -0
- package/dist/hooks/index.js +4 -0
- package/dist/hooks/loader.js +147 -0
- package/dist/hooks/registry.js +55 -0
- package/dist/http-helpers.js +131 -0
- package/dist/index.js +49 -0
- package/dist/knowledge-routes.js +534 -0
- package/dist/memory-bounds.js +71 -0
- package/dist/milady-plugin.js +90 -0
- package/dist/models-routes.js +28 -0
- package/dist/onboarding-names.js +78 -0
- package/dist/onboarding-presets.js +922 -0
- package/dist/package.json +1 -0
- package/dist/permissions-routes.js +109 -0
- package/dist/plugin-validation.js +107 -0
- package/dist/plugins/whatsapp/actions.js +91 -0
- package/dist/plugins/whatsapp/index.js +16 -0
- package/dist/plugins/whatsapp/service.js +270 -0
- package/dist/provider-switch-config.js +41 -0
- package/dist/providers/admin-trust.js +46 -0
- package/dist/providers/autonomous-state.js +101 -0
- package/dist/providers/session-bridge.js +86 -0
- package/dist/providers/session-utils.js +36 -0
- package/dist/providers/simple-mode.js +50 -0
- package/dist/providers/ui-catalog.js +15 -0
- package/dist/providers/workspace-provider.js +93 -0
- package/dist/providers/workspace.js +348 -0
- package/dist/registry-routes.js +86 -0
- package/dist/registry-service.js +164 -0
- package/dist/restart.js +40 -0
- package/dist/runtime/core-plugins.js +37 -0
- package/dist/runtime/custom-actions.js +250 -0
- package/dist/runtime/eliza.js +2061 -0
- package/dist/runtime/embedding-manager-support.js +185 -0
- package/dist/runtime/embedding-manager.js +193 -0
- package/dist/runtime/embedding-presets.js +54 -0
- package/dist/runtime/embedding-state.js +8 -0
- package/dist/runtime/milady-plugin.js +90 -0
- package/dist/runtime/onboarding-names.js +78 -0
- package/dist/runtime/restart.js +40 -0
- package/dist/runtime/version.js +7 -0
- package/dist/sandbox-routes.js +1112 -0
- package/dist/security/audit-log.js +149 -0
- package/dist/security/network-policy.js +70 -0
- package/dist/server.js +7949 -0
- package/dist/services/agent-export.js +559 -0
- package/dist/services/app-manager.js +389 -0
- package/dist/services/browser-capture.js +86 -0
- package/dist/services/fallback-training-service.js +128 -0
- package/dist/services/mcp-marketplace.js +134 -0
- package/dist/services/plugin-installer.js +396 -0
- package/dist/services/plugin-manager-types.js +15 -0
- package/dist/services/registry-client-app-meta.js +144 -0
- package/dist/services/registry-client-endpoints.js +166 -0
- package/dist/services/registry-client-local.js +271 -0
- package/dist/services/registry-client-network.js +93 -0
- package/dist/services/registry-client-queries.js +70 -0
- package/dist/services/registry-client.js +157 -0
- package/dist/services/sandbox-engine.js +511 -0
- package/dist/services/sandbox-manager.js +297 -0
- package/dist/services/self-updater.js +175 -0
- package/dist/services/skill-catalog-client.js +119 -0
- package/dist/services/skill-marketplace.js +521 -0
- package/dist/services/stream-manager.js +236 -0
- package/dist/services/update-checker.js +121 -0
- package/dist/services/update-notifier.js +29 -0
- package/dist/services/version-compat.js +78 -0
- package/dist/services/whatsapp-pairing.js +196 -0
- package/dist/shared/ui-catalog-prompt.js +728 -0
- package/dist/subscription-routes.js +172 -0
- package/dist/terminal/links.js +19 -0
- package/dist/terminal/palette.js +14 -0
- package/dist/terminal/theme.js +25 -0
- package/dist/terminal-run-limits.js +24 -0
- package/dist/training-routes.js +158 -0
- package/dist/trajectory-routes.js +300 -0
- package/dist/trigger-routes.js +246 -0
- package/dist/triggers/action.js +218 -0
- package/dist/triggers/runtime.js +281 -0
- package/dist/triggers/scheduling.js +295 -0
- package/dist/triggers/types.js +5 -0
- package/dist/tui/components/assistant-message.js +76 -0
- package/dist/tui/components/chat-editor.js +34 -0
- package/dist/tui/components/embeddings-overlay.js +46 -0
- package/dist/tui/components/footer.js +60 -0
- package/dist/tui/components/index.js +15 -0
- package/dist/tui/components/modal-frame.js +45 -0
- package/dist/tui/components/modal-style.js +15 -0
- package/dist/tui/components/model-selector.js +70 -0
- package/dist/tui/components/pinned-chat-layout.js +46 -0
- package/dist/tui/components/plugins-endpoints-tab.js +196 -0
- package/dist/tui/components/plugins-installed-tab-view.js +69 -0
- package/dist/tui/components/plugins-installed-tab.js +319 -0
- package/dist/tui/components/plugins-overlay-catalog.js +81 -0
- package/dist/tui/components/plugins-overlay-data-api.js +21 -0
- package/dist/tui/components/plugins-overlay-data-shared.js +20 -0
- package/dist/tui/components/plugins-overlay-data.js +323 -0
- package/dist/tui/components/plugins-overlay.js +117 -0
- package/dist/tui/components/plugins-store-tab.js +148 -0
- package/dist/tui/components/settings-overlay.js +61 -0
- package/dist/tui/components/status-bar.js +64 -0
- package/dist/tui/components/tool-execution.js +68 -0
- package/dist/tui/components/user-message.js +22 -0
- package/dist/tui/eliza-tui-bridge.js +606 -0
- package/dist/tui/index.js +370 -0
- package/dist/tui/modal-presets.js +33 -0
- package/dist/tui/model-spec.js +46 -0
- package/dist/tui/sse-parser.js +78 -0
- package/dist/tui/theme.js +110 -0
- package/dist/tui/titlebar-spinner.js +62 -0
- package/dist/tui/tui-app.js +311 -0
- package/dist/tui/ws-client.js +215 -0
- package/dist/twitter-verify.js +134 -0
- package/dist/tx-service.js +108 -0
- package/dist/utils/exec-safety.js +17 -0
- package/dist/utils/globals.js +20 -0
- package/dist/utils/milady-root.js +61 -0
- package/dist/utils/number-parsing.js +37 -0
- package/dist/version-resolver.js +37 -0
- package/dist/version.js +7 -0
- package/dist/wallet-routes.js +266 -0
- package/dist/wallet.js +568 -0
- package/dist/whatsapp-routes.js +182 -0
- package/dist/zip-utils.js +109 -0
- package/milady.mjs +14 -0
- package/package.json +111 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { isBlockedPrivateOrLinkLocalIp, normalizeHostLike } from "../security/network-policy.js";
|
|
2
|
+
import { logger } from "@elizaos/core";
|
|
3
|
+
import { lookup } from "node:dns/promises";
|
|
4
|
+
import net from "node:net";
|
|
5
|
+
|
|
6
|
+
//#region src/services/registry-client-endpoints.ts
|
|
7
|
+
const BLOCKED_REGISTRY_HOST_LITERALS = new Set([
|
|
8
|
+
"localhost",
|
|
9
|
+
"127.0.0.1",
|
|
10
|
+
"::1",
|
|
11
|
+
"0.0.0.0",
|
|
12
|
+
"169.254.169.254"
|
|
13
|
+
]);
|
|
14
|
+
function normaliseEndpointUrl(url) {
|
|
15
|
+
return url.replace(/\/+$/, "");
|
|
16
|
+
}
|
|
17
|
+
function isDefaultEndpoint(url, defaultUrl) {
|
|
18
|
+
return normaliseEndpointUrl(url) === normaliseEndpointUrl(defaultUrl);
|
|
19
|
+
}
|
|
20
|
+
function parseRegistryEndpointUrl(rawUrl) {
|
|
21
|
+
let parsed;
|
|
22
|
+
try {
|
|
23
|
+
parsed = new URL(rawUrl);
|
|
24
|
+
} catch {
|
|
25
|
+
throw new Error("Endpoint URL must be a valid absolute URL");
|
|
26
|
+
}
|
|
27
|
+
if (parsed.protocol !== "https:") throw new Error("Endpoint URL must use https://");
|
|
28
|
+
const hostname = normalizeHostLike(parsed.hostname);
|
|
29
|
+
if (!hostname) throw new Error("Endpoint URL hostname is required");
|
|
30
|
+
if (BLOCKED_REGISTRY_HOST_LITERALS.has(hostname) || hostname.endsWith(".localhost") || hostname.endsWith(".local")) throw new Error(`Endpoint host "${hostname}" is blocked`);
|
|
31
|
+
if (net.isIP(hostname) && isBlockedPrivateOrLinkLocalIp(hostname)) throw new Error(`Endpoint host "${hostname}" is blocked`);
|
|
32
|
+
return parsed;
|
|
33
|
+
}
|
|
34
|
+
async function resolveRegistryEndpointUrlRejection(rawUrl) {
|
|
35
|
+
let parsed;
|
|
36
|
+
try {
|
|
37
|
+
parsed = parseRegistryEndpointUrl(rawUrl);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
return {
|
|
40
|
+
rejection: error instanceof Error ? error.message : String(error),
|
|
41
|
+
endpoint: null
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const hostname = normalizeHostLike(parsed.hostname);
|
|
45
|
+
if (!hostname) return {
|
|
46
|
+
rejection: "Endpoint URL hostname is required",
|
|
47
|
+
endpoint: null
|
|
48
|
+
};
|
|
49
|
+
if (net.isIP(hostname)) return {
|
|
50
|
+
rejection: null,
|
|
51
|
+
endpoint: {
|
|
52
|
+
parsed,
|
|
53
|
+
hostname,
|
|
54
|
+
pinnedAddress: hostname
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
let addresses;
|
|
58
|
+
try {
|
|
59
|
+
const resolved = await lookup(hostname, { all: true });
|
|
60
|
+
addresses = Array.isArray(resolved) ? resolved : [resolved];
|
|
61
|
+
} catch {
|
|
62
|
+
return {
|
|
63
|
+
rejection: `Could not resolve endpoint host "${hostname}"`,
|
|
64
|
+
endpoint: null
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (addresses.length === 0) return {
|
|
68
|
+
rejection: `Could not resolve endpoint host "${hostname}"`,
|
|
69
|
+
endpoint: null
|
|
70
|
+
};
|
|
71
|
+
for (const entry of addresses) if (isBlockedPrivateOrLinkLocalIp(entry.address)) return {
|
|
72
|
+
rejection: `Endpoint host "${hostname}" resolves to blocked address ${entry.address}`,
|
|
73
|
+
endpoint: null
|
|
74
|
+
};
|
|
75
|
+
return {
|
|
76
|
+
rejection: null,
|
|
77
|
+
endpoint: {
|
|
78
|
+
parsed,
|
|
79
|
+
hostname,
|
|
80
|
+
pinnedAddress: addresses[0]?.address ?? null
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
async function fetchSingleEndpoint(url, label) {
|
|
85
|
+
const { rejection, endpoint } = await resolveRegistryEndpointUrlRejection(url);
|
|
86
|
+
if (rejection || !endpoint) {
|
|
87
|
+
logger.warn(`[registry-client] Endpoint "${label}" (${url}) blocked: ${rejection ?? "validation failed"}`);
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
if (endpoint.pinnedAddress && !net.isIP(endpoint.hostname)) {
|
|
92
|
+
const refreshed = await lookup(endpoint.hostname, { all: true });
|
|
93
|
+
const refreshedAddresses = new Set((Array.isArray(refreshed) ? refreshed : [refreshed]).map((entry) => normalizeHostLike(entry.address)));
|
|
94
|
+
if (!refreshedAddresses.has(normalizeHostLike(endpoint.pinnedAddress))) {
|
|
95
|
+
logger.warn(`[registry-client] Endpoint "${label}" (${url}) blocked: host resolution changed before fetch`);
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
for (const address of refreshedAddresses) if (isBlockedPrivateOrLinkLocalIp(address)) {
|
|
99
|
+
logger.warn(`[registry-client] Endpoint "${label}" (${url}) blocked: host resolves to blocked address ${address}`);
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const resp = await fetch(url, { redirect: "error" });
|
|
104
|
+
if (!resp.ok) {
|
|
105
|
+
logger.warn(`[registry-client] Endpoint "${label}" (${url}): ${resp.status} ${resp.statusText}`);
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
const data = await resp.json();
|
|
109
|
+
if (!data.registry || typeof data.registry !== "object") {
|
|
110
|
+
logger.warn(`[registry-client] Endpoint "${label}" (${url}): missing registry field`);
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
const plugins = /* @__PURE__ */ new Map();
|
|
114
|
+
for (const [name, raw] of Object.entries(data.registry)) {
|
|
115
|
+
const e = raw;
|
|
116
|
+
const git = e.git ?? {};
|
|
117
|
+
const npm = e.npm ?? {};
|
|
118
|
+
const supports = e.supports ?? {
|
|
119
|
+
v0: false,
|
|
120
|
+
v1: false,
|
|
121
|
+
v2: false
|
|
122
|
+
};
|
|
123
|
+
plugins.set(name, {
|
|
124
|
+
name,
|
|
125
|
+
gitRepo: git.repo ?? "unknown/unknown",
|
|
126
|
+
gitUrl: `https://github.com/${git.repo ?? "unknown/unknown"}.git`,
|
|
127
|
+
description: e.description ?? "",
|
|
128
|
+
homepage: e.homepage ?? null,
|
|
129
|
+
topics: e.topics ?? [],
|
|
130
|
+
stars: e.stargazers_count ?? 0,
|
|
131
|
+
language: e.language ?? "TypeScript",
|
|
132
|
+
npm: {
|
|
133
|
+
package: npm.repo ?? name,
|
|
134
|
+
v0Version: npm.v0 ?? null,
|
|
135
|
+
v1Version: npm.v1 ?? null,
|
|
136
|
+
v2Version: npm.v2 ?? null
|
|
137
|
+
},
|
|
138
|
+
git: {
|
|
139
|
+
v0Branch: git.v0?.branch ?? null,
|
|
140
|
+
v1Branch: git.v1?.branch ?? null,
|
|
141
|
+
v2Branch: git.v2?.branch ?? null
|
|
142
|
+
},
|
|
143
|
+
supports
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return plugins;
|
|
147
|
+
} catch (err) {
|
|
148
|
+
logger.warn(`[registry-client] Endpoint "${label}" (${url}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async function mergeCustomEndpoints(plugins, endpoints) {
|
|
153
|
+
const enabledEndpoints = endpoints.filter((ep) => ep.enabled !== false);
|
|
154
|
+
if (enabledEndpoints.length === 0) return;
|
|
155
|
+
const results = await Promise.allSettled(enabledEndpoints.map((ep) => fetchSingleEndpoint(ep.url, ep.label)));
|
|
156
|
+
for (const result of results) if (result.status === "fulfilled" && result.value) for (const [name, info] of result.value) {
|
|
157
|
+
if (plugins.has(name)) {
|
|
158
|
+
logger.warn(`[registry-client] Ignoring custom endpoint override for ${name}`);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
plugins.set(name, info);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
//#endregion
|
|
166
|
+
export { isDefaultEndpoint, mergeCustomEndpoints, normaliseEndpointUrl, parseRegistryEndpointUrl };
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { mergeAppMeta, resolveAppOverride } from "./registry-client-app-meta.js";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import fs from "node:fs/promises";
|
|
6
|
+
|
|
7
|
+
//#region src/services/registry-client-local.ts
|
|
8
|
+
function uniquePaths(paths) {
|
|
9
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10
|
+
const ordered = [];
|
|
11
|
+
for (const p of paths) {
|
|
12
|
+
const resolved = path.resolve(p);
|
|
13
|
+
if (!seen.has(resolved)) {
|
|
14
|
+
seen.add(resolved);
|
|
15
|
+
ordered.push(resolved);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return ordered;
|
|
19
|
+
}
|
|
20
|
+
function resolveWorkspaceRoots() {
|
|
21
|
+
const envRoot = process.env.MILADY_WORKSPACE_ROOT?.trim();
|
|
22
|
+
if (envRoot) return uniquePaths([envRoot]);
|
|
23
|
+
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
|
24
|
+
const packageRoot = path.resolve(moduleDir, "..", "..");
|
|
25
|
+
const cwd = process.cwd();
|
|
26
|
+
return uniquePaths([
|
|
27
|
+
packageRoot,
|
|
28
|
+
cwd,
|
|
29
|
+
path.resolve(cwd, ".."),
|
|
30
|
+
path.resolve(cwd, "..", "..")
|
|
31
|
+
].filter((candidate) => Boolean(candidate)));
|
|
32
|
+
}
|
|
33
|
+
function repoString(repo) {
|
|
34
|
+
if (!repo) return null;
|
|
35
|
+
if (typeof repo === "string") return repo;
|
|
36
|
+
if (typeof repo.url === "string" && repo.url.length > 0) return repo.url;
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
function normaliseGitHubRepo(repo) {
|
|
40
|
+
if (!repo) return null;
|
|
41
|
+
const cleaned = repo.replace(/^git\+/, "").replace(/\.git$/, "").replace(/^https?:\/\/github\.com\//, "").replace(/^git@github\.com:/, "").trim();
|
|
42
|
+
if (!cleaned.includes("/")) return null;
|
|
43
|
+
return cleaned;
|
|
44
|
+
}
|
|
45
|
+
async function readJsonFile(filePath) {
|
|
46
|
+
try {
|
|
47
|
+
const raw = await fs.readFile(filePath, "utf-8");
|
|
48
|
+
return JSON.parse(raw);
|
|
49
|
+
} catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function toLocalAppMeta(app, fallbackDisplayName) {
|
|
54
|
+
if (!app) return void 0;
|
|
55
|
+
const launchType = app.launchType ?? "url";
|
|
56
|
+
return {
|
|
57
|
+
displayName: app.displayName ?? fallbackDisplayName,
|
|
58
|
+
category: app.category ?? "game",
|
|
59
|
+
launchType,
|
|
60
|
+
launchUrl: app.launchUrl ?? null,
|
|
61
|
+
icon: app.icon ?? null,
|
|
62
|
+
capabilities: app.capabilities ?? [],
|
|
63
|
+
minPlayers: app.minPlayers ?? null,
|
|
64
|
+
maxPlayers: app.maxPlayers ?? null,
|
|
65
|
+
viewer: app.viewer
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function toDisplayNameFromDirName(dirName) {
|
|
69
|
+
return dirName.replace(/^app-/, "").split("-").filter((part) => part.length > 0).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
70
|
+
}
|
|
71
|
+
function parseRepositoryMetadata(repository) {
|
|
72
|
+
const gitRepo = normaliseGitHubRepo(repoString(repository)) ?? "local/workspace";
|
|
73
|
+
return {
|
|
74
|
+
gitRepo,
|
|
75
|
+
gitUrl: `https://github.com/${gitRepo}.git`
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function buildDiscoveredEntry(packageDir, dirName, packageJson, manifest) {
|
|
79
|
+
if (!packageJson?.name || packageJson.name.length === 0) return null;
|
|
80
|
+
const packageAppMeta = toLocalAppMeta(packageJson.elizaos?.app, toDisplayNameFromDirName(dirName));
|
|
81
|
+
const mergedMeta = mergeAppMeta(toLocalAppMeta(manifest?.app, toDisplayNameFromDirName(dirName)), packageAppMeta);
|
|
82
|
+
const overriddenMeta = resolveAppOverride(packageJson.name, mergedMeta);
|
|
83
|
+
const kind = packageJson.elizaos?.kind === "app" || manifest?.kind === "app" ? "app" : overriddenMeta ? "app" : void 0;
|
|
84
|
+
const repo = parseRepositoryMetadata(packageJson.repository ?? manifest?.repository);
|
|
85
|
+
const description = packageJson.description ?? manifest?.description ?? "";
|
|
86
|
+
const homepage = packageJson.homepage ?? manifest?.homepage ?? overriddenMeta?.launchUrl ?? null;
|
|
87
|
+
const version = packageJson.version ?? manifest?.version ?? null;
|
|
88
|
+
return {
|
|
89
|
+
name: packageJson.name,
|
|
90
|
+
gitRepo: repo.gitRepo,
|
|
91
|
+
gitUrl: repo.gitUrl,
|
|
92
|
+
description,
|
|
93
|
+
homepage,
|
|
94
|
+
topics: [],
|
|
95
|
+
stars: 0,
|
|
96
|
+
language: "TypeScript",
|
|
97
|
+
npm: {
|
|
98
|
+
package: packageJson.name,
|
|
99
|
+
v0Version: null,
|
|
100
|
+
v1Version: null,
|
|
101
|
+
v2Version: version
|
|
102
|
+
},
|
|
103
|
+
git: {
|
|
104
|
+
v0Branch: null,
|
|
105
|
+
v1Branch: null,
|
|
106
|
+
v2Branch: "main"
|
|
107
|
+
},
|
|
108
|
+
supports: {
|
|
109
|
+
v0: false,
|
|
110
|
+
v1: false,
|
|
111
|
+
v2: true
|
|
112
|
+
},
|
|
113
|
+
localPath: packageDir,
|
|
114
|
+
kind,
|
|
115
|
+
appMeta: overriddenMeta ?? void 0
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async function discoverLocalWorkspaceApps() {
|
|
119
|
+
const discovered = /* @__PURE__ */ new Map();
|
|
120
|
+
for (const workspaceRoot of resolveWorkspaceRoots()) {
|
|
121
|
+
const pluginsDir = path.join(workspaceRoot, "plugins");
|
|
122
|
+
let entries;
|
|
123
|
+
try {
|
|
124
|
+
entries = await fs.readdir(pluginsDir, { withFileTypes: true });
|
|
125
|
+
} catch {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
for (const entry of entries) {
|
|
129
|
+
if (!entry.isDirectory() && !entry.isSymbolicLink() || !entry.name.startsWith("app-")) continue;
|
|
130
|
+
const packageDir = path.join(pluginsDir, entry.name);
|
|
131
|
+
const packageJson = await readJsonFile(path.join(packageDir, "package.json"));
|
|
132
|
+
if (!packageJson) continue;
|
|
133
|
+
const manifest = await readJsonFile(path.join(packageDir, "elizaos.plugin.json"));
|
|
134
|
+
const info = buildDiscoveredEntry(packageDir, entry.name, packageJson, manifest);
|
|
135
|
+
if (info) discovered.set(info.name, info);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const stateDir = process.env.MILADY_STATE_DIR?.trim() || path.join(os.homedir(), ".milady");
|
|
139
|
+
const installedBase = path.join(stateDir, "plugins", "installed");
|
|
140
|
+
try {
|
|
141
|
+
const installedEntries = await fs.readdir(installedBase, { withFileTypes: true });
|
|
142
|
+
for (const entry of installedEntries) {
|
|
143
|
+
if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
|
|
144
|
+
const installDir = path.join(installedBase, entry.name);
|
|
145
|
+
const nmDir = path.join(installDir, "node_modules");
|
|
146
|
+
const pkgDirs = [];
|
|
147
|
+
try {
|
|
148
|
+
const nmEntries = await fs.readdir(nmDir, { withFileTypes: true });
|
|
149
|
+
for (const nm of nmEntries) if (nm.name.startsWith("@")) {
|
|
150
|
+
const scopeDir = path.join(nmDir, nm.name);
|
|
151
|
+
try {
|
|
152
|
+
const scopeEntries = await fs.readdir(scopeDir, { withFileTypes: true });
|
|
153
|
+
for (const se of scopeEntries) pkgDirs.push(path.join(scopeDir, se.name));
|
|
154
|
+
} catch {}
|
|
155
|
+
} else if (nm.isDirectory() || nm.isSymbolicLink()) pkgDirs.push(path.join(nmDir, nm.name));
|
|
156
|
+
} catch {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
for (const pkgDir of pkgDirs) {
|
|
160
|
+
const pkgJson = await readJsonFile(path.join(pkgDir, "package.json"));
|
|
161
|
+
if (!pkgJson?.name) continue;
|
|
162
|
+
if (pkgJson.elizaos?.kind !== "app") continue;
|
|
163
|
+
if (discovered.has(pkgJson.name)) continue;
|
|
164
|
+
const manifest = await readJsonFile(path.join(pkgDir, "elizaos.plugin.json"));
|
|
165
|
+
const info = buildDiscoveredEntry(pkgDir, pkgJson.name.replace(/^@[^/]+\//, "").replace(/^plugin-/, "app-"), pkgJson, manifest);
|
|
166
|
+
if (info) discovered.set(info.name, info);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
} catch {}
|
|
170
|
+
return discovered;
|
|
171
|
+
}
|
|
172
|
+
async function discoverNodeModulePlugins() {
|
|
173
|
+
const discovered = /* @__PURE__ */ new Map();
|
|
174
|
+
for (const workspaceRoot of resolveWorkspaceRoots()) {
|
|
175
|
+
const elizaosDir = path.join(workspaceRoot, "node_modules", "@elizaos");
|
|
176
|
+
let entries;
|
|
177
|
+
try {
|
|
178
|
+
entries = await fs.readdir(elizaosDir, { withFileTypes: true });
|
|
179
|
+
} catch {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
for (const entry of entries) {
|
|
183
|
+
if (!entry.name.startsWith("plugin-")) continue;
|
|
184
|
+
if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
|
|
185
|
+
const packageDir = path.join(elizaosDir, entry.name);
|
|
186
|
+
const packageJson = await readJsonFile(path.join(packageDir, "package.json"));
|
|
187
|
+
if (!packageJson?.name) continue;
|
|
188
|
+
if (!(packageJson.packageType === "plugin" || packageJson.keywords?.includes("elizaos") || packageJson.elizaos !== void 0 || packageJson.agentConfig !== void 0)) continue;
|
|
189
|
+
if (packageJson.elizaos?.kind === "app") continue;
|
|
190
|
+
const repo = parseRepositoryMetadata(packageJson.repository);
|
|
191
|
+
const version = packageJson.version ?? null;
|
|
192
|
+
let localPath = packageDir;
|
|
193
|
+
try {
|
|
194
|
+
const realPath = await fs.realpath(packageDir);
|
|
195
|
+
if (realPath !== packageDir) localPath = realPath;
|
|
196
|
+
} catch {}
|
|
197
|
+
discovered.set(packageJson.name, {
|
|
198
|
+
name: packageJson.name,
|
|
199
|
+
gitRepo: repo.gitRepo,
|
|
200
|
+
gitUrl: repo.gitUrl,
|
|
201
|
+
description: packageJson.description ?? "",
|
|
202
|
+
homepage: packageJson.homepage ?? null,
|
|
203
|
+
topics: [],
|
|
204
|
+
stars: 0,
|
|
205
|
+
language: "TypeScript",
|
|
206
|
+
npm: {
|
|
207
|
+
package: packageJson.name,
|
|
208
|
+
v0Version: null,
|
|
209
|
+
v1Version: null,
|
|
210
|
+
v2Version: version
|
|
211
|
+
},
|
|
212
|
+
git: {
|
|
213
|
+
v0Branch: null,
|
|
214
|
+
v1Branch: null,
|
|
215
|
+
v2Branch: "main"
|
|
216
|
+
},
|
|
217
|
+
supports: {
|
|
218
|
+
v0: false,
|
|
219
|
+
v1: false,
|
|
220
|
+
v2: true
|
|
221
|
+
},
|
|
222
|
+
localPath
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return discovered;
|
|
227
|
+
}
|
|
228
|
+
async function applyNodeModulePlugins(plugins) {
|
|
229
|
+
const localPlugins = await discoverNodeModulePlugins();
|
|
230
|
+
if (localPlugins.size === 0) return;
|
|
231
|
+
for (const [name, localInfo] of localPlugins.entries()) {
|
|
232
|
+
const existing = plugins.get(name);
|
|
233
|
+
if (!existing) plugins.set(name, localInfo);
|
|
234
|
+
else if (!existing.localPath) plugins.set(name, {
|
|
235
|
+
...existing,
|
|
236
|
+
localPath: localInfo.localPath
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
async function applyLocalWorkspaceApps(plugins) {
|
|
241
|
+
const localApps = await discoverLocalWorkspaceApps();
|
|
242
|
+
if (localApps.size === 0) return;
|
|
243
|
+
for (const [name, localInfo] of localApps.entries()) {
|
|
244
|
+
const existing = plugins.get(name);
|
|
245
|
+
if (!existing) {
|
|
246
|
+
plugins.set(name, localInfo);
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
plugins.set(name, {
|
|
250
|
+
...existing,
|
|
251
|
+
localPath: localInfo.localPath,
|
|
252
|
+
kind: localInfo.kind ?? existing.kind,
|
|
253
|
+
appMeta: mergeAppMeta(existing.appMeta, localInfo.appMeta),
|
|
254
|
+
description: localInfo.description || existing.description,
|
|
255
|
+
homepage: localInfo.homepage ?? existing.homepage,
|
|
256
|
+
npm: {
|
|
257
|
+
...existing.npm,
|
|
258
|
+
package: existing.npm.package || localInfo.npm.package,
|
|
259
|
+
v2Version: existing.npm.v2Version ?? localInfo.npm.v2Version
|
|
260
|
+
},
|
|
261
|
+
git: {
|
|
262
|
+
v0Branch: existing.git.v0Branch ?? localInfo.git.v0Branch,
|
|
263
|
+
v1Branch: existing.git.v1Branch ?? localInfo.git.v1Branch,
|
|
264
|
+
v2Branch: existing.git.v2Branch ?? localInfo.git.v2Branch
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
//#endregion
|
|
271
|
+
export { applyLocalWorkspaceApps, applyNodeModulePlugins };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
//#region src/services/registry-client-network.ts
|
|
2
|
+
async function fetchFromNetwork(params) {
|
|
3
|
+
const { generatedRegistryUrl, indexRegistryUrl, applyLocalWorkspaceApps, applyNodeModulePlugins, sanitizeSandbox } = params;
|
|
4
|
+
try {
|
|
5
|
+
const resp = await fetch(generatedRegistryUrl, { redirect: "error" });
|
|
6
|
+
if (resp.ok) {
|
|
7
|
+
const data = await resp.json();
|
|
8
|
+
const plugins = /* @__PURE__ */ new Map();
|
|
9
|
+
for (const [name, e] of Object.entries(data.registry)) {
|
|
10
|
+
const info = {
|
|
11
|
+
name,
|
|
12
|
+
gitRepo: e.git.repo,
|
|
13
|
+
gitUrl: `https://github.com/${e.git.repo}.git`,
|
|
14
|
+
description: e.description || "",
|
|
15
|
+
homepage: e.homepage,
|
|
16
|
+
topics: e.topics || [],
|
|
17
|
+
stars: e.stargazers_count || 0,
|
|
18
|
+
language: e.language || "TypeScript",
|
|
19
|
+
npm: {
|
|
20
|
+
package: e.npm.repo,
|
|
21
|
+
v0Version: e.npm.v0,
|
|
22
|
+
v1Version: e.npm.v1,
|
|
23
|
+
v2Version: e.npm.v2
|
|
24
|
+
},
|
|
25
|
+
git: {
|
|
26
|
+
v0Branch: e.git.v0?.branch ?? null,
|
|
27
|
+
v1Branch: e.git.v1?.branch ?? null,
|
|
28
|
+
v2Branch: e.git.v2?.branch ?? null
|
|
29
|
+
},
|
|
30
|
+
supports: e.supports
|
|
31
|
+
};
|
|
32
|
+
if (e.kind === "app" || e.app) info.kind = "app";
|
|
33
|
+
if (e.app) info.appMeta = {
|
|
34
|
+
displayName: e.app.displayName,
|
|
35
|
+
category: e.app.category,
|
|
36
|
+
launchType: e.app.launchType,
|
|
37
|
+
launchUrl: e.app.launchUrl,
|
|
38
|
+
icon: e.app.icon,
|
|
39
|
+
capabilities: e.app.capabilities || [],
|
|
40
|
+
minPlayers: e.app.minPlayers ?? null,
|
|
41
|
+
maxPlayers: e.app.maxPlayers ?? null,
|
|
42
|
+
viewer: e.app.viewer ? {
|
|
43
|
+
...e.app.viewer,
|
|
44
|
+
sandbox: sanitizeSandbox(e.app.viewer.sandbox)
|
|
45
|
+
} : void 0
|
|
46
|
+
};
|
|
47
|
+
plugins.set(name, info);
|
|
48
|
+
}
|
|
49
|
+
await applyLocalWorkspaceApps(plugins);
|
|
50
|
+
await applyNodeModulePlugins(plugins);
|
|
51
|
+
return plugins;
|
|
52
|
+
}
|
|
53
|
+
} catch {}
|
|
54
|
+
const resp = await fetch(indexRegistryUrl, { redirect: "error" });
|
|
55
|
+
if (!resp.ok) throw new Error(`index.json: ${resp.status} ${resp.statusText}`);
|
|
56
|
+
const data = await resp.json();
|
|
57
|
+
const plugins = /* @__PURE__ */ new Map();
|
|
58
|
+
for (const [name, gitRef] of Object.entries(data)) {
|
|
59
|
+
const repo = gitRef.replace(/^github:/, "");
|
|
60
|
+
plugins.set(name, {
|
|
61
|
+
name,
|
|
62
|
+
gitRepo: repo,
|
|
63
|
+
gitUrl: `https://github.com/${repo}.git`,
|
|
64
|
+
description: "",
|
|
65
|
+
homepage: null,
|
|
66
|
+
topics: [],
|
|
67
|
+
stars: 0,
|
|
68
|
+
language: "TypeScript",
|
|
69
|
+
npm: {
|
|
70
|
+
package: name,
|
|
71
|
+
v0Version: null,
|
|
72
|
+
v1Version: null,
|
|
73
|
+
v2Version: null
|
|
74
|
+
},
|
|
75
|
+
git: {
|
|
76
|
+
v0Branch: null,
|
|
77
|
+
v1Branch: null,
|
|
78
|
+
v2Branch: "next"
|
|
79
|
+
},
|
|
80
|
+
supports: {
|
|
81
|
+
v0: false,
|
|
82
|
+
v1: false,
|
|
83
|
+
v2: false
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
await applyLocalWorkspaceApps(plugins);
|
|
88
|
+
await applyNodeModulePlugins(plugins);
|
|
89
|
+
return plugins;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
//#endregion
|
|
93
|
+
export { fetchFromNetwork };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
//#region src/services/registry-client-queries.ts
|
|
2
|
+
function normalizePluginLookupAlias(name) {
|
|
3
|
+
const trimmed = name.trim();
|
|
4
|
+
if (!trimmed) return trimmed;
|
|
5
|
+
const lower = trimmed.toLowerCase();
|
|
6
|
+
if (lower === "obsidan") return "obsidian";
|
|
7
|
+
if (lower === "plugin-obsidan") return "plugin-obsidian";
|
|
8
|
+
if (lower === "@elizaos/plugin-obsidan") return "@elizaos/plugin-obsidian";
|
|
9
|
+
return trimmed;
|
|
10
|
+
}
|
|
11
|
+
function getPluginInfoFromRegistry(registry, name) {
|
|
12
|
+
let p = registry.get(name);
|
|
13
|
+
if (p) return p;
|
|
14
|
+
if (!name.startsWith("@")) {
|
|
15
|
+
p = registry.get(`@elizaos/${name}`);
|
|
16
|
+
if (p) return p;
|
|
17
|
+
p = registry.get(`@elizaos/plugin-${name}`);
|
|
18
|
+
if (p) return p;
|
|
19
|
+
}
|
|
20
|
+
const bare = name.replace(/^@[^/]+\//, "");
|
|
21
|
+
for (const [key, value] of registry) if (key.endsWith(`/${bare}`)) return value;
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
function scoreEntries(entries, query, limit, extraNames, extraTerms) {
|
|
25
|
+
const lq = query.toLowerCase();
|
|
26
|
+
const terms = lq.split(/\s+/).filter((t) => t.length > 1);
|
|
27
|
+
const scored = [];
|
|
28
|
+
for (const p of entries) {
|
|
29
|
+
const ln = p.name.toLowerCase();
|
|
30
|
+
const ld = p.description.toLowerCase();
|
|
31
|
+
const aliases = extraNames?.(p) ?? [];
|
|
32
|
+
let s = 0;
|
|
33
|
+
if (ln === lq || ln === `@elizaos/${lq}` || aliases.some((a) => a === lq)) s += 100;
|
|
34
|
+
else if (ln.includes(lq) || aliases.some((a) => a.includes(lq))) s += 50;
|
|
35
|
+
if (ld.includes(lq)) s += 30;
|
|
36
|
+
for (const t of p.topics) if (t.toLowerCase().includes(lq)) s += 25;
|
|
37
|
+
for (const t of extraTerms?.(p) ?? []) if (t.toLowerCase().includes(lq)) s += 25;
|
|
38
|
+
for (const term of terms) {
|
|
39
|
+
if (ln.includes(term) || aliases.some((a) => a.includes(term))) s += 15;
|
|
40
|
+
if (ld.includes(term)) s += 10;
|
|
41
|
+
for (const t of p.topics) if (t.toLowerCase().includes(term)) s += 8;
|
|
42
|
+
}
|
|
43
|
+
if (s > 0) {
|
|
44
|
+
if (p.stars > 100) s += 3;
|
|
45
|
+
if (p.stars > 500) s += 3;
|
|
46
|
+
if (p.stars > 1e3) s += 4;
|
|
47
|
+
scored.push({
|
|
48
|
+
p,
|
|
49
|
+
s
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
scored.sort((a, b) => b.s - a.s || b.p.stars - a.p.stars);
|
|
54
|
+
return scored.slice(0, limit);
|
|
55
|
+
}
|
|
56
|
+
function toPluginListItem(p) {
|
|
57
|
+
return {
|
|
58
|
+
name: p.name,
|
|
59
|
+
description: p.description,
|
|
60
|
+
stars: p.stars,
|
|
61
|
+
repository: `https://github.com/${p.gitRepo}`,
|
|
62
|
+
topics: p.topics,
|
|
63
|
+
latestVersion: p.npm.v2Version || p.npm.v1Version || p.npm.v0Version,
|
|
64
|
+
supports: p.supports,
|
|
65
|
+
npm: p.npm
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
//#endregion
|
|
70
|
+
export { getPluginInfoFromRegistry, normalizePluginLookupAlias, scoreEntries, toPluginListItem };
|