orionfold-relay 0.15.2 → 0.15.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -25202,8 +25202,8 @@ import { execFileSync as execFileSync3 } from "child_process";
25202
25202
  import yaml12 from "js-yaml";
25203
25203
  import semver from "semver";
25204
25204
  function relayCoreVersion() {
25205
- if (semver.valid("0.15.2")) {
25206
- return "0.15.2";
25205
+ if (semver.valid("0.15.3")) {
25206
+ return "0.15.3";
25207
25207
  }
25208
25208
  try {
25209
25209
  const root = getAppRoot(import.meta.dirname, 3);
@@ -25645,6 +25645,12 @@ function buildNextLaunchArgs({
25645
25645
  function buildSidecarUrl(port, host = SIDECAR_LOOPBACK_HOST) {
25646
25646
  return `http://${host}:${port}`;
25647
25647
  }
25648
+ function isNonLoopbackHost(host) {
25649
+ const h = host.trim().toLowerCase();
25650
+ if (h === "localhost" || h === "::1") return false;
25651
+ if (/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(h)) return false;
25652
+ return true;
25653
+ }
25648
25654
 
25649
25655
  // bin/cli.ts
25650
25656
  init_ainative_paths();
@@ -25842,6 +25848,7 @@ Environment variables:
25842
25848
 
25843
25849
  Examples:
25844
25850
  node dist/cli.js --port 3210 --no-open
25851
+ node dist/cli.js --hostname 0.0.0.0 --port 3000 # expose on the LAN (see warning)
25845
25852
  node dist/cli.js --data-dir ~/.relay-dogfood --port 3100
25846
25853
  node dist/cli.js plugin dry-run my-plugin # print confinement policy
25847
25854
  node dist/cli.js pack add ./my-pack # install a Relay pack (folder or git url)
@@ -25849,7 +25856,11 @@ Examples:
25849
25856
  node dist/cli.js pack remove my-pack # uninstall a pack
25850
25857
  `;
25851
25858
  }
25852
- program.name("relay").description("Orionfold Relay \u2014 a local-first, multi-agent orchestration runtime and builder scaffold for AI-native work.").version(pkg.version).addHelpText("after", getHelpText).option("-p, --port <number>", "port to start on", "3000").option("--data-dir <path>", "custom data directory (overrides RELAY_DATA_DIR)").option("--reset", "delete the local database before starting").option("--no-open", "don't auto-open browser").option("--safe-mode", "disable Kind-1 plugin MCP servers; Kind-5 primitives bundles still load");
25859
+ program.name("relay").description("Orionfold Relay \u2014 a local-first, multi-agent orchestration runtime and builder scaffold for AI-native work.").version(pkg.version).addHelpText("after", getHelpText).option("-p, --port <number>", "port to start on", "3000").option(
25860
+ "--hostname <host>",
25861
+ "host to bind to (default 127.0.0.1; use 0.0.0.0 to expose on the network)",
25862
+ "127.0.0.1"
25863
+ ).option("--data-dir <path>", "custom data directory (overrides RELAY_DATA_DIR)").option("--reset", "delete the local database before starting").option("--no-open", "don't auto-open browser").option("--safe-mode", "disable Kind-1 plugin MCP servers; Kind-5 primitives bundles still load");
25853
25864
  var firstArg = process.argv[2];
25854
25865
  var isPluginSubcommand = firstArg === "plugin";
25855
25866
  var isPackSubcommand = firstArg === "pack";
@@ -25979,11 +25990,18 @@ async function main() {
25979
25990
  }
25980
25991
  const nextEntrypoint = resolveNextEntrypoint(effectiveCwd);
25981
25992
  const isPrebuilt = existsSync12(join20(effectiveCwd, ".next", "BUILD_ID"));
25993
+ const bindHost = opts.hostname || "127.0.0.1";
25994
+ if (isNonLoopbackHost(bindHost)) {
25995
+ console.warn(
25996
+ `\u26A0 Binding to ${bindHost} \u2014 Relay will be reachable from other machines on the network. It is designed for local-first, single-user use and has no network authentication. Only do this on a trusted network, and put a reverse proxy with auth in front if exposing it more broadly.`
25997
+ );
25998
+ }
25982
25999
  const nextArgs = buildNextLaunchArgs({
25983
26000
  isPrebuilt,
25984
- port: actualPort
26001
+ port: actualPort,
26002
+ host: bindHost
25985
26003
  });
25986
- const sidecarUrl = buildSidecarUrl(actualPort);
26004
+ const sidecarUrl = buildSidecarUrl(actualPort, bindHost);
25987
26005
  console.log(`Orionfold Relay ${pkg.version} \u2014 Community Edition`);
25988
26006
  console.log(`Data dir: ${DATA_DIR}`);
25989
26007
  console.log(`Mode: ${isPrebuilt ? "production" : "development"}`);
@@ -26002,10 +26020,11 @@ async function main() {
26002
26020
  }
26003
26021
  });
26004
26022
  if (opts.open !== false) {
26023
+ const openUrl = isNonLoopbackHost(bindHost) ? buildSidecarUrl(actualPort, "127.0.0.1") : sidecarUrl;
26005
26024
  setTimeout(async () => {
26006
26025
  try {
26007
26026
  const open = (await import("open")).default;
26008
- await open(sidecarUrl);
26027
+ await open(openUrl);
26009
26028
  } catch {
26010
26029
  }
26011
26030
  }, 3e3);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orionfold-relay",
3
- "version": "0.15.2",
3
+ "version": "0.15.3",
4
4
  "description": "Orionfold Relay — a local-first, multi-agent orchestration runtime and builder scaffold for AI-native work.",
5
5
  "keywords": [
6
6
  "ai",
@@ -83,3 +83,21 @@ export function buildNextLaunchArgs({
83
83
  export function buildSidecarUrl(port: number, host = SIDECAR_LOOPBACK_HOST): string {
84
84
  return `http://${host}:${port}`;
85
85
  }
86
+
87
+ /**
88
+ * True when `host` is NOT a loopback address — i.e. binding to it exposes the
89
+ * server beyond the local machine. Relay is local-first with light auth, so the
90
+ * CLI warns before binding to such a host (`--hostname 0.0.0.0`, a LAN IP, a
91
+ * hostname, etc.). This is an advisory gate, not access control, so it errs
92
+ * toward warning: anything not provably loopback returns true.
93
+ *
94
+ * Loopback = `localhost`, IPv6 `::1`, or any `127.0.0.0/8` address (Linux lets
95
+ * you bind e.g. `127.0.0.5`). `0.0.0.0` / `::` are INADDR_ANY ("all
96
+ * interfaces") — the most exposing choice — and are treated as non-loopback.
97
+ */
98
+ export function isNonLoopbackHost(host: string): boolean {
99
+ const h = host.trim().toLowerCase();
100
+ if (h === "localhost" || h === "::1") return false;
101
+ if (/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(h)) return false;
102
+ return true;
103
+ }