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

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 (95) hide show
  1. package/api/i18n-locale-routes.d.ts +7 -0
  2. package/api/i18n-locale-routes.d.ts.map +1 -0
  3. package/api/i18n-locale-routes.js +58 -0
  4. package/api/ios-local-agent-transport.d.ts +3 -0
  5. package/api/ios-local-agent-transport.d.ts.map +1 -1
  6. package/api/ios-local-agent-transport.js +22 -1
  7. package/api/server.d.ts.map +1 -1
  8. package/api/server.js +5 -0
  9. package/benchmark/cerebras-autowire.d.ts.map +1 -1
  10. package/benchmark/cerebras-autowire.js +9 -2
  11. package/package.json +36 -36
  12. package/packaging/debian/rules +1 -1
  13. package/packaging/flatpak/generate-sources.sh +6 -1
  14. package/packaging/snap/snapcraft.yaml +15 -11
  15. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaAgentService.java +2 -1
  16. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaNativeBridge.java +5 -0
  17. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaStartupTrace.java +28 -0
  18. package/platforms/android/app/src/main/java/ai/elizaos/app/ElizaVoicePlugin.java +1 -1
  19. package/platforms/android/app/src/main/java/ai/elizaos/app/MainActivity.java +1 -0
  20. package/platforms/electrobun/package.json +10 -10
  21. package/platforms/electrobun/remotes/local-model/README.md +2 -5
  22. package/platforms/electrobun/remotes/local-model/src/bun/eliza1-catalog.ts +0 -16
  23. package/platforms/electrobun/remotes/local-model/src/dev/phase8-smoke.ts +0 -2
  24. package/platforms/electrobun/scripts/smoke-test.sh +8 -2
  25. package/platforms/electrobun/scripts/stage-macos-release-artifacts.sh +8 -2
  26. package/platforms/electrobun/src/bridge/electrobun-boot-config.ts +8 -0
  27. package/platforms/electrobun/src/bridge/electrobun-crypto-ready.ts +5 -1
  28. package/platforms/electrobun/src/bridge/electrobun-direct-rpc.ts +5 -11
  29. package/platforms/electrobun/src/preload.js +1 -1
  30. package/platforms/ios/App/App/Base.lproj/Main.storyboard +1 -1
  31. package/platforms/ios/App/App/ElizaBridgeViewController.swift +22 -0
  32. package/platforms/ios/App/App/ElizaStartupTrace.swift +12 -0
  33. package/platforms/ios/App/App.xcodeproj/project.pbxproj +8 -0
  34. package/runtime/eliza.d.ts.map +1 -1
  35. package/runtime/eliza.js +18 -0
  36. package/runtime/voice-warmup.d.ts +4 -4
  37. package/runtime/voice-warmup.d.ts.map +1 -1
  38. package/runtime/voice-warmup.js +4 -4
  39. package/scripts/aosp/compile-libllama-paths.mjs +110 -0
  40. package/scripts/aosp/compile-libllama.mjs +35 -106
  41. package/scripts/aosp/compile-libllama.test.mjs +18 -2
  42. package/scripts/assert-required-bundled-packages.test.ts +24 -2
  43. package/scripts/build-bundled-agent-skills-artifact.mjs +32 -8
  44. package/scripts/build-bundled-orchestrator-artifact.mjs +34 -12
  45. package/scripts/build-llama-cpp-mtp.mjs +27 -3
  46. package/scripts/build-patched-electrobun-cli.mjs +30 -2
  47. package/scripts/bun-riscv64/bun-version.json +1 -1
  48. package/scripts/bun-riscv64/validate.sh +21 -8
  49. package/scripts/check-real-local-reset.ts +13 -1
  50. package/scripts/check-sms-gateway-completion-audit.mjs +96 -31
  51. package/scripts/check-sms-gateway-readiness.mjs +54 -17
  52. package/scripts/clean-repo.mjs +21 -3
  53. package/scripts/copy-runtime-node-modules.ts +68 -63
  54. package/scripts/desktop-build.mjs +46 -5
  55. package/scripts/dev-platform-no-install.test.mjs +19 -0
  56. package/scripts/dev-platform.mjs +6 -2
  57. package/scripts/disable-local-eliza-workspace.mjs +23 -1
  58. package/scripts/docker-ci-smoke.sh +6 -5
  59. package/scripts/ensure-avatars.mjs +18 -5
  60. package/scripts/ensure-bundled-workspaces.mjs +4 -15
  61. package/scripts/ensure-type-package-aliases.mjs +47 -3
  62. package/scripts/ffi-stub/Makefile +5 -2
  63. package/scripts/ios-xcframework/build-xcframework.mjs +22 -11
  64. package/scripts/ios-xcframework/run-physical-device-smoke.mjs +99 -6
  65. package/scripts/ios-xcframework/runtime-symbol-shim.c +560 -105
  66. package/scripts/lib/agent-source-watcher.test.mjs +24 -4
  67. package/scripts/lib/apple-entitlement-audit.test.mjs +19 -2
  68. package/scripts/lib/artifact-staleness.test.mts +18 -1
  69. package/scripts/lib/patch-bun-exports.mjs +20 -2
  70. package/scripts/lib/patch-bun-exports.test.mjs +108 -4
  71. package/scripts/lib/renderer-build-manifest.test.mts +18 -1
  72. package/scripts/lib/stage-android-agent.mjs +16 -3
  73. package/scripts/lib/verify-ondevice-artifact.test.mts +18 -1
  74. package/scripts/link-docker-local-app-packages.mjs +26 -1
  75. package/scripts/mas-smoke.test.mjs +25 -9
  76. package/scripts/omnivoice-fuse/prepare.mjs +27 -4
  77. package/scripts/package-electrobun-linux.mjs +22 -7
  78. package/scripts/patch-deps.mjs +18 -5
  79. package/scripts/playwright-ui-live-stack.ts +16 -3
  80. package/scripts/playwright-ui-smoke-api-stub.mjs +167 -2
  81. package/scripts/prepare-ios-cocoapods.sh +5 -1
  82. package/scripts/prune-cdn-local-assets.mjs +52 -5
  83. package/scripts/run-mobile-build-android-app-actions.test.mjs +19 -1
  84. package/scripts/run-mobile-build-mtp-staleness.test.mts +20 -4
  85. package/scripts/run-mobile-build.mjs +63 -2
  86. package/scripts/stage-android-agent.test.mjs +19 -1
  87. package/scripts/stage-desktop-fused-lib.mjs +26 -1
  88. package/scripts/sync-desktop-renderer.mjs +53 -12
  89. package/scripts/test-sms-gateway-software.mjs +20 -4
  90. package/cli/command-format.d.ts +0 -2
  91. package/cli/command-format.d.ts.map +0 -1
  92. package/cli/command-format.js +0 -20
  93. package/register-runtime-hooks.d.ts +0 -2
  94. package/register-runtime-hooks.d.ts.map +0 -1
  95. package/register-runtime-hooks.js +0 -19
