ai-fly 0.3.0-alpha.1 → 0.3.0-alpha.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/ai-fly.js CHANGED
@@ -9,7 +9,7 @@ const USAGE = `ai-fly — peer-to-peer HTTP/WebSocket bridge with AI-ready prese
9
9
 
10
10
  Daemon:
11
11
  ai-fly run the provider daemon (foreground; Ctrl+C stops)
12
- ai-fly daemon start [--detach] [--data <dir>] [--relay <url>]...
12
+ ai-fly daemon start [--detach] [--data <dir>] [--relay <url>]... [--proxy <url|env|none>]
13
13
  ai-fly daemon stop [--force] | info | restart [--detach] | log [--lines <n>]
14
14
  ai-fly serve alias of 'daemon start'
15
15
 
@@ -27,9 +27,10 @@ Provider:
27
27
  ai-fly presets [search] [--json] featured + models.dev long tail
28
28
 
29
29
  Consumer:
30
- ai-fly join <dweb1-token> [--data <dir>] admit this device (fabric layer)
31
- ai-fly import <aifly1-link> [--run] [--preview] bundle link: join + keyring
32
- ai-fly run [--data <dir>] [--strict-ports] run the local gateway
30
+ ai-fly join <dweb1-token> [--data <dir>] [--proxy …] admit this device (fabric layer)
31
+ ai-fly import <aifly1-link> [--run] [--preview] [--proxy …] bundle link: join + keyring
32
+ ai-fly run [--data <dir>] [--strict-ports] [--proxy …] [--detach] run the local gateway
33
+ ai-fly run stop|info|restart|log [--force] [--lines <n>] gateway lifecycle (mirrors daemon)
33
34
  ai-fly ports [--data <dir>] [<serviceId> --port <n>] view/override mapped ports
34
35
  ai-fly test [--data <dir>] [--service <name>] [--form …] [--content <text>]
35
36
  single AI request through the local gateway
@@ -60,8 +61,8 @@ async function dispatch(command, rest) {
60
61
  const lazy = (load) => {
61
62
  return (argv, ctx) => load().then((m) => m.run([...argv], ctx));
62
63
  };
63
- return match(command).with("serve", () => lazy(() => import("./serve-Dk8Id1ai.mjs"))(rest)).with("daemon", () => lazy(() => import("./daemon-Cw1uCKMA.mjs"))(rest)).with("presets", () => lazy(() => import("./presets-C73CAMZ6.mjs"))(rest)).with("secret", () => lazy(() => import("./secret-SA37VND5.mjs"))(rest)).with("settings", async () => (await import("./settings-DU0YqNDt.mjs")).runAsSettings(rest, {})).with("relay", async () => (await import("./settings-DU0YqNDt.mjs")).runAsRelay(rest, {})).with("test", () => lazy(() => import("./test-Bc0OKBAi.mjs"))(rest)).with("service", () => lazy(() => import("./service-B5uORhl3.mjs"))(rest)).with("group", () => lazy(() => import("./group-B96IKEDF.mjs"))(rest)).with("share", () => lazy(() => import("./share-D1eMLG2r.mjs"))(rest)).with("revoke", () => lazy(() => import("./revoke-uRcIM8BX.mjs"))(rest)).with("join", () => lazy(() => import("./join-BB0W6DDq.mjs"))(rest)).with("import", () => lazy(() => import("./import-DL3cw0Ec.mjs"))(rest)).with("run", () => lazy(() => import("./run-CcWiV8JC.mjs"))(rest)).with("ports", () => lazy(() => import("./ports-8QzyXRWz.mjs"))(rest)).with("forget", () => lazy(() => import("./forget-BM0J4Oji.mjs"))(rest)).with("key", () => {
64
- if (rest[0] === "add") return lazy(() => import("./key-uMhgWu1I.mjs"))(rest);
64
+ return match(command).with("serve", () => lazy(() => import("./serve-DSBlodTF.mjs"))(rest)).with("daemon", () => lazy(() => import("./daemon-ZWUSWAgM.mjs"))(rest)).with("presets", () => lazy(() => import("./presets-C73CAMZ6.mjs"))(rest)).with("secret", () => lazy(() => import("./secret-SA37VND5.mjs"))(rest)).with("settings", async () => (await import("./settings-DU0YqNDt.mjs")).runAsSettings(rest, {})).with("relay", async () => (await import("./settings-DU0YqNDt.mjs")).runAsRelay(rest, {})).with("test", () => lazy(() => import("./test-Bc0OKBAi.mjs"))(rest)).with("service", () => lazy(() => import("./service-B5uORhl3.mjs"))(rest)).with("group", () => lazy(() => import("./group-B96IKEDF.mjs"))(rest)).with("share", () => lazy(() => import("./share-Cug0944N.mjs"))(rest)).with("revoke", () => lazy(() => import("./revoke-CkpvK33Q.mjs"))(rest)).with("join", () => lazy(() => import("./join-DsKUAibH.mjs"))(rest)).with("import", () => lazy(() => import("./import-tilxdbTH.mjs"))(rest)).with("run", () => lazy(() => import("./run-bbDjqVLr.mjs"))(rest)).with("ports", () => lazy(() => import("./ports-rRppuBgo.mjs"))(rest)).with("forget", () => lazy(() => import("./forget-B17zGwj4.mjs"))(rest)).with("key", () => {
65
+ if (rest[0] === "add") return lazy(() => import("./key-CNufbB__.mjs"))(rest);
65
66
  return lazy(() => import("./key-BiEp995L.mjs"))(rest);
66
67
  }).with("status", async () => {
67
68
  const [scope, ...tail] = rest;
@@ -69,8 +70,8 @@ async function dispatch(command, rest) {
69
70
  const wantConsumer = scope === "consumer" || scope !== "provider" && consumersRootExists();
70
71
  const argv = scope === "provider" || scope === "consumer" ? tail : rest;
71
72
  let code = 0;
72
- if (wantProvider) code = Math.max(code, await lazy(() => import("./status-Eu_4Bc1O.mjs"))(argv));
73
- if (wantConsumer) code = Math.max(code, await lazy(() => import("./status-C24okZuH.mjs"))(argv));
73
+ if (wantProvider) code = Math.max(code, await lazy(() => import("./status-SkNsxGnk.mjs"))(argv));
74
+ if (wantConsumer) code = Math.max(code, await lazy(() => import("./status-B-j454u2.mjs"))(argv));
74
75
  if (!wantProvider && !wantConsumer) process.stdout.write("nothing to report: no provider storage and no imported consumers\n");
75
76
  return code;
76
77
  }).otherwise(() => {
@@ -1,5 +1,5 @@
1
1
  import { n as resolveRelayUrls, t as loadConfig } from "./config-BlZnFqx7.mjs";
2
- import { t as loadSdk } from "./sdk-DCHLGZRg.mjs";
2
+ import { n as loadSdk, t as resolveHttpProxy } from "./proxy-D7VMUVEg.mjs";
3
3
  import { t as loadSettings } from "./settings-C1Hb4zwd.mjs";
4
4
  import { homedir } from "node:os";
5
5
  //#region src/cli/commands/consumer/common.ts
@@ -17,15 +17,18 @@ function ctxHomedir(ctx) {
17
17
  * provider 在那个 relay 上,不拨它就永远会不了面):逐次解析为
18
18
  * flag > ring/链接内嵌 relay(opts.relayUrls,调用侧按 ring 传入)> env > file。
19
19
  * @param linkRelayUrls aifly1. 链接内嵌 relay(import 的 join 阶段用;空 = 缺席)
20
+ * @param proxyFlag --proxy 旗标值(url | 'env' | 'none';缺省回落 AIFLY_PROXY env)
20
21
  */
21
- async function createSdkFabricFactory(relayFlag, ctx = {}, linkRelayUrls) {
22
+ async function createSdkFabricFactory(relayFlag, ctx = {}, linkRelayUrls, proxyFlag) {
22
23
  const sdk = await loadSdk();
24
+ const httpProxy = resolveHttpProxy(proxyFlag);
23
25
  let relaySettings = null;
24
26
  try {
25
27
  relaySettings = loadSettings(ctxHomedir(ctx)).relayUrls;
26
28
  } catch {}
27
29
  const toOpts = (opts) => {
28
30
  const fabricOpts = { dataDir: opts.dataDir };
31
+ if (httpProxy !== void 0) fabricOpts.httpProxy = httpProxy;
29
32
  const link = opts.relayUrls ?? linkRelayUrls;
30
33
  const urls = resolveRelayUrls({
31
34
  ...relayFlag !== void 0 ? { flag: relayFlag } : {},
@@ -1,91 +1,13 @@
1
1
  import { n as UsageError, r as reportCliError, t as CliError } from "./errors-BGtxPkM7.mjs";
2
2
  import { n as parseArgv } from "./args-CSxXW9eD.mjs";
3
3
  import { r as settingsPath, t as loadSettings } from "./settings-C1Hb4zwd.mjs";
4
+ import { a as killHard, c as terminateGracefully, i as isAlive, l as writeLastStart, n as daemonDir, o as readLastStart, r as ensureDaemonDir, s as readPid, t as clearPid, u as writePid } from "./daemon-state-CYkiW3SA.mjs";
4
5
  import { r as openStore } from "./common-CqxqIg6D.mjs";
5
- import { existsSync, mkdirSync, openSync, readFileSync, writeFileSync } from "node:fs";
6
+ import { openSync, readFileSync } from "node:fs";
6
7
  import { homedir } from "node:os";
7
- import { isAbsolute, join, resolve } from "node:path";
8
- import { execFileSync, spawn } from "node:child_process";
8
+ import { isAbsolute, resolve } from "node:path";
9
+ import { spawn } from "node:child_process";
9
10
  import process from "node:process";
10
- //#region src/cli/daemon-state.ts
11
- function daemonDir(base = homedir()) {
12
- const root = join(base, ".aifly", "daemon");
13
- return {
14
- root,
15
- pidFile: join(root, "pid"),
16
- lastStartFile: join(root, "last-start.json"),
17
- logFile: join(root, "daemon.log")
18
- };
19
- }
20
- function ensureDaemonDir(base = homedir()) {
21
- const dir = daemonDir(base);
22
- mkdirSync(dir.root, { recursive: true });
23
- return dir;
24
- }
25
- function writePid(pid, base = homedir()) {
26
- const dir = ensureDaemonDir(base);
27
- writeFileSync(dir.pidFile, `${pid}\n`);
28
- }
29
- function readPid(base = homedir()) {
30
- try {
31
- const raw = readFileSync(daemonDir(base).pidFile, "utf8").trim();
32
- const pid = Number.parseInt(raw, 10);
33
- return Number.isInteger(pid) && pid > 0 ? pid : null;
34
- } catch {
35
- return null;
36
- }
37
- }
38
- function clearPid(base = homedir()) {
39
- const { pidFile } = daemonDir(base);
40
- if (existsSync(pidFile)) writeFileSync(pidFile, "");
41
- }
42
- function writeLastStart(last, base = homedir()) {
43
- const dir = ensureDaemonDir(base);
44
- writeFileSync(dir.lastStartFile, `${JSON.stringify(last, null, 2)}\n`);
45
- }
46
- function readLastStart(base = homedir()) {
47
- try {
48
- const raw = JSON.parse(readFileSync(daemonDir(base).lastStartFile, "utf8"));
49
- if (typeof raw.entry === "string" && Array.isArray(raw.args)) return {
50
- entry: raw.entry,
51
- args: raw.args,
52
- startedAt: Number(raw.startedAt) || Date.now()
53
- };
54
- return null;
55
- } catch {
56
- return null;
57
- }
58
- }
59
- /** 进程活性(ESRCH = 不存在)。 */
60
- function isAlive(pid) {
61
- try {
62
- process.kill(pid, 0);
63
- return true;
64
- } catch (error) {
65
- return error.code === "EPERM";
66
- }
67
- }
68
- /** 优雅终止:SIGTERM → 轮询 ≤timeoutMs → 仍未退返回 false(调用方决定硬杀)。 */
69
- async function terminateGracefully(pid, timeoutMs = 1e4) {
70
- process.kill(pid, "SIGTERM");
71
- const deadline = Date.now() + timeoutMs;
72
- while (Date.now() < deadline) {
73
- if (!isAlive(pid)) return true;
74
- await new Promise((resolve) => setTimeout(resolve, 200));
75
- }
76
- return false;
77
- }
78
- /** 硬杀:posix SIGKILL;win32 taskkill(无优雅信号语义,USAGE 明示)。 */
79
- function killHard(pid) {
80
- if (process.platform === "win32") execFileSync("taskkill", [
81
- "/PID",
82
- String(pid),
83
- "/F",
84
- "/T"
85
- ], { stdio: "ignore" });
86
- else process.kill(pid, "SIGKILL");
87
- }
88
- //#endregion
89
11
  //#region src/cli/commands/provider/daemon.ts
90
12
  const SPEC = {
91
13
  detach: { type: "boolean" },
@@ -97,14 +19,18 @@ const SPEC = {
97
19
  relay: { type: "multi" },
98
20
  alias: { type: "string" },
99
21
  "log-usage": { type: "boolean" },
22
+ proxy: { type: "string" },
100
23
  lines: { type: "string" }
101
24
  };
102
25
  const USAGE = `usage:
103
- ai-fly daemon start [--detach] [--data <dir>] [--relay <url>]...
26
+ ai-fly daemon start [--detach] [--data <dir>] [--relay <url>]... [--proxy <url|env|none>]
104
27
  ai-fly daemon stop [--force]
105
28
  ai-fly daemon info
106
- ai-fly daemon restart [--detach] [--data <dir>] [--relay <url>]...
107
- ai-fly daemon log [--lines <n>]`;
29
+ ai-fly daemon restart [--detach] [--data <dir>] [--relay <url>]... [--proxy <url|env|none>]
30
+ ai-fly daemon log [--lines <n>]
31
+
32
+ --proxy: relay 控制面 HTTP 代理(QUIC 数据面永不过代理);等价 env AIFLY_PROXY。
33
+ 'env' = 读进程环境变量(HTTP_PROXY/HTTPS_PROXY);'none' = 显式禁用。`;
108
34
  async function run(argv, ctx = {}) {
109
35
  const home = ctx.homedir ?? homedir();
110
36
  const sub = argv[0];
@@ -173,7 +99,7 @@ async function start(startArgv, home) {
173
99
  process.on("exit", () => {
174
100
  clearPid(home);
175
101
  });
176
- const { run: serveRun } = await import("./serve-Dk8Id1ai.mjs");
102
+ const { run: serveRun } = await import("./serve-DSBlodTF.mjs");
177
103
  return serveRun([...startArgv], { homedir: home });
178
104
  }
179
105
  /** 后台 pid(活性核验;陈旧 pidfile 就地清理返回 null)。 */
@@ -0,0 +1,85 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { execFileSync } from "node:child_process";
5
+ import process from "node:process";
6
+ //#region src/cli/daemon-state.ts
7
+ function daemonDir(base = homedir(), kind = "daemon") {
8
+ const root = join(base, ".aifly", kind);
9
+ return {
10
+ root,
11
+ pidFile: join(root, "pid"),
12
+ lastStartFile: join(root, "last-start.json"),
13
+ logFile: join(root, `${kind}.log`)
14
+ };
15
+ }
16
+ function ensureDaemonDir(base = homedir(), kind = "daemon") {
17
+ const dir = daemonDir(base, kind);
18
+ mkdirSync(dir.root, { recursive: true });
19
+ return dir;
20
+ }
21
+ function writePid(pid, base = homedir(), kind = "daemon") {
22
+ const dir = ensureDaemonDir(base, kind);
23
+ writeFileSync(dir.pidFile, `${pid}\n`);
24
+ }
25
+ function readPid(base = homedir(), kind = "daemon") {
26
+ try {
27
+ const raw = readFileSync(daemonDir(base, kind).pidFile, "utf8").trim();
28
+ const pid = Number.parseInt(raw, 10);
29
+ return Number.isInteger(pid) && pid > 0 ? pid : null;
30
+ } catch {
31
+ return null;
32
+ }
33
+ }
34
+ function clearPid(base = homedir(), kind = "daemon") {
35
+ const { pidFile } = daemonDir(base, kind);
36
+ if (existsSync(pidFile)) writeFileSync(pidFile, "");
37
+ }
38
+ function writeLastStart(last, base = homedir(), kind = "daemon") {
39
+ const dir = ensureDaemonDir(base, kind);
40
+ writeFileSync(dir.lastStartFile, `${JSON.stringify(last, null, 2)}\n`);
41
+ }
42
+ function readLastStart(base = homedir(), kind = "daemon") {
43
+ try {
44
+ const raw = JSON.parse(readFileSync(daemonDir(base, kind).lastStartFile, "utf8"));
45
+ if (typeof raw.entry === "string" && Array.isArray(raw.args)) return {
46
+ entry: raw.entry,
47
+ args: raw.args,
48
+ startedAt: Number(raw.startedAt) || Date.now()
49
+ };
50
+ return null;
51
+ } catch {
52
+ return null;
53
+ }
54
+ }
55
+ /** 进程活性(ESRCH = 不存在)。 */
56
+ function isAlive(pid) {
57
+ try {
58
+ process.kill(pid, 0);
59
+ return true;
60
+ } catch (error) {
61
+ return error.code === "EPERM";
62
+ }
63
+ }
64
+ /** 优雅终止:SIGTERM → 轮询 ≤timeoutMs → 仍未退返回 false(调用方决定硬杀)。 */
65
+ async function terminateGracefully(pid, timeoutMs = 1e4) {
66
+ process.kill(pid, "SIGTERM");
67
+ const deadline = Date.now() + timeoutMs;
68
+ while (Date.now() < deadline) {
69
+ if (!isAlive(pid)) return true;
70
+ await new Promise((resolve) => setTimeout(resolve, 200));
71
+ }
72
+ return false;
73
+ }
74
+ /** 硬杀:posix SIGKILL;win32 taskkill(无优雅信号语义,USAGE 明示)。 */
75
+ function killHard(pid) {
76
+ if (process.platform === "win32") execFileSync("taskkill", [
77
+ "/PID",
78
+ String(pid),
79
+ "/F",
80
+ "/T"
81
+ ], { stdio: "ignore" });
82
+ else process.kill(pid, "SIGKILL");
83
+ }
84
+ //#endregion
85
+ export { killHard as a, terminateGracefully as c, isAlive as i, writeLastStart as l, daemonDir as n, readLastStart as o, ensureDaemonDir as r, readPid as s, clearPid as t, writePid as u };
@@ -1,7 +1,7 @@
1
1
  import { n as UsageError } from "./errors-BGtxPkM7.mjs";
2
2
  import { n as parseArgv } from "./args-CSxXW9eD.mjs";
3
3
  import { d as removeKeyring, n as consumersRoot } from "./store-BiTS2FTl.mjs";
4
- import { n as ctxHomedir, r as ctxOut } from "./common-Ds1lf39d.mjs";
4
+ import { n as ctxHomedir, r as ctxOut } from "./common-CgxCXeTt.mjs";
5
5
  import { homedir } from "node:os";
6
6
  //#region src/cli/commands/consumer/forget.ts
7
7
  async function run(argv, ctx = {}) {
@@ -1,7 +1,7 @@
1
1
  import { n as UsageError } from "./errors-BGtxPkM7.mjs";
2
2
  import { n as parseArgv } from "./args-CSxXW9eD.mjs";
3
3
  import { n as consumersRoot, s as listKeyrings } from "./store-BiTS2FTl.mjs";
4
- import { a as ringsForRun, i as printListeners, n as ctxHomedir, o as waitForSignals, r as ctxOut, t as createSdkFabricFactory } from "./common-Ds1lf39d.mjs";
4
+ import { a as ringsForRun, i as printListeners, n as ctxHomedir, o as waitForSignals, r as ctxOut, t as createSdkFabricFactory } from "./common-CgxCXeTt.mjs";
5
5
  import { a as importLink, i as formatLinkPreview, n as decodeShareLink, r as formatKeyringSummary } from "./join-hyqiwEek.mjs";
6
6
  import { n as createFabricProviderTransport, t as startEngine } from "./runtime-D_nxUEjd.mjs";
7
7
  import { homedir } from "node:os";
@@ -15,7 +15,8 @@ async function run(argv, ctx = {}) {
15
15
  preview: { type: "boolean" },
16
16
  run: { type: "boolean" },
17
17
  "strict-ports": { type: "boolean" },
18
- relay: { type: "multi" }
18
+ relay: { type: "multi" },
19
+ proxy: { type: "string" }
19
20
  }, { homedir: ctx.homedir ?? homedir() });
20
21
  const link = positionals[0];
21
22
  if (link === void 0) throw new UsageError("error: import requires a share link argument\nusage: ai-fly import <aifly1-link> [--data <dir>] [--preview] [--run]");
@@ -31,7 +32,7 @@ async function run(argv, ctx = {}) {
31
32
  if (flagRelays !== void 0 && flagRelays.length > 0 && linkRelays.length > 0) {
32
33
  if (!(flagRelays.length === linkRelays.length && flagRelays.every((u) => linkRelays.includes(u)))) out("warning: --relay overrides the share link's relay entries; if the provider stays unreachable, drop the flag to use the link's entries");
33
34
  } else if (linkRelays.length > 0) out(`relay: using ${linkRelays.length} entry URL(s) from the share link (override with --relay)`);
34
- const factory = await createSdkFabricFactory(flagRelays, ctx, linkRelays);
35
+ const factory = await createSdkFabricFactory(flagRelays, ctx, linkRelays, options.proxy);
35
36
  const result = await importLink(link, {
36
37
  consumersRoot: root,
37
38
  fabric: factory
@@ -1,7 +1,7 @@
1
1
  import { n as UsageError } from "./errors-BGtxPkM7.mjs";
2
2
  import { n as parseArgv } from "./args-CSxXW9eD.mjs";
3
3
  import { n as consumersRoot } from "./store-BiTS2FTl.mjs";
4
- import { n as ctxHomedir, r as ctxOut, t as createSdkFabricFactory } from "./common-Ds1lf39d.mjs";
4
+ import { n as ctxHomedir, r as ctxOut, t as createSdkFabricFactory } from "./common-CgxCXeTt.mjs";
5
5
  import { o as joinDevice } from "./join-hyqiwEek.mjs";
6
6
  import { homedir } from "node:os";
7
7
  //#region src/cli/commands/consumer/join.ts
@@ -11,13 +11,14 @@ async function run(argv, ctx = {}) {
11
11
  type: "string",
12
12
  tilde: true
13
13
  },
14
- relay: { type: "multi" }
14
+ relay: { type: "multi" },
15
+ proxy: { type: "string" }
15
16
  }, { homedir: ctx.homedir ?? homedir() });
16
17
  const token = positionals[0];
17
18
  if (token === void 0) throw new UsageError("error: join requires an invite token argument\nusage: ai-fly join <dweb1-token> [--data <dir>]");
18
19
  const out = ctxOut(ctx);
19
20
  const root = consumersRoot(options.data, ctxHomedir(ctx));
20
- const factory = await createSdkFabricFactory(options.relay, ctx);
21
+ const factory = await createSdkFabricFactory(options.relay, ctx, void 0, options.proxy);
21
22
  const result = await joinDevice(token, root, { fabric: factory });
22
23
  if (result.alreadyJoined) {
23
24
  out(`already joined to provider '${result.ring.alias}' (${result.ring.endpointId})`);
@@ -1,7 +1,7 @@
1
1
  import { n as UsageError } from "./errors-BGtxPkM7.mjs";
2
2
  import { n as parseArgv } from "./args-CSxXW9eD.mjs";
3
3
  import { n as consumersRoot } from "./store-BiTS2FTl.mjs";
4
- import { n as ctxHomedir, r as ctxOut } from "./common-Ds1lf39d.mjs";
4
+ import { n as ctxHomedir, r as ctxOut } from "./common-CgxCXeTt.mjs";
5
5
  import { r as formatKeyringSummary, t as addKey } from "./join-hyqiwEek.mjs";
6
6
  import { homedir } from "node:os";
7
7
  //#region src/cli/commands/consumer/key.ts
@@ -1,7 +1,7 @@
1
1
  import { n as UsageError } from "./errors-BGtxPkM7.mjs";
2
2
  import { n as parseArgv } from "./args-CSxXW9eD.mjs";
3
3
  import { n as consumersRoot, p as setPort, s as listKeyrings } from "./store-BiTS2FTl.mjs";
4
- import { n as ctxHomedir, r as ctxOut } from "./common-Ds1lf39d.mjs";
4
+ import { n as ctxHomedir, r as ctxOut } from "./common-CgxCXeTt.mjs";
5
5
  import { i as validatePortArg, n as desiredPortFor } from "./ports-pI59MtmI.mjs";
6
6
  import { homedir } from "node:os";
7
7
  //#region src/cli/commands/consumer/ports.ts
@@ -0,0 +1,21 @@
1
+ import { n as UsageError } from "./errors-BGtxPkM7.mjs";
2
+ //#region src/sdk.ts
3
+ async function loadSdk() {
4
+ const candidate = await import("@jixo/opendweb-client-sdk");
5
+ if (typeof candidate.Fabric === "function") return candidate;
6
+ const def = candidate.default;
7
+ if (def !== void 0 && typeof def.Fabric === "function") return def;
8
+ throw new Error("error: @jixo/opendweb-client-sdk export shape unexpected (no Fabric via named or default interop)");
9
+ }
10
+ //#endregion
11
+ //#region src/cli/proxy.ts
12
+ function resolveHttpProxy(flag, env = process.env.AIFLY_PROXY) {
13
+ const spec = flag ?? env;
14
+ if (spec === void 0 || spec === "") return void 0;
15
+ if (spec === "none") return "none";
16
+ if (spec === "env") return "from-env";
17
+ if (!/^https?:\/\//i.test(spec)) throw new UsageError(`error: --proxy expects an http(s):// URL, 'env' or 'none' (got '${spec}')`);
18
+ return { url: spec };
19
+ }
20
+ //#endregion
21
+ export { loadSdk as n, resolveHttpProxy as t };
@@ -1,7 +1,8 @@
1
1
  import { n as UsageError, r as reportCliError } from "./errors-BGtxPkM7.mjs";
2
2
  import { n as parseArgv } from "./args-CSxXW9eD.mjs";
3
+ import { t as resolveHttpProxy } from "./proxy-D7VMUVEg.mjs";
3
4
  import { d as str, l as resolveDataDir, u as resolvedRelayUrls } from "./common-CqxqIg6D.mjs";
4
- import { t as openExistingFabric } from "./serve-DQ5ces99.mjs";
5
+ import { t as openExistingFabric } from "./serve-Be4zdKVj.mjs";
5
6
  import { homedir } from "node:os";
6
7
  //#region src/cli/commands/provider/revoke.ts
7
8
  const SPEC = {
@@ -20,7 +21,7 @@ async function run(argv, ctx = {}) {
20
21
  if (endpointId === void 0 || endpointId === "") throw new UsageError("error: revoke requires an <endpointId> argument");
21
22
  if (positionals.length > 1) throw new UsageError(`error: unexpected argument '${positionals[1]}'`);
22
23
  const dataDir = resolveDataDir(str(options.data), home);
23
- fabric = await openExistingFabric(dataDir, resolvedRelayUrls(options, home));
24
+ fabric = await openExistingFabric(dataDir, resolvedRelayUrls(options, home), resolveHttpProxy(void 0));
24
25
  await fabric.revoke(endpointId);
25
26
  process.stdout.write(`member revoked: ${endpointId}\n`);
26
27
  return 0;
@@ -0,0 +1,215 @@
1
+ import { n as UsageError, r as reportCliError, t as CliError } from "./errors-BGtxPkM7.mjs";
2
+ import { n as parseArgv } from "./args-CSxXW9eD.mjs";
3
+ import { n as consumersRoot, s as listKeyrings } from "./store-BiTS2FTl.mjs";
4
+ import { a as ringsForRun, i as printListeners, n as ctxHomedir, o as waitForSignals, r as ctxOut, t as createSdkFabricFactory } from "./common-CgxCXeTt.mjs";
5
+ import { n as createFabricProviderTransport, t as startEngine } from "./runtime-D_nxUEjd.mjs";
6
+ import { a as killHard, c as terminateGracefully, i as isAlive, l as writeLastStart, n as daemonDir, o as readLastStart, r as ensureDaemonDir, s as readPid, t as clearPid, u as writePid } from "./daemon-state-CYkiW3SA.mjs";
7
+ import { openSync, readFileSync } from "node:fs";
8
+ import { resolve } from "node:path";
9
+ import { spawn } from "node:child_process";
10
+ //#region src/cli/commands/consumer/run.ts
11
+ const KIND = "gateway";
12
+ const SPEC = {
13
+ detach: { type: "boolean" },
14
+ force: { type: "boolean" },
15
+ data: {
16
+ type: "string",
17
+ tilde: true
18
+ },
19
+ "strict-ports": { type: "boolean" },
20
+ relay: { type: "multi" },
21
+ proxy: { type: "string" },
22
+ lines: { type: "string" }
23
+ };
24
+ const USAGE = `usage:
25
+ ai-fly run [--data <dir>] [--strict-ports] [--relay <url>]... [--proxy <url|env|none>] [--detach]
26
+ ai-fly run stop [--force]
27
+ ai-fly run info
28
+ ai-fly run restart [--detach] [同 start 参数]
29
+ ai-fly run log [--lines <n>]`;
30
+ async function run(argv, ctx = {}) {
31
+ const home = ctxHomedir(ctx);
32
+ const sub = argv[0];
33
+ try {
34
+ switch (sub) {
35
+ case "stop": return await stop(argv.slice(1), home);
36
+ case "info": return info(argv.slice(1), home);
37
+ case "restart": return await restart(argv.slice(1), home, ctx);
38
+ case "log": return log(argv.slice(1), home);
39
+ default: return await start(argv, home, ctx);
40
+ }
41
+ } catch (err) {
42
+ return reportCliError(err);
43
+ }
44
+ }
45
+ /** last-start 记忆(args 含 "run" token,restart 原样回放前剥除)。 */
46
+ function lastStartOf(runArgv) {
47
+ if (process.argv[1] === void 0) throw new CliError("error: cannot resolve the CLI entry for gateway respawn");
48
+ return {
49
+ entry: resolve(process.argv[1]),
50
+ args: ["run", ...runArgv],
51
+ startedAt: Date.now()
52
+ };
53
+ }
54
+ async function start(runArgv, home, ctx) {
55
+ const { options, positionals } = parseArgv([...runArgv], SPEC, { homedir: home });
56
+ if (positionals.length > 0) throw new UsageError(`error: unexpected argument '${positionals[0]}' (known subcommands: stop, info, restart, log)\n${USAGE}`);
57
+ const running = currentPid(home);
58
+ if (running !== null && running !== process.pid) throw new CliError(`error: gateway already running (pid ${running}); try 'ai-fly run restart'`);
59
+ const out = ctxOut(ctx);
60
+ const root = consumersRoot(options.data, home);
61
+ const { rings, warnings } = listKeyrings(root);
62
+ for (const w of warnings) out(`warning: ${w}`);
63
+ const engineRings = ringsForRun(rings);
64
+ if (engineRings.length === 0) throw new CliError("error: no imported providers - run 'ai-fly import <aifly1-link>' or 'ai-fly join <token>' first");
65
+ if (options.detach === true) {
66
+ const dir = ensureDaemonDir(home, KIND);
67
+ const respawnArgs = ["run", ...runArgv.filter((a) => a !== "--detach")];
68
+ const logFd = openSync(dir.logFile, "a");
69
+ const child = spawn(process.execPath, [
70
+ ...process.execArgv,
71
+ process.argv[1],
72
+ ...respawnArgs
73
+ ], {
74
+ detached: true,
75
+ stdio: [
76
+ "ignore",
77
+ logFd,
78
+ logFd
79
+ ],
80
+ env: process.env,
81
+ cwd: process.cwd()
82
+ });
83
+ child.unref();
84
+ await new Promise((resolve) => setTimeout(resolve, 400));
85
+ if (child.exitCode !== null) throw new CliError(`error: gateway exited immediately - see ${dir.logFile}`);
86
+ writePid(child.pid, home, KIND);
87
+ writeLastStart(lastStartOf(respawnArgs.slice(1)), home, KIND);
88
+ process.stdout.write(`gateway started in background (pid ${child.pid}) - log: ${dir.logFile}\n`);
89
+ return 0;
90
+ }
91
+ writePid(process.pid, home, KIND);
92
+ writeLastStart(lastStartOf(runArgv), home, KIND);
93
+ process.on("exit", () => {
94
+ clearPid(home, KIND);
95
+ });
96
+ const factory = await createSdkFabricFactory(options.relay, ctx, void 0, options.proxy);
97
+ out(`gateway starting - booting fabric for ${engineRings.length} provider ring(s) (unreachable relays can stall this ~30s; Ctrl+C to abort)...`);
98
+ const engine = await startEngine({
99
+ rings: engineRings,
100
+ consumersRoot: root,
101
+ sessionFactoryFor: (ring) => createFabricProviderTransport(factory, {
102
+ dataDir: `${root}/${ring.endpointId.slice(0, 8)}/fabric`,
103
+ providerEndpointId: ring.endpointId,
104
+ ...ring.relayUrls.length > 0 ? { relayUrls: ring.relayUrls } : {}
105
+ }),
106
+ strictPorts: options["strict-ports"] === true,
107
+ onNotice: out
108
+ });
109
+ printListeners(out, engine.gateway.listenerInfo());
110
+ out("gateway running - press Ctrl-C to stop");
111
+ await waitForSignals();
112
+ await engine.stop();
113
+ out("gateway stopped");
114
+ return 0;
115
+ }
116
+ /** 后台 pid(活性核验;陈旧 pidfile 就地清理返回 null)。 */
117
+ function currentPid(home) {
118
+ const pid = readPid(home, KIND);
119
+ if (pid === null) return null;
120
+ if (!isAlive(pid)) {
121
+ clearPid(home, KIND);
122
+ return null;
123
+ }
124
+ return pid;
125
+ }
126
+ async function stop(stopArgv, home) {
127
+ const { options, positionals } = parseArgv([...stopArgv], SPEC, { homedir: home });
128
+ if (positionals.length > 0) throw new UsageError(`error: unexpected argument '${positionals[0]}'`);
129
+ const pid = currentPid(home);
130
+ if (pid === null) {
131
+ process.stdout.write("gateway is not running\n");
132
+ return 0;
133
+ }
134
+ if (process.platform === "win32") {
135
+ killHard(pid);
136
+ clearPid(home, KIND);
137
+ process.stdout.write(`gateway stopped (pid ${pid}, forced - windows has no cross-process graceful signal)\n`);
138
+ return 0;
139
+ }
140
+ const graceful = await terminateGracefully(pid);
141
+ if (!graceful && options.force !== true) throw new CliError(`error: gateway (pid ${pid}) did not exit in time - retry with --force`);
142
+ if (!graceful) killHard(pid);
143
+ clearPid(home, KIND);
144
+ process.stdout.write(`gateway stopped (pid ${pid}${graceful ? "" : ", forced"})\n`);
145
+ return 0;
146
+ }
147
+ function info(infoArgv, home) {
148
+ const { positionals } = parseArgv([...infoArgv], SPEC, { homedir: home });
149
+ if (positionals.length > 0) throw new UsageError(`error: unexpected argument '${positionals[0]}'`);
150
+ const pid = currentPid(home);
151
+ const last = readLastStart(home, KIND);
152
+ const out = (line) => {
153
+ process.stdout.write(`${line}\n`);
154
+ };
155
+ out(pid !== null ? `running : yes (pid ${pid})` : "running : no");
156
+ if (pid !== null && last !== null) {
157
+ const up = Math.max(0, Math.round((Date.now() - last.startedAt) / 1e3));
158
+ out(`uptime : ${Math.floor(up / 60)}m ${up % 60}s`);
159
+ }
160
+ if (last !== null) {
161
+ out(`entry : ${last.entry}`);
162
+ out(`arguments : ${last.args.join(" ")}`);
163
+ }
164
+ out(`state dir : ${daemonDir(home, KIND).root}`);
165
+ out(`log file : ${daemonDir(home, KIND).logFile}`);
166
+ const dataArg = last?.args.includes("--data") ? last.args[last.args.indexOf("--data") + 1] : void 0;
167
+ const root = consumersRoot(dataArg, home);
168
+ try {
169
+ const { rings } = listKeyrings(root);
170
+ const services = rings.reduce((n, r) => n + r.services.length, 0);
171
+ const keys = rings.reduce((n, r) => n + r.keys.length, 0);
172
+ out(`data dir : ${root}`);
173
+ out(`rings : ${rings.length} (services: ${services}, keys: ${keys})`);
174
+ } catch {
175
+ out(`data dir : ${root} (store not readable)`);
176
+ }
177
+ return 0;
178
+ }
179
+ async function restart(restartArgv, home, ctx) {
180
+ parseArgv([...restartArgv], SPEC, { homedir: home });
181
+ const pid = currentPid(home);
182
+ if (pid !== null) {
183
+ const graceful = process.platform === "win32" ? false : await terminateGracefully(pid);
184
+ if (!graceful) killHard(pid);
185
+ clearPid(home, KIND);
186
+ process.stdout.write(`gateway stopped (pid ${pid}${graceful ? "" : ", forced"})\n`);
187
+ } else process.stdout.write("gateway was not running\n");
188
+ if (restartArgv.some((a) => !a.startsWith("--detach"))) return await start(restartArgv, home, ctx);
189
+ const last = readLastStart(home, KIND);
190
+ const detachWanted = restartArgv.includes("--detach");
191
+ if (last === null) return await start(detachWanted ? ["--detach"] : [], home, ctx);
192
+ const replay = last.args.filter((a) => a !== "run" && a !== "--detach");
193
+ return await start(detachWanted ? [...replay, "--detach"] : replay, home, ctx);
194
+ }
195
+ function log(logArgv, home) {
196
+ const { options, positionals } = parseArgv([...logArgv], SPEC, { homedir: home });
197
+ if (positionals.length > 0) throw new UsageError(`error: unexpected argument '${positionals[0]}'`);
198
+ const lines = Math.max(1, Number.parseInt(String(options.lines ?? "50"), 10) || 50);
199
+ const { logFile } = daemonDir(home, KIND);
200
+ try {
201
+ const content = readFileSync(logFile, "utf8").trimEnd();
202
+ if (content === "") {
203
+ process.stdout.write("(gateway.log is empty)\n");
204
+ return 0;
205
+ }
206
+ const tail = content.split("\n").slice(-lines).join("\n");
207
+ process.stdout.write(`${tail}\n`);
208
+ return 0;
209
+ } catch {
210
+ process.stdout.write(`no gateway log yet (${logFile})\n`);
211
+ return 0;
212
+ }
213
+ }
214
+ //#endregion
215
+ export { run };
@@ -1,5 +1,5 @@
1
1
  import { c as RESP_META_HEADER_WHITELIST, i as FRAME_TYPE, s as REJECTED_CODE, t as ERROR_CODE } from "./frames-BDqvhB2Y.mjs";
2
- import { t as loadSdk } from "./sdk-DCHLGZRg.mjs";
2
+ import { n as loadSdk } from "./proxy-D7VMUVEg.mjs";
3
3
  import { i as ensurePrivateDir, r as atomicWriteFileSync, t as ProviderStore } from "./store-CrTUwskE.mjs";
4
4
  import { n as FabricWireAdapter, r as DEFAULT_BODY_CHUNK_BYTES, t as WireSession } from "./mux-CS1zhF4W.mjs";
5
5
  import { a as collectEnvVarNames, i as buildUpstreamRequest, n as RewriteError, r as SecretMissingError, s as buildServiceEntry, t as PathNotOfferedError } from "./rewrite-xZHWnyJk.mjs";
@@ -1097,12 +1097,13 @@ function concatBytes(parts) {
1097
1097
  function providerFabricDir(dataDir) {
1098
1098
  return join(dataDir, "fabric");
1099
1099
  }
1100
- function fabricOptions(dataDir, relayUrls) {
1100
+ function fabricOptions(dataDir, relayUrls, httpProxy) {
1101
1101
  const opts = { dataDir: providerFabricDir(dataDir) };
1102
1102
  if (relayUrls !== void 0 && relayUrls.length > 0) opts.relay = {
1103
1103
  mode: "custom",
1104
1104
  urls: [relayUrls[0], ...relayUrls.slice(1)]
1105
1105
  };
1106
+ if (httpProxy !== void 0) opts.httpProxy = httpProxy;
1106
1107
  return opts;
1107
1108
  }
1108
1109
  function dirHasEntries(path) {
@@ -1112,9 +1113,9 @@ function dirHasEntries(path) {
1112
1113
  * 打开(或首启创建 root)数据目录下的 Fabric。已存在 fabric 数据则 open 复入
1113
1114
  * (EndpointId/名册不变),否则 createRoot。
1114
1115
  */
1115
- async function openOrCreateFabric(dataDir, relayUrls) {
1116
+ async function openOrCreateFabric(dataDir, relayUrls, httpProxy) {
1116
1117
  const { Fabric } = await loadSdk();
1117
- const opts = fabricOptions(dataDir, relayUrls);
1118
+ const opts = fabricOptions(dataDir, relayUrls, httpProxy);
1118
1119
  if (dirHasEntries(providerFabricDir(dataDir))) try {
1119
1120
  return await Fabric.open(opts);
1120
1121
  } catch (err) {
@@ -1127,10 +1128,10 @@ async function openOrCreateFabric(dataDir, relayUrls) {
1127
1128
  }
1128
1129
  }
1129
1130
  /** 打开既有 fabric 身份(share/revoke/status 用;未初始化时抛错)。 */
1130
- async function openExistingFabric(dataDir, relayUrls) {
1131
+ async function openExistingFabric(dataDir, relayUrls, httpProxy) {
1131
1132
  if (!dirHasEntries(providerFabricDir(dataDir))) throw new Error(`error: no fabric identity under ${dataDir}; run 'ai-fly serve --data <dir>' first`);
1132
1133
  const { Fabric } = await loadSdk();
1133
- return Fabric.open(fabricOptions(dataDir, relayUrls));
1134
+ return Fabric.open(fabricOptions(dataDir, relayUrls, httpProxy));
1134
1135
  }
1135
1136
  /** 扫描空/未设置的 $env 变量(已声明但为空 -> WARNING 列表)。 */
1136
1137
  function findEmptyEnvRefs(services, env = process.env) {
@@ -1169,7 +1170,7 @@ async function startProviderDaemon(opts) {
1169
1170
  const limits = new LimitEnforcer({ dataDir: opts.dataDir });
1170
1171
  const secretsStore = SecretsStore.open(opts.dataDir);
1171
1172
  const secrets = opts.secrets ?? ((name) => secretsStore.resolve(name)?.headerValue);
1172
- const fabric = await openOrCreateFabric(opts.dataDir, opts.relayUrls);
1173
+ const fabric = await openOrCreateFabric(opts.dataDir, opts.relayUrls, opts.httpProxy);
1173
1174
  const engine = new ProviderEngine({
1174
1175
  fabric,
1175
1176
  store,
@@ -1,7 +1,8 @@
1
1
  import { n as UsageError, r as reportCliError } from "./errors-BGtxPkM7.mjs";
2
2
  import { n as parseArgv } from "./args-CSxXW9eD.mjs";
3
+ import { t as resolveHttpProxy } from "./proxy-D7VMUVEg.mjs";
3
4
  import { d as str, l as resolveDataDir, u as resolvedRelayUrls } from "./common-CqxqIg6D.mjs";
4
- import { n as startProviderDaemon } from "./serve-DQ5ces99.mjs";
5
+ import { n as startProviderDaemon } from "./serve-Be4zdKVj.mjs";
5
6
  import { homedir } from "node:os";
6
7
  //#region src/cli/commands/provider/serve.ts
7
8
  const SPEC = {
@@ -11,7 +12,8 @@ const SPEC = {
11
12
  },
12
13
  relay: { type: "multi" },
13
14
  alias: { type: "string" },
14
- "log-usage": { type: "boolean" }
15
+ "log-usage": { type: "boolean" },
16
+ proxy: { type: "string" }
15
17
  };
16
18
  async function run(argv, ctx = {}) {
17
19
  try {
@@ -19,12 +21,22 @@ async function run(argv, ctx = {}) {
19
21
  const { options, positionals } = parseArgv(argv, SPEC, { homedir: home });
20
22
  if (positionals.length > 0) throw new UsageError(`error: unexpected argument '${positionals[0]}' (serve takes no positional arguments)`);
21
23
  const dataDir = resolveDataDir(str(options.data), home);
22
- const relayUrls = resolvedRelayUrls(options, home);
24
+ const relayUrls = resolvedRelayUrls(options, home) ?? [];
25
+ const httpProxy = resolveHttpProxy(str(options.proxy));
26
+ process.stdout.write([
27
+ "ai-fly daemon starting",
28
+ ` relay: ${relayUrls.length > 0 ? relayUrls.join(", ") : "n0 public relays (default)"}`,
29
+ ` data : ${dataDir}`,
30
+ ...httpProxy !== void 0 ? [` proxy: ${httpProxy === "from-env" ? "env" : httpProxy === "none" ? "none" : httpProxy.url}`] : [],
31
+ "booting fabric (unreachable relays can stall this ~30s; Ctrl+C to abort)...",
32
+ ""
33
+ ].join("\n"));
23
34
  const daemon = await startProviderDaemon({
24
35
  dataDir,
25
36
  relayUrls,
26
37
  alias: str(options.alias),
27
- logUsage: options["log-usage"] === true
38
+ logUsage: options["log-usage"] === true,
39
+ ...httpProxy !== void 0 ? { httpProxy } : {}
28
40
  });
29
41
  process.stdout.write(`${daemon.banner}\n`);
30
42
  let stopping = false;
@@ -1,9 +1,10 @@
1
1
  import { r as reportCliError, t as CliError } from "./errors-BGtxPkM7.mjs";
2
2
  import { n as parseArgv, r as parseDurationMs, t as assertDurationRange } from "./args-CSxXW9eD.mjs";
3
3
  import { l as SERVICE_ENTRY_SCHEMA } from "./frames-BDqvhB2Y.mjs";
4
+ import { t as resolveHttpProxy } from "./proxy-D7VMUVEg.mjs";
4
5
  import { n as StoreError } from "./store-CrTUwskE.mjs";
5
6
  import { c as requireString, d as str, l as resolveDataDir, r as openStore, u as resolvedRelayUrls } from "./common-CqxqIg6D.mjs";
6
- import { t as openExistingFabric } from "./serve-DQ5ces99.mjs";
7
+ import { t as openExistingFabric } from "./serve-Be4zdKVj.mjs";
7
8
  import { s as buildServiceEntry } from "./rewrite-xZHWnyJk.mjs";
8
9
  import { homedir } from "node:os";
9
10
  import { z } from "zod";
@@ -88,7 +89,7 @@ async function run(argv, ctx = {}) {
88
89
  const store = openStore(dataDir);
89
90
  const resolvedRelay = resolvedRelayUrls(options, home);
90
91
  if (resolvedRelay === void 0) process.stdout.write("warning: no relay configured for this command (flag/env/config); the link will carry public default relays - if the provider daemon runs on a custom relay, pass a matching --relay\n");
91
- fabric = await openExistingFabric(dataDir, resolvedRelay);
92
+ fabric = await openExistingFabric(dataDir, resolvedRelay, resolveHttpProxy(void 0));
92
93
  const invite = await issueInvite(fabric, ttlMs, options["allow-relayless"] === true);
93
94
  const relayStatus = await fabric.relayStatus();
94
95
  const result = buildShareLink({
@@ -1,6 +1,6 @@
1
1
  import { n as parseArgv } from "./args-CSxXW9eD.mjs";
2
2
  import { n as consumersRoot, s as listKeyrings } from "./store-BiTS2FTl.mjs";
3
- import { a as ringsForRun, n as ctxHomedir, r as ctxOut, t as createSdkFabricFactory } from "./common-Ds1lf39d.mjs";
3
+ import { a as ringsForRun, n as ctxHomedir, r as ctxOut, t as createSdkFabricFactory } from "./common-CgxCXeTt.mjs";
4
4
  import { n as createFabricProviderTransport, t as startEngine } from "./runtime-D_nxUEjd.mjs";
5
5
  import { homedir } from "node:os";
6
6
  //#region src/cli/commands/consumer/status.ts
@@ -59,7 +59,8 @@ async function run(argv, ctx = {}) {
59
59
  tilde: true
60
60
  },
61
61
  verbose: { type: "boolean" },
62
- relay: { type: "multi" }
62
+ relay: { type: "multi" },
63
+ proxy: { type: "string" }
63
64
  }, { homedir: ctx.homedir ?? homedir() });
64
65
  const verbose = options.verbose === true || positionals.includes("-v");
65
66
  const out = ctxOut(ctx);
@@ -71,7 +72,7 @@ async function run(argv, ctx = {}) {
71
72
  for (const line of formatStatus([], verbose)) out(line);
72
73
  return 0;
73
74
  }
74
- const factory = await createSdkFabricFactory(options.relay, ctx);
75
+ const factory = await createSdkFabricFactory(options.relay, ctx, void 0, options.proxy);
75
76
  const engine = await startEngine({
76
77
  rings: engineRings,
77
78
  consumersRoot: root,
@@ -1,7 +1,8 @@
1
1
  import { r as reportCliError } from "./errors-BGtxPkM7.mjs";
2
2
  import { n as parseArgv } from "./args-CSxXW9eD.mjs";
3
+ import { t as resolveHttpProxy } from "./proxy-D7VMUVEg.mjs";
3
4
  import { d as str, l as resolveDataDir, r as openStore, u as resolvedRelayUrls } from "./common-CqxqIg6D.mjs";
4
- import { t as openExistingFabric } from "./serve-DQ5ces99.mjs";
5
+ import { t as openExistingFabric } from "./serve-Be4zdKVj.mjs";
5
6
  import { c as detailDisplayLines, o as buildServiceDetail } from "./rewrite-xZHWnyJk.mjs";
6
7
  import { homedir } from "node:os";
7
8
  //#region src/cli/commands/provider/status.ts
@@ -35,7 +36,7 @@ async function run(argv, ctx = {}) {
35
36
  for (const line of detailDisplayLines(buildServiceDetail(s))) lines.push(` ${line}`);
36
37
  }
37
38
  try {
38
- fabric = await openExistingFabric(dataDir, resolvedRelayUrls(options, home));
39
+ fabric = await openExistingFabric(dataDir, resolvedRelayUrls(options, home), resolveHttpProxy(void 0));
39
40
  const fabricIdHex = await fabric.fabricIdHex();
40
41
  const members = await fabric.members();
41
42
  const relay = await fabric.relayStatus();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-fly",
3
- "version": "0.3.0-alpha.1",
3
+ "version": "0.3.0-alpha.3",
4
4
  "description": "ai-fly — peer-to-peer HTTP/WebSocket bridge with AI-ready presets, over OpenDWeb fabric",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "type": "module",
@@ -1,43 +0,0 @@
1
- import { t as CliError } from "./errors-BGtxPkM7.mjs";
2
- import { n as parseArgv } from "./args-CSxXW9eD.mjs";
3
- import { n as consumersRoot, s as listKeyrings } from "./store-BiTS2FTl.mjs";
4
- import { a as ringsForRun, i as printListeners, n as ctxHomedir, o as waitForSignals, r as ctxOut, t as createSdkFabricFactory } from "./common-Ds1lf39d.mjs";
5
- import { n as createFabricProviderTransport, t as startEngine } from "./runtime-D_nxUEjd.mjs";
6
- import { homedir } from "node:os";
7
- //#region src/cli/commands/consumer/run.ts
8
- async function run(argv, ctx = {}) {
9
- const { options } = parseArgv(argv, {
10
- data: {
11
- type: "string",
12
- tilde: true
13
- },
14
- "strict-ports": { type: "boolean" },
15
- relay: { type: "multi" }
16
- }, { homedir: ctx.homedir ?? homedir() });
17
- const out = ctxOut(ctx);
18
- const root = consumersRoot(options.data, ctxHomedir(ctx));
19
- const { rings, warnings } = listKeyrings(root);
20
- for (const w of warnings) out(`warning: ${w}`);
21
- const engineRings = ringsForRun(rings);
22
- if (engineRings.length === 0) throw new CliError("error: no imported providers - run 'ai-fly import <aifly1-link>' or 'ai-fly join <token>' first");
23
- const factory = await createSdkFabricFactory(options.relay, ctx);
24
- const engine = await startEngine({
25
- rings: engineRings,
26
- consumersRoot: root,
27
- sessionFactoryFor: (ring) => createFabricProviderTransport(factory, {
28
- dataDir: `${root}/${ring.endpointId.slice(0, 8)}/fabric`,
29
- providerEndpointId: ring.endpointId,
30
- ...ring.relayUrls.length > 0 ? { relayUrls: ring.relayUrls } : {}
31
- }),
32
- strictPorts: options["strict-ports"] === true,
33
- onNotice: out
34
- });
35
- printListeners(out, engine.gateway.listenerInfo());
36
- out("gateway running - press Ctrl-C to stop");
37
- await waitForSignals();
38
- await engine.stop();
39
- out("gateway stopped");
40
- return 0;
41
- }
42
- //#endregion
43
- export { run };
@@ -1,10 +0,0 @@
1
- //#region src/sdk.ts
2
- async function loadSdk() {
3
- const candidate = await import("@jixo/opendweb-client-sdk");
4
- if (typeof candidate.Fabric === "function") return candidate;
5
- const def = candidate.default;
6
- if (def !== void 0 && typeof def.Fabric === "function") return def;
7
- throw new Error("error: @jixo/opendweb-client-sdk export shape unexpected (no Fabric via named or default interop)");
8
- }
9
- //#endregion
10
- export { loadSdk as t };