flockbay 0.10.16 → 0.10.19

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.
@@ -1,7 +1,7 @@
1
1
  import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
2
2
  import os, { homedir } from 'node:os';
3
3
  import { randomUUID, createCipheriv, randomBytes } from 'node:crypto';
4
- import { l as logger, p as projectPath, d as backoff, e as delay, R as RawJSONLinesSchema, c as configuration, f as readDaemonState, g as clearDaemonState, b as packageJson, r as readSettings, h as readCredentials, u as updateSettings, w as writeCredentials, i as unrealMcpPythonDir, j as acquireDaemonLock, k as writeDaemonState, m as ApiMachineClient, n as releaseDaemonLock, s as sendUnrealMcpTcpCommand, A as ApiClient, o as clearCredentials, q as clearMachineId, t as installUnrealMcpPluginToEngine, v as getLatestDaemonLog } from './types-CwzNqYEx.mjs';
4
+ import { l as logger, p as projectPath, d as backoff, e as delay, R as RawJSONLinesSchema, c as configuration, f as readDaemonState, g as clearDaemonState, b as packageJson, r as readSettings, h as readCredentials, u as updateSettings, w as writeCredentials, i as unrealMcpPythonDir, j as acquireDaemonLock, k as writeDaemonState, m as ApiMachineClient, n as releaseDaemonLock, s as sendUnrealMcpTcpCommand, A as ApiClient, o as clearCredentials, q as clearMachineId, t as installUnrealMcpPluginToEngine, v as getLatestDaemonLog, x as normalizeServerUrlForNode } from './types-BQvaA3sv.mjs';
5
5
  import { spawn, execFileSync, execSync } from 'node:child_process';
6
6
  import path, { resolve, join, dirname } from 'node:path';
7
7
  import { createInterface } from 'node:readline';
@@ -4581,7 +4581,13 @@ async function checkIfDaemonRunningAndCleanupStaleState() {
4581
4581
  return false;
4582
4582
  }
4583
4583
  }
4584
- return false;
4584
+ const lockPid = readDaemonLockPid();
4585
+ if (!lockPid) return false;
4586
+ if (!isProcessAlive(lockPid)) {
4587
+ await cleanupDaemonState();
4588
+ return false;
4589
+ }
4590
+ return true;
4585
4591
  }
4586
4592
  async function isDaemonRunningCurrentCliVersion() {
4587
4593
  logger.debug("[DAEMON CONTROL] Checking if daemon is running same version");
@@ -4637,7 +4643,43 @@ async function stopDaemon() {
4637
4643
  await cleanupDaemonState();
4638
4644
  return;
4639
4645
  }
4640
- logger.debug("No daemon state found");
4646
+ const lockPid = readDaemonLockPid();
4647
+ if (!lockPid) {
4648
+ logger.debug("No daemon state found");
4649
+ return;
4650
+ }
4651
+ if (!isProcessAlive(lockPid)) {
4652
+ logger.debug("[DAEMON RUN] Daemon lock PID not running, cleaning up state");
4653
+ await cleanupDaemonState();
4654
+ return;
4655
+ }
4656
+ const cmd = readProcessCommand(lockPid);
4657
+ const looksLikeDaemon = looksLikeFlockbayDaemonCommand(cmd, configuration.profile);
4658
+ if (!looksLikeDaemon) {
4659
+ logger.debug("[DAEMON RUN] Daemon lock is held by an unexpected process; refusing to kill", {
4660
+ lockPid,
4661
+ cmd: cmd || null
4662
+ });
4663
+ return;
4664
+ }
4665
+ logger.debug(`[DAEMON RUN] Stopping daemon by lock PID ${lockPid} (state file missing)`);
4666
+ try {
4667
+ process.kill(lockPid, "SIGTERM");
4668
+ } catch (error) {
4669
+ logger.debug("[DAEMON RUN] Failed to SIGTERM lock PID", { lockPid, error });
4670
+ }
4671
+ try {
4672
+ await waitForProcessDeath(lockPid, 2e3);
4673
+ } catch {
4674
+ }
4675
+ if (isProcessAlive(lockPid)) {
4676
+ try {
4677
+ process.kill(lockPid, "SIGKILL");
4678
+ } catch (error) {
4679
+ logger.debug("[DAEMON RUN] Failed to SIGKILL lock PID", { lockPid, error });
4680
+ }
4681
+ }
4682
+ await cleanupDaemonState();
4641
4683
  } catch (error) {
4642
4684
  logger.debug("Error stopping daemon", error);
4643
4685
  }
@@ -4654,6 +4696,39 @@ async function waitForProcessDeath(pid, timeout) {
4654
4696
  }
4655
4697
  throw new Error("Process did not die within timeout");
4656
4698
  }
4699
+ function isProcessAlive(pid) {
4700
+ try {
4701
+ process.kill(pid, 0);
4702
+ return true;
4703
+ } catch {
4704
+ return false;
4705
+ }
4706
+ }
4707
+ function readDaemonLockPid() {
4708
+ try {
4709
+ const raw = readFileSync$1(configuration.daemonLockFile, "utf-8").trim();
4710
+ const pid = Number(raw);
4711
+ return Number.isFinite(pid) && pid > 0 ? pid : null;
4712
+ } catch {
4713
+ return null;
4714
+ }
4715
+ }
4716
+ function readProcessCommand(pid) {
4717
+ try {
4718
+ return String(execFileSync("ps", ["-p", String(pid), "-o", "command="], { encoding: "utf8" }) || "").trim();
4719
+ } catch {
4720
+ return null;
4721
+ }
4722
+ }
4723
+ function looksLikeFlockbayDaemonCommand(command, profile) {
4724
+ const cmd = String(command || "").trim();
4725
+ if (!cmd) return false;
4726
+ if (!cmd.includes("flockbay")) return false;
4727
+ if (!cmd.includes("daemon")) return false;
4728
+ if (!cmd.includes("start-sync")) return false;
4729
+ if (!cmd.includes("--profile")) return false;
4730
+ return cmd.includes(profile);
4731
+ }
4657
4732
 
4658
4733
  async function findAllFlockbayProcesses() {
4659
4734
  try {
@@ -4938,8 +5013,8 @@ async function loginWithClerkAndPairMachine() {
4938
5013
  logger.debug("[AUTH] Starting Clerk-based CLI login + machine pairing");
4939
5014
  const settings = await updateSettings(async (s) => {
4940
5015
  const machineId2 = s.machineId || randomUUID();
4941
- const serverUrl2 = s.serverUrl || configuration.serverUrl;
4942
- const webappUrl = s.webappUrl || configuration.webappUrl;
5016
+ const serverUrl2 = configuration.serverUrl;
5017
+ const webappUrl = configuration.webappUrl;
4943
5018
  return { ...s, machineId: machineId2, serverUrl: serverUrl2, webappUrl };
4944
5019
  });
4945
5020
  const serverUrl = configuration.serverUrl.replace(/\/+$/, "");
@@ -11575,6 +11650,51 @@ async function reauthForCurrentServerKeepingMachineId() {
11575
11650
  await clearCredentials();
11576
11651
  await loginWithClerkAndPairMachine();
11577
11652
  }
11653
+ function isLocalDevServerUrl(url) {
11654
+ try {
11655
+ const u = new URL(String(url || "").trim());
11656
+ const host = u.hostname.toLowerCase();
11657
+ return host === "localhost" || host === "127.0.0.1" || host === "0.0.0.0" || host.endsWith(".localhost");
11658
+ } catch {
11659
+ return false;
11660
+ }
11661
+ }
11662
+ async function isServerReachable(url) {
11663
+ const base = String(url || "").trim().replace(/\/+$/, "");
11664
+ if (!base) return false;
11665
+ try {
11666
+ const res = await fetch(`${base}/healthz`, { method: "GET", signal: AbortSignal.timeout(1200) });
11667
+ return res.ok;
11668
+ } catch {
11669
+ return false;
11670
+ }
11671
+ }
11672
+ async function ensureProdServerWhenLocalDevUnreachable() {
11673
+ if ((process.env.FLOCKBAY_SERVER_URL || "").trim()) return;
11674
+ const settings = await readSettings().catch(() => null);
11675
+ const configured = String(settings?.serverUrl || "").trim();
11676
+ if (!configured) return;
11677
+ const normalized = normalizeServerUrlForNode(configured);
11678
+ if (!isLocalDevServerUrl(normalized)) return;
11679
+ const reachable = await isServerReachable(normalized);
11680
+ if (reachable) return;
11681
+ const shouldSwitch = await promptYesNo(
11682
+ `This profile is configured to use a local server (${normalized}), but it isn't reachable.
11683
+
11684
+ Switch this profile to production (https://api.flockbay.com) and re-authenticate?`,
11685
+ { defaultYes: true }
11686
+ );
11687
+ if (!shouldSwitch) return;
11688
+ const nextWebappUrl = String(settings?.webappUrl || "").trim() || "https://flockbay.com";
11689
+ await updateSettings((s) => ({
11690
+ ...s,
11691
+ serverUrl: "https://api.flockbay.com",
11692
+ webappUrl: nextWebappUrl
11693
+ }));
11694
+ configuration.serverUrl = "https://api.flockbay.com";
11695
+ configuration.webappUrl = nextWebappUrl;
11696
+ await reauthForCurrentServerKeepingMachineId();
11697
+ }
11578
11698
  function openUrlBestEffort(url) {
11579
11699
  const u = String(url || "").trim();
11580
11700
  if (!u) return;
@@ -11643,6 +11763,29 @@ async function startDaemonDetachedOrExit(opts) {
11643
11763
  const auth = await readCredentials().catch(() => null);
11644
11764
  const settings = await readSettings().catch(() => null);
11645
11765
  const daemon = await readDaemonState().catch(() => null);
11766
+ const desiredOrgId = auth?.orgId ? String(auth.orgId).trim() : "";
11767
+ const desiredMachineId = settings?.machineId ? String(settings.machineId).trim() : "";
11768
+ const daemonOrgId = typeof status?.orgId === "string" ? status.orgId.trim() : "";
11769
+ const daemonMachineId = typeof status?.machineId === "string" ? status.machineId.trim() : "";
11770
+ const daemonServerUrl = typeof status?.serverUrl === "string" ? status.serverUrl.trim() : "";
11771
+ const desiredServerUrl = String(configuration.serverUrl || "").trim();
11772
+ const orgMismatch = desiredOrgId && daemonOrgId && desiredOrgId !== daemonOrgId;
11773
+ const machineMismatch = desiredMachineId && daemonMachineId && desiredMachineId !== daemonMachineId;
11774
+ const serverMismatch = desiredServerUrl && daemonServerUrl && desiredServerUrl !== daemonServerUrl;
11775
+ if ((orgMismatch || machineMismatch || serverMismatch) && !opts?.restartAttempted) {
11776
+ console.error("");
11777
+ console.error(chalk.yellow("Daemon is running with different settings than the current CLI profile."));
11778
+ if (serverMismatch) console.error(chalk.gray(`Daemon server: ${daemonServerUrl || "unknown"}`));
11779
+ if (desiredServerUrl) console.error(chalk.gray(`CLI server: ${desiredServerUrl}`));
11780
+ if (orgMismatch) console.error(chalk.gray(`Daemon org: ${daemonOrgId || "unknown"}`));
11781
+ if (desiredOrgId) console.error(chalk.gray(`CLI org: ${desiredOrgId}`));
11782
+ if (machineMismatch) console.error(chalk.gray(`Daemon machine: ${daemonMachineId || "unknown"}`));
11783
+ if (desiredMachineId) console.error(chalk.gray(`CLI machine: ${desiredMachineId}`));
11784
+ console.error(chalk.gray("Restarting daemon to apply current login/pairing..."));
11785
+ await stopDaemon();
11786
+ await startDaemonDetachedOrExit({ ...opts, restartAttempted: true });
11787
+ return;
11788
+ }
11646
11789
  console.log(chalk.bold("\nFlockbay ready\n"));
11647
11790
  console.log(chalk.gray(`Profile: ${configuration.profile}`));
11648
11791
  console.log(chalk.gray(`Server: ${configuration.serverUrl}`));
@@ -11670,11 +11813,19 @@ async function startDaemonDetachedOrExit(opts) {
11670
11813
  }
11671
11814
  console.error("");
11672
11815
  console.error(chalk.red("Daemon is running but not connected to the server."));
11816
+ console.error(chalk.gray(`Profile: ${configuration.profile}`));
11817
+ console.error(chalk.gray(`Server: ${configuration.serverUrl}`));
11673
11818
  if (typeof status?.connection?.lastHttpUpsertError === "string" && status.connection.lastHttpUpsertError.trim()) {
11674
11819
  console.error(chalk.gray(`Last upsert error: ${status.connection.lastHttpUpsertError.trim()}`));
11675
11820
  }
11676
11821
  if (lastConnectError) console.error(chalk.gray(`Last connect error: ${lastConnectError}`));
11677
- console.error(chalk.gray("Tip: if the backend is restarting, wait a moment and re-run `flockbay start`."));
11822
+ if (isLocalDevServerUrl(configuration.serverUrl)) {
11823
+ console.error(chalk.gray("Tip: if you meant to run against production, set the server URL or use a prod profile:"));
11824
+ console.error(chalk.gray(" FLOCKBAY_SERVER_URL=https://api.flockbay.com flockbay start"));
11825
+ console.error(chalk.gray(" flockbay start --profile prod"));
11826
+ } else {
11827
+ console.error(chalk.gray("Tip: if the backend is restarting, wait a moment and re-run `flockbay start`."));
11828
+ }
11678
11829
  process.exit(1);
11679
11830
  }
11680
11831
  }
@@ -11878,6 +12029,7 @@ async function authAndSetupMachineIfNeeded() {
11878
12029
  return;
11879
12030
  }
11880
12031
  try {
12032
+ await ensureProdServerWhenLocalDevUnreachable();
11881
12033
  await ensureMachineAuthOrLogin();
11882
12034
  const skipUnreal = startArgs.includes("--skip-unreal");
11883
12035
  if (!skipUnreal) {
@@ -11912,7 +12064,7 @@ ${engineRoot}`, {
11912
12064
  } else if (subcommand === "codex") {
11913
12065
  try {
11914
12066
  await chdirToNearestUprojectRootIfPresent();
11915
- const { runCodex } = await import('./runCodex-Di9eHddq.mjs');
12067
+ const { runCodex } = await import('./runCodex-DwsaTF4s.mjs');
11916
12068
  let startedBy = void 0;
11917
12069
  let sessionId = void 0;
11918
12070
  for (let i = 1; i < args.length; i++) {
@@ -12007,7 +12159,7 @@ ${engineRoot}`, {
12007
12159
  }
12008
12160
  try {
12009
12161
  await chdirToNearestUprojectRootIfPresent();
12010
- const { runGemini } = await import('./runGemini-BS6sBU_V.mjs');
12162
+ const { runGemini } = await import('./runGemini-qA5dD13X.mjs');
12011
12163
  let startedBy = void 0;
12012
12164
  let sessionId = void 0;
12013
12165
  for (let i = 1; i < args.length; i++) {
@@ -3,7 +3,7 @@
3
3
  var chalk = require('chalk');
4
4
  var os = require('node:os');
5
5
  var node_crypto = require('node:crypto');
6
- var types = require('./types-SUAKq-K0.cjs');
6
+ var types = require('./types-CL_3YyS9.cjs');
7
7
  var node_child_process = require('node:child_process');
8
8
  var path = require('node:path');
9
9
  var node_readline = require('node:readline');
@@ -1272,7 +1272,7 @@ function buildDaemonSafeEnv(baseEnv, binPath) {
1272
1272
  env[pathKey] = [...prepend, ...existingParts].join(pathSep);
1273
1273
  return env;
1274
1274
  }
1275
- const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-Cau-_Qvn.cjs', document.baseURI).href)));
1275
+ const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-BiUf5vLX.cjs', document.baseURI).href)));
1276
1276
  const __dirname$1 = path.join(__filename$1, "..");
1277
1277
  function getGlobalClaudeVersion(claudeExecutable) {
1278
1278
  try {
@@ -4603,7 +4603,13 @@ async function checkIfDaemonRunningAndCleanupStaleState() {
4603
4603
  return false;
4604
4604
  }
4605
4605
  }
4606
- return false;
4606
+ const lockPid = readDaemonLockPid();
4607
+ if (!lockPid) return false;
4608
+ if (!isProcessAlive(lockPid)) {
4609
+ await cleanupDaemonState();
4610
+ return false;
4611
+ }
4612
+ return true;
4607
4613
  }
4608
4614
  async function isDaemonRunningCurrentCliVersion() {
4609
4615
  types.logger.debug("[DAEMON CONTROL] Checking if daemon is running same version");
@@ -4659,7 +4665,43 @@ async function stopDaemon() {
4659
4665
  await cleanupDaemonState();
4660
4666
  return;
4661
4667
  }
4662
- types.logger.debug("No daemon state found");
4668
+ const lockPid = readDaemonLockPid();
4669
+ if (!lockPid) {
4670
+ types.logger.debug("No daemon state found");
4671
+ return;
4672
+ }
4673
+ if (!isProcessAlive(lockPid)) {
4674
+ types.logger.debug("[DAEMON RUN] Daemon lock PID not running, cleaning up state");
4675
+ await cleanupDaemonState();
4676
+ return;
4677
+ }
4678
+ const cmd = readProcessCommand(lockPid);
4679
+ const looksLikeDaemon = looksLikeFlockbayDaemonCommand(cmd, types.configuration.profile);
4680
+ if (!looksLikeDaemon) {
4681
+ types.logger.debug("[DAEMON RUN] Daemon lock is held by an unexpected process; refusing to kill", {
4682
+ lockPid,
4683
+ cmd: cmd || null
4684
+ });
4685
+ return;
4686
+ }
4687
+ types.logger.debug(`[DAEMON RUN] Stopping daemon by lock PID ${lockPid} (state file missing)`);
4688
+ try {
4689
+ process.kill(lockPid, "SIGTERM");
4690
+ } catch (error) {
4691
+ types.logger.debug("[DAEMON RUN] Failed to SIGTERM lock PID", { lockPid, error });
4692
+ }
4693
+ try {
4694
+ await waitForProcessDeath(lockPid, 2e3);
4695
+ } catch {
4696
+ }
4697
+ if (isProcessAlive(lockPid)) {
4698
+ try {
4699
+ process.kill(lockPid, "SIGKILL");
4700
+ } catch (error) {
4701
+ types.logger.debug("[DAEMON RUN] Failed to SIGKILL lock PID", { lockPid, error });
4702
+ }
4703
+ }
4704
+ await cleanupDaemonState();
4663
4705
  } catch (error) {
4664
4706
  types.logger.debug("Error stopping daemon", error);
4665
4707
  }
@@ -4676,6 +4718,39 @@ async function waitForProcessDeath(pid, timeout) {
4676
4718
  }
4677
4719
  throw new Error("Process did not die within timeout");
4678
4720
  }
4721
+ function isProcessAlive(pid) {
4722
+ try {
4723
+ process.kill(pid, 0);
4724
+ return true;
4725
+ } catch {
4726
+ return false;
4727
+ }
4728
+ }
4729
+ function readDaemonLockPid() {
4730
+ try {
4731
+ const raw = fs$3.readFileSync(types.configuration.daemonLockFile, "utf-8").trim();
4732
+ const pid = Number(raw);
4733
+ return Number.isFinite(pid) && pid > 0 ? pid : null;
4734
+ } catch {
4735
+ return null;
4736
+ }
4737
+ }
4738
+ function readProcessCommand(pid) {
4739
+ try {
4740
+ return String(node_child_process.execFileSync("ps", ["-p", String(pid), "-o", "command="], { encoding: "utf8" }) || "").trim();
4741
+ } catch {
4742
+ return null;
4743
+ }
4744
+ }
4745
+ function looksLikeFlockbayDaemonCommand(command, profile) {
4746
+ const cmd = String(command || "").trim();
4747
+ if (!cmd) return false;
4748
+ if (!cmd.includes("flockbay")) return false;
4749
+ if (!cmd.includes("daemon")) return false;
4750
+ if (!cmd.includes("start-sync")) return false;
4751
+ if (!cmd.includes("--profile")) return false;
4752
+ return cmd.includes(profile);
4753
+ }
4679
4754
 
4680
4755
  async function findAllFlockbayProcesses() {
4681
4756
  try {
@@ -4960,8 +5035,8 @@ async function loginWithClerkAndPairMachine() {
4960
5035
  types.logger.debug("[AUTH] Starting Clerk-based CLI login + machine pairing");
4961
5036
  const settings = await types.updateSettings(async (s) => {
4962
5037
  const machineId2 = s.machineId || node_crypto.randomUUID();
4963
- const serverUrl2 = s.serverUrl || types.configuration.serverUrl;
4964
- const webappUrl = s.webappUrl || types.configuration.webappUrl;
5038
+ const serverUrl2 = types.configuration.serverUrl;
5039
+ const webappUrl = types.configuration.webappUrl;
4965
5040
  return { ...s, machineId: machineId2, serverUrl: serverUrl2, webappUrl };
4966
5041
  });
4967
5042
  const serverUrl = types.configuration.serverUrl.replace(/\/+$/, "");
@@ -11597,6 +11672,51 @@ async function reauthForCurrentServerKeepingMachineId() {
11597
11672
  await types.clearCredentials();
11598
11673
  await loginWithClerkAndPairMachine();
11599
11674
  }
11675
+ function isLocalDevServerUrl(url) {
11676
+ try {
11677
+ const u = new URL(String(url || "").trim());
11678
+ const host = u.hostname.toLowerCase();
11679
+ return host === "localhost" || host === "127.0.0.1" || host === "0.0.0.0" || host.endsWith(".localhost");
11680
+ } catch {
11681
+ return false;
11682
+ }
11683
+ }
11684
+ async function isServerReachable(url) {
11685
+ const base = String(url || "").trim().replace(/\/+$/, "");
11686
+ if (!base) return false;
11687
+ try {
11688
+ const res = await fetch(`${base}/healthz`, { method: "GET", signal: AbortSignal.timeout(1200) });
11689
+ return res.ok;
11690
+ } catch {
11691
+ return false;
11692
+ }
11693
+ }
11694
+ async function ensureProdServerWhenLocalDevUnreachable() {
11695
+ if ((process.env.FLOCKBAY_SERVER_URL || "").trim()) return;
11696
+ const settings = await types.readSettings().catch(() => null);
11697
+ const configured = String(settings?.serverUrl || "").trim();
11698
+ if (!configured) return;
11699
+ const normalized = types.normalizeServerUrlForNode(configured);
11700
+ if (!isLocalDevServerUrl(normalized)) return;
11701
+ const reachable = await isServerReachable(normalized);
11702
+ if (reachable) return;
11703
+ const shouldSwitch = await promptYesNo(
11704
+ `This profile is configured to use a local server (${normalized}), but it isn't reachable.
11705
+
11706
+ Switch this profile to production (https://api.flockbay.com) and re-authenticate?`,
11707
+ { defaultYes: true }
11708
+ );
11709
+ if (!shouldSwitch) return;
11710
+ const nextWebappUrl = String(settings?.webappUrl || "").trim() || "https://flockbay.com";
11711
+ await types.updateSettings((s) => ({
11712
+ ...s,
11713
+ serverUrl: "https://api.flockbay.com",
11714
+ webappUrl: nextWebappUrl
11715
+ }));
11716
+ types.configuration.serverUrl = "https://api.flockbay.com";
11717
+ types.configuration.webappUrl = nextWebappUrl;
11718
+ await reauthForCurrentServerKeepingMachineId();
11719
+ }
11600
11720
  function openUrlBestEffort(url) {
11601
11721
  const u = String(url || "").trim();
11602
11722
  if (!u) return;
@@ -11665,6 +11785,29 @@ async function startDaemonDetachedOrExit(opts) {
11665
11785
  const auth = await types.readCredentials().catch(() => null);
11666
11786
  const settings = await types.readSettings().catch(() => null);
11667
11787
  const daemon = await types.readDaemonState().catch(() => null);
11788
+ const desiredOrgId = auth?.orgId ? String(auth.orgId).trim() : "";
11789
+ const desiredMachineId = settings?.machineId ? String(settings.machineId).trim() : "";
11790
+ const daemonOrgId = typeof status?.orgId === "string" ? status.orgId.trim() : "";
11791
+ const daemonMachineId = typeof status?.machineId === "string" ? status.machineId.trim() : "";
11792
+ const daemonServerUrl = typeof status?.serverUrl === "string" ? status.serverUrl.trim() : "";
11793
+ const desiredServerUrl = String(types.configuration.serverUrl || "").trim();
11794
+ const orgMismatch = desiredOrgId && daemonOrgId && desiredOrgId !== daemonOrgId;
11795
+ const machineMismatch = desiredMachineId && daemonMachineId && desiredMachineId !== daemonMachineId;
11796
+ const serverMismatch = desiredServerUrl && daemonServerUrl && desiredServerUrl !== daemonServerUrl;
11797
+ if ((orgMismatch || machineMismatch || serverMismatch) && !opts?.restartAttempted) {
11798
+ console.error("");
11799
+ console.error(chalk.yellow("Daemon is running with different settings than the current CLI profile."));
11800
+ if (serverMismatch) console.error(chalk.gray(`Daemon server: ${daemonServerUrl || "unknown"}`));
11801
+ if (desiredServerUrl) console.error(chalk.gray(`CLI server: ${desiredServerUrl}`));
11802
+ if (orgMismatch) console.error(chalk.gray(`Daemon org: ${daemonOrgId || "unknown"}`));
11803
+ if (desiredOrgId) console.error(chalk.gray(`CLI org: ${desiredOrgId}`));
11804
+ if (machineMismatch) console.error(chalk.gray(`Daemon machine: ${daemonMachineId || "unknown"}`));
11805
+ if (desiredMachineId) console.error(chalk.gray(`CLI machine: ${desiredMachineId}`));
11806
+ console.error(chalk.gray("Restarting daemon to apply current login/pairing..."));
11807
+ await stopDaemon();
11808
+ await startDaemonDetachedOrExit({ ...opts, restartAttempted: true });
11809
+ return;
11810
+ }
11668
11811
  console.log(chalk.bold("\nFlockbay ready\n"));
11669
11812
  console.log(chalk.gray(`Profile: ${types.configuration.profile}`));
11670
11813
  console.log(chalk.gray(`Server: ${types.configuration.serverUrl}`));
@@ -11692,11 +11835,19 @@ async function startDaemonDetachedOrExit(opts) {
11692
11835
  }
11693
11836
  console.error("");
11694
11837
  console.error(chalk.red("Daemon is running but not connected to the server."));
11838
+ console.error(chalk.gray(`Profile: ${types.configuration.profile}`));
11839
+ console.error(chalk.gray(`Server: ${types.configuration.serverUrl}`));
11695
11840
  if (typeof status?.connection?.lastHttpUpsertError === "string" && status.connection.lastHttpUpsertError.trim()) {
11696
11841
  console.error(chalk.gray(`Last upsert error: ${status.connection.lastHttpUpsertError.trim()}`));
11697
11842
  }
11698
11843
  if (lastConnectError) console.error(chalk.gray(`Last connect error: ${lastConnectError}`));
11699
- console.error(chalk.gray("Tip: if the backend is restarting, wait a moment and re-run `flockbay start`."));
11844
+ if (isLocalDevServerUrl(types.configuration.serverUrl)) {
11845
+ console.error(chalk.gray("Tip: if you meant to run against production, set the server URL or use a prod profile:"));
11846
+ console.error(chalk.gray(" FLOCKBAY_SERVER_URL=https://api.flockbay.com flockbay start"));
11847
+ console.error(chalk.gray(" flockbay start --profile prod"));
11848
+ } else {
11849
+ console.error(chalk.gray("Tip: if the backend is restarting, wait a moment and re-run `flockbay start`."));
11850
+ }
11700
11851
  process.exit(1);
11701
11852
  }
11702
11853
  }
@@ -11900,6 +12051,7 @@ async function authAndSetupMachineIfNeeded() {
11900
12051
  return;
11901
12052
  }
11902
12053
  try {
12054
+ await ensureProdServerWhenLocalDevUnreachable();
11903
12055
  await ensureMachineAuthOrLogin();
11904
12056
  const skipUnreal = startArgs.includes("--skip-unreal");
11905
12057
  if (!skipUnreal) {
@@ -11934,7 +12086,7 @@ ${engineRoot}`, {
11934
12086
  } else if (subcommand === "codex") {
11935
12087
  try {
11936
12088
  await chdirToNearestUprojectRootIfPresent();
11937
- const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-DzP3VUa-.cjs'); });
12089
+ const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-Bh3-ebwT.cjs'); });
11938
12090
  let startedBy = void 0;
11939
12091
  let sessionId = void 0;
11940
12092
  for (let i = 1; i < args.length; i++) {
@@ -12029,7 +12181,7 @@ ${engineRoot}`, {
12029
12181
  }
12030
12182
  try {
12031
12183
  await chdirToNearestUprojectRootIfPresent();
12032
- const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-CpmehDQ2.cjs'); });
12184
+ const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-hXryGqFd.cjs'); });
12033
12185
  let startedBy = void 0;
12034
12186
  let sessionId = void 0;
12035
12187
  for (let i = 1; i < args.length; i++) {
package/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  require('chalk');
4
- require('./index-Cau-_Qvn.cjs');
5
- require('./types-SUAKq-K0.cjs');
4
+ require('./index-BiUf5vLX.cjs');
5
+ require('./types-CL_3YyS9.cjs');
6
6
  require('zod');
7
7
  require('node:child_process');
8
8
  require('node:fs');
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import 'chalk';
2
- import './index-DtmFQzXY.mjs';
3
- import './types-CwzNqYEx.mjs';
2
+ import './index-5jfGXWTy.mjs';
3
+ import './types-BQvaA3sv.mjs';
4
4
  import 'zod';
5
5
  import 'node:child_process';
6
6
  import 'node:fs';
package/dist/lib.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var types = require('./types-SUAKq-K0.cjs');
3
+ var types = require('./types-CL_3YyS9.cjs');
4
4
  require('axios');
5
5
  require('node:fs');
6
6
  require('node:os');
package/dist/lib.d.cts CHANGED
@@ -617,15 +617,9 @@ declare class Logger {
617
617
  }
618
618
  declare let logger: Logger;
619
619
 
620
- /**
621
- * Global configuration for Flockbay CLI
622
- *
623
- * Centralizes all configuration including environment variables and paths
624
- * Environment files should be loaded using Node's --env-file flag
625
- */
626
620
  declare class Configuration {
627
- readonly serverUrl: string;
628
- readonly webappUrl: string;
621
+ serverUrl: string;
622
+ webappUrl: string;
629
623
  readonly isDaemonProcess: boolean;
630
624
  readonly profile: string;
631
625
  readonly flockbayHomeDir: string;
package/dist/lib.d.mts CHANGED
@@ -617,15 +617,9 @@ declare class Logger {
617
617
  }
618
618
  declare let logger: Logger;
619
619
 
620
- /**
621
- * Global configuration for Flockbay CLI
622
- *
623
- * Centralizes all configuration including environment variables and paths
624
- * Environment files should be loaded using Node's --env-file flag
625
- */
626
620
  declare class Configuration {
627
- readonly serverUrl: string;
628
- readonly webappUrl: string;
621
+ serverUrl: string;
622
+ webappUrl: string;
629
623
  readonly isDaemonProcess: boolean;
630
624
  readonly profile: string;
631
625
  readonly flockbayHomeDir: string;
package/dist/lib.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-CwzNqYEx.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-BQvaA3sv.mjs';
2
2
  import 'axios';
3
3
  import 'node:fs';
4
4
  import 'node:os';
@@ -2,7 +2,7 @@
2
2
 
3
3
  var ink = require('ink');
4
4
  var React = require('react');
5
- var types = require('./types-SUAKq-K0.cjs');
5
+ var types = require('./types-CL_3YyS9.cjs');
6
6
  var index_js = require('@modelcontextprotocol/sdk/client/index.js');
7
7
  var stdio_js = require('@modelcontextprotocol/sdk/client/stdio.js');
8
8
  var z = require('zod');
@@ -12,7 +12,7 @@ var fs = require('node:fs');
12
12
  var os = require('node:os');
13
13
  var path = require('node:path');
14
14
  var node_child_process = require('node:child_process');
15
- var index = require('./index-Cau-_Qvn.cjs');
15
+ var index = require('./index-BiUf5vLX.cjs');
16
16
  require('axios');
17
17
  require('node:events');
18
18
  require('socket.io-client');
@@ -1,6 +1,6 @@
1
1
  import { useStdout, useInput, Box, Text, render } from 'ink';
2
2
  import React, { useState, useRef, useEffect, useCallback } from 'react';
3
- import { l as logger, A as ApiClient, r as readSettings, p as projectPath, c as configuration, b as packageJson } from './types-CwzNqYEx.mjs';
3
+ import { l as logger, A as ApiClient, r as readSettings, p as projectPath, c as configuration, b as packageJson } from './types-BQvaA3sv.mjs';
4
4
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
5
5
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
6
6
  import { z } from 'zod';
@@ -10,7 +10,7 @@ import fs__default from 'node:fs';
10
10
  import os from 'node:os';
11
11
  import path, { resolve, join } from 'node:path';
12
12
  import { spawnSync } from 'node:child_process';
13
- import { s as shouldCountToolCall, c as consumeToolQuota, f as formatQuotaDeniedReason, h as hashObject, i as initialMachineMetadata, E as ElicitationHub, n as notifyDaemonSessionStarted, M as MessageQueue2, P as PLATFORM_SYSTEM_PROMPT, a as setLatestUserImages, w as withUserImagesMarker, r as registerKillSessionHandler, b as MessageBuffer, d as startFlockbayServer, e as detectUnrealProject, g as buildProjectCapsule, t as trimIdent, j as autoFinalizeCoordinationWorkItem, k as detectScreenshotsForGate, l as applyCoordinationSideEffectsFromMcpToolResult, m as stopCaffeinate } from './index-DtmFQzXY.mjs';
13
+ import { s as shouldCountToolCall, c as consumeToolQuota, f as formatQuotaDeniedReason, h as hashObject, i as initialMachineMetadata, E as ElicitationHub, n as notifyDaemonSessionStarted, M as MessageQueue2, P as PLATFORM_SYSTEM_PROMPT, a as setLatestUserImages, w as withUserImagesMarker, r as registerKillSessionHandler, b as MessageBuffer, d as startFlockbayServer, e as detectUnrealProject, g as buildProjectCapsule, t as trimIdent, j as autoFinalizeCoordinationWorkItem, k as detectScreenshotsForGate, l as applyCoordinationSideEffectsFromMcpToolResult, m as stopCaffeinate } from './index-5jfGXWTy.mjs';
14
14
  import 'axios';
15
15
  import 'node:events';
16
16
  import 'socket.io-client';
@@ -6,8 +6,8 @@ var node_crypto = require('node:crypto');
6
6
  var os = require('node:os');
7
7
  var path = require('node:path');
8
8
  var fs$2 = require('node:fs/promises');
9
- var types = require('./types-SUAKq-K0.cjs');
10
- var index = require('./index-Cau-_Qvn.cjs');
9
+ var types = require('./types-CL_3YyS9.cjs');
10
+ var index = require('./index-BiUf5vLX.cjs');
11
11
  var node_child_process = require('node:child_process');
12
12
  var sdk = require('@agentclientprotocol/sdk');
13
13
  var fs = require('fs');
@@ -4,8 +4,8 @@ import { randomUUID, createHash } from 'node:crypto';
4
4
  import os from 'node:os';
5
5
  import path, { resolve, join as join$1, basename } from 'node:path';
6
6
  import { mkdir, writeFile, readFile } from 'node:fs/promises';
7
- import { l as logger, b as packageJson, A as ApiClient, r as readSettings, p as projectPath, c as configuration } from './types-CwzNqYEx.mjs';
8
- import { s as shouldCountToolCall, c as consumeToolQuota, f as formatQuotaDeniedReason, h as hashObject, i as initialMachineMetadata, n as notifyDaemonSessionStarted, M as MessageQueue2, g as buildProjectCapsule, a as setLatestUserImages, b as MessageBuffer, w as withUserImagesMarker, P as PLATFORM_SYSTEM_PROMPT, r as registerKillSessionHandler, d as startFlockbayServer, o as extractUserImagesMarker, p as getLatestUserImages, j as autoFinalizeCoordinationWorkItem, E as ElicitationHub, k as detectScreenshotsForGate, m as stopCaffeinate } from './index-DtmFQzXY.mjs';
7
+ import { l as logger, b as packageJson, A as ApiClient, r as readSettings, p as projectPath, c as configuration } from './types-BQvaA3sv.mjs';
8
+ import { s as shouldCountToolCall, c as consumeToolQuota, f as formatQuotaDeniedReason, h as hashObject, i as initialMachineMetadata, n as notifyDaemonSessionStarted, M as MessageQueue2, g as buildProjectCapsule, a as setLatestUserImages, b as MessageBuffer, w as withUserImagesMarker, P as PLATFORM_SYSTEM_PROMPT, r as registerKillSessionHandler, d as startFlockbayServer, o as extractUserImagesMarker, p as getLatestUserImages, j as autoFinalizeCoordinationWorkItem, E as ElicitationHub, k as detectScreenshotsForGate, m as stopCaffeinate } from './index-5jfGXWTy.mjs';
9
9
  import { spawn, spawnSync } from 'node:child_process';
10
10
  import { ndJsonStream, ClientSideConnection } from '@agentclientprotocol/sdk';
11
11
  import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
@@ -21,7 +21,7 @@ import net from 'node:net';
21
21
  import { spawn as spawn$1 } from 'node:child_process';
22
22
 
23
23
  var name = "flockbay";
24
- var version = "0.10.16";
24
+ var version = "0.10.19";
25
25
  var description = "Flockbay CLI (local agent + daemon)";
26
26
  var author = "Eduardo Orellana";
27
27
  var license = "UNLICENSED";
@@ -176,7 +176,7 @@ function parseProfileFromProcessArgs() {
176
176
  const args = process.argv.slice(2);
177
177
  for (let i = 0; i < args.length; i++) {
178
178
  const a = String(args[i] || "");
179
- if (a === "--profile") {
179
+ if (a === "--profile" || a === "-profile" || a === "-p") {
180
180
  const v = String(args[i + 1] || "").trim();
181
181
  if (v && !v.startsWith("-")) return v;
182
182
  }
@@ -184,6 +184,10 @@ function parseProfileFromProcessArgs() {
184
184
  const v = a.slice("--profile=".length).trim();
185
185
  if (v) return v;
186
186
  }
187
+ if (a.startsWith("-profile=")) {
188
+ const v = a.slice("-profile=".length).trim();
189
+ if (v) return v;
190
+ }
187
191
  }
188
192
  return "";
189
193
  }
@@ -241,7 +245,7 @@ class Configuration {
241
245
  }
242
246
  } catch {
243
247
  }
244
- const rawServerUrl = process.env.FLOCKBAY_SERVER_URL || persistedSettings?.serverUrl || "https://api-internal.flockbay.com";
248
+ const rawServerUrl = process.env.FLOCKBAY_SERVER_URL || persistedSettings?.serverUrl || "https://api.flockbay.com";
245
249
  this.serverUrl = normalizeServerUrlForNode(rawServerUrl);
246
250
  this.webappUrl = process.env.FLOCKBAY_WEBAPP_URL || persistedSettings?.webappUrl || "https://flockbay.com";
247
251
  this.isExperimentalEnabled = ["true", "1", "yes"].includes(
@@ -3770,4 +3774,4 @@ const RawJSONLinesSchema = z$1.discriminatedUnion("type", [
3770
3774
  }).passthrough()
3771
3775
  ]);
3772
3776
 
3773
- export { ApiClient as A, RawJSONLinesSchema as R, ApiSessionClient as a, packageJson as b, configuration as c, backoff as d, delay as e, readDaemonState as f, clearDaemonState as g, readCredentials as h, unrealMcpPythonDir as i, acquireDaemonLock as j, writeDaemonState as k, logger as l, ApiMachineClient as m, releaseDaemonLock as n, clearCredentials as o, projectPath as p, clearMachineId as q, readSettings as r, sendUnrealMcpTcpCommand as s, installUnrealMcpPluginToEngine as t, updateSettings as u, getLatestDaemonLog as v, writeCredentials as w };
3777
+ export { ApiClient as A, RawJSONLinesSchema as R, ApiSessionClient as a, packageJson as b, configuration as c, backoff as d, delay as e, readDaemonState as f, clearDaemonState as g, readCredentials as h, unrealMcpPythonDir as i, acquireDaemonLock as j, writeDaemonState as k, logger as l, ApiMachineClient as m, releaseDaemonLock as n, clearCredentials as o, projectPath as p, clearMachineId as q, readSettings as r, sendUnrealMcpTcpCommand as s, installUnrealMcpPluginToEngine as t, updateSettings as u, getLatestDaemonLog as v, writeCredentials as w, normalizeServerUrlForNode as x };
@@ -42,7 +42,7 @@ function _interopNamespaceDefault(e) {
42
42
  var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
43
43
 
44
44
  var name = "flockbay";
45
- var version = "0.10.16";
45
+ var version = "0.10.19";
46
46
  var description = "Flockbay CLI (local agent + daemon)";
47
47
  var author = "Eduardo Orellana";
48
48
  var license = "UNLICENSED";
@@ -197,7 +197,7 @@ function parseProfileFromProcessArgs() {
197
197
  const args = process.argv.slice(2);
198
198
  for (let i = 0; i < args.length; i++) {
199
199
  const a = String(args[i] || "");
200
- if (a === "--profile") {
200
+ if (a === "--profile" || a === "-profile" || a === "-p") {
201
201
  const v = String(args[i + 1] || "").trim();
202
202
  if (v && !v.startsWith("-")) return v;
203
203
  }
@@ -205,6 +205,10 @@ function parseProfileFromProcessArgs() {
205
205
  const v = a.slice("--profile=".length).trim();
206
206
  if (v) return v;
207
207
  }
208
+ if (a.startsWith("-profile=")) {
209
+ const v = a.slice("-profile=".length).trim();
210
+ if (v) return v;
211
+ }
208
212
  }
209
213
  return "";
210
214
  }
@@ -262,7 +266,7 @@ class Configuration {
262
266
  }
263
267
  } catch {
264
268
  }
265
- const rawServerUrl = process.env.FLOCKBAY_SERVER_URL || persistedSettings?.serverUrl || "https://api-internal.flockbay.com";
269
+ const rawServerUrl = process.env.FLOCKBAY_SERVER_URL || persistedSettings?.serverUrl || "https://api.flockbay.com";
266
270
  this.serverUrl = normalizeServerUrlForNode(rawServerUrl);
267
271
  this.webappUrl = process.env.FLOCKBAY_WEBAPP_URL || persistedSettings?.webappUrl || "https://flockbay.com";
268
272
  this.isExperimentalEnabled = ["true", "1", "yes"].includes(
@@ -766,7 +770,7 @@ class RpcHandlerManager {
766
770
  }
767
771
  }
768
772
 
769
- const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-SUAKq-K0.cjs', document.baseURI).href))));
773
+ const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-CL_3YyS9.cjs', document.baseURI).href))));
770
774
  function projectPath() {
771
775
  const path = path$1.resolve(__dirname$1, "..");
772
776
  return path;
@@ -3805,6 +3809,7 @@ exports.delay = delay;
3805
3809
  exports.getLatestDaemonLog = getLatestDaemonLog;
3806
3810
  exports.installUnrealMcpPluginToEngine = installUnrealMcpPluginToEngine;
3807
3811
  exports.logger = logger;
3812
+ exports.normalizeServerUrlForNode = normalizeServerUrlForNode;
3808
3813
  exports.packageJson = packageJson;
3809
3814
  exports.projectPath = projectPath;
3810
3815
  exports.readCredentials = readCredentials;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flockbay",
3
- "version": "0.10.16",
3
+ "version": "0.10.19",
4
4
  "description": "Flockbay CLI (local agent + daemon)",
5
5
  "author": "Eduardo Orellana",
6
6
  "license": "UNLICENSED",