vora-ai 0.1.37 → 0.1.38

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 (29) hide show
  1. package/dist/.buildstamp +1 -1
  2. package/dist/build-info.json +3 -3
  3. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  4. package/dist/cli-startup-metadata.json +1 -1
  5. package/dist/{command-registry-DoRR_ykS.js → command-registry-BRC9rQRa.js} +4 -4
  6. package/dist/{command-registry-oO4_XKsL.js → command-registry-CNW-_45W.js} +1 -1
  7. package/dist/completion-cli-CZqBPvMj.js +2 -0
  8. package/dist/{completion-cli-BSVP90BO.js → completion-cli-wmAo3zAc.js} +2 -2
  9. package/dist/{doctor-completion-CLfiq4-c.js → doctor-completion-D9ct64dl.js} +1 -1
  10. package/dist/entry.js +1 -1
  11. package/dist/extensions/telegram/.vora-runtime-deps-stamp.json +1 -1
  12. package/dist/{gateway-cli-DNaH7pBF.js → gateway-cli-DDZpfER2.js} +1 -1
  13. package/dist/index.js +1 -1
  14. package/dist/{onboard-VNwsDuUB.js → onboard-BgmpmwJd.js} +1 -1
  15. package/dist/{program-q6W4mv2i.js → program-CSIyPhvT.js} +1 -1
  16. package/dist/{prompt-select-styled-2R-9jWL7.js → prompt-select-styled-BXm08-uh.js} +1 -1
  17. package/dist/{register.maintenance-DMZegmso.js → register.maintenance-Bpuqh4Q-.js} +1 -1
  18. package/dist/{register.onboard-CxR6bI1n.js → register.onboard-D-PZwo7h.js} +1 -1
  19. package/dist/{register.setup-BT2-kAsK.js → register.setup-BJyCA8h7.js} +1 -1
  20. package/dist/{register.subclis-B-9NwtNV.js → register.subclis-BMN-F1BZ.js} +4 -4
  21. package/dist/{register.subclis-BQu4VqOI.js → register.subclis-Cdl19lw2.js} +1 -1
  22. package/dist/{run-main-BWhbuxQt.js → run-main-CHgQSnRn.js} +4 -4
  23. package/dist/{setup-B35nGXkQ.js → setup-Cu2MyUlf.js} +2 -2
  24. package/dist/{setup.finalize-BueEFawv.js → setup.finalize-CRAM1yrm.js} +3 -3
  25. package/dist/{update-cli-BbcBxt3_.js → update-cli-DhdDYxXa.js} +3 -3
  26. package/dist/{voice-cli-CXiYCrQf.js → voice-cli-BRD6l0Sl.js} +32 -7
  27. package/package.json +1 -1
  28. package/scripts/agora-stt-bridge.mjs +54 -11
  29. package/dist/completion-cli-B6W-7yKI.js +0 -2
package/dist/.buildstamp CHANGED
@@ -1 +1 @@
1
- {"builtAt":1776477728789,"head":"7cb18f8b1e45487f1627768901dac2dc10dda292"}
1
+ {"builtAt":1776480007494,"head":"93abfe1b07bd746d7181c78415ddc656e7bb8a4f"}
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.37",
3
- "commit": "7cb18f8b1e45487f1627768901dac2dc10dda292",
4
- "builtAt": "2026-04-18T02:02:09.438Z"
2
+ "version": "0.1.38",
3
+ "commit": "93abfe1b07bd746d7181c78415ddc656e7bb8a4f",
4
+ "builtAt": "2026-04-18T02:40:08.213Z"
5
5
  }
@@ -1 +1 @@
1
- 61df678f55f820c36800453e93a0b24dc4caa6d8ac7e6ec54d71e4885e06c512
1
+ 01b677ec20c9e797dda796c71459c28ae4b6a18ed0c7a835cedc7b231dee672f
@@ -10,5 +10,5 @@
10
10
  "signal",
11
11
  "imessage"
12
12
  ],
