@elizaos/app-core 2.0.0-beta.3 → 2.0.3-beta.3

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 (1466) hide show
  1. package/agent-bridge.d.ts +27 -0
  2. package/agent-bridge.d.ts.map +1 -0
  3. package/agent-bridge.js +26 -0
  4. package/api/__tests__/sandbox-test-helpers.js +1 -1
  5. package/api/auth/audit.d.ts +1 -1
  6. package/api/auth/audit.js +1 -1
  7. package/api/auth/auth-context.d.ts +1 -1
  8. package/api/auth/auth-context.js +1 -1
  9. package/api/auth/bootstrap-token.d.ts +1 -1
  10. package/api/auth/bootstrap-token.js +2 -2
  11. package/api/auth/index.d.ts +9 -10
  12. package/api/auth/index.d.ts.map +1 -1
  13. package/api/auth/index.js +9 -10
  14. package/api/auth/passwords.js +2 -2
  15. package/api/auth/sensitive-rate-limit.d.ts +1 -4
  16. package/api/auth/sensitive-rate-limit.d.ts.map +1 -1
  17. package/api/auth/sensitive-rate-limit.js +6 -6
  18. package/api/auth/sessions.d.ts +1 -1
  19. package/api/auth/sessions.js +2 -2
  20. package/api/auth-bootstrap-routes.d.ts +7 -14
  21. package/api/auth-bootstrap-routes.d.ts.map +1 -1
  22. package/api/auth-bootstrap-routes.js +14 -27
  23. package/api/auth-pairing-routes.d.ts +17 -0
  24. package/api/auth-pairing-routes.d.ts.map +1 -0
  25. package/api/auth-pairing-routes.js +299 -0
  26. package/api/auth-session-routes.d.ts +2 -2
  27. package/api/auth-session-routes.d.ts.map +1 -1
  28. package/api/auth-session-routes.js +36 -15
  29. package/api/auth.d.ts +13 -20
  30. package/api/auth.d.ts.map +1 -1
  31. package/api/auth.js +32 -27
  32. package/api/automations-compat-routes.d.ts +1 -1
  33. package/api/automations-compat-routes.d.ts.map +1 -1
  34. package/api/automations-compat-routes.js +5 -5
  35. package/api/background-tasks-routes.d.ts +4 -0
  36. package/api/background-tasks-routes.d.ts.map +1 -0
  37. package/api/background-tasks-routes.js +63 -0
  38. package/api/catalog-routes.d.ts +1 -1
  39. package/api/catalog-routes.js +3 -3
  40. package/api/cloud-pair-route.d.ts +26 -0
  41. package/api/cloud-pair-route.d.ts.map +1 -0
  42. package/api/cloud-pair-route.js +222 -0
  43. package/api/cloud-voice-routes.d.ts +52 -0
  44. package/api/cloud-voice-routes.d.ts.map +1 -0
  45. package/api/cloud-voice-routes.js +50 -0
  46. package/api/compat-route-shared.d.ts +14 -7
  47. package/api/compat-route-shared.d.ts.map +1 -1
  48. package/api/compat-route-shared.js +27 -188
  49. package/api/credential-resolver.d.ts +2 -2
  50. package/api/credential-resolver.d.ts.map +1 -1
  51. package/api/credential-resolver.js +8 -2
  52. package/api/database-rows-compat-routes.d.ts +1 -1
  53. package/api/database-rows-compat-routes.d.ts.map +1 -1
  54. package/api/database-rows-compat-routes.js +69 -31
  55. package/api/dev-boot-history.d.ts +26 -0
  56. package/api/dev-boot-history.d.ts.map +1 -0
  57. package/api/dev-boot-history.js +69 -0
  58. package/api/dev-compat-routes.d.ts +6 -1
  59. package/api/dev-compat-routes.d.ts.map +1 -1
  60. package/api/dev-compat-routes.js +127 -4
  61. package/api/dev-console-log.d.ts +2 -2
  62. package/api/dev-console-log.d.ts.map +1 -1
  63. package/api/dev-console-log.js +8 -5
  64. package/api/dev-route-catalog.d.ts +58 -0
  65. package/api/dev-route-catalog.d.ts.map +1 -0
  66. package/api/dev-route-catalog.js +477 -0
  67. package/api/dev-stack.d.ts.map +1 -1
  68. package/api/dev-stack.js +6 -9
  69. package/api/drop-status-compat-route.d.ts +3 -0
  70. package/api/drop-status-compat-route.d.ts.map +1 -0
  71. package/api/drop-status-compat-route.js +12 -0
  72. package/api/first-run-routes.d.ts +4 -0
  73. package/api/first-run-routes.d.ts.map +1 -0
  74. package/api/first-run-routes.js +208 -0
  75. package/api/first-run-tts-route.d.ts +19 -0
  76. package/api/first-run-tts-route.d.ts.map +1 -0
  77. package/api/first-run-tts-route.js +59 -0
  78. package/api/internal-routes.d.ts +23 -0
  79. package/api/internal-routes.d.ts.map +1 -0
  80. package/api/internal-routes.js +203 -0
  81. package/api/ios-local-agent-transport.d.ts +36 -0
  82. package/api/ios-local-agent-transport.d.ts.map +1 -0
  83. package/api/ios-local-agent-transport.js +566 -0
  84. package/api/onboarding-voice-lines.d.ts +23 -0
  85. package/api/onboarding-voice-lines.d.ts.map +1 -0
  86. package/api/onboarding-voice-lines.js +8 -0
  87. package/api/perf-instrument.d.ts +43 -0
  88. package/api/perf-instrument.d.ts.map +1 -0
  89. package/api/perf-instrument.js +113 -0
  90. package/api/response.d.ts.map +1 -1
  91. package/api/response.js +14 -14
  92. package/api/runtime-mode-routes.d.ts +1 -1
  93. package/api/runtime-mode-routes.d.ts.map +1 -1
  94. package/api/runtime-mode-routes.js +2 -2
  95. package/api/secrets-inventory-routes.js +2 -2
  96. package/api/secrets-manager-routes.d.ts +1 -1
  97. package/api/secrets-manager-routes.d.ts.map +1 -1
  98. package/api/secrets-manager-routes.js +9 -10
  99. package/api/sensitive-request-routes.d.ts +2 -2
  100. package/api/sensitive-request-routes.js +5 -5
  101. package/api/server-config-filter.d.ts.map +1 -1
  102. package/api/server-config-filter.js +0 -1
  103. package/api/server-cors.d.ts.map +1 -1
  104. package/api/server-cors.js +13 -2
  105. package/api/server-first-run-helpers.d.ts +26 -0
  106. package/api/server-first-run-helpers.d.ts.map +1 -0
  107. package/api/server-first-run-helpers.js +268 -0
  108. package/api/server-security.js +1 -1
  109. package/api/server-startup.d.ts.map +1 -1
  110. package/api/server-startup.js +3 -4
  111. package/api/server-wallet-trade.js +1 -1
  112. package/api/server.d.ts +11 -11
  113. package/api/server.d.ts.map +1 -1
  114. package/api/server.js +227 -139
  115. package/api/setup-contract.d.ts +63 -0
  116. package/api/setup-contract.d.ts.map +1 -0
  117. package/api/setup-contract.js +39 -0
  118. package/api/training-benchmarks.d.ts +97 -0
  119. package/api/training-benchmarks.d.ts.map +1 -0
  120. package/api/training-benchmarks.js +329 -0
  121. package/api/workbench-compat-routes.d.ts +1 -1
  122. package/api/workbench-compat-routes.js +2 -2
  123. package/benchmark/cerebras-autowire.d.ts +28 -0
  124. package/benchmark/cerebras-autowire.d.ts.map +1 -0
  125. package/benchmark/cerebras-autowire.js +62 -0
  126. package/benchmark/lifeops-bench-handler.d.ts +36 -0
  127. package/benchmark/lifeops-bench-handler.d.ts.map +1 -1
  128. package/benchmark/lifeops-bench-handler.js +63 -1
  129. package/benchmark/lifeops-fake-backend.d.ts +39 -0
  130. package/benchmark/lifeops-fake-backend.d.ts.map +1 -1
  131. package/benchmark/lifeops-fake-backend.js +993 -21
  132. package/benchmark/mock-plugin.d.ts.map +1 -1
  133. package/benchmark/mock-plugin.js +0 -24
  134. package/benchmark/plugin.d.ts +2 -1
  135. package/benchmark/plugin.d.ts.map +1 -1
  136. package/benchmark/plugin.js +989 -68
  137. package/benchmark/replay-capture.d.ts +2 -2
  138. package/benchmark/replay-capture.d.ts.map +1 -1
  139. package/benchmark/replay-capture.js +3 -3
  140. package/benchmark/server-utils.d.ts +164 -11
  141. package/benchmark/server-utils.d.ts.map +1 -1
  142. package/benchmark/server-utils.js +625 -62
  143. package/benchmark/server.d.ts.map +1 -1
  144. package/benchmark/server.js +1962 -118
  145. package/boot-profile.d.ts +3 -0
  146. package/boot-profile.d.ts.map +1 -0
  147. package/boot-profile.js +30 -0
  148. package/browser.d.ts +23 -1
  149. package/browser.d.ts.map +1 -1
  150. package/browser.js +20 -1
  151. package/cli/argv.js +1 -1
  152. package/cli/banner.js +1 -1
  153. package/cli/command-format.js +2 -2
  154. package/cli/doctor/checks.d.ts.map +1 -1
  155. package/cli/doctor/checks.js +6 -6
  156. package/cli/plugins-cli.d.ts.map +1 -1
  157. package/cli/plugins-cli.js +82 -32
  158. package/cli/profile.d.ts.map +1 -1
  159. package/cli/profile.js +5 -4
  160. package/cli/program/build-program.js +4 -4
  161. package/cli/program/command-registry.d.ts.map +1 -1
  162. package/cli/program/command-registry.js +13 -11
  163. package/cli/program/help.js +5 -5
  164. package/cli/program/preaction.js +5 -5
  165. package/cli/program/register.auth.d.ts +27 -1
  166. package/cli/program/register.auth.d.ts.map +1 -1
  167. package/cli/program/register.auth.js +193 -12
  168. package/cli/program/register.capability-router.d.ts +29 -0
  169. package/cli/program/register.capability-router.d.ts.map +1 -0
  170. package/cli/program/register.capability-router.js +568 -0
  171. package/cli/program/register.config.js +1 -1
  172. package/cli/program/register.configure.d.ts.map +1 -1
  173. package/cli/program/register.configure.js +1 -1
  174. package/cli/program/register.dashboard.d.ts.map +1 -1
  175. package/cli/program/register.dashboard.js +17 -8
  176. package/cli/program/register.db.d.ts.map +1 -1
  177. package/cli/program/register.db.js +3 -4
  178. package/cli/program/register.doctor.js +7 -7
  179. package/cli/program/register.setup.d.ts.map +1 -1
  180. package/cli/program/register.setup.js +14 -10
  181. package/cli/program/register.start.d.ts.map +1 -1
  182. package/cli/program/register.start.js +5 -3
  183. package/cli/program/register.subclis.js +3 -3
  184. package/cli/program/register.update.d.ts +6 -0
  185. package/cli/program/register.update.d.ts.map +1 -1
  186. package/cli/program/register.update.js +58 -6
  187. package/cli/program.d.ts +1 -1
  188. package/cli/program.js +1 -1
  189. package/cli/run-main.js +4 -4
  190. package/config/app-config.d.ts +2 -0
  191. package/config/app-config.d.ts.map +1 -0
  192. package/config/app-config.js +1 -0
  193. package/connectors/capacitor-jsc.d.ts.map +1 -1
  194. package/connectors/capacitor-jsc.js +16 -10
  195. package/connectors/capacitor-quickjs.d.ts.map +1 -1
  196. package/connectors/capacitor-quickjs.js +18 -13
  197. package/connectors/capacitor-sqlite.d.ts.map +1 -1
  198. package/connectors/capacitor-sqlite.js +27 -12
  199. package/dispatch/approval-queue.d.ts +37 -0
  200. package/dispatch/approval-queue.d.ts.map +1 -0
  201. package/dispatch/approval-queue.js +25 -0
  202. package/dispatch/channel-registry.d.ts +30 -0
  203. package/dispatch/channel-registry.d.ts.map +1 -0
  204. package/dispatch/channel-registry.js +22 -0
  205. package/dispatch/connector-registry.d.ts +39 -0
  206. package/dispatch/connector-registry.d.ts.map +1 -0
  207. package/dispatch/connector-registry.js +24 -0
  208. package/dispatch/index.d.ts +14 -0
  209. package/dispatch/index.d.ts.map +1 -0
  210. package/dispatch/index.js +13 -0
  211. package/dispatch/send-policy.d.ts +36 -0
  212. package/dispatch/send-policy.d.ts.map +1 -0
  213. package/dispatch/send-policy.js +16 -0
  214. package/entry.js +28 -11
  215. package/first-run/first-run-config.d.ts +55 -0
  216. package/first-run/first-run-config.d.ts.map +1 -0
  217. package/first-run/first-run-config.js +178 -0
  218. package/first-run/runtime-target.d.ts +4 -0
  219. package/first-run/runtime-target.d.ts.map +1 -0
  220. package/first-run/runtime-target.js +13 -0
  221. package/index.d.ts +46 -34
  222. package/index.d.ts.map +1 -1
  223. package/index.js +53 -33
  224. package/package.json +166 -51
  225. package/packaging/PUBLISHING_GUIDE.md +20 -20
  226. package/packaging/debian/apt-repo-config/README.md +18 -0
  227. package/packaging/debian/apt-repo-config/conf/distributions +11 -0
  228. package/packaging/flatpak/README.md +26 -16
  229. package/packaging/flatpak/ai.elizaos.App.metainfo.xml +17 -12
  230. package/packaging/flatpak/ai.elizaos.App.store.yml +5 -5
  231. package/packaging/flatpak/ai.elizaos.App.yml +10 -24
  232. package/packaging/flatpak/elizaos-app-wrapper.store.sh +2 -2
  233. package/packaging/flatpak/generate-sources.sh +74 -0
  234. package/packaging/flatpak/node-sources.json +7930 -0
  235. package/packaging/inno/build-inno.ps1 +34 -9
  236. package/packaging/msix/AppxManifest.store.xml +1 -1
  237. package/packaging/msix/README.md +39 -19
  238. package/packaging/msix/build-msix.ps1 +44 -14
  239. package/packaging/snap/snapcraft.yaml +22 -21
  240. package/packaging/test-packaging.sh +2 -2
  241. package/permissions/types.d.ts +1 -1
  242. package/permissions/types.js +1 -1
  243. package/platform/elizaos-agent-browser-stub.d.ts +143 -0
  244. package/platform/elizaos-agent-browser-stub.d.ts.map +1 -0
  245. package/platform/elizaos-agent-browser-stub.js +157 -0
  246. package/platform/elizaos-plugin-elizacloud-browser-stub.d.ts +34 -0
  247. package/platform/elizaos-plugin-elizacloud-browser-stub.d.ts.map +1 -0
  248. package/platform/elizaos-plugin-elizacloud-browser-stub.js +51 -0
  249. package/platform/empty-node-module.d.ts +148 -0
  250. package/platform/empty-node-module.d.ts.map +1 -1
  251. package/platform/empty-node-module.js +140 -3
  252. package/platform/ios-runtime-backends.d.ts +83 -0
  253. package/platform/ios-runtime-backends.d.ts.map +1 -0
  254. package/platform/ios-runtime-backends.js +133 -0
  255. package/platform/ios-runtime-bridge.d.ts +15 -0
  256. package/platform/ios-runtime-bridge.d.ts.map +1 -0
  257. package/platform/ios-runtime-bridge.js +526 -0
  258. package/platform/native-library-policy.d.ts +23 -0
  259. package/platform/native-library-policy.d.ts.map +1 -0
  260. package/platform/native-library-policy.js +112 -0
  261. package/platform/native-plugin-entrypoints.d.ts +19 -0
  262. package/platform/native-plugin-entrypoints.d.ts.map +1 -0
  263. package/platform/native-plugin-entrypoints.js +29 -0
  264. package/platforms/android/README.md +68 -10
  265. package/platforms/android/app/build.gradle +291 -3
  266. package/platforms/android/app/capacitor.build.gradle +18 -1
  267. package/platforms/android/app/proguard-rules.pro +17 -2
  268. package/platforms/android/app/src/androidTest/java/ai/elizaos/app/ElizaOsInstrumentedTest.java +1 -1
  269. package/platforms/android/app/src/main/AndroidManifest.xml +335 -18
  270. package/platforms/android/app/src/main/assets/runners/eliza-tasks.js +177 -0
  271. package/platforms/android/app/src/main/elizavoice-jni/CMakeLists.txt +100 -0
  272. package/platforms/android/app/src/main/elizavoice-jni/elizavoice-jni.cpp +1629 -0
  273. package/platforms/android/app/src/main/java/ai/elizaos/app/AgentPlugin.java +111 -171
  274. package/platforms/android/app/src/main/java/ai/elizaos/app/AndroidVirtualizationBridge.java +284 -0
  275. package/platforms/android/app/src/main/java/ai/elizaos/app/BatteryOptimizationPlugin.java +95 -0
  276. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAccessibilityService.java +55 -0
  277. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAgentService.java +1283 -141
  278. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAndroidSystemBridge.java +83 -0
  279. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAssistActivity.java +50 -1
  280. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaBionicInferenceServer.java +740 -0
  281. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaBootReceiver.java +90 -8
  282. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaBrowserActivity.java +2 -2
  283. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaCalendarActivity.java +1 -1
  284. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaCameraActivity.java +1 -1
  285. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaClockActivity.java +2 -2
  286. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaContactsActivity.java +1 -1
  287. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaDialActivity.java +1 -1
  288. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaInCallService.java +1 -1
  289. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaMmsReceiver.java +1 -1
  290. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaNativeBridge.java +22 -0
  291. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaNotificationListenerService.java +45 -0
  292. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaQuickActionsWidgetProvider.java +68 -0
  293. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaShareActivity.java +132 -0
  294. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaSmsComposeActivity.java +1 -1
  295. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaSmsGatewayService.java +268 -0
  296. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaSmsReceiver.java +12 -1
  297. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaTasksWorker.java +194 -0
  298. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaVoiceCaptureService.java +198 -0
  299. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaVoiceNative.java +255 -0
  300. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaVoicePlugin.java +505 -0
  301. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaVoiceTileService.java +39 -0
  302. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaWorkScheduler.java +60 -0
  303. package/platforms/android/app/src/main/java/ai/elizaos/app/GatewayConnectionService.java +53 -19
  304. package/platforms/android/app/src/main/java/ai/elizaos/app/MainActivity.java +160 -33
  305. package/platforms/android/app/src/main/java/ai/elizaos/app/ResourceProbePlugin.java +169 -0
  306. package/platforms/android/app/src/main/java/ai/elizaos/app/VoiceCapturePlugin.java +119 -0
  307. package/platforms/android/app/src/main/res/drawable/eliza_widget_background.xml +10 -0
  308. package/platforms/android/app/src/main/res/drawable/eliza_widget_button_background.xml +13 -0
  309. package/platforms/android/app/src/main/res/drawable/splash.png +0 -0
  310. package/platforms/android/app/src/main/res/drawable-land-hdpi/splash.png +0 -0
  311. package/platforms/android/app/src/main/res/drawable-land-mdpi/splash.png +0 -0
  312. package/platforms/android/app/src/main/res/drawable-land-xhdpi/splash.png +0 -0
  313. package/platforms/android/app/src/main/res/drawable-land-xxhdpi/splash.png +0 -0
  314. package/platforms/android/app/src/main/res/drawable-land-xxxhdpi/splash.png +0 -0
  315. package/platforms/android/app/src/main/res/drawable-port-hdpi/splash.png +0 -0
  316. package/platforms/android/app/src/main/res/drawable-port-mdpi/splash.png +0 -0
  317. package/platforms/android/app/src/main/res/drawable-port-xhdpi/splash.png +0 -0
  318. package/platforms/android/app/src/main/res/drawable-port-xxhdpi/splash.png +0 -0
  319. package/platforms/android/app/src/main/res/drawable-port-xxxhdpi/splash.png +0 -0
  320. package/platforms/android/app/src/main/res/layout/eliza_quick_actions_widget.xml +86 -0
  321. package/platforms/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +2 -1
  322. package/platforms/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +2 -1
  323. package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  324. package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png +0 -0
  325. package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png +0 -0
  326. package/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  327. package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  328. package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png +0 -0
  329. package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png +0 -0
  330. package/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  331. package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  332. package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
  333. package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png +0 -0
  334. package/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  335. package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  336. package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
  337. package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png +0 -0
  338. package/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  339. package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  340. package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
  341. package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png +0 -0
  342. package/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  343. package/platforms/android/app/src/main/res/values/android_app_actions.xml +48 -0
  344. package/platforms/android/app/src/main/res/values/colors.xml +12 -0
  345. package/platforms/android/app/src/main/res/values/ic_launcher_background.xml +2 -2
  346. package/platforms/android/app/src/main/res/values/strings.xml +2 -2
  347. package/platforms/android/app/src/main/res/values/styles.xml +28 -1
  348. package/platforms/android/app/src/main/res/xml/eliza_accessibility_service.xml +9 -0
  349. package/platforms/android/app/src/main/res/xml/eliza_quick_actions_widget.xml +13 -0
  350. package/platforms/android/app/src/main/res/xml/shortcuts.xml +121 -0
  351. package/platforms/android/build.gradle +2 -2
  352. package/platforms/android/capacitor-cordova-android-plugins/build.gradle +9 -3
  353. package/platforms/android/capacitor-cordova-android-plugins/cordova.variables.gradle +6 -2
  354. package/platforms/android/capacitor-cordova-android-plugins/src/main/AndroidManifest.xml +7 -2
  355. package/platforms/android/capacitor-cordova-android-plugins/src/main/java/.gitkeep +0 -1
  356. package/platforms/android/capacitor.settings.gradle +66 -16
  357. package/platforms/android/gradle.properties +1 -0
  358. package/platforms/android/update-manifest/generate-manifest.mjs +97 -0
  359. package/platforms/android/update-manifest/schema.json +26 -0
  360. package/platforms/apple-store-entitlements.reviewed.json +155 -0
  361. package/platforms/electrobun/.generated/brand-config.json +3 -2
  362. package/platforms/electrobun/LICENSE +21 -0
  363. package/platforms/electrobun/README.md +15 -1
  364. package/platforms/electrobun/assets/appIcon.icns +0 -0
  365. package/platforms/electrobun/assets/appIcon.ico +0 -0
  366. package/platforms/electrobun/assets/appIcon.iconset/icon_128x128.png +0 -0
  367. package/platforms/electrobun/assets/appIcon.iconset/icon_128x128@2x.png +0 -0
  368. package/platforms/electrobun/assets/appIcon.iconset/icon_16x16.png +0 -0
  369. package/platforms/electrobun/assets/appIcon.iconset/icon_16x16@2x.png +0 -0
  370. package/platforms/electrobun/assets/appIcon.iconset/icon_256x256.png +0 -0
  371. package/platforms/electrobun/assets/appIcon.iconset/icon_256x256@2x.png +0 -0
  372. package/platforms/electrobun/assets/appIcon.iconset/icon_32x32.png +0 -0
  373. package/platforms/electrobun/assets/appIcon.iconset/icon_32x32@2x.png +0 -0
  374. package/platforms/electrobun/assets/appIcon.iconset/icon_512x512.png +0 -0
  375. package/platforms/electrobun/assets/brand-config.json +6 -6
  376. package/platforms/electrobun/biome.json +9 -9
  377. package/platforms/electrobun/docs/capability-collapse-matrix.json +318 -0
  378. package/platforms/electrobun/docs/capability-collapse-matrix.md +129 -0
  379. package/platforms/electrobun/docs/capability-routing.md +86 -0
  380. package/platforms/electrobun/docs/database-boot-policy.md +90 -0
  381. package/platforms/electrobun/docs/riscv64-port.md +175 -0
  382. package/platforms/electrobun/docs/startup-first-run-cleanup.md +18 -0
  383. package/platforms/electrobun/docs/trace-first-annotations.md +52 -0
  384. package/platforms/electrobun/docs/ui-boundary-audit.json +580 -0
  385. package/platforms/electrobun/docs/ui-boundary-audit.md +257 -0
  386. package/platforms/electrobun/electrobun.config.ts +591 -364
  387. package/platforms/electrobun/entitlements/JUSTIFICATIONS.md +141 -0
  388. package/platforms/electrobun/entitlements/README.md +34 -6
  389. package/platforms/electrobun/entitlements/mas-bun.entitlements +15 -0
  390. package/platforms/electrobun/entitlements/mas.entitlements +6 -4
  391. package/platforms/electrobun/native/macos/window-effects.mm +1526 -0
  392. package/platforms/electrobun/package.json +21 -13
  393. package/platforms/electrobun/remotes/fs/README.md +70 -0
  394. package/platforms/electrobun/remotes/fs/electrobun.config.ts +38 -0
  395. package/platforms/electrobun/remotes/fs/package.json +12 -0
  396. package/platforms/electrobun/remotes/fs/plugin.json +25 -0
  397. package/platforms/electrobun/remotes/fs/src/bun/errors.ts +57 -0
  398. package/platforms/electrobun/remotes/fs/src/bun/file-limits.ts +50 -0
  399. package/platforms/electrobun/remotes/fs/src/bun/fs-service.ts +389 -0
  400. package/platforms/electrobun/remotes/fs/src/bun/path-guard.ts +270 -0
  401. package/platforms/electrobun/remotes/fs/src/bun/protocol.ts +149 -0
  402. package/platforms/electrobun/remotes/fs/src/bun/worker.ts +174 -0
  403. package/platforms/electrobun/remotes/fs/src/dev/phase5-smoke.ts +171 -0
  404. package/platforms/electrobun/remotes/fs/src/web/index.html +8 -0
  405. package/platforms/electrobun/remotes/git/README.md +75 -0
  406. package/platforms/electrobun/remotes/git/electrobun.config.ts +44 -0
  407. package/platforms/electrobun/remotes/git/package.json +12 -0
  408. package/platforms/electrobun/remotes/git/plugin.json +31 -0
  409. package/platforms/electrobun/remotes/git/src/bun/errors.ts +69 -0
  410. package/platforms/electrobun/remotes/git/src/bun/git-command.ts +156 -0
  411. package/platforms/electrobun/remotes/git/src/bun/git-service.ts +446 -0
  412. package/platforms/electrobun/remotes/git/src/bun/operation-history.ts +124 -0
  413. package/platforms/electrobun/remotes/git/src/bun/protocol.ts +252 -0
  414. package/platforms/electrobun/remotes/git/src/bun/worker.ts +316 -0
  415. package/platforms/electrobun/remotes/git/src/dev/phase7-smoke.ts +141 -0
  416. package/platforms/electrobun/remotes/git/src/web/index.html +8 -0
  417. package/platforms/electrobun/remotes/local-model/README.md +138 -0
  418. package/platforms/electrobun/remotes/local-model/electrobun.config.ts +46 -0
  419. package/platforms/electrobun/remotes/local-model/package.json +12 -0
  420. package/platforms/electrobun/remotes/local-model/plugin.json +33 -0
  421. package/platforms/electrobun/remotes/local-model/src/bun/download-state.ts +115 -0
  422. package/platforms/electrobun/remotes/local-model/src/bun/eliza1-catalog.ts +405 -0
  423. package/platforms/electrobun/remotes/local-model/src/bun/errors.ts +74 -0
  424. package/platforms/electrobun/remotes/local-model/src/bun/hf-eliza1-client.ts +169 -0
  425. package/platforms/electrobun/remotes/local-model/src/bun/local-inference-api-client.ts +245 -0
  426. package/platforms/electrobun/remotes/local-model/src/bun/model-service.ts +490 -0
  427. package/platforms/electrobun/remotes/local-model/src/bun/protocol.ts +301 -0
  428. package/platforms/electrobun/remotes/local-model/src/bun/worker.ts +248 -0
  429. package/platforms/electrobun/remotes/local-model/src/dev/phase8-smoke.ts +116 -0
  430. package/platforms/electrobun/remotes/local-model/src/web/index.html +13 -0
  431. package/platforms/electrobun/remotes/pty/README.md +65 -0
  432. package/platforms/electrobun/remotes/pty/electrobun.config.ts +47 -0
  433. package/platforms/electrobun/remotes/pty/package.json +12 -0
  434. package/platforms/electrobun/remotes/pty/plugin.json +34 -0
  435. package/platforms/electrobun/remotes/pty/src/bun/errors.ts +57 -0
  436. package/platforms/electrobun/remotes/pty/src/bun/output-buffer.ts +127 -0
  437. package/platforms/electrobun/remotes/pty/src/bun/protocol.ts +192 -0
  438. package/platforms/electrobun/remotes/pty/src/bun/pty-service.ts +562 -0
  439. package/platforms/electrobun/remotes/pty/src/bun/worker.ts +218 -0
  440. package/platforms/electrobun/remotes/pty/src/dev/phase6-smoke.ts +127 -0
  441. package/platforms/electrobun/remotes/pty/src/web/index.html +8 -0
  442. package/platforms/electrobun/remotes/runtime/README.md +370 -0
  443. package/platforms/electrobun/remotes/runtime/electrobun.config.ts +48 -0
  444. package/platforms/electrobun/remotes/runtime/package.json +14 -0
  445. package/platforms/electrobun/remotes/runtime/plugin.json +30 -0
  446. package/platforms/electrobun/remotes/runtime/src/bun/api-client.ts +620 -0
  447. package/platforms/electrobun/remotes/runtime/src/bun/errors.ts +45 -0
  448. package/platforms/electrobun/remotes/runtime/src/bun/log-buffer.ts +33 -0
  449. package/platforms/electrobun/remotes/runtime/src/bun/protocol.ts +366 -0
  450. package/platforms/electrobun/remotes/runtime/src/bun/route-discovery.ts +419 -0
  451. package/platforms/electrobun/remotes/runtime/src/bun/runtime-manager.ts +423 -0
  452. package/platforms/electrobun/remotes/runtime/src/bun/sse-parser.ts +99 -0
  453. package/platforms/electrobun/remotes/runtime/src/bun/stream-manager.ts +887 -0
  454. package/platforms/electrobun/remotes/runtime/src/bun/worker.ts +1231 -0
  455. package/platforms/electrobun/remotes/runtime/src/dev/phase1-smoke.ts +34 -0
  456. package/platforms/electrobun/remotes/runtime/src/dev/phase2-smoke.ts +91 -0
  457. package/platforms/electrobun/remotes/runtime/src/dev/phase3-smoke.ts +137 -0
  458. package/platforms/electrobun/remotes/runtime/src/web/index.css +187 -0
  459. package/platforms/electrobun/remotes/runtime/src/web/index.html +76 -0
  460. package/platforms/electrobun/remotes/runtime/src/web/index.ts +192 -0
  461. package/platforms/electrobun/remotes/surface/README.md +201 -0
  462. package/platforms/electrobun/remotes/surface/electrobun.config.ts +38 -0
  463. package/platforms/electrobun/remotes/surface/package.json +12 -0
  464. package/platforms/electrobun/remotes/surface/plugin.json +28 -0
  465. package/platforms/electrobun/remotes/surface/src/bun/worker.ts +132 -0
  466. package/platforms/electrobun/remotes/surface/src/dev/phase4-smoke.ts +566 -0
  467. package/platforms/electrobun/remotes/surface/src/protocol/event-types.ts +84 -0
  468. package/platforms/electrobun/remotes/surface/src/protocol/runtime-client.ts +673 -0
  469. package/platforms/electrobun/remotes/surface/src/web/app.ts +595 -0
  470. package/platforms/electrobun/remotes/surface/src/web/index.css +460 -0
  471. package/platforms/electrobun/remotes/surface/src/web/index.html +466 -0
  472. package/platforms/electrobun/remotes/surface/src/web/index.ts +5 -0
  473. package/platforms/electrobun/remotes/surface/src/web/render.ts +455 -0
  474. package/platforms/electrobun/remotes/surface/src/web/state.ts +427 -0
  475. package/platforms/electrobun/scripts/build-macos-effects.sh +4 -0
  476. package/platforms/electrobun/scripts/ensure-build-folder.ts +28 -0
  477. package/platforms/electrobun/scripts/local-adhoc-sign-macos.ts +159 -159
  478. package/platforms/electrobun/scripts/postwrap-diagnostics.ts +424 -339
  479. package/platforms/electrobun/scripts/postwrap-sign-runtime-macos.ts +302 -271
  480. package/platforms/electrobun/scripts/smoke-test-windows.ps1 +17 -16
  481. package/platforms/electrobun/scripts/smoke-test.sh +5 -7
  482. package/platforms/electrobun/scripts/sync-web-assets.mjs +13 -13
  483. package/platforms/electrobun/scripts/verify-rpc-handlers.ts +109 -110
  484. package/platforms/electrobun/scripts/verify-windows-installer-proof.ps1 +3 -8
  485. package/platforms/electrobun/src/__stubs__/bun-ffi.ts +31 -31
  486. package/platforms/electrobun/src/__stubs__/electrobun-bun.ts +1 -1
  487. package/platforms/electrobun/src/agent-ready-state.ts +8 -8
  488. package/platforms/electrobun/src/agent-reset-from-main.test.ts +162 -0
  489. package/platforms/electrobun/src/agent-reset-from-main.ts +62 -62
  490. package/platforms/electrobun/src/agent-status-rpc.test.ts +95 -0
  491. package/platforms/electrobun/src/agent-status-rpc.ts +156 -0
  492. package/platforms/electrobun/src/api-base.test.ts +247 -0
  493. package/platforms/electrobun/src/api-base.ts +202 -93
  494. package/platforms/electrobun/src/application-menu-action-registry.ts +9 -9
  495. package/platforms/electrobun/src/application-menu.ts +341 -348
  496. package/platforms/electrobun/src/background-notice.ts +36 -36
  497. package/platforms/electrobun/src/boot-progress.test.ts +188 -0
  498. package/platforms/electrobun/src/boot-progress.ts +111 -0
  499. package/platforms/electrobun/src/brand-config.test.ts +39 -0
  500. package/platforms/electrobun/src/brand-config.ts +141 -129
  501. package/platforms/electrobun/src/bridge/browser-tabs-renderer-registry.ts +28 -28
  502. package/platforms/electrobun/src/bridge/electrobun-boot-config.ts +42 -0
  503. package/platforms/electrobun/src/bridge/electrobun-crypto-ready.ts +120 -0
  504. package/platforms/electrobun/src/bridge/electrobun-direct-rpc.ts +342 -357
  505. package/platforms/electrobun/src/bridge/electrobun-stub.ts +13 -13
  506. package/platforms/electrobun/src/browser-workspace-bridge-server.ts +285 -243
  507. package/platforms/electrobun/src/cloud-auth-window.ts +136 -136
  508. package/platforms/electrobun/src/cloud-disconnect-from-main.ts +90 -90
  509. package/platforms/electrobun/src/config-and-auth-rpc.test.ts +256 -0
  510. package/platforms/electrobun/src/config-and-auth-rpc.ts +302 -0
  511. package/platforms/electrobun/src/conversations-and-character-rpc.test.ts +185 -0
  512. package/platforms/electrobun/src/conversations-and-character-rpc.ts +131 -0
  513. package/platforms/electrobun/src/dashboard-rpc.test.ts +200 -0
  514. package/platforms/electrobun/src/dashboard-rpc.ts +344 -0
  515. package/platforms/electrobun/src/database/database-lock.ts +141 -0
  516. package/platforms/electrobun/src/database/database-mode.ts +149 -0
  517. package/platforms/electrobun/src/database/database-recovery.ts +72 -0
  518. package/platforms/electrobun/src/database/database-snapshot.ts +190 -0
  519. package/platforms/electrobun/src/database/database.test.ts +196 -0
  520. package/platforms/electrobun/src/database/index.ts +5 -0
  521. package/platforms/electrobun/src/database/pglite-paths.ts +100 -0
  522. package/platforms/electrobun/src/desktop-deep-link-events.test.ts +30 -0
  523. package/platforms/electrobun/src/desktop-deep-link-events.ts +17 -0
  524. package/platforms/electrobun/src/desktop-http-request.test.ts +102 -73
  525. package/platforms/electrobun/src/desktop-http-request.ts +97 -85
  526. package/platforms/electrobun/src/desktop-pill-config.test.ts +27 -0
  527. package/platforms/electrobun/src/desktop-pill-config.ts +40 -0
  528. package/platforms/electrobun/src/desktop-test-bridge-server.ts +232 -204
  529. package/platforms/electrobun/src/desktop-tray-config.test.ts +87 -0
  530. package/platforms/electrobun/src/desktop-tray-config.ts +84 -0
  531. package/platforms/electrobun/src/devtools-layout.ts +41 -41
  532. package/platforms/electrobun/src/diagnostic-format.test.ts +71 -0
  533. package/platforms/electrobun/src/diagnostic-format.ts +75 -36
  534. package/platforms/electrobun/src/dynamic-view-rpc-schema.test.ts +37 -0
  535. package/platforms/electrobun/src/dynamic-views/README.md +44 -0
  536. package/platforms/electrobun/src/dynamic-views/demo/agent-run-trace.html +135 -0
  537. package/platforms/electrobun/src/dynamic-views/errors.ts +29 -0
  538. package/platforms/electrobun/src/dynamic-views/host.test.ts +353 -0
  539. package/platforms/electrobun/src/dynamic-views/host.ts +332 -0
  540. package/platforms/electrobun/src/dynamic-views/index.ts +57 -0
  541. package/platforms/electrobun/src/dynamic-views/kiosk-canvas.ts +89 -0
  542. package/platforms/electrobun/src/dynamic-views/registry.test.ts +139 -0
  543. package/platforms/electrobun/src/dynamic-views/registry.ts +196 -0
  544. package/platforms/electrobun/src/dynamic-views/session-manager.test.ts +355 -0
  545. package/platforms/electrobun/src/dynamic-views/session-manager.ts +348 -0
  546. package/platforms/electrobun/src/dynamic-views/types.ts +105 -0
  547. package/platforms/electrobun/src/electrobun-boot-config.test.ts +50 -0
  548. package/platforms/electrobun/src/electrobun-config.test.ts +62 -0
  549. package/platforms/electrobun/src/electrobun-crypto-ready.test.ts +65 -0
  550. package/platforms/electrobun/src/electrobun-window-options.ts +25 -0
  551. package/platforms/electrobun/src/extension-rpc.test.ts +88 -0
  552. package/platforms/electrobun/src/extension-rpc.ts +102 -0
  553. package/platforms/electrobun/src/fatal-shutdown.test.ts +12 -16
  554. package/platforms/electrobun/src/fatal-shutdown.ts +1 -1
  555. package/platforms/electrobun/src/first-party-remotes.test.ts +169 -0
  556. package/platforms/electrobun/src/first-party-remotes.ts +297 -0
  557. package/platforms/electrobun/src/first-run-rpc.test.ts +192 -0
  558. package/platforms/electrobun/src/first-run-rpc.ts +146 -0
  559. package/platforms/electrobun/src/floating-chat-window.ts +181 -181
  560. package/platforms/electrobun/src/inbox-rpc.test.ts +123 -0
  561. package/platforms/electrobun/src/inbox-rpc.ts +158 -0
  562. package/platforms/electrobun/src/index.ts +2608 -2098
  563. package/platforms/electrobun/src/kiosk-mode.ts +50 -0
  564. package/platforms/electrobun/src/launch/index.ts +4 -0
  565. package/platforms/electrobun/src/launch/launch-dynamic-view.ts +37 -0
  566. package/platforms/electrobun/src/launch/launch-orchestrator.test.ts +224 -0
  567. package/platforms/electrobun/src/launch/launch-orchestrator.ts +456 -0
  568. package/platforms/electrobun/src/launch/launch-store.test.ts +97 -0
  569. package/platforms/electrobun/src/launch/launch-store.ts +134 -0
  570. package/platforms/electrobun/src/launch/types.ts +103 -0
  571. package/platforms/electrobun/src/launch/views/launch-diagnostics.html +205 -0
  572. package/platforms/electrobun/src/lifecycle/agent-ready-publish.test.ts +50 -0
  573. package/platforms/electrobun/src/lifecycle/agent-ready-publish.ts +27 -0
  574. package/platforms/electrobun/src/lifecycle/api-base-owner.test.ts +83 -0
  575. package/platforms/electrobun/src/lifecycle/api-base-owner.ts +63 -31
  576. package/platforms/electrobun/src/lifecycle/desktop-session-prime.ts +44 -44
  577. package/platforms/electrobun/src/logger.ts +14 -14
  578. package/platforms/electrobun/src/main-window-runtime.ts +83 -83
  579. package/platforms/electrobun/src/main-window-session.test.ts +109 -0
  580. package/platforms/electrobun/src/main-window-session.ts +87 -51
  581. package/platforms/electrobun/src/menu-reset-from-main.ts +158 -158
  582. package/platforms/electrobun/src/native/agent-env.test.ts +52 -0
  583. package/platforms/electrobun/src/native/agent-runtime-layout.test.ts +42 -0
  584. package/platforms/electrobun/src/native/agent-state-dir.test.ts +91 -0
  585. package/platforms/electrobun/src/native/agent.ts +2133 -1682
  586. package/platforms/electrobun/src/native/auth-bridge.test.ts +67 -0
  587. package/platforms/electrobun/src/native/auth-bridge.ts +464 -360
  588. package/platforms/electrobun/src/native/browser-workspace.ts +723 -471
  589. package/platforms/electrobun/src/native/camera.ts +50 -50
  590. package/platforms/electrobun/src/native/canvas.ts +444 -445
  591. package/platforms/electrobun/src/native/credentials.ts +678 -616
  592. package/platforms/electrobun/src/native/desktop-window.test.ts +416 -0
  593. package/platforms/electrobun/src/native/desktop.ts +2200 -2156
  594. package/platforms/electrobun/src/native/editor-bridge.ts +201 -201
  595. package/platforms/electrobun/src/native/file-watcher.ts +154 -154
  596. package/platforms/electrobun/src/native/gateway.ts +179 -180
  597. package/platforms/electrobun/src/native/gpu-window.ts +256 -256
  598. package/platforms/electrobun/src/native/index.ts +82 -74
  599. package/platforms/electrobun/src/native/location.test.ts +44 -0
  600. package/platforms/electrobun/src/native/location.ts +90 -80
  601. package/platforms/electrobun/src/native/loopback-port.ts +60 -60
  602. package/platforms/electrobun/src/native/mac-window-effects.ts +166 -104
  603. package/platforms/electrobun/src/native/music-player.ts +38 -38
  604. package/platforms/electrobun/src/native/permissions-shared.ts +249 -150
  605. package/platforms/electrobun/src/native/permissions.ts +301 -208
  606. package/platforms/electrobun/src/native/power-state.ts +129 -129
  607. package/platforms/electrobun/src/native/remote-plugin-host.test.ts +1394 -0
  608. package/platforms/electrobun/src/native/remote-plugin-host.ts +1541 -0
  609. package/platforms/electrobun/src/native/screencapture.ts +667 -573
  610. package/platforms/electrobun/src/native/steward.ts +207 -204
  611. package/platforms/electrobun/src/native/swabble.ts +68 -324
  612. package/platforms/electrobun/src/native/talkmode.ts +253 -422
  613. package/platforms/electrobun/src/native/webgpu-browser-support.test.ts +18 -0
  614. package/platforms/electrobun/src/native/webgpu-browser-support.ts +165 -147
  615. package/platforms/electrobun/src/native-onboarding.ts +270 -0
  616. package/platforms/electrobun/src/onboarding-overlay-window.ts +141 -0
  617. package/platforms/electrobun/src/persisted-deployment.ts +91 -0
  618. package/platforms/electrobun/src/pill-window.test.ts +91 -0
  619. package/platforms/electrobun/src/pill-window.ts +99 -0
  620. package/platforms/electrobun/src/preload-validation.ts +44 -44
  621. package/platforms/electrobun/src/preload.js +1 -1
  622. package/platforms/electrobun/src/print-electrobun-dev-settings-banner.ts +120 -120
  623. package/platforms/electrobun/src/renderer-api-proxy.test.ts +73 -0
  624. package/platforms/electrobun/src/renderer-api-proxy.ts +86 -0
  625. package/platforms/electrobun/src/renderer-static.test.ts +53 -0
  626. package/platforms/electrobun/src/renderer-static.ts +144 -57
  627. package/platforms/electrobun/src/rpc-handler-slices.ts +121 -0
  628. package/platforms/electrobun/src/rpc-handlers.test.ts +267 -0
  629. package/platforms/electrobun/src/rpc-handlers.ts +1306 -913
  630. package/platforms/electrobun/src/rpc-parse-utils.ts +57 -0
  631. package/platforms/electrobun/src/rpc-port-resolver.test.ts +45 -0
  632. package/platforms/electrobun/src/rpc-port-resolver.ts +31 -0
  633. package/platforms/electrobun/src/rpc-schema.ts +2556 -1619
  634. package/platforms/electrobun/src/runtime-layout.ts +105 -105
  635. package/platforms/electrobun/src/runtime-permissions.ts +95 -95
  636. package/platforms/electrobun/src/runtime-rpc.test.ts +126 -0
  637. package/platforms/electrobun/src/runtime-rpc.ts +237 -0
  638. package/platforms/electrobun/src/screenshot-dev-server.ts +87 -87
  639. package/platforms/electrobun/src/settings-mutations-rpc.test.ts +193 -0
  640. package/platforms/electrobun/src/settings-mutations-rpc.ts +220 -0
  641. package/platforms/electrobun/src/startup-trace.ts +274 -270
  642. package/platforms/electrobun/src/subscription-rpc.test.ts +89 -0
  643. package/platforms/electrobun/src/subscription-rpc.ts +192 -0
  644. package/platforms/electrobun/src/surface-windows.test.ts +355 -0
  645. package/platforms/electrobun/src/surface-windows.ts +410 -410
  646. package/platforms/electrobun/src/trace/README.md +73 -0
  647. package/platforms/electrobun/src/trace/errors.ts +21 -0
  648. package/platforms/electrobun/src/trace/index.ts +40 -0
  649. package/platforms/electrobun/src/trace/trace-dynamic-view.ts +40 -0
  650. package/platforms/electrobun/src/trace/trace-host-requests.ts +473 -0
  651. package/platforms/electrobun/src/trace/trace-service.test.ts +186 -0
  652. package/platforms/electrobun/src/trace/trace-service.ts +324 -0
  653. package/platforms/electrobun/src/trace/trace-store.test.ts +141 -0
  654. package/platforms/electrobun/src/trace/trace-store.ts +551 -0
  655. package/platforms/electrobun/src/trace/types.ts +250 -0
  656. package/platforms/electrobun/src/trace/views/agent-run-trace.html +311 -0
  657. package/platforms/electrobun/src/types/web-speech.d.ts +28 -28
  658. package/platforms/electrobun/src/types.ts +5 -5
  659. package/platforms/electrobun/src/update-availability.test.ts +72 -0
  660. package/platforms/electrobun/src/update-availability.ts +90 -0
  661. package/platforms/electrobun/src/update-rpc.test.ts +83 -0
  662. package/platforms/electrobun/src/update-rpc.ts +123 -0
  663. package/platforms/electrobun/src/voice/README.md +184 -0
  664. package/platforms/electrobun/src/voice/errors.ts +42 -0
  665. package/platforms/electrobun/src/voice/index.ts +78 -0
  666. package/platforms/electrobun/src/voice/types.ts +316 -0
  667. package/platforms/electrobun/src/voice/voice-host-requests.ts +259 -0
  668. package/platforms/electrobun/src/voice/voice-latency-budget.test.ts +66 -0
  669. package/platforms/electrobun/src/voice/voice-latency-budget.ts +243 -0
  670. package/platforms/electrobun/src/voice/voice-live-validation.test.ts +357 -0
  671. package/platforms/electrobun/src/voice/voice-live-validation.ts +838 -0
  672. package/platforms/electrobun/src/voice/voice-pipeline.ts +250 -0
  673. package/platforms/electrobun/src/voice/voice-playback-adapter.ts +31 -0
  674. package/platforms/electrobun/src/voice/voice-runtime-adapter.test.ts +213 -0
  675. package/platforms/electrobun/src/voice/voice-runtime-adapter.ts +687 -0
  676. package/platforms/electrobun/src/voice/voice-service.test.ts +587 -0
  677. package/platforms/electrobun/src/voice/voice-service.ts +1067 -0
  678. package/platforms/electrobun/src/voice/voice-stream-coordinator.test.ts +115 -0
  679. package/platforms/electrobun/src/voice/voice-stream-coordinator.ts +270 -0
  680. package/platforms/electrobun/src/voice/voice-trace.ts +97 -0
  681. package/platforms/electrobun/src/voice/voice-tts-chunker.test.ts +91 -0
  682. package/platforms/electrobun/src/voice/voice-tts-chunker.ts +194 -0
  683. package/platforms/electrobun/src/windows-cef-profile.ts +88 -88
  684. package/platforms/electrobun/tsconfig.json +88 -12
  685. package/platforms/electrobun/update-channels.json +22 -0
  686. package/platforms/electrobun/vitest.electrobun.config.ts +72 -42
  687. package/platforms/ios/App/App/App.entitlements +4 -0
  688. package/platforms/ios/App/App/AppDelegate.swift +80 -18
  689. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ios-marketing-1024.png +0 -0
  690. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-20x20@1x.png +0 -0
  691. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-20x20@2x.png +0 -0
  692. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-29x29@1x.png +0 -0
  693. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-29x29@2x.png +0 -0
  694. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-40x40@1x.png +0 -0
  695. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-40x40@2x.png +0 -0
  696. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-76x76@1x.png +0 -0
  697. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-76x76@2x.png +0 -0
  698. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-ipad-83_5x83_5@2x.png +0 -0
  699. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-20x20@2x.png +0 -0
  700. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-20x20@3x.png +0 -0
  701. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-29x29@2x.png +0 -0
  702. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-29x29@3x.png +0 -0
  703. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-40x40@2x.png +0 -0
  704. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-40x40@3x.png +0 -0
  705. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-60x60@2x.png +0 -0
  706. package/platforms/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-iphone-60x60@3x.png +0 -0
  707. package/platforms/ios/App/App/Base.lproj/LaunchScreen.storyboard +4 -9
  708. package/platforms/ios/App/App/ComputerUseBridge.swift +589 -0
  709. package/platforms/ios/App/App/DeviceActivityMonitorExtension/DeviceActivityMonitorExtension.entitlements +12 -0
  710. package/platforms/ios/App/App/DeviceActivityMonitorExtension/DeviceActivityMonitorExtension.swift +34 -0
  711. package/platforms/ios/App/App/DeviceActivityMonitorExtension/Info.plist +29 -0
  712. package/platforms/ios/App/App/DeviceActivityReportExtension/DeviceActivityReportExtension.entitlements +12 -0
  713. package/platforms/ios/App/App/DeviceActivityReportExtension/DeviceActivityReportExtension.swift +53 -0
  714. package/platforms/ios/App/App/DeviceActivityReportExtension/Info.plist +27 -0
  715. package/platforms/ios/App/App/ElizaAppIntents.swift +183 -0
  716. package/platforms/ios/App/App/ElizaIntentPlugin.swift +342 -5
  717. package/platforms/ios/App/App/Info.plist +17 -1
  718. package/platforms/ios/App/App/runners/eliza-tasks.js +177 -0
  719. package/platforms/ios/App/App.xcodeproj/project.pbxproj +262 -6
  720. package/platforms/ios/App/BroadcastExtension/SampleHandler.swift +100 -0
  721. package/platforms/ios/App/Podfile +5 -0
  722. package/platforms/ios/App/Podfile.lock +83 -59
  723. package/register-runtime-hooks.js +11 -5
  724. package/registry/index.d.ts +1 -5
  725. package/registry/index.d.ts.map +1 -1
  726. package/registry/index.js +10 -68
  727. package/runtime/android-avf-microdroid-bridge.d.ts +29 -0
  728. package/runtime/android-avf-microdroid-bridge.d.ts.map +1 -0
  729. package/runtime/android-avf-microdroid-bridge.js +149 -0
  730. package/runtime/api-dev-settings-banner.d.ts.map +1 -1
  731. package/runtime/api-dev-settings-banner.js +5 -13
  732. package/runtime/app-core-runtime-hooks.d.ts +21 -0
  733. package/runtime/app-core-runtime-hooks.d.ts.map +1 -0
  734. package/runtime/app-core-runtime-hooks.js +10 -0
  735. package/runtime/autonomy-policy.d.ts +2 -0
  736. package/runtime/autonomy-policy.d.ts.map +1 -0
  737. package/runtime/autonomy-policy.js +4 -0
  738. package/runtime/bundled-fused-lib.d.ts +36 -0
  739. package/runtime/bundled-fused-lib.d.ts.map +1 -0
  740. package/runtime/bundled-fused-lib.js +77 -0
  741. package/runtime/channel-plugin-map.d.ts +1 -5
  742. package/runtime/channel-plugin-map.d.ts.map +1 -1
  743. package/runtime/channel-plugin-map.js +11 -31
  744. package/runtime/desktop/AppWindowRenderer.d.ts +17 -0
  745. package/runtime/desktop/AppWindowRenderer.d.ts.map +1 -0
  746. package/runtime/desktop/AppWindowRenderer.js +360 -0
  747. package/runtime/desktop/DesktopSurfaceNavigationRuntime.d.ts +2 -0
  748. package/runtime/desktop/DesktopSurfaceNavigationRuntime.d.ts.map +1 -0
  749. package/runtime/desktop/DesktopSurfaceNavigationRuntime.js +41 -0
  750. package/runtime/desktop/DesktopTrayRuntime.d.ts +2 -0
  751. package/runtime/desktop/DesktopTrayRuntime.d.ts.map +1 -0
  752. package/runtime/desktop/DesktopTrayRuntime.js +174 -0
  753. package/runtime/desktop/DetachedShellRoot.d.ts +10 -0
  754. package/runtime/desktop/DetachedShellRoot.d.ts.map +1 -0
  755. package/runtime/desktop/DetachedShellRoot.js +111 -0
  756. package/runtime/desktop/index.d.ts +6 -0
  757. package/runtime/desktop/index.d.ts.map +1 -0
  758. package/runtime/desktop/index.js +5 -0
  759. package/runtime/desktop/tray-menu.d.ts +20 -0
  760. package/runtime/desktop/tray-menu.d.ts.map +1 -0
  761. package/runtime/desktop/tray-menu.js +143 -0
  762. package/runtime/dev-server.d.ts +1 -1
  763. package/runtime/dev-server.d.ts.map +1 -1
  764. package/runtime/dev-server.js +104 -19
  765. package/runtime/eliza.d.ts +75 -1
  766. package/runtime/eliza.d.ts.map +1 -1
  767. package/runtime/eliza.js +606 -122
  768. package/runtime/ensure-text-to-speech-handler.d.ts.map +1 -1
  769. package/runtime/ensure-text-to-speech-handler.js +10 -3
  770. package/runtime/mobile-safe-runtime.d.ts +181 -2
  771. package/runtime/mobile-safe-runtime.d.ts.map +1 -1
  772. package/runtime/mobile-safe-runtime.js +1019 -12
  773. package/runtime/mode/remote-forwarder.d.ts.map +1 -1
  774. package/runtime/mode/remote-forwarder.js +2 -2
  775. package/runtime/mode/route-mode-guard.d.ts +2 -3
  776. package/runtime/mode/route-mode-guard.d.ts.map +1 -1
  777. package/runtime/mode/route-mode-guard.js +4 -5
  778. package/runtime/mode/route-mode-matrix.d.ts +1 -1
  779. package/runtime/mode/route-mode-matrix.d.ts.map +1 -1
  780. package/runtime/mode/route-mode-matrix.js +14 -1
  781. package/runtime/mode/runtime-mode.d.ts +1 -1
  782. package/runtime/mode/runtime-mode.js +1 -1
  783. package/runtime/runtime-bootstrap-policy.d.ts.map +1 -1
  784. package/runtime/runtime-bootstrap-policy.js +14 -2
  785. package/runtime/telegram-standalone-handler.d.ts.map +1 -1
  786. package/runtime/telegram-standalone-handler.js +10 -9
  787. package/runtime/tts-cache-wiring.d.ts +29 -0
  788. package/runtime/tts-cache-wiring.d.ts.map +1 -0
  789. package/runtime/tts-cache-wiring.js +114 -0
  790. package/runtime/voice-warmup.d.ts +66 -0
  791. package/runtime/voice-warmup.d.ts.map +1 -0
  792. package/runtime/voice-warmup.js +101 -0
  793. package/scripts/android-sms-gateway-template.test.mjs +1014 -0
  794. package/scripts/aosp/README.md +29 -16
  795. package/scripts/aosp/compile-libllama-zig-pin.test.mjs +147 -0
  796. package/scripts/aosp/compile-libllama.mjs +1750 -267
  797. package/scripts/aosp/compile-libllama.test.mjs +133 -0
  798. package/scripts/aosp/compile-shim.mjs +68 -19
  799. package/scripts/aosp/deploy-pixel.mjs +405 -0
  800. package/scripts/aosp/lib/load-variant-config.mjs +3 -3
  801. package/scripts/aosp/llama-cpp-patches/README.md +8 -8
  802. package/scripts/aosp/llama-cpp-patches/apply-patches.mjs +23 -6
  803. package/scripts/aosp/llama-cpp-patches/polarquant/README.md +37 -0
  804. package/scripts/aosp/llama-cpp-patches/qjl/README.md +37 -0
  805. package/scripts/aosp/seccomp-shim/sigsys-handler-arm64.c +169 -0
  806. package/scripts/aosp/seccomp-shim/sigsys-handler-riscv64.c +217 -0
  807. package/scripts/aosp/smoke-cuttlefish.mjs +34 -4
  808. package/scripts/aosp/stage-default-models.mjs +59 -35
  809. package/scripts/aosp/stage-default-models.test.mjs +23 -0
  810. package/scripts/aosp/variant-config-schema.ts +2 -2
  811. package/scripts/assert-required-bundled-packages.test.ts +555 -0
  812. package/scripts/audit-apple-store-sandbox.mjs +146 -0
  813. package/scripts/audit-live-test-surface.mjs +5 -2
  814. package/scripts/build-capacitor-app.mjs +21 -0
  815. package/scripts/build-flatpak.mjs +5 -5
  816. package/scripts/build-helpers/arm64-simd.mjs +72 -0
  817. package/scripts/build-helpers/omnivoice-merged.mjs +87 -0
  818. package/scripts/build-helpers/verify-fused-symbols.mjs +600 -0
  819. package/scripts/build-helpers/verify-fused-symbols.test.mjs +0 -0
  820. package/scripts/build-image.sh +1 -1
  821. package/scripts/build-llama-cpp-mtp.mjs +488 -0
  822. package/scripts/build-native-plugins.mjs +230 -18
  823. package/scripts/build-patched-electrobun-cli.mjs +68 -10
  824. package/scripts/build-win.mjs +1 -1
  825. package/scripts/bun-riscv64/Dockerfile +418 -0
  826. package/scripts/bun-riscv64/README.md +316 -0
  827. package/scripts/bun-riscv64/build.sh +469 -0
  828. package/scripts/bun-riscv64/bun-patches/0001-config-add-riscv64-arch.patch +74 -0
  829. package/scripts/bun-riscv64/bun-patches/0002-flags-add-riscv64-march-mabi.patch +16 -0
  830. package/scripts/bun-riscv64/bun-patches/0003-zig-add-riscv64-target-triple-and-cpu.patch +26 -0
  831. package/scripts/bun-riscv64/bun-patches/0004-webkit-force-local-mode-on-riscv64.patch +33 -0
  832. package/scripts/bun-riscv64/bun-patches/0005-tinycc-disable-on-riscv64.patch +16 -0
  833. package/scripts/bun-riscv64/bun-patches/0006-build-add-riscv64-cli-validation.patch +15 -0
  834. package/scripts/bun-riscv64/bun-patches/0007-deps-per-dep-riscv64-checks.patch +24 -0
  835. package/scripts/bun-riscv64/bun-patches/0008-source-stabilize-riscv64-musl-build.patch +226 -0
  836. package/scripts/bun-riscv64/bun-patches/0009-disable-wasm-streaming-hooks-for-c-loop.patch +162 -0
  837. package/scripts/bun-riscv64/bun-patches/0010-disable-inspector-profiler-for-riscv64-c-loop.patch +80 -0
  838. package/scripts/bun-riscv64/bun-patches/0011-process-arch-add-riscv64.patch +23 -0
  839. package/scripts/bun-riscv64/bun-patches/0012-cpu-features-add-riscv64-fallback.patch +13 -0
  840. package/scripts/bun-riscv64/bun-patches/0013-disable-console-inspector-hooks-for-riscv64-c-loop.patch +43 -0
  841. package/scripts/bun-riscv64/bun-patches/0014-disable-custom-inspector-dispatchers-on-riscv64.patch +127 -0
  842. package/scripts/bun-riscv64/bun-patches/0015-disable-jsc-profiler-builtins-on-riscv64.patch +75 -0
  843. package/scripts/bun-riscv64/bun-patches/0016-node-vm-disable-jit-cached-data-on-riscv64-c-loop.patch +96 -0
  844. package/scripts/bun-riscv64/bun-patches/0017-disable-performance-domjit-signature-on-riscv64-c-loop.patch +34 -0
  845. package/scripts/bun-riscv64/bun-patches/0018-fix-serialized-script-identifier-big-endian-path.patch +19 -0
  846. package/scripts/bun-riscv64/bun-patches/0019-add-wtf-timer-fire-bridge-for-c-loop.patch +24 -0
  847. package/scripts/bun-riscv64/bun-patches/0020-run-riscv64-smoke-test-under-qemu.patch +13 -0
  848. package/scripts/bun-riscv64/bun-patches/0021-fix-riscv64-linux-open-flags.patch +25 -0
  849. package/scripts/bun-riscv64/bun-patches/0022-zlib-riscv64-generic-kernels.patch +25 -0
  850. package/scripts/bun-riscv64/bun-patches/README.md +127 -0
  851. package/scripts/bun-riscv64/bun-version.json +202 -0
  852. package/scripts/bun-riscv64/run-build.sh +162 -0
  853. package/scripts/bun-riscv64/rust-core/0001-riscv64-rust-core-port.patch +868 -0
  854. package/scripts/bun-riscv64/rust-core/0002-second-wave-riscv64-source-gaps.patch +130 -0
  855. package/scripts/bun-riscv64/rust-core/0003-third-wave-riscv64-crash-handler-gaps.patch +78 -0
  856. package/scripts/bun-riscv64/rust-core/0004-rust-target-cpu-riscv64.patch +39 -0
  857. package/scripts/bun-riscv64/rust-core/0005-fifth-wave-riscv64-source-gaps.patch +96 -0
  858. package/scripts/bun-riscv64/rust-core/0006-cpp-wasm-and-inspector-guards-riscv64.patch +91 -0
  859. package/scripts/bun-riscv64/rust-core/0007-bun-alloc-max-align-t-riscv64.patch +36 -0
  860. package/scripts/bun-riscv64/rust-core/0008-workspace-lints-warn-not-deny-riscv64.patch +75 -0
  861. package/scripts/bun-riscv64/rust-core/0009-zigglobalobject-wasm-streaming-guards-riscv64.patch +109 -0
  862. package/scripts/bun-riscv64/rust-core/0010-tcc-externs-stub-on-riscv64.patch +62 -0
  863. package/scripts/bun-riscv64/rust-core/0011-clippy-ptr-cast-lints-warn-riscv64.patch +61 -0
  864. package/scripts/bun-riscv64/rust-core/README.md +80 -0
  865. package/scripts/bun-riscv64/rust-core/webkit-patches/0003-disable-dfg-ftl-on-riscv64.patch +60 -0
  866. package/scripts/bun-riscv64/rust-core/webkit-patches/0004-riscv64-do-not-force-wasm-in-c-loop.patch +31 -0
  867. package/scripts/bun-riscv64/rust-core/webkit-patches/0005-domjit-effect-allow-no-dfg-c-loop.patch +40 -0
  868. package/scripts/bun-riscv64/rust-core/webkit-patches/0006-disable-usewasm-when-webassembly-compiled-out.patch +33 -0
  869. package/scripts/bun-riscv64/rust-core/webkit-patches/0007-restore-dropped-includes-and-llint-fwd-decl.patch +31 -0
  870. package/scripts/bun-riscv64/validate.sh +264 -0
  871. package/scripts/bun-riscv64/webkit-patches/0001-cherry-pick-llint-riscv64.recipe +155 -0
  872. package/scripts/bun-riscv64/webkit-patches/0002-cherry-pick-baseline-jit-riscv64.recipe +40 -0
  873. package/scripts/bun-riscv64/webkit-patches/0003-disable-dfg-ftl-on-riscv64.patch +60 -0
  874. package/scripts/bun-riscv64/webkit-patches/0004-riscv64-do-not-force-wasm-in-c-loop.patch +31 -0
  875. package/scripts/bun-riscv64/webkit-patches/0005-domjit-effect-allow-no-dfg-c-loop.patch +40 -0
  876. package/scripts/bun-riscv64/webkit-patches/0006-disable-usewasm-when-webassembly-compiled-out.patch +33 -0
  877. package/scripts/bun-riscv64/webkit-patches/0007-restore-dropped-includes-and-llint-fwd-decl.patch +72 -0
  878. package/scripts/bun-riscv64/webkit-patches/README.md +146 -0
  879. package/scripts/check-homepage-public-readiness.mjs +353 -0
  880. package/scripts/check-homepage-release-data.mjs +110 -0
  881. package/scripts/check-i18n.mjs +1 -1
  882. package/scripts/check-real-local-chat.ts +147 -0
  883. package/scripts/check-real-local-provisioning.ts +104 -0
  884. package/scripts/check-real-local-reset.ts +249 -0
  885. package/scripts/check-sms-gateway-completion-audit.mjs +428 -0
  886. package/scripts/check-sms-gateway-readiness.mjs +266 -0
  887. package/scripts/clean-repo.mjs +5 -5
  888. package/scripts/codesign-mas.mjs +222 -16
  889. package/scripts/collect-docker-runtime-deps.mjs +229 -0
  890. package/scripts/continue-sms-gateway-work.mjs +121 -0
  891. package/scripts/copy-runtime-node-modules.ts +1050 -195
  892. package/scripts/deploy-cloud-api-production-gateway.mjs +52 -0
  893. package/scripts/desktop-build.mjs +965 -98
  894. package/scripts/dev-platform.mjs +346 -102
  895. package/scripts/dev-startup-smoke.mjs +248 -0
  896. package/scripts/dev-ui.mjs +418 -176
  897. package/scripts/disable-local-eliza-workspace.mjs +35 -0
  898. package/scripts/docker-ci-smoke.sh +465 -96
  899. package/scripts/docker-entrypoint.sh +62 -1
  900. package/scripts/docker-entrypoint.test.ts +283 -0
  901. package/scripts/ensure-avatars.mjs +2 -2
  902. package/scripts/ensure-electrobun-core.mjs +1 -1
  903. package/scripts/ensure-generated-core-proto-js.mjs +1 -1
  904. package/scripts/ensure-type-package-aliases.mjs +62 -5
  905. package/scripts/ensure-vision-deps.mjs +20 -1
  906. package/scripts/entry.ts +1 -1
  907. package/scripts/ffi-stub/Makefile +64 -0
  908. package/scripts/ffi-stub/README.md +391 -0
  909. package/scripts/ffi-stub/asr-ffi-smoke.ts +139 -0
  910. package/scripts/ffi-stub/ffi-stub.c +539 -0
  911. package/scripts/ffi-stub/ffi.h +538 -0
  912. package/scripts/ffi-stub/libelizainference_stub.so +0 -0
  913. package/scripts/ffi-stub/tts-stream-ffi-smoke.ts +349 -0
  914. package/scripts/generate-first-run-voicelines.mjs +194 -0
  915. package/scripts/generate-plugin-index.js +4 -3
  916. package/scripts/generate-static-asset-manifest.mjs +1 -1
  917. package/scripts/i18n-dynamic-keys.json +5 -5
  918. package/scripts/init-submodules.mjs +2 -2
  919. package/scripts/install-android-sms-gateway.md +177 -0
  920. package/scripts/install-android-sms-gateway.mjs +1088 -0
  921. package/scripts/ios-xcframework/README.md +74 -72
  922. package/scripts/ios-xcframework/build-xcframework.mjs +204 -43
  923. package/scripts/ios-xcframework/run-physical-device-smoke.mjs +1943 -0
  924. package/scripts/ios-xcframework/runtime-symbol-shim.c +450 -0
  925. package/scripts/kernel-patches/cpu-polar-kernels.mjs +441 -0
  926. package/scripts/kernel-patches/cpu-simd-kernels.mjs +253 -0
  927. package/scripts/kernel-patches/cpu-thread-parallelism.mjs +368 -0
  928. package/scripts/kernel-patches/cuda-kernels.mjs +117 -0
  929. package/scripts/kernel-patches/metal-kernels.mjs +1698 -109
  930. package/scripts/kernel-patches/server-omnivoice-route.mjs +718 -0
  931. package/scripts/kernel-patches/server-structured-output.mjs +279 -0
  932. package/scripts/kernel-patches/vulkan-dispatch-log.mjs +166 -0
  933. package/scripts/kernel-patches/vulkan-dispatch-log.test.mjs +50 -0
  934. package/scripts/kernel-patches/vulkan-dispatch-patches/01-vulkan-shaders-gen.patch +30 -16
  935. package/scripts/kernel-patches/vulkan-dispatch-patches/02-ggml-vulkan-pipelines.patch +75 -30
  936. package/scripts/kernel-patches/vulkan-kernels.mjs +800 -49
  937. package/scripts/lib/agent-source-watcher.mjs +173 -0
  938. package/scripts/lib/agent-source-watcher.test.mjs +184 -0
  939. package/scripts/lib/api-supervisor.mjs +78 -9
  940. package/scripts/lib/api-supervisor.test.mjs +121 -0
  941. package/scripts/lib/app-dir.mjs +2 -16
  942. package/scripts/lib/apple-entitlement-audit.mjs +655 -0
  943. package/scripts/lib/apple-entitlement-audit.test.mjs +144 -0
  944. package/scripts/lib/artifact-staleness.d.mts +33 -0
  945. package/scripts/lib/artifact-staleness.mjs +122 -0
  946. package/scripts/lib/artifact-staleness.test.mts +98 -0
  947. package/scripts/lib/bun-version-guard.mjs +13 -13
  948. package/scripts/lib/capacitor-plugin-build-needed.mjs +4 -3
  949. package/scripts/lib/capacitor-plugin-names.mjs +30 -14
  950. package/scripts/lib/desktop-preflight.mjs +9 -5
  951. package/scripts/lib/desktop-startup-embedding-warmup-policy.mjs +51 -0
  952. package/scripts/lib/desktop-startup-embedding-warmup-policy.test.mjs +55 -0
  953. package/scripts/lib/duet-bridge.d.mts +63 -0
  954. package/scripts/lib/duet-bridge.mjs +193 -0
  955. package/scripts/lib/ios-plist-url-scheme.mjs +80 -0
  956. package/scripts/lib/mobile-build-decisions.mjs +97 -0
  957. package/scripts/lib/node-path-env.mjs +4 -2
  958. package/scripts/lib/orchestrator-desktop-dev-banner.mjs +12 -3
  959. package/scripts/lib/patch-bun-exports.mjs +90 -27
  960. package/scripts/lib/patch-bun-exports.test.mjs +79 -0
  961. package/scripts/lib/renderer-build-action.mjs +35 -0
  962. package/scripts/lib/renderer-build-action.test.mjs +70 -0
  963. package/scripts/lib/renderer-build-manifest.d.mts +65 -0
  964. package/scripts/lib/renderer-build-manifest.mjs +257 -0
  965. package/scripts/lib/renderer-build-manifest.test.mts +277 -0
  966. package/scripts/lib/stage-android-agent.mjs +757 -99
  967. package/scripts/lib/sync-eliza-env-aliases.mjs +3 -25
  968. package/scripts/lib/ui-smoke-stub-decision.mjs +33 -0
  969. package/scripts/lib/ui-smoke-stub-decision.test.mjs +46 -0
  970. package/scripts/lib/verify-ondevice-artifact.d.mts +16 -0
  971. package/scripts/lib/verify-ondevice-artifact.mjs +61 -0
  972. package/scripts/lib/verify-ondevice-artifact.test.mts +98 -0
  973. package/scripts/lib/vite-renderer-dist-stale.mjs +5 -0
  974. package/scripts/lib/voice-latency-report.mjs +154 -0
  975. package/scripts/lib/websocket-pending-queue.ts +92 -0
  976. package/scripts/lifeops-prompt-benchmark.ts +21 -12
  977. package/scripts/link-docker-local-app-packages.mjs +109 -36
  978. package/scripts/local-stt-bench.ts +192 -0
  979. package/scripts/maintain-cloud-api-production-gateway.mjs +54 -0
  980. package/scripts/mas-smoke.mjs +459 -0
  981. package/scripts/mas-smoke.test.mjs +220 -0
  982. package/scripts/mobile-auth-simulator-smoke.mjs +0 -1
  983. package/scripts/normalize-eliza-capture.ts +97 -0
  984. package/scripts/omnivoice-fuse/prepare.mjs +2543 -23
  985. package/scripts/pack-upstreams.mjs +65 -5
  986. package/scripts/package-electrobun-linux.mjs +303 -0
  987. package/scripts/patch-deps.mjs +5 -3
  988. package/scripts/patches/llama-asr-word-timestamps.patch +218 -0
  989. package/scripts/playwright-ui-live-stack.ts +588 -157
  990. package/scripts/playwright-ui-smoke-api-stub.mjs +3495 -111
  991. package/scripts/pre-review-local.mjs +2 -2
  992. package/scripts/prepare-ios-cocoapods.sh +41 -3
  993. package/scripts/release-check.ts +180 -84
  994. package/scripts/relink-workspace-packages-to-dist.mjs +21 -4
  995. package/scripts/rt.mjs +16 -1
  996. package/scripts/run-biome-check.mjs +1 -1
  997. package/scripts/run-coding-agent-e2e.mjs +3 -3
  998. package/scripts/run-eliza-app-core-script.mjs +34 -0
  999. package/scripts/run-local-plugin-live-smoke.mjs +66 -2
  1000. package/scripts/run-mobile-build-android-app-actions.test.mjs +426 -0
  1001. package/scripts/run-mobile-build-brand-separation.test.mts +33 -0
  1002. package/scripts/run-mobile-build-ios-engine-gate.test.mjs +85 -0
  1003. package/scripts/run-mobile-build-mtp-staleness.test.mts +198 -0
  1004. package/scripts/run-mobile-build.mjs +5082 -610
  1005. package/scripts/run-node-runtime.mjs +184 -7
  1006. package/scripts/run-node-runtime.test.mjs +167 -0
  1007. package/scripts/run-node-tsx.mjs +80 -33
  1008. package/scripts/run-node.mjs +41 -1
  1009. package/scripts/run-production-build.mjs +34 -27
  1010. package/scripts/run-release-check.mjs +19 -0
  1011. package/scripts/run-release-contract-suite.mjs +107 -14
  1012. package/scripts/run-ui-smoke-playwright-suite.mjs +0 -2
  1013. package/scripts/runtime-package-manifest.ts +21 -3
  1014. package/scripts/serve-real-local-agent.ts +72 -0
  1015. package/scripts/setup-upstreams.mjs +42 -1
  1016. package/scripts/sms-gateway-status.mjs +194 -0
  1017. package/scripts/stage-android-agent.test.mjs +97 -0
  1018. package/scripts/stage-desktop-fused-lib.mjs +453 -0
  1019. package/scripts/stage-elizavoice-lib.mjs +363 -0
  1020. package/scripts/startup-integration-script-drift.test.ts +82 -4
  1021. package/scripts/streaming-pipeline-bench.ts +543 -0
  1022. package/scripts/sync-homepage-porkbun-dns.mjs +262 -0
  1023. package/scripts/test-sms-gateway-software.mjs +100 -0
  1024. package/scripts/type-audit.mjs +1 -1
  1025. package/scripts/validate-bluebubbles-outbound.mjs +293 -0
  1026. package/scripts/validate-cdn-assets.mjs +15 -7
  1027. package/scripts/validate-regression-matrix.mjs +109 -8
  1028. package/scripts/verify-android-sms-gateway-e2e.mjs +362 -0
  1029. package/scripts/verify-bluebubbles-gateway-e2e.mjs +191 -0
  1030. package/scripts/verify-bluebubbles-inbound-readiness.mjs +88 -0
  1031. package/scripts/verify-cloud-api-production-deploy.mjs +87 -0
  1032. package/scripts/verify-cloud-sms-onboarding-flow.mjs +336 -0
  1033. package/scripts/verify-ondevice-artifact.mjs +111 -0
  1034. package/scripts/voice/freeze-voice.mjs +521 -0
  1035. package/scripts/voice-attribution-smoke.ts +644 -0
  1036. package/scripts/voice-create-profile.mjs +379 -0
  1037. package/scripts/voice-duet.mjs +1355 -0
  1038. package/scripts/voice-e2e-hardware.ts +877 -0
  1039. package/scripts/voice-interactive.mjs +1721 -0
  1040. package/scripts/voice-latency-report.mjs +96 -0
  1041. package/scripts/voice-latency-report.test.ts +176 -0
  1042. package/scripts/voice-preset/build-default-voice-preset.mjs +249 -0
  1043. package/scripts/voice-preset/build-onboarding-voice.mjs +281 -0
  1044. package/scripts/watch-sms-gateway-readiness.mjs +303 -0
  1045. package/scripts/write-homepage-release-data.mjs +458 -26
  1046. package/security/agent-vault-id.d.ts +2 -2
  1047. package/security/agent-vault-id.js +1 -1
  1048. package/security/hydrate-wallet-keys-from-platform-store.d.ts.map +1 -1
  1049. package/security/hydrate-wallet-keys-from-platform-store.js +23 -14
  1050. package/security/platform-secure-store-node.d.ts +3 -3
  1051. package/security/platform-secure-store-node.js +3 -3
  1052. package/security/wallet-os-store-actions.d.ts +0 -9
  1053. package/security/wallet-os-store-actions.d.ts.map +1 -1
  1054. package/security/wallet-os-store-actions.js +3 -10
  1055. package/services/account-pool.d.ts +23 -14
  1056. package/services/account-pool.d.ts.map +1 -1
  1057. package/services/account-pool.js +86 -24
  1058. package/services/account-usage.d.ts.map +1 -1
  1059. package/services/account-usage.js +2 -5
  1060. package/services/ambient-audio/consent.d.ts +9 -0
  1061. package/services/ambient-audio/consent.d.ts.map +1 -0
  1062. package/services/ambient-audio/consent.js +28 -0
  1063. package/services/ambient-audio/index.d.ts +7 -0
  1064. package/services/ambient-audio/index.d.ts.map +1 -0
  1065. package/services/ambient-audio/index.js +4 -0
  1066. package/services/ambient-audio/replay-buffer.d.ts +14 -0
  1067. package/services/ambient-audio/replay-buffer.d.ts.map +1 -0
  1068. package/services/ambient-audio/replay-buffer.js +66 -0
  1069. package/services/ambient-audio/response-gate.d.ts +3 -0
  1070. package/services/ambient-audio/response-gate.d.ts.map +1 -0
  1071. package/services/ambient-audio/response-gate.js +33 -0
  1072. package/services/ambient-audio/service.d.ts +22 -0
  1073. package/services/ambient-audio/service.d.ts.map +1 -0
  1074. package/services/ambient-audio/service.js +47 -0
  1075. package/services/ambient-audio/types.d.ts +42 -0
  1076. package/services/ambient-audio/types.d.ts.map +1 -0
  1077. package/services/app-updates/update-policy.d.ts +64 -0
  1078. package/services/app-updates/update-policy.d.ts.map +1 -0
  1079. package/services/app-updates/update-policy.js +228 -0
  1080. package/services/auth-store.d.ts +37 -1
  1081. package/services/auth-store.d.ts.map +1 -1
  1082. package/services/auth-store.js +59 -26
  1083. package/services/cloud-jwks-store.d.ts +3 -3
  1084. package/services/cloud-jwks-store.d.ts.map +1 -1
  1085. package/services/cloud-jwks-store.js +5 -8
  1086. package/services/coding-account-bridge.d.ts +71 -0
  1087. package/services/coding-account-bridge.d.ts.map +1 -0
  1088. package/services/coding-account-bridge.js +267 -0
  1089. package/services/connector-target-catalog.d.ts +11 -4
  1090. package/services/connector-target-catalog.d.ts.map +1 -1
  1091. package/services/connector-target-catalog.js +7 -4
  1092. package/services/credential-tunnel-service.d.ts +66 -0
  1093. package/services/credential-tunnel-service.d.ts.map +1 -0
  1094. package/services/credential-tunnel-service.js +227 -0
  1095. package/services/github-credentials.d.ts +1 -1
  1096. package/services/github-credentials.js +1 -1
  1097. package/services/inference-abort.d.ts +47 -0
  1098. package/services/inference-abort.d.ts.map +1 -0
  1099. package/services/inference-abort.js +76 -0
  1100. package/services/persistence.d.ts +2 -3
  1101. package/services/persistence.d.ts.map +1 -1
  1102. package/services/persistence.js +2 -3
  1103. package/services/phrase-chunked-tts.d.ts +136 -0
  1104. package/services/phrase-chunked-tts.d.ts.map +1 -0
  1105. package/services/phrase-chunked-tts.js +208 -0
  1106. package/services/sandbox-registry.d.ts +78 -0
  1107. package/services/sandbox-registry.d.ts.map +1 -0
  1108. package/services/sandbox-registry.js +323 -0
  1109. package/services/secrets-manager-installer.d.ts +8 -1
  1110. package/services/secrets-manager-installer.d.ts.map +1 -1
  1111. package/services/secrets-manager-installer.js +27 -2
  1112. package/services/sensitive-requests/cloud-link-adapter.d.ts +15 -0
  1113. package/services/sensitive-requests/cloud-link-adapter.d.ts.map +1 -0
  1114. package/services/sensitive-requests/cloud-link-adapter.js +73 -0
  1115. package/services/sensitive-requests/index.d.ts +27 -0
  1116. package/services/sensitive-requests/index.d.ts.map +1 -0
  1117. package/services/sensitive-requests/index.js +51 -0
  1118. package/services/sensitive-requests/instruct-dm-only-adapter.d.ts +14 -0
  1119. package/services/sensitive-requests/instruct-dm-only-adapter.d.ts.map +1 -0
  1120. package/services/sensitive-requests/instruct-dm-only-adapter.js +22 -0
  1121. package/services/sensitive-requests/owner-app-inline-adapter.d.ts +3 -0
  1122. package/services/sensitive-requests/owner-app-inline-adapter.d.ts.map +1 -0
  1123. package/services/sensitive-requests/owner-app-inline-adapter.js +146 -0
  1124. package/services/sensitive-requests/owner-app-oauth-adapter.d.ts +3 -0
  1125. package/services/sensitive-requests/owner-app-oauth-adapter.d.ts.map +1 -0
  1126. package/services/sensitive-requests/owner-app-oauth-adapter.js +156 -0
  1127. package/services/sensitive-requests/public-link-adapter.d.ts +14 -0
  1128. package/services/sensitive-requests/public-link-adapter.d.ts.map +1 -0
  1129. package/services/sensitive-requests/public-link-adapter.js +86 -0
  1130. package/services/sensitive-requests/tunnel-link-adapter.d.ts +17 -0
  1131. package/services/sensitive-requests/tunnel-link-adapter.d.ts.map +1 -0
  1132. package/services/sensitive-requests/tunnel-link-adapter.js +38 -0
  1133. package/services/steward-credentials.d.ts +1 -1
  1134. package/services/steward-credentials.d.ts.map +1 -1
  1135. package/services/steward-credentials.js +10 -6
  1136. package/services/steward-sidecar/health-check.d.ts.map +1 -1
  1137. package/services/steward-sidecar/health-check.js +4 -3
  1138. package/services/steward-sidecar/process-management.d.ts +1 -1
  1139. package/services/steward-sidecar/process-management.d.ts.map +1 -1
  1140. package/services/steward-sidecar/process-management.js +9 -3
  1141. package/services/steward-sidecar/types.d.ts +1 -1
  1142. package/services/steward-sidecar/types.d.ts.map +1 -1
  1143. package/services/steward-sidecar/wallet-setup.d.ts +1 -1
  1144. package/services/steward-sidecar/wallet-setup.d.ts.map +1 -1
  1145. package/services/steward-sidecar/wallet-setup.js +8 -7
  1146. package/services/steward-sidecar.d.ts +5 -5
  1147. package/services/steward-sidecar.d.ts.map +1 -1
  1148. package/services/steward-sidecar.js +27 -19
  1149. package/services/task-host-capabilities.d.ts +60 -0
  1150. package/services/task-host-capabilities.d.ts.map +1 -0
  1151. package/services/task-host-capabilities.js +122 -0
  1152. package/services/tool-call-cache/index.d.ts +2 -2
  1153. package/services/tool-call-cache/index.d.ts.map +1 -1
  1154. package/services/tool-call-cache/index.js +1 -1
  1155. package/services/trigger-event-bridge.js +1 -1
  1156. package/services/tunnel-to-mobile/index.d.ts +2 -0
  1157. package/services/tunnel-to-mobile/index.d.ts.map +1 -0
  1158. package/services/tunnel-to-mobile/index.js +1 -0
  1159. package/services/tunnel-to-mobile/tunnel-to-mobile-client.d.ts +105 -0
  1160. package/services/tunnel-to-mobile/tunnel-to-mobile-client.d.ts.map +1 -0
  1161. package/services/tunnel-to-mobile/tunnel-to-mobile-client.js +190 -0
  1162. package/services/vault-bootstrap.d.ts.map +1 -1
  1163. package/services/vault-bootstrap.js +52 -21
  1164. package/services/vault-mirror.d.ts +1 -1
  1165. package/services/vault-mirror.d.ts.map +1 -1
  1166. package/services/vault-mirror.js +29 -6
  1167. package/services/voice-profiles/diarization-pipeline.d.ts +6 -0
  1168. package/services/voice-profiles/diarization-pipeline.d.ts.map +1 -0
  1169. package/services/voice-profiles/diarization-pipeline.js +20 -0
  1170. package/services/voice-profiles/index.d.ts +12 -0
  1171. package/services/voice-profiles/index.d.ts.map +1 -0
  1172. package/services/voice-profiles/index.js +5 -0
  1173. package/services/voice-profiles/nickname-evaluator.d.ts +14 -0
  1174. package/services/voice-profiles/nickname-evaluator.d.ts.map +1 -0
  1175. package/services/voice-profiles/nickname-evaluator.js +46 -0
  1176. package/services/voice-profiles/owner-confidence.d.ts +10 -0
  1177. package/services/voice-profiles/owner-confidence.d.ts.map +1 -0
  1178. package/services/voice-profiles/owner-confidence.js +38 -0
  1179. package/services/voice-profiles/private-challenge.d.ts +20 -0
  1180. package/services/voice-profiles/private-challenge.d.ts.map +1 -0
  1181. package/services/voice-profiles/private-challenge.js +44 -0
  1182. package/services/voice-profiles/store.d.ts +21 -0
  1183. package/services/voice-profiles/store.d.ts.map +1 -0
  1184. package/services/voice-profiles/store.js +50 -0
  1185. package/services/voice-profiles/types.d.ts +38 -0
  1186. package/services/voice-profiles/types.d.ts.map +1 -0
  1187. package/services/voice-profiles/types.js +1 -0
  1188. package/styles/electrobun-mac-window-drag.css +4 -4
  1189. package/test/helpers/__tests__/live-agent-test.smoke.test.ts +43 -70
  1190. package/test/helpers/browser-mocks.ts +2 -2
  1191. package/test/helpers/conditional-tests.ts +2 -2
  1192. package/test/helpers/live-agent-test.ts +537 -551
  1193. package/test/helpers/live-provider.test.ts +95 -5
  1194. package/test/helpers/live-provider.ts +234 -56
  1195. package/test/helpers/live-runtime-server.ts +4 -4
  1196. package/test/helpers/pglite-runtime.ts +1 -1
  1197. package/test/helpers/real-runtime.ts +72 -20
  1198. package/test/helpers/trajectory-harness.ts +11 -7
  1199. package/test/scripts/start-eliza-live.ts +9 -0
  1200. package/test/scripts/test-parallel.mjs +1 -1
  1201. package/test/scripts/test-root-unit.mjs +6 -7
  1202. package/test/scripts/websocket-pending-queue.test.ts +119 -0
  1203. package/test-support/test-helpers.d.ts +0 -33
  1204. package/test-support/test-helpers.d.ts.map +1 -1
  1205. package/test-support/test-helpers.js +81 -189
  1206. package/ui-compat.d.ts +14 -2
  1207. package/ui-compat.d.ts.map +1 -1
  1208. package/ui-compat.js +23 -3
  1209. package/api/auth-pairing-compat-routes.d.ts +0 -17
  1210. package/api/auth-pairing-compat-routes.d.ts.map +0 -1
  1211. package/api/auth-pairing-compat-routes.js +0 -301
  1212. package/api/local-inference-compat-routes.d.ts +0 -16
  1213. package/api/local-inference-compat-routes.d.ts.map +0 -1
  1214. package/api/local-inference-compat-routes.js +0 -617
  1215. package/api/onboarding-compat-routes.d.ts +0 -4
  1216. package/api/onboarding-compat-routes.d.ts.map +0 -1
  1217. package/api/onboarding-compat-routes.js +0 -207
  1218. package/api/plugins-compat-routes.d.ts +0 -103
  1219. package/api/plugins-compat-routes.d.ts.map +0 -1
  1220. package/api/plugins-compat-routes.js +0 -1181
  1221. package/api/server-onboarding-compat.d.ts +0 -31
  1222. package/api/server-onboarding-compat.d.ts.map +0 -1
  1223. package/api/server-onboarding-compat.js +0 -283
  1224. package/benchmark/cua-routes.d.ts +0 -10
  1225. package/benchmark/cua-routes.d.ts.map +0 -1
  1226. package/benchmark/cua-routes.js +0 -179
  1227. package/benchmark/mock-plugin-base.d.ts +0 -9
  1228. package/benchmark/mock-plugin-base.d.ts.map +0 -1
  1229. package/benchmark/mock-plugin-base.js +0 -325
  1230. package/cli/parse-duration.d.ts +0 -5
  1231. package/cli/parse-duration.d.ts.map +0 -1
  1232. package/cli/parse-duration.js +0 -27
  1233. package/patches/llama-cpp-capacitor@0.1.5.patch +0 -2387
  1234. package/platform/agent-browser-stub.d.ts +0 -27
  1235. package/platform/agent-browser-stub.d.ts.map +0 -1
  1236. package/platform/agent-browser-stub.js +0 -16
  1237. package/platforms/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java +0 -26
  1238. package/platforms/android/app/src/main/res/drawable/ic_launcher_background.xml +0 -170
  1239. package/platforms/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +0 -34
  1240. package/platforms/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java +0 -18
  1241. package/platforms/electrobun/assets/appIcon.iconset/icon_512x512@2x.png +0 -0
  1242. package/platforms/electrobun/assets/appIcon.png +0 -0
  1243. package/platforms/electrobun/scripts/build-whisper-universal.sh +0 -137
  1244. package/platforms/electrobun/scripts/build-whisper.sh +0 -95
  1245. package/platforms/electrobun/scripts/ensure-whisper-model.sh +0 -93
  1246. package/platforms/electrobun/src/libMacWindowEffects.dylib +0 -0
  1247. package/platforms/electrobun/src/native/whisper.ts +0 -280
  1248. package/platforms/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png +0 -0
  1249. package/platforms/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png +0 -0
  1250. package/platforms/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png +0 -0
  1251. package/registry/generate-apps.d.ts +0 -2
  1252. package/registry/generate-apps.d.ts.map +0 -1
  1253. package/registry/generate-apps.js +0 -338
  1254. package/registry/generate.d.ts +0 -2
  1255. package/registry/generate.d.ts.map +0 -1
  1256. package/registry/generate.js +0 -506
  1257. package/registry/loader.d.ts +0 -27
  1258. package/registry/loader.d.ts.map +0 -1
  1259. package/registry/loader.js +0 -111
  1260. package/registry/schema.d.ts +0 -989
  1261. package/registry/schema.d.ts.map +0 -1
  1262. package/registry/schema.js +0 -264
  1263. package/runtime/embedding-manager-support.d.ts +0 -77
  1264. package/runtime/embedding-manager-support.d.ts.map +0 -1
  1265. package/runtime/embedding-manager-support.js +0 -309
  1266. package/runtime/embedding-presets.d.ts +0 -5
  1267. package/runtime/embedding-presets.d.ts.map +0 -1
  1268. package/runtime/embedding-presets.js +0 -47
  1269. package/runtime/embedding-warmup-policy.d.ts +0 -13
  1270. package/runtime/embedding-warmup-policy.d.ts.map +0 -1
  1271. package/runtime/embedding-warmup-policy.js +0 -33
  1272. package/runtime/ensure-local-inference-handler.d.ts +0 -25
  1273. package/runtime/ensure-local-inference-handler.d.ts.map +0 -1
  1274. package/runtime/ensure-local-inference-handler.js +0 -389
  1275. package/runtime/mobile-local-inference-gate.d.ts +0 -21
  1276. package/runtime/mobile-local-inference-gate.d.ts.map +0 -1
  1277. package/runtime/mobile-local-inference-gate.js +0 -24
  1278. package/scripts/aosp/avd-test.mjs +0 -403
  1279. package/scripts/aosp/boot-validate.mjs +0 -536
  1280. package/scripts/aosp/build-aosp.mjs +0 -448
  1281. package/scripts/aosp/build-bootanimation.mjs +0 -178
  1282. package/scripts/aosp/capture-screens.mjs +0 -325
  1283. package/scripts/aosp/e2e-validate.mjs +0 -225
  1284. package/scripts/aosp/lint-init-rc.mjs +0 -258
  1285. package/scripts/aosp/llama-shim/eliza_llama_shim.c +0 -276
  1286. package/scripts/aosp/sim.mjs +0 -277
  1287. package/scripts/aosp/sync-to-aosp.mjs +0 -134
  1288. package/scripts/aosp/validate.mjs +0 -1273
  1289. package/scripts/build-llama-cpp-dflash.mjs +0 -1866
  1290. package/scripts/generate-onboarding-voicelines.mjs +0 -194
  1291. package/scripts/generated/static-asset-manifest.json +0 -4
  1292. package/scripts/normalize-parallax-capture.ts +0 -97
  1293. package/scripts/omnivoice-fuse/Makefile +0 -44
  1294. package/scripts/omnivoice-fuse/README.md +0 -266
  1295. package/scripts/omnivoice-fuse/cmake-graft.mjs +0 -180
  1296. package/scripts/omnivoice-fuse/ffi-stub.c +0 -222
  1297. package/scripts/omnivoice-fuse/ffi.h +0 -158
  1298. package/scripts/omnivoice-fuse/libelizainference_stub.dylib +0 -0
  1299. package/scripts/omnivoice-fuse/verify-symbols.mjs +0 -138
  1300. package/security/cloud-secret-store.d.ts +0 -34
  1301. package/security/cloud-secret-store.d.ts.map +0 -1
  1302. package/security/cloud-secret-store.js +0 -65
  1303. package/security/export-guard.d.ts +0 -34
  1304. package/security/export-guard.d.ts.map +0 -1
  1305. package/security/export-guard.js +0 -127
  1306. package/services/local-inference/__stress__/cache-stress-helpers.d.ts +0 -76
  1307. package/services/local-inference/__stress__/cache-stress-helpers.d.ts.map +0 -1
  1308. package/services/local-inference/__stress__/cache-stress-helpers.js +0 -238
  1309. package/services/local-inference/active-model.d.ts +0 -180
  1310. package/services/local-inference/active-model.d.ts.map +0 -1
  1311. package/services/local-inference/active-model.js +0 -362
  1312. package/services/local-inference/assignments.d.ts +0 -58
  1313. package/services/local-inference/assignments.d.ts.map +0 -1
  1314. package/services/local-inference/assignments.js +0 -179
  1315. package/services/local-inference/backend.d.ts +0 -200
  1316. package/services/local-inference/backend.d.ts.map +0 -1
  1317. package/services/local-inference/backend.js +0 -242
  1318. package/services/local-inference/bundled-models.d.ts +0 -34
  1319. package/services/local-inference/bundled-models.d.ts.map +0 -1
  1320. package/services/local-inference/bundled-models.js +0 -104
  1321. package/services/local-inference/cache-bridge.d.ts +0 -184
  1322. package/services/local-inference/cache-bridge.d.ts.map +0 -1
  1323. package/services/local-inference/cache-bridge.js +0 -333
  1324. package/services/local-inference/catalog.d.ts +0 -57
  1325. package/services/local-inference/catalog.d.ts.map +0 -1
  1326. package/services/local-inference/catalog.js +0 -262
  1327. package/services/local-inference/conversation-registry.d.ts +0 -122
  1328. package/services/local-inference/conversation-registry.d.ts.map +0 -1
  1329. package/services/local-inference/conversation-registry.js +0 -182
  1330. package/services/local-inference/device-bridge.d.ts +0 -139
  1331. package/services/local-inference/device-bridge.d.ts.map +0 -1
  1332. package/services/local-inference/device-bridge.js +0 -774
  1333. package/services/local-inference/dflash-doctor.d.ts +0 -27
  1334. package/services/local-inference/dflash-doctor.d.ts.map +0 -1
  1335. package/services/local-inference/dflash-doctor.js +0 -149
  1336. package/services/local-inference/dflash-server.d.ts +0 -248
  1337. package/services/local-inference/dflash-server.d.ts.map +0 -1
  1338. package/services/local-inference/dflash-server.js +0 -1076
  1339. package/services/local-inference/downloader.d.ts +0 -48
  1340. package/services/local-inference/downloader.d.ts.map +0 -1
  1341. package/services/local-inference/downloader.js +0 -688
  1342. package/services/local-inference/engine.d.ts +0 -282
  1343. package/services/local-inference/engine.d.ts.map +0 -1
  1344. package/services/local-inference/engine.js +0 -743
  1345. package/services/local-inference/external-scanner.d.ts +0 -17
  1346. package/services/local-inference/external-scanner.d.ts.map +0 -1
  1347. package/services/local-inference/external-scanner.js +0 -261
  1348. package/services/local-inference/handler-registry.d.ts +0 -72
  1349. package/services/local-inference/handler-registry.d.ts.map +0 -1
  1350. package/services/local-inference/handler-registry.js +0 -159
  1351. package/services/local-inference/hardware.d.ts +0 -26
  1352. package/services/local-inference/hardware.d.ts.map +0 -1
  1353. package/services/local-inference/hardware.js +0 -139
  1354. package/services/local-inference/hf-search.d.ts +0 -19
  1355. package/services/local-inference/hf-search.d.ts.map +0 -1
  1356. package/services/local-inference/hf-search.js +0 -169
  1357. package/services/local-inference/index.d.ts +0 -10
  1358. package/services/local-inference/index.d.ts.map +0 -1
  1359. package/services/local-inference/index.js +0 -7
  1360. package/services/local-inference/llama-server-metrics.d.ts +0 -108
  1361. package/services/local-inference/llama-server-metrics.d.ts.map +0 -1
  1362. package/services/local-inference/llama-server-metrics.js +0 -175
  1363. package/services/local-inference/manifest/index.d.ts +0 -4
  1364. package/services/local-inference/manifest/index.d.ts.map +0 -1
  1365. package/services/local-inference/manifest/index.js +0 -5
  1366. package/services/local-inference/manifest/schema.d.ts +0 -419
  1367. package/services/local-inference/manifest/schema.d.ts.map +0 -1
  1368. package/services/local-inference/manifest/schema.js +0 -227
  1369. package/services/local-inference/manifest/types.d.ts +0 -23
  1370. package/services/local-inference/manifest/types.d.ts.map +0 -1
  1371. package/services/local-inference/manifest/types.js +0 -5
  1372. package/services/local-inference/manifest/validator.d.ts +0 -43
  1373. package/services/local-inference/manifest/validator.d.ts.map +0 -1
  1374. package/services/local-inference/manifest/validator.js +0 -187
  1375. package/services/local-inference/paths.d.ts +0 -8
  1376. package/services/local-inference/paths.d.ts.map +0 -1
  1377. package/services/local-inference/paths.js +0 -7
  1378. package/services/local-inference/providers.d.ts +0 -61
  1379. package/services/local-inference/providers.d.ts.map +0 -1
  1380. package/services/local-inference/providers.js +0 -334
  1381. package/services/local-inference/ram-budget.d.ts +0 -57
  1382. package/services/local-inference/ram-budget.d.ts.map +0 -1
  1383. package/services/local-inference/ram-budget.js +0 -107
  1384. package/services/local-inference/readiness.d.ts +0 -9
  1385. package/services/local-inference/readiness.d.ts.map +0 -1
  1386. package/services/local-inference/readiness.js +0 -153
  1387. package/services/local-inference/recommendation.d.ts +0 -62
  1388. package/services/local-inference/recommendation.d.ts.map +0 -1
  1389. package/services/local-inference/recommendation.js +0 -309
  1390. package/services/local-inference/registry.d.ts +0 -35
  1391. package/services/local-inference/registry.d.ts.map +0 -1
  1392. package/services/local-inference/registry.js +0 -117
  1393. package/services/local-inference/router-handler.d.ts +0 -51
  1394. package/services/local-inference/router-handler.d.ts.map +0 -1
  1395. package/services/local-inference/router-handler.js +0 -165
  1396. package/services/local-inference/routing-policy.d.ts +0 -55
  1397. package/services/local-inference/routing-policy.d.ts.map +0 -1
  1398. package/services/local-inference/routing-policy.js +0 -195
  1399. package/services/local-inference/routing-preferences.d.ts +0 -8
  1400. package/services/local-inference/routing-preferences.d.ts.map +0 -1
  1401. package/services/local-inference/routing-preferences.js +0 -7
  1402. package/services/local-inference/service.d.ts +0 -88
  1403. package/services/local-inference/service.d.ts.map +0 -1
  1404. package/services/local-inference/service.js +0 -210
  1405. package/services/local-inference/session-pool.d.ts +0 -72
  1406. package/services/local-inference/session-pool.d.ts.map +0 -1
  1407. package/services/local-inference/session-pool.js +0 -125
  1408. package/services/local-inference/types.d.ts +0 -309
  1409. package/services/local-inference/types.d.ts.map +0 -1
  1410. package/services/local-inference/types.js +0 -23
  1411. package/services/local-inference/verify.d.ts +0 -8
  1412. package/services/local-inference/verify.d.ts.map +0 -1
  1413. package/services/local-inference/verify.js +0 -7
  1414. package/services/local-inference/voice/barge-in.d.ts +0 -15
  1415. package/services/local-inference/voice/barge-in.d.ts.map +0 -1
  1416. package/services/local-inference/voice/barge-in.js +0 -20
  1417. package/services/local-inference/voice/engine-bridge.d.ts +0 -256
  1418. package/services/local-inference/voice/engine-bridge.d.ts.map +0 -1
  1419. package/services/local-inference/voice/engine-bridge.js +0 -398
  1420. package/services/local-inference/voice/ffi-bindings.d.ts +0 -114
  1421. package/services/local-inference/voice/ffi-bindings.d.ts.map +0 -1
  1422. package/services/local-inference/voice/ffi-bindings.js +0 -281
  1423. package/services/local-inference/voice/index.d.ts +0 -51
  1424. package/services/local-inference/voice/index.d.ts.map +0 -1
  1425. package/services/local-inference/voice/index.js +0 -50
  1426. package/services/local-inference/voice/lifecycle.d.ts +0 -135
  1427. package/services/local-inference/voice/lifecycle.d.ts.map +0 -1
  1428. package/services/local-inference/voice/lifecycle.js +0 -189
  1429. package/services/local-inference/voice/phoneme-tokenizer.d.ts +0 -58
  1430. package/services/local-inference/voice/phoneme-tokenizer.d.ts.map +0 -1
  1431. package/services/local-inference/voice/phoneme-tokenizer.js +0 -53
  1432. package/services/local-inference/voice/phrase-cache.d.ts +0 -24
  1433. package/services/local-inference/voice/phrase-cache.d.ts.map +0 -1
  1434. package/services/local-inference/voice/phrase-cache.js +0 -32
  1435. package/services/local-inference/voice/phrase-chunker.d.ts +0 -20
  1436. package/services/local-inference/voice/phrase-chunker.d.ts.map +0 -1
  1437. package/services/local-inference/voice/phrase-chunker.js +0 -85
  1438. package/services/local-inference/voice/ring-buffer.d.ts +0 -40
  1439. package/services/local-inference/voice/ring-buffer.d.ts.map +0 -1
  1440. package/services/local-inference/voice/ring-buffer.js +0 -85
  1441. package/services/local-inference/voice/rollback-queue.d.ts +0 -24
  1442. package/services/local-inference/voice/rollback-queue.d.ts.map +0 -1
  1443. package/services/local-inference/voice/rollback-queue.js +0 -49
  1444. package/services/local-inference/voice/scheduler.d.ts +0 -47
  1445. package/services/local-inference/voice/scheduler.d.ts.map +0 -1
  1446. package/services/local-inference/voice/scheduler.js +0 -123
  1447. package/services/local-inference/voice/shared-resources.d.ts +0 -119
  1448. package/services/local-inference/voice/shared-resources.d.ts.map +0 -1
  1449. package/services/local-inference/voice/shared-resources.js +0 -83
  1450. package/services/local-inference/voice/speaker-preset-cache.d.ts +0 -28
  1451. package/services/local-inference/voice/speaker-preset-cache.d.ts.map +0 -1
  1452. package/services/local-inference/voice/speaker-preset-cache.js +0 -44
  1453. package/services/local-inference/voice/types.d.ts +0 -80
  1454. package/services/local-inference/voice/types.d.ts.map +0 -1
  1455. package/services/local-inference/voice/voice-preset-format.d.ts +0 -56
  1456. package/services/local-inference/voice/voice-preset-format.d.ts.map +0 -1
  1457. package/services/local-inference/voice/voice-preset-format.js +0 -184
  1458. package/services/plugin-installer.d.ts +0 -22
  1459. package/services/plugin-installer.d.ts.map +0 -1
  1460. package/services/plugin-installer.js +0 -41
  1461. package/test/helpers/i18n.ts +0 -5
  1462. package/test/helpers/loopback.ts +0 -33
  1463. package/test/helpers/react-test.ts +0 -40
  1464. package/test/helpers/skip-without.ts +0 -53
  1465. package/test/scripts/task-agent-live-smoke.ts +0 -1335
  1466. /package/services/{local-inference/voice → ambient-audio}/types.js +0 -0
@@ -1,10 +1,331 @@
1
+ import { existsSync, readFileSync } from "node:fs";
1
2
  import http from "node:http";
3
+ import path from "node:path";
4
+ import { gunzipSync } from "node:zlib";
2
5
  import { WebSocketServer } from "ws";
3
6
 
4
7
  const port = Number(process.env.ELIZA_UI_SMOKE_API_PORT || "31337");
8
+ const repoRoot = path.resolve(new URL("../../..", import.meta.url).pathname);
9
+ const SMOKE_GENERATED_AT = "2026-01-01T00:00:00.000Z";
10
+ const DEMO_ORCHESTRATOR = process.env.ELIZA_UI_SMOKE_DEMO_ORCHESTRATOR === "1";
5
11
  let browserWorkspaceCounter = 0;
6
12
  let browserWorkspaceTabs = [];
7
13
  let lifeOpsAppEnabled = true;
14
+ let conversationCounter = 0;
15
+ let messageCounter = 0;
16
+ const stubConversations = [];
17
+ const stubConversationMessages = new Map();
18
+ const unhandledApiRequests = [];
19
+ const ONE_PIXEL_PNG = Buffer.from(
20
+ "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII=",
21
+ "base64",
22
+ );
23
+
24
+ // A minimal valid 16-bit PCM mono WAV of silence. The onboarding voice path
25
+ // POSTs /api/tts/first-run/speak and plays the returned bytes as audio/wav, so
26
+ // the stub must return decodable audio (not a 501) to avoid a console.error.
27
+ function buildSilentWav() {
28
+ const sampleRate = 8000;
29
+ const dataBytes = 1600; // ~0.1s of silence
30
+ const header = Buffer.alloc(44);
31
+ header.write("RIFF", 0, "ascii");
32
+ header.writeUInt32LE(36 + dataBytes, 4);
33
+ header.write("WAVE", 8, "ascii");
34
+ header.write("fmt ", 12, "ascii");
35
+ header.writeUInt32LE(16, 16); // PCM fmt chunk size
36
+ header.writeUInt16LE(1, 20); // audioFormat = PCM
37
+ header.writeUInt16LE(1, 22); // mono
38
+ header.writeUInt32LE(sampleRate, 24);
39
+ header.writeUInt32LE(sampleRate * 2, 28); // byteRate (mono, 16-bit)
40
+ header.writeUInt16LE(2, 32); // blockAlign
41
+ header.writeUInt16LE(16, 34); // bitsPerSample
42
+ header.write("data", 36, "ascii");
43
+ header.writeUInt32LE(dataBytes, 40);
44
+ return Buffer.concat([header, Buffer.alloc(dataBytes)]);
45
+ }
46
+
47
+ const SILENT_WAV = buildSilentWav();
48
+ // Deterministic transcript the local-inference ASR stub returns for any audio
49
+ // the /chat overlay captures — keeps the voice e2e turn reproducible.
50
+ const SMOKE_VOICE_TRANSCRIPT = "this is the voice smoke transcript";
51
+ // The spoken reply the stub returns for that transcript — a clean sentence so
52
+ // the overlay's TTS output is non-empty and the assistant bubble is assertable.
53
+ const SMOKE_VOICE_REPLY = "Got it, this is the spoken reply.";
54
+ function readSmokeVrm() {
55
+ const candidates = [
56
+ new URL(
57
+ "../../../plugins/plugin-companion/public/vrms/eliza-1.vrm.gz",
58
+ import.meta.url,
59
+ ),
60
+ new URL(
61
+ "../../../plugins/plugin-companion/public_src/vrms/eliza-1.vrm",
62
+ import.meta.url,
63
+ ),
64
+ ];
65
+
66
+ for (const candidate of candidates) {
67
+ if (!existsSync(candidate)) continue;
68
+ const body = readFileSync(candidate);
69
+ return candidate.pathname.endsWith(".gz") ? gunzipSync(body) : body;
70
+ }
71
+
72
+ return Buffer.alloc(4);
73
+ }
74
+
75
+ const SMOKE_VRM = readSmokeVrm();
76
+
77
+ // A collapsed plugin declares ONE view that draws gui + tui (+ xr) from the
78
+ // same `<Name>View` componentExport and the same bundle on the same `/<id>`
79
+ // route. In the stub a `modalities` 6th element expands that single declaration
80
+ // into one gui object + one tui object (both at `/<id>`, both serving the same
81
+ // componentExport), mirroring how the real /api/views collapses modalities.
82
+ // Plugins that still declare a standalone tui route (training) keep a separate
83
+ // `tui` row with its own `/<id>/tui` path below.
84
+ const smokeViewDeclarations = [
85
+ [
86
+ "companion",
87
+ "Companion",
88
+ "plugin-companion",
89
+ "/companion",
90
+ "CompanionView",
91
+ ["gui", "tui"],
92
+ ],
93
+ [
94
+ "contacts",
95
+ "Contacts",
96
+ "plugin-contacts",
97
+ "/contacts",
98
+ "ContactsView",
99
+ ["gui", "tui"],
100
+ ],
101
+ [
102
+ "hyperliquid",
103
+ "Hyperliquid",
104
+ "plugin-hyperliquid-app",
105
+ "/hyperliquid",
106
+ "HyperliquidView",
107
+ ["gui", "tui"],
108
+ ],
109
+ // NOTE: the LifeOps overview view was removed (PA no longer registers a
110
+ // `lifeops` view). Its stub entries are deleted so the smoke launcher matches
111
+ // production. The decomposed per-domain views below are the real surfaces.
112
+ // Decomposed personal-assistant domain views — registered so their dynamic
113
+ // bundles load in keyless ui-smoke and the decomposed-interactions spec can
114
+ // drive them (closing INTERACTION_DEBT in view-interaction-coverage.test.ts).
115
+ // NOTE: "documents" is intentionally NOT registered here — its view path
116
+ // `/documents` collides with the built-in "documents" tab (App.tsx findView
117
+ // matches `/${tab}`), which would hijack the `/character/documents` route.
118
+ ["calendar", "Calendar", "plugin-calendar", "/calendar", "CalendarView"],
119
+ ["finances", "Finances", "plugin-finances", "/finances", "FinancesView"],
120
+ ["focus", "Focus", "plugin-blocker", "/focus", "FocusView"],
121
+ ["goals", "Goals", "plugin-goals", "/goals", "GoalsView"],
122
+ ["health", "Health", "plugin-health", "/health", "HealthView"],
123
+ ["inbox", "Inbox", "plugin-inbox", "/inbox", "InboxView"],
124
+ ["todos", "Todos", "plugin-todos", "/todos", "TodosView"],
125
+ [
126
+ "relationships",
127
+ "Relationships",
128
+ "plugin-relationships",
129
+ "/relationships",
130
+ "RelationshipsView",
131
+ ],
132
+ [
133
+ "messages",
134
+ "Messages",
135
+ "plugin-messages",
136
+ "/messages",
137
+ "MessagesView",
138
+ ["gui", "tui"],
139
+ ],
140
+ [
141
+ "model-tester",
142
+ "Model Tester",
143
+ "app-model-tester",
144
+ "/model-tester",
145
+ "ModelTesterView",
146
+ ["gui", "tui"],
147
+ ],
148
+ // Phone collapsed to ONE source: gui + tui (+ xr) all mount the single
149
+ // PhoneView spatial component from the same bundle.
150
+ ["phone", "Phone", "plugin-phone", "/phone", "PhoneView", ["gui", "tui"]],
151
+ [
152
+ "polymarket",
153
+ "Polymarket",
154
+ "plugin-polymarket-app",
155
+ "/polymarket",
156
+ "PolymarketView",
157
+ ["gui", "tui"],
158
+ ],
159
+ [
160
+ "shopify",
161
+ "Shopify",
162
+ "plugin-shopify-ui",
163
+ "/shopify",
164
+ "ShopifyView",
165
+ ["gui", "tui"],
166
+ ],
167
+ [
168
+ "steward",
169
+ "Steward",
170
+ "plugin-steward-app",
171
+ "/steward",
172
+ "StewardView",
173
+ ["gui", "tui"],
174
+ ],
175
+ [
176
+ "vincent",
177
+ "Vincent",
178
+ "plugin-vincent",
179
+ "/vincent",
180
+ "VincentView",
181
+ ["gui", "tui"],
182
+ ],
183
+ [
184
+ "wallet",
185
+ "Wallet",
186
+ "plugin-wallet-ui",
187
+ "/wallet",
188
+ "InventoryView",
189
+ ["gui", "tui"],
190
+ ],
191
+ [
192
+ "vector-browser",
193
+ "Vector Browser",
194
+ "plugin-vector-browser",
195
+ "/vector-browser",
196
+ "VectorBrowserView",
197
+ ],
198
+ ["feed", "Feed", "plugin-feed", "/feed", "FeedView", ["gui", "tui"]],
199
+ [
200
+ "views-manager",
201
+ "Views",
202
+ "plugin-app-control",
203
+ "/views",
204
+ "ViewManagerView",
205
+ ["gui", "tui"],
206
+ ],
207
+ [
208
+ "screenshare",
209
+ "Screenshare",
210
+ "plugin-screenshare",
211
+ "/screenshare",
212
+ "ScreenshareView",
213
+ ["gui", "tui"],
214
+ ],
215
+ [
216
+ "social-alpha",
217
+ "Social Alpha",
218
+ "plugin-social-alpha",
219
+ "/social-alpha",
220
+ "SocialAlphaView",
221
+ ],
222
+ [
223
+ "task-coordinator",
224
+ "Task Coordinator",
225
+ "plugin-task-coordinator",
226
+ "/task-coordinator",
227
+ "TaskCoordinatorView",
228
+ ["gui", "tui"],
229
+ ],
230
+ [
231
+ "orchestrator",
232
+ "Orchestrator",
233
+ "plugin-task-coordinator",
234
+ "/orchestrator",
235
+ "OrchestratorView",
236
+ ["gui", "tui"],
237
+ ],
238
+ [
239
+ "trajectory-logger",
240
+ "Trajectory Logger",
241
+ "plugin-trajectory-logger",
242
+ "/trajectory-logger",
243
+ "TrajectoryLoggerView",
244
+ ["gui", "tui"],
245
+ ],
246
+ // Training is NOT collapsed: it keeps a standalone gui route plus a separate
247
+ // tui declaration on its own `/training/tui` route.
248
+ ["training", "Fine Tuning", "plugin-training", "/training", "FineTuningView"],
249
+ [
250
+ "training",
251
+ "Fine Tuning TUI",
252
+ "plugin-training",
253
+ "/training/tui",
254
+ "FineTuningTuiView",
255
+ "tui",
256
+ ],
257
+ ];
258
+
259
+ function smokeViewObject({
260
+ id,
261
+ label,
262
+ pluginDirName,
263
+ viewPath,
264
+ componentExport,
265
+ viewType,
266
+ }) {
267
+ const encodedId = encodeURIComponent(id);
268
+ const query = viewType === "tui" ? "?viewType=tui&v=ui-smoke" : "?v=ui-smoke";
269
+ const bundlePath = path.join(
270
+ repoRoot,
271
+ "plugins",
272
+ pluginDirName,
273
+ "dist",
274
+ "views",
275
+ "bundle.js",
276
+ );
277
+ return {
278
+ id,
279
+ label,
280
+ viewType,
281
+ pluginName: `@elizaos/${pluginDirName}`,
282
+ path: viewPath,
283
+ order: 100,
284
+ bundlePath: "dist/views/bundle.js",
285
+ bundleUrl: `/api/views/${encodedId}/bundle.js${query}`,
286
+ componentExport,
287
+ available: true,
288
+ realBundleAvailable: existsSync(bundlePath),
289
+ visibleInManager: true,
290
+ capabilities: [
291
+ {
292
+ id: "get-state",
293
+ label: "Get state",
294
+ inputSchema: { type: "object" },
295
+ },
296
+ ],
297
+ _smokePluginDirName: pluginDirName,
298
+ };
299
+ }
300
+
301
+ // A collapsed declaration carries a `modalities` array as its 6th element and
302
+ // expands to one view object per surface (gui + tui), all sharing the same
303
+ // `/<id>` route and `<Name>View` componentExport. A legacy declaration carries
304
+ // a single `viewType` string (default "gui").
305
+ const smokeViews = smokeViewDeclarations.flatMap(
306
+ ([
307
+ id,
308
+ label,
309
+ pluginDirName,
310
+ viewPath,
311
+ componentExport,
312
+ modalitiesOrViewType = "gui",
313
+ ]) => {
314
+ const viewTypes = Array.isArray(modalitiesOrViewType)
315
+ ? modalitiesOrViewType
316
+ : [modalitiesOrViewType];
317
+ return viewTypes.map((viewType) =>
318
+ smokeViewObject({
319
+ id,
320
+ label,
321
+ pluginDirName,
322
+ viewPath,
323
+ componentExport,
324
+ viewType,
325
+ }),
326
+ );
327
+ },
328
+ );
8
329
 
9
330
  const stubPlugins = [
10
331
  {
@@ -89,12 +410,14 @@ function stubCatalogApp({
89
410
 
90
411
  const stubCatalogApps = [
91
412
  stubCatalogApp({
92
- name: "@elizaos/app-lifeops",
413
+ name: "@elizaos/plugin-personal-assistant",
93
414
  displayName: "LifeOps",
94
415
  description:
95
416
  "Run tasks, reminders, calendar, inbox, and connected workflows.",
96
417
  capabilities: ["lifeops", "tasks", "calendar", "gmail"],
97
- heroImage: "/app-heroes/lifeops.png",
418
+ // No heroImage: the lifeops surface was removed and /app-heroes/lifeops.png
419
+ // does not exist; the catalog renders the hero conditionally, so omitting it
420
+ // avoids the 404 console error (which the visual smoke asserts against).
98
421
  }),
99
422
  stubCatalogApp({
100
423
  name: "@elizaos/app-plugin-viewer",
@@ -112,7 +435,7 @@ const stubCatalogApps = [
112
435
  heroImage: "/app-heroes/skills-viewer.png",
113
436
  }),
114
437
  stubCatalogApp({
115
- name: "@elizaos/app-training",
438
+ name: "@elizaos/plugin-training",
116
439
  displayName: "Fine Tuning",
117
440
  description:
118
441
  "Build datasets, inspect trajectories, and activate tuned models.",
@@ -162,25 +485,53 @@ const stubCatalogApps = [
162
485
  heroImage: "/app-heroes/log-viewer.png",
163
486
  }),
164
487
  stubCatalogApp({
165
- name: "@elizaos/app-companion",
488
+ name: "@elizaos/plugin-companion",
166
489
  displayName: "Companion",
167
490
  description: "The companion overlay shell for ambient agent presence.",
168
491
  category: "social",
169
492
  }),
170
493
  stubCatalogApp({
171
- name: "@elizaos/app-shopify",
494
+ name: "@elizaos/plugin-steward-app",
495
+ displayName: "Steward",
496
+ description: "Review wallet approvals and inventory status.",
497
+ capabilities: ["wallet", "approvals", "inventory"],
498
+ }),
499
+ stubCatalogApp({
500
+ name: "@elizaos/plugin-elizamaker",
501
+ displayName: "ElizaMaker",
502
+ description: "Run drop, mint, whitelist, and verification workflows.",
503
+ capabilities: ["drops", "minting", "whitelist"],
504
+ }),
505
+ stubCatalogApp({
506
+ name: "@elizaos/plugin-shopify-ui",
172
507
  displayName: "Shopify",
173
508
  description: "Manage Shopify store operations from the agent workspace.",
174
509
  category: "platform",
175
510
  }),
176
511
  stubCatalogApp({
177
- name: "@elizaos/app-vincent",
512
+ name: "@elizaos/plugin-vincent",
178
513
  displayName: "Vincent",
179
514
  description: "Manage Vincent DeFi account access and trading context.",
180
515
  category: "platform",
181
516
  }),
517
+ stubCatalogApp({
518
+ name: "@elizaos/plugin-hyperliquid-app",
519
+ displayName: "Hyperliquid",
520
+ description: "Inspect Hyperliquid markets, positions, and order status.",
521
+ category: "platform",
522
+ capabilities: ["hyperliquid", "trading", "wallet"],
523
+ }),
524
+ stubCatalogApp({
525
+ name: "@elizaos/plugin-polymarket-app",
526
+ displayName: "Polymarket",
527
+ description: "Browse prediction markets and native trading readiness.",
528
+ category: "platform",
529
+ capabilities: ["polymarket", "prediction-markets", "wallet"],
530
+ }),
182
531
  ];
183
532
 
533
+ let smokeFavoriteApps = [];
534
+
184
535
  const stubMemoryStats = {
185
536
  total: 0,
186
537
  byType: {},
@@ -390,6 +741,113 @@ const emptyWalletMarketOverview = {
390
741
  predictions: [],
391
742
  };
392
743
 
744
+ const stubHyperliquidStatus = {
745
+ publicReadReady: true,
746
+ signerReady: false,
747
+ executionReady: false,
748
+ executionBlockedReason:
749
+ "Signed Hyperliquid exchange mutations are disabled in UI smoke.",
750
+ accountAddress: null,
751
+ apiBaseUrl: "https://api.hyperliquid.xyz",
752
+ credentialMode: "none",
753
+ readiness: {
754
+ publicReads: true,
755
+ accountReads: false,
756
+ signer: false,
757
+ execution: false,
758
+ },
759
+ account: {
760
+ address: null,
761
+ source: "none",
762
+ guidance:
763
+ "Connect a managed vault or configure an account address for account reads.",
764
+ },
765
+ vault: {
766
+ configured: false,
767
+ ready: false,
768
+ address: null,
769
+ guidance: "Public market reads do not require a vault.",
770
+ },
771
+ apiWallet: {
772
+ configured: false,
773
+ guidance: "API-wallet delegation is optional.",
774
+ },
775
+ };
776
+
777
+ const stubHyperliquidMarkets = {
778
+ markets: [
779
+ {
780
+ name: "BTC",
781
+ index: 0,
782
+ szDecimals: 5,
783
+ maxLeverage: 50,
784
+ onlyIsolated: false,
785
+ isDelisted: false,
786
+ },
787
+ {
788
+ name: "ETH",
789
+ index: 1,
790
+ szDecimals: 4,
791
+ maxLeverage: 50,
792
+ onlyIsolated: false,
793
+ isDelisted: false,
794
+ },
795
+ ],
796
+ source: "hyperliquid-info-meta",
797
+ fetchedAt: "2026-01-01T00:00:00.000Z",
798
+ };
799
+
800
+ const stubPolymarketStatus = {
801
+ publicReads: {
802
+ ready: true,
803
+ reason: null,
804
+ gammaApiBase: "https://gamma-api.polymarket.com",
805
+ dataApiBase: "https://data-api.polymarket.com",
806
+ },
807
+ trading: {
808
+ ready: false,
809
+ credentialsReady: false,
810
+ missing: [
811
+ "POLYMARKET_PRIVATE_KEY",
812
+ "CLOB_API_KEY",
813
+ "CLOB_API_SECRET",
814
+ "CLOB_API_PASSPHRASE",
815
+ ],
816
+ reason: "Trading is disabled in UI smoke.",
817
+ clobApiBase: "https://clob.polymarket.com",
818
+ },
819
+ };
820
+
821
+ const stubPolymarketMarket = {
822
+ id: "ui-smoke-market",
823
+ slug: "ui-smoke-market",
824
+ question: "Will the UI smoke suite stay green?",
825
+ description: "Deterministic fixture market for app-window QA.",
826
+ category: "QA",
827
+ active: true,
828
+ closed: false,
829
+ archived: false,
830
+ restricted: false,
831
+ enableOrderBook: true,
832
+ conditionId: "0xsmoke",
833
+ clobTokenIds: ["yes-token", "no-token"],
834
+ outcomes: [
835
+ { name: "Yes", price: "0.72" },
836
+ { name: "No", price: "0.28" },
837
+ ],
838
+ liquidity: "10000",
839
+ volume: "42000",
840
+ volume24hr: "1200",
841
+ lastTradePrice: "0.72",
842
+ bestBid: "0.71",
843
+ bestAsk: "0.73",
844
+ image: null,
845
+ icon: null,
846
+ endDate: null,
847
+ startDate: "2026-01-01T00:00:00.000Z",
848
+ updatedAt: "2026-01-01T00:00:00.000Z",
849
+ };
850
+
393
851
  const smokeGeneratedAt = "2026-01-01T00:00:00.000Z";
394
852
 
395
853
  const emptyLifeOpsOverviewSummary = {
@@ -662,6 +1120,144 @@ function parsePositiveInt(value, fallback) {
662
1120
  return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
663
1121
  }
664
1122
 
1123
+ function createStubConversation({ title = "New chat", metadata = {} } = {}) {
1124
+ conversationCounter += 1;
1125
+ const createdAt = nowIso();
1126
+ const conversation = {
1127
+ id: `stub-conversation-${conversationCounter}`,
1128
+ title:
1129
+ typeof title === "string" && title.trim().length > 0
1130
+ ? title.trim()
1131
+ : "New chat",
1132
+ roomId: `stub-room-${conversationCounter}`,
1133
+ metadata:
1134
+ metadata && typeof metadata === "object" && !Array.isArray(metadata)
1135
+ ? metadata
1136
+ : {},
1137
+ createdAt,
1138
+ updatedAt: createdAt,
1139
+ };
1140
+ stubConversations.unshift(conversation);
1141
+ stubConversationMessages.set(conversation.id, []);
1142
+ return conversation;
1143
+ }
1144
+
1145
+ function findStubConversation(id) {
1146
+ return stubConversations.find((conversation) => conversation.id === id);
1147
+ }
1148
+
1149
+ function createStubMessage(role, text) {
1150
+ messageCounter += 1;
1151
+ return {
1152
+ id: `stub-message-${messageCounter}`,
1153
+ role,
1154
+ text: typeof text === "string" ? text : "",
1155
+ timestamp: Date.now(),
1156
+ };
1157
+ }
1158
+
1159
+ function stableTextHash(text) {
1160
+ let hash = 0x811c9dc5;
1161
+ for (let index = 0; index < text.length; index += 1) {
1162
+ hash ^= text.charCodeAt(index);
1163
+ hash = Math.imul(hash, 0x01000193) >>> 0;
1164
+ }
1165
+ return hash.toString(16).padStart(8, "0");
1166
+ }
1167
+
1168
+ function normalizeAssistantInput(value) {
1169
+ return typeof value === "string" ? value.trim().replace(/\s+/g, " ") : "";
1170
+ }
1171
+
1172
+ function classifyAssistantAction(text) {
1173
+ const normalized = text.toLowerCase();
1174
+ if (/\b(wallet|inventory|address|balance)\b/.test(normalized)) {
1175
+ return { type: "navigate", target: "/wallet" };
1176
+ }
1177
+ if (/\b(view|views|app|apps)\b/.test(normalized)) {
1178
+ return { type: "navigate", target: "/views" };
1179
+ }
1180
+ if (/\b(setting|settings|provider|model|voice)\b/.test(normalized)) {
1181
+ return { type: "navigate", target: "/settings" };
1182
+ }
1183
+ if (/\b(chat|conversation|message)\b/.test(normalized)) {
1184
+ return { type: "navigate", target: "/chat" };
1185
+ }
1186
+ return { type: "noop", target: null };
1187
+ }
1188
+
1189
+ function createDeterministicAssistantText({ body, conversationId, transport }) {
1190
+ const inputText = normalizeAssistantInput(body?.text ?? body?.message);
1191
+ if (inputText === SMOKE_VOICE_TRANSCRIPT) {
1192
+ // Voice e2e: reply to the spoken turn with a plain sentence (not the JSON
1193
+ // fixture) so the bidirectional voice output is speakable + assertable.
1194
+ return SMOKE_VOICE_REPLY;
1195
+ }
1196
+ if (/\bbroken[_ -]?llm[_ -]?response\b/i.test(inputText)) {
1197
+ return `BROKEN_MOCK_LLM_RESPONSE:${JSON.stringify({
1198
+ fixture: "ui-smoke-assistant-v1",
1199
+ conversationId,
1200
+ transport,
1201
+ input: { text: inputText },
1202
+ action: classifyAssistantAction(inputText),
1203
+ }).slice(0, -2)}`;
1204
+ }
1205
+ const payload = {
1206
+ fixture: "ui-smoke-assistant-v1",
1207
+ registrySeam: "strict-fixture-registry",
1208
+ conversationId,
1209
+ transport,
1210
+ input: {
1211
+ text: inputText,
1212
+ length: inputText.length,
1213
+ hash: stableTextHash(inputText),
1214
+ },
1215
+ action: classifyAssistantAction(inputText),
1216
+ };
1217
+ return JSON.stringify(payload);
1218
+ }
1219
+
1220
+ function recordUnhandledApiRequest(req, url) {
1221
+ const entry = {
1222
+ method: req.method ?? "GET",
1223
+ path: url.pathname,
1224
+ search: url.search,
1225
+ at: nowIso(),
1226
+ };
1227
+ unhandledApiRequests.push(entry);
1228
+ if (unhandledApiRequests.length > 50) {
1229
+ unhandledApiRequests.shift();
1230
+ }
1231
+ console.error(
1232
+ `[playwright-ui-smoke-api-stub] unhandled API route: ${entry.method} ${entry.path}${entry.search}`,
1233
+ );
1234
+ return entry;
1235
+ }
1236
+
1237
+ function appendStubMessage(conversationId, message) {
1238
+ const messages = stubConversationMessages.get(conversationId) ?? [];
1239
+ messages.push(message);
1240
+ stubConversationMessages.set(conversationId, messages);
1241
+ const conversation = findStubConversation(conversationId);
1242
+ if (conversation) conversation.updatedAt = nowIso();
1243
+ return message;
1244
+ }
1245
+
1246
+ function cleanupEmptyStubConversations({ keepId } = {}) {
1247
+ const deleted = [];
1248
+ for (let index = stubConversations.length - 1; index >= 0; index -= 1) {
1249
+ const conversation = stubConversations[index];
1250
+ if (typeof keepId === "string" && conversation.id === keepId) continue;
1251
+ const messages = stubConversationMessages.get(conversation.id) ?? [];
1252
+ const hasUserMessage = messages.some((message) => message.role === "user");
1253
+ if (hasUserMessage) continue;
1254
+ stubConversations.splice(index, 1);
1255
+ stubConversationMessages.delete(conversation.id);
1256
+ deleted.push(conversation.id);
1257
+ }
1258
+ return deleted;
1259
+ }
1260
+
665
1261
  function buildRuntimeSnapshot(url) {
666
1262
  const maxDepth = parsePositiveInt(url.searchParams.get("depth"), 10);
667
1263
  const maxArrayLength = parsePositiveInt(
@@ -878,6 +1474,581 @@ function sendEmpty(req, res, status) {
878
1474
  res.end();
879
1475
  }
880
1476
 
1477
+ function sendBinary(req, res, status, contentType, body) {
1478
+ applyCors(req, res);
1479
+ res.statusCode = status;
1480
+ res.setHeader("Content-Type", contentType);
1481
+ res.end(req.method === "HEAD" ? undefined : body);
1482
+ }
1483
+
1484
+ function contentTypeForSmokeViewAsset(assetPath) {
1485
+ const ext = path.extname(assetPath).toLowerCase();
1486
+ if (ext === ".js" || ext === ".mjs")
1487
+ return "application/javascript; charset=utf-8";
1488
+ if (ext === ".css") return "text/css; charset=utf-8";
1489
+ if (ext === ".map" || ext === ".json")
1490
+ return "application/json; charset=utf-8";
1491
+ if (ext === ".svg") return "image/svg+xml";
1492
+ if (ext === ".png") return "image/png";
1493
+ if (ext === ".jpg" || ext === ".jpeg") return "image/jpeg";
1494
+ if (ext === ".webp") return "image/webp";
1495
+ return "application/octet-stream";
1496
+ }
1497
+
1498
+ function convertNamedImportsToDestructuring(namedImports) {
1499
+ return namedImports
1500
+ .split(",")
1501
+ .map((part) => part.trim())
1502
+ .filter(Boolean)
1503
+ .map((part) => part.replace(/\s+as\s+/u, ": "))
1504
+ .join(", ");
1505
+ }
1506
+
1507
+ function buildHostExternalImportReplacement(importClause, specifier, index) {
1508
+ const moduleVar = `__eliza_dynamic_view_host_external_${index}`;
1509
+ const lines = [
1510
+ `const ${moduleVar} = await globalThis.__ELIZA_DYNAMIC_VIEW_IMPORT__(${JSON.stringify(specifier)});`,
1511
+ ];
1512
+ const trimmed = importClause.trim();
1513
+ if (trimmed.startsWith("* as ")) {
1514
+ lines.push(`const ${trimmed.slice("* as ".length).trim()} = ${moduleVar};`);
1515
+ return lines.join("\n");
1516
+ }
1517
+ const namedMatch = trimmed.match(/^\{([\s\S]*)\}$/u);
1518
+ if (namedMatch) {
1519
+ lines.push(
1520
+ `const { ${convertNamedImportsToDestructuring(namedMatch[1])} } = ${moduleVar};`,
1521
+ );
1522
+ return lines.join("\n");
1523
+ }
1524
+ const defaultAndNamedMatch = trimmed.match(/^([^,]+),\s*\{([\s\S]*)\}$/u);
1525
+ if (defaultAndNamedMatch) {
1526
+ lines.push(
1527
+ `const ${defaultAndNamedMatch[1].trim()} = ${moduleVar}.default ?? ${moduleVar};`,
1528
+ );
1529
+ lines.push(
1530
+ `const { ${convertNamedImportsToDestructuring(defaultAndNamedMatch[2])} } = ${moduleVar};`,
1531
+ );
1532
+ return lines.join("\n");
1533
+ }
1534
+ lines.push(`const ${trimmed} = ${moduleVar}.default ?? ${moduleVar};`);
1535
+ return lines.join("\n");
1536
+ }
1537
+
1538
+ function rewriteHostExternalImports(source, specifiers) {
1539
+ if (specifiers.length === 0) return source;
1540
+ const specifierPattern = specifiers
1541
+ .map((item) => item.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&"))
1542
+ .join("|");
1543
+ const fromImportPattern = new RegExp(
1544
+ `import\\s+([^;]*?)\\s+from\\s+["'](${specifierPattern})["'];?`,
1545
+ "gu",
1546
+ );
1547
+ const sideEffectPattern = new RegExp(
1548
+ `import\\s+["'](${specifierPattern})["'];?`,
1549
+ "gu",
1550
+ );
1551
+ let replacementIndex = 0;
1552
+ return source
1553
+ .replace(fromImportPattern, (_match, importClause, specifier) =>
1554
+ buildHostExternalImportReplacement(
1555
+ String(importClause),
1556
+ String(specifier),
1557
+ replacementIndex++,
1558
+ ),
1559
+ )
1560
+ .replace(
1561
+ sideEffectPattern,
1562
+ (_match, specifier) =>
1563
+ `await globalThis.__ELIZA_DYNAMIC_VIEW_IMPORT__(${JSON.stringify(String(specifier))});`,
1564
+ );
1565
+ }
1566
+
1567
+ function parseHostExternalSpecifiers(url) {
1568
+ if (url.searchParams.get("hostExternalRuntime") !== "1") return [];
1569
+ return (url.searchParams.get("hostExternalSpecifiers") ?? "")
1570
+ .split(",")
1571
+ .map((item) => item.trim())
1572
+ .filter(Boolean);
1573
+ }
1574
+
1575
+ function smokeViewByRequest(id, viewType) {
1576
+ return smokeViews.find(
1577
+ (view) => view.id === id && view.viewType === (viewType || "gui"),
1578
+ );
1579
+ }
1580
+
1581
+ function safeComponentExportName(value) {
1582
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(value) ? value : "SmokeView";
1583
+ }
1584
+
1585
+ function smokeTuiViewBundleSource(view, exportName) {
1586
+ const label = JSON.stringify(view.label);
1587
+ const id = JSON.stringify(view.id);
1588
+ const viewType = JSON.stringify(view.viewType);
1589
+ const pluginName = JSON.stringify(view.pluginName);
1590
+ const commands =
1591
+ view.id === "feed"
1592
+ ? [
1593
+ "refresh-agent-status",
1594
+ "refresh-feed",
1595
+ "list-agents",
1596
+ "summarize-feed",
1597
+ ]
1598
+ : ["status", "refresh", "inspect", "help"];
1599
+ return `import React from "react";
1600
+
1601
+ const viewMeta = {
1602
+ id: ${id},
1603
+ label: ${label},
1604
+ viewType: ${viewType},
1605
+ pluginName: ${pluginName}
1606
+ };
1607
+ const commands = ${JSON.stringify(commands)};
1608
+
1609
+ function SmokeView() {
1610
+ const [outputs, setOutputs] = React.useState([]);
1611
+ const runCommand = async (command) => {
1612
+ window.dispatchEvent(new CustomEvent("eliza:tui-command", {
1613
+ detail: { viewId: viewMeta.id, command }
1614
+ }));
1615
+ let result;
1616
+ try {
1617
+ const response = await fetch("/api/views/" + encodeURIComponent(viewMeta.id) + "/interact?viewType=tui", {
1618
+ method: "POST",
1619
+ headers: { "content-type": "application/json" },
1620
+ body: JSON.stringify({ capability: command, timeoutMs: 5000 })
1621
+ });
1622
+ result = await response.json();
1623
+ } catch (error) {
1624
+ result = { ok: false, error: error instanceof Error ? error.message : String(error) };
1625
+ }
1626
+ setOutputs((current) => [...current, { command, result }]);
1627
+ };
1628
+ const state = JSON.stringify({
1629
+ viewId: viewMeta.id,
1630
+ viewType: "tui",
1631
+ status: "ready",
1632
+ fixture: "ui-smoke",
1633
+ commandCount: commands.length
1634
+ });
1635
+ return React.createElement(
1636
+ "div",
1637
+ {
1638
+ "data-view-state": state,
1639
+ style: {
1640
+ minHeight: "100vh",
1641
+ background: "#020617",
1642
+ color: "#cbd5e1",
1643
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
1644
+ padding: 20
1645
+ }
1646
+ },
1647
+ React.createElement("div", { style: { color: "#7dd3fc", marginBottom: 4 } }, "elizaos://" + viewMeta.id + " --type=tui"),
1648
+ React.createElement("div", { style: { color: "#94a3b8", marginBottom: 16 } }, viewMeta.label + " smoke terminal"),
1649
+ React.createElement(
1650
+ "div",
1651
+ { style: { display: "flex", flexWrap: "wrap", gap: 8 } },
1652
+ ...commands.map((command) =>
1653
+ React.createElement(
1654
+ "button",
1655
+ {
1656
+ key: command,
1657
+ type: "button",
1658
+ "data-terminal-command": command,
1659
+ onClick: () => void runCommand(command),
1660
+ style: {
1661
+ border: "1px solid #38bdf8",
1662
+ borderRadius: 4,
1663
+ color: "#e0f2fe",
1664
+ background: "transparent",
1665
+ padding: "6px 10px"
1666
+ }
1667
+ },
1668
+ command
1669
+ )
1670
+ )
1671
+ ),
1672
+ ...outputs.map((entry, index) =>
1673
+ React.createElement(
1674
+ "pre",
1675
+ {
1676
+ key: entry.command + index,
1677
+ "data-terminal-output": entry.result?.ok ? "ok" : "error",
1678
+ style: {
1679
+ marginTop: 8,
1680
+ whiteSpace: "pre-wrap",
1681
+ color: entry.result?.ok ? "#bbf7d0" : "#fecaca"
1682
+ }
1683
+ },
1684
+ "$ " + entry.command + "\\n" + JSON.stringify(entry.result, null, 2)
1685
+ )
1686
+ )
1687
+ );
1688
+ }
1689
+
1690
+ export { SmokeView as ${exportName} };
1691
+ export default SmokeView;
1692
+ export async function interact(capability, params = {}) {
1693
+ return { ok: true, viewId: viewMeta.id, viewType: viewMeta.viewType, capability, params };
1694
+ }
1695
+ `;
1696
+ }
1697
+
1698
+ function smokeScreenshareBundleSource(view, exportName) {
1699
+ const label = JSON.stringify(view.label);
1700
+ const id = JSON.stringify(view.id);
1701
+ const viewType = JSON.stringify(view.viewType);
1702
+ const pluginName = JSON.stringify(view.pluginName);
1703
+ return `import React from "react";
1704
+
1705
+ const viewMeta = {
1706
+ id: ${id},
1707
+ label: ${label},
1708
+ viewType: ${viewType},
1709
+ pluginName: ${pluginName}
1710
+ };
1711
+
1712
+ function maskSession(value) {
1713
+ if (!value) return "";
1714
+ return value.slice(0, 6) + "\\u2026" + value.slice(-4);
1715
+ }
1716
+
1717
+ function maskToken(value) {
1718
+ if (!value) return "";
1719
+ return "\\u2022\\u2022\\u2022\\u2022 " + value.slice(-4);
1720
+ }
1721
+
1722
+ function SmokeView() {
1723
+ const [capabilities, setCapabilities] = React.useState(null);
1724
+ const [host, setHost] = React.useState(null);
1725
+ const [token, setToken] = React.useState("");
1726
+ const [viewerUrl, setViewerUrl] = React.useState("");
1727
+ const [remoteBase, setRemoteBase] = React.useState("");
1728
+ const [remoteSession, setRemoteSession] = React.useState("");
1729
+ const [remoteToken, setRemoteToken] = React.useState("");
1730
+
1731
+ const refreshCapabilities = React.useCallback(async () => {
1732
+ const response = await fetch("/api/apps/screenshare/capabilities");
1733
+ setCapabilities(await response.json());
1734
+ }, []);
1735
+
1736
+ React.useEffect(() => {
1737
+ void refreshCapabilities();
1738
+ }, [refreshCapabilities]);
1739
+
1740
+ const startHost = async () => {
1741
+ const response = await fetch("/api/apps/screenshare/session", {
1742
+ method: "POST",
1743
+ headers: { "content-type": "application/json" },
1744
+ body: JSON.stringify({ label: "This machine" })
1745
+ });
1746
+ const result = await response.json();
1747
+ setHost(result.session);
1748
+ setToken(result.token);
1749
+ setViewerUrl(result.viewerUrl);
1750
+ };
1751
+
1752
+ const copyDetails = async () => {
1753
+ await navigator.clipboard.writeText(JSON.stringify({
1754
+ sessionId: host?.id,
1755
+ token
1756
+ }));
1757
+ };
1758
+
1759
+ const openHostViewer = () => {
1760
+ if (viewerUrl) window.open(viewerUrl);
1761
+ };
1762
+
1763
+ const openRemote = () => {
1764
+ const url = new URL("/api/apps/screenshare/viewer", remoteBase);
1765
+ url.searchParams.set("sessionId", remoteSession);
1766
+ url.searchParams.set("token", remoteToken);
1767
+ url.searchParams.set("remoteBase", remoteBase);
1768
+ window.open(url.toString());
1769
+ };
1770
+
1771
+ const stopHost = async () => {
1772
+ if (!host?.id) return;
1773
+ const response = await fetch("/api/apps/screenshare/session/" + encodeURIComponent(host.id) + "/stop", {
1774
+ method: "POST",
1775
+ headers: {
1776
+ "content-type": "application/json",
1777
+ "x-screenshare-token": token
1778
+ },
1779
+ body: JSON.stringify({ token })
1780
+ });
1781
+ const result = await response.json();
1782
+ setHost(result.session);
1783
+ };
1784
+
1785
+ const capabilityList = capabilities?.capabilities ?? {};
1786
+ return React.createElement(
1787
+ "section",
1788
+ { "aria-label": viewMeta.label, style: { minHeight: "100vh", padding: 24 } },
1789
+ React.createElement("h1", null, viewMeta.label),
1790
+ React.createElement("p", null, viewMeta.pluginName + " dynamic view smoke surface is ready."),
1791
+ React.createElement("h2", null, "Host"),
1792
+ React.createElement("button", { type: "button", onClick: startHost }, "Start host session"),
1793
+ host && React.createElement("button", { type: "button", onClick: copyDetails }, "Copy host details"),
1794
+ host && React.createElement("button", { type: "button", onClick: openHostViewer }, "Open host viewer"),
1795
+ host && React.createElement("button", { type: "button", onClick: stopHost }, "Stop host session"),
1796
+ host && React.createElement("div", null,
1797
+ React.createElement("input", { placeholder: "Session", readOnly: true, value: maskSession(host.id) }),
1798
+ React.createElement("input", { placeholder: "Token", readOnly: true, value: maskToken(token) }),
1799
+ React.createElement("span", null, String(host.frameCount ?? 0)),
1800
+ React.createElement("span", null, String(host.inputCount ?? 0)),
1801
+ React.createElement("span", null, host.status)
1802
+ ),
1803
+ React.createElement("h2", null, "Capabilities"),
1804
+ React.createElement("button", { type: "button", onClick: () => void refreshCapabilities() }, "Refresh capabilities"),
1805
+ React.createElement("div", null,
1806
+ React.createElement("span", null, "Screenshot"),
1807
+ React.createElement("span", null, capabilityList.screenshot?.available ? "Ready" : "Unavailable")
1808
+ ),
1809
+ React.createElement("div", null,
1810
+ React.createElement("span", null, "Keyboard"),
1811
+ React.createElement("span", null, capabilityList.keyboard?.available ? "Ready" : "Unavailable")
1812
+ ),
1813
+ React.createElement("h2", null, "Remote"),
1814
+ React.createElement("input", { placeholder: "Server URL", value: remoteBase, onChange: (event) => setRemoteBase(event.target.value) }),
1815
+ React.createElement("input", { placeholder: "Session", value: remoteSession, onChange: (event) => setRemoteSession(event.target.value) }),
1816
+ React.createElement("input", { placeholder: "Token", value: remoteToken, onChange: (event) => setRemoteToken(event.target.value) }),
1817
+ React.createElement("button", { type: "button", onClick: openRemote }, "Connect to remote")
1818
+ );
1819
+ }
1820
+
1821
+ export { SmokeView as ${exportName} };
1822
+ export default SmokeView;
1823
+ export async function interact(capability, params = {}) {
1824
+ return { ok: true, viewId: viewMeta.id, viewType: viewMeta.viewType, capability, params };
1825
+ }
1826
+ `;
1827
+ }
1828
+
1829
+ function smokeTaskCoordinatorBundleSource(view, exportName) {
1830
+ const label = JSON.stringify(view.label);
1831
+ const id = JSON.stringify(view.id);
1832
+ const viewType = JSON.stringify(view.viewType);
1833
+ const pluginName = JSON.stringify(view.pluginName);
1834
+ return `import React from "react";
1835
+
1836
+ const viewMeta = {
1837
+ id: ${id},
1838
+ label: ${label},
1839
+ viewType: ${viewType},
1840
+ pluginName: ${pluginName}
1841
+ };
1842
+
1843
+ function statusLabel(thread) {
1844
+ return String(thread?.status ?? "open").replace(/_/g, " ");
1845
+ }
1846
+
1847
+ function SmokeView() {
1848
+ const [tasks, setTasks] = React.useState([]);
1849
+ const [detail, setDetail] = React.useState(null);
1850
+ const [search, setSearch] = React.useState("");
1851
+
1852
+ const loadTasks = React.useCallback(async (nextSearch = search) => {
1853
+ const url = new URL("/api/orchestrator/tasks", window.location.origin);
1854
+ url.searchParams.set("limit", "50");
1855
+ if (nextSearch) url.searchParams.set("search", nextSearch);
1856
+ const response = await fetch(url.pathname + url.search);
1857
+ const result = await response.json();
1858
+ setTasks(result.tasks ?? []);
1859
+ }, [search]);
1860
+
1861
+ React.useEffect(() => {
1862
+ void loadTasks("");
1863
+ }, []);
1864
+
1865
+ const updateSearch = (value) => {
1866
+ setSearch(value);
1867
+ void loadTasks(value);
1868
+ };
1869
+
1870
+ const openTask = async (task) => {
1871
+ const response = await fetch("/api/orchestrator/tasks/" + encodeURIComponent(task.id));
1872
+ setDetail(await response.json());
1873
+ };
1874
+
1875
+ const archiveTask = async () => {
1876
+ if (!detail?.id) return;
1877
+ await fetch("/api/orchestrator/tasks/" + encodeURIComponent(detail.id) + "/archive", { method: "POST" });
1878
+ await loadTasks(search);
1879
+ };
1880
+
1881
+ const reopenTask = async () => {
1882
+ if (!detail?.id) return;
1883
+ await fetch("/api/orchestrator/tasks/" + encodeURIComponent(detail.id) + "/reopen", { method: "POST" });
1884
+ const response = await fetch("/api/orchestrator/tasks/" + encodeURIComponent(detail.id));
1885
+ setDetail(await response.json());
1886
+ await loadTasks(search);
1887
+ };
1888
+
1889
+ return React.createElement(
1890
+ "section",
1891
+ {
1892
+ "aria-label": viewMeta.label,
1893
+ "data-testid": "chat-widget-orchestrator",
1894
+ style: { minHeight: "100vh", padding: 24 }
1895
+ },
1896
+ React.createElement("h1", null, viewMeta.label),
1897
+ React.createElement("p", null, viewMeta.pluginName + " dynamic view smoke surface is ready."),
1898
+ React.createElement("input", {
1899
+ placeholder: "Search tasks",
1900
+ value: search,
1901
+ onChange: (event) => updateSearch(event.target.value)
1902
+ }),
1903
+ React.createElement(
1904
+ "div",
1905
+ null,
1906
+ ...tasks.map((task) =>
1907
+ React.createElement(
1908
+ "button",
1909
+ {
1910
+ key: task.id,
1911
+ type: "button",
1912
+ onClick: () => void openTask(task),
1913
+ style: { display: "block", marginTop: 8 }
1914
+ },
1915
+ task.title + " " + statusLabel(task)
1916
+ )
1917
+ )
1918
+ ),
1919
+ detail && React.createElement(
1920
+ "article",
1921
+ { "aria-label": "Task detail", style: { marginTop: 16 } },
1922
+ React.createElement("h2", null, detail.title),
1923
+ React.createElement("p", null, detail.summary ?? detail.originalRequest ?? ""),
1924
+ ...(detail.acceptanceCriteria ?? []).map((item) => React.createElement("p", { key: item }, item)),
1925
+ ...(detail.sessions ?? []).map((session) =>
1926
+ React.createElement(
1927
+ "div",
1928
+ { key: session.id },
1929
+ React.createElement("span", null, session.label),
1930
+ React.createElement("span", null, (session.framework ?? "") + " (" + (session.providerSource ?? "") + ")")
1931
+ )
1932
+ ),
1933
+ ...(detail.artifacts ?? []).map((artifact) => React.createElement("p", { key: artifact.id }, artifact.title)),
1934
+ ...(detail.pendingDecisions ?? []).map((decision) => React.createElement("p", { key: decision.sessionId }, decision.promptText)),
1935
+ ...(detail.events ?? []).map((event) => React.createElement("p", { key: event.id }, event.summary)),
1936
+ ...(detail.transcripts ?? []).map((transcript) => React.createElement("p", { key: transcript.id }, transcript.content)),
1937
+ detail.status === "archived"
1938
+ ? React.createElement("button", { type: "button", onClick: () => void reopenTask() }, "Reopen")
1939
+ : React.createElement("button", { type: "button", onClick: () => void archiveTask() }, "Delete")
1940
+ )
1941
+ );
1942
+ }
1943
+
1944
+ export { SmokeView as ${exportName} };
1945
+ export default SmokeView;
1946
+ export async function interact(capability, params = {}) {
1947
+ return { ok: true, viewId: viewMeta.id, viewType: viewMeta.viewType, capability, params };
1948
+ }
1949
+ `;
1950
+ }
1951
+
1952
+ function smokeGenericViewBundleSource(view, exportName) {
1953
+ const label = JSON.stringify(view.label);
1954
+ const id = JSON.stringify(view.id);
1955
+ const viewType = JSON.stringify(view.viewType);
1956
+ const pluginName = JSON.stringify(view.pluginName);
1957
+ return `import React from "react";
1958
+
1959
+ const viewMeta = {
1960
+ id: ${id},
1961
+ label: ${label},
1962
+ viewType: ${viewType},
1963
+ pluginName: ${pluginName}
1964
+ };
1965
+
1966
+ function SmokeView() {
1967
+ return React.createElement(
1968
+ "section",
1969
+ { "aria-label": viewMeta.label, style: { minHeight: "100vh", padding: 24 } },
1970
+ React.createElement("h1", null, viewMeta.label),
1971
+ React.createElement("p", null, viewMeta.pluginName + " dynamic view smoke surface is ready."),
1972
+ React.createElement("button", { type: "button" }, "Refresh view"),
1973
+ React.createElement("input", { "aria-label": viewMeta.label + " input", defaultValue: viewMeta.id })
1974
+ );
1975
+ }
1976
+
1977
+ export { SmokeView as ${exportName} };
1978
+ export default SmokeView;
1979
+ export async function interact(capability, params = {}) {
1980
+ return { ok: true, viewId: viewMeta.id, viewType: viewMeta.viewType, capability, params };
1981
+ }
1982
+ `;
1983
+ }
1984
+
1985
+ function smokeViewBundleSource(view) {
1986
+ const exportName = safeComponentExportName(view.componentExport);
1987
+ if (view.viewType === "tui") {
1988
+ return smokeTuiViewBundleSource(view, exportName);
1989
+ }
1990
+ if (view.id === "screenshare") {
1991
+ return smokeScreenshareBundleSource(view, exportName);
1992
+ }
1993
+ if (view.id === "task-coordinator") {
1994
+ return smokeTaskCoordinatorBundleSource(view, exportName);
1995
+ }
1996
+ return smokeGenericViewBundleSource(view, exportName);
1997
+ }
1998
+
1999
+ function sendSmokeViewAsset(req, res, url, view, subResource) {
2000
+ const bundleDir = path.join(
2001
+ repoRoot,
2002
+ "plugins",
2003
+ view._smokePluginDirName,
2004
+ "dist",
2005
+ "views",
2006
+ );
2007
+ const assetPath = path.resolve(bundleDir, decodeURIComponent(subResource));
2008
+ const relative = path.relative(bundleDir, assetPath);
2009
+ if (
2010
+ relative.startsWith("..") ||
2011
+ path.isAbsolute(relative) ||
2012
+ relative === ""
2013
+ ) {
2014
+ sendJson(req, res, 400, { error: "Malformed view asset path" });
2015
+ return;
2016
+ }
2017
+ const hostExternalSpecifiers = parseHostExternalSpecifiers(url);
2018
+ if (!existsSync(assetPath)) {
2019
+ if (subResource === "bundle.js") {
2020
+ const source = smokeViewBundleSource(view);
2021
+ const body =
2022
+ hostExternalSpecifiers.length > 0
2023
+ ? rewriteHostExternalImports(source, hostExternalSpecifiers)
2024
+ : source;
2025
+ sendBinary(
2026
+ req,
2027
+ res,
2028
+ 200,
2029
+ "application/javascript; charset=utf-8",
2030
+ Buffer.from(body, "utf8"),
2031
+ );
2032
+ return;
2033
+ }
2034
+ sendJson(req, res, 404, { error: `View asset not found: ${subResource}` });
2035
+ return;
2036
+ }
2037
+ const rawBody = readFileSync(assetPath);
2038
+ const body =
2039
+ hostExternalSpecifiers.length > 0 &&
2040
+ contentTypeForSmokeViewAsset(assetPath).startsWith("application/javascript")
2041
+ ? Buffer.from(
2042
+ rewriteHostExternalImports(
2043
+ rawBody.toString("utf8"),
2044
+ hostExternalSpecifiers,
2045
+ ),
2046
+ "utf8",
2047
+ )
2048
+ : rawBody;
2049
+ sendBinary(req, res, 200, contentTypeForSmokeViewAsset(assetPath), body);
2050
+ }
2051
+
881
2052
  function sendSseHeaders(req, res) {
882
2053
  applyCors(req, res);
883
2054
  res.writeHead(200, {
@@ -892,6 +2063,15 @@ function writeSseEvent(res, payload) {
892
2063
  res.write(`data: ${JSON.stringify(payload)}\n\n`);
893
2064
  }
894
2065
 
2066
+ function sendReadySseStream(req, res) {
2067
+ sendSseHeaders(req, res);
2068
+ writeSseEvent(res, { type: "ready" });
2069
+ const interval = setInterval(() => {
2070
+ res.write(": heartbeat\n\n");
2071
+ }, 15_000);
2072
+ req.on("close", () => clearInterval(interval));
2073
+ }
2074
+
895
2075
  async function readJsonBody(req) {
896
2076
  const chunks = [];
897
2077
  for await (const chunk of req) {
@@ -903,6 +2083,17 @@ async function readJsonBody(req) {
903
2083
  return JSON.parse(Buffer.concat(chunks).toString("utf8"));
904
2084
  }
905
2085
 
2086
+ // Consume and discard a request body (binary or irrelevant) so the socket
2087
+ // drains cleanly before the response is sent.
2088
+ async function drainRequest(req) {
2089
+ await new Promise((resolve) => {
2090
+ req.on("data", () => {});
2091
+ req.on("end", resolve);
2092
+ req.on("error", resolve);
2093
+ req.resume();
2094
+ });
2095
+ }
2096
+
906
2097
  function workbenchOverview() {
907
2098
  return {
908
2099
  tasks: [],
@@ -923,140 +2114,1621 @@ function workbenchOverview() {
923
2114
  };
924
2115
  }
925
2116
 
926
- function streamSettings(payload = {}) {
2117
+ const emptyOrchestratorUsage = {
2118
+ inputTokens: 0,
2119
+ outputTokens: 0,
2120
+ reasoningTokens: 0,
2121
+ cacheTokens: 0,
2122
+ totalTokens: 0,
2123
+ costUsd: 0,
2124
+ state: "unavailable",
2125
+ byProvider: [],
2126
+ };
2127
+
2128
+ function emptyOrchestratorStatus() {
927
2129
  return {
928
- ok: true,
929
- settings: {
930
- theme: "eliza",
931
- avatarIndex: 0,
932
- ...payload,
2130
+ taskCount: 0,
2131
+ activeTaskCount: 0,
2132
+ pausedTaskCount: 0,
2133
+ blockedTaskCount: 0,
2134
+ validatingTaskCount: 0,
2135
+ sessionCount: 0,
2136
+ activeSessionCount: 0,
2137
+ usage: emptyOrchestratorUsage,
2138
+ byStatus: {
2139
+ open: 0,
2140
+ active: 0,
2141
+ waiting_on_user: 0,
2142
+ blocked: 0,
2143
+ validating: 0,
2144
+ done: 0,
2145
+ failed: 0,
2146
+ archived: 0,
2147
+ interrupted: 0,
933
2148
  },
934
2149
  };
935
2150
  }
936
2151
 
937
- const sockets = new Set();
938
- const server = http.createServer(async (req, res) => {
939
- const url = new URL(
940
- req.url ?? "/",
941
- `http://${req.headers.host ?? `127.0.0.1:${port}`}`,
942
- );
2152
+ function emptyTrajectoryList(url) {
2153
+ return {
2154
+ trajectories: [],
2155
+ total: 0,
2156
+ offset: Number(url.searchParams.get("offset") ?? 0),
2157
+ limit: Number(url.searchParams.get("limit") ?? 50),
2158
+ };
2159
+ }
943
2160
 
944
- if (req.method === "OPTIONS") {
945
- sendEmpty(req, res, 204);
946
- return;
947
- }
2161
+ function orchestratorUsage(overrides = {}) {
2162
+ const createdAt = overrides.createdAt ?? new Date().toISOString();
2163
+ return {
2164
+ inputTokens: 0,
2165
+ outputTokens: 0,
2166
+ reasoningTokens: 0,
2167
+ cacheTokens: 0,
2168
+ totalTokens: 0,
2169
+ costUsd: 0,
2170
+ state: "unavailable",
2171
+ usageState: "unavailable",
2172
+ byProvider: [],
2173
+ metadata: {},
2174
+ createdAt,
2175
+ updatedAt: overrides.updatedAt ?? createdAt,
2176
+ ...overrides,
2177
+ };
2178
+ }
948
2179
 
949
- if (req.method === "HEAD" && url.pathname === "/api/avatar/vrm") {
950
- sendEmpty(req, res, 404);
951
- return;
952
- }
2180
+ function createDemoOrchestratorState() {
2181
+ const startedAtMs = Date.now();
2182
+ const startedAt = new Date(startedAtMs).toISOString();
2183
+ const richUsage = orchestratorUsage({
2184
+ inputTokens: 8400,
2185
+ outputTokens: 2600,
2186
+ reasoningTokens: 1345,
2187
+ totalTokens: 12_345,
2188
+ costUsd: 0.42,
2189
+ state: "measured",
2190
+ usageState: "measured",
2191
+ byProvider: [
2192
+ {
2193
+ provider: "cerebras",
2194
+ model: "gpt-oss-120b",
2195
+ inputTokens: 8400,
2196
+ outputTokens: 2600,
2197
+ reasoningTokens: 1345,
2198
+ cacheTokens: 0,
2199
+ totalTokens: 12_345,
2200
+ costUsd: 0.42,
2201
+ state: "measured",
2202
+ },
2203
+ {
2204
+ provider: "codex",
2205
+ model: "codex-cli",
2206
+ inputTokens: 1200,
2207
+ outputTokens: 900,
2208
+ reasoningTokens: 0,
2209
+ cacheTokens: 0,
2210
+ totalTokens: 2100,
2211
+ costUsd: 0,
2212
+ state: "estimated",
2213
+ },
2214
+ ],
2215
+ createdAt: startedAt,
2216
+ updatedAt: startedAt,
2217
+ });
2218
+ const detail = createDemoTaskDetail({
2219
+ id: "smoke-task-1",
2220
+ title: "Build Kanban planner app",
2221
+ status: "active",
2222
+ priority: "urgent",
2223
+ goal: "Build and verify a tiny Kanban planner app with accessible columns, cards, and persistence.",
2224
+ originalRequest:
2225
+ "Use Codex plus Cerebras gpt-oss-120b to build a planner app.",
2226
+ summary: "Codex has generated files; Cerebras is reviewing UX.",
2227
+ sessionCount: 2,
2228
+ activeSessionCount: 2,
2229
+ latestSessionId: "session-codex",
2230
+ latestSessionLabel: "Codex Builder",
2231
+ latestWorkdir: "/tmp/orchestrator-kanban",
2232
+ latestRepo: "/home/nubs/Git/iqlabs/eliza-labs/eliza",
2233
+ latestActivityAt: startedAtMs,
2234
+ createdAt: startedAt,
2235
+ updatedAt: startedAt,
2236
+ acceptanceCriteria: [
2237
+ "Planner renders three workflow columns",
2238
+ "Cards can be created and moved",
2239
+ "Generated files pass syntax checks",
2240
+ ],
2241
+ currentPlan: {
2242
+ summary: "Build, review, and verify the Kanban planner.",
2243
+ steps: [
2244
+ { title: "Generate app shell", status: "completed" },
2245
+ { title: "Review visual affordances", status: "in_progress" },
2246
+ { title: "Run browser smoke checks", status: "pending" },
2247
+ ],
2248
+ },
2249
+ planRevisions: [
2250
+ {
2251
+ id: "plan-rev-1",
2252
+ threadId: "smoke-task-1",
2253
+ plan: {
2254
+ summary: "Build, review, and verify the Kanban planner.",
2255
+ steps: [
2256
+ { title: "Generate app shell", status: "completed" },
2257
+ { title: "Review visual affordances", status: "in_progress" },
2258
+ { title: "Run browser smoke checks", status: "pending" },
2259
+ ],
2260
+ },
2261
+ basePlanRevisionId: null,
2262
+ editSummary: null,
2263
+ createdBy: "system",
2264
+ metadata: {},
2265
+ timestamp: startedAtMs,
2266
+ createdAt: startedAt,
2267
+ },
2268
+ ],
2269
+ providerPolicy: {
2270
+ preferredFramework: "codex",
2271
+ providerSource: "cerebras",
2272
+ model: "gpt-oss-120b",
2273
+ },
2274
+ sessions: [
2275
+ {
2276
+ id: "session-codex-record",
2277
+ threadId: "smoke-task-1",
2278
+ sessionId: "session-codex",
2279
+ label: "Codex Builder",
2280
+ status: "running",
2281
+ framework: "codex",
2282
+ providerSource: "local-auth",
2283
+ model: "codex-cli",
2284
+ originalTask:
2285
+ "Generate the planner shell and persist card movement locally.",
2286
+ workdir: "/tmp/orchestrator-kanban",
2287
+ repo: "/home/nubs/Git/iqlabs/eliza-labs/eliza",
2288
+ activeTool: "write",
2289
+ decisionCount: 0,
2290
+ autoResolvedCount: 0,
2291
+ registeredAt: startedAtMs,
2292
+ lastActivityAt: startedAtMs,
2293
+ idleCheckCount: 0,
2294
+ taskDelivered: true,
2295
+ completionSummary: null,
2296
+ lastSeenDecisionIndex: 0,
2297
+ lastInputSentAt: null,
2298
+ stoppedAt: null,
2299
+ inputTokens: 1200,
2300
+ outputTokens: 900,
2301
+ reasoningTokens: 0,
2302
+ totalTokens: 2100,
2303
+ cacheTokens: 0,
2304
+ costUsd: 0,
2305
+ usageState: "estimated",
2306
+ metadata: {},
2307
+ createdAt: startedAt,
2308
+ updatedAt: startedAt,
2309
+ },
2310
+ {
2311
+ id: "session-cerebras-record",
2312
+ threadId: "smoke-task-1",
2313
+ sessionId: "session-cerebras",
2314
+ label: "Cerebras Reviewer",
2315
+ status: "running",
2316
+ framework: "eliza",
2317
+ providerSource: "cerebras",
2318
+ model: "gpt-oss-120b",
2319
+ originalTask:
2320
+ "Review the planner visual affordances and interaction model.",
2321
+ workdir: "/tmp/orchestrator-kanban",
2322
+ repo: "/home/nubs/Git/iqlabs/eliza-labs/eliza",
2323
+ activeTool: "review",
2324
+ decisionCount: 0,
2325
+ autoResolvedCount: 0,
2326
+ registeredAt: startedAtMs,
2327
+ lastActivityAt: startedAtMs,
2328
+ idleCheckCount: 0,
2329
+ taskDelivered: true,
2330
+ completionSummary: null,
2331
+ lastSeenDecisionIndex: 0,
2332
+ lastInputSentAt: null,
2333
+ stoppedAt: null,
2334
+ inputTokens: 8400,
2335
+ outputTokens: 2600,
2336
+ reasoningTokens: 1345,
2337
+ totalTokens: 12_345,
2338
+ cacheTokens: 0,
2339
+ costUsd: 0.42,
2340
+ usageState: "measured",
2341
+ metadata: {},
2342
+ createdAt: startedAt,
2343
+ updatedAt: startedAt,
2344
+ },
2345
+ ],
2346
+ artifacts: [
2347
+ {
2348
+ id: "artifact-index",
2349
+ threadId: "smoke-task-1",
2350
+ sessionId: "session-codex",
2351
+ title: "Kanban planner HTML",
2352
+ artifactType: "file",
2353
+ path: "planner/index.html",
2354
+ uri: null,
2355
+ mimeType: "text/html",
2356
+ verificationStatus: "passed",
2357
+ metadata: {},
2358
+ createdAt: startedAt,
2359
+ },
2360
+ {
2361
+ id: "artifact-test",
2362
+ threadId: "smoke-task-1",
2363
+ sessionId: "session-cerebras",
2364
+ title: "Browser smoke report",
2365
+ artifactType: "verification",
2366
+ path: "reports/kanban-smoke.md",
2367
+ uri: null,
2368
+ mimeType: "text/markdown",
2369
+ verificationStatus: "pending",
2370
+ metadata: {},
2371
+ createdAt: startedAt,
2372
+ },
2373
+ ],
2374
+ usage: richUsage,
2375
+ });
2376
+
2377
+ return {
2378
+ tasks: [detail],
2379
+ messages: [
2380
+ {
2381
+ id: "message-user-1",
2382
+ threadId: "smoke-task-1",
2383
+ sessionId: null,
2384
+ senderKind: "user",
2385
+ direction: "stdout",
2386
+ content: "Create a compact Kanban planner app.",
2387
+ timestamp: startedAtMs - 4000,
2388
+ metadata: {},
2389
+ createdAt: new Date(startedAtMs - 4000).toISOString(),
2390
+ },
2391
+ {
2392
+ id: "message-agent-1",
2393
+ threadId: "smoke-task-1",
2394
+ sessionId: "session-codex",
2395
+ senderKind: "sub_agent",
2396
+ direction: "stdout",
2397
+ content: "Generated the planner shell and wired card movement.",
2398
+ timestamp: startedAtMs - 2000,
2399
+ metadata: {},
2400
+ createdAt: new Date(startedAtMs - 2000).toISOString(),
2401
+ },
2402
+ ],
2403
+ events: [
2404
+ {
2405
+ id: "event-tool-write",
2406
+ threadId: "smoke-task-1",
2407
+ sessionId: "session-codex",
2408
+ eventType: "tool_running",
2409
+ summary: "write planner files",
2410
+ timestamp: startedAtMs - 1000,
2411
+ data: {
2412
+ toolCall: {
2413
+ id: "tool-write-index",
2414
+ title: "write",
2415
+ kind: "edit",
2416
+ status: "completed",
2417
+ rawInput: {
2418
+ path: "planner/index.html",
2419
+ content: '<main id="board"></main>',
2420
+ },
2421
+ output: "Wrote planner/index.html",
2422
+ },
2423
+ },
2424
+ createdAt: new Date(startedAtMs - 1000).toISOString(),
2425
+ },
2426
+ {
2427
+ id: "event-validation",
2428
+ threadId: "smoke-task-1",
2429
+ sessionId: "session-cerebras",
2430
+ eventType: "task_registered",
2431
+ summary: "Cerebras reviewer joined for UX validation",
2432
+ timestamp: startedAtMs - 500,
2433
+ data: {},
2434
+ createdAt: new Date(startedAtMs - 500).toISOString(),
2435
+ },
2436
+ ],
2437
+ nextTaskId: 2,
2438
+ nextMessageId: 2,
2439
+ nextEventId: 2,
2440
+ nextSessionId: 3,
2441
+ };
2442
+ }
2443
+
2444
+ function createDemoTaskDetail(overrides = {}) {
2445
+ const id = overrides.id ?? "smoke-task-1";
2446
+ const createdAt = overrides.createdAt ?? new Date().toISOString();
2447
+ return {
2448
+ id,
2449
+ title: "Audit orchestrator surface",
2450
+ kind: "coding",
2451
+ status: "open",
2452
+ priority: "high",
2453
+ paused: false,
2454
+ originalRequest: "Audit orchestrator surface",
2455
+ summary: "Created by ui-smoke demo mode.",
2456
+ sessionCount: 0,
2457
+ activeSessionCount: 0,
2458
+ latestSessionId: null,
2459
+ latestSessionLabel: null,
2460
+ latestWorkdir: null,
2461
+ latestRepo: null,
2462
+ latestActivityAt: null,
2463
+ decisionCount: 0,
2464
+ usage: orchestratorUsage(),
2465
+ createdAt,
2466
+ updatedAt: overrides.updatedAt ?? createdAt,
2467
+ closedAt: null,
2468
+ archivedAt: null,
2469
+ goal: "Verify controls, routing, and message flow.",
2470
+ roomId: null,
2471
+ taskRoomId: null,
2472
+ worldId: null,
2473
+ ownerUserId: null,
2474
+ parentTaskId: null,
2475
+ acceptanceCriteria: ["Task appears in rail", "Message posts"],
2476
+ currentPlan: null,
2477
+ providerPolicy: null,
2478
+ lastUserTurnAt: null,
2479
+ lastCoordinatorTurnAt: null,
2480
+ metadata: {},
2481
+ sessions: [],
2482
+ decisions: [],
2483
+ events: [],
2484
+ artifacts: [],
2485
+ messages: [],
2486
+ transcripts: [],
2487
+ planRevisions: [],
2488
+ ...overrides,
2489
+ };
2490
+ }
2491
+
2492
+ function summarizeDemoTask(detail) {
2493
+ return {
2494
+ id: detail.id,
2495
+ title: detail.title,
2496
+ kind: detail.kind,
2497
+ status: detail.status,
2498
+ priority: detail.priority,
2499
+ paused: detail.paused,
2500
+ originalRequest: detail.originalRequest,
2501
+ summary: detail.summary,
2502
+ sessionCount: detail.sessionCount,
2503
+ activeSessionCount: detail.activeSessionCount,
2504
+ latestSessionId: detail.latestSessionId,
2505
+ latestSessionLabel: detail.latestSessionLabel,
2506
+ latestWorkdir: detail.latestWorkdir,
2507
+ latestRepo: detail.latestRepo,
2508
+ latestActivityAt: detail.latestActivityAt,
2509
+ decisionCount: detail.decisionCount,
2510
+ usage: detail.usage,
2511
+ createdAt: detail.createdAt,
2512
+ updatedAt: detail.updatedAt,
2513
+ closedAt: detail.closedAt,
2514
+ archivedAt: detail.archivedAt,
2515
+ };
2516
+ }
2517
+
2518
+ function demoOrchestratorStatus(state) {
2519
+ const visibleTasks = state.tasks;
2520
+ const byStatus = {
2521
+ open: 0,
2522
+ active: 0,
2523
+ waiting_on_user: 0,
2524
+ blocked: 0,
2525
+ validating: 0,
2526
+ done: 0,
2527
+ failed: 0,
2528
+ archived: 0,
2529
+ interrupted: 0,
2530
+ };
2531
+ let sessionCount = 0;
2532
+ let activeSessionCount = 0;
2533
+ for (const task of visibleTasks) {
2534
+ if (byStatus[task.status] !== undefined) byStatus[task.status] += 1;
2535
+ sessionCount += Number(task.sessionCount ?? 0);
2536
+ activeSessionCount += Number(task.activeSessionCount ?? 0);
2537
+ }
2538
+ return {
2539
+ taskCount: visibleTasks.length,
2540
+ activeTaskCount: byStatus.active,
2541
+ pausedTaskCount: visibleTasks.filter((task) => task.paused === true).length,
2542
+ blockedTaskCount: byStatus.blocked + byStatus.waiting_on_user,
2543
+ validatingTaskCount: byStatus.validating,
2544
+ sessionCount,
2545
+ activeSessionCount,
2546
+ usage: visibleTasks[0]?.usage ?? emptyOrchestratorUsage,
2547
+ byStatus,
2548
+ };
2549
+ }
2550
+
2551
+ function demoTaskList(state, url) {
2552
+ const status = url.searchParams.get("status");
2553
+ const includeArchived = url.searchParams.get("includeArchived") === "true";
2554
+ const search = (url.searchParams.get("search") ?? "").toLowerCase();
2555
+ const limit = Math.max(1, Number(url.searchParams.get("limit") ?? 50));
2556
+ return state.tasks
2557
+ .filter((task) => includeArchived || task.status !== "archived")
2558
+ .filter((task) => !status || task.status === status)
2559
+ .filter((task) => {
2560
+ if (!search) return true;
2561
+ return [task.title, task.goal, task.summary, task.originalRequest]
2562
+ .join(" ")
2563
+ .toLowerCase()
2564
+ .includes(search);
2565
+ })
2566
+ .slice(0, limit)
2567
+ .map(summarizeDemoTask);
2568
+ }
2569
+
2570
+ function demoTimelinePage(state, taskId, url) {
2571
+ const limit =
2572
+ Math.max(1, Number.parseInt(url.searchParams.get("limit") ?? "100", 10)) ||
2573
+ 100;
2574
+ const start =
2575
+ Math.max(0, Number.parseInt(url.searchParams.get("cursor") ?? "0", 10)) ||
2576
+ 0;
2577
+ const items = [
2578
+ ...state.messages
2579
+ .filter((message) => message.threadId === taskId)
2580
+ .map((message) => ({
2581
+ id: `message:${message.id}`,
2582
+ kind: "message",
2583
+ threadId: message.threadId,
2584
+ sessionId: message.sessionId ?? null,
2585
+ timestamp: message.timestamp,
2586
+ createdAt: message.createdAt,
2587
+ message,
2588
+ })),
2589
+ ...state.events
2590
+ .filter((event) => event.threadId === taskId)
2591
+ .map((event) => ({
2592
+ id: `event:${event.id}`,
2593
+ kind: "event",
2594
+ threadId: event.threadId,
2595
+ sessionId: event.sessionId ?? null,
2596
+ timestamp: event.timestamp,
2597
+ createdAt: event.createdAt,
2598
+ event,
2599
+ })),
2600
+ ].sort((a, b) => Number(b.timestamp) - Number(a.timestamp));
2601
+ const page = items.slice(start, start + limit);
2602
+ const next = start + limit;
2603
+ return {
2604
+ items: page,
2605
+ nextCursor: next < items.length ? String(next) : null,
2606
+ };
2607
+ }
2608
+
2609
+ function pushDemoEvent(state, taskId, summary, data = {}) {
2610
+ const event = {
2611
+ id: `demo-event-${state.nextEventId++}`,
2612
+ threadId: taskId,
2613
+ sessionId: null,
2614
+ eventType: "operator_action",
2615
+ summary,
2616
+ timestamp: Date.now(),
2617
+ data,
2618
+ createdAt: new Date().toISOString(),
2619
+ };
2620
+ state.events.push(event);
2621
+ return event;
2622
+ }
2623
+
2624
+ function pushDemoMessage(state, taskId, senderKind, content, sessionId = null) {
2625
+ const message = {
2626
+ id: `demo-message-${state.nextMessageId++}`,
2627
+ threadId: taskId,
2628
+ sessionId,
2629
+ senderKind,
2630
+ direction: "stdout",
2631
+ content,
2632
+ timestamp: Date.now(),
2633
+ metadata: {},
2634
+ createdAt: new Date().toISOString(),
2635
+ };
2636
+ state.messages.push(message);
2637
+ return message;
2638
+ }
2639
+
2640
+ const demoOrchestratorState = DEMO_ORCHESTRATOR
2641
+ ? createDemoOrchestratorState()
2642
+ : null;
2643
+
2644
+ async function handleDemoOrchestratorRoute(req, res, url) {
2645
+ if (!demoOrchestratorState) return false;
2646
+ if (!url.pathname.startsWith("/api/orchestrator")) return false;
2647
+
2648
+ if (req.method === "GET" && url.pathname === "/api/orchestrator/status") {
2649
+ sendJson(req, res, 200, demoOrchestratorStatus(demoOrchestratorState));
2650
+ return true;
2651
+ }
2652
+
2653
+ if (req.method === "GET" && url.pathname === "/api/orchestrator/tasks") {
2654
+ sendJson(req, res, 200, {
2655
+ tasks: demoTaskList(demoOrchestratorState, url),
2656
+ });
2657
+ return true;
2658
+ }
2659
+
2660
+ if (req.method === "POST" && url.pathname === "/api/orchestrator/tasks") {
2661
+ const body = (await readJsonBody(req)) || {};
2662
+ const id = `demo-task-${demoOrchestratorState.nextTaskId++}`;
2663
+ const detail = createDemoTaskDetail({
2664
+ id,
2665
+ title: body.title || "Demo orchestrator task",
2666
+ goal: body.goal || body.originalRequest || body.title || "Demo task",
2667
+ originalRequest:
2668
+ body.originalRequest || body.goal || body.title || "Demo task",
2669
+ priority: body.priority || "normal",
2670
+ acceptanceCriteria: Array.isArray(body.acceptanceCriteria)
2671
+ ? body.acceptanceCriteria
2672
+ : ["Created from the visible local UI"],
2673
+ providerPolicy: body.providerPolicy ?? null,
2674
+ status: "open",
2675
+ summary: "Created locally in demo mode.",
2676
+ currentPlan: {
2677
+ summary: "Demo task created from the local UI.",
2678
+ steps: [
2679
+ { title: "Capture request", status: "completed" },
2680
+ { title: "Assign sub-agent", status: "pending" },
2681
+ { title: "Verify result", status: "pending" },
2682
+ ],
2683
+ },
2684
+ });
2685
+ demoOrchestratorState.tasks.unshift(detail);
2686
+ pushDemoMessage(
2687
+ demoOrchestratorState,
2688
+ id,
2689
+ "user",
2690
+ detail.originalRequest || detail.goal,
2691
+ );
2692
+ pushDemoEvent(demoOrchestratorState, id, "Task created from local demo UI");
2693
+ sendJson(req, res, 200, detail);
2694
+ return true;
2695
+ }
2696
+
2697
+ if (req.method === "POST" && url.pathname === "/api/orchestrator/pause-all") {
2698
+ for (const task of demoOrchestratorState.tasks) task.paused = true;
2699
+ sendJson(req, res, 200, { paused: demoOrchestratorState.tasks.length });
2700
+ return true;
2701
+ }
2702
+
2703
+ if (
2704
+ req.method === "POST" &&
2705
+ url.pathname === "/api/orchestrator/resume-all"
2706
+ ) {
2707
+ for (const task of demoOrchestratorState.tasks) task.paused = false;
2708
+ sendJson(req, res, 200, { resumed: demoOrchestratorState.tasks.length });
2709
+ return true;
2710
+ }
2711
+
2712
+ const taskPath = url.pathname.slice("/api/orchestrator/tasks/".length);
2713
+ if (!taskPath || taskPath === url.pathname) return false;
2714
+ const parts = taskPath.split("/").map((part) => decodeURIComponent(part));
2715
+ const [taskId, action, subId, subAction] = parts;
2716
+ const task = demoOrchestratorState.tasks.find((item) => item.id === taskId);
2717
+
2718
+ if (action === "stream" && req.method === "GET") {
2719
+ sendReadySseStream(req, res);
2720
+ return true;
2721
+ }
2722
+
2723
+ if (!task) {
2724
+ sendJson(req, res, 404, { error: `Task not found: ${taskId}` });
2725
+ return true;
2726
+ }
2727
+
2728
+ if (!action) {
2729
+ if (req.method === "GET") {
2730
+ sendJson(req, res, 200, task);
2731
+ return true;
2732
+ }
2733
+ if (req.method === "PATCH") {
2734
+ const body = (await readJsonBody(req)) || {};
2735
+ Object.assign(task, body, { updatedAt: new Date().toISOString() });
2736
+ sendJson(req, res, 200, task);
2737
+ return true;
2738
+ }
2739
+ if (req.method === "DELETE") {
2740
+ demoOrchestratorState.tasks = demoOrchestratorState.tasks.filter(
2741
+ (item) => item.id !== taskId,
2742
+ );
2743
+ demoOrchestratorState.messages = demoOrchestratorState.messages.filter(
2744
+ (item) => item.threadId !== taskId,
2745
+ );
2746
+ demoOrchestratorState.events = demoOrchestratorState.events.filter(
2747
+ (item) => item.threadId !== taskId,
2748
+ );
2749
+ sendJson(req, res, 200, { deleted: true });
2750
+ return true;
2751
+ }
2752
+ }
2753
+
2754
+ if (action === "messages") {
2755
+ if (req.method === "GET") {
2756
+ sendJson(req, res, 200, {
2757
+ items: demoOrchestratorState.messages.filter(
2758
+ (item) => item.threadId === taskId,
2759
+ ),
2760
+ nextCursor: null,
2761
+ });
2762
+ return true;
2763
+ }
2764
+ if (req.method === "POST") {
2765
+ const body = (await readJsonBody(req)) || {};
2766
+ const content = String(body.content ?? "").trim();
2767
+ if (content) {
2768
+ pushDemoMessage(demoOrchestratorState, taskId, "user", content);
2769
+ pushDemoMessage(
2770
+ demoOrchestratorState,
2771
+ taskId,
2772
+ "orchestrator",
2773
+ `Demo orchestrator received: ${content}`,
2774
+ );
2775
+ pushDemoEvent(demoOrchestratorState, taskId, "Message forwarded");
2776
+ task.summary = "New demo message received from the local UI.";
2777
+ task.updatedAt = new Date().toISOString();
2778
+ }
2779
+ sendJson(req, res, 200, { recorded: true, forwardedTo: [] });
2780
+ return true;
2781
+ }
2782
+ }
2783
+
2784
+ if (action === "events" && req.method === "GET") {
2785
+ sendJson(req, res, 200, {
2786
+ items: demoOrchestratorState.events.filter(
2787
+ (item) => item.threadId === taskId,
2788
+ ),
2789
+ nextCursor: null,
2790
+ });
2791
+ return true;
2792
+ }
2793
+
2794
+ if (action === "timeline" && req.method === "GET") {
2795
+ sendJson(
2796
+ req,
2797
+ res,
2798
+ 200,
2799
+ demoTimelinePage(demoOrchestratorState, taskId, url),
2800
+ );
2801
+ return true;
2802
+ }
2803
+
2804
+ if (action === "usage" && req.method === "GET") {
2805
+ sendJson(req, res, 200, task.usage ?? emptyOrchestratorUsage);
2806
+ return true;
2807
+ }
2808
+
2809
+ if (action === "plan-revisions") {
2810
+ if (req.method === "GET") {
2811
+ sendJson(req, res, 200, {
2812
+ items: task.planRevisions ?? [],
2813
+ nextCursor: null,
2814
+ });
2815
+ return true;
2816
+ }
2817
+ if (req.method === "POST") {
2818
+ const body = (await readJsonBody(req)) || {};
2819
+ const revision = {
2820
+ id: `plan-rev-${(task.planRevisions?.length ?? 0) + 1}`,
2821
+ threadId: taskId,
2822
+ plan: body.plan ?? task.currentPlan ?? {},
2823
+ basePlanRevisionId: body.basePlanRevisionId ?? null,
2824
+ editSummary: body.editSummary ?? "Edited in local demo mode",
2825
+ createdBy: body.createdBy ?? "operator",
2826
+ metadata: body.metadata ?? {},
2827
+ timestamp: Date.now(),
2828
+ createdAt: new Date().toISOString(),
2829
+ };
2830
+ task.planRevisions = [revision, ...(task.planRevisions ?? [])];
2831
+ task.currentPlan = revision.plan;
2832
+ sendJson(req, res, 200, revision);
2833
+ return true;
2834
+ }
2835
+ }
2836
+
2837
+ if (action === "agents" && req.method === "POST" && !subId) {
2838
+ const body = (await readJsonBody(req)) || {};
2839
+ const sessionId = `demo-session-${demoOrchestratorState.nextSessionId++}`;
2840
+ const session = {
2841
+ id: `${sessionId}-record`,
2842
+ threadId: taskId,
2843
+ sessionId,
2844
+ label: body.label || "Demo sub-agent",
2845
+ status: "running",
2846
+ framework: body.framework || "codex",
2847
+ providerSource: body.providerSource || "local-demo",
2848
+ model: body.model || "gpt-5.4",
2849
+ originalTask: body.task || "Assist with the demo task.",
2850
+ workdir: body.workdir || task.latestWorkdir || "/tmp/orchestrator-demo",
2851
+ repo: body.repo || task.latestRepo || null,
2852
+ activeTool: "thinking",
2853
+ decisionCount: 0,
2854
+ autoResolvedCount: 0,
2855
+ registeredAt: Date.now(),
2856
+ lastActivityAt: Date.now(),
2857
+ idleCheckCount: 0,
2858
+ taskDelivered: true,
2859
+ completionSummary: null,
2860
+ lastSeenDecisionIndex: 0,
2861
+ lastInputSentAt: null,
2862
+ stoppedAt: null,
2863
+ inputTokens: 0,
2864
+ outputTokens: 0,
2865
+ reasoningTokens: 0,
2866
+ totalTokens: 0,
2867
+ cacheTokens: 0,
2868
+ costUsd: 0,
2869
+ usageState: "estimated",
2870
+ metadata: {},
2871
+ createdAt: new Date().toISOString(),
2872
+ updatedAt: new Date().toISOString(),
2873
+ };
2874
+ task.sessions = [...(task.sessions ?? []), session];
2875
+ task.sessionCount = task.sessions.length;
2876
+ task.activeSessionCount = task.sessions.filter(
2877
+ (item) => item.status === "running",
2878
+ ).length;
2879
+ task.latestSessionId = session.sessionId;
2880
+ task.latestSessionLabel = session.label;
2881
+ task.latestActivityAt = session.lastActivityAt;
2882
+ pushDemoEvent(demoOrchestratorState, taskId, `Added ${session.label}`);
2883
+ sendJson(req, res, 200, task);
2884
+ return true;
2885
+ }
2886
+
2887
+ if (
2888
+ action === "agents" &&
2889
+ subId &&
2890
+ subAction === "stop" &&
2891
+ req.method === "POST"
2892
+ ) {
2893
+ task.sessions = (task.sessions ?? []).map((session) =>
2894
+ session.sessionId === subId
2895
+ ? {
2896
+ ...session,
2897
+ status: "stopped",
2898
+ stoppedAt: Date.now(),
2899
+ activeTool: null,
2900
+ updatedAt: new Date().toISOString(),
2901
+ }
2902
+ : session,
2903
+ );
2904
+ task.activeSessionCount = task.sessions.filter(
2905
+ (item) => item.status === "running",
2906
+ ).length;
2907
+ pushDemoEvent(demoOrchestratorState, taskId, `Stopped agent ${subId}`);
2908
+ sendJson(req, res, 200, { stopped: true });
2909
+ return true;
2910
+ }
2911
+
2912
+ if (req.method === "POST") {
2913
+ const body = (await readJsonBody(req)) || {};
2914
+ if (action === "pause") {
2915
+ task.paused = true;
2916
+ pushDemoEvent(demoOrchestratorState, taskId, "Task paused");
2917
+ sendJson(req, res, 200, task);
2918
+ return true;
2919
+ }
2920
+ if (action === "resume") {
2921
+ task.paused = false;
2922
+ pushDemoEvent(demoOrchestratorState, taskId, "Task resumed");
2923
+ sendJson(req, res, 200, task);
2924
+ return true;
2925
+ }
2926
+ if (action === "archive") {
2927
+ task.status = "archived";
2928
+ task.archivedAt = new Date().toISOString();
2929
+ pushDemoEvent(demoOrchestratorState, taskId, "Task archived");
2930
+ sendJson(req, res, 200, { archived: true });
2931
+ return true;
2932
+ }
2933
+ if (action === "reopen") {
2934
+ task.status = "open";
2935
+ task.archivedAt = null;
2936
+ pushDemoEvent(demoOrchestratorState, taskId, "Task reopened");
2937
+ sendJson(req, res, 200, task);
2938
+ return true;
2939
+ }
2940
+ if (action === "fork") {
2941
+ const forked = createDemoTaskDetail({
2942
+ ...task,
2943
+ id: `demo-task-${demoOrchestratorState.nextTaskId++}`,
2944
+ title: body.title || `Fork of ${task.title}`,
2945
+ goal: body.goal || task.goal,
2946
+ parentTaskId: task.id,
2947
+ status: "open",
2948
+ archivedAt: null,
2949
+ sessions: [],
2950
+ sessionCount: 0,
2951
+ activeSessionCount: 0,
2952
+ });
2953
+ demoOrchestratorState.tasks.unshift(forked);
2954
+ pushDemoEvent(demoOrchestratorState, forked.id, "Task forked");
2955
+ sendJson(req, res, 200, forked);
2956
+ return true;
2957
+ }
2958
+ if (action === "validate") {
2959
+ task.status = body.passed === true ? "done" : "blocked";
2960
+ task.summary = body.summary || task.summary;
2961
+ pushDemoEvent(
2962
+ demoOrchestratorState,
2963
+ taskId,
2964
+ "Validation submitted",
2965
+ body,
2966
+ );
2967
+ sendJson(req, res, 200, task);
2968
+ return true;
2969
+ }
2970
+ if (action === "retry-turn") {
2971
+ pushDemoEvent(
2972
+ demoOrchestratorState,
2973
+ taskId,
2974
+ "Retry turn requested",
2975
+ body,
2976
+ );
2977
+ sendJson(req, res, 200, task);
2978
+ return true;
2979
+ }
2980
+ if (action === "rerun-from-event") {
2981
+ pushDemoEvent(
2982
+ demoOrchestratorState,
2983
+ taskId,
2984
+ "Rerun from event requested",
2985
+ body,
2986
+ );
2987
+ sendJson(req, res, 200, task);
2988
+ return true;
2989
+ }
2990
+ if (action === "restart") {
2991
+ task.status = "active";
2992
+ pushDemoEvent(
2993
+ demoOrchestratorState,
2994
+ taskId,
2995
+ "Task restart requested",
2996
+ body,
2997
+ );
2998
+ sendJson(req, res, 200, task);
2999
+ return true;
3000
+ }
3001
+ if (action === "restart-with-edited-plan") {
3002
+ task.status = "active";
3003
+ if (body.plan && typeof body.plan === "object")
3004
+ task.currentPlan = body.plan;
3005
+ pushDemoEvent(
3006
+ demoOrchestratorState,
3007
+ taskId,
3008
+ "Restart with edited plan requested",
3009
+ body,
3010
+ );
3011
+ sendJson(req, res, 200, task);
3012
+ return true;
3013
+ }
3014
+ }
3015
+
3016
+ sendJson(req, res, 404, {
3017
+ error: `Unhandled demo orchestrator route ${url.pathname}`,
3018
+ });
3019
+ return true;
3020
+ }
3021
+
3022
+ function streamSettings(payload = {}) {
3023
+ return {
3024
+ ok: true,
3025
+ settings: {
3026
+ theme: "eliza",
3027
+ avatarIndex: 0,
3028
+ ...payload,
3029
+ },
3030
+ };
3031
+ }
3032
+
3033
+ const databaseRowsByTable = {
3034
+ messages: [
3035
+ {
3036
+ id: "msg-smoke-1",
3037
+ content:
3038
+ "UI smoke database row with https://example.com/smoke-image.png media",
3039
+ roomId: "room-smoke",
3040
+ entityId: "entity-smoke",
3041
+ createdAt: SMOKE_GENERATED_AT,
3042
+ },
3043
+ {
3044
+ id: "msg-smoke-2",
3045
+ content: "UI smoke vector sample row",
3046
+ roomId: "room-smoke",
3047
+ entityId: "entity-smoke",
3048
+ createdAt: SMOKE_GENERATED_AT,
3049
+ },
3050
+ ],
3051
+ memories: [
3052
+ {
3053
+ id: "memory-smoke-1",
3054
+ text: "Deterministic memory fixture for UI smoke.",
3055
+ roomId: "room-smoke",
3056
+ entityId: "entity-smoke",
3057
+ createdAt: SMOKE_GENERATED_AT,
3058
+ dim_0: 0.12,
3059
+ dim_1: 0.34,
3060
+ dim_2: 0.56,
3061
+ },
3062
+ ],
3063
+ media: [
3064
+ {
3065
+ id: "media-smoke-1",
3066
+ url: "https://example.com/smoke-image.png",
3067
+ type: "image",
3068
+ filename: "smoke-image.png",
3069
+ createdAt: SMOKE_GENERATED_AT,
3070
+ },
3071
+ ],
3072
+ };
3073
+
3074
+ const databaseTables = Object.entries(databaseRowsByTable).map(
3075
+ ([name, rows]) => ({
3076
+ name,
3077
+ schema: "public",
3078
+ rowCount: rows.length,
3079
+ columns: Object.keys(rows[0] ?? {}).map((columnName) => ({
3080
+ name: columnName,
3081
+ type: columnName.startsWith("dim_") ? "double precision" : "text",
3082
+ nullable: false,
3083
+ defaultValue: null,
3084
+ isPrimaryKey: columnName === "id",
3085
+ })),
3086
+ }),
3087
+ );
3088
+
3089
+ function databaseRowsResponse(tableName, url) {
3090
+ const rows = databaseRowsByTable[tableName] ?? [];
3091
+ const offset = Number(url.searchParams.get("offset") ?? "0");
3092
+ const limit = Number(url.searchParams.get("limit") ?? "50");
3093
+ const sort = url.searchParams.get("sort");
3094
+ const order = url.searchParams.get("order") === "desc" ? "desc" : "asc";
3095
+ const sortedRows = sort
3096
+ ? [...rows].sort((left, right) => {
3097
+ const leftValue = String(left[sort] ?? "");
3098
+ const rightValue = String(right[sort] ?? "");
3099
+ return order === "desc"
3100
+ ? rightValue.localeCompare(leftValue)
3101
+ : leftValue.localeCompare(rightValue);
3102
+ })
3103
+ : rows;
3104
+ const pageRows = sortedRows.slice(offset, offset + limit);
3105
+ return {
3106
+ table: tableName,
3107
+ rows: pageRows,
3108
+ columns: Object.keys(rows[0] ?? {}),
3109
+ total: rows.length,
3110
+ offset,
3111
+ limit,
3112
+ };
3113
+ }
3114
+
3115
+ function executeDatabaseQueryResult(sql) {
3116
+ const match = /from\s+"?([a-z0-9_-]+)"?/iu.exec(sql ?? "");
3117
+ const tableName =
3118
+ match?.[1] && databaseRowsByTable[match[1]] ? match[1] : "messages";
3119
+ const rows = databaseRowsByTable[tableName] ?? [];
3120
+ return {
3121
+ columns: Object.keys(rows[0] ?? {}),
3122
+ rows,
3123
+ rowCount: rows.length,
3124
+ durationMs: 1,
3125
+ };
3126
+ }
3127
+
3128
+ const sockets = new Set();
3129
+ const server = http.createServer(async (req, res) => {
3130
+ const url = new URL(
3131
+ req.url ?? "/",
3132
+ `http://${req.headers.host ?? `127.0.0.1:${port}`}`,
3133
+ );
3134
+
3135
+ if (req.method === "OPTIONS") {
3136
+ sendEmpty(req, res, 204);
3137
+ return;
3138
+ }
3139
+
3140
+ if (
3141
+ (req.method === "GET" || req.method === "HEAD") &&
3142
+ url.pathname === "/api/avatar/vrm"
3143
+ ) {
3144
+ sendBinary(req, res, 200, "application/octet-stream", SMOKE_VRM);
3145
+ return;
3146
+ }
3147
+
3148
+ if (
3149
+ (req.method === "GET" || req.method === "HEAD") &&
3150
+ url.pathname === "/api/avatar/background"
3151
+ ) {
3152
+ sendBinary(req, res, 200, "image/png", ONE_PIXEL_PNG);
3153
+ return;
3154
+ }
3155
+
3156
+ if (
3157
+ (req.method === "GET" || req.method === "HEAD") &&
3158
+ url.pathname.startsWith("/api/apps/hero/")
3159
+ ) {
3160
+ sendBinary(req, res, 200, "image/png", ONE_PIXEL_PNG);
3161
+ return;
3162
+ }
3163
+
3164
+ if (req.method === "GET" && url.pathname === "/api/commands") {
3165
+ sendJson(req, res, 200, {
3166
+ commands: [],
3167
+ surface: url.searchParams.get("surface"),
3168
+ agentId: null,
3169
+ generatedAt: SMOKE_GENERATED_AT,
3170
+ });
3171
+ return;
3172
+ }
3173
+
3174
+ if (req.method === "GET" && url.pathname === "/api/custom-actions") {
3175
+ sendJson(req, res, 200, { actions: [] });
3176
+ return;
3177
+ }
3178
+
3179
+ if (req.method === "GET" && url.pathname === "/api/notifications") {
3180
+ sendJson(req, res, 200, { notifications: [], unreadCount: 0 });
3181
+ return;
3182
+ }
3183
+
3184
+ if (req.method === "GET" && url.pathname === "/api/views") {
3185
+ const requestedViewType = url.searchParams.get("viewType");
3186
+ const views =
3187
+ requestedViewType === "gui" || requestedViewType === "tui"
3188
+ ? smokeViews.filter((view) => view.viewType === requestedViewType)
3189
+ : smokeViews;
3190
+ sendJson(req, res, 200, { views });
3191
+ return;
3192
+ }
3193
+
3194
+ if (req.method === "GET" && url.pathname === "/api/views/current") {
3195
+ sendJson(req, res, 200, { currentView: null });
3196
+ return;
3197
+ }
3198
+
3199
+ if (
3200
+ (req.method === "GET" || req.method === "HEAD") &&
3201
+ url.pathname.startsWith("/api/views/")
3202
+ ) {
3203
+ const afterPrefix = url.pathname.slice("/api/views/".length);
3204
+ const slashIndex = afterPrefix.indexOf("/");
3205
+ const rawId =
3206
+ slashIndex === -1 ? afterPrefix : afterPrefix.slice(0, slashIndex);
3207
+ const subResource =
3208
+ slashIndex === -1 ? "" : afterPrefix.slice(slashIndex + 1);
3209
+ const id = decodeURIComponent(rawId);
3210
+ const view = smokeViewByRequest(id, url.searchParams.get("viewType"));
3211
+ if (!view) {
3212
+ sendJson(req, res, 404, { error: `View not found: ${id}` });
3213
+ return;
3214
+ }
3215
+ if (subResource === "") {
3216
+ sendJson(req, res, 200, view);
3217
+ return;
3218
+ }
3219
+ if (subResource === "hero") {
3220
+ sendBinary(req, res, 200, "image/png", ONE_PIXEL_PNG);
3221
+ return;
3222
+ }
3223
+ if (subResource === "bundle.js") {
3224
+ sendSmokeViewAsset(req, res, url, view, "bundle.js");
3225
+ return;
3226
+ }
3227
+ sendSmokeViewAsset(req, res, url, view, subResource);
3228
+ return;
3229
+ }
3230
+
3231
+ if (req.method === "POST" && url.pathname.startsWith("/api/views/")) {
3232
+ sendJson(req, res, 200, { ok: true });
3233
+ return;
3234
+ }
3235
+
3236
+ if (req.method === "GET" && url.pathname === "/api/health") {
3237
+ sendJson(req, res, 200, { status: "ok" });
3238
+ return;
3239
+ }
3240
+
3241
+ if (req.method === "GET" && url.pathname === "/api/first-run/status") {
3242
+ sendJson(req, res, 200, { complete: true });
3243
+ return;
3244
+ }
3245
+
3246
+ if (req.method === "GET" && url.pathname === "/api/first-run/options") {
3247
+ sendJson(req, res, 200, {
3248
+ names: [],
3249
+ styles: [],
3250
+ providers: [],
3251
+ cloudProviders: [],
3252
+ models: {
3253
+ nano: [],
3254
+ small: [],
3255
+ medium: [],
3256
+ large: [],
3257
+ mega: [],
3258
+ },
3259
+ inventoryProviders: [],
3260
+ sharedStyleRules: "",
3261
+ });
3262
+ return;
3263
+ }
3264
+
3265
+ if (req.method === "GET" && url.pathname === "/api/auth/status") {
3266
+ sendJson(req, res, 200, {
3267
+ required: false,
3268
+ pairingEnabled: false,
3269
+ expiresAt: null,
3270
+ });
3271
+ return;
3272
+ }
3273
+
3274
+ if (req.method === "GET" && url.pathname === "/api/auth/me") {
3275
+ sendJson(req, res, 200, {
3276
+ identity: stubAuthIdentity,
3277
+ session: stubAuthSession,
3278
+ access: stubAuthAccess,
3279
+ });
3280
+ return;
3281
+ }
3282
+
3283
+ if (req.method === "GET" && url.pathname === "/api/auth/sessions") {
3284
+ sendJson(req, res, 200, {
3285
+ sessions: [
3286
+ {
3287
+ id: stubAuthSession.id,
3288
+ kind: stubAuthSession.kind,
3289
+ ip: "127.0.0.1",
3290
+ userAgent: "Playwright smoke",
3291
+ lastSeenAt: Date.now(),
3292
+ expiresAt: null,
3293
+ current: true,
3294
+ },
3295
+ ],
3296
+ });
3297
+ return;
3298
+ }
3299
+
3300
+ if (req.method === "GET" && url.pathname === "/api/agent/status") {
3301
+ sendJson(req, res, 200, { firstRunComplete: true, status: "running" });
3302
+ return;
3303
+ }
3304
+
3305
+ if (req.method === "POST" && url.pathname === "/api/emote") {
3306
+ const body = (await readJsonBody(req)) || {};
3307
+ sendJson(req, res, 200, {
3308
+ ok: true,
3309
+ emoteId: typeof body.emoteId === "string" ? body.emoteId : null,
3310
+ });
3311
+ return;
3312
+ }
3313
+
3314
+ if (req.method === "GET" && url.pathname === "/api/status") {
3315
+ sendJson(req, res, 200, {
3316
+ state: "running",
3317
+ agentName: "Playwright Smoke",
3318
+ model: "ui-smoke",
3319
+ startup: { phase: "running", attempt: 0 },
3320
+ pendingRestart: false,
3321
+ pendingRestartReasons: [],
3322
+ });
3323
+ return;
3324
+ }
3325
+
3326
+ if (url.pathname === "/api/config") {
3327
+ const config = {
3328
+ cloud: { enabled: false },
3329
+ media: {},
3330
+ // Select the local-inference voice provider so the /chat overlay's
3331
+ // bidirectional loop drives /api/asr/local-inference (in) and
3332
+ // /api/tts/local-inference (out) — both stubbed below.
3333
+ messages: {
3334
+ tts: { provider: "local-inference" },
3335
+ asr: { provider: "local-inference" },
3336
+ },
3337
+ plugins: { entries: {} },
3338
+ ui: {},
3339
+ wallet: {},
3340
+ };
3341
+ if (req.method === "GET") {
3342
+ sendJson(req, res, 200, config);
3343
+ return;
3344
+ }
3345
+ if (req.method === "PUT" || req.method === "PATCH") {
3346
+ const body = (await readJsonBody(req)) || {};
3347
+ sendJson(req, res, 200, {
3348
+ ...config,
3349
+ ...(body && typeof body === "object" && !Array.isArray(body)
3350
+ ? body
3351
+ : {}),
3352
+ });
3353
+ return;
3354
+ }
3355
+ }
3356
+
3357
+ if (req.method === "GET" && url.pathname === "/api/database/status") {
3358
+ sendJson(req, res, 200, {
3359
+ provider: "pglite",
3360
+ connected: true,
3361
+ serverVersion: "16.0-ui-smoke",
3362
+ tableCount: databaseTables.length,
3363
+ pgliteDataDir: null,
3364
+ postgresHost: null,
3365
+ });
3366
+ return;
3367
+ }
3368
+
3369
+ if (req.method === "GET" && url.pathname === "/api/database/config") {
3370
+ sendJson(req, res, 200, {
3371
+ config: {},
3372
+ activeProvider: "pglite",
3373
+ needsRestart: false,
3374
+ });
3375
+ return;
3376
+ }
3377
+
3378
+ if (req.method === "PUT" && url.pathname === "/api/database/config") {
3379
+ sendJson(req, res, 200, {
3380
+ config: (await readJsonBody(req)) || {},
3381
+ activeProvider: "pglite",
3382
+ needsRestart: false,
3383
+ });
3384
+ return;
3385
+ }
3386
+
3387
+ if (req.method === "POST" && url.pathname === "/api/database/test") {
3388
+ sendJson(req, res, 200, {
3389
+ success: true,
3390
+ serverVersion: "16.0-ui-smoke",
3391
+ error: null,
3392
+ durationMs: 1,
3393
+ });
3394
+ return;
3395
+ }
3396
+
3397
+ if (req.method === "GET" && url.pathname === "/api/database/tables") {
3398
+ sendJson(req, res, 200, { tables: databaseTables });
3399
+ return;
3400
+ }
3401
+
3402
+ const databaseRowsMatch = /^\/api\/database\/tables\/([^/]+)\/rows$/.exec(
3403
+ url.pathname,
3404
+ );
3405
+ if (databaseRowsMatch) {
3406
+ const tableName = decodeURIComponent(databaseRowsMatch[1]);
3407
+ if (req.method === "GET") {
3408
+ sendJson(req, res, 200, databaseRowsResponse(tableName, url));
3409
+ return;
3410
+ }
3411
+ if (["POST", "PUT", "DELETE"].includes(req.method ?? "GET")) {
3412
+ sendJson(req, res, 200, {
3413
+ ok: true,
3414
+ table: tableName,
3415
+ row: databaseRowsByTable[tableName]?.[0] ?? null,
3416
+ });
3417
+ return;
3418
+ }
3419
+ }
3420
+
3421
+ if (req.method === "POST" && url.pathname === "/api/database/query") {
3422
+ const body = (await readJsonBody(req)) || {};
3423
+ sendJson(req, res, 200, executeDatabaseQueryResult(String(body.sql ?? "")));
3424
+ return;
3425
+ }
3426
+
3427
+ if (
3428
+ (req.method === "GET" || req.method === "POST") &&
3429
+ url.pathname === "/api/database/vectors/search"
3430
+ ) {
3431
+ const query =
3432
+ req.method === "POST"
3433
+ ? (await readJsonBody(req))?.query
3434
+ : url.searchParams.get("query");
3435
+ sendJson(req, res, 200, {
3436
+ query: typeof query === "string" ? query : "",
3437
+ table: "memories",
3438
+ limit: 10,
3439
+ count: 1,
3440
+ results: [
3441
+ {
3442
+ id: "memory-smoke-1",
3443
+ text: "Deterministic memory fixture for UI smoke.",
3444
+ similarity: 0.98,
3445
+ roomId: "room-smoke",
3446
+ entityId: "entity-smoke",
3447
+ createdAt: SMOKE_GENERATED_AT,
3448
+ tableName: "memories",
3449
+ },
3450
+ ],
3451
+ });
3452
+ return;
3453
+ }
3454
+
3455
+ if (req.method === "GET" && url.pathname === "/api/vincent/status") {
3456
+ sendJson(req, res, 200, {
3457
+ connected: false,
3458
+ connectedAt: null,
3459
+ tradingVenues: ["hyperliquid", "polymarket"],
3460
+ });
3461
+ return;
3462
+ }
953
3463
 
954
- if (req.method === "HEAD" && url.pathname === "/api/avatar/background") {
955
- sendEmpty(req, res, 404);
3464
+ if (req.method === "GET" && url.pathname === "/api/vincent/strategy") {
3465
+ sendJson(req, res, 200, { connected: false, strategy: null });
956
3466
  return;
957
3467
  }
958
3468
 
959
- if (req.method === "GET" && url.pathname === "/api/health") {
960
- sendJson(req, res, 200, { status: "ok" });
3469
+ if (req.method === "GET" && url.pathname === "/api/vincent/trading-profile") {
3470
+ sendJson(req, res, 200, { connected: false, profile: null });
961
3471
  return;
962
3472
  }
963
3473
 
964
- if (req.method === "GET" && url.pathname === "/api/onboarding/status") {
965
- sendJson(req, res, 200, { complete: true });
3474
+ if (req.method === "GET" && url.pathname === "/api/shopify/status") {
3475
+ sendJson(req, res, 200, { connected: false, shop: null });
3476
+ return;
3477
+ }
3478
+
3479
+ if (req.method === "GET" && url.pathname === "/api/shopify/products") {
3480
+ sendJson(req, res, 200, { products: [], total: 0, page: 1, pageSize: 25 });
3481
+ return;
3482
+ }
3483
+
3484
+ if (req.method === "GET" && url.pathname === "/api/shopify/orders") {
3485
+ sendJson(req, res, 200, { orders: [], total: 0 });
3486
+ return;
3487
+ }
3488
+
3489
+ if (req.method === "GET" && url.pathname === "/api/shopify/inventory") {
3490
+ sendJson(req, res, 200, { items: [], locations: [] });
3491
+ return;
3492
+ }
3493
+
3494
+ if (req.method === "GET" && url.pathname === "/api/shopify/customers") {
3495
+ sendJson(req, res, 200, { customers: [], total: 0 });
3496
+ return;
3497
+ }
3498
+
3499
+ if (req.method === "GET" && url.pathname === "/api/hyperliquid/status") {
3500
+ sendJson(req, res, 200, stubHyperliquidStatus);
3501
+ return;
3502
+ }
3503
+
3504
+ if (req.method === "GET" && url.pathname === "/api/hyperliquid/markets") {
3505
+ sendJson(req, res, 200, stubHyperliquidMarkets);
966
3506
  return;
967
3507
  }
968
3508
 
969
- if (req.method === "GET" && url.pathname === "/api/onboarding/options") {
3509
+ if (req.method === "GET" && url.pathname === "/api/hyperliquid/positions") {
970
3510
  sendJson(req, res, 200, {
971
- names: [],
972
- styles: [],
973
- providers: [],
974
- cloudProviders: [],
975
- models: {
976
- nano: [],
977
- small: [],
978
- medium: [],
979
- large: [],
980
- mega: [],
981
- },
982
- inventoryProviders: [],
983
- sharedStyleRules: "",
3511
+ accountAddress: null,
3512
+ positions: [],
3513
+ readBlockedReason:
3514
+ "Connect an account address to read Hyperliquid positions.",
3515
+ fetchedAt: null,
984
3516
  });
985
3517
  return;
986
3518
  }
987
3519
 
988
- if (req.method === "GET" && url.pathname === "/api/auth/status") {
3520
+ if (req.method === "GET" && url.pathname === "/api/hyperliquid/orders") {
989
3521
  sendJson(req, res, 200, {
990
- required: false,
991
- pairingEnabled: false,
992
- expiresAt: null,
3522
+ accountAddress: null,
3523
+ orders: [],
3524
+ readBlockedReason: "Connect an account address to read open orders.",
3525
+ fetchedAt: null,
993
3526
  });
994
3527
  return;
995
3528
  }
996
3529
 
997
- if (req.method === "GET" && url.pathname === "/api/auth/me") {
3530
+ if (req.method === "GET" && url.pathname === "/api/polymarket/status") {
3531
+ sendJson(req, res, 200, stubPolymarketStatus);
3532
+ return;
3533
+ }
3534
+
3535
+ if (req.method === "GET" && url.pathname === "/api/polymarket/markets") {
998
3536
  sendJson(req, res, 200, {
999
- identity: stubAuthIdentity,
1000
- session: stubAuthSession,
1001
- access: stubAuthAccess,
3537
+ markets: [stubPolymarketMarket],
3538
+ source: { api: "gamma", endpoint: "/markets" },
1002
3539
  });
1003
3540
  return;
1004
3541
  }
1005
3542
 
1006
- if (req.method === "GET" && url.pathname === "/api/auth/sessions") {
3543
+ if (req.method === "GET" && url.pathname === "/api/polymarket/market") {
1007
3544
  sendJson(req, res, 200, {
1008
- sessions: [
1009
- {
1010
- id: stubAuthSession.id,
1011
- kind: stubAuthSession.kind,
1012
- ip: "127.0.0.1",
1013
- userAgent: "Playwright smoke",
1014
- lastSeenAt: Date.now(),
1015
- expiresAt: null,
1016
- current: true,
1017
- },
1018
- ],
3545
+ market: stubPolymarketMarket,
3546
+ source: { api: "gamma", endpoint: "/markets" },
1019
3547
  });
1020
3548
  return;
1021
3549
  }
1022
3550
 
1023
- if (req.method === "GET" && url.pathname === "/api/agent/status") {
1024
- sendJson(req, res, 200, { onboardingComplete: true, status: "running" });
3551
+ if (req.method === "GET" && url.pathname === "/api/polymarket/orderbook") {
3552
+ sendJson(req, res, 200, {
3553
+ tokenId: url.searchParams.get("token_id") ?? "yes-token",
3554
+ market: stubPolymarketMarket.id,
3555
+ assetId: null,
3556
+ bids: [{ price: "0.71", size: "100" }],
3557
+ asks: [{ price: "0.73", size: "100" }],
3558
+ bestBid: "0.71",
3559
+ bestBidSize: "100",
3560
+ bestAsk: "0.73",
3561
+ bestAskSize: "100",
3562
+ midpoint: "0.72",
3563
+ spread: "0.02",
3564
+ bidLevels: 1,
3565
+ askLevels: 1,
3566
+ lastTradePrice: "0.72",
3567
+ tickSize: "0.01",
3568
+ source: { api: "clob", endpoint: "/book" },
3569
+ });
1025
3570
  return;
1026
3571
  }
1027
3572
 
1028
- if (req.method === "GET" && url.pathname === "/api/status") {
3573
+ if (req.method === "GET" && url.pathname === "/api/polymarket/orders") {
1029
3574
  sendJson(req, res, 200, {
1030
- state: "running",
1031
- startup: { phase: "running", attempt: 0 },
1032
- pendingRestart: false,
1033
- pendingRestartReasons: [],
3575
+ enabled: false,
3576
+ reason: "Trading is disabled in UI smoke.",
3577
+ requiredForTrading: [
3578
+ "POLYMARKET_PRIVATE_KEY",
3579
+ "CLOB_API_KEY",
3580
+ "CLOB_API_SECRET",
3581
+ "CLOB_API_PASSPHRASE",
3582
+ ],
1034
3583
  });
1035
3584
  return;
1036
3585
  }
1037
3586
 
1038
- if (req.method === "GET" && url.pathname === "/api/config") {
3587
+ if (req.method === "GET" && url.pathname === "/api/polymarket/positions") {
1039
3588
  sendJson(req, res, 200, {
1040
- cloud: { enabled: false },
1041
- media: {},
1042
- plugins: { entries: {} },
1043
- ui: {},
1044
- wallet: {},
3589
+ positions: [],
3590
+ source: { api: "data", endpoint: "/positions" },
1045
3591
  });
1046
3592
  return;
1047
3593
  }
1048
3594
 
1049
- if (req.method === "GET" && url.pathname === "/api/vincent/status") {
1050
- sendJson(req, res, 200, {
1051
- connected: false,
1052
- connectedAt: null,
1053
- tradingVenues: ["hyperliquid", "polymarket"],
3595
+ if (url.pathname === "/api/conversations") {
3596
+ if (req.method === "GET") {
3597
+ sendJson(req, res, 200, { conversations: stubConversations });
3598
+ return;
3599
+ }
3600
+ if (req.method === "POST") {
3601
+ const body = (await readJsonBody(req)) || {};
3602
+ const conversation = createStubConversation({
3603
+ title: body.title,
3604
+ metadata: body.metadata,
3605
+ });
3606
+ sendJson(req, res, 200, { conversation });
3607
+ return;
3608
+ }
3609
+ }
3610
+
3611
+ if (
3612
+ req.method === "POST" &&
3613
+ url.pathname === "/api/conversations/cleanup-empty"
3614
+ ) {
3615
+ const body = (await readJsonBody(req)) || {};
3616
+ const deleted = cleanupEmptyStubConversations({
3617
+ keepId: body.keepId,
1054
3618
  });
3619
+ sendJson(req, res, 200, { deleted });
1055
3620
  return;
1056
3621
  }
1057
3622
 
1058
- if (req.method === "GET" && url.pathname === "/api/conversations") {
1059
- sendJson(req, res, 200, { conversations: [] });
3623
+ const conversationMessagesMatch = url.pathname.match(
3624
+ /^\/api\/conversations\/([^/]+)\/messages(?:\/(stream|truncate))?$/,
3625
+ );
3626
+ if (conversationMessagesMatch) {
3627
+ const conversationId = decodeURIComponent(conversationMessagesMatch[1]);
3628
+ const action = conversationMessagesMatch[2] ?? null;
3629
+ const conversation = findStubConversation(conversationId);
3630
+ if (!conversation) {
3631
+ sendJson(req, res, 404, { error: "Conversation not found" });
3632
+ return;
3633
+ }
3634
+
3635
+ if (req.method === "GET" && action === null) {
3636
+ sendJson(req, res, 200, {
3637
+ messages: stubConversationMessages.get(conversationId) ?? [],
3638
+ });
3639
+ return;
3640
+ }
3641
+
3642
+ if (req.method === "POST" && action === "truncate") {
3643
+ stubConversationMessages.set(conversationId, []);
3644
+ conversation.updatedAt = nowIso();
3645
+ sendJson(req, res, 200, { ok: true, messages: [] });
3646
+ return;
3647
+ }
3648
+
3649
+ if (req.method === "POST" && action === "stream") {
3650
+ const body = (await readJsonBody(req)) || {};
3651
+ appendStubMessage(conversationId, createStubMessage("user", body.text));
3652
+ const text = createDeterministicAssistantText({
3653
+ body,
3654
+ conversationId,
3655
+ transport: "sse",
3656
+ });
3657
+ appendStubMessage(conversationId, createStubMessage("assistant", text));
3658
+ sendSseHeaders(req, res);
3659
+ writeSseEvent(res, { type: "token", text, fullText: text });
3660
+ writeSseEvent(res, { type: "done", fullText: text, agentName: "Eliza" });
3661
+ res.end();
3662
+ return;
3663
+ }
3664
+
3665
+ if (req.method === "POST" && action === null) {
3666
+ const body = (await readJsonBody(req)) || {};
3667
+ appendStubMessage(conversationId, createStubMessage("user", body.text));
3668
+ const text = createDeterministicAssistantText({
3669
+ body,
3670
+ conversationId,
3671
+ transport: "json",
3672
+ });
3673
+ appendStubMessage(conversationId, createStubMessage("assistant", text));
3674
+ sendJson(req, res, 200, { text, agentName: "Eliza" });
3675
+ return;
3676
+ }
3677
+ }
3678
+
3679
+ const conversationMatch = url.pathname.match(
3680
+ /^\/api\/conversations\/([^/]+)$/,
3681
+ );
3682
+ if (conversationMatch) {
3683
+ const conversationId = decodeURIComponent(conversationMatch[1]);
3684
+ const conversation = findStubConversation(conversationId);
3685
+ if (!conversation) {
3686
+ sendJson(req, res, 404, { error: "Conversation not found" });
3687
+ return;
3688
+ }
3689
+ if (req.method === "PATCH") {
3690
+ const body = (await readJsonBody(req)) || {};
3691
+ if (typeof body.title === "string" && body.title.trim().length > 0) {
3692
+ conversation.title = body.title.trim();
3693
+ }
3694
+ if (
3695
+ Object.hasOwn(body, "metadata") &&
3696
+ body.metadata &&
3697
+ typeof body.metadata === "object" &&
3698
+ !Array.isArray(body.metadata)
3699
+ ) {
3700
+ conversation.metadata = body.metadata;
3701
+ }
3702
+ conversation.updatedAt = nowIso();
3703
+ sendJson(req, res, 200, { conversation });
3704
+ return;
3705
+ }
3706
+ if (req.method === "DELETE") {
3707
+ const index = stubConversations.findIndex(
3708
+ (item) => item.id === conversationId,
3709
+ );
3710
+ if (index >= 0) stubConversations.splice(index, 1);
3711
+ stubConversationMessages.delete(conversationId);
3712
+ sendJson(req, res, 200, { ok: true });
3713
+ return;
3714
+ }
3715
+ }
3716
+
3717
+ const conversationGreetingMatch = url.pathname.match(
3718
+ /^\/api\/conversations\/([^/]+)\/greeting$/,
3719
+ );
3720
+ if (req.method === "POST" && conversationGreetingMatch) {
3721
+ const conversationId = decodeURIComponent(conversationGreetingMatch[1]);
3722
+ if (!findStubConversation(conversationId)) {
3723
+ sendJson(req, res, 404, { error: "Conversation not found" });
3724
+ return;
3725
+ }
3726
+ sendJson(req, res, 200, {
3727
+ text: "What would you like to check?",
3728
+ agentName: "Eliza",
3729
+ generated: false,
3730
+ persisted: true,
3731
+ });
1060
3732
  return;
1061
3733
  }
1062
3734
 
@@ -1085,6 +3757,16 @@ const server = http.createServer(async (req, res) => {
1085
3757
  return;
1086
3758
  }
1087
3759
 
3760
+ if (req.method === "GET" && url.pathname === "/api/runtime/mode") {
3761
+ sendJson(req, res, 200, {
3762
+ mode: "local",
3763
+ deploymentRuntime: "local",
3764
+ isRemoteController: false,
3765
+ remoteApiBaseConfigured: false,
3766
+ });
3767
+ return;
3768
+ }
3769
+
1088
3770
  if (req.method === "GET" && url.pathname === "/api/memories/stats") {
1089
3771
  sendJson(req, res, 200, stubMemoryStats);
1090
3772
  return;
@@ -1224,46 +3906,325 @@ const server = http.createServer(async (req, res) => {
1224
3906
  }
1225
3907
  }
1226
3908
 
1227
- if (req.method === "GET" && url.pathname === "/api/character") {
1228
- sendJson(req, res, 200, { character: stubCharacter, agentName: "Eliza" });
3909
+ if (req.method === "GET" && url.pathname === "/api/character") {
3910
+ sendJson(req, res, 200, { character: stubCharacter, agentName: "Eliza" });
3911
+ return;
3912
+ }
3913
+
3914
+ if (req.method === "GET" && url.pathname === "/api/character/history") {
3915
+ sendJson(req, res, 200, { history: [], total: 0 });
3916
+ return;
3917
+ }
3918
+
3919
+ if (req.method === "GET" && url.pathname === "/api/character/experiences") {
3920
+ sendJson(req, res, 200, {
3921
+ data: stubExperiences,
3922
+ total: stubExperiences.length,
3923
+ });
3924
+ return;
3925
+ }
3926
+
3927
+ if (req.method === "GET" && url.pathname === "/api/relationships/activity") {
3928
+ sendJson(req, res, 200, { activity: [] });
3929
+ return;
3930
+ }
3931
+
3932
+ if (req.method === "GET" && url.pathname === "/api/documents") {
3933
+ sendJson(req, res, 200, {
3934
+ documents: [],
3935
+ total: 0,
3936
+ limit: parsePositiveInt(url.searchParams.get("limit"), 100),
3937
+ offset: parsePositiveInt(url.searchParams.get("offset"), 0),
3938
+ });
3939
+ return;
3940
+ }
3941
+
3942
+ if (req.method === "GET" && url.pathname === "/api/voice/profiles") {
3943
+ sendJson(req, res, 200, { profiles: [] });
3944
+ return;
3945
+ }
3946
+
3947
+ if (req.method === "GET" && url.pathname === "/api/subscription/status") {
3948
+ sendJson(req, res, 200, { providers: [] });
3949
+ return;
3950
+ }
3951
+
3952
+ if (req.method === "GET" && url.pathname === "/api/update/status") {
3953
+ sendJson(req, res, 200, {
3954
+ currentVersion: "0.0.0-ui-smoke",
3955
+ channel: "stable",
3956
+ installMethod: "source",
3957
+ updateAuthority: "manual",
3958
+ nextAction: "manual",
3959
+ canAutoUpdate: false,
3960
+ canExecuteUpdate: false,
3961
+ remoteDisplay: false,
3962
+ updateCommand: null,
3963
+ updateInstructions: null,
3964
+ updateAvailable: false,
3965
+ latestVersion: "0.0.0-ui-smoke",
3966
+ channels: {
3967
+ stable: "0.0.0-ui-smoke",
3968
+ beta: "0.0.0-ui-smoke",
3969
+ nightly: "0.0.0-ui-smoke",
3970
+ },
3971
+ distTags: {},
3972
+ lastCheckAt: null,
3973
+ error: null,
3974
+ });
3975
+ return;
3976
+ }
3977
+
3978
+ if (req.method === "GET" && url.pathname === "/api/permissions") {
3979
+ const permission = {
3980
+ id: "shell",
3981
+ status: "granted",
3982
+ lastChecked: Date.now(),
3983
+ canRequest: false,
3984
+ platform: process.platform,
3985
+ };
3986
+ sendJson(req, res, 200, {
3987
+ shell: permission,
3988
+ notifications: { ...permission, id: "notifications" },
3989
+ microphone: { ...permission, id: "microphone" },
3990
+ camera: { ...permission, id: "camera" },
3991
+ "screen-capture": { ...permission, id: "screen-capture" },
3992
+ accessibility: { ...permission, id: "accessibility" },
3993
+ "website-blocking": {
3994
+ ...permission,
3995
+ id: "website-blocking",
3996
+ status: "not-applicable",
3997
+ },
3998
+ _platform: process.platform,
3999
+ _shellEnabled: true,
4000
+ });
4001
+ return;
4002
+ }
4003
+
4004
+ if (req.method === "GET" && url.pathname === "/api/permissions/shell") {
4005
+ sendJson(req, res, 200, {
4006
+ id: "shell",
4007
+ status: "granted",
4008
+ lastChecked: Date.now(),
4009
+ canRequest: false,
4010
+ platform: process.platform,
4011
+ });
4012
+ return;
4013
+ }
4014
+
4015
+ if (
4016
+ (req.method === "GET" || req.method === "PUT") &&
4017
+ url.pathname === "/api/secrets/manager/preferences"
4018
+ ) {
4019
+ if (req.method === "PUT") {
4020
+ await readJsonBody(req);
4021
+ }
4022
+ sendJson(req, res, 200, {
4023
+ preferences: { enabled: ["in-house"], routing: {} },
4024
+ });
4025
+ return;
4026
+ }
4027
+
4028
+ if (
4029
+ req.method === "GET" &&
4030
+ url.pathname === "/api/secrets/manager/backends"
4031
+ ) {
4032
+ sendJson(req, res, 200, {
4033
+ backends: [
4034
+ {
4035
+ id: "in-house",
4036
+ label: "Local (encrypted)",
4037
+ available: true,
4038
+ signedIn: true,
4039
+ detail: "UI smoke local vault",
4040
+ authMode: null,
4041
+ },
4042
+ ],
4043
+ });
4044
+ return;
4045
+ }
4046
+
4047
+ // Secrets-manager modal load endpoints — the modal's load() requires all of
4048
+ // these to be ok or it shows an error banner instead of the tabs/add-secret
4049
+ // form. Minimal valid shapes (vault-tabs/types.ts) so the modal renders.
4050
+ if (
4051
+ req.method === "GET" &&
4052
+ url.pathname === "/api/secrets/manager/backends"
4053
+ ) {
4054
+ sendJson(req, res, 200, {
4055
+ backends: [{ id: "in-house", label: "In-House Vault", available: true }],
4056
+ });
4057
+ return;
4058
+ }
4059
+ if (
4060
+ req.method === "GET" &&
4061
+ url.pathname === "/api/secrets/manager/preferences"
4062
+ ) {
4063
+ sendJson(req, res, 200, { preferences: { enabled: ["in-house"] } });
4064
+ return;
4065
+ }
4066
+ if (
4067
+ req.method === "GET" &&
4068
+ url.pathname === "/api/secrets/manager/install/methods"
4069
+ ) {
4070
+ sendJson(req, res, 200, { methods: {} });
4071
+ return;
4072
+ }
4073
+ if (req.method === "GET" && url.pathname === "/api/secrets/routing") {
4074
+ sendJson(req, res, 200, { config: { rules: [] } });
4075
+ return;
4076
+ }
4077
+
4078
+ if (req.method === "GET" && url.pathname === "/api/secrets/inventory") {
4079
+ const category = url.searchParams.get("category");
4080
+ sendJson(req, res, 200, {
4081
+ entries:
4082
+ category === "wallet"
4083
+ ? [
4084
+ {
4085
+ key: "EVM_PRIVATE_KEY",
4086
+ label: "EVM private key",
4087
+ category: "wallet",
4088
+ backend: "in-house",
4089
+ isSet: true,
4090
+ updatedAt: SMOKE_GENERATED_AT,
4091
+ },
4092
+ {
4093
+ key: "SOLANA_PRIVATE_KEY",
4094
+ label: "Solana private key",
4095
+ category: "wallet",
4096
+ backend: "in-house",
4097
+ isSet: true,
4098
+ updatedAt: SMOKE_GENERATED_AT,
4099
+ },
4100
+ ]
4101
+ : [],
4102
+ });
4103
+ return;
4104
+ }
4105
+
4106
+ const secretInventoryMatch = /^\/api\/secrets\/inventory\/([^/]+)$/.exec(
4107
+ url.pathname,
4108
+ );
4109
+ if (secretInventoryMatch) {
4110
+ const key = decodeURIComponent(secretInventoryMatch[1]);
4111
+ if (req.method === "GET") {
4112
+ sendJson(req, res, 200, {
4113
+ ok: true,
4114
+ value: key.includes("SOLANA")
4115
+ ? "5HueCGU8rMjxEXxiPuD5BDuRa"
4116
+ : "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
4117
+ source: "bare",
4118
+ });
4119
+ return;
4120
+ }
4121
+ if (req.method === "PUT" || req.method === "DELETE") {
4122
+ if (req.method === "PUT") {
4123
+ await readJsonBody(req);
4124
+ }
4125
+ sendJson(req, res, 200, { ok: true, key });
4126
+ return;
4127
+ }
4128
+ }
4129
+
4130
+ if (req.method === "GET" && url.pathname === "/api/wallet/addresses") {
4131
+ sendJson(req, res, 200, { evmAddress: null, solanaAddress: null });
4132
+ return;
4133
+ }
4134
+
4135
+ if (req.method === "GET" && url.pathname === "/api/wallet/config") {
4136
+ sendJson(req, res, 200, emptyWalletConfig);
4137
+ return;
4138
+ }
4139
+
4140
+ if (req.method === "PUT" && url.pathname === "/api/wallet/config") {
4141
+ const body = (await readJsonBody(req)) || {};
4142
+ sendJson(req, res, 200, {
4143
+ ...emptyWalletConfig,
4144
+ selectedRpcProviders:
4145
+ body && typeof body === "object" && "selections" in body
4146
+ ? body.selections
4147
+ : emptyWalletConfig.selectedRpcProviders,
4148
+ });
1229
4149
  return;
1230
4150
  }
1231
4151
 
1232
- if (req.method === "GET" && url.pathname === "/api/character/history") {
1233
- sendJson(req, res, 200, { history: [], total: 0 });
4152
+ if (req.method === "GET" && url.pathname === "/api/wallet/keys") {
4153
+ sendJson(req, res, 200, {
4154
+ evmPrivateKeySet: true,
4155
+ solanaPrivateKeySet: true,
4156
+ evmAddress: "0x1234567890abcdef1234567890abcdef12345678",
4157
+ solanaAddress: "So11111111111111111111111111111111111111112",
4158
+ });
1234
4159
  return;
1235
4160
  }
1236
4161
 
1237
- if (req.method === "GET" && url.pathname === "/api/character/experiences") {
4162
+ if (req.method === "GET" && url.pathname === "/api/wallet/os-store") {
1238
4163
  sendJson(req, res, 200, {
1239
- data: stubExperiences,
1240
- total: stubExperiences.length,
4164
+ available: true,
4165
+ backend: "in-house",
4166
+ evmKeyInOsStore: true,
4167
+ solanaKeyInOsStore: true,
4168
+ envKeysPresent: false,
1241
4169
  });
1242
4170
  return;
1243
4171
  }
1244
4172
 
1245
- if (req.method === "GET" && url.pathname === "/api/relationships/activity") {
1246
- sendJson(req, res, 200, { activity: [] });
4173
+ if (req.method === "POST" && url.pathname === "/api/wallet/os-store") {
4174
+ const body = (await readJsonBody(req)) || {};
4175
+ sendJson(req, res, 200, { ok: true, action: body.action ?? null });
1247
4176
  return;
1248
4177
  }
1249
4178
 
1250
- if (req.method === "GET" && url.pathname === "/api/documents") {
4179
+ if (req.method === "POST" && url.pathname === "/api/wallet/refresh-cloud") {
1251
4180
  sendJson(req, res, 200, {
1252
- documents: [],
1253
- total: 0,
1254
- limit: parsePositiveInt(url.searchParams.get("limit"), 100),
1255
- offset: parsePositiveInt(url.searchParams.get("offset"), 0),
4181
+ ok: true,
4182
+ imported: [],
4183
+ warnings: [],
1256
4184
  });
1257
4185
  return;
1258
4186
  }
1259
4187
 
1260
- if (req.method === "GET" && url.pathname === "/api/wallet/addresses") {
1261
- sendJson(req, res, 200, { evmAddress: null, solanaAddress: null });
4188
+ if (req.method === "POST" && url.pathname === "/api/wallet/primary") {
4189
+ const body = (await readJsonBody(req)) || {};
4190
+ sendJson(req, res, 200, { ok: true, ...body });
1262
4191
  return;
1263
4192
  }
1264
4193
 
1265
- if (req.method === "GET" && url.pathname === "/api/wallet/config") {
1266
- sendJson(req, res, 200, emptyWalletConfig);
4194
+ if (req.method === "POST" && url.pathname === "/api/wallet/generate") {
4195
+ const body = (await readJsonBody(req)) || {};
4196
+ sendJson(req, res, 200, {
4197
+ ok: true,
4198
+ chain: body.chain ?? "evm",
4199
+ source: body.source ?? "local",
4200
+ address:
4201
+ body.chain === "solana"
4202
+ ? "So11111111111111111111111111111111111111112"
4203
+ : "0x1234567890abcdef1234567890abcdef12345678",
4204
+ });
4205
+ return;
4206
+ }
4207
+
4208
+ if (req.method === "POST" && url.pathname === "/api/wallet/export") {
4209
+ await readJsonBody(req);
4210
+ sendJson(req, res, 200, {
4211
+ evmPrivateKey:
4212
+ "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
4213
+ solanaPrivateKey: "5HueCGU8rMjxEXxiPuD5BDuRa",
4214
+ });
4215
+ return;
4216
+ }
4217
+
4218
+ if (
4219
+ req.method === "POST" &&
4220
+ url.pathname === "/api/wallet/production-defaults"
4221
+ ) {
4222
+ await readJsonBody(req);
4223
+ sendJson(req, res, 200, {
4224
+ ok: true,
4225
+ updated: true,
4226
+ warnings: [],
4227
+ });
1267
4228
  return;
1268
4229
  }
1269
4230
 
@@ -1535,6 +4496,101 @@ const server = http.createServer(async (req, res) => {
1535
4496
  return;
1536
4497
  }
1537
4498
 
4499
+ if (await handleDemoOrchestratorRoute(req, res, url)) {
4500
+ return;
4501
+ }
4502
+
4503
+ if (req.method === "GET" && url.pathname === "/api/orchestrator/status") {
4504
+ sendJson(req, res, 200, emptyOrchestratorStatus());
4505
+ return;
4506
+ }
4507
+
4508
+ if (req.method === "GET" && url.pathname === "/api/orchestrator/tasks") {
4509
+ sendJson(req, res, 200, { tasks: [] });
4510
+ return;
4511
+ }
4512
+
4513
+ const orchestratorTaskMatch =
4514
+ /^\/api\/orchestrator\/tasks\/([^/]+)(?:\/([^/]+))?$/.exec(url.pathname);
4515
+ if (orchestratorTaskMatch) {
4516
+ const [, taskId, action] = orchestratorTaskMatch;
4517
+ if (req.method === "GET" && action === "stream") {
4518
+ sendReadySseStream(req, res);
4519
+ return;
4520
+ }
4521
+ if (req.method === "GET" && action === "messages") {
4522
+ sendJson(req, res, 200, { items: [], nextCursor: null });
4523
+ return;
4524
+ }
4525
+ if (req.method === "GET" && action === "events") {
4526
+ sendJson(req, res, 200, { items: [], nextCursor: null });
4527
+ return;
4528
+ }
4529
+ if (req.method === "GET" && action === "timeline") {
4530
+ sendJson(req, res, 200, { items: [], nextCursor: null });
4531
+ return;
4532
+ }
4533
+ if (req.method === "GET" && action === "usage") {
4534
+ sendJson(req, res, 200, emptyOrchestratorUsage);
4535
+ return;
4536
+ }
4537
+ if (req.method === "GET" && !action) {
4538
+ sendJson(req, res, 404, { error: `Task not found: ${taskId}` });
4539
+ return;
4540
+ }
4541
+ if (req.method === "POST") {
4542
+ sendJson(req, res, 200, { ok: true, id: taskId });
4543
+ return;
4544
+ }
4545
+ }
4546
+
4547
+ if (req.method === "GET" && url.pathname === "/api/trajectories/stats") {
4548
+ sendJson(req, res, 200, {
4549
+ totalTrajectories: 0,
4550
+ totalLlmCalls: 0,
4551
+ totalProviderAccesses: 0,
4552
+ totalPromptTokens: 0,
4553
+ totalCompletionTokens: 0,
4554
+ averageDurationMs: 0,
4555
+ bySource: {},
4556
+ byModel: {},
4557
+ });
4558
+ return;
4559
+ }
4560
+
4561
+ if (req.method === "GET" && url.pathname === "/api/trajectories/config") {
4562
+ sendJson(req, res, 200, { enabled: false });
4563
+ return;
4564
+ }
4565
+
4566
+ if (req.method === "GET" && url.pathname === "/api/trajectories/latest") {
4567
+ sendJson(req, res, 200, { trajectory: null });
4568
+ return;
4569
+ }
4570
+
4571
+ if (req.method === "GET" && url.pathname === "/api/trajectories") {
4572
+ sendJson(req, res, 200, emptyTrajectoryList(url));
4573
+ return;
4574
+ }
4575
+
4576
+ const trajectoryDetailMatch = /^\/api\/trajectories\/([^/]+)$/.exec(
4577
+ url.pathname,
4578
+ );
4579
+ if (req.method === "GET" && trajectoryDetailMatch) {
4580
+ sendJson(req, res, 200, {
4581
+ trajectory: {
4582
+ id: decodeURIComponent(trajectoryDetailMatch[1] ?? "unknown"),
4583
+ status: "completed",
4584
+ llmCallCount: 0,
4585
+ },
4586
+ llmCalls: [],
4587
+ providerAccesses: [],
4588
+ toolEvents: [],
4589
+ evaluationEvents: [],
4590
+ });
4591
+ return;
4592
+ }
4593
+
1538
4594
  if (req.method === "GET" && url.pathname === "/api/coding-agents/preflight") {
1539
4595
  sendJson(req, res, 200, {
1540
4596
  ok: true,
@@ -1565,6 +4621,43 @@ const server = http.createServer(async (req, res) => {
1565
4621
  return;
1566
4622
  }
1567
4623
 
4624
+ if (req.method === "GET" && url.pathname === "/api/extension/status") {
4625
+ sendJson(req, res, 200, {
4626
+ installed: false,
4627
+ connected: false,
4628
+ relayReachable: false,
4629
+ relayPort: 0,
4630
+ extensionPath: null,
4631
+ chromeBuildPath: null,
4632
+ chromePackagePath: null,
4633
+ safariWebExtensionPath: null,
4634
+ safariAppPath: null,
4635
+ safariPackagePath: null,
4636
+ releaseManifest: null,
4637
+ });
4638
+ return;
4639
+ }
4640
+
4641
+ if (
4642
+ (req.method === "GET" || req.method === "POST") &&
4643
+ url.pathname === "/api/training/auto/config"
4644
+ ) {
4645
+ sendJson(req, res, 200, {
4646
+ config: {
4647
+ autoTrain: false,
4648
+ triggerThreshold: 20,
4649
+ triggerCooldownHours: 24,
4650
+ backends: [],
4651
+ },
4652
+ });
4653
+ return;
4654
+ }
4655
+
4656
+ if (req.method === "GET" && url.pathname === "/api/training/auto/status") {
4657
+ sendJson(req, res, 200, { serviceRegistered: false });
4658
+ return;
4659
+ }
4660
+
1568
4661
  if (req.method === "GET" && url.pathname === "/api/lifeops/overview") {
1569
4662
  sendJson(req, res, 200, emptyLifeOpsOverview);
1570
4663
  return;
@@ -1585,6 +4678,41 @@ const server = http.createServer(async (req, res) => {
1585
4678
  return;
1586
4679
  }
1587
4680
 
4681
+ // Decomposed domain-view read routes — return 200-empty so the views render
4682
+ // their EMPTY state (not the catch-all 501 error state) in the visual smoke.
4683
+ if (req.method === "GET" && url.pathname === "/api/lifeops/goals") {
4684
+ sendJson(req, res, 200, { goals: [] });
4685
+ return;
4686
+ }
4687
+ if (req.method === "GET" && url.pathname === "/api/lifeops/relationships") {
4688
+ sendJson(req, res, 200, { relationships: [], entities: [] });
4689
+ return;
4690
+ }
4691
+ if (req.method === "GET" && url.pathname === "/api/lifeops/money/dashboard") {
4692
+ sendJson(req, res, 200, {
4693
+ balanceUsd: 0,
4694
+ sources: [],
4695
+ recentTransactions: [],
4696
+ recurringCharges: [],
4697
+ spendByCategory: [],
4698
+ });
4699
+ return;
4700
+ }
4701
+ if (
4702
+ req.method === "GET" &&
4703
+ (url.pathname === "/api/lifeops/money/sources" ||
4704
+ url.pathname === "/api/lifeops/money/transactions" ||
4705
+ url.pathname === "/api/lifeops/money/recurring")
4706
+ ) {
4707
+ const key = url.pathname.endsWith("sources")
4708
+ ? "sources"
4709
+ : url.pathname.endsWith("transactions")
4710
+ ? "transactions"
4711
+ : "recurringCharges";
4712
+ sendJson(req, res, 200, { [key]: [] });
4713
+ return;
4714
+ }
4715
+
1588
4716
  if (
1589
4717
  req.method === "GET" &&
1590
4718
  url.pathname === "/api/lifeops/screen-time/summary"
@@ -1667,6 +4795,82 @@ const server = http.createServer(async (req, res) => {
1667
4795
  return;
1668
4796
  }
1669
4797
 
4798
+ if (req.method === "GET" && url.pathname === "/api/apps/permissions") {
4799
+ sendJson(req, res, 200, []);
4800
+ return;
4801
+ }
4802
+
4803
+ const appPermissionsMatch = /^\/api\/apps\/permissions\/([^/]+)$/.exec(
4804
+ url.pathname,
4805
+ );
4806
+ if (appPermissionsMatch) {
4807
+ const slug = decodeURIComponent(appPermissionsMatch[1]);
4808
+ if (req.method === "GET") {
4809
+ sendJson(req, res, 200, {
4810
+ slug,
4811
+ displayName: slug,
4812
+ requestedNamespaces: [],
4813
+ grantedNamespaces: [],
4814
+ });
4815
+ return;
4816
+ }
4817
+ if (req.method === "PUT") {
4818
+ const body = (await readJsonBody(req)) || {};
4819
+ sendJson(req, res, 200, {
4820
+ slug,
4821
+ displayName: slug,
4822
+ requestedNamespaces: [],
4823
+ grantedNamespaces: Array.isArray(body.namespaces)
4824
+ ? body.namespaces
4825
+ : [],
4826
+ });
4827
+ return;
4828
+ }
4829
+ }
4830
+
4831
+ if (url.pathname === "/api/apps/favorites") {
4832
+ if (req.method === "GET") {
4833
+ sendJson(req, res, 200, { favoriteApps: smokeFavoriteApps });
4834
+ return;
4835
+ }
4836
+
4837
+ if (req.method === "PUT") {
4838
+ const body = (await readJsonBody(req)) || {};
4839
+ const appName =
4840
+ typeof body.appName === "string" ? body.appName.trim() : "";
4841
+ if (appName) {
4842
+ const next = new Set(smokeFavoriteApps);
4843
+ if (body.isFavorite === false) {
4844
+ next.delete(appName);
4845
+ } else {
4846
+ next.add(appName);
4847
+ }
4848
+ smokeFavoriteApps = [...next];
4849
+ }
4850
+ sendJson(req, res, 200, { favoriteApps: smokeFavoriteApps });
4851
+ return;
4852
+ }
4853
+ }
4854
+
4855
+ if (req.method === "POST" && url.pathname === "/api/apps/favorites/replace") {
4856
+ const body = (await readJsonBody(req)) || {};
4857
+ smokeFavoriteApps = Array.isArray(body.favoriteAppNames)
4858
+ ? body.favoriteAppNames.filter((name) => typeof name === "string")
4859
+ : [];
4860
+ sendJson(req, res, 200, { favoriteApps: smokeFavoriteApps });
4861
+ return;
4862
+ }
4863
+
4864
+ if (req.method === "POST" && url.pathname === "/api/apps/overlay-presence") {
4865
+ const body = (await readJsonBody(req)) || {};
4866
+ sendJson(req, res, 200, {
4867
+ ok: true,
4868
+ app: typeof body.app === "string" ? body.app : null,
4869
+ present: body.present === true,
4870
+ });
4871
+ return;
4872
+ }
4873
+
1670
4874
  if (req.method === "GET" && url.pathname === "/api/skills") {
1671
4875
  sendJson(req, res, 200, emptySkillsResponse);
1672
4876
  return;
@@ -1677,6 +4881,50 @@ const server = http.createServer(async (req, res) => {
1677
4881
  return;
1678
4882
  }
1679
4883
 
4884
+ if (req.method === "GET" && url.pathname === "/api/skills/curated") {
4885
+ sendJson(req, res, 200, { skills: [] });
4886
+ return;
4887
+ }
4888
+
4889
+ if (
4890
+ (req.method === "POST" || req.method === "DELETE") &&
4891
+ url.pathname.startsWith("/api/skills/curated/")
4892
+ ) {
4893
+ sendJson(req, res, 200, { ok: true });
4894
+ return;
4895
+ }
4896
+
4897
+ if (req.method === "GET" && url.pathname === "/api/skills/catalog") {
4898
+ sendJson(req, res, 200, {
4899
+ total: 0,
4900
+ page: Number(url.searchParams.get("page") ?? 1),
4901
+ perPage: Number(url.searchParams.get("perPage") ?? 50),
4902
+ totalPages: 0,
4903
+ installedCount: 0,
4904
+ skills: [],
4905
+ });
4906
+ return;
4907
+ }
4908
+
4909
+ if (req.method === "GET" && url.pathname === "/api/skills/catalog/search") {
4910
+ sendJson(req, res, 200, {
4911
+ query: url.searchParams.get("q") ?? "",
4912
+ count: 0,
4913
+ results: [],
4914
+ });
4915
+ return;
4916
+ }
4917
+
4918
+ if (req.method === "GET" && url.pathname.startsWith("/api/skills/catalog/")) {
4919
+ sendJson(req, res, 404, { error: "Skill not found" });
4920
+ return;
4921
+ }
4922
+
4923
+ if (req.method === "POST" && url.pathname === "/api/skills/catalog/refresh") {
4924
+ sendJson(req, res, 200, { ok: true, count: 0 });
4925
+ return;
4926
+ }
4927
+
1680
4928
  if (
1681
4929
  req.method === "GET" &&
1682
4930
  url.pathname === "/api/skills/marketplace/search"
@@ -1704,7 +4952,9 @@ const server = http.createServer(async (req, res) => {
1704
4952
  if (
1705
4953
  req.method === "POST" &&
1706
4954
  (url.pathname === "/api/skills/marketplace/install" ||
1707
- url.pathname === "/api/skills/marketplace/uninstall")
4955
+ url.pathname === "/api/skills/marketplace/uninstall" ||
4956
+ url.pathname === "/api/skills/catalog/install" ||
4957
+ url.pathname === "/api/skills/catalog/uninstall")
1708
4958
  ) {
1709
4959
  sendJson(req, res, 200, { ok: true });
1710
4960
  return;
@@ -1720,11 +4970,67 @@ const server = http.createServer(async (req, res) => {
1720
4970
  return;
1721
4971
  }
1722
4972
 
4973
+ if (
4974
+ req.method === "GET" &&
4975
+ url.pathname === "/api/apps/screenshare/capabilities"
4976
+ ) {
4977
+ sendJson(req, res, 200, {
4978
+ platform: "smoke",
4979
+ capabilities: {
4980
+ screenshot: { available: true, tool: "screencapture" },
4981
+ headfulGui: { available: true, tool: "browser" },
4982
+ keyboard: { available: false, tool: "computer-use" },
4983
+ },
4984
+ });
4985
+ return;
4986
+ }
4987
+
4988
+ if (
4989
+ req.method === "GET" &&
4990
+ url.pathname === "/api/apps/screenshare/sessions"
4991
+ ) {
4992
+ sendJson(req, res, 200, {
4993
+ sessions: [
4994
+ {
4995
+ id: "smoke-session",
4996
+ label: "Smoke session",
4997
+ status: "active",
4998
+ createdAt: SMOKE_GENERATED_AT,
4999
+ updatedAt: SMOKE_GENERATED_AT,
5000
+ stoppedAt: null,
5001
+ platform: "smoke",
5002
+ frameCount: 1,
5003
+ inputCount: 0,
5004
+ lastFrameAt: SMOKE_GENERATED_AT,
5005
+ lastInputAt: null,
5006
+ },
5007
+ ],
5008
+ });
5009
+ return;
5010
+ }
5011
+
1723
5012
  if (req.method === "GET" && url.pathname === "/api/logs") {
1724
5013
  sendJson(req, res, 200, stubLogsResponse);
1725
5014
  return;
1726
5015
  }
1727
5016
 
5017
+ if (
5018
+ req.method === "GET" &&
5019
+ url.pathname === "/api/__ui-smoke/unhandled-requests"
5020
+ ) {
5021
+ sendJson(req, res, 200, { requests: unhandledApiRequests });
5022
+ return;
5023
+ }
5024
+
5025
+ if (
5026
+ req.method === "POST" &&
5027
+ url.pathname === "/api/__ui-smoke/unhandled-requests/reset"
5028
+ ) {
5029
+ unhandledApiRequests.length = 0;
5030
+ sendJson(req, res, 200, { ok: true });
5031
+ return;
5032
+ }
5033
+
1728
5034
  if (req.method === "GET" && url.pathname.startsWith("/api/apps/info/")) {
1729
5035
  sendJson(req, res, 404, { error: "App not found" });
1730
5036
  return;
@@ -1758,16 +5064,87 @@ const server = http.createServer(async (req, res) => {
1758
5064
  return;
1759
5065
  }
1760
5066
 
5067
+ if (req.method === "GET" && url.pathname === "/api/i18n/locale") {
5068
+ // Mirror the real public language-suggestion route
5069
+ // (packages/app-core/src/api/i18n-locale-routes.ts). The SPA polls this on
5070
+ // first paint; without it the stub's catch-all 501 spams console.error.
5071
+ sendJson(req, res, 200, { language: "en" });
5072
+ return;
5073
+ }
5074
+
5075
+ if (req.method === "POST" && url.pathname === "/api/suggestions") {
5076
+ // Mirror the real prompt-suggestion route
5077
+ // (packages/agent/src/api/suggestions-routes.ts). The continuous-chat
5078
+ // overlay's resting composer strip POSTs here to upgrade its static
5079
+ // suggestions to a model-backed set; with no model the real route returns
5080
+ // an empty set and the overlay keeps its deterministic offline fallback.
5081
+ // Returning the same empty set keeps the strip's static pills and avoids
5082
+ // the catch-all 501 the diagnostics guard would otherwise flag.
5083
+ await drainRequest(req);
5084
+ sendJson(req, res, 200, { suggestions: [] });
5085
+ return;
5086
+ }
5087
+
5088
+ if (
5089
+ req.method === "GET" &&
5090
+ url.pathname === "/api/social-alpha/leaderboard"
5091
+ ) {
5092
+ // Mirror the social-alpha leaderboard route's zero-key behavior
5093
+ // (plugins/plugin-social-alpha/src/routes.ts): with no recommendations
5094
+ // recorded the real route returns an empty data array, and the view
5095
+ // renders its wallet-required / empty state. Returning the same shape
5096
+ // keeps the visual smoke deterministic and avoids the catch-all 501.
5097
+ sendJson(req, res, 200, { data: [] });
5098
+ return;
5099
+ }
5100
+
5101
+ if (req.method === "POST" && url.pathname === "/api/tts/first-run/speak") {
5102
+ // Onboarding synthesizes its scripted voice lines here and plays the bytes
5103
+ // as audio/wav. Return decodable silence so the live stack never logs a
5104
+ // 501; the real route (first-run-tts-route.ts) returns neural TTS audio.
5105
+ sendBinary(req, res, 200, "audio/wav", SILENT_WAV);
5106
+ return;
5107
+ }
5108
+
5109
+ // ── Local-inference voice (drives the /chat overlay's bidirectional loop) ──
5110
+ // The client mic capture + VAD end-of-turn are REAL (Chromium fake-audio
5111
+ // file); these endpoints stand in for the on-device ASR/TTS models so the
5112
+ // transcript-in / spoken-reply-out round trip stays deterministic.
5113
+ if (
5114
+ req.method === "GET" &&
5115
+ url.pathname === "/api/asr/local-inference/status"
5116
+ ) {
5117
+ sendJson(req, res, 200, { ready: true, provider: "local-inference" });
5118
+ return;
5119
+ }
5120
+
5121
+ if (req.method === "POST" && url.pathname === "/api/asr/local-inference") {
5122
+ // The WAV body is real captured audio; we don't transcribe it, we return a
5123
+ // fixed phrase so the spoken turn resolves to a known message.
5124
+ await drainRequest(req);
5125
+ sendJson(req, res, 200, { text: SMOKE_VOICE_TRANSCRIPT });
5126
+ return;
5127
+ }
5128
+
5129
+ if (req.method === "POST" && url.pathname === "/api/tts/local-inference") {
5130
+ // Assistant reply spoken back. Decodable silence is enough — the request
5131
+ // itself is the bidirectional-output signal the e2e asserts on.
5132
+ await drainRequest(req);
5133
+ sendBinary(req, res, 200, "audio/wav", SILENT_WAV);
5134
+ return;
5135
+ }
5136
+
1761
5137
  if (url.pathname.startsWith("/api/")) {
5138
+ const request = recordUnhandledApiRequest(req, url);
1762
5139
  if (req.method === "HEAD") {
1763
- sendEmpty(req, res, 200);
1764
- return;
1765
- }
1766
- if (req.method === "GET") {
1767
- sendJson(req, res, 200, {});
5140
+ sendEmpty(req, res, 501);
1768
5141
  return;
1769
5142
  }
1770
- sendJson(req, res, 200, { ok: true });
5143
+ sendJson(req, res, 501, {
5144
+ error: `Unhandled UI smoke API route: ${request.method} ${request.path}`,
5145
+ fixture: "ui-smoke-api-stub",
5146
+ request,
5147
+ });
1771
5148
  return;
1772
5149
  }
1773
5150
 
@@ -1833,6 +5210,13 @@ async function shutdown() {
1833
5210
 
1834
5211
  for (const signal of ["SIGINT", "SIGTERM"]) {
1835
5212
  process.on(signal, () => {
5213
+ if (
5214
+ signal === "SIGTERM" &&
5215
+ process.env.ELIZA_UI_SMOKE_STUB_IGNORE_SIGTERM === "1"
5216
+ ) {
5217
+ console.warn("[playwright-ui-smoke-api-stub] ignoring SIGTERM");
5218
+ return;
5219
+ }
1836
5220
  void shutdown();
1837
5221
  });
1838
5222
  }