@@ -23,6 +23,7 @@
23
23
  */
24
24
 
25
25
  import assert from "node:assert/strict";
26
+ import { execFileSync } from "node:child_process";
26
27
  import fs from "node:fs";
27
28
  import os from "node:os";
28
29
  import path from "node:path";
@@ -44,6 +45,14 @@ import {
44
45
  import { useIsolatedConfigEnv } from "../test/helpers/isolated-config.ts";
45
46
  import { createRealTestRuntime } from "../test/helpers/real-runtime.ts";
46
47
 
48
+ const REPO_ROOT = path.resolve(import.meta.dirname, "..", "..", "..");
49
+ const CLEANUP_HELPER_SCRIPT = path.join(
50
+ REPO_ROOT,
51
+ "packages",
52
+ "scripts",
53
+ "rm-path-recursive.mjs",
54
+ );
55
+
47
56
  async function getJson(url: string): Promise<Record<string, unknown>> {
48
57
  const res = await fetch(url);
49
58
  assert.equal(res.status, 200, `${url} should return 200, got ${res.status}`);
@@ -223,7 +232,10 @@ async function main(): Promise<void> {
223
232
  } finally {
224
233
  await configEnv.restore().catch(() => undefined);
225
234
  try {
226
- fs.rmSync(dataRoot, { recursive: true, force: true });
235
+ execFileSync(process.execPath, [CLEANUP_HELPER_SCRIPT, dataRoot], {
236
+ cwd: REPO_ROOT,
237
+ stdio: "ignore",
238
+ });
227
239
  } catch {
228
240
  // best-effort temp cleanup
229
241
  }
@@ -6,7 +6,7 @@
6
6
  * prints which objective requirements are currently proven versus externally
7
7
  * blocked.
8
8
  */
9
- import { spawnSync } from "node:child_process";
9
+ import { execFileSync, spawnSync } from "node:child_process";
10
10
  import fs from "node:fs";
11
11
  import path from "node:path";
12
12
  import { fileURLToPath } from "node:url";
@@ -15,6 +15,12 @@ const scriptDir = path.dirname(fileURLToPath(import.meta.url));
15
15
  const appCoreRoot = path.resolve(scriptDir, "..");
16
16
  const repoRoot = path.resolve(scriptDir, "..", "..", "..");
17
17
  const packagesRoot = path.join(repoRoot, "packages");
18
+ const cleanupHelperScript = path.join(
19
+ repoRoot,
20
+ "packages",
21
+ "scripts",
22
+ "rm-path-recursive.mjs",
23
+ );
18
24
  const defaultEvidencePath = path.join(
19
25
  repoRoot,
20
26
  ".eliza-local",
@@ -70,10 +76,13 @@ function parseArgs(argv) {
70
76
  const checks = [
71
77
  {
72
78
  key: "homepage-bundle",
73
- label: "published homepage bundle points users at the shared gateway number",
79
+ label:
80
+ "published homepage bundle points users at the shared gateway number",
74
81
  command: ["node", ["./scripts/check-homepage-public-readiness.mjs"]],
75
82
  pass: (result) =>
76
- /PASS homepage-bundle: .*gateway=yes personal-number=no/.test(result.output),
83
+ /PASS homepage-bundle: .*gateway=yes personal-number=no/.test(
84
+ result.output,
85
+ ),
77
86
  },
78
87
  {
79
88
  key: "homepage-public-dns",
@@ -103,7 +112,8 @@ const checks = [
103
112
  },
104
113
  {
105
114
  key: "cloud-onboarding",
106
- label: "production Cloud API routes unknown sender to onboarding through +14159611510/bluebubbles/blooio, gets product/pricing/$5 credit and login link",
115
+ label:
116
+ "production Cloud API routes unknown sender to onboarding through +14159611510/bluebubbles/blooio, gets product/pricing/$5 credit and login link",
107
117
  command: ["node", ["./scripts/verify-cloud-api-production-deploy.mjs"]],
108
118
  pass: (result) =>
109
119
  result.status === 0 &&
@@ -118,7 +128,8 @@ const checks = [
118
128
  },
119
129
  {
120
130
  key: "routing-contracts",
121
- label: "known-owner priority, friend-contact routing, and contact recording contracts pass",
131
+ label:
132
+ "known-owner priority, friend-contact routing, and contact recording contracts pass",
122
133
  command: [
123
134
  "bun",
124
135
  [
@@ -162,7 +173,8 @@ const checks = [
162
173
  /Cannot find module '@elizaos\/core'|Cannot find package '@elizaos\/core'|WriteFailed/.test(
163
174
  result.output,
164
175
  ),
165
- blockedDetail: "linked workspace test runtime is not built or Bun coverage output failed",
176
+ blockedDetail:
177
+ "linked workspace test runtime is not built or Bun coverage output failed",
166
178
  next: [
167
179
  "build linked workspaces: bun run --cwd packages/cloud-shared build:linked-workspaces",
168
180
  "rerun: bun run --cwd packages/app-core sms-gateway:status",
@@ -170,7 +182,8 @@ const checks = [
170
182
  },
171
183
  {
172
184
  key: "provisioning-handoff",
173
- label: "post-login provisioning grants starter credit and copies onboarding transcript into agent memory",
185
+ label:
186
+ "post-login provisioning grants starter credit and copies onboarding transcript into agent memory",
174
187
  command: [
175
188
  "bun",
176
189
  [
@@ -199,29 +212,45 @@ const checks = [
199
212
  cwd: () => createBunTestCwd("sms-gateway-provisioning-"),
200
213
  pass: (result) =>
201
214
  result.status === 0 &&
202
- /12 pass/.test(result.output) &&
215
+ /\d+ pass/.test(result.output) &&
203
216
  /0 fail/.test(result.output),
204
217
  },
205
218
  {
206
219
  key: "android-apk",
207
- label: "Android SMS gateway APK is built and has the required gateway manifest surface",
208
- command: ["node", ["./scripts/install-android-sms-gateway.mjs", "--doctor"]],
220
+ label:
221
+ "Android SMS gateway APK is built and has the required gateway manifest surface",
222
+ command: [
223
+ "node",
224
+ ["./scripts/install-android-sms-gateway.mjs", "--doctor"],
225
+ ],
209
226
  pass: (result) =>
210
227
  /PASS apk: .*eliza-android-sms-gateway-debug\.apk/.test(result.output) &&
211
- /PASS apk-manifest: SMS gateway manifest surface is present/.test(result.output),
228
+ /PASS apk-manifest: SMS gateway manifest surface is present/.test(
229
+ result.output,
230
+ ),
212
231
  },
213
232
  {
214
233
  key: "android-transport",
215
234
  label: "Android physical SMS gateway is installed and physically verified",
216
235
  command: [
217
236
  "node",
218
- ["./scripts/verify-android-sms-gateway-e2e.mjs", "--wait-device", "2", "--timeout", "1"],
237
+ [
238
+ "./scripts/verify-android-sms-gateway-e2e.mjs",
239
+ "--wait-device",
240
+ "2",
241
+ "--timeout",
242
+ "1",
243
+ ],
219
244
  ],
220
245
  pass: (result) =>
221
246
  result.status === 0 &&
222
247
  /Physical Android SMS gateway verification passed/.test(result.output),
223
- blocked: (result) => /Timed out waiting .* for an adb device|Missing SMS gateway milestones/.test(result.output),
224
- blockedDetail: "Android phone is not paired/connected and physical SMS milestones are not proven",
248
+ blocked: (result) =>
249
+ /Timed out waiting .* for an adb device|Missing SMS gateway milestones/.test(
250
+ result.output,
251
+ ),
252
+ blockedDetail:
253
+ "Android phone is not paired/connected and physical SMS milestones are not proven",
225
254
  next: [
226
255
  "open Android Developer Options > Wireless debugging > Pair device with pairing code",
227
256
  "leave this running while opening the pairing screen: bun run --cwd packages/app-core sms-gateway:watch:pair",
@@ -231,24 +260,35 @@ const checks = [
231
260
  },
232
261
  {
233
262
  key: "bluebubbles-inbound",
234
- label: "BlueBubbles fallback bridge can receive and forward inbound events to Cloud as +14159611510",
263
+ label:
264
+ "BlueBubbles fallback bridge can receive and forward inbound events to Cloud as +14159611510",
235
265
  command: ["node", ["./scripts/verify-bluebubbles-inbound-readiness.mjs"]],
236
266
  pass: (result) =>
237
267
  result.status === 0 &&
238
268
  /gateway=\+14159611510/.test(result.output) &&
239
269
  /inbound=pass/.test(result.output),
240
270
  blocked: (result) =>
241
- /bridge|cloud-secret|bluebubbles-server|inbound-webhook|gateway/.test(result.output),
242
- blockedDetail: "BlueBubbles bridge, server, cloud secret, or inbound webhook is not ready",
243
- next: ["rerun bridge doctor: bun run --cwd packages/app-core sms-gateway:doctor"],
271
+ /bridge|cloud-secret|bluebubbles-server|inbound-webhook|gateway/.test(
272
+ result.output,
273
+ ),
274
+ blockedDetail:
275
+ "BlueBubbles bridge, server, cloud secret, or inbound webhook is not ready",
276
+ next: [
277
+ "rerun bridge doctor: bun run --cwd packages/app-core sms-gateway:doctor",
278
+ ],
244
279
  },
245
280
  {
246
281
  key: "bluebubbles-transport",
247
282
  label: "BlueBubbles fallback outbound path is real-send validated",
248
283
  command: ["bun", ["run", "sms-gateway:validate:bluebubbles"]],
249
- pass: (result) => result.status === 0 && /PASS .* validated at/.test(result.output),
250
- blocked: (result) => /Refusing to send without --confirm-real-send|Shortcut outbound validation missing/.test(result.output),
251
- blockedDetail: "real outbound validation send has not been explicitly confirmed",
284
+ pass: (result) =>
285
+ result.status === 0 && /PASS .* validated at/.test(result.output),
286
+ blocked: (result) =>
287
+ /Refusing to send without --confirm-real-send|Shortcut outbound validation missing/.test(
288
+ result.output,
289
+ ),
290
+ blockedDetail:
291
+ "real outbound validation send has not been explicitly confirmed",
252
292
  next: [
253
293
  "after explicit real-send approval, run: bun run --cwd packages/app-core sms-gateway:validate:bluebubbles -- --confirm-real-send",
254
294
  "then verify pending egress: bun run --cwd packages/app-core sms-gateway:verify:bluebubbles",
@@ -267,6 +307,13 @@ function createBunTestCwd(prefix) {
267
307
  return cwd;
268
308
  }
269
309
 
310
+ function removePathRecursive(targetPath) {
311
+ execFileSync(process.execPath, [cleanupHelperScript, targetPath], {
312
+ cwd: repoRoot,
313
+ stdio: "inherit",
314
+ });
315
+ }
316
+
270
317
  function run(command, args, { cwd = appCoreRoot } = {}) {
271
318
  const result = spawnSync(command, args, {
272
319
  cwd,
@@ -304,7 +351,7 @@ function summarizeEvidenceJson(value) {
304
351
  "sentCount",
305
352
  "error",
306
353
  ]) {
307
- if (Object.prototype.hasOwnProperty.call(value, key)) {
354
+ if (Object.hasOwn(value, key)) {
308
355
  summary[key] = value[key];
309
356
  }
310
357
  }
@@ -326,7 +373,7 @@ function summarizeEvidenceJson(value) {
326
373
  "apexRecords",
327
374
  "wwwCnames",
328
375
  ]) {
329
- if (Object.prototype.hasOwnProperty.call(value.details, key)) {
376
+ if (Object.hasOwn(value.details, key)) {
330
377
  summary[key] = value.details[key];
331
378
  }
332
379
  }
@@ -364,8 +411,12 @@ function writeEvidence({ evidencePath, ok, results }) {
364
411
  ok,
365
412
  checkedAt: new Date().toISOString(),
366
413
  gatewayPhoneNumber: "+14159611510",
367
- proven: results.filter((result) => result.status === "proven").map((result) => result.key),
368
- blocked: results.filter((result) => result.status === "blocked").map((result) => result.key),
414
+ proven: results
415
+ .filter((result) => result.status === "proven")
416
+ .map((result) => result.key),
417
+ blocked: results
418
+ .filter((result) => result.status === "blocked")
419
+ .map((result) => result.key),
369
420
  requirements: results,
370
421
  };
371
422
  fs.writeFileSync(evidencePath, `${JSON.stringify(evidence, null, 2)}\n`);
@@ -379,7 +430,7 @@ for (const check of checks) {
379
430
  const [command, args] = check.command;
380
431
  const cwd = check.cwd?.();
381
432
  const result = run(command, args, { cwd });
382
- if (cwd) fs.rmSync(cwd, { recursive: true, force: true });
433
+ if (cwd) removePathRecursive(cwd);
383
434
  const passed = check.pass(result);
384
435
  const isBlocked = !passed && check.blocked?.(result);
385
436
  if (passed) {
@@ -401,7 +452,9 @@ for (const check of checks) {
401
452
  const detail = isBlocked
402
453
  ? check.blockedDetail
403
454
  : oneLine(result.output).slice(0, 240) || `exit ${result.status}`;
404
- console.log(`[sms-gateway-audit] BLOCKED ${check.key}: ${check.label}; ${detail}`);
455
+ console.log(
456
+ `[sms-gateway-audit] BLOCKED ${check.key}: ${check.label}; ${detail}`,
457
+ );
405
458
  for (const next of check.next ?? []) {
406
459
  console.log(`[sms-gateway-audit] NEXT ${check.key}: ${next}`);
407
460
  }
@@ -419,10 +472,22 @@ for (const check of checks) {
419
472
  }
420
473
 
421
474
  if (blocked) {
422
- console.log("[sms-gateway-audit] status=blocked physical/end-to-end completion is not proven.");
423
- writeEvidence({ evidencePath: args.evidencePath, ok: false, results: evidenceResults });
475
+ console.log(
476
+ "[sms-gateway-audit] status=blocked physical/end-to-end completion is not proven.",
477
+ );
478
+ writeEvidence({
479
+ evidencePath: args.evidencePath,
480
+ ok: false,
481
+ results: evidenceResults,
482
+ });
424
483
  process.exitCode = 1;
425
484
  } else {
426
- console.log("[sms-gateway-audit] status=complete all objective requirements are currently proven.");
427
- writeEvidence({ evidencePath: args.evidencePath, ok: true, results: evidenceResults });
485
+ console.log(
486
+ "[sms-gateway-audit] status=complete all objective requirements are currently proven.",
487
+ );
488
+ writeEvidence({
489
+ evidencePath: args.evidencePath,
490
+ ok: true,
491
+ results: evidenceResults,
492
+ });
428
493
  }
@@ -5,7 +5,7 @@
5
5
  * This command is read-only: it does not send SMS and does not modify macOS,
6
6
  * Android, BlueBubbles, or cloud state.
7
7
  */
8
- import { spawnSync } from "node:child_process";
8
+ import { execFileSync, spawnSync } from "node:child_process";
9
9
  import fs from "node:fs";
10
10
  import path from "node:path";
11
11
  import { fileURLToPath } from "node:url";
@@ -13,9 +13,21 @@ import { fileURLToPath } from "node:url";
13
13
  const scriptDir = path.dirname(fileURLToPath(import.meta.url));
14
14
  const repoRoot = path.resolve(scriptDir, "..", "..", "..");
15
15
  const packagesRoot = path.resolve(scriptDir, "..", "..");
16
- const homepageScript = path.join(scriptDir, "check-homepage-public-readiness.mjs");
16
+ const cleanupHelperScript = path.join(
17
+ repoRoot,
18
+ "packages",
19
+ "scripts",
20
+ "rm-path-recursive.mjs",
21
+ );
22
+ const homepageScript = path.join(
23
+ scriptDir,
24
+ "check-homepage-public-readiness.mjs",
25
+ );
17
26
  const installScript = path.join(scriptDir, "install-android-sms-gateway.mjs");
18
- const cloudOnboardingScript = path.join(scriptDir, "verify-cloud-sms-onboarding-flow.mjs");
27
+ const cloudOnboardingScript = path.join(
28
+ scriptDir,
29
+ "verify-cloud-sms-onboarding-flow.mjs",
30
+ );
19
31
  const routingContractTests = [
20
32
  path.join(
21
33
  packagesRoot,
@@ -43,7 +55,8 @@ const routingContractTests = [
43
55
  "index.test.ts",
44
56
  ),
45
57
  ];
46
- const adbPath = "/opt/homebrew/share/android-commandlinetools/platform-tools/adb";
58
+ const adbPath =
59
+ "/opt/homebrew/share/android-commandlinetools/platform-tools/adb";
47
60
  const bridgeUrl = "http://127.0.0.1:8795";
48
61
  const onboardingContinuationUrl =
49
62
  "https://elizaos-homepage.pages.dev/get-started/?onboardingSession=readiness-smoke";
@@ -71,7 +84,9 @@ function printSection(title, result) {
71
84
  if (result.stdout.trim()) console.log(result.stdout.trim());
72
85
  if (result.stderr.trim()) console.error(result.stderr.trim());
73
86
  if (result.status !== 0) {
74
- console.error(`[sms-gateway-readiness] ${title} exited with ${result.status}`);
87
+ console.error(
88
+ `[sms-gateway-readiness] ${title} exited with ${result.status}`,
89
+ );
75
90
  blocked = true;
76
91
  }
77
92
  }
@@ -91,11 +106,14 @@ function usbInventoryFromIoreg() {
91
106
  const devices = [];
92
107
  for (const line of result.stdout.split(/\r?\n/)) {
93
108
  const nameMatch = line.match(/"USB Product Name"\s*=\s*"([^"]+)"/);
94
- const registryMatch = line.match(/\+\-o\s+([^@<]+)@/);
109
+ const registryMatch = line.match(/\+-o\s+([^@<]+)@/);
95
110
  const name = nameMatch?.[1] ?? registryMatch?.[1];
96
111
  if (!name) continue;
97
112
  const trimmed = name.trim();
98
- if (!trimmed || /Root Hub|XHCI|\bUSB\s*(?:3\.|2\.|1\.|Bus)\b/i.test(trimmed)) {
113
+ if (
114
+ !trimmed ||
115
+ /Root Hub|XHCI|\bUSB\s*(?:3\.|2\.|1\.|Bus)\b/i.test(trimmed)
116
+ ) {
99
117
  continue;
100
118
  }
101
119
  if (!devices.includes(trimmed)) devices.push(trimmed);
@@ -123,9 +141,7 @@ function printHostUsbState() {
123
141
  const fallback = usbInventoryFromIoreg();
124
142
  printSection("host usb", {
125
143
  status: fallback.status,
126
- stdout: fallback.stdout.trim()
127
- ? fallback.stdout.trim()
128
- : fallback.stdout,
144
+ stdout: fallback.stdout.trim() ? fallback.stdout.trim() : fallback.stdout,
129
145
  stderr: fallback.stderr.trim(),
130
146
  });
131
147
  }
@@ -155,7 +171,10 @@ function fetchDeployedGetStartedChunk(body) {
155
171
  };
156
172
  }
157
173
 
158
- const chunkUrl = new URL(`/assets/${getStartedMatch[1]}`, onboardingContinuationUrl).href;
174
+ const chunkUrl = new URL(
175
+ `/assets/${getStartedMatch[1]}`,
176
+ onboardingContinuationUrl,
177
+ ).href;
159
178
  const chunk = curlText(chunkUrl);
160
179
  if (chunk.status !== 0) return chunk;
161
180
 
@@ -186,16 +205,21 @@ function printOnboardingContinuationState() {
186
205
  const statusLine = lines.pop() ?? "";
187
206
  const body = lines.join("\n");
188
207
  const [httpCode, effectiveUrl] = statusLine.split(/\s+/, 2);
189
- const hasAppShell = body.includes('id="root"') && body.includes("/assets/index-");
208
+ const hasAppShell =
209
+ body.includes('id="root"') && body.includes("/assets/index-");
190
210
  const chunk = hasAppShell
191
211
  ? fetchDeployedGetStartedChunk(body)
192
212
  : { status: 1, stdout: "", stderr: "app shell missing" };
193
213
  const hasOnboardingSession = chunk.stdout.includes("onboardingSession");
194
- const hasOnboardingChatApi = chunk.stdout.includes("/api/eliza-app/first-run/chat");
214
+ const hasOnboardingChatApi = chunk.stdout.includes(
215
+ "/api/eliza-app/first-run/chat",
216
+ );
195
217
  const hasBlooioPlatform = chunk.stdout.includes("blooio");
196
218
  const passed =
197
219
  httpCode === "200" &&
198
- effectiveUrl?.startsWith("https://elizaos-homepage.pages.dev/get-started/") &&
220
+ effectiveUrl?.startsWith(
221
+ "https://elizaos-homepage.pages.dev/get-started/",
222
+ ) &&
199
223
  hasAppShell &&
200
224
  chunk.status === 0 &&
201
225
  hasOnboardingSession &&
@@ -207,12 +231,18 @@ function printOnboardingContinuationState() {
207
231
  `url=${effectiveUrl || onboardingContinuationUrl} status=${httpCode || "unknown"} app-shell=${hasAppShell ? "yes" : "no"}` +
208
232
  ` chunk=${chunk.url ?? "unknown"} onboardingSession=${hasOnboardingSession ? "yes" : "no"}` +
209
233
  ` onboardingChatApi=${hasOnboardingChatApi ? "yes" : "no"} platform=blooio:${hasBlooioPlatform ? "yes" : "no"}`,
210
- stderr: [result.stderr.trim(), chunk.stderr?.trim()].filter(Boolean).join("\n"),
234
+ stderr: [result.stderr.trim(), chunk.stderr?.trim()]
235
+ .filter(Boolean)
236
+ .join("\n"),
211
237
  });
212
238
  }
213
239
 
214
240
  function printAndroidState() {
215
- printGateSection("android doctor", run("node", [installScript, "--doctor"]), /\bBLOCKED\b/);
241
+ printGateSection(
242
+ "android doctor",
243
+ run("node", [installScript, "--doctor"]),
244
+ /\bBLOCKED\b/,
245
+ );
216
246
  printSection("adb devices", run(adbPath, ["devices", "-l"]));
217
247
  printHostUsbState();
218
248
  }
@@ -240,6 +270,13 @@ function createRoutingContractCwd() {
240
270
  return cwd;
241
271
  }
242
272
 
273
+ function removePathRecursive(targetPath) {
274
+ execFileSync(process.execPath, [cleanupHelperScript, targetPath], {
275
+ cwd: repoRoot,
276
+ stdio: "inherit",
277
+ });
278
+ }
279
+
243
280
  function printRoutingContractState() {
244
281
  const cwd = createRoutingContractCwd();
245
282
  try {
@@ -250,7 +287,7 @@ function printRoutingContractState() {
250
287
  );
251
288
  }
252
289
  } finally {
253
- fs.rmSync(cwd, { recursive: true, force: true });
290
+ removePathRecursive(cwd);
254
291
  }
255
292
  }
256
293
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { spawnSync } from "node:child_process";
2
+ import { execFileSync, spawnSync } from "node:child_process";
3
3
  /**
4
4
  * Remove build outputs and tool caches so the next `bun run build` / dev run is cold.
5
5
  *
@@ -21,14 +21,32 @@ import {
21
21
  import { resolveRepoRootFromImportMeta } from "./lib/repo-root.mjs";
22
22
 
23
23
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
24
+ const RECURSIVE_CLEANUP_SCRIPT = path.resolve(
25
+ __dirname,
26
+ "../../scripts/rm-path-recursive.mjs",
27
+ );
24
28
  const root = resolveRepoRootFromImportMeta(import.meta.url);
25
29
  const deep = process.argv.includes("--deep");
26
30
  const globalToolCache = process.env.ELIZA_CLEAN_GLOBAL_TOOL_CACHE === "1";
27
31
 
32
+ function removeDirectoryRecursive(targetPath) {
33
+ try {
34
+ execFileSync("node", [RECURSIVE_CLEANUP_SCRIPT, path.resolve(targetPath)], {
35
+ encoding: "utf8",
36
+ stdio: "pipe",
37
+ });
38
+ } catch (error) {
39
+ const detail = [error?.stdout, error?.stderr].filter(Boolean).join("\n");
40
+ throw new Error(detail || error?.message || String(error), {
41
+ cause: error,
42
+ });
43
+ }
44
+ }
45
+
28
46
  function rmPath(label, abs) {
29
47
  if (!existsSync(abs)) return;
30
48
  try {
31
- rmSync(abs, { recursive: true, force: true });
49
+ removeDirectoryRecursive(abs);
32
50
  console.log(` removed ${label}`);
33
51
  } catch (err) {
34
52
  console.warn(
@@ -70,7 +88,7 @@ function rmPluginDists() {
70
88
  if (!existsSync(pluginsRoot)) return;
71
89
  for (const name of CAPACITOR_PLUGIN_NAMES) {
72
90
  const dir = nativePluginDir(name);
73
- rmPath(path.relative(root, dir) + "/dist", path.join(dir, "dist"));
91
+ rmPath(`${path.relative(root, dir)}/dist`, path.join(dir, "dist"));
74
92
  }
75
93
  // Any extra plugin dirs (not in canonical list) still get dist removed
76
94
  try {