13
- "rootHelpText": "\n🌊 VORA 0.1.37 (7cb18f8) — Local processing, global conversational AI.\n\nUsage: vora [options] [command]\n\nOptions:\n --container <name> Run the CLI inside a running Podman/Docker container\n named <name> (default: env VORA_CONTAINER)\n --dev Dev profile: isolate state under ~/.vora-dev, default\n gateway port 19001, and shift derived ports\n (browser/canvas)\n -h, --help Display help for command\n --log-level <level> Global log level override for file + console\n (silent|fatal|error|warn|info|debug|trace)\n --no-color Disable ANSI colors\n --profile <name> Use a named profile (isolates\n VORA_STATE_DIR/VORA_CONFIG_PATH under ~/.vora-<name>)\n -V, --version output the version number\n\nCommands:\n Hint: commands suffixed with * have subcommands. Run <command> --help for details.\n acp * Agent Control Protocol tools\n agent Run one agent turn via the Gateway\n agents * Manage isolated agents (workspaces, auth, routing)\n approvals * Manage exec approvals (gateway or node host)\n backup * Create and verify local backup archives for Vora state\n channels * Manage connected chat channels (Telegram, Discord, etc.)\n clawbot * Legacy clawbot command aliases\n completion Generate shell completion script\n config * Non-interactive config helpers\n (get/set/unset/file/validate). Default: starts guided\n setup.\n configure Interactive configuration for credentials, channels,\n gateway, and agent defaults\n cron * Manage cron jobs via the Gateway scheduler\n daemon * Gateway service (legacy alias)\n dashboard Open the Control UI with your current token\n devices * Device pairing + token management\n directory * Lookup contact and group IDs (self, peers, groups) for\n supported chat channels\n dns * DNS helpers for wide-area discovery (Tailscale + CoreDNS)\n docs Search the live Vora docs\n doctor Health checks + quick fixes for the gateway and channels\n gateway * Run, inspect, and query the WebSocket Gateway\n health Fetch health from the running gateway\n help Display help for command\n hooks * Manage internal agent hooks\n logs Tail gateway file logs via RPC\n message * Send, read, and manage messages\n models * Discover, scan, and configure models\n node * Run and manage the headless node host service\n nodes * Manage gateway-owned node pairing and node commands\n onboard Interactive onboarding for gateway, workspace, and skills\n pairing * Secure DM pairing (approve inbound requests)\n plugins * Manage Vora plugins and extensions\n qr Generate iOS pairing QR/setup code\n reset Reset local config/state (keeps the CLI installed)\n sandbox * Manage sandbox containers for agent isolation\n secrets * Secrets runtime reload controls\n security * Security tools and local config audits\n sessions * List stored conversation sessions\n setup Initialize local config and agent workspace\n skills * List and inspect available skills\n status Show channel health and recent session recipients\n system * System events, heartbeat, and presence\n tasks * Inspect durable background task state\n tui Open a terminal UI connected to the Gateway\n uninstall Uninstall the gateway service + local data (CLI remains)\n update * Update Vora and inspect update channel status\n voice * Wake-word terminal voice loop (OpenWakeWord trigger + STT\n bridge + Gateway chat + optional Hume TTS)\n webhooks * Webhook helpers and integrations\n\nExamples:\n vora models --help\n Show detailed help for the models command.\n vora onboard\n Run interactive onboarding for the gateway, workspace, and skills.\n vora configure --section model --section gateway\n Re-open only the model and gateway configuration sections.\n vora gateway --port 27106\n Run the WebSocket Gateway locally.\n vora --dev gateway\n Run a dev Gateway (isolated state/config) on ws://127.0.0.1:19001.\n vora gateway --force\n Kill anything bound to the default gateway port, then start it.\n vora models status --plain\n Show the configured provider and default-model state.\n vora gateway ...\n Gateway control via WebSocket.\n vora message send --channel telegram --target @mychat --message \"Hi\"\n Send through a configured channel and print the result in the terminal.\n\nDocs: https://docs.vora.ai/cli\n\n"
13
+ "rootHelpText": "\n🌊 VORA 0.1.38 (93abfe1) — I speak fluent Audio, mild sarcasm, and aggressive Voice Activity Detection.\n\nUsage: vora [options] [command]\n\nOptions:\n --container <name> Run the CLI inside a running Podman/Docker container\n named <name> (default: env VORA_CONTAINER)\n --dev Dev profile: isolate state under ~/.vora-dev, default\n gateway port 19001, and shift derived ports\n (browser/canvas)\n -h, --help Display help for command\n --log-level <level> Global log level override for file + console\n (silent|fatal|error|warn|info|debug|trace)\n --no-color Disable ANSI colors\n --profile <name> Use a named profile (isolates\n VORA_STATE_DIR/VORA_CONFIG_PATH under ~/.vora-<name>)\n -V, --version output the version number\n\nCommands:\n Hint: commands suffixed with * have subcommands. Run <command> --help for details.\n acp * Agent Control Protocol tools\n agent Run one agent turn via the Gateway\n agents * Manage isolated agents (workspaces, auth, routing)\n approvals * Manage exec approvals (gateway or node host)\n backup * Create and verify local backup archives for Vora state\n channels * Manage connected chat channels (Telegram, Discord, etc.)\n clawbot * Legacy clawbot command aliases\n completion Generate shell completion script\n config * Non-interactive config helpers\n (get/set/unset/file/validate). Default: starts guided\n setup.\n configure Interactive configuration for credentials, channels,\n gateway, and agent defaults\n cron * Manage cron jobs via the Gateway scheduler\n daemon * Gateway service (legacy alias)\n dashboard Open the Control UI with your current token\n devices * Device pairing + token management\n directory * Lookup contact and group IDs (self, peers, groups) for\n supported chat channels\n dns * DNS helpers for wide-area discovery (Tailscale + CoreDNS)\n docs Search the live Vora docs\n doctor Health checks + quick fixes for the gateway and channels\n gateway * Run, inspect, and query the WebSocket Gateway\n health Fetch health from the running gateway\n help Display help for command\n hooks * Manage internal agent hooks\n logs Tail gateway file logs via RPC\n message * Send, read, and manage messages\n models * Discover, scan, and configure models\n node * Run and manage the headless node host service\n nodes * Manage gateway-owned node pairing and node commands\n onboard Interactive onboarding for gateway, workspace, and skills\n pairing * Secure DM pairing (approve inbound requests)\n plugins * Manage Vora plugins and extensions\n qr Generate iOS pairing QR/setup code\n reset Reset local config/state (keeps the CLI installed)\n sandbox * Manage sandbox containers for agent isolation\n secrets * Secrets runtime reload controls\n security * Security tools and local config audits\n sessions * List stored conversation sessions\n setup Initialize local config and agent workspace\n skills * List and inspect available skills\n status Show channel health and recent session recipients\n system * System events, heartbeat, and presence\n tasks * Inspect durable background task state\n tui Open a terminal UI connected to the Gateway\n uninstall Uninstall the gateway service + local data (CLI remains)\n update * Update Vora and inspect update channel status\n voice * Wake-word terminal voice loop (OpenWakeWord trigger + STT\n bridge + Gateway chat + optional Hume TTS)\n webhooks * Webhook helpers and integrations\n\nExamples:\n vora models --help\n Show detailed help for the models command.\n vora onboard\n Run interactive onboarding for the gateway, workspace, and skills.\n vora configure --section model --section gateway\n Re-open only the model and gateway configuration sections.\n vora gateway --port 27106\n Run the WebSocket Gateway locally.\n vora --dev gateway\n Run a dev Gateway (isolated state/config) on ws://127.0.0.1:19001.\n vora gateway --force\n Kill anything bound to the default gateway port, then start it.\n vora models status --plain\n Show the configured provider and default-model state.\n vora gateway ...\n Gateway control via WebSocket.\n vora message send --channel telegram --target @mychat --message \"Hi\"\n Send through a configured channel and print the result in the terminal.\n\nDocs: https://docs.vora.ai/cli\n\n"
14
14
  }
@@ -1,7 +1,7 @@
1
1
  import { O as hasHelpOrVersion, T as getPrimaryCommand } from "./logger-DtBbg3AQ.js";
