@elizaos/autonomous 2.0.0-alpha.10

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/LICENSE +21 -0
  2. package/package.json +270 -0
  3. package/src/actions/emote.ts +101 -0
  4. package/src/actions/restart.ts +101 -0
  5. package/src/actions/send-message.ts +168 -0
  6. package/src/actions/stream-control.ts +439 -0
  7. package/src/actions/switch-stream-source.ts +126 -0
  8. package/src/actions/terminal.ts +186 -0
  9. package/src/api/agent-admin-routes.ts +178 -0
  10. package/src/api/agent-lifecycle-routes.ts +129 -0
  11. package/src/api/agent-model.ts +143 -0
  12. package/src/api/agent-transfer-routes.ts +211 -0
  13. package/src/api/apps-routes.ts +210 -0
  14. package/src/api/auth-routes.ts +90 -0
  15. package/src/api/bsc-trade.ts +736 -0
  16. package/src/api/bug-report-routes.ts +161 -0
  17. package/src/api/character-routes.ts +421 -0
  18. package/src/api/cloud-billing-routes.ts +598 -0
  19. package/src/api/cloud-compat-routes.ts +192 -0
  20. package/src/api/cloud-routes.ts +529 -0
  21. package/src/api/cloud-status-routes.ts +234 -0
  22. package/src/api/compat-utils.ts +154 -0
  23. package/src/api/connector-health.ts +135 -0
  24. package/src/api/coordinator-wiring.ts +179 -0
  25. package/src/api/credit-detection.ts +47 -0
  26. package/src/api/database.ts +1357 -0
  27. package/src/api/diagnostics-routes.ts +389 -0
  28. package/src/api/drop-service.ts +205 -0
  29. package/src/api/early-logs.ts +111 -0
  30. package/src/api/http-helpers.ts +252 -0
  31. package/src/api/index.ts +85 -0
  32. package/src/api/knowledge-routes.ts +1189 -0
  33. package/src/api/knowledge-service-loader.ts +92 -0
  34. package/src/api/memory-bounds.ts +121 -0
  35. package/src/api/memory-routes.ts +349 -0
  36. package/src/api/merkle-tree.ts +239 -0
  37. package/src/api/models-routes.ts +72 -0
  38. package/src/api/nfa-routes.ts +169 -0
  39. package/src/api/nft-verify.ts +188 -0
  40. package/src/api/og-tracker.ts +72 -0
  41. package/src/api/parse-action-block.ts +145 -0
  42. package/src/api/permissions-routes.ts +222 -0
  43. package/src/api/plugin-validation.ts +355 -0
  44. package/src/api/provider-switch-config.ts +455 -0
  45. package/src/api/registry-routes.ts +165 -0
  46. package/src/api/registry-service.ts +292 -0
  47. package/src/api/route-helpers.ts +21 -0
  48. package/src/api/sandbox-routes.ts +1480 -0
  49. package/src/api/server.ts +17674 -0
  50. package/src/api/signal-routes.ts +265 -0
  51. package/src/api/stream-persistence.ts +297 -0
  52. package/src/api/stream-route-state.ts +48 -0
  53. package/src/api/stream-routes.ts +1046 -0
  54. package/src/api/stream-voice-routes.ts +208 -0
  55. package/src/api/streaming-text.ts +129 -0
  56. package/src/api/streaming-types.ts +23 -0
  57. package/src/api/subscription-routes.ts +283 -0
  58. package/src/api/terminal-run-limits.ts +31 -0
  59. package/src/api/training-backend-check.ts +40 -0
  60. package/src/api/training-routes.ts +314 -0
  61. package/src/api/training-service-like.ts +46 -0
  62. package/src/api/trajectory-routes.ts +714 -0
  63. package/src/api/trigger-routes.ts +438 -0
  64. package/src/api/twitter-verify.ts +226 -0
  65. package/src/api/tx-service.ts +193 -0
  66. package/src/api/wallet-dex-prices.ts +206 -0
  67. package/src/api/wallet-evm-balance.ts +989 -0
  68. package/src/api/wallet-routes.ts +505 -0
  69. package/src/api/wallet-rpc.ts +523 -0
  70. package/src/api/wallet-trading-profile.ts +694 -0
  71. package/src/api/wallet.ts +745 -0
  72. package/src/api/whatsapp-routes.ts +282 -0
  73. package/src/api/zip-utils.ts +130 -0
  74. package/src/auth/anthropic.ts +63 -0
  75. package/src/auth/apply-stealth.ts +38 -0
  76. package/src/auth/claude-code-stealth.ts +141 -0
  77. package/src/auth/credentials.ts +226 -0
  78. package/src/auth/index.ts +18 -0
  79. package/src/auth/openai-codex.ts +94 -0
  80. package/src/auth/types.ts +24 -0
  81. package/src/awareness/registry.ts +220 -0
  82. package/src/bin.ts +10 -0
  83. package/src/cli/index.ts +36 -0
  84. package/src/cli/parse-duration.ts +43 -0
  85. package/src/cloud/auth.test.ts +370 -0
  86. package/src/cloud/auth.ts +176 -0
  87. package/src/cloud/backup.test.ts +150 -0
  88. package/src/cloud/backup.ts +50 -0
  89. package/src/cloud/base-url.ts +45 -0
  90. package/src/cloud/bridge-client.test.ts +481 -0
  91. package/src/cloud/bridge-client.ts +307 -0
  92. package/src/cloud/cloud-manager.test.ts +223 -0
  93. package/src/cloud/cloud-manager.ts +151 -0
  94. package/src/cloud/cloud-proxy.test.ts +122 -0
  95. package/src/cloud/cloud-proxy.ts +52 -0
  96. package/src/cloud/index.ts +23 -0
  97. package/src/cloud/reconnect.test.ts +178 -0
  98. package/src/cloud/reconnect.ts +108 -0
  99. package/src/cloud/validate-url.test.ts +147 -0
  100. package/src/cloud/validate-url.ts +176 -0
  101. package/src/config/character-schema.ts +44 -0
  102. package/src/config/config.ts +149 -0
  103. package/src/config/env-vars.ts +86 -0
  104. package/src/config/includes.ts +196 -0
  105. package/src/config/index.ts +15 -0
  106. package/src/config/object-utils.ts +10 -0
  107. package/src/config/paths.ts +92 -0
  108. package/src/config/plugin-auto-enable.ts +520 -0
  109. package/src/config/schema.ts +1342 -0
  110. package/src/config/telegram-custom-commands.ts +99 -0
  111. package/src/config/types.agent-defaults.ts +342 -0
  112. package/src/config/types.agents.ts +112 -0
  113. package/src/config/types.gateway.ts +243 -0
  114. package/src/config/types.hooks.ts +124 -0
  115. package/src/config/types.messages.ts +201 -0
  116. package/src/config/types.milady.ts +791 -0
  117. package/src/config/types.tools.ts +416 -0
  118. package/src/config/types.ts +7 -0
  119. package/src/config/zod-schema.agent-runtime.ts +777 -0
  120. package/src/config/zod-schema.core.ts +778 -0
  121. package/src/config/zod-schema.hooks.ts +139 -0
  122. package/src/config/zod-schema.providers-core.ts +1126 -0
  123. package/src/config/zod-schema.session.ts +98 -0
  124. package/src/config/zod-schema.ts +865 -0
  125. package/src/contracts/apps.ts +46 -0
  126. package/src/contracts/awareness.ts +56 -0
  127. package/src/contracts/config.ts +172 -0
  128. package/src/contracts/drop.ts +21 -0
  129. package/src/contracts/index.ts +8 -0
  130. package/src/contracts/onboarding.ts +592 -0
  131. package/src/contracts/permissions.ts +52 -0
  132. package/src/contracts/verification.ts +9 -0
  133. package/src/contracts/wallet.ts +503 -0
  134. package/src/diagnostics/integration-observability.ts +132 -0
  135. package/src/emotes/catalog.ts +655 -0
  136. package/src/external-modules.d.ts +7 -0
  137. package/src/hooks/discovery.test.ts +357 -0
  138. package/src/hooks/discovery.ts +231 -0
  139. package/src/hooks/eligibility.ts +146 -0
  140. package/src/hooks/hooks.test.ts +320 -0
  141. package/src/hooks/index.ts +8 -0
  142. package/src/hooks/loader.test.ts +418 -0
  143. package/src/hooks/loader.ts +256 -0
  144. package/src/hooks/registry.test.ts +168 -0
  145. package/src/hooks/registry.ts +74 -0
  146. package/src/hooks/types.ts +121 -0
  147. package/src/index.ts +19 -0
  148. package/src/onboarding-presets.ts +828 -0
  149. package/src/plugins/custom-rtmp/index.ts +40 -0
  150. package/src/providers/admin-trust.ts +76 -0
  151. package/src/providers/session-bridge.ts +143 -0
  152. package/src/providers/session-utils.ts +42 -0
  153. package/src/providers/simple-mode.ts +113 -0
  154. package/src/providers/ui-catalog.ts +135 -0
  155. package/src/providers/workspace-provider.ts +213 -0
  156. package/src/providers/workspace.ts +497 -0
  157. package/src/runtime/agent-event-service.ts +57 -0
  158. package/src/runtime/cloud-onboarding.test.ts +489 -0
  159. package/src/runtime/cloud-onboarding.ts +408 -0
  160. package/src/runtime/core-plugins.ts +53 -0
  161. package/src/runtime/custom-actions.ts +605 -0
  162. package/src/runtime/eliza.ts +4941 -0
  163. package/src/runtime/embedding-presets.ts +73 -0
  164. package/src/runtime/index.ts +8 -0
  165. package/src/runtime/milady-plugin.ts +180 -0
  166. package/src/runtime/onboarding-names.ts +76 -0
  167. package/src/runtime/release-plugin-policy.ts +119 -0
  168. package/src/runtime/restart.ts +59 -0
  169. package/src/runtime/trajectory-persistence.ts +2584 -0
  170. package/src/runtime/version.ts +6 -0
  171. package/src/security/audit-log.ts +222 -0
  172. package/src/security/network-policy.ts +91 -0
  173. package/src/server/index.ts +6 -0
  174. package/src/services/agent-export.ts +976 -0
  175. package/src/services/app-manager.ts +755 -0
  176. package/src/services/browser-capture.ts +215 -0
  177. package/src/services/coding-agent-context.ts +355 -0
  178. package/src/services/fallback-training-service.ts +196 -0
  179. package/src/services/index.ts +17 -0
  180. package/src/services/mcp-marketplace.ts +327 -0
  181. package/src/services/plugin-manager-types.ts +185 -0
  182. package/src/services/privy-wallets.ts +352 -0
  183. package/src/services/registry-client-app-meta.ts +201 -0
  184. package/src/services/registry-client-endpoints.ts +253 -0
  185. package/src/services/registry-client-local.ts +485 -0
  186. package/src/services/registry-client-network.ts +173 -0
  187. package/src/services/registry-client-queries.ts +176 -0
  188. package/src/services/registry-client-types.ts +104 -0
  189. package/src/services/registry-client.ts +366 -0
  190. package/src/services/remote-signing-service.ts +261 -0
  191. package/src/services/sandbox-engine.ts +753 -0
  192. package/src/services/sandbox-manager.ts +503 -0
  193. package/src/services/self-updater.ts +213 -0
  194. package/src/services/signal-pairing.ts +189 -0
  195. package/src/services/signing-policy.ts +230 -0
  196. package/src/services/skill-catalog-client.ts +195 -0
  197. package/src/services/skill-marketplace.ts +909 -0
  198. package/src/services/stream-manager.ts +707 -0
  199. package/src/services/tts-stream-bridge.ts +465 -0
  200. package/src/services/update-checker.ts +163 -0
  201. package/src/services/version-compat.ts +367 -0
  202. package/src/services/whatsapp-pairing.ts +279 -0
  203. package/src/shared/ui-catalog-prompt.ts +1158 -0
  204. package/src/test-support/process-helpers.ts +35 -0
  205. package/src/test-support/route-test-helpers.ts +113 -0
  206. package/src/test-support/test-helpers.ts +304 -0
  207. package/src/testing/index.ts +3 -0
  208. package/src/triggers/action.ts +342 -0
  209. package/src/triggers/runtime.ts +432 -0
  210. package/src/triggers/scheduling.ts +472 -0
  211. package/src/triggers/types.ts +133 -0
  212. package/src/types/app-hyperscape-routes-shim.d.ts +29 -0
  213. package/src/types/external-modules.d.ts +7 -0
  214. package/src/utils/exec-safety.ts +23 -0
  215. package/src/utils/number-parsing.ts +112 -0
  216. package/src/utils/spoken-text.ts +65 -0
  217. package/src/version-resolver.ts +60 -0
  218. package/test/api/agent-admin-routes.test.ts +160 -0
  219. package/test/api/agent-lifecycle-routes.test.ts +164 -0
  220. package/test/api/agent-transfer-routes.test.ts +136 -0
  221. package/test/api/apps-routes.test.ts +140 -0
  222. package/test/api/auth-routes.test.ts +160 -0
  223. package/test/api/bug-report-routes.test.ts +88 -0
  224. package/test/api/knowledge-routes.test.ts +73 -0
  225. package/test/api/lifecycle.test.ts +342 -0
  226. package/test/api/memory-routes.test.ts +74 -0
  227. package/test/api/models-routes.test.ts +112 -0
  228. package/test/api/nfa-routes.test.ts +78 -0
  229. package/test/api/permissions-routes.test.ts +185 -0
  230. package/test/api/registry-routes.test.ts +157 -0
  231. package/test/api/signal-routes.test.ts +113 -0
  232. package/test/api/subscription-routes.test.ts +90 -0
  233. package/test/api/trigger-routes.test.ts +87 -0
  234. package/test/api/wallet-routes.observability.test.ts +191 -0
  235. package/test/api/wallet-routes.test.ts +502 -0
  236. package/test/diagnostics/integration-observability.test.ts +135 -0
  237. package/test/security/audit-log.test.ts +229 -0
  238. package/test/security/network-policy.test.ts +143 -0
  239. package/test/services/version-compat.test.ts +127 -0
  240. package/tsconfig.build.json +21 -0
  241. package/tsconfig.json +19 -0
