zrocclaw 0.0.15 → 0.0.16

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zrocclaw",
3
- "version": "0.0.15",
3
+ "version": "0.0.16",
4
4
  "description": "个人专属浏览器AI助手命令行工具",
5
5
  "keywords": [
6
6
  "zrocclaw",
@@ -25,18 +25,20 @@
25
25
  ],
26
26
  "scripts": {},
27
27
  "dependencies": {
28
+ "@langchain/core": "^1.1.34",
29
+ "@langchain/langgraph": "^1.2.4",
30
+ "@langchain/openai": "^1.3.0",
28
31
  "commander": "^12.1.0",
29
- "pm2": "^5.4.3",
30
32
  "cors": "^2.8.6",
31
33
  "dotenv": "^17.3.1",
32
34
  "express": "^5.2.1",
35
+ "express-async-errors": "^3.1.1",
33
36
  "helmet": "^8.1.0",
34
37
  "http-proxy-middleware": "^3.0.5",
35
- "@langchain/core": "^1.1.34",
36
- "@langchain/langgraph": "^1.2.4",
37
- "@langchain/openai": "^1.3.0",
38
38
  "langchain": "^1.2.35",
39
+ "node-schedule": "^2.1.1",
39
40
  "playwright": "^1.58.2",
41
+ "pm2": "^5.4.3",
40
42
  "zod": "^4.3.6"
41
43
  }
42
44
  }
package/server/server.js CHANGED
@@ -172,9 +172,28 @@ var session_default = sessionModel;
172
172
  var import_promises = __toESM(require("fs/promises"));
173
173
  var import_path2 = __toESM(require("path"));
174
174
  var import_crypto = __toESM(require("crypto"));
175
+
176
+ // src/middlewares/errorHandler.ts
177
+ var BusinessError = class extends Error {
178
+ constructor(code, message) {
179
+ super(message);
180
+ this.code = code;
181
+ this.name = "BusinessError";
182
+ }
183
+ };
184
+ function errorHandler(err, req, res, next) {
185
+ console.error(`[Error] ${err.message}`, err);
186
+ if (err instanceof BusinessError) {
187
+ return res.error(err.message, err.code);
188
+ }
189
+ const message = false ? err.message : "Internal Server Error";
190
+ return res.error(message, 500);
191
+ }
192
+
193
+ // src/routes/config.ts
175
194
  var router = (0, import_express.Router)();
176
195
  router.get("/", (req, res) => {
177
- res.json({ configPath: getConfigPath() });
196
+ res.success({ configPath: getConfigPath() });
178
197
  });
179
198
  var configDir = getConfigPath();
180
199
  var configModelPath = import_path2.default.join(configDir, "model.json");
@@ -194,20 +213,19 @@ async function writeModelConfig(config) {
194
213
  await import_promises.default.mkdir(configDir, { recursive: true });
195
214
  await import_promises.default.writeFile(configModelPath, JSON.stringify(config, null, 2), "utf-8");
196
215
  }