2
2
  import { n as removeCommandByName, t as registerLazyCommand } from "./register-lazy-command-C4_WvYdL.js";
3
3
  import { t as getCoreCliCommandDescriptors } from "./core-command-descriptors-Dmh3xVCU.js";
4
- import { i as registerSubCliCommands } from "./register.subclis-B-9NwtNV.js";
4
+ import { i as registerSubCliCommands } from "./register.subclis-BMN-F1BZ.js";
5
5
  //#region src/cli/program/command-registry.ts
6
6
  const shouldRegisterCorePrimaryOnly = (argv) => {
7
7
  if (hasHelpOrVersion(argv)) return false;
@@ -15,7 +15,7 @@ const coreEntries = [
15
15
  hasSubcommands: false
16
16
  }],
17
17
  register: async ({ program }) => {
18
- (await import("./register.setup-BT2-kAsK.js")).registerSetupCommand(program);
18
+ (await import("./register.setup-BJyCA8h7.js")).registerSetupCommand(program);
19
19
  }
20
20
  },
21
21
  {
@@ -25,7 +25,7 @@ const coreEntries = [
25
25
  hasSubcommands: false
26
26
  }],
27
27
  register: async ({ program }) => {
28
- (await import("./register.onboard-CxR6bI1n.js")).registerOnboardCommand(program);
28
+ (await import("./register.onboard-D-PZwo7h.js")).registerOnboardCommand(program);
29
29
  }
30
30
  },
31
31
  {
@@ -82,7 +82,7 @@ const coreEntries = [
82
82
  }
83
83
  ],
84
84
  register: async ({ program }) => {
85
- (await import("./register.maintenance-DMZegmso.js")).registerMaintenanceCommands(program);
85
+ (await import("./register.maintenance-Bpuqh4Q-.js")).registerMaintenanceCommands(program);
86
86
  }
87
87
  },