@@ -0,0 +1,485 @@
1
+ import fs from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import {
6
+ mergeAppMeta,
7
+ resolveAppOverride,
8
+ } from "./registry-client-app-meta.js";
9
+ import type {
10
+ AppUiExtensionConfig,
11
+ RegistryAppMeta,
12
+ RegistryAppViewerMeta,
13
+ RegistryPluginInfo,
14
+ } from "./registry-client-types.js";
15
+
16
+ interface LocalPackageAppMeta {
17
+ displayName?: string;
18
+ category?: string;
19
+ launchType?: string;
20
+ launchUrl?: string | null;
21
+ icon?: string | null;
22
+ capabilities?: string[];
23
+ minPlayers?: number | null;
24
+ maxPlayers?: number | null;
25
+ uiExtension?: AppUiExtensionConfig;
26
+ viewer?: RegistryAppViewerMeta;
27
+ }
28
+
29
+ interface LocalPackageElizaConfig {
30
+ kind?: string;
31
+ app?: LocalPackageAppMeta;
32
+ }
33
+
34
+ interface LocalPackageJson {
35
+ name?: string;
36
+ version?: string;
37
+ description?: string;
38
+ homepage?: string;
39
+ keywords?: string[];
40
+ repository?: string | { type?: string; url?: string };
41
+ elizaos?: LocalPackageElizaConfig;
42
+ }
43
+
44
+ interface LocalPluginManifest {
45
+ id?: string;
46
+ name?: string;
47
+ version?: string;
48
+ description?: string;
49
+ homepage?: string;
50
+ tags?: string[];
51
+ repository?: string | { type?: string; url?: string };
52
+ kind?: string;
53
+ app?: LocalPackageAppMeta;
54
+ }
55
+
56
+ const LOCAL_PLUGIN_TAG_STOPWORDS = new Set([
57
+ "plugin",
58
+ "plugins",
59
+ "eliza",
60
+ "elizaos",
61
+ "milady",
62
+ "elizaos-plugin",
63
+ "elizaos-plugins",
64
+ "feature",
65
+ ]);
66
+
67
+ function uniquePaths(paths: string[]): string[] {
68
+ const seen = new Set<string>();
69
+ const ordered: string[] = [];
70
+ for (const p of paths) {
71
+ const resolved = path.resolve(p);
72
+ if (!seen.has(resolved)) {
73
+ seen.add(resolved);
74
+ ordered.push(resolved);
75
+ }
76
+ }
77
+ return ordered;
78
+ }
79
+
80
+ function resolveWorkspaceRoots(): string[] {
81
+ const envRoot = process.env.MILADY_WORKSPACE_ROOT?.trim();
82
+ if (envRoot) return uniquePaths([envRoot]);
83
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
84
+ const packageRoot = path.resolve(moduleDir, "..", "..");
85
+ const cwd = process.cwd();
86
+ const roots = [
87
+ packageRoot,
88
+ cwd,
89
+ path.resolve(cwd, ".."),
90
+ path.resolve(cwd, "..", ".."),
91
+ ].filter((candidate): candidate is string => Boolean(candidate));
92
+ return uniquePaths(roots);
93
+ }
94
+
95
+ function repoString(
96
+ repo: LocalPackageJson["repository"] | LocalPluginManifest["repository"],
97
+ ): string | null {
98
+ if (!repo) return null;
99
+ if (typeof repo === "string") return repo;
100
+ if (typeof repo.url === "string" && repo.url.length > 0) return repo.url;
101
+ return null;
102
+ }
103
+
104
+ function normaliseGitHubRepo(repo: string | null): string | null {
105
+ if (!repo) return null;
106
+ const cleaned = repo
107
+ .replace(/^git\+/, "")
108
+ .replace(/\.git$/, "")
109
+ .replace(/^https?:\/\/github\.com\//, "")
110
+ .replace(/^git@github\.com:/, "")
111
+ .trim();
112
+ if (!cleaned.includes("/")) return null;
113
+ return cleaned;
114
+ }
115
+
116
+ async function readJsonFile<T>(filePath: string): Promise<T | null> {
117
+ try {
118
+ const raw = await fs.readFile(filePath, "utf-8");
119
+ return JSON.parse(raw) as T;
120
+ } catch {
121
+ return null;
122
+ }
123
+ }
124
+
125
+ function normalizeLocalTag(tag: string): string | null {
126
+ const normalized = tag
127
+ .trim()
128
+ .toLowerCase()
129
+ .replace(/&/g, " and ")
130
+ .replace(/[^a-z0-9]+/g, "-")
131
+ .replace(/^-+|-+$/g, "");
132
+ if (!normalized || LOCAL_PLUGIN_TAG_STOPWORDS.has(normalized)) return null;
133
+ return normalized;
134
+ }
135
+
136
+ function normalizeLocalTags(values: unknown): string[] {
137
+ if (!Array.isArray(values)) return [];
138
+ const tags: string[] = [];
139
+ const seen = new Set<string>();
140
+ for (const value of values) {
141
+ if (typeof value !== "string") continue;
142
+ const normalized = normalizeLocalTag(value);
143
+ if (!normalized || seen.has(normalized)) continue;
144
+ seen.add(normalized);
145
+ tags.push(normalized);
146
+ }
147
+ return tags;
148
+ }
149
+
150
+ function toLocalAppMeta(
151
+ app: LocalPackageAppMeta | undefined,
152
+ fallbackDisplayName: string,
153
+ ): RegistryAppMeta | undefined {
154
+ if (!app) return undefined;
155
+ const launchType = app.launchType ?? "url";
156
+ return {
157
+ displayName: app.displayName ?? fallbackDisplayName,
158
+ category: app.category ?? "game",
159
+ launchType,
160
+ launchUrl: app.launchUrl ?? null,
161
+ icon: app.icon ?? null,
162
+ capabilities: app.capabilities ?? [],
163
+ minPlayers: app.minPlayers ?? null,
164
+ maxPlayers: app.maxPlayers ?? null,
165
+ uiExtension: app.uiExtension,
166
+ viewer: app.viewer,
167
+ };
168
+ }
169
+
170
+ function toDisplayNameFromDirName(dirName: string): string {
171
+ return dirName
172
+ .replace(/^app-/, "")
173
+ .split("-")
174
+ .filter((part) => part.length > 0)
175
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
176
+ .join(" ");
177
+ }
178
+
179
+ function parseRepositoryMetadata(
180
+ repository:
181
+ | LocalPackageJson["repository"]
182
+ | LocalPluginManifest["repository"]
183
+ | undefined,
184
+ ): { gitRepo: string; gitUrl: string } {
185
+ const repoValue = repoString(repository);
186
+ const gitRepo = normaliseGitHubRepo(repoValue) ?? "local/workspace";
187
+ return {
188
+ gitRepo,
189
+ gitUrl: `https://github.com/${gitRepo}.git`,
190
+ };
191
+ }
192
+
193
+ function buildDiscoveredEntry(
194
+ packageDir: string,
195
+ dirName: string,
196
+ packageJson: LocalPackageJson,
197
+ manifest: LocalPluginManifest | null,
198
+ ): RegistryPluginInfo | null {
199
+ if (!packageJson?.name || packageJson.name.length === 0) return null;
200
+
201
+ const packageAppMeta = toLocalAppMeta(
202
+ packageJson.elizaos?.app,
203
+ toDisplayNameFromDirName(dirName),
204
+ );
205
+ const manifestAppMeta = toLocalAppMeta(
206
+ manifest?.app,
207
+ toDisplayNameFromDirName(dirName),
208
+ );
209
+ const mergedMeta = mergeAppMeta(manifestAppMeta, packageAppMeta);
210
+ const overriddenMeta = resolveAppOverride(packageJson.name, mergedMeta);
211
+
212
+ const kind =
213
+ packageJson.elizaos?.kind === "app" || manifest?.kind === "app"
214
+ ? "app"
215
+ : overriddenMeta
216
+ ? "app"
217
+ : undefined;
218
+
219
+ const repo = parseRepositoryMetadata(
220
+ packageJson.repository ?? manifest?.repository,
221
+ );
222
+ const description = packageJson.description ?? manifest?.description ?? "";
223
+ const topics = normalizeLocalTags([
224
+ ...(packageJson.keywords ?? []),
225
+ ...(manifest?.tags ?? []),
226
+ ]);
227
+ const homepage =
228
+ packageJson.homepage ??
229
+ manifest?.homepage ??
230
+ overriddenMeta?.launchUrl ??
231
+ null;
232
+ const version = packageJson.version ?? manifest?.version ?? null;
233
+
234
+ return {
235
+ name: packageJson.name,
236
+ gitRepo: repo.gitRepo,
237
+ gitUrl: repo.gitUrl,
238
+ description,
239
+ homepage,
240
+ topics,
241
+ stars: 0,
242
+ language: "TypeScript",
243
+ npm: {
244
+ package: packageJson.name,
245
+ v0Version: null,
246
+ v1Version: null,
247
+ v2Version: version,
248
+ },
249
+ git: {
250
+ v0Branch: null,
251
+ v1Branch: null,
252
+ v2Branch: "main",
253
+ },
254
+ supports: { v0: false, v1: false, v2: true },
255
+ localPath: packageDir,
256
+ kind,
257
+ appMeta: overriddenMeta ?? undefined,
258
+ };
259
+ }
260
+
261
+ async function discoverLocalWorkspaceApps(): Promise<
262
+ Map<string, RegistryPluginInfo>
263
+ > {
264
+ const discovered = new Map<string, RegistryPluginInfo>();
265
+
266
+ for (const workspaceRoot of resolveWorkspaceRoots()) {
267
+ const pluginsDir = path.join(workspaceRoot, "plugins");
268
+ let entries: Array<import("node:fs").Dirent>;
269
+ try {
270
+ entries = await fs.readdir(pluginsDir, { withFileTypes: true });
271
+ } catch {
272
+ continue;
273
+ }
274
+
275
+ for (const entry of entries) {
276
+ if (
277
+ (!entry.isDirectory() && !entry.isSymbolicLink()) ||
278
+ !entry.name.startsWith("app-")
279
+ )
280
+ continue;
281
+ const packageDir = path.join(pluginsDir, entry.name);
282
+ const packageJson = await readJsonFile<LocalPackageJson>(
283
+ path.join(packageDir, "package.json"),
284
+ );
285
+ if (!packageJson) continue;
286
+
287
+ const manifest = await readJsonFile<LocalPluginManifest>(
288
+ path.join(packageDir, "elizaos.plugin.json"),
289
+ );
290
+ const info = buildDiscoveredEntry(
291
+ packageDir,
292
+ entry.name,
293
+ packageJson,
294
+ manifest,
295
+ );
296
+ if (info) discovered.set(info.name, info);
297
+ }
298
+ }
299
+
300
+ const stateDir =
301
+ process.env.MILADY_STATE_DIR?.trim() || path.join(os.homedir(), ".milady");
302
+ const installedBase = path.join(stateDir, "plugins", "installed");
303
+ try {
304
+ const installedEntries = await fs.readdir(installedBase, {
305
+ withFileTypes: true,
306
+ });
307
+ for (const entry of installedEntries) {
308
+ if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
309
+ const installDir = path.join(installedBase, entry.name);
310
+ const nmDir = path.join(installDir, "node_modules");
311
+ const pkgDirs: string[] = [];
312
+ try {
313
+ const nmEntries = await fs.readdir(nmDir, { withFileTypes: true });
314
+ for (const nm of nmEntries) {
315
+ if (nm.name.startsWith("@")) {
316
+ const scopeDir = path.join(nmDir, nm.name);
317
+ try {
318
+ const scopeEntries = await fs.readdir(scopeDir, {
319
+ withFileTypes: true,
320
+ });
321
+ for (const se of scopeEntries) {
322
+ pkgDirs.push(path.join(scopeDir, se.name));
323
+ }
324
+ } catch {
325
+ // skip
326
+ }
327
+ } else if (nm.isDirectory() || nm.isSymbolicLink()) {
328
+ pkgDirs.push(path.join(nmDir, nm.name));
329
+ }
330
+ }
331
+ } catch {
332
+ continue;
333
+ }
334
+
335
+ for (const pkgDir of pkgDirs) {
336
+ const pkgJson = await readJsonFile<LocalPackageJson>(
337
+ path.join(pkgDir, "package.json"),
338
+ );
339
+ if (!pkgJson?.name) continue;
340
+ if (pkgJson.elizaos?.kind !== "app") continue;
341
+ if (discovered.has(pkgJson.name)) continue;
342
+
343
+ const manifest = await readJsonFile<LocalPluginManifest>(
344
+ path.join(pkgDir, "elizaos.plugin.json"),
345
+ );
346
+ const dirName = pkgJson.name
347
+ .replace(/^@[^/]+\//, "")
348
+ .replace(/^plugin-/, "app-");
349
+ const info = buildDiscoveredEntry(pkgDir, dirName, pkgJson, manifest);
350
+ if (info) discovered.set(info.name, info);
351
+ }
352
+ }
353
+ } catch {
354
+ // installed dir may not exist
355
+ }
356
+
357
+ return discovered;
358
+ }
359
+
360
+ async function discoverNodeModulePlugins(): Promise<
361
+ Map<string, RegistryPluginInfo>
362
+ > {
363
+ const discovered = new Map<string, RegistryPluginInfo>();
364
+
365
+ for (const workspaceRoot of resolveWorkspaceRoots()) {
366
+ const elizaosDir = path.join(workspaceRoot, "node_modules", "@elizaos");
367
+ let entries: Array<import("node:fs").Dirent>;
368
+ try {
369
+ entries = await fs.readdir(elizaosDir, { withFileTypes: true });
370
+ } catch {
371
+ continue;
372
+ }
373
+
374
+ for (const entry of entries) {
375
+ if (!entry.name.startsWith("plugin-")) continue;
376
+ if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
377
+
378
+ const packageDir = path.join(elizaosDir, entry.name);
379
+ const packageJson = await readJsonFile<
380
+ LocalPackageJson & {
381
+ packageType?: string;
382
+ keywords?: string[];
383
+ agentConfig?: Record<string, unknown>;
384
+ }
385
+ >(path.join(packageDir, "package.json"));
386
+ if (!packageJson?.name) continue;
387
+
388
+ const isPlugin =
389
+ packageJson.packageType === "plugin" ||
390
+ packageJson.keywords?.includes("elizaos") ||
391
+ packageJson.elizaos !== undefined ||
392
+ packageJson.agentConfig !== undefined;
393
+ if (!isPlugin) continue;
394
+
395
+ if (packageJson.elizaos?.kind === "app") continue;
396
+
397
+ const repo = parseRepositoryMetadata(packageJson.repository);
398
+ const version = packageJson.version ?? null;
399
+
400
+ let localPath = packageDir;
401
+ try {
402
+ const realPath = await fs.realpath(packageDir);
403
+ if (realPath !== packageDir) localPath = realPath;
404
+ } catch {
405
+ // fallback
406
+ }
407
+
408
+ discovered.set(packageJson.name, {
409
+ name: packageJson.name,
410
+ gitRepo: repo.gitRepo,
411
+ gitUrl: repo.gitUrl,
412
+ description: packageJson.description ?? "",
413
+ homepage: packageJson.homepage ?? null,
414
+ topics: normalizeLocalTags(packageJson.keywords),
415
+ stars: 0,
416
+ language: "TypeScript",
417
+ npm: {
418
+ package: packageJson.name,
419
+ v0Version: null,
420
+ v1Version: null,
421
+ v2Version: version,
422
+ },
423
+ git: {
424
+ v0Branch: null,
425
+ v1Branch: null,
426
+ v2Branch: "main",
427
+ },
428
+ supports: { v0: false, v1: false, v2: true },
429
+ localPath,
430
+ });
431
+ }
432
+ }
433
+
434
+ return discovered;
435
+ }
436
+
437
+ export async function applyNodeModulePlugins(
438
+ plugins: Map<string, RegistryPluginInfo>,
439
+ ): Promise<void> {
440
+ const localPlugins = await discoverNodeModulePlugins();
441
+ if (localPlugins.size === 0) return;
442
+
443
+ for (const [name, localInfo] of localPlugins.entries()) {
444
+ const existing = plugins.get(name);
445
+ if (!existing) {
446
+ plugins.set(name, localInfo);
447
+ } else if (!existing.localPath) {
448
+ plugins.set(name, { ...existing, localPath: localInfo.localPath });
449
+ }
450
+ }
451
+ }
452
+
453
+ export async function applyLocalWorkspaceApps(
454
+ plugins: Map<string, RegistryPluginInfo>,
455
+ ): Promise<void> {
456
+ const localApps = await discoverLocalWorkspaceApps();
457
+ if (localApps.size === 0) return;
458
+
459
+ for (const [name, localInfo] of localApps.entries()) {
460
+ const existing = plugins.get(name);
461
+ if (!existing) {
462
+ plugins.set(name, localInfo);
463
+ continue;
464
+ }
465
+
466
+ plugins.set(name, {
467
+ ...existing,
468
+ localPath: localInfo.localPath,
469
+ kind: localInfo.kind ?? existing.kind,
470
+ appMeta: mergeAppMeta(existing.appMeta, localInfo.appMeta),
471
+ description: localInfo.description || existing.description,
472
+ homepage: localInfo.homepage ?? existing.homepage,
473
+ npm: {
474
+ ...existing.npm,
475
+ package: existing.npm.package || localInfo.npm.package,
476
+ v2Version: existing.npm.v2Version ?? localInfo.npm.v2Version,
477
+ },
478
+ git: {
479
+ v0Branch: existing.git.v0Branch ?? localInfo.git.v0Branch,
480
+ v1Branch: existing.git.v1Branch ?? localInfo.git.v1Branch,
481
+ v2Branch: existing.git.v2Branch ?? localInfo.git.v2Branch,
482
+ },
483
+ });
484
+ }
485
+ }
@@ -0,0 +1,173 @@
1
+ import { createIntegrationTelemetrySpan } from "../diagnostics/integration-observability";
2
+ import type { RegistryPluginInfo } from "./registry-client-types.js";
3
+
4
+ export async function fetchFromNetwork(params: {
5
+ generatedRegistryUrl: string;
6
+ indexRegistryUrl: string;
7
+ applyLocalWorkspaceApps: (
8
+ plugins: Map<string, RegistryPluginInfo>,
9
+ ) => Promise<void>;
10
+ applyNodeModulePlugins: (
11
+ plugins: Map<string, RegistryPluginInfo>,
12
+ ) => Promise<void>;
13
+ sanitizeSandbox: (value?: string) => string;
14
+ }): Promise<Map<string, RegistryPluginInfo>> {
15
+ const {
16
+ generatedRegistryUrl,
17
+ indexRegistryUrl,
18
+ applyLocalWorkspaceApps,
19
+ applyNodeModulePlugins,
20
+ sanitizeSandbox,
21
+ } = params;
22
+
23
+ const generatedSpan = createIntegrationTelemetrySpan({
24
+ boundary: "marketplace",
25
+ operation: "fetch_generated_registry",
26
+ });
27
+ try {
28
+ const resp = await fetch(generatedRegistryUrl, { redirect: "error" });
29
+ if (resp.ok) {
30
+ const data = (await resp.json()) as {
31
+ registry: Record<
32
+ string,
33
+ {
34
+ git: {
35
+ repo: string;
36
+ v0: { branch: string | null };
37
+ v1: { branch: string | null };
38
+ v2: { branch: string | null };
39
+ };
40
+ npm: {
41
+ repo: string;
42
+ v0: string | null;
43
+ v1: string | null;
44
+ v2: string | null;
45
+ };
46
+ supports: { v0: boolean; v1: boolean; v2: boolean };
47
+ description: string;
48
+ homepage: string | null;
49
+ topics: string[];
50
+ stargazers_count: number;
51
+ language: string;
52
+ kind?: string;
53
+ app?: {
54
+ displayName: string;
55
+ category: string;
56
+ launchType: string;
57
+ launchUrl: string | null;
58
+ icon: string | null;
59
+ capabilities: string[];
60
+ minPlayers: number | null;
61
+ maxPlayers: number | null;
62
+ uiExtension?: {
63
+ detailPanelId: string;
64
+ };
65
+ viewer?: {
66
+ url: string;
67
+ embedParams?: Record<string, string>;
68
+ postMessageAuth?: boolean;
69
+ sandbox?: string;
70
+ };
71
+ };
72
+ }
73
+ >;
74
+ };
75
+ const plugins = new Map<string, RegistryPluginInfo>();
76
+ for (const [name, e] of Object.entries(data.registry)) {
77
+ const info: RegistryPluginInfo = {
78
+ name,
79
+ gitRepo: e.git.repo,
80
+ gitUrl: `https://github.com/${e.git.repo}.git`,
81
+ description: e.description || "",
82
+ homepage: e.homepage,
83
+ topics: e.topics || [],
84
+ stars: e.stargazers_count || 0,
85
+ language: e.language || "TypeScript",
86
+ npm: {
87
+ package: e.npm.repo,
88
+ v0Version: e.npm.v0,
89
+ v1Version: e.npm.v1,
90
+ v2Version: e.npm.v2,
91
+ },
92
+ git: {
93
+ v0Branch: e.git.v0?.branch ?? null,
94
+ v1Branch: e.git.v1?.branch ?? null,
95
+ v2Branch: e.git.v2?.branch ?? null,
96
+ },
97
+ supports: e.supports,
98
+ };
99
+
100
+ if (e.kind === "app" || e.app) {
101
+ info.kind = "app";
102
+ }
103
+ if (e.app) {
104
+ info.appMeta = {
105
+ displayName: e.app.displayName,
106
+ category: e.app.category,
107
+ launchType: e.app.launchType,
108
+ launchUrl: e.app.launchUrl,
109
+ icon: e.app.icon,
110
+ capabilities: e.app.capabilities || [],
111
+ minPlayers: e.app.minPlayers ?? null,
112
+ maxPlayers: e.app.maxPlayers ?? null,
113
+ uiExtension: e.app.uiExtension,
114
+ viewer: e.app.viewer
115
+ ? {
116
+ ...e.app.viewer,
117
+ sandbox: sanitizeSandbox(e.app.viewer.sandbox),
118
+ }
119
+ : undefined,
120
+ };
121
+ }
122
+
123
+ plugins.set(name, info);
124
+ }
125
+ await applyLocalWorkspaceApps(plugins);
126
+ await applyNodeModulePlugins(plugins);
127
+ generatedSpan.success({ statusCode: resp.status });
128
+ return plugins;
129
+ }
130
+ generatedSpan.failure({ statusCode: resp.status, errorKind: "http_error" });
131
+ } catch (err) {
132
+ generatedSpan.failure({ error: err });
133
+ // caller logs fallback warnings
134
+ }
135
+
136
+ const indexSpan = createIntegrationTelemetrySpan({
137
+ boundary: "marketplace",
138
+ operation: "fetch_index_registry",
139
+ });
140
+ let resp: Response;
141
+ try {
142
+ resp = await fetch(indexRegistryUrl, { redirect: "error" });
143
+ } catch (err) {
144
+ indexSpan.failure({ error: err });
145
+ throw err;
146
+ }
147
+ if (!resp.ok) {
148
+ indexSpan.failure({ statusCode: resp.status, errorKind: "http_error" });
149
+ throw new Error(`index.json: ${resp.status} ${resp.statusText}`);
150
+ }
151
+ const data = (await resp.json()) as Record<string, string>;
152
+ const plugins = new Map<string, RegistryPluginInfo>();
153
+ for (const [name, gitRef] of Object.entries(data)) {
154
+ const repo = gitRef.replace(/^github:/, "");
155
+ plugins.set(name, {
156
+ name,
157
+ gitRepo: repo,
158
+ gitUrl: `https://github.com/${repo}.git`,
159
+ description: "",
160
+ homepage: null,
161
+ topics: [],
162
+ stars: 0,
163
+ language: "TypeScript",
164
+ npm: { package: name, v0Version: null, v1Version: null, v2Version: null },
165
+ git: { v0Branch: null, v1Branch: null, v2Branch: "next" },
166
+ supports: { v0: false, v1: false, v2: false },
167
+ });
168
+ }
169
+ await applyLocalWorkspaceApps(plugins);
170
+ await applyNodeModulePlugins(plugins);
171
+ indexSpan.success({ statusCode: resp.status });
172
+ return plugins;
173
+ }