197
- router.get("/model", async (req, res) => {
216
+ router.get("/model", async (req, res, next) => {
198
217
  try {
199
218
  const config = await readModelConfig();
200
219
  if (Object.keys(config).length === 0) {
201
220
  await writeModelConfig({});
202
- return res.json({});
221
+ return res.success({});
203
222
  }
204
- res.json(config);
223
+ res.success(config);
205
224
  } catch (error) {
206
- console.error("\u83B7\u53D6\u6A21\u578B\u5931\u8D25:", error);
207
- res.status(500).json({ error: "\u83B7\u53D6\u6A21\u578B\u5931\u8D25" });
225
+ next(error);
208
226
  }
209
227
  });
210
- router.post("/model", async (req, res) => {
228
+ router.post("/model", async (req, res, next) => {
211
229
  try {
212
230
  const { modelName, provider, apiKey, baseURL } = req.body;
213
231
  const newModel = {
@@ -226,17 +244,16 @@ router.post("/model", async (req, res) => {
226
244
  config.defaultModel = newModel;
227
245
  }
228
246
  await writeModelConfig(config);
229
- res.json(newModel);
247
+ res.success(newModel);
230
248
  } catch (error) {
231
- console.error("\u65B0\u589E\u6A21\u578B\u5931\u8D25:", error);
232
- res.status(500).json({ error: "\u65B0\u589E\u6A21\u578B\u5931\u8D25" });
249
+ next(error);
233
250
  }
234
251
  });
235
- router.post("/model/edit", async (req, res) => {
252
+ router.post("/model/edit", async (req, res, next) => {
236
253
  try {
237
254
  const modelData = req.body;
238
255
  if (!modelData || !modelData.id) {
239
- return res.status(400).json({ error: "\u7F3A\u5C11\u6A21\u578BID" });
256
+ throw new BusinessError(400, "\u7F3A\u5C11\u6A21\u578BID");
240
257
  }
241
258
  const config = await readModelConfig();
242
259
  if (!Array.isArray(config.models)) {
@@ -244,24 +261,23 @@ router.post("/model/edit", async (req, res) => {
244
261
  }
245
262
  const index = config.models.findIndex((m) => m.id === modelData.id);
246
263
  if (index === -1) {
247
- return res.status(404).json({ error: "\u6A21\u578B\u4E0D\u5B58\u5728" });
264
+ throw new BusinessError(404, "\u6A21\u578B\u4E0D\u5B58\u5728");
248
265
  }
249
266
  config.models[index] = { ...config.models[index], ...modelData };
250
267
  if (config.defaultModel && config.defaultModel.id === modelData.id) {
251
268
  config.defaultModel = config.models[index];
252
269
  }
253
270
  await writeModelConfig(config);
254
- res.json(config.models[index]);
271
+ res.success(config.models[index]);
255
272
  } catch (error) {
256
- console.error("\u7F16\u8F91\u6A21\u578B\u5931\u8D25:", error);
257
- res.status(500).json({ error: "\u7F16\u8F91\u6A21\u578B\u5931\u8D25" });
273
+ next(error);
258
274
  }
259
275
  });
260
- router.post("/model/delete", async (req, res) => {
276
+ router.post("/model/delete", async (req, res, next) => {
261
277
  try {
262
278
  const { id } = req.body;
263
279
  if (!id) {
264
- return res.status(400).json({ error: "\u7F3A\u5C11\u6A21\u578BID" });
280
+ throw new BusinessError(400, "\u7F3A\u5C11\u6A21\u578BID");
265
281
  }
266
282
  const config = await readModelConfig();
267
283
  if (!Array.isArray(config.models)) {
@@ -270,23 +286,22 @@ router.post("/model/delete", async (req, res) => {
270
286
  const initialLength = config.models.length;
271
287
  config.models = config.models.filter((m) => m.id !== id);
272
288
  if (config.models.length === initialLength) {
273
- return res.status(404).json({ error: "\u6A21\u578B\u4E0D\u5B58\u5728" });
289
+ throw new BusinessError(404, "\u6A21\u578B\u4E0D\u5B58\u5728");
274
290
  }
275
291
  if (config.defaultModel && config.defaultModel.id === id) {
276
292
  config.defaultModel = config.models.length > 0 ? config.models[0] : null;
277
293
  }
278
294
  await writeModelConfig(config);
279
- res.json({ success: true, message: "\u5220\u9664\u6210\u529F" });
295
+ res.success({ success: true }, "\u5220\u9664\u6210\u529F");
280
296
  } catch (error) {
281
- console.error("\u5220\u9664\u6A21\u578B\u5931\u8D25:", error);
282
- res.status(500).json({ error: "\u5220\u9664\u6A21\u578B\u5931\u8D25" });
297
+ next(error);
283
298
  }
284
299
  });
285
- router.post("/model/default", async (req, res) => {
300
+ router.post("/model/default", async (req, res, next) => {
286
301
  try {
287
302
  const { id } = req.body;
288
303
  if (!id) {
289
- return res.status(400).json({ error: "\u7F3A\u5C11\u6A21\u578BID" });
304
+ throw new BusinessError(400, "\u7F3A\u5C11\u6A21\u578BID");
290
305
  }
291
306
  const config = await readModelConfig();
292
307
  if (!Array.isArray(config.models)) {
@@ -294,14 +309,13 @@ router.post("/model/default", async (req, res) => {
294
309
  }
295
310
  const model = config.models.find((m) => m.id === id);
296
311
  if (!model) {
297
- return res.status(404).json({ error: "\u6A21\u578B\u4E0D\u5B58\u5728" });
312
+ throw new BusinessError(404, "\u6A21\u578B\u4E0D\u5B58\u5728");
298
313
  }
299
314
  config.defaultModel = model;
300
315
  await writeModelConfig(config);
301
- res.json({ success: true, defaultModel: config.defaultModel });
316
+ res.success({ success: true, defaultModel: config.defaultModel });
302
317
  } catch (error) {
303
- console.error("\u8BBE\u7F6E\u9ED8\u8BA4\u6A21\u578B\u5931\u8D25:", error);
304
- res.status(500).json({ error: "\u8BBE\u7F6E\u9ED8\u8BA4\u6A21\u578B\u5931\u8D25" });
318
+ next(error);
305
319
  }
306
320
  });
307
321
  var workspaceDir = getWorkspacePath();
@@ -323,24 +337,23 @@ async function writeSkillsConfig(config) {
323
337
  await import_promises.default.mkdir(workspaceDir, { recursive: true });
324
338
  await import_promises.default.writeFile(workspaceSkillsPath, JSON.stringify(config, null, 2), "utf-8");
325
339
  }
326
- router.get("/skills", async (req, res) => {
340
+ router.get("/skills", async (req, res, next) => {
327
341
  try {
328
342
  try {
329
343
  await import_promises.default.access(workspaceSkillsPath);
330
344
  } catch (e) {
331
345
  if (e.code === "ENOENT") {
332
346
  await writeSkillsConfig([]);
333
- return res.json([]);
347
+ return res.success([]);
334
348
  }
335
349
  }
336
350
  const config = await readSkillsConfig();
337
- res.json(config);
351
+ res.success(config);
338
352
  } catch (error) {
339
- console.error("\u83B7\u53D6\u6280\u80FD\u5217\u8868\u5931\u8D25:", error);
340
- res.status(500).json({ error: "\u83B7\u53D6\u6280\u80FD\u5217\u8868\u5931\u8D25" });
353
+ next(error);
341
354
  }
342
355
  });
343
- router.post("/skills", async (req, res) => {
356
+ router.post("/skills", async (req, res, next) => {
344
357
  try {
345
358
  const { name, summary, content } = req.body;
346
359
  const id = import_crypto.default.randomUUID();
@@ -352,58 +365,56 @@ router.post("/skills", async (req, res) => {
352
365
  };
353
366
  const skills = await readSkillsConfig();
354
367
  if (!Array.isArray(skills)) {
355
- throw new Error("skills.json \u683C\u5F0F\u9519\u8BEF");
368
+ throw new BusinessError(500, "skills.json \u683C\u5F0F\u9519\u8BEF");
356
369
  }
357
370
  skills.unshift(newSkill);
358
371
  await writeSkillsConfig(skills);
359
372
  await import_promises.default.mkdir(skillsDir, { recursive: true });
360
373
  const mdPath = import_path2.default.join(skillsDir, `${id}.md`);
361
374
  await import_promises.default.writeFile(mdPath, content || "", "utf-8");
362
- res.json(newSkill);
375
+ res.success(newSkill);
363
376
  } catch (error) {
364
- console.error("\u65B0\u589E\u6280\u80FD\u5931\u8D25:", error);
365
- res.status(500).json({ error: "\u65B0\u589E\u6280\u80FD\u5931\u8D25" });
377
+ next(error);
366
378
  }
367
379
  });
368
- router.post("/skills/edit", async (req, res) => {
380
+ router.post("/skills/edit", async (req, res, next) => {
369
381
  try {
370
382
  const { id, name, summary, content } = req.body;
371
383
  if (!id) {
372
- return res.status(400).json({ error: "\u7F3A\u5C11\u6280\u80FDID" });
384
+ throw new BusinessError(400, "\u7F3A\u5C11\u6280\u80FDID");
373
385
  }
374
386
  const skills = await readSkillsConfig();
375
387
  if (!Array.isArray(skills)) {
376
- throw new Error("skills.json \u683C\u5F0F\u9519\u8BEF");
388
+ throw new BusinessError(500, "skills.json \u683C\u5F0F\u9519\u8BEF");
377
389
  }
378
390
  const index = skills.findIndex((s) => s.id === id);
379
391
  if (index === -1) {
380
- return res.status(404).json({ error: "\u6280\u80FD\u4E0D\u5B58\u5728" });
392
+ throw new BusinessError(404, "\u6280\u80FD\u4E0D\u5B58\u5728");
381
393
  }
382
394
  skills[index] = { ...skills[index], name, summary };
383
395
  await writeSkillsConfig(skills);
384
396
  await import_promises.default.mkdir(skillsDir, { recursive: true });
385
397
  const mdPath = import_path2.default.join(skillsDir, `${id}.md`);
386
398
  await import_promises.default.writeFile(mdPath, content || "", "utf-8");
387
- res.json(skills[index]);
399
+ res.success(skills[index]);
388
400
  } catch (error) {
389
- console.error("\u7F16\u8F91\u6280\u80FD\u5931\u8D25:", error);
390
- res.status(500).json({ error: "\u7F16\u8F91\u6280\u80FD\u5931\u8D25" });
401
+ next(error);
391
402
  }
392
403
  });
393
- router.post("/skills/delete", async (req, res) => {
404
+ router.post("/skills/delete", async (req, res, next) => {
394
405
  try {
395
406
  const { id } = req.body;
396
407
  if (!id) {
397
- return res.status(400).json({ error: "\u7F3A\u5C11\u6280\u80FDID" });
408
+ throw new BusinessError(400, "\u7F3A\u5C11\u6280\u80FDID");
398
409
  }
399
410
  let skills = await readSkillsConfig();
400
411
  if (!Array.isArray(skills)) {
401
- throw new Error("skills.json \u683C\u5F0F\u9519\u8BEF");
412
+ throw new BusinessError(500, "skills.json \u683C\u5F0F\u9519\u8BEF");
402
413
  }
403
414
  const initialLength = skills.length;
404
415
  skills = skills.filter((s) => s.id !== id);
405
416
  if (skills.length === initialLength) {
406
- return res.status(404).json({ error: "\u6280\u80FD\u4E0D\u5B58\u5728" });
417
+ throw new BusinessError(404, "\u6280\u80FD\u4E0D\u5B58\u5728");
407
418
  }
408
419
  await writeSkillsConfig(skills);
409
420
  const mdPath = import_path2.default.join(skillsDir, `${id}.md`);
@@ -414,32 +425,30 @@ router.post("/skills/delete", async (req, res) => {
414
425
  console.error("\u5220\u9664\u6280\u80FD\u6587\u4EF6\u5931\u8D25:", e);
415
426
  }
416
427
  }
417
- res.json({ success: true, message: "\u5220\u9664\u6210\u529F" });
428
+ res.success({ success: true }, "\u5220\u9664\u6210\u529F");
418
429
  } catch (error) {
419
- console.error("\u5220\u9664\u6280\u80FD\u5931\u8D25:", error);
420
- res.status(500).json({ error: "\u5220\u9664\u6280\u80FD\u5931\u8D25" });
430
+ next(error);
421
431
  }
422
432
  });
423
- router.post("/skills/detail", async (req, res) => {
433
+ router.post("/skills/detail", async (req, res, next) => {
424
434
  try {
425
435
  const { id } = req.body;
426
436
  if (!id) {
427
- return res.status(400).json({ error: "\u7F3A\u5C11\u6280\u80FDID" });
437
+ throw new BusinessError(400, "\u7F3A\u5C11\u6280\u80FDID");
428
438
  }
429
439
  const mdPath = import_path2.default.join(skillsDir, `${id}.md`);
430
440
  try {
431
441
  await import_promises.default.access(mdPath);
432
442
  const content = await import_promises.default.readFile(mdPath, "utf-8");
433
- res.json({ content });
443
+ res.success({ content });
434
444
  } catch (e) {
435
445
  if (e.code === "ENOENT") {
436
- return res.status(404).json({ error: "\u6280\u80FD\u6587\u4EF6\u4E0D\u5B58\u5728" });
446
+ throw new BusinessError(404, "\u6280\u80FD\u6587\u4EF6\u4E0D\u5B58\u5728");
437
447
  }
438
448
  throw e;
439
449
  }
440
450
  } catch (error) {
441
- console.error("\u83B7\u53D6\u6280\u80FD\u8BE6\u60C5\u5931\u8D25:", error);
442
- res.status(500).json({ error: "\u83B7\u53D6\u6280\u80FD\u8BE6\u60C5\u5931\u8D25" });
451
+ next(error);
443
452
  }
444
453
  });
445
454
  var config_default = router;
@@ -649,7 +658,7 @@ var PlaywrightExecutor = class {
649
658
  }
650
659
  };
651
660
 
652
- // ../../packages/core/dist/chunk-JNJYWTIE.mjs
661
+ // ../../packages/core/dist/chunk-6FTQJGGG.mjs
653
662
  var import_openai = require("@langchain/openai");
654
663
  var import_langchain = require("langchain");
655
664
  var import_messages = require("@langchain/core/messages");
@@ -931,22 +940,26 @@ var extractPageStateTool = (0, import_tools3.tool)(
931
940
  };
932
941
  const container = document.createElement("div");
933
942
  container.className = "ai-label-container";
934
- container.style.position = "fixed";
943
+ container.style.position = "absolute";
935
944
  container.style.top = "0";
936
945
  container.style.left = "0";
937
946
  container.style.zIndex = "9999999";
938
947
  container.style.pointerEvents = "none";
948
+ container.style.width = "100%";
949
+ container.style.height = "100%";
939
950
  document.body.appendChild(container);
940
951
  elements.forEach((el) => {
941
952
  const rect = el.getBoundingClientRect();
942
953
  if (isVisible(el) && isInViewport(rect)) {
943
954
  const id = currentId++;
944
955
  el.setAttribute("idu-mark-id", id.toString());
956
+ const absoluteTop = rect.top + window.scrollY;
957
+ const absoluteLeft = rect.left + window.scrollX;
945
958
  const label = document.createElement("div");
946
959
  label.innerText = `${id}`;
947
960
  label.style.position = "absolute";
948
- label.style.top = `${Math.max(0, rect.top)}px`;
949
- label.style.left = `${Math.max(0, rect.left)}px`;
961
+ label.style.top = `${Math.max(0, absoluteTop)}px`;
962
+ label.style.left = `${Math.max(0, absoluteLeft)}px`;
950
963
  label.style.backgroundColor = "transparent";
951
964
  label.style.color = "red";
952
965
  label.style.fontSize = "12px";
@@ -1420,20 +1433,20 @@ var configDir2 = getConfigPath();
1420
1433
  var configFilePath = import_path3.default.join(configDir2, "model.json");
1421
1434
  var router2 = (0, import_express2.Router)();
1422
1435
  router2.get("/", (req, res) => {
1423
- res.json({ status: "OK" });
1436
+ res.success({ status: "OK" });
1424
1437
  });
1425
- router2.post("/stream", async (req, res) => {
1438
+ router2.post("/stream", async (req, res, next) => {
1426
1439
  try {
1427
1440
  const query = req.body.query;
1428
1441
  const thread_id = req.body.thread_id;
1429
1442
  if (!query || !thread_id) {
1430
- return res.status(400).json({ error: "Missing query or thread_id in request body" });
1443
+ throw new BusinessError(400, "Missing query or thread_id in request body");
1431
1444
  }
1432
1445
  const configContent = await import_promises2.default.readFile(configFilePath, "utf-8");
1433
1446
  const config = JSON.parse(configContent);
1434
1447
  const modelConfig = config.defaultModel;
1435
1448
  if (!modelConfig) {
1436
- return res.status(500).json({ error: "defaultModel not found in config" });
1449
+ throw new BusinessError(500, "defaultModel not found in config");
1437
1450
  }
1438
1451
  res.setHeader("Content-Type", "text/event-stream");
1439
1452
  res.setHeader("Cache-Control", "no-cache");
@@ -1444,53 +1457,86 @@ router2.post("/stream", async (req, res) => {
1444
1457
  }
1445
1458
  res.end();
1446
1459
  } catch (error) {
1447
- console.error("Stream error:", error);
1448
1460
  if (!res.headersSent) {
1449
- res.status(500).json({ error: "Internal server error" });
1461
+ next(error);
1450
1462
  } else {
1463
+ console.error("Stream error after headers sent:", error);
1451
1464
  res.end();
1452
1465
  }
1453
1466
  }
1454
1467
  });
1455
- router2.get("/session", (req, res) => {
1456
- const isNew = req.query.new === "true";
1457
- let sessionId = session_default.getSessionId();
1458
- if (!sessionId || isNew) {
1459
- sessionId = import_crypto2.default.randomUUID();
1460
- session_default.setSessionId(sessionId);
1468
+ router2.get("/session", (req, res, next) => {
1469
+ try {
1470
+ const isNew = req.query.new === "true";
1471
+ let sessionId = session_default.getSessionId();
1472
+ if (!sessionId || isNew) {
1473
+ sessionId = import_crypto2.default.randomUUID();
1474
+ session_default.setSessionId(sessionId);
1475
+ }
1476
+ res.success({ sessionId });
1477
+ } catch (error) {
1478
+ next(error);
1461
1479
  }
1462
- res.json({ sessionId });
1463
1480
  });
1464
- router2.post("/history", (req, res) => {
1465
- const { sessionId } = req.body;
1466
- if (!sessionId) {
1467
- return res.status(400).json({ error: "Missing sessionId" });
1481
+ router2.post("/history", (req, res, next) => {
1482
+ try {
1483
+ const { sessionId } = req.body;
1484
+ if (!sessionId) {
1485
+ throw new BusinessError(400, "Missing sessionId");
1486
+ }
1487
+ const data = session_default.getSessionData();
1488
+ res.success({ data });
1489
+ } catch (error) {
1490
+ next(error);
1468
1491
  }
1469
- const data = session_default.getSessionData();
1470
- res.json({ data });
1471
1492
  });
1472
- router2.post("/history/add", (req, res) => {
1473
- const { sessionId, id, role, content, ...rest } = req.body;
1474
- if (!sessionId) {
1475
- return res.status(400).json({ error: "Missing sessionId" });
1476
- }
1477
- if (!id || !role || !content) {
1478
- return res.status(400).json({ error: "Missing required SessionDataItem fields (id, role, content)" });
1493
+ router2.post("/history/add", (req, res, next) => {
1494
+ try {
1495
+ const { sessionId, id, role, content, ...rest } = req.body;
1496
+ if (!sessionId) {
1497
+ throw new BusinessError(400, "Missing sessionId");
1498
+ }
1499
+ if (!id || !role || !content) {
1500
+ throw new BusinessError(400, "Missing required SessionDataItem fields (id, role, content)");
1501
+ }
1502
+ const item = { id, role, content, ...rest };
1503
+ session_default.addSessionItem(item);
1504
+ res.success({ success: true });
1505
+ } catch (error) {
1506
+ next(error);
1479
1507
  }
1480
- const item = { id, role, content, ...rest };
1481
- session_default.addSessionItem(item);
1482
- res.json({ success: true });
1483
1508
  });
1484
1509
  var chat_default = router2;
1485
1510
 
1486
1511
  // src/app.ts
1487
1512
  var import_dotenv = __toESM(require("dotenv"));
1488
1513
  var import_path4 = __toESM(require("path"));
1514
+
1515
+ // src/middlewares/responseFormatter.ts
1516
+ var responseFormatter = (req, res, next) => {
1517
+ res.success = function(data, message = "success") {
1518
+ return this.json({
1519
+ code: 0,
1520
+ message,
1521
+ data
1522
+ });
1523
+ };
1524
+ res.error = function(message, code = -1) {
1525
+ return this.status(200).json({
1526
+ code,
1527
+ message
1528
+ });
1529
+ };
1530
+ next();
1531
+ };
1532
+
1533
+ // src/app.ts
1489
1534
  import_dotenv.default.config();
1490
1535
  var app = (0, import_express3.default)();
1491
1536
  app.use((0, import_helmet.default)());
1492
1537
  app.use((0, import_cors.default)());
1493
1538
  app.use(import_express3.default.json());
1539
+ app.use(responseFormatter);
1494
1540
  app.get("/health", (req, res) => {
1495
1541
  res.json({ status: "OK", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
1496
1542
  });
@@ -1499,6 +1545,7 @@ app.use("/chat", chat_default);
1499
1545
  if (true) {
1500
1546
  app.use("/web", import_express3.default.static(import_path4.default.join(__dirname, "static")));
1501
1547
  }
1548
+ app.use(errorHandler);
1502
1549
  var app_default = app;
1503
1550
 
1504
1551
  // src/server.ts
@@ -1 +1 @@
1
- .markdown-body[data-v-18317f9d] p{margin-bottom:.5em}.markdown-body[data-v-18317f9d] p:last-child{margin-bottom:0}.markdown-body[data-v-18317f9d] pre{background-color:var(--fallback-b3,oklch(var(--b3) / 1));border-radius:.5rem;margin-top:.5em;margin-bottom:.5em;padding:.5rem;overflow-x:auto}.markdown-body[data-v-18317f9d] code{background-color:var(--fallback-b3,oklch(var(--b3) / .5));border-radius:.25rem;padding:.1rem .3rem;font-family:monospace}.markdown-body[data-v-18317f9d] pre code{background-color:#0000;padding:0}.markdown-body[data-v-18317f9d] a{color:var(--fallback-p,oklch(var(--p) / 1));text-decoration:underline}textarea[data-v-f19df973]::-webkit-scrollbar{width:4px}textarea[data-v-f19df973]::-webkit-scrollbar-track{background:0 0}textarea[data-v-f19df973]::-webkit-scrollbar-thumb{background-color:var(--fallback-bc,oklch(var(--bc)/.2));border-radius:4px}.overflow-y-auto[data-v-8b42149f]::-webkit-scrollbar{width:6px}.overflow-y-auto[data-v-8b42149f]::-webkit-scrollbar-track{background:0 0}.overflow-y-auto[data-v-8b42149f]::-webkit-scrollbar-thumb{background-color:var(--fallback-bc,oklch(var(--bc)/.2));border-radius:10px}
1
+ .markdown-body[data-v-18317f9d] p{margin-bottom:.5em}.markdown-body[data-v-18317f9d] p:last-child{margin-bottom:0}.markdown-body[data-v-18317f9d] pre{background-color:var(--fallback-b3,oklch(var(--b3) / 1));border-radius:.5rem;margin-top:.5em;margin-bottom:.5em;padding:.5rem;overflow-x:auto}.markdown-body[data-v-18317f9d] code{background-color:var(--fallback-b3,oklch(var(--b3) / .5));border-radius:.25rem;padding:.1rem .3rem;font-family:monospace}.markdown-body[data-v-18317f9d] pre code{background-color:#0000;padding:0}.markdown-body[data-v-18317f9d] a{color:var(--fallback-p,oklch(var(--p) / 1));text-decoration:underline}textarea[data-v-f19df973]::-webkit-scrollbar{width:4px}textarea[data-v-f19df973]::-webkit-scrollbar-track{background:0 0}textarea[data-v-f19df973]::-webkit-scrollbar-thumb{background-color:var(--fallback-bc,oklch(var(--bc)/.2));border-radius:4px}.overflow-y-auto[data-v-fc3c2bf0]::-webkit-scrollbar{width:6px}.overflow-y-auto[data-v-fc3c2bf0]::-webkit-scrollbar-track{background:0 0}.overflow-y-auto[data-v-fc3c2bf0]::-webkit-scrollbar-thumb{background-color:var(--fallback-bc,oklch(var(--bc)/.2));border-radius:10px}