88
88
  {
@@ -1,3 +1,3 @@
1
1
  import "./core-command-descriptors-Dmh3xVCU.js";
2
- import { n as registerCoreCliByName } from "./command-registry-DoRR_ykS.js";
2
+ import { n as registerCoreCliByName } from "./command-registry-BRC9rQRa.js";
3
3
  export { registerCoreCliByName };
@@ -0,0 +1,2 @@
1
+ import { a as registerCompletionCli } from "./completion-cli-wmAo3zAc.js";
2
+ export { registerCompletionCli };
@@ -3,8 +3,8 @@ import { t as formatDocsLink } from "./links-D-QW4VCX.js";
3
3
  import { r as theme } from "./theme-DEBOahQW.js";
4
4
  import { _ as resolveStateDir } from "./paths-5dqsPi5h.js";
5
5
  import { m as pathExists } from "./utils-D25qzO4S.js";
6
- import { n as loadValidatedConfigForPluginRegistration, r as registerSubCliByName, t as getSubCliEntries } from "./register.subclis-B-9NwtNV.js";
7
- import { n as registerCoreCliByName, t as getCoreCliCommandNames } from "./command-registry-DoRR_ykS.js";
6
+ import { n as loadValidatedConfigForPluginRegistration, r as registerSubCliByName, t as getSubCliEntries } from "./register.subclis-BMN-F1BZ.js";
7
+ import { n as registerCoreCliByName, t as getCoreCliCommandNames } from "./command-registry-BRC9rQRa.js";
8
8
  import { t as getProgramContext } from "./program-context-C0Ru__k1.js";
9
9
  import path from "node:path";
10
10
  import os from "node:os";
@@ -1,7 +1,7 @@
1
1
  import { t as resolveVoraPackageRoot } from "./vora-root-fqgy2cBi.js";
2
2
  import { n as resolveCliName } from "./cli-name-C_IzpPbS.js";
3
3
  import { t as note } from "./note-DfcrAbT0.js";
4
- import { c as usesSlowDynamicCompletion, i as isCompletionInstalled, o as resolveCompletionCachePath, r as installCompletion, s as resolveShellFromEnv, t as completionCacheExists } from "./completion-cli-BSVP90BO.js";
4
+ import { c as usesSlowDynamicCompletion, i as isCompletionInstalled, o as resolveCompletionCachePath, r as installCompletion, s as resolveShellFromEnv, t as completionCacheExists } from "./completion-cli-wmAo3zAc.js";
5
5
  import path from "node:path";
6
6
  import { spawnSync } from "node:child_process";
7
7
  //#region src/commands/doctor-completion.ts
package/dist/entry.js CHANGED
@@ -200,7 +200,7 @@ function tryHandleRootHelpFastPath(argv, deps = {}) {
200
200
  }
201
201
  function runMainOrRootHelp(argv) {
202
202
  if (tryHandleRootHelpFastPath(argv)) return;
203
- import("./run-main-BWhbuxQt.js").then(({ runCli }) => runCli(argv)).catch((error) => {
203
+ import("./run-main-CHgQSnRn.js").then(({ runCli }) => runCli(argv)).catch((error) => {
204
204
  console.error("[vora] Failed to start CLI:", error instanceof Error ? error.stack ?? error.message : error);
205
205
  process$1.exitCode = 1;
206
206
  });
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "fingerprint": "f5cc4428157244c03371a02e98bc2b0556e1853613db4dfe31efcfd24cef35f1",
3
- "generatedAt": "2026-04-18T02:02:08.668Z"
3
+ "generatedAt": "2026-04-18T02:40:07.361Z"
4
4
  }
@@ -196,7 +196,7 @@ import { s as normalizeUpdateChannel } from "./update-channels-C8-n6_kE.js";
196
196
  import { n as compareSemverStrings, o as resolveNpmChannelTag, t as checkUpdateStatus } from "./update-check-Cw2Zo7Rn.js";
197
197
  import { i as resolveGatewayStartupPluginIds, r as resolveConfiguredDeferredChannelPluginIds } from "./channel-plugin-ids-BgeBHwp9.js";
198
198
  import { l as startTaskRegistryMaintenance, n as getInspectableTaskRegistrySummary } from "./task-registry.maintenance-CfvslEdg.js";
199
- import { t as runSetupWizard } from "./setup-B35nGXkQ.js";
199
+ import { t as runSetupWizard } from "./setup-Cu2MyUlf.js";
200
200
  import { _ as buildGogWatchStartArgs, g as buildGogWatchServeArgs, i as ensureTailscaleEndpoint, w as resolveGmailHookRuntimeConfig } from "./gmail-setup-utils-CstpQWwK.js";
201
201
  import { i as loadAgentIdentity, o as pruneAgentConfig, r as findAgentEntryIndex, t as applyAgentConfig } from "./agents.config-BXIFVvWT.js";
202
202
  import { a as resolveApnsAuthConfigFromEnv, c as shouldClearStoredApnsRegistration, d as MediaOffloadError, f as parseMessageWithAttachments, l as resolveApnsRelayConfigFromEnv, n as loadApnsRegistration, o as sendApnsAlert, r as normalizeApnsEnvironment, s as sendApnsBackgroundWake, t as clearApnsRegistrationIfCurrent, u as normalizeRpcAttachmentsToChatAttachments } from "./push-apns-wrSw6X5_.js";
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ let saveSessionStore;
28
28
  let toWhatsappJid;
29
29
  let waitForever;
30
30
  async function loadLegacyCliDeps() {
31
- const [{ installGaxiosFetchCompat }, { runCli }] = await Promise.all([import("./gaxios-fetch-compat-BZRlVrBH.js"), import("./run-main-BWhbuxQt.js")]);
31
+ const [{ installGaxiosFetchCompat }, { runCli }] = await Promise.all([import("./gaxios-fetch-compat-BZRlVrBH.js"), import("./run-main-CHgQSnRn.js")]);
32
32
  return {
33
33
  installGaxiosFetchCompat,
34
34
  runCli
@@ -11,7 +11,7 @@ import { c as normalizeGatewayTokenInput, d as randomToken, f as resolveControlU
11
11
  import { n as logConfigUpdated } from "./logging-BQ-k0nK2.js";
12
12
  import { t as WizardCancelledError } from "./prompts-BVJ3zQFl.js";
13
13
  import { t as createClackPrompter } from "./clack-prompter-Be8sX0Lg.js";
14
- import { t as runSetupWizard } from "./setup-B35nGXkQ.js";
14
+ import { t as runSetupWizard } from "./setup-Cu2MyUlf.js";
15
15
  import { a as resolveManifestProviderOnboardAuthFlags } from "./provider-auth-choices-DcNzlbgs.js";
16
16
  import { i as resolveDeprecatedAuthChoiceReplacement, n as isDeprecatedAuthChoice, r as normalizeLegacyOnboardAuthChoice, t as formatDeprecatedNonInteractiveAuthChoiceError } from "./auth-choice-legacy-DGeZIT-G.js";
17
17
  import { r as applyLocalSetupWorkspaceConfig } from "./onboard-config-DkkHPbTO.js";
@@ -7,7 +7,7 @@ import { n as VERSION } from "./version-A4Ns-pm9.js";
7
7
  import { n as resolveCliName } from "./cli-name-C_IzpPbS.js";
8
8
  import { t as emitCliBanner } from "./banner-C5yJCudk.js";
9
9
  import { n as resolveCliChannelOptions } from "./channel-options-D_8z6c-h.js";
10
- import { i as registerProgramCommands } from "./command-registry-DoRR_ykS.js";
10
+ import { i as registerProgramCommands } from "./command-registry-BRC9rQRa.js";
11
11
  import { n as setProgramContext } from "./program-context-C0Ru__k1.js";
12
12
  import { t as isCommandJsonOutputMode } from "./json-mode-KmFHsA3R.js";
13
13
  import "./ports-CQo1U86K.js";
@@ -108,7 +108,7 @@ import { t as ensureSystemdUserLingerInteractive } from "./systemd-linger-B_gzrf
108
108
  import { t as formatHealthCheckFailure } from "./health-format-TyQPx9cW.js";
109
109
  import { a as stripUnknownConfigKeys, i as resolveConfigPathTarget, n as formatConfigPath, r as noteOpencodeProviderOverrides, t as runDoctorConfigPreflight } from "./doctor-config-preflight-B2IpAFkH.js";
110
110
  import { a as isMattermostMutableAllowEntry, i as isMSTeamsMutableAllowEntry, n as isGoogleChatMutableAllowEntry, o as isSlackMutableAllowEntry, r as isIrcMutableAllowEntry, s as isZalouserMutableGroupEntry, t as isDiscordMutableAllowEntry } from "./mutable-allowlist-detectors-zVflHd8P.js";
111
- import { n as doctorShellCompletion } from "./doctor-completion-CLfiq4-c.js";
111
+ import { n as doctorShellCompletion } from "./doctor-completion-D9ct64dl.js";
112
112
  import { t as collectChannelStatusIssues } from "./channels-status-issues-CCJ10zgF.js";
113
113
  import { t as resolveDefaultChannelAccountContext } from "./channel-account-context-ChxhkByq.js";
114
114
  import "./doctor-state-migrations-BlH3irT5.js";
@@ -16,7 +16,7 @@ import { r as resolveGatewayService } from "./service-BnUY5mkU.js";
16
16
  import { n as resolveConfiguredSecretInputWithFallback } from "./resolve-configured-secret-input-string-BGHutVyf.js";
17
17
  import { n as runCommandWithRuntime } from "./cli-utils-4n6KI2ho.js";
18
18
  import { a as removePath, i as listAgentSessionDirs, o as removeStateAndLinkedPaths, r as buildCleanupPlan, s as removeWorkspaceDirs } from "./backup-create-DZood8Ea.js";
19
- import { n as doctorCommand, t as selectStyled } from "./prompt-select-styled-2R-9jWL7.js";
19
+ import { n as doctorCommand, t as selectStyled } from "./prompt-select-styled-BXm08-uh.js";
20
20
  import path from "node:path";
21
21
  import { cancel, confirm, isCancel, multiselect } from "@clack/prompts";
22
22
  //#region src/infra/clipboard.ts
@@ -4,7 +4,7 @@ import { r as theme } from "./theme-DEBOahQW.js";
4
4
  import { n as runCommandWithRuntime } from "./cli-utils-4n6KI2ho.js";
5
5
  import { a as resolveManifestProviderOnboardAuthFlags } from "./provider-auth-choices-DcNzlbgs.js";
6
6
  import { n as formatAuthChoiceChoicesForCli } from "./auth-choice-options-Blz8a0tL.js";
7
- import { n as CORE_ONBOARD_AUTH_FLAGS, t as setupWizardCommand } from "./onboard-VNwsDuUB.js";
7
+ import { n as CORE_ONBOARD_AUTH_FLAGS, t as setupWizardCommand } from "./onboard-BgmpmwJd.js";
8
8
  //#region src/cli/program/register.onboard.ts
9
9
  function resolveInstallDaemonFlag(command, opts) {
10
10
  if (!command || typeof command !== "object") return;
@@ -11,7 +11,7 @@ import { s as resolveSessionTranscriptsDir } from "./paths-UyCuvwtc.js";
11
11
  import { n as safeParseWithSchema } from "./zod-parse-DHX0rEx9.js";
12
12
  import { n as runCommandWithRuntime } from "./cli-utils-4n6KI2ho.js";
13
13
  import { n as logConfigUpdated, t as formatConfigPath } from "./logging-BQ-k0nK2.js";
14
- import { t as setupWizardCommand } from "./onboard-VNwsDuUB.js";
14
+ import { t as setupWizardCommand } from "./onboard-BgmpmwJd.js";
15
15
  import fs from "node:fs/promises";
16
16
  import { z } from "zod";
17
17
  import JSON5 from "json5";
@@ -30,7 +30,7 @@ const entries = [
30
30
  description: "Run, inspect, and query the WebSocket Gateway",
31
31
  hasSubcommands: true,
32
32
  register: async (program) => {
33
- (await import("./gateway-cli-DNaH7pBF.js")).registerGatewayCli(program);
33
+ (await import("./gateway-cli-DDZpfER2.js")).registerGatewayCli(program);
34
34
  }
35
35
  },
36
36
  {
@@ -118,7 +118,7 @@ const entries = [
118
118
  description: "Wake-word terminal voice loop (OpenWakeWord trigger + STT bridge + Gateway chat + optional Hume TTS)",
119
119
  hasSubcommands: true,
120
120
  register: async (program) => {
121
- (await import("./voice-cli-CXiYCrQf.js")).registerVoiceCli(program);
121
+ (await import("./voice-cli-BRD6l0Sl.js")).registerVoiceCli(program);
122
122
  }
123
123
  },
124
124
  {
@@ -244,7 +244,7 @@ const entries = [
244
244
  description: "Update Vora and inspect update channel status",
245
245
  hasSubcommands: true,
246
246
  register: async (program) => {
247
- (await import("./update-cli-BbcBxt3_.js")).registerUpdateCli(program);
247
+ (await import("./update-cli-DhdDYxXa.js")).registerUpdateCli(program);
248
248
  }
249
249
  },
250
250
  {
@@ -252,7 +252,7 @@ const entries = [
252
252
  description: "Generate shell completion script",
253
253
  hasSubcommands: false,
254
254
  register: async (program) => {
255
- (await import("./completion-cli-B6W-7yKI.js")).registerCompletionCli(program);
255
+ (await import("./completion-cli-CZqBPvMj.js")).registerCompletionCli(program);
256
256
  }
257
257
  }
258
258
  ];
@@ -1,3 +1,3 @@
1
1
  import "./subcli-descriptors-Cc423xKz.js";
2
- import { n as loadValidatedConfigForPluginRegistration, r as registerSubCliByName } from "./register.subclis-B-9NwtNV.js";
2
+ import { n as loadValidatedConfigForPluginRegistration, r as registerSubCliByName } from "./register.subclis-BMN-F1BZ.js";
3
3
  export { loadValidatedConfigForPluginRegistration, registerSubCliByName };
@@ -374,7 +374,7 @@ async function runCli(argv = process$1.argv) {
374
374
  }
375
375
  if (await tryRouteCli(normalizedArgv)) return;
376
376
  enableConsoleCapture();
377
- const { buildProgram } = await import("./program-q6W4mv2i.js");
377
+ const { buildProgram } = await import("./program-CSIyPhvT.js");
378
378
  const program = buildProgram();
379
379
  const { installUnhandledRejectionHandler } = await import("./unhandled-rejections-D0HD8aaS.js");
380
380
  installUnhandledRejectionHandler();
@@ -388,10 +388,10 @@ async function runCli(argv = process$1.argv) {
388
388
  const { getProgramContext } = await import("./program-context-Bntrf4rW.js");
389
389
  const ctx = getProgramContext(program);
390
390
  if (ctx) {
391
- const { registerCoreCliByName } = await import("./command-registry-oO4_XKsL.js");
391
+ const { registerCoreCliByName } = await import("./command-registry-CNW-_45W.js");
392
392
  await registerCoreCliByName(program, ctx, primary, parseArgv);
393
393
  }
394
- const { registerSubCliByName } = await import("./register.subclis-BQu4VqOI.js");
394
+ const { registerSubCliByName } = await import("./register.subclis-Cdl19lw2.js");
395
395
  await registerSubCliByName(program, primary);
396
396
  }
397
397
  if (!shouldSkipPluginCommandRegistration({
@@ -400,7 +400,7 @@ async function runCli(argv = process$1.argv) {
400
400
  hasBuiltinPrimary: primary !== null && program.commands.some((command) => command.name() === primary)
401
401
  })) {
402
402
  const { registerPluginCliCommands } = await import("./cli-QwFXIS1_.js");
403
- const { loadValidatedConfigForPluginRegistration } = await import("./register.subclis-BQu4VqOI.js");
403
+ const { loadValidatedConfigForPluginRegistration } = await import("./register.subclis-Cdl19lw2.js");
404
404
  const config = await loadValidatedConfigForPluginRegistration();
405
405
  if (config) {
406
406
  await registerPluginCliCommands(program, config, void 0, void 0, {
@@ -106,7 +106,7 @@ async function setupQuickstartVoiceRuntime(params) {
106
106
  "STT/TTS use the VORA backend by default, so local Agora/Hume keys are not required."
107
107
  ].join("\n"), "Voice runtime");
108
108
  try {
109
- const { runVoiceSetup } = await import("./voice-cli-CXiYCrQf.js");
109
+ const { runVoiceSetup } = await import("./voice-cli-BRD6l0Sl.js");
110
110
  await runVoiceSetup({}, params.runtime);
111
111
  await params.prompter.note([
112
112
  "Voice runtime is ready.",
@@ -464,7 +464,7 @@ async function runSetupWizard(opts, runtime = defaultRuntime, prompter) {
464
464
  mode
465
465
  });
466
466
  await writeConfigFile(nextConfig);
467
- const { finalizeSetupWizard } = await import("./setup.finalize-BueEFawv.js");
467
+ const { finalizeSetupWizard } = await import("./setup.finalize-CRAM1yrm.js");
468
468
  const { launchedTui } = await finalizeSetupWizard({
469
469
  flow,
470
470
  opts,
@@ -10,12 +10,12 @@ import { f as resolveControlUiLinks, g as waitForGatewayReachable, i as formatCo
10
10
  import { r as resolveGatewayService, t as describeGatewayServiceRestart } from "./service-BnUY5mkU.js";
11
11
  import { i as isSystemdUserServiceAvailable } from "./systemd-9Gclqlhk.js";
12
12
  import { t as listConfiguredWebSearchProviders } from "./runtime-B0GlgEXr.js";
13
- import { r as installCompletion } from "./completion-cli-BSVP90BO.js";
13
+ import { r as installCompletion } from "./completion-cli-wmAo3zAc.js";
14
14
  import { r as healthCommand } from "./health-DJqooRWK.js";
15
15
  import { t as ensureControlUiAssetsBuilt } from "./control-ui-assets-DVSZ-yd-.js";
16
16
  import { t as resolveSetupSecretInputString } from "./setup.secret-input-DeWdLao-.js";
17
17
  import { t as formatHealthCheckFailure } from "./health-format-TyQPx9cW.js";
18
- import { r as ensureCompletionCacheExists, t as checkShellCompletionStatus } from "./doctor-completion-CLfiq4-c.js";
18
+ import { r as ensureCompletionCacheExists, t as checkShellCompletionStatus } from "./doctor-completion-D9ct64dl.js";
19
19
  import { t as runTui } from "./tui-DCtnC9C0.js";
20
20
  import path from "node:path";
21
21
  import os from "node:os";
@@ -351,7 +351,7 @@ async function finalizeSetupWizard(options) {
351
351
  if (hatchChoice === "voice") {
352
352
  restoreTerminalState("pre-setup voice", { resumeStdinIfPaused: true });
353
353
  try {
354
- const { runVoiceLoop } = await import("./voice-cli-CXiYCrQf.js");
354
+ const { runVoiceLoop } = await import("./voice-cli-BRD6l0Sl.js");
355
355
  await runVoiceLoop({
356
356
  url: links.wsUrl,
357
357
  token: settings.authMode === "token" ? settings.gatewayToken : void 0,
@@ -21,14 +21,14 @@ import { a as terminateStaleGatewayPids, i as renderRestartDiagnostics, s as wai
21
21
  import { r as formatDurationPrecise } from "./format-duration-C7KLrjgc.js";
22
22
  import { o as trimLogTail } from "./restart-sentinel-CjIY0IZ8.js";
23
23
  import { t as formatHelpExamples } from "./help-format-DC7U6A-Y.js";
24
- import { r as installCompletion } from "./completion-cli-BSVP90BO.js";
24
+ import { r as installCompletion } from "./completion-cli-wmAo3zAc.js";
25
25
  import { n as renderTable, t as getTerminalTableWidth } from "./table-CYPwb2Cg.js";
26
26
  import { c as resolveEffectiveUpdateChannel, i as formatUpdateChannelLabel, l as resolveUpdateChannelDisplay, r as channelToNpmTag, s as normalizeUpdateChannel } from "./update-channels-C8-n6_kE.js";
27
27
  import { i as fetchNpmTagVersion, n as compareSemverStrings, o as resolveNpmChannelTag, r as fetchNpmPackageTargetStatus, t as checkUpdateStatus } from "./update-check-Cw2Zo7Rn.js";
28
28
  import { a as collectInstalledGlobalPackageErrors, c as detectGlobalInstallManagerForRoot, d as resolveGlobalInstallSpec, f as resolveGlobalPackageRoot, h as readPackageVersion, i as cleanupGlobalRenameDirs, l as globalInstallArgs, m as readPackageName, n as runGatewayUpdate, o as createGlobalInstallEnv, p as normalizePackageTagInput, r as canResolveRegistryVersionForPackageTarget, s as detectGlobalInstallManagerByPresence, u as resolveExpectedInstalledVersionFromSpec } from "./server-startup-matrix-migration-DL743qrx.js";
29
29
  import { n as updateNpmInstalledPlugins, t as syncPluginsForUpdateChannel } from "./update-XayfF-ly.js";
30
- import { n as doctorCommand, t as selectStyled } from "./prompt-select-styled-2R-9jWL7.js";
31
- import { r as ensureCompletionCacheExists, t as checkShellCompletionStatus } from "./doctor-completion-CLfiq4-c.js";
30
+ import { n as doctorCommand, t as selectStyled } from "./prompt-select-styled-BXm08-uh.js";
31
+ import { r as ensureCompletionCacheExists, t as checkShellCompletionStatus } from "./doctor-completion-D9ct64dl.js";
32
32
  import { i as resolveUpdateAvailability, n as formatUpdateOneLiner, t as formatUpdateAvailableHint } from "./status.update-209xudNW.js";
33
33
  import path from "node:path";
34
34
  import { spawn, spawnSync } from "node:child_process";
@@ -15,7 +15,7 @@ const DEFAULT_WAKE_MODEL_FILE = "hey_vora.onnx";
15
15
  const DEFAULT_WAKE_THRESHOLD = .5;
16
16
  const DEFAULT_WAIT_MS = 4e4;
17
17
  const DEFAULT_STT_TIMEOUT_MS = 25e3;
18
- const DEFAULT_STT_LANGUAGE = "en-US,vi-VN";
18
+ const DEFAULT_STT_LANGUAGE = "vi-VN,en-US";
19
19
  const DEFAULT_HUME_VOICE_ID = "9e068547-5ba4-4c8e-8e03-69282a008f04";
20
20
  const DEFAULT_HUME_SPEED = 1.2;
21
21
  const DEFAULT_TTS_TIMEOUT_MS = 2e4;
@@ -782,7 +782,7 @@ function resolveShellCommand(command) {
782
782
  args: ["-lc", command]
783
783
  };
784
784
  }
785
- async function runShellCommand(command, timeoutMs) {
785
+ async function runShellCommand(command, timeoutMs, opts) {
786
786
  const shell = resolveShellCommand(command);
787
787
  const child = spawn(shell.bin, shell.args, { stdio: [
788
788
  "ignore",
@@ -791,15 +791,24 @@ async function runShellCommand(command, timeoutMs) {
791
791
  ] });
792
792
  let stdout = "";
793
793
  let stderr = "";
794
+ let stderrLineBuffer = "";
794
795
  child.stdout?.on("data", (chunk) => {
795
796
  stdout += chunk.toString();
796
797
  });
797
798
  child.stderr?.on("data", (chunk) => {
798
- stderr += chunk.toString();
799
+ const text = chunk.toString();
800
+ stderr += text;
801
+ if (opts?.onStderrLine) {
802
+ stderrLineBuffer += text;
803
+ const lines = stderrLineBuffer.split(/\r?\n/g);
804
+ stderrLineBuffer = lines.pop() ?? "";
805
+ for (const line of lines) opts.onStderrLine(line);
806
+ }
799
807
  });
800
808
  const done = new Promise((resolve, reject) => {
801
809
  child.on("error", reject);
802
810
  child.on("close", (code) => {
811
+ if (opts?.onStderrLine && stderrLineBuffer.trim().length > 0) opts.onStderrLine(stderrLineBuffer);
803
812
  resolve({
804
813
  code: typeof code === "number" ? code : 1,
805
814
  stdout,
@@ -974,11 +983,26 @@ async function transcribeSpeech(resolved, opts) {
974
983
  const command = resolved.stt.agoraCommand;
975
984
  if (!command) throw new Error("Agora STT provider selected but no bridge command is available. Set --agora-stt-command or VORA_AGORA_STT_COMMAND.");
976
985
  const timeoutMs = opts?.timeoutMs ?? resolved.stt.timeoutMs;
977
- const result = await runShellCommand(applyTemplate(command, {
986
+ const rendered = applyTemplate(command, {
978
987
  lang: resolved.stt.language,
979
988
  timeout_ms: String(timeoutMs)
980
- }), timeoutMs + DEFAULT_STT_BRIDGE_COMMAND_GRACE_MS);
989
+ });
990
+ const phase = opts?.phase ?? "voice";
991
+ defaultRuntime.log(`[voice] preparing ${phase} STT (${resolved.stt.language}); wait for "listening now" before speaking`);
992
+ let readyLogged = false;
993
+ const result = await runShellCommand(rendered, timeoutMs + DEFAULT_STT_BRIDGE_COMMAND_GRACE_MS, { onStderrLine: (line) => {
994
+ const message = line.trim();
995
+ if (!message) return;
996
+ if (message === "[agora-stt-bridge] ready") {
997
+ readyLogged = true;
998
+ process.stdout.write("\x07");
999
+ defaultRuntime.log(`[voice] listening now (${resolved.stt.language}); speak now`);
1000
+ return;
1001
+ }
1002
+ if (message.includes("fatal:") || message.includes("managed browser unavailable") || message.includes("browser auto-open disabled")) defaultRuntime.error(message);
1003
+ } });
981
1004
  if (result.code !== 0) throw new Error(`Agora STT bridge failed (exit ${result.code}): ${result.stderr.trim() || "no stderr"}`);
1005
+ if (!readyLogged) defaultRuntime.log("[voice] STT bridge completed without an explicit ready signal");
982
1006
  return extractTranscriptFromCommandOutput(result.stdout);
983
1007
  }
984
1008
  function normalizeHistoryMessages(payload) {
@@ -1507,12 +1531,13 @@ async function runVoiceConversation(params) {
1507
1531
  if (params.resolved.once) return;
1508
1532
  if (!params.resolved.conversation.followUpEnabled || followUpTurns >= params.resolved.conversation.followUpMaxTurns) return;
1509
1533
  const followUpListenMs = Math.min(params.resolved.conversation.followUpMs, params.resolved.conversation.followUpSttTimeoutMs);
1510
- defaultRuntime.log(`[voice] follow-up window open for ${Math.round(followUpListenMs / 1e3)}s; speak naturally, or stay quiet to sleep`);
1534
+ defaultRuntime.log(`[voice] preparing follow-up window (${Math.round(followUpListenMs / 1e3)}s after ready); wait for "listening now"`);
1511
1535
  let nextTranscript = "";
1512
1536
  try {
1513
1537
  nextTranscript = (await transcribeSpeech(params.resolved, {
1514
1538
  timeoutMs: followUpListenMs,
1515
- prompt: "Follow-up (blank to sleep): "
1539
+ prompt: "Follow-up (blank to sleep): ",
1540
+ phase: "follow-up"
1516
1541
  })).trim();
1517
1542
  } catch (error) {
1518
1543
  if (String(error).toLowerCase().includes("timeout")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vora-ai",
3
- "version": "0.1.37",
3
+ "version": "0.1.38",
4
4
  "description": "Voice-first AI agent core engine — VORA",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/vora-ai/vora-core#readme",
@@ -7,7 +7,7 @@ import http from "node:http";
7
7
  const DEFAULT_TIMEOUT_MS = 45_000;
8
8
  const DEFAULT_API_BASE = "https://api.agora.io";
9
9
  const DEFAULT_BACKEND_URL = "https://vora-ai-backend-uemj.onrender.com";
10
- const DEFAULT_LANGUAGE = "en-US,vi-VN";
10
+ const DEFAULT_LANGUAGE = "vi-VN,en-US";
11
11
  const DEFAULT_RTC_UID = "1002";
12
12
  const DEFAULT_STT_AUDIO_UID = "111";
13
13
  const DEFAULT_STT_TEXT_UID = "222";
@@ -649,16 +649,13 @@ function buildBrowserHtml(browserConfig) {
649
649
  throw new Error("Agora STT start returned no agentId");
650
650
  }
651
651
  agentId = String(start.agentId);
652
+ await post("/ready", { agentId });
652
653
  setStatus("Listening... speak your command now.", "ok");
653
654
  } catch (error) {
654
655
  await resolveError(String(error));
655
656
  }
656
657
  }
657
658
 
658
- setTimeout(() => {
659
- void resolveError("timeout waiting for final transcript");
660
- }, Math.max(1000, CONFIG.timeoutMs));
661
-
662
659
  window.addEventListener("beforeunload", () => {
663
660
  void cleanup();
664
661
  });
@@ -831,6 +828,20 @@ async function main() {
831
828
  let done = false;
832
829
  let currentAgentId = "";
833
830
  let browserController = null;
831
+ let ready = false;
832
+ let startupTimeout;
833
+ let listenTimeout;
834
+
835
+ const clearTimers = () => {
836
+ if (startupTimeout) {
837
+ clearTimeout(startupTimeout);
838
+ startupTimeout = undefined;
839
+ }
840
+ if (listenTimeout) {
841
+ clearTimeout(listenTimeout);
842
+ listenTimeout = undefined;
843
+ }
844
+ };
834
845
 
835
846
  const closeBrowser = async () => {
836
847
  if (!browserController) {
@@ -846,6 +857,7 @@ async function main() {
846
857
  return;
847
858
  }
848
859
  done = true;
860
+ clearTimers();
849
861
  await stopAgoraStt(resolvedConfig, currentAgentId).catch(() => undefined);
850
862
  await closeBrowser();
851
863
  if (server) {
@@ -860,6 +872,7 @@ async function main() {
860
872
  return;
861
873
  }
862
874
  done = true;
875
+ clearTimers();
863
876
  await stopAgoraStt(resolvedConfig, currentAgentId).catch(() => undefined);
864
877
  await closeBrowser();
865
878
  if (server) {
@@ -869,6 +882,15 @@ async function main() {
869
882
  process.exit(0);
870
883
  };
871
884
 
885
+ const armListenTimeout = () => {
886
+ if (listenTimeout) {
887
+ return;
888
+ }
889
+ listenTimeout = setTimeout(() => {
890
+ void fail(`timeout after ${resolvedConfig.timeoutMs}ms`);
891
+ }, resolvedConfig.timeoutMs);
892
+ };
893
+
872
894
  server = http.createServer(async (req, res) => {
873
895
  const requestUrl = new URL(req.url || "/", "http://127.0.0.1");
874
896
  const pathname = requestUrl.pathname;
@@ -890,6 +912,28 @@ async function main() {
890
912
  return;
891
913
  }
892
914
 
915
+ if (req.method === "POST" && pathname === "/ready") {
916
+ try {
917
+ const body = await readJsonBody(req);
918
+ const agentId =
919
+ typeof body?.agentId === "string" && body.agentId.trim().length > 0
920
+ ? body.agentId.trim()
921
+ : currentAgentId;
922
+ if (agentId && agentId !== currentAgentId) {
923
+ currentAgentId = agentId;
924
+ }
925
+ if (!ready) {
926
+ ready = true;
927
+ process.stderr.write("[agora-stt-bridge] ready\n");
928
+ armListenTimeout();
929
+ }
930
+ jsonResponse(res, 200, { ok: true });
931
+ } catch (error) {
932
+ jsonResponse(res, 500, { ok: false, error: String(error) });
933
+ }
934
+ return;
935
+ }
936
+
893
937
  if (req.method === "POST" && pathname === "/api/stop") {
894
938
  try {
895
939
  const body = await readJsonBody(req);
@@ -959,7 +1003,10 @@ async function main() {
959
1003
  const source = resolvedConfig.backendUrl ? `backend=${safeBase(resolvedConfig.backendUrl)}` : "direct-agora";
960
1004
  process.stderr.write(`[agora-stt-bridge] channel=${resolvedConfig.channel} uid=${resolvedConfig.uid} ${source}\n`);
961
1005
  process.stderr.write(`[agora-stt-bridge] local capture URL:\n${localUrl}\n`);
962
- process.stderr.write("[agora-stt-bridge] waiting for one final transcript...\n");
1006
+ process.stderr.write("[agora-stt-bridge] preparing microphone capture...\n");
1007
+ startupTimeout = setTimeout(() => {
1008
+ void fail("timeout waiting for microphone/STT readiness");
1009
+ }, Math.max(45_000, resolvedConfig.timeoutMs + 15_000));
963
1010
  if (config.browserMode === "managed") {
964
1011
  try {
965
1012
  browserController = await openManagedBrowser(localUrl, config.showBrowser);
@@ -981,12 +1028,8 @@ async function main() {
981
1028
  process.stderr.write("[agora-stt-bridge] browser auto-open disabled; open the local capture URL manually.\n");
982
1029
  }
983
1030
 
984
- const timeout = setTimeout(() => {
985
- void fail(`timeout after ${resolvedConfig.timeoutMs}ms`);
986
- }, resolvedConfig.timeoutMs + 15_000);
987
-
988
1031
  const stop = async () => {
989
- clearTimeout(timeout);
1032
+ clearTimers();
990
1033
  if (!done) {
991
1034
  await fail("interrupted");
992
1035
  }
@@ -1,2 +0,0 @@
1
- import { a as registerCompletionCli } from "./completion-cli-BSVP90BO.js";
2
- export { registerCompletionCli };