@agentxjs/portagent 1.3.0 → 1.5.0
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/LICENSE +0 -0
- package/README.md +23 -9
- package/dist/cli/index.js +659 -16
- package/dist/cli/index.js.map +15 -1
- package/dist/public/assets/main-fa01qzjx.js +77 -0
- package/dist/public/assets/main-pnn8q2ty.js +54596 -0
- package/dist/public/assets/main-pnn8q2ty.js.map +312 -0
- package/dist/public/assets/styles.css +2186 -0
- package/dist/public/index.html +3 -3
- package/dist/server/index.js +90 -133
- package/dist/server/index.js.map +13 -1
- package/package.json +15 -37
- package/dist/public/assets/browser-C0DG1J1h.js +0 -2
- package/dist/public/assets/browser-C0DG1J1h.js.map +0 -1
- package/dist/public/assets/index-BbPBfuHo.js +0 -1012
- package/dist/public/assets/index-BbPBfuHo.js.map +0 -1
- package/dist/public/assets/index-C4JWk6jH.css +0 -1
- package/dist/public/assets/index-XtJbS8_7.js +0 -2
- package/dist/public/assets/index-XtJbS8_7.js.map +0 -1
- package/dist/public/assets/reconnecting-websocket-mjs-Dd04wD44.js +0 -20
- package/dist/public/assets/reconnecting-websocket-mjs-Dd04wD44.js.map +0 -1
package/dist/public/index.html
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>Portagent - AgentX Portal</title>
|
|
8
|
-
<
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-C4JWk6jH.css">
|
|
8
|
+
<link rel="stylesheet" href="/assets/styles.css" />
|
|
10
9
|
</head>
|
|
11
10
|
<body>
|
|
12
11
|
<div id="root"></div>
|
|
12
|
+
<script type="module" src="/assets/main-pnn8q2ty.js"></script>
|
|
13
13
|
</body>
|
|
14
|
-
</html>
|
|
14
|
+
</html>
|
package/dist/server/index.js
CHANGED
|
@@ -1,15 +1,33 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
|
+
|
|
1
20
|
// src/server/index.ts
|
|
2
|
-
import {
|
|
3
|
-
import { fileURLToPath } from "url";
|
|
21
|
+
import { resolve } from "path";
|
|
4
22
|
import { createServer } from "http";
|
|
5
23
|
import { Hono as Hono2 } from "hono";
|
|
6
24
|
import { cors } from "hono/cors";
|
|
7
25
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
8
26
|
import { existsSync, readFileSync } from "fs";
|
|
9
27
|
import { createAgentX } from "agentxjs";
|
|
10
|
-
import { homedir } from "os";
|
|
11
|
-
import { join } from "path";
|
|
12
|
-
import { mkdirSync } from "fs";
|
|
28
|
+
import { homedir } from "node:os";
|
|
29
|
+
import { join } from "node:path";
|
|
30
|
+
import { mkdirSync } from "node:fs";
|
|
13
31
|
|
|
14
32
|
// src/server/auth.ts
|
|
15
33
|
import { Hono } from "hono";
|
|
@@ -18,10 +36,11 @@ import * as jose from "jose";
|
|
|
18
36
|
var TOKEN_EXPIRY = "7d";
|
|
19
37
|
function isValidInviteCode(code) {
|
|
20
38
|
const timestamp = parseInt(code, 10);
|
|
21
|
-
if (isNaN(timestamp))
|
|
22
|
-
|
|
39
|
+
if (isNaN(timestamp))
|
|
40
|
+
return false;
|
|
41
|
+
const now = new Date;
|
|
23
42
|
const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 1);
|
|
24
|
-
const expectedTimestamp = Math.floor(todayStart.getTime() /
|
|
43
|
+
const expectedTimestamp = Math.floor(todayStart.getTime() / 1000);
|
|
25
44
|
return timestamp === expectedTimestamp;
|
|
26
45
|
}
|
|
27
46
|
async function createToken(secret, userId) {
|
|
@@ -50,7 +69,7 @@ function toUserInfo(user) {
|
|
|
50
69
|
};
|
|
51
70
|
}
|
|
52
71
|
function authRoutes(userRepository, jwtSecret, agentx, config = {}) {
|
|
53
|
-
const app = new Hono
|
|
72
|
+
const app = new Hono;
|
|
54
73
|
const { inviteCodeRequired = true } = config;
|
|
55
74
|
app.get("/config", (c) => {
|
|
56
75
|
return c.json({ inviteCodeRequired });
|
|
@@ -87,14 +106,11 @@ function authRoutes(userRepository, jwtSecret, agentx, config = {}) {
|
|
|
87
106
|
avatar: body.avatar
|
|
88
107
|
});
|
|
89
108
|
const token = await createToken(jwtSecret, user.userId);
|
|
90
|
-
return c.json(
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
},
|
|
96
|
-
201
|
|
97
|
-
);
|
|
109
|
+
return c.json({
|
|
110
|
+
token,
|
|
111
|
+
user: toUserInfo(user),
|
|
112
|
+
expiresIn: TOKEN_EXPIRY
|
|
113
|
+
}, 201);
|
|
98
114
|
} catch (error) {
|
|
99
115
|
const message = error instanceof Error ? error.message : "Registration failed";
|
|
100
116
|
return c.json({ error: message }, 400);
|
|
@@ -167,21 +183,17 @@ function createAuthMiddleware(jwtSecret) {
|
|
|
167
183
|
}
|
|
168
184
|
|
|
169
185
|
// src/server/database/SQLiteUserRepository.ts
|
|
170
|
-
import Database from "
|
|
186
|
+
import { Database } from "bun:sqlite";
|
|
171
187
|
import { randomUUID } from "crypto";
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
var SQLiteUserRepository = class {
|
|
188
|
+
|
|
189
|
+
class SQLiteUserRepository {
|
|
175
190
|
db;
|
|
176
191
|
constructor(dbPath) {
|
|
177
192
|
this.db = new Database(dbPath);
|
|
178
193
|
this.initDatabase();
|
|
179
194
|
}
|
|
180
|
-
/**
|
|
181
|
-
* Initialize database schema
|
|
182
|
-
*/
|
|
183
195
|
initDatabase() {
|
|
184
|
-
this.db.
|
|
196
|
+
this.db.run("PRAGMA foreign_keys = ON");
|
|
185
197
|
this.db.exec(`
|
|
186
198
|
CREATE TABLE IF NOT EXISTS users (
|
|
187
199
|
userId TEXT PRIMARY KEY,
|
|
@@ -201,9 +213,6 @@ var SQLiteUserRepository = class {
|
|
|
201
213
|
CREATE INDEX IF NOT EXISTS idx_users_containerId ON users(containerId);
|
|
202
214
|
`);
|
|
203
215
|
}
|
|
204
|
-
/**
|
|
205
|
-
* Create a new user
|
|
206
|
-
*/
|
|
207
216
|
async createUser(input) {
|
|
208
217
|
if (await this.usernameExists(input.username)) {
|
|
209
218
|
throw new Error(`Username '${input.username}' already exists`);
|
|
@@ -211,7 +220,10 @@ var SQLiteUserRepository = class {
|
|
|
211
220
|
if (input.email && await this.emailExists(input.email)) {
|
|
212
221
|
throw new Error(`Email '${input.email}' already exists`);
|
|
213
222
|
}
|
|
214
|
-
const passwordHash = await hash(input.password,
|
|
223
|
+
const passwordHash = await Bun.password.hash(input.password, {
|
|
224
|
+
algorithm: "bcrypt",
|
|
225
|
+
cost: 10
|
|
226
|
+
});
|
|
215
227
|
const userId = randomUUID();
|
|
216
228
|
const now = Date.now();
|
|
217
229
|
const email = input.email || `${userId}@noemail.portagent`;
|
|
@@ -232,23 +244,9 @@ var SQLiteUserRepository = class {
|
|
|
232
244
|
userId, username, email, passwordHash, containerId, displayName, avatar, isActive, createdAt, updatedAt
|
|
233
245
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
234
246
|
`);
|
|
235
|
-
stmt.run(
|
|
236
|
-
user.userId,
|
|
237
|
-
user.username,
|
|
238
|
-
user.email,
|
|
239
|
-
user.passwordHash,
|
|
240
|
-
user.containerId,
|
|
241
|
-
user.displayName,
|
|
242
|
-
user.avatar,
|
|
243
|
-
user.isActive ? 1 : 0,
|
|
244
|
-
user.createdAt,
|
|
245
|
-
user.updatedAt
|
|
246
|
-
);
|
|
247
|
+
stmt.run(user.userId, user.username, user.email, user.passwordHash, user.containerId, user.displayName ?? null, user.avatar ?? null, user.isActive ? 1 : 0, user.createdAt, user.updatedAt);
|
|
247
248
|
return user;
|
|
248
249
|
}
|
|
249
|
-
/**
|
|
250
|
-
* Find user by ID
|
|
251
|
-
*/
|
|
252
250
|
async findUserById(userId) {
|
|
253
251
|
const stmt = this.db.prepare(`
|
|
254
252
|
SELECT * FROM users WHERE userId = ?
|
|
@@ -256,9 +254,6 @@ var SQLiteUserRepository = class {
|
|
|
256
254
|
const row = stmt.get(userId);
|
|
257
255
|
return row ? this.rowToUser(row) : null;
|
|
258
256
|
}
|
|
259
|
-
/**
|
|
260
|
-
* Find user by username
|
|
261
|
-
*/
|
|
262
257
|
async findUserByUsername(username) {
|
|
263
258
|
const stmt = this.db.prepare(`
|
|
264
259
|
SELECT * FROM users WHERE username = ?
|
|
@@ -266,9 +261,6 @@ var SQLiteUserRepository = class {
|
|
|
266
261
|
const row = stmt.get(username);
|
|
267
262
|
return row ? this.rowToUser(row) : null;
|
|
268
263
|
}
|
|
269
|
-
/**
|
|
270
|
-
* Find user by email
|
|
271
|
-
*/
|
|
272
264
|
async findUserByEmail(email) {
|
|
273
265
|
const stmt = this.db.prepare(`
|
|
274
266
|
SELECT * FROM users WHERE email = ?
|
|
@@ -276,9 +268,6 @@ var SQLiteUserRepository = class {
|
|
|
276
268
|
const row = stmt.get(email);
|
|
277
269
|
return row ? this.rowToUser(row) : null;
|
|
278
270
|
}
|
|
279
|
-
/**
|
|
280
|
-
* Find user by username or email
|
|
281
|
-
*/
|
|
282
271
|
async findUserByUsernameOrEmail(usernameOrEmail) {
|
|
283
272
|
const stmt = this.db.prepare(`
|
|
284
273
|
SELECT * FROM users WHERE username = ? OR email = ?
|
|
@@ -286,9 +275,6 @@ var SQLiteUserRepository = class {
|
|
|
286
275
|
const row = stmt.get(usernameOrEmail, usernameOrEmail);
|
|
287
276
|
return row ? this.rowToUser(row) : null;
|
|
288
277
|
}
|
|
289
|
-
/**
|
|
290
|
-
* Update user
|
|
291
|
-
*/
|
|
292
278
|
async updateUser(userId, updates) {
|
|
293
279
|
const user = await this.findUserById(userId);
|
|
294
280
|
if (!user) {
|
|
@@ -296,27 +282,27 @@ var SQLiteUserRepository = class {
|
|
|
296
282
|
}
|
|
297
283
|
const fields = [];
|
|
298
284
|
const values = [];
|
|
299
|
-
if (updates.username !==
|
|
285
|
+
if (updates.username !== undefined) {
|
|
300
286
|
fields.push("username = ?");
|
|
301
287
|
values.push(updates.username);
|
|
302
288
|
}
|
|
303
|
-
if (updates.email !==
|
|
289
|
+
if (updates.email !== undefined) {
|
|
304
290
|
fields.push("email = ?");
|
|
305
291
|
values.push(updates.email);
|
|
306
292
|
}
|
|
307
|
-
if (updates.passwordHash !==
|
|
293
|
+
if (updates.passwordHash !== undefined) {
|
|
308
294
|
fields.push("passwordHash = ?");
|
|
309
295
|
values.push(updates.passwordHash);
|
|
310
296
|
}
|
|
311
|
-
if (updates.displayName !==
|
|
297
|
+
if (updates.displayName !== undefined) {
|
|
312
298
|
fields.push("displayName = ?");
|
|
313
299
|
values.push(updates.displayName);
|
|
314
300
|
}
|
|
315
|
-
if (updates.avatar !==
|
|
301
|
+
if (updates.avatar !== undefined) {
|
|
316
302
|
fields.push("avatar = ?");
|
|
317
303
|
values.push(updates.avatar);
|
|
318
304
|
}
|
|
319
|
-
if (updates.isActive !==
|
|
305
|
+
if (updates.isActive !== undefined) {
|
|
320
306
|
fields.push("isActive = ?");
|
|
321
307
|
values.push(updates.isActive ? 1 : 0);
|
|
322
308
|
}
|
|
@@ -332,9 +318,6 @@ var SQLiteUserRepository = class {
|
|
|
332
318
|
stmt.run(...values);
|
|
333
319
|
return await this.findUserById(userId);
|
|
334
320
|
}
|
|
335
|
-
/**
|
|
336
|
-
* Delete user
|
|
337
|
-
*/
|
|
338
321
|
async deleteUser(userId) {
|
|
339
322
|
const stmt = this.db.prepare(`
|
|
340
323
|
DELETE FROM users WHERE userId = ?
|
|
@@ -342,9 +325,6 @@ var SQLiteUserRepository = class {
|
|
|
342
325
|
const result = stmt.run(userId);
|
|
343
326
|
return result.changes > 0;
|
|
344
327
|
}
|
|
345
|
-
/**
|
|
346
|
-
* List all users
|
|
347
|
-
*/
|
|
348
328
|
async listUsers() {
|
|
349
329
|
const stmt = this.db.prepare(`
|
|
350
330
|
SELECT * FROM users ORDER BY createdAt DESC
|
|
@@ -352,31 +332,18 @@ var SQLiteUserRepository = class {
|
|
|
352
332
|
const rows = stmt.all();
|
|
353
333
|
return rows.map((row) => this.rowToUser(row));
|
|
354
334
|
}
|
|
355
|
-
/**
|
|
356
|
-
* Check if username exists
|
|
357
|
-
*/
|
|
358
335
|
async usernameExists(username) {
|
|
359
336
|
const stmt = this.db.prepare(`
|
|
360
337
|
SELECT 1 FROM users WHERE username = ?
|
|
361
338
|
`);
|
|
362
|
-
return stmt.get(username) !==
|
|
339
|
+
return stmt.get(username) !== null;
|
|
363
340
|
}
|
|
364
|
-
/**
|
|
365
|
-
* Check if email exists
|
|
366
|
-
*/
|
|
367
341
|
async emailExists(email) {
|
|
368
342
|
const stmt = this.db.prepare(`
|
|
369
343
|
SELECT 1 FROM users WHERE email = ?
|
|
370
344
|
`);
|
|
371
|
-
return stmt.get(email) !==
|
|
345
|
+
return stmt.get(email) !== null;
|
|
372
346
|
}
|
|
373
|
-
/**
|
|
374
|
-
* Verify password for login
|
|
375
|
-
*
|
|
376
|
-
* @param usernameOrEmail - Username or email
|
|
377
|
-
* @param password - Plain text password
|
|
378
|
-
* @returns User record if valid, null if invalid
|
|
379
|
-
*/
|
|
380
347
|
async verifyPassword(usernameOrEmail, password) {
|
|
381
348
|
const user = await this.findUserByUsernameOrEmail(usernameOrEmail);
|
|
382
349
|
if (!user) {
|
|
@@ -385,18 +352,12 @@ var SQLiteUserRepository = class {
|
|
|
385
352
|
if (!user.isActive) {
|
|
386
353
|
return null;
|
|
387
354
|
}
|
|
388
|
-
const isValid = await
|
|
355
|
+
const isValid = await Bun.password.verify(password, user.passwordHash);
|
|
389
356
|
return isValid ? user : null;
|
|
390
357
|
}
|
|
391
|
-
/**
|
|
392
|
-
* Close database connection
|
|
393
|
-
*/
|
|
394
358
|
close() {
|
|
395
359
|
this.db.close();
|
|
396
360
|
}
|
|
397
|
-
// ============================================================================
|
|
398
|
-
// Private Helpers
|
|
399
|
-
// ============================================================================
|
|
400
361
|
rowToUser(row) {
|
|
401
362
|
return {
|
|
402
363
|
userId: row.userId,
|
|
@@ -411,12 +372,11 @@ var SQLiteUserRepository = class {
|
|
|
411
372
|
updatedAt: row.updatedAt
|
|
412
373
|
};
|
|
413
374
|
}
|
|
414
|
-
}
|
|
415
|
-
|
|
375
|
+
}
|
|
416
376
|
// src/server/logger.ts
|
|
417
377
|
import pino from "pino";
|
|
418
|
-
import fs from "fs";
|
|
419
|
-
import path from "path";
|
|
378
|
+
import fs from "node:fs";
|
|
379
|
+
import path from "node:path";
|
|
420
380
|
var LEVEL_MAP = {
|
|
421
381
|
debug: "debug",
|
|
422
382
|
info: "info",
|
|
@@ -424,7 +384,11 @@ var LEVEL_MAP = {
|
|
|
424
384
|
error: "error",
|
|
425
385
|
silent: "silent"
|
|
426
386
|
};
|
|
427
|
-
|
|
387
|
+
|
|
388
|
+
class PinoLoggerAdapter {
|
|
389
|
+
name;
|
|
390
|
+
level;
|
|
391
|
+
pino;
|
|
428
392
|
constructor(name, level, pino2) {
|
|
429
393
|
this.name = name;
|
|
430
394
|
this.level = level;
|
|
@@ -458,16 +422,17 @@ var PinoLoggerAdapter = class {
|
|
|
458
422
|
isErrorEnabled() {
|
|
459
423
|
return this.pino.isLevelEnabled("error");
|
|
460
424
|
}
|
|
461
|
-
}
|
|
462
|
-
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
class PinoLoggerFactory {
|
|
463
428
|
rootLogger;
|
|
464
429
|
constructor(options) {
|
|
465
|
-
const { level, logDir, pretty =
|
|
430
|
+
const { level, logDir, pretty = true } = options;
|
|
466
431
|
if (!fs.existsSync(logDir)) {
|
|
467
432
|
fs.mkdirSync(logDir, { recursive: true });
|
|
468
433
|
}
|
|
469
434
|
const getLogFilePath = () => {
|
|
470
|
-
const now =
|
|
435
|
+
const now = new Date;
|
|
471
436
|
const dateStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;
|
|
472
437
|
return path.join(logDir, `portagent-${dateStr}.log`);
|
|
473
438
|
};
|
|
@@ -495,7 +460,6 @@ var PinoLoggerFactory = class {
|
|
|
495
460
|
target: "pino/file",
|
|
496
461
|
level: LEVEL_MAP[level],
|
|
497
462
|
options: { destination: 1 }
|
|
498
|
-
// stdout
|
|
499
463
|
});
|
|
500
464
|
}
|
|
501
465
|
this.rootLogger = pino({
|
|
@@ -509,11 +473,9 @@ var PinoLoggerFactory = class {
|
|
|
509
473
|
const childLogger = this.rootLogger.child({ name });
|
|
510
474
|
return new PinoLoggerAdapter(name, this.rootLogger.level, childLogger);
|
|
511
475
|
}
|
|
512
|
-
}
|
|
476
|
+
}
|
|
513
477
|
|
|
514
478
|
// src/server/index.ts
|
|
515
|
-
var __filename = fileURLToPath(import.meta.url);
|
|
516
|
-
var __dirname = dirname(__filename);
|
|
517
479
|
function getDataPaths() {
|
|
518
480
|
const dataDir = process.env.AGENTX_DIR || join(homedir(), ".agentx");
|
|
519
481
|
const dataDirPath = join(dataDir, "data");
|
|
@@ -534,19 +496,17 @@ var JWT_SECRET = process.env.JWT_SECRET || crypto.randomUUID();
|
|
|
534
496
|
var INVITE_CODE_REQUIRED = process.env.INVITE_CODE_REQUIRED === "true";
|
|
535
497
|
async function createApp() {
|
|
536
498
|
const paths = getDataPaths();
|
|
537
|
-
const app = new Hono2
|
|
538
|
-
app.use(
|
|
539
|
-
"*",
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
allowHeaders: ["Content-Type", "Authorization"]
|
|
544
|
-
})
|
|
545
|
-
);
|
|
499
|
+
const app = new Hono2;
|
|
500
|
+
app.use("*", cors({
|
|
501
|
+
origin: "*",
|
|
502
|
+
allowMethods: ["GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS"],
|
|
503
|
+
allowHeaders: ["Content-Type", "Authorization"]
|
|
504
|
+
}));
|
|
546
505
|
const apiKey = process.env.LLM_PROVIDER_KEY;
|
|
547
506
|
if (!apiKey) {
|
|
548
507
|
console.error("Error: LLM_PROVIDER_KEY is required");
|
|
549
|
-
console.log(
|
|
508
|
+
console.log(`
|
|
509
|
+
Set it via environment variable:`);
|
|
550
510
|
console.log(" export LLM_PROVIDER_KEY=sk-ant-xxx");
|
|
551
511
|
process.exit(1);
|
|
552
512
|
}
|
|
@@ -557,7 +517,7 @@ async function createApp() {
|
|
|
557
517
|
const loggerFactory = new PinoLoggerFactory({
|
|
558
518
|
level: logLevel,
|
|
559
519
|
logDir: paths.logsDirPath,
|
|
560
|
-
pretty:
|
|
520
|
+
pretty: true
|
|
561
521
|
});
|
|
562
522
|
const agentx = await createAgentX({
|
|
563
523
|
llm: {
|
|
@@ -570,26 +530,24 @@ async function createApp() {
|
|
|
570
530
|
factory: loggerFactory
|
|
571
531
|
},
|
|
572
532
|
agentxDir: paths.dataDir,
|
|
573
|
-
// Auto-configures storage at {dataDir}/data/agentx.db
|
|
574
533
|
server
|
|
575
|
-
// Attach to existing HTTP server
|
|
576
534
|
});
|
|
577
535
|
const userRepository = new SQLiteUserRepository(paths.userDbPath);
|
|
578
536
|
const authMiddleware = createAuthMiddleware(JWT_SECRET);
|
|
579
537
|
app.get("/health", (c) => c.json({ status: "ok", timestamp: Date.now() }));
|
|
580
|
-
app.route(
|
|
581
|
-
"/api/auth",
|
|
582
|
-
authRoutes(userRepository, JWT_SECRET, agentx, { inviteCodeRequired: INVITE_CODE_REQUIRED })
|
|
583
|
-
);
|
|
538
|
+
app.route("/api/auth", authRoutes(userRepository, JWT_SECRET, agentx, { inviteCodeRequired: INVITE_CODE_REQUIRED }));
|
|
584
539
|
app.use("/agentx/*", authMiddleware);
|
|
585
540
|
app.get("/agentx/info", (c) => {
|
|
541
|
+
const isDev2 = true;
|
|
542
|
+
const wsUrl = isDev2 ? `ws://localhost:${PORT}/ws` : undefined;
|
|
586
543
|
return c.json({
|
|
587
544
|
version: "0.1.0",
|
|
588
|
-
wsPath: "/ws"
|
|
545
|
+
wsPath: "/ws",
|
|
546
|
+
wsUrl
|
|
589
547
|
});
|
|
590
548
|
});
|
|
591
|
-
const
|
|
592
|
-
const
|
|
549
|
+
const isDev = import.meta.dir.includes("/src/");
|
|
550
|
+
const publicDir = isDev ? resolve(import.meta.dir, "../../dist/public") : resolve(import.meta.dir, "../public");
|
|
593
551
|
if (existsSync(publicDir)) {
|
|
594
552
|
app.use("/*", serveStatic({ root: publicDir }));
|
|
595
553
|
app.get("*", (c) => {
|
|
@@ -602,10 +560,7 @@ async function createApp() {
|
|
|
602
560
|
});
|
|
603
561
|
} else if (isDev) {
|
|
604
562
|
app.get("*", (c) => {
|
|
605
|
-
return c.text(
|
|
606
|
-
"Static files not found. Run 'pnpm build:client' first, or use 'pnpm dev' for development.",
|
|
607
|
-
404
|
|
608
|
-
);
|
|
563
|
+
return c.text("Static files not found. Run 'pnpm build:client' first, or use 'pnpm dev' for development.", 404);
|
|
609
564
|
});
|
|
610
565
|
}
|
|
611
566
|
return { app, server, agentx, userRepository, paths };
|
|
@@ -640,11 +595,12 @@ Endpoints:`);
|
|
|
640
595
|
console.log(` WS /ws - WebSocket connection`);
|
|
641
596
|
server.listen(PORT, "0.0.0.0", () => {
|
|
642
597
|
console.log(`
|
|
643
|
-
\
|
|
644
|
-
console.log(`\
|
|
598
|
+
\uD83D\uDE80 Server running at http://localhost:${PORT}`);
|
|
599
|
+
console.log(`\uD83D\uDD0C WebSocket available at ws://localhost:${PORT}/ws`);
|
|
645
600
|
});
|
|
646
601
|
const shutdown = async () => {
|
|
647
|
-
console.log(
|
|
602
|
+
console.log(`
|
|
603
|
+
Shutting down...`);
|
|
648
604
|
await agentx.dispose();
|
|
649
605
|
userRepository.close();
|
|
650
606
|
server.close();
|
|
@@ -655,7 +611,8 @@ Endpoints:`);
|
|
|
655
611
|
process.on("SIGTERM", shutdown);
|
|
656
612
|
}
|
|
657
613
|
export {
|
|
658
|
-
|
|
659
|
-
|
|
614
|
+
startServer,
|
|
615
|
+
createApp
|
|
660
616
|
};
|
|
661
|
-
|
|
617
|
+
|
|
618
|
+
//# debugId=189D7C9D8A79235864756E2164756E21
|