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.
Files changed (241) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +7 -0
  2. package/dist/actions/emote.js +64 -0
  3. package/dist/actions/restart.js +81 -0
  4. package/dist/actions/send-message.js +152 -0
  5. package/dist/agent-admin-routes.js +82 -0
  6. package/dist/agent-lifecycle-routes.js +79 -0
  7. package/dist/agent-transfer-routes.js +102 -0
  8. package/dist/api/agent-admin-routes.js +82 -0
  9. package/dist/api/agent-lifecycle-routes.js +79 -0
  10. package/dist/api/agent-transfer-routes.js +102 -0
  11. package/dist/api/apps-hyperscape-routes.js +58 -0
  12. package/dist/api/apps-routes.js +114 -0
  13. package/dist/api/auth-routes.js +56 -0
  14. package/dist/api/autonomy-routes.js +44 -0
  15. package/dist/api/bug-report-routes.js +111 -0
  16. package/dist/api/character-routes.js +195 -0
  17. package/dist/api/cloud-routes.js +330 -0
  18. package/dist/api/cloud-status-routes.js +155 -0
  19. package/dist/api/compat-utils.js +111 -0
  20. package/dist/api/database.js +735 -0
  21. package/dist/api/diagnostics-routes.js +205 -0
  22. package/dist/api/drop-service.js +134 -0
  23. package/dist/api/early-logs.js +86 -0
  24. package/dist/api/http-helpers.js +131 -0
  25. package/dist/api/knowledge-routes.js +534 -0
  26. package/dist/api/memory-bounds.js +71 -0
  27. package/dist/api/models-routes.js +28 -0
  28. package/dist/api/og-tracker.js +36 -0
  29. package/dist/api/permissions-routes.js +109 -0
  30. package/dist/api/plugin-validation.js +198 -0
  31. package/dist/api/provider-switch-config.js +41 -0
  32. package/dist/api/registry-routes.js +86 -0
  33. package/dist/api/registry-service.js +164 -0
  34. package/dist/api/sandbox-routes.js +1112 -0
  35. package/dist/api/server.js +7949 -0
  36. package/dist/api/subscription-routes.js +172 -0
  37. package/dist/api/terminal-run-limits.js +24 -0
  38. package/dist/api/training-routes.js +158 -0
  39. package/dist/api/trajectory-routes.js +300 -0
  40. package/dist/api/trigger-routes.js +246 -0
  41. package/dist/api/twitter-verify.js +134 -0
  42. package/dist/api/tx-service.js +108 -0
  43. package/dist/api/wallet-routes.js +266 -0
  44. package/dist/api/wallet.js +568 -0
  45. package/dist/api/whatsapp-routes.js +182 -0
  46. package/dist/api/zip-utils.js +109 -0
  47. package/dist/apps-hyperscape-routes.js +58 -0
  48. package/dist/apps-routes.js +114 -0
  49. package/dist/ascii.js +20 -0
  50. package/dist/auth/anthropic.js +44 -0
  51. package/dist/auth/apply-stealth.js +41 -0
  52. package/dist/auth/claude-code-stealth.js +78 -0
  53. package/dist/auth/credentials.js +156 -0
  54. package/dist/auth/index.js +5 -0
  55. package/dist/auth/openai-codex.js +66 -0
  56. package/dist/auth/types.js +9 -0
  57. package/dist/auth-routes.js +56 -0
  58. package/dist/autonomy-routes.js +44 -0
  59. package/dist/bug-report-routes.js +111 -0
  60. package/dist/build-info.json +6 -0
  61. package/dist/character-routes.js +195 -0
  62. package/dist/cli/argv.js +63 -0
  63. package/dist/cli/banner.js +34 -0
  64. package/dist/cli/cli-name.js +21 -0
  65. package/dist/cli/cli-utils.js +16 -0
  66. package/dist/cli/git-commit.js +78 -0
  67. package/dist/cli/parse-duration.js +15 -0
  68. package/dist/cli/plugins-cli.js +590 -0
  69. package/dist/cli/profile-utils.js +9 -0
  70. package/dist/cli/profile.js +95 -0
  71. package/dist/cli/program/build-program.js +17 -0
  72. package/dist/cli/program/command-registry.js +23 -0
  73. package/dist/cli/program/help.js +47 -0
  74. package/dist/cli/program/preaction.js +33 -0
  75. package/dist/cli/program/register.config.js +106 -0
  76. package/dist/cli/program/register.configure.js +20 -0
  77. package/dist/cli/program/register.dashboard.js +124 -0
  78. package/dist/cli/program/register.models.js +23 -0
  79. package/dist/cli/program/register.setup.js +36 -0
  80. package/dist/cli/program/register.start.js +22 -0
  81. package/dist/cli/program/register.subclis.js +70 -0
  82. package/dist/cli/program/register.tui.js +163 -0
  83. package/dist/cli/program/register.update.js +154 -0
  84. package/dist/cli/program.js +3 -0
  85. package/dist/cli/run-main.js +37 -0
  86. package/dist/cli/version.js +7 -0
  87. package/dist/cloud/validate-url.js +93 -0
  88. package/dist/cloud-routes.js +330 -0
  89. package/dist/cloud-status-routes.js +155 -0
  90. package/dist/compat-utils.js +111 -0
  91. package/dist/config/config.js +69 -0
  92. package/dist/config/env-vars.js +19 -0
  93. package/dist/config/includes.js +121 -0
  94. package/dist/config/object-utils.js +7 -0
  95. package/dist/config/paths.js +38 -0
  96. package/dist/config/plugin-auto-enable.js +231 -0
  97. package/dist/config/schema.js +864 -0
  98. package/dist/config/telegram-custom-commands.js +76 -0
  99. package/dist/config/zod-schema.agent-runtime.js +519 -0
  100. package/dist/config/zod-schema.core.js +538 -0
  101. package/dist/config/zod-schema.hooks.js +103 -0
  102. package/dist/config/zod-schema.js +488 -0
  103. package/dist/config/zod-schema.providers-core.js +785 -0
  104. package/dist/config/zod-schema.session.js +73 -0
  105. package/dist/core-plugins.js +37 -0
  106. package/dist/custom-actions.js +250 -0
  107. package/dist/database.js +735 -0
  108. package/dist/diagnostics/integration-observability.js +57 -0
  109. package/dist/diagnostics-routes.js +205 -0
  110. package/dist/drop-service.js +134 -0
  111. package/dist/early-logs.js +24 -0
  112. package/dist/eliza.js +2061 -0
  113. package/dist/emotes/catalog.js +271 -0
  114. package/dist/entry.js +40 -0
  115. package/dist/hooks/discovery.js +167 -0
  116. package/dist/hooks/eligibility.js +64 -0
  117. package/dist/hooks/index.js +4 -0
  118. package/dist/hooks/loader.js +147 -0
  119. package/dist/hooks/registry.js +55 -0
  120. package/dist/http-helpers.js +131 -0
  121. package/dist/index.js +49 -0
  122. package/dist/knowledge-routes.js +534 -0
  123. package/dist/memory-bounds.js +71 -0
  124. package/dist/milady-plugin.js +90 -0
  125. package/dist/models-routes.js +28 -0
  126. package/dist/onboarding-names.js +78 -0
  127. package/dist/onboarding-presets.js +922 -0
  128. package/dist/package.json +1 -0
  129. package/dist/permissions-routes.js +109 -0
  130. package/dist/plugin-validation.js +107 -0
  131. package/dist/plugins/whatsapp/actions.js +91 -0
  132. package/dist/plugins/whatsapp/index.js +16 -0
  133. package/dist/plugins/whatsapp/service.js +270 -0
  134. package/dist/provider-switch-config.js +41 -0
  135. package/dist/providers/admin-trust.js +46 -0
  136. package/dist/providers/autonomous-state.js +101 -0
  137. package/dist/providers/session-bridge.js +86 -0
  138. package/dist/providers/session-utils.js +36 -0
  139. package/dist/providers/simple-mode.js +50 -0
  140. package/dist/providers/ui-catalog.js +15 -0
  141. package/dist/providers/workspace-provider.js +93 -0
  142. package/dist/providers/workspace.js +348 -0
  143. package/dist/registry-routes.js +86 -0
  144. package/dist/registry-service.js +164 -0
  145. package/dist/restart.js +40 -0
  146. package/dist/runtime/core-plugins.js +37 -0
  147. package/dist/runtime/custom-actions.js +250 -0
  148. package/dist/runtime/eliza.js +2061 -0
  149. package/dist/runtime/embedding-manager-support.js +185 -0
  150. package/dist/runtime/embedding-manager.js +193 -0
  151. package/dist/runtime/embedding-presets.js +54 -0
  152. package/dist/runtime/embedding-state.js +8 -0
  153. package/dist/runtime/milady-plugin.js +90 -0
  154. package/dist/runtime/onboarding-names.js +78 -0
  155. package/dist/runtime/restart.js +40 -0
  156. package/dist/runtime/version.js +7 -0
  157. package/dist/sandbox-routes.js +1112 -0
  158. package/dist/security/audit-log.js +149 -0
  159. package/dist/security/network-policy.js +70 -0
  160. package/dist/server.js +7949 -0
  161. package/dist/services/agent-export.js +559 -0
  162. package/dist/services/app-manager.js +389 -0
  163. package/dist/services/browser-capture.js +86 -0
  164. package/dist/services/fallback-training-service.js +128 -0
  165. package/dist/services/mcp-marketplace.js +134 -0
  166. package/dist/services/plugin-installer.js +396 -0
  167. package/dist/services/plugin-manager-types.js +15 -0
  168. package/dist/services/registry-client-app-meta.js +144 -0
  169. package/dist/services/registry-client-endpoints.js +166 -0
  170. package/dist/services/registry-client-local.js +271 -0
  171. package/dist/services/registry-client-network.js +93 -0
  172. package/dist/services/registry-client-queries.js +70 -0
  173. package/dist/services/registry-client.js +157 -0
  174. package/dist/services/sandbox-engine.js +511 -0
  175. package/dist/services/sandbox-manager.js +297 -0
  176. package/dist/services/self-updater.js +175 -0
  177. package/dist/services/skill-catalog-client.js +119 -0
  178. package/dist/services/skill-marketplace.js +521 -0
  179. package/dist/services/stream-manager.js +236 -0
  180. package/dist/services/update-checker.js +121 -0
  181. package/dist/services/update-notifier.js +29 -0
  182. package/dist/services/version-compat.js +78 -0
  183. package/dist/services/whatsapp-pairing.js +196 -0
  184. package/dist/shared/ui-catalog-prompt.js +728 -0
  185. package/dist/subscription-routes.js +172 -0
  186. package/dist/terminal/links.js +19 -0
  187. package/dist/terminal/palette.js +14 -0
  188. package/dist/terminal/theme.js +25 -0
  189. package/dist/terminal-run-limits.js +24 -0
  190. package/dist/training-routes.js +158 -0
  191. package/dist/trajectory-routes.js +300 -0
  192. package/dist/trigger-routes.js +246 -0
  193. package/dist/triggers/action.js +218 -0
  194. package/dist/triggers/runtime.js +281 -0
  195. package/dist/triggers/scheduling.js +295 -0
  196. package/dist/triggers/types.js +5 -0
  197. package/dist/tui/components/assistant-message.js +76 -0
  198. package/dist/tui/components/chat-editor.js +34 -0
  199. package/dist/tui/components/embeddings-overlay.js +46 -0
  200. package/dist/tui/components/footer.js +60 -0
  201. package/dist/tui/components/index.js +15 -0
  202. package/dist/tui/components/modal-frame.js +45 -0
  203. package/dist/tui/components/modal-style.js +15 -0
  204. package/dist/tui/components/model-selector.js +70 -0
  205. package/dist/tui/components/pinned-chat-layout.js +46 -0
  206. package/dist/tui/components/plugins-endpoints-tab.js +196 -0
  207. package/dist/tui/components/plugins-installed-tab-view.js +69 -0
  208. package/dist/tui/components/plugins-installed-tab.js +319 -0
  209. package/dist/tui/components/plugins-overlay-catalog.js +81 -0
  210. package/dist/tui/components/plugins-overlay-data-api.js +21 -0
  211. package/dist/tui/components/plugins-overlay-data-shared.js +20 -0
  212. package/dist/tui/components/plugins-overlay-data.js +323 -0
  213. package/dist/tui/components/plugins-overlay.js +117 -0
  214. package/dist/tui/components/plugins-store-tab.js +148 -0
  215. package/dist/tui/components/settings-overlay.js +61 -0
  216. package/dist/tui/components/status-bar.js +64 -0
  217. package/dist/tui/components/tool-execution.js +68 -0
  218. package/dist/tui/components/user-message.js +22 -0
  219. package/dist/tui/eliza-tui-bridge.js +606 -0
  220. package/dist/tui/index.js +370 -0
  221. package/dist/tui/modal-presets.js +33 -0
  222. package/dist/tui/model-spec.js +46 -0
  223. package/dist/tui/sse-parser.js +78 -0
  224. package/dist/tui/theme.js +110 -0
  225. package/dist/tui/titlebar-spinner.js +62 -0
  226. package/dist/tui/tui-app.js +311 -0
  227. package/dist/tui/ws-client.js +215 -0
  228. package/dist/twitter-verify.js +134 -0
  229. package/dist/tx-service.js +108 -0
  230. package/dist/utils/exec-safety.js +17 -0
  231. package/dist/utils/globals.js +20 -0
  232. package/dist/utils/milady-root.js +61 -0
  233. package/dist/utils/number-parsing.js +37 -0
  234. package/dist/version-resolver.js +37 -0
  235. package/dist/version.js +7 -0
  236. package/dist/wallet-routes.js +266 -0
  237. package/dist/wallet.js +568 -0
  238. package/dist/whatsapp-routes.js +182 -0
  239. package/dist/zip-utils.js +109 -0
  240. package/milady.mjs +14 -0
  241. 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 };