aigetwey 1.0.1

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 (216) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/LICENSE +21 -0
  3. package/README.md +302 -0
  4. package/assets/logo.svg +8 -0
  5. package/assets/screenshot.png +0 -0
  6. package/assets/wordmark.svg +9 -0
  7. package/config.example.yaml +56 -0
  8. package/dashboard/.env.example +12 -0
  9. package/dashboard/next-env.d.ts +6 -0
  10. package/dashboard/next.config.ts +12 -0
  11. package/dashboard/package-lock.json +1771 -0
  12. package/dashboard/package.json +29 -0
  13. package/dashboard/postcss.config.mjs +5 -0
  14. package/dashboard/src/app/(console)/combos/page.tsx +10 -0
  15. package/dashboard/src/app/(console)/config/page.tsx +5 -0
  16. package/dashboard/src/app/(console)/console/page.tsx +92 -0
  17. package/dashboard/src/app/(console)/endpoint/page.tsx +5 -0
  18. package/dashboard/src/app/(console)/layout.tsx +17 -0
  19. package/dashboard/src/app/(console)/page.tsx +8 -0
  20. package/dashboard/src/app/(console)/providers/[id]/page.tsx +6 -0
  21. package/dashboard/src/app/(console)/providers/page.tsx +5 -0
  22. package/dashboard/src/app/(console)/quota/page.tsx +5 -0
  23. package/dashboard/src/app/(console)/tools/[id]/page.tsx +6 -0
  24. package/dashboard/src/app/(console)/tools/page.tsx +5 -0
  25. package/dashboard/src/app/(console)/usage/page.tsx +24 -0
  26. package/dashboard/src/app/api/cli-detect/[tool]/route.ts +253 -0
  27. package/dashboard/src/app/api/gw/[...path]/route.ts +89 -0
  28. package/dashboard/src/app/api/login/route.ts +30 -0
  29. package/dashboard/src/app/api/logout/route.ts +9 -0
  30. package/dashboard/src/app/api/password/route.ts +34 -0
  31. package/dashboard/src/app/globals.css +340 -0
  32. package/dashboard/src/app/icon.svg +8 -0
  33. package/dashboard/src/app/layout.tsx +28 -0
  34. package/dashboard/src/app/login/page.tsx +60 -0
  35. package/dashboard/src/components/AreaChart.tsx +115 -0
  36. package/dashboard/src/components/Badge.tsx +32 -0
  37. package/dashboard/src/components/Button.tsx +60 -0
  38. package/dashboard/src/components/CapacityBadges.tsx +40 -0
  39. package/dashboard/src/components/Checkbox.tsx +40 -0
  40. package/dashboard/src/components/CliToolConfig.tsx +63 -0
  41. package/dashboard/src/components/ConfigEditor.tsx +199 -0
  42. package/dashboard/src/components/ConfirmModal.tsx +36 -0
  43. package/dashboard/src/components/CooldownTimer.tsx +42 -0
  44. package/dashboard/src/components/EndpointView.tsx +439 -0
  45. package/dashboard/src/components/Icon.tsx +25 -0
  46. package/dashboard/src/components/KeyReveal.tsx +78 -0
  47. package/dashboard/src/components/Lamp.tsx +8 -0
  48. package/dashboard/src/components/LogTable.tsx +223 -0
  49. package/dashboard/src/components/LogoutButton.tsx +20 -0
  50. package/dashboard/src/components/ModelPicker.tsx +121 -0
  51. package/dashboard/src/components/ModelSelectModal.tsx +126 -0
  52. package/dashboard/src/components/PasswordEditor.tsx +86 -0
  53. package/dashboard/src/components/PricingEditor.tsx +171 -0
  54. package/dashboard/src/components/ProviderDetail.tsx +566 -0
  55. package/dashboard/src/components/ProviderManager.tsx +311 -0
  56. package/dashboard/src/components/QuotaView.tsx +78 -0
  57. package/dashboard/src/components/Rail.tsx +82 -0
  58. package/dashboard/src/components/RichCard.tsx +46 -0
  59. package/dashboard/src/components/RoutingView.tsx +329 -0
  60. package/dashboard/src/components/ThemeProvider.tsx +36 -0
  61. package/dashboard/src/components/ToastProvider.tsx +58 -0
  62. package/dashboard/src/components/ToolDetail.tsx +475 -0
  63. package/dashboard/src/components/TopBar.tsx +128 -0
  64. package/dashboard/src/components/UsageView.tsx +151 -0
  65. package/dashboard/src/components/ui.tsx +54 -0
  66. package/dashboard/src/lib/capabilities.ts +318 -0
  67. package/dashboard/src/lib/cliTools.ts +120 -0
  68. package/dashboard/src/lib/client.ts +190 -0
  69. package/dashboard/src/lib/gateway.ts +269 -0
  70. package/dashboard/src/lib/session.ts +71 -0
  71. package/dashboard/src/middleware.ts +37 -0
  72. package/dashboard/tsconfig.json +21 -0
  73. package/dist/adapters/anthropic.js +289 -0
  74. package/dist/adapters/anthropic.js.map +1 -0
  75. package/dist/adapters/gemini.js +268 -0
  76. package/dist/adapters/gemini.js.map +1 -0
  77. package/dist/adapters/index.js +8 -0
  78. package/dist/adapters/index.js.map +1 -0
  79. package/dist/adapters/openai.js +13 -0
  80. package/dist/adapters/openai.js.map +1 -0
  81. package/dist/cli/tray/autostart.js +152 -0
  82. package/dist/cli/tray/autostart.js.map +1 -0
  83. package/dist/cli/tray/icon.js +4 -0
  84. package/dist/cli/tray/icon.js.map +1 -0
  85. package/dist/cli/tray/tray.js +141 -0
  86. package/dist/cli/tray/tray.js.map +1 -0
  87. package/dist/cli/tray/trayRuntime.js +91 -0
  88. package/dist/cli/tray/trayRuntime.js.map +1 -0
  89. package/dist/cli.js +361 -0
  90. package/dist/cli.js.map +1 -0
  91. package/dist/config.js +728 -0
  92. package/dist/config.js.map +1 -0
  93. package/dist/core/authStore.js +78 -0
  94. package/dist/core/authStore.js.map +1 -0
  95. package/dist/core/canonical.js +9 -0
  96. package/dist/core/canonical.js.map +1 -0
  97. package/dist/core/console-buffer.js +25 -0
  98. package/dist/core/console-buffer.js.map +1 -0
  99. package/dist/core/fallback.js +62 -0
  100. package/dist/core/fallback.js.map +1 -0
  101. package/dist/core/handler.js +174 -0
  102. package/dist/core/handler.js.map +1 -0
  103. package/dist/core/keypool.js +105 -0
  104. package/dist/core/keypool.js.map +1 -0
  105. package/dist/core/quota.js +165 -0
  106. package/dist/core/quota.js.map +1 -0
  107. package/dist/core/state.js +52 -0
  108. package/dist/core/state.js.map +1 -0
  109. package/dist/db.js +193 -0
  110. package/dist/db.js.map +1 -0
  111. package/dist/headroom/compress.js +44 -0
  112. package/dist/headroom/compress.js.map +1 -0
  113. package/dist/headroom/detect.js +108 -0
  114. package/dist/headroom/detect.js.map +1 -0
  115. package/dist/headroom/process.js +158 -0
  116. package/dist/headroom/process.js.map +1 -0
  117. package/dist/inject/caveman.js +30 -0
  118. package/dist/inject/caveman.js.map +1 -0
  119. package/dist/inject/index.js +24 -0
  120. package/dist/inject/index.js.map +1 -0
  121. package/dist/inject/ponytail.js +19 -0
  122. package/dist/inject/ponytail.js.map +1 -0
  123. package/dist/middleware/auth.js +66 -0
  124. package/dist/middleware/auth.js.map +1 -0
  125. package/dist/providers/capabilities.js +246 -0
  126. package/dist/providers/capabilities.js.map +1 -0
  127. package/dist/providers/free.js +43 -0
  128. package/dist/providers/free.js.map +1 -0
  129. package/dist/providers/pricing.js +224 -0
  130. package/dist/providers/pricing.js.map +1 -0
  131. package/dist/providers/vertex.js +97 -0
  132. package/dist/providers/vertex.js.map +1 -0
  133. package/dist/routes/admin.js +622 -0
  134. package/dist/routes/admin.js.map +1 -0
  135. package/dist/routes/health.js +4 -0
  136. package/dist/routes/health.js.map +1 -0
  137. package/dist/routes/index.js +12 -0
  138. package/dist/routes/index.js.map +1 -0
  139. package/dist/routes/v1.js +75 -0
  140. package/dist/routes/v1.js.map +1 -0
  141. package/dist/rtk/detect.js +50 -0
  142. package/dist/rtk/detect.js.map +1 -0
  143. package/dist/rtk/filters.js +85 -0
  144. package/dist/rtk/filters.js.map +1 -0
  145. package/dist/rtk/index.js +39 -0
  146. package/dist/rtk/index.js.map +1 -0
  147. package/dist/server.js +100 -0
  148. package/dist/server.js.map +1 -0
  149. package/dist/stream/anthropic-stream.js +239 -0
  150. package/dist/stream/anthropic-stream.js.map +1 -0
  151. package/dist/stream/chunk.js +7 -0
  152. package/dist/stream/chunk.js.map +1 -0
  153. package/dist/stream/gemini-stream.js +135 -0
  154. package/dist/stream/gemini-stream.js.map +1 -0
  155. package/dist/stream/index.js +12 -0
  156. package/dist/stream/index.js.map +1 -0
  157. package/dist/stream/openai-stream.js +34 -0
  158. package/dist/stream/openai-stream.js.map +1 -0
  159. package/dist/stream/sse.js +64 -0
  160. package/dist/stream/sse.js.map +1 -0
  161. package/dist/translator/thinking.js +70 -0
  162. package/dist/translator/thinking.js.map +1 -0
  163. package/dist/translator/thinkingUnified.js +322 -0
  164. package/dist/translator/thinkingUnified.js.map +1 -0
  165. package/dist/upstream/client.js +120 -0
  166. package/dist/upstream/client.js.map +1 -0
  167. package/package.json +76 -0
  168. package/run.sh +27 -0
  169. package/src/adapters/anthropic.ts +377 -0
  170. package/src/adapters/gemini.ts +341 -0
  171. package/src/adapters/index.ts +17 -0
  172. package/src/adapters/openai.ts +22 -0
  173. package/src/cli/tray/autostart.ts +133 -0
  174. package/src/cli/tray/icon.ts +4 -0
  175. package/src/cli/tray/tray.ts +156 -0
  176. package/src/cli/tray/trayRuntime.ts +90 -0
  177. package/src/cli.ts +379 -0
  178. package/src/config.ts +777 -0
  179. package/src/core/authStore.ts +86 -0
  180. package/src/core/canonical.ts +93 -0
  181. package/src/core/console-buffer.ts +39 -0
  182. package/src/core/fallback.ts +116 -0
  183. package/src/core/handler.ts +236 -0
  184. package/src/core/keypool.ts +152 -0
  185. package/src/core/quota.ts +214 -0
  186. package/src/core/state.ts +65 -0
  187. package/src/db.ts +280 -0
  188. package/src/headroom/compress.ts +78 -0
  189. package/src/headroom/detect.ts +119 -0
  190. package/src/headroom/process.ts +166 -0
  191. package/src/inject/caveman.ts +35 -0
  192. package/src/inject/index.ts +46 -0
  193. package/src/inject/ponytail.ts +31 -0
  194. package/src/middleware/auth.ts +76 -0
  195. package/src/providers/capabilities.ts +297 -0
  196. package/src/providers/free.ts +53 -0
  197. package/src/providers/pricing.ts +261 -0
  198. package/src/providers/vertex.ts +117 -0
  199. package/src/routes/admin.ts +716 -0
  200. package/src/routes/health.ts +5 -0
  201. package/src/routes/index.ts +24 -0
  202. package/src/routes/v1.ts +87 -0
  203. package/src/rtk/detect.ts +55 -0
  204. package/src/rtk/filters.ts +94 -0
  205. package/src/rtk/index.ts +58 -0
  206. package/src/server.ts +108 -0
  207. package/src/stream/anthropic-stream.ts +310 -0
  208. package/src/stream/chunk.ts +46 -0
  209. package/src/stream/gemini-stream.ts +158 -0
  210. package/src/stream/index.ts +23 -0
  211. package/src/stream/openai-stream.ts +41 -0
  212. package/src/stream/sse.ts +72 -0
  213. package/src/translator/thinking.ts +64 -0
  214. package/src/translator/thinkingUnified.ts +319 -0
  215. package/src/upstream/client.ts +155 -0
  216. package/tsconfig.json +20 -0
package/dist/cli.js ADDED
@@ -0,0 +1,361 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `aigetwey` launcher — one command brings up the whole stack:
4
+ * - the gateway (Fastify) on its configured port (default 18080)
5
+ * - the dashboard (Next.js) on port 3000, pointed at the gateway
6
+ *
7
+ * Both run as child processes in THIS terminal (stdio inherited), so Ctrl-C
8
+ * tears down both cleanly — no orphaned background servers. An admin password
9
+ * and session secret are generated if not already in the environment, and the
10
+ * browser is opened once the gateway answers.
11
+ *
12
+ * Prefers a production build when present (dist/server.js, dashboard/.next),
13
+ * otherwise falls back to the tsx / Next dev flow for live reload.
14
+ */
15
+ import { spawn, execSync } from "node:child_process";
16
+ import { randomBytes } from "node:crypto";
17
+ import { existsSync, copyFileSync } from "node:fs";
18
+ import { resolve, dirname, join } from "node:path";
19
+ import { fileURLToPath } from "node:url";
20
+ import { createInterface } from "node:readline";
21
+ import { ensureTrayRuntime } from "./cli/tray/trayRuntime.js";
22
+ import { initTray, killTray } from "./cli/tray/tray.js";
23
+ import { enableAutoStart } from "./cli/tray/autostart.js";
24
+ const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
25
+ const dashboardDir = join(root, "dashboard");
26
+ function parseArgs(argv) {
27
+ const o = { noBrowser: false, yes: false, help: false, tray: false };
28
+ for (let i = 0; i < argv.length; i++) {
29
+ const a = argv[i];
30
+ if (a === "-p" || a === "--port")
31
+ o.port = Number(argv[++i]);
32
+ else if (a === "-n" || a === "--no-browser")
33
+ o.noBrowser = true;
34
+ else if (a === "-y" || a === "--yes")
35
+ o.yes = true;
36
+ else if (a === "-t" || a === "--tray")
37
+ o.tray = true;
38
+ else if (a === "-h" || a === "--help")
39
+ o.help = true;
40
+ }
41
+ return o;
42
+ }
43
+ const opts = parseArgs(process.argv.slice(2));
44
+ const HELP = `
45
+ aigetwey — personal AI gateway + dashboard
46
+
47
+ Usage: aigetwey [options]
48
+
49
+ Options:
50
+ -p, --port <n> port for the gateway + dashboard, one URL (default 18080)
51
+ -n, --no-browser start without opening the browser (terminal logs only)
52
+ -y, --yes skip the interactive menu (just run; honors --no-browser)
53
+ -t, --tray run in the system tray (background, no terminal needed)
54
+ -h, --help show this help
55
+
56
+ With a TTY and no --yes, a menu lets you pick: Web UI / Terminal / Hide to Tray / Exit.
57
+ `;
58
+ const GATEWAY_PORT = opts.port ?? Number(process.env.AIGETWEY_PORT ?? 18080);
59
+ const DASHBOARD_PORT = Number(process.env.DASHBOARD_PORT ?? 3000);
60
+ // reuse env secrets if present, otherwise generate (admin) / random (session).
61
+ const adminPassword = process.env.AIGETWEY_ADMIN_PASSWORD ?? randomBytes(6).toString("hex");
62
+ const sessionSecret = process.env.SESSION_SECRET ?? randomBytes(24).toString("hex");
63
+ const generatedPw = !process.env.AIGETWEY_ADMIN_PASSWORD;
64
+ function openBrowser(url) {
65
+ const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
66
+ spawn(cmd, [url], { stdio: "ignore", detached: true, shell: process.platform === "win32" }).unref();
67
+ }
68
+ async function waitForGateway(url, timeoutMs = 20000) {
69
+ const deadline = Date.now() + timeoutMs;
70
+ while (Date.now() < deadline) {
71
+ try {
72
+ const res = await fetch(url, { method: "GET" });
73
+ // any HTTP answer (even 401/503) means the port is up
74
+ if (res.status > 0)
75
+ return true;
76
+ }
77
+ catch {
78
+ // not up yet
79
+ }
80
+ await new Promise((r) => setTimeout(r, 400));
81
+ }
82
+ return false;
83
+ }
84
+ const children = [];
85
+ /**
86
+ * Kill a child AND its descendants. npm/npx spawn grandchildren (next-server,
87
+ * tsx→node); signalling only the direct child leaves those orphaned, holding
88
+ * their ports and breaking the next run. Children are spawned detached (own
89
+ * process group), so a negative-pid signal reaches the whole group.
90
+ */
91
+ function killTree(c, sig = "SIGTERM") {
92
+ if (!c.pid || c.killed)
93
+ return;
94
+ try {
95
+ process.kill(-c.pid, sig);
96
+ }
97
+ catch {
98
+ try {
99
+ c.kill(sig);
100
+ }
101
+ catch {
102
+ // already gone
103
+ }
104
+ }
105
+ }
106
+ function shutdown() {
107
+ void killTray();
108
+ for (const c of children)
109
+ killTree(c);
110
+ }
111
+ /** The pid listening on a TCP port, or null. Best-effort, POSIX-only. */
112
+ function pidOnPort(port) {
113
+ for (const probe of [
114
+ `ss -ltnHp 'sport = :${port}' 2>/dev/null`,
115
+ `lsof -ti tcp:${port} -sTCP:LISTEN 2>/dev/null`,
116
+ ]) {
117
+ try {
118
+ const out = execSync(probe, { encoding: "utf8" });
119
+ const m = out.match(/pid=(\d+)/) ?? out.match(/^\s*(\d+)\s*$/m);
120
+ if (m)
121
+ return Number(m[1]);
122
+ }
123
+ catch {
124
+ // tool absent or nothing listening — try the next probe
125
+ }
126
+ }
127
+ return null;
128
+ }
129
+ /**
130
+ * Make sure `port` is free before we bind it. A leftover dev server (next/node/
131
+ * tsx) from a previous run that died ungracefully is reaped automatically — the
132
+ * zero-config promise is "just run", not "go hunt a stray pid". A port held by
133
+ * something unrelated is left alone and surfaced as a clear error.
134
+ */
135
+ async function ensurePortFree(port, envVar) {
136
+ if (process.platform === "win32")
137
+ return;
138
+ const pid = pidOnPort(port);
139
+ if (!pid)
140
+ return;
141
+ let cmd = "";
142
+ try {
143
+ cmd = execSync(`ps -p ${pid} -o command= 2>/dev/null`, { encoding: "utf8" });
144
+ }
145
+ catch {
146
+ // ps failed — fall through to the unknown-owner branch
147
+ }
148
+ if (!/next|node|tsx|aigetwey/.test(cmd)) {
149
+ console.error(` port ${port} is in use by another process (pid ${pid}). free it or set ${envVar}.`);
150
+ process.exit(1);
151
+ }
152
+ console.log(` port ${port} held by a stale dev server (pid ${pid}) — reaping it.`);
153
+ try {
154
+ process.kill(pid, "SIGTERM");
155
+ }
156
+ catch {
157
+ // already exiting
158
+ }
159
+ const deadline = Date.now() + 3000;
160
+ while (Date.now() < deadline && pidOnPort(port)) {
161
+ await new Promise((r) => setTimeout(r, 150));
162
+ }
163
+ if (pidOnPort(port)) {
164
+ try {
165
+ process.kill(pid, "SIGKILL");
166
+ }
167
+ catch {
168
+ // gone between checks
169
+ }
170
+ }
171
+ }
172
+ process.on("SIGINT", () => {
173
+ shutdown();
174
+ process.exit(0);
175
+ });
176
+ process.on("SIGTERM", () => {
177
+ shutdown();
178
+ process.exit(0);
179
+ });
180
+ function spawnGateway() {
181
+ const built = existsSync(join(root, "dist", "server.js"));
182
+ const [cmd, args] = built ? ["node", ["dist/server.js"]] : ["npx", ["tsx", "src/server.ts"]];
183
+ return spawn(cmd, args, {
184
+ cwd: root,
185
+ stdio: "inherit",
186
+ detached: true, // own process group → killTree reaps tsx→node grandchildren
187
+ env: {
188
+ ...process.env,
189
+ AIGETWEY_ADMIN_PASSWORD: adminPassword,
190
+ AIGETWEY_PORT: String(GATEWAY_PORT),
191
+ // single-URL mode: the gateway reverse-proxies the dashboard, so the whole
192
+ // app lives on the gateway port.
193
+ AIGETWEY_DASHBOARD_PORT: String(DASHBOARD_PORT),
194
+ },
195
+ });
196
+ }
197
+ function spawnDashboard() {
198
+ // serve the optimized build when present, else dev mode (HMR live-reload).
199
+ const prod = existsSync(join(dashboardDir, ".next", "BUILD_ID"));
200
+ const args = prod ? ["run", "start"] : ["run", "dev"];
201
+ return spawn("npm", args, {
202
+ cwd: dashboardDir,
203
+ stdio: "inherit",
204
+ detached: true, // own process group → killTree reaps the next-server grandchild
205
+ env: {
206
+ ...process.env,
207
+ PORT: String(DASHBOARD_PORT),
208
+ GATEWAY_URL: `http://127.0.0.1:${GATEWAY_PORT}`,
209
+ ADMIN_PASSWORD: adminPassword,
210
+ SESSION_SECRET: sessionSecret,
211
+ },
212
+ });
213
+ }
214
+ /**
215
+ * One-time bootstrap so a fresh `npm i -g aigetwey` runs with a single command.
216
+ * Seeds a working config from the example, installs the dashboard's own deps
217
+ * (npm doesn't install nested package node_modules for us), and builds the
218
+ * dashboard if the published .next is absent. Each step is skipped once done, so
219
+ * normal runs pay nothing.
220
+ */
221
+ function ensureSetup() {
222
+ if (!existsSync(join(root, "config.yaml")) && existsSync(join(root, "config.example.yaml"))) {
223
+ copyFileSync(join(root, "config.example.yaml"), join(root, "config.yaml"));
224
+ console.log(" seeded config.yaml from the example — edit it to add providers.");
225
+ }
226
+ if (!existsSync(join(root, "node_modules"))) {
227
+ console.log(" installing gateway dependencies (first run)…");
228
+ execSync("npm install --omit=dev", { cwd: root, stdio: "inherit" });
229
+ }
230
+ if (existsSync(join(dashboardDir, "package.json"))) {
231
+ if (!existsSync(join(dashboardDir, "node_modules"))) {
232
+ console.log(" installing dashboard dependencies (first run)…");
233
+ execSync("npm install", { cwd: dashboardDir, stdio: "inherit" });
234
+ }
235
+ if (!existsSync(join(dashboardDir, ".next", "BUILD_ID"))) {
236
+ console.log(" building dashboard (first run)…");
237
+ execSync("npm run build", { cwd: dashboardDir, stdio: "inherit" });
238
+ }
239
+ }
240
+ }
241
+ function prompt(q) {
242
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
243
+ return new Promise((res) => rl.question(q, (a) => { rl.close(); res(a); }));
244
+ }
245
+ /**
246
+ * aigetwey-style launch menu. With a TTY (and no --yes), let the operator pick
247
+ * how to run; otherwise honor the flags. "web" opens the browser, "terminal"
248
+ * runs with live logs only, "exit" quits before starting anything.
249
+ */
250
+ async function chooseMode() {
251
+ if (opts.yes || !process.stdin.isTTY)
252
+ return opts.noBrowser ? "terminal" : "web";
253
+ console.log("\n aigetwey\n\n" +
254
+ " [1] Web UI start + open the dashboard in your browser\n" +
255
+ " [2] Terminal start with live logs only (no browser)\n" +
256
+ " [3] Hide to Tray run in the background with a tray icon\n" +
257
+ " [4] Exit\n");
258
+ const c = (await prompt(" choose [1]: ")).trim().toLowerCase();
259
+ if (c === "4" || c === "exit" || c === "q")
260
+ return "exit";
261
+ if (c === "3" || c === "hide" || c === "tray")
262
+ return "hide";
263
+ if (c === "2" || c === "terminal")
264
+ return "terminal";
265
+ return "web"; // default on Enter
266
+ }
267
+ /**
268
+ * "Hide to Tray": re-launch ourselves detached with --tray (which runs the stack
269
+ * + tray icon and survives the terminal closing), then exit so the background
270
+ * copy claims the ports. Also enables run-on-startup, matching aigetwey.
271
+ */
272
+ function hideToTray() {
273
+ try {
274
+ enableAutoStart();
275
+ }
276
+ catch { /* optional */ }
277
+ console.log("\n starting background process… (tray icon appears in a few seconds)");
278
+ const bg = spawn(process.execPath, [fileURLToPath(import.meta.url), "--tray"], {
279
+ detached: true,
280
+ stdio: "ignore",
281
+ env: { ...process.env, AIGETWEY_ADMIN_PASSWORD: adminPassword, SESSION_SECRET: sessionSecret },
282
+ });
283
+ bg.unref();
284
+ console.log(` aigetwey now running in the background (pid ${bg.pid}).`);
285
+ console.log(" right-click the tray icon → Open Dashboard / Quit. You can close this terminal.\n");
286
+ }
287
+ async function main() {
288
+ if (opts.help) {
289
+ console.log(HELP);
290
+ return;
291
+ }
292
+ // background tray process: skip the menu, never open a browser, show the tray.
293
+ const mode = opts.tray ? "tray" : await chooseMode();
294
+ if (mode === "exit")
295
+ return;
296
+ if (mode === "hide") {
297
+ hideToTray();
298
+ return;
299
+ }
300
+ const wantBrowser = mode === "web";
301
+ console.log("\n aigetwey — starting gateway + dashboard\n");
302
+ ensureSetup();
303
+ await ensurePortFree(GATEWAY_PORT, "AIGETWEY_PORT");
304
+ const gw = spawnGateway();
305
+ children.push(gw);
306
+ gw.on("exit", (code) => {
307
+ console.error(`\n gateway exited (${code}). shutting down.`);
308
+ shutdown();
309
+ process.exit(code ?? 1);
310
+ });
311
+ const up = await waitForGateway(`http://127.0.0.1:${GATEWAY_PORT}/health`);
312
+ if (!up) {
313
+ console.error(" gateway did not come up in time — check config.yaml / logs above.");
314
+ shutdown();
315
+ process.exit(1);
316
+ }
317
+ // the dashboard is optional: skip it cleanly if it hasn't been scaffolded yet.
318
+ if (!existsSync(join(dashboardDir, "package.json"))) {
319
+ console.log(`\n gateway http://127.0.0.1:${GATEWAY_PORT}`);
320
+ console.log(" dashboard not found (dashboard/ not scaffolded) — running gateway only.\n");
321
+ if (generatedPw)
322
+ console.log(` admin password (generated): ${adminPassword}\n`);
323
+ return;
324
+ }
325
+ await ensurePortFree(DASHBOARD_PORT, "DASHBOARD_PORT");
326
+ const dash = spawnDashboard();
327
+ children.push(dash);
328
+ dash.on("exit", (code) => {
329
+ console.error(`\n dashboard exited (${code}). shutting down.`);
330
+ shutdown();
331
+ process.exit(code ?? 1);
332
+ });
333
+ // one URL for everything — the gateway reverse-proxies the dashboard. Wait for
334
+ // the dashboard to answer THROUGH the proxy before opening the browser.
335
+ const appUrl = `http://127.0.0.1:${GATEWAY_PORT}`;
336
+ await waitForGateway(`${appUrl}/login`, 30000);
337
+ console.log(`\n aigetwey ${appUrl} (dashboard + API, one URL)`);
338
+ if (generatedPw) {
339
+ console.log(`\n admin password (generated): ${adminPassword}`);
340
+ console.log(" set AIGETWEY_ADMIN_PASSWORD to keep it stable across runs.\n");
341
+ }
342
+ if (mode === "tray") {
343
+ ensureTrayRuntime({ silent: true });
344
+ const started = initTray({ dashboardUrl: appUrl, port: GATEWAY_PORT, onQuit: shutdown });
345
+ console.log(started
346
+ ? "\n running in the system tray — right-click the icon for Open Dashboard / Quit.\n"
347
+ : "\n (tray unavailable on this session — running in the background; Ctrl-C or kill to stop.)\n");
348
+ }
349
+ else if (wantBrowser) {
350
+ openBrowser(appUrl);
351
+ }
352
+ else {
353
+ console.log(` (terminal mode — open ${appUrl} when you want the dashboard)\n`);
354
+ }
355
+ }
356
+ main().catch((e) => {
357
+ console.error(e);
358
+ shutdown();
359
+ process.exit(1);
360
+ });
361
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}