hermes-web-ui 0.2.6 → 0.2.7

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 (117) hide show
  1. package/README.md +15 -5
  2. package/dist/{assets/Button-BHvh9zmj.js → client/assets/Button-zECKCotA.js} +1 -1
  3. package/dist/{assets/ChannelsView-DZMniRoi.js → client/assets/ChannelsView-Bvh3tnio.js} +1 -1
  4. package/dist/client/assets/ChannelsView-xCdAEZam.css +1 -0
  5. package/dist/{assets/ChatView-Dt1eqp6-.js → client/assets/ChatView-CJZahJ1V.js} +3 -3
  6. package/dist/client/assets/ChatView-Ds8Q3Yrv.css +1 -0
  7. package/dist/{assets/Close-DYPlamoH.js → client/assets/Close-DjLWDodG.js} +1 -1
  8. package/dist/{assets/FormItem-C75Y2lpf.js → client/assets/FormItem-CZ9auYA2.js} +1 -1
  9. package/dist/{assets/Input-CS0p63GR.js → client/assets/Input-DxJk6pT-.js} +1 -1
  10. package/dist/{assets/InputNumber-lHTE1DBf.js → client/assets/InputNumber-BTqp81h0.js} +1 -1
  11. package/dist/client/assets/JobsView-Bbg7Yvse.css +1 -0
  12. package/dist/{assets/JobsView-kGXDpDGq.js → client/assets/JobsView-DsfGyjnT.js} +2 -2
  13. package/dist/client/assets/LoginView-BiWaCYS0.js +1 -0
  14. package/dist/client/assets/LoginView-Bt3yT3yN.css +1 -0
  15. package/dist/client/assets/LogsView-D9Es8tZb.css +1 -0
  16. package/dist/client/assets/LogsView-DuORyFFY.js +1 -0
  17. package/dist/{assets/MarkdownRenderer-Bp-uAEtp.js → client/assets/MarkdownRenderer-BA3oPVqT.js} +1 -1
  18. package/dist/client/assets/MemoryView-CU3JHweh.css +1 -0
  19. package/dist/{assets/MemoryView-CWEya0jB.js → client/assets/MemoryView-VgQFNMsP.js} +2 -2
  20. package/dist/{assets/Modal-mFCAbKPD.js → client/assets/Modal-WQKdvHJY.js} +1 -1
  21. package/dist/client/assets/ModelsView-HlT7QxLF.css +1 -0
  22. package/dist/{assets/ModelsView-BdPt2Mo_.js → client/assets/ModelsView-QDRloKd5.js} +1 -1
  23. package/dist/{assets/Popconfirm-C2OzcGTX.js → client/assets/Popconfirm-02A7vL_z.js} +1 -1
  24. package/dist/{assets/Popover-CRZpNb8Q.js → client/assets/Popover-2C1zuptC.js} +1 -1
  25. package/dist/{assets/Scrollbar-CA0Mq0os.js → client/assets/Scrollbar-Bg2FeTtI.js} +1 -1
  26. package/dist/{assets/Select-DLECSo9D.js → client/assets/Select-C_hKaXgI.js} +1 -1
  27. package/dist/client/assets/SettingRow-CLLFxWP3.js +1 -0
  28. package/dist/client/assets/SettingRow-DsjrPlmy.css +1 -0
  29. package/dist/{assets/SettingsView-DWXjfdpD.js → client/assets/SettingsView-CeScqhwO.js} +2 -2
  30. package/dist/client/assets/SettingsView-vVdZjtPc.css +1 -0
  31. package/dist/{assets/SkillsView-Gb4tyJjH.js → client/assets/SkillsView-D6CegW4w.js} +1 -1
  32. package/dist/client/assets/SkillsView-l8q6J0Ov.css +1 -0
  33. package/dist/{assets/Spin-BbbA3R-G.js → client/assets/Spin-lybeIDeX.js} +1 -1
  34. package/dist/{assets/Suffix-BMwB7UJK.js → client/assets/Suffix-Dv1UElLH.js} +1 -1
  35. package/dist/{assets/Switch-Xa0U6jwA.js → client/assets/Switch-mgeu-lpD.js} +1 -1
  36. package/dist/{assets/Tag-NMAaTGW7.js → client/assets/Tag-DWc4lbAm.js} +1 -1
  37. package/dist/{assets/TerminalView-B7iMIrM8.css → client/assets/TerminalView-CuqATvpq.css} +1 -1
  38. package/dist/{assets/TerminalView-CvTXTM3W.js → client/assets/TerminalView-DmnXOHFu.js} +2 -2
  39. package/dist/{assets/Tooltip-C9RmASqV.js → client/assets/Tooltip-DrDTmrj3.js} +1 -1
  40. package/dist/client/assets/UsageView-BgU-h2NT.css +1 -0
  41. package/dist/{assets/UsageView-DiCHVrs8.js → client/assets/UsageView-C3O6-vbW.js} +1 -1
  42. package/dist/{assets/Warning-CmJYhk3M.js → client/assets/Warning-t1i_4T5i.js} +1 -1
  43. package/dist/{assets/_plugin-vue_export-helper-NLzeiXdV.js → client/assets/_plugin-vue_export-helper-BkT4A29V.js} +1 -1
  44. package/dist/client/assets/app-BUjbfMSg.js +1 -0
  45. package/dist/client/assets/app-p59ZckFN.js +1 -0
  46. package/dist/{assets/browser-DNwI2j4X.js → client/assets/browser-DzAOCZtm.js} +1 -1
  47. package/dist/client/assets/chat-CX1Hza8X.js +6 -0
  48. package/dist/client/assets/context-BM8ZQCOz.js +1 -0
  49. package/dist/{assets/fade-in-scale-up.cssr-BMJXPg-3.js → client/assets/fade-in-scale-up.cssr-DQl-Z54c.js} +1 -1
  50. package/dist/{assets/index-DlNQjiQP.js → client/assets/index-95z-iQoj.js} +2 -2
  51. package/dist/{assets/index-TVVcuwR0.css → client/assets/index-C33O1KZm.css} +1 -1
  52. package/dist/client/assets/jobs-B9NHIxuL.js +1 -0
  53. package/dist/{assets/pinia-DKSOddVw.js → client/assets/pinia-bPUFQqFK.js} +1 -1
  54. package/dist/{assets/router-CpYvE976.js → client/assets/router-COwpqexM.js} +2 -2
  55. package/dist/client/assets/sessions-B1SPfe-R.js +1 -0
  56. package/dist/client/assets/skills-CRtljpt6.js +1 -0
  57. package/dist/client/assets/use-compitable-BnlNjEug.js +1 -0
  58. package/dist/{assets/use-message-17mZlZe3.js → client/assets/use-message-g8F4Z57w.js} +1 -1
  59. package/dist/client/index.html +38 -0
  60. package/dist/server/index.js +6 -26
  61. package/dist/server/routes/{config.js → hermes/config.js} +4 -4
  62. package/dist/server/routes/{filesystem.js → hermes/filesystem.js} +13 -13
  63. package/dist/server/routes/hermes/index.d.ts +5 -0
  64. package/dist/server/routes/hermes/index.js +25 -0
  65. package/dist/server/routes/{logs.js → hermes/logs.js} +3 -3
  66. package/dist/server/routes/hermes/profiles.d.ts +2 -0
  67. package/dist/server/routes/hermes/profiles.js +222 -0
  68. package/dist/server/routes/{proxy-handler.js → hermes/proxy-handler.js} +6 -2
  69. package/dist/server/routes/{proxy.d.ts → hermes/proxy.d.ts} +2 -0
  70. package/dist/server/routes/hermes/proxy.js +20 -0
  71. package/dist/server/routes/{sessions.js → hermes/sessions.js} +5 -5
  72. package/dist/server/routes/{terminal.js → hermes/terminal.js} +2 -2
  73. package/dist/server/routes/{weixin.js → hermes/weixin.js} +4 -4
  74. package/dist/server/services/auth.js +1 -1
  75. package/dist/server/services/hermes-cli.d.ts +53 -0
  76. package/dist/server/services/hermes-cli.js +195 -0
  77. package/package.json +5 -5
  78. package/dist/assets/ChannelsView-C7Wor1FB.css +0 -1
  79. package/dist/assets/ChatView-gR62J-Xr.css +0 -1
  80. package/dist/assets/JobsView-DoUtVQm_.css +0 -1
  81. package/dist/assets/LoginView-BXByybMK.css +0 -1
  82. package/dist/assets/LoginView-HQwDR5A7.js +0 -1
  83. package/dist/assets/LogsView-COSQTXoG.css +0 -1
  84. package/dist/assets/LogsView-KPcTBGzh.js +0 -1
  85. package/dist/assets/MemoryView-CL5H-3mE.css +0 -1
  86. package/dist/assets/ModelsView-DbBXgw4g.css +0 -1
  87. package/dist/assets/SettingRow-CsKwX-jv.js +0 -1
  88. package/dist/assets/SettingRow-Dwpo-tP0.css +0 -1
  89. package/dist/assets/SettingsView-Citzr3ci.css +0 -1
  90. package/dist/assets/SkillsView-BNEWlriU.css +0 -1
  91. package/dist/assets/UsageView-DKigFrVY.css +0 -1
  92. package/dist/assets/app-CQZfHgyy.js +0 -1
  93. package/dist/assets/app-DeeNNd_a.js +0 -1
  94. package/dist/assets/chat-DnFbBAAK.js +0 -6
  95. package/dist/assets/context-DLFTSrww.js +0 -1
  96. package/dist/assets/jobs-B7U8gZia.js +0 -1
  97. package/dist/assets/sessions-DTV2WuAE.js +0 -1
  98. package/dist/assets/skills-DwX9oZGG.js +0 -1
  99. package/dist/assets/use-compitable-D2-fMbL2.js +0 -1
  100. package/dist/index.html +0 -38
  101. package/dist/server/routes/proxy.js +0 -12
  102. /package/dist/{assets → client/assets}/MarkdownRenderer-Bd-nS4jK.css +0 -0
  103. /package/dist/{assets → client/assets}/dance-gGRu7JHG.mp4 +0 -0
  104. /package/dist/{assets → client/assets}/logo-Cd-t_oGE.js +0 -0
  105. /package/dist/{assets → client/assets}/omit-C4dR5R2G.js +0 -0
  106. /package/dist/{assets → client/assets}/thinking-Cwsva50h.mp4 +0 -0
  107. /package/dist/{favicon.ico → client/favicon.ico} +0 -0
  108. /package/dist/{favicon.svg → client/favicon.svg} +0 -0
  109. /package/dist/{icons.svg → client/icons.svg} +0 -0
  110. /package/dist/{logo.png → client/logo.png} +0 -0
  111. /package/dist/server/routes/{config.d.ts → hermes/config.d.ts} +0 -0
  112. /package/dist/server/routes/{filesystem.d.ts → hermes/filesystem.d.ts} +0 -0
  113. /package/dist/server/routes/{logs.d.ts → hermes/logs.d.ts} +0 -0
  114. /package/dist/server/routes/{proxy-handler.d.ts → hermes/proxy-handler.d.ts} +0 -0
  115. /package/dist/server/routes/{sessions.d.ts → hermes/sessions.d.ts} +0 -0
  116. /package/dist/server/routes/{terminal.d.ts → hermes/terminal.d.ts} +0 -0
  117. /package/dist/server/routes/{weixin.d.ts → hermes/weixin.d.ts} +0 -0
@@ -37,7 +37,7 @@ exports.setupTerminalWebSocket = setupTerminalWebSocket;
37
37
  const ws_1 = require("ws");
38
38
  const fs_1 = require("fs");
39
39
  const pty = __importStar(require("node-pty"));
40
- const auth_1 = require("../services/auth");
40
+ const auth_1 = require("../../services/auth");
41
41
  // ─── Shell detection ────────────────────────────────────────────
42
42
  function findShell() {
43
43
  const candidates = [
@@ -89,7 +89,7 @@ function setupTerminalWebSocket(httpServer) {
89
89
  const defaultShell = findShell();
90
90
  httpServer.on('upgrade', async (req, socket, head) => {
91
91
  const url = new URL(req.url || '', `http://${req.headers.host}`);
92
- if (url.pathname !== '/terminal') {
92
+ if (url.pathname !== '/api/hermes/terminal') {
93
93
  socket.destroy();
94
94
  return;
95
95
  }
@@ -10,12 +10,12 @@ const promises_1 = require("fs/promises");
10
10
  const promises_2 = require("fs/promises");
11
11
  const path_1 = require("path");
12
12
  const os_1 = require("os");
13
- const hermes_cli_1 = require("../services/hermes-cli");
13
+ const hermes_cli_1 = require("../../services/hermes-cli");
14
14
  const envPath = (0, path_1.resolve)((0, os_1.homedir)(), '.hermes/.env');
15
15
  const ILINK_BASE = 'https://ilinkai.weixin.qq.com';
16
16
  exports.weixinRoutes = new router_1.default();
17
17
  // GET /api/weixin/qrcode — fetch QR code from Tencent iLink API
18
- exports.weixinRoutes.get('/api/weixin/qrcode', async (ctx) => {
18
+ exports.weixinRoutes.get('/api/hermes/weixin/qrcode', async (ctx) => {
19
19
  try {
20
20
  const res = await axios_1.default.get(`${ILINK_BASE}/ilink/bot/get_bot_qrcode`, {
21
21
  params: { bot_type: 3 },
@@ -38,7 +38,7 @@ exports.weixinRoutes.get('/api/weixin/qrcode', async (ctx) => {
38
38
  }
39
39
  });
40
40
  // GET /api/weixin/qrcode/status — poll QR scan status
41
- exports.weixinRoutes.get('/api/weixin/qrcode/status', async (ctx) => {
41
+ exports.weixinRoutes.get('/api/hermes/weixin/qrcode/status', async (ctx) => {
42
42
  const qrcode = ctx.query.qrcode;
43
43
  if (!qrcode) {
44
44
  ctx.status = 400;
@@ -69,7 +69,7 @@ exports.weixinRoutes.get('/api/weixin/qrcode/status', async (ctx) => {
69
69
  }
70
70
  });
71
71
  // POST /api/weixin/save — save weixin credentials to .env
72
- exports.weixinRoutes.post('/api/weixin/save', async (ctx) => {
72
+ exports.weixinRoutes.post('/api/hermes/weixin/save', async (ctx) => {
73
73
  const { account_id, token, base_url } = ctx.request.body;
74
74
  if (!account_id || !token) {
75
75
  ctx.status = 400;
@@ -48,7 +48,7 @@ async function authMiddleware(token) {
48
48
  // Skip non-API paths (static files, health check, SPA)
49
49
  const path = ctx.path;
50
50
  if (path === '/health' ||
51
- (!path.startsWith('/api') && !path.startsWith('/v1') && path !== '/upload' && path !== '/webhook')) {
51
+ (!path.startsWith('/api') && !path.startsWith('/v1') && path !== '/webhook')) {
52
52
  await next();
53
53
  return;
54
54
  }
@@ -58,6 +58,10 @@ export declare function startGatewayBackground(): Promise<number | null>;
58
58
  * Restart Hermes gateway
59
59
  */
60
60
  export declare function restartGateway(): Promise<string>;
61
+ /**
62
+ * Stop Hermes gateway
63
+ */
64
+ export declare function stopGateway(): Promise<string>;
61
65
  /**
62
66
  * List available log files
63
67
  */
@@ -66,3 +70,52 @@ export declare function listLogFiles(): Promise<LogFileInfo[]>;
66
70
  * Read log lines
67
71
  */
68
72
  export declare function readLogs(logName?: string, lines?: number, level?: string, session?: string, since?: string): Promise<string>;
73
+ export interface HermesProfile {
74
+ name: string;
75
+ active: boolean;
76
+ model: string;
77
+ gateway: string;
78
+ alias: string;
79
+ }
80
+ export interface HermesProfileDetail {
81
+ name: string;
82
+ path: string;
83
+ model: string;
84
+ provider: string;
85
+ gateway: string;
86
+ skills: number;
87
+ hasEnv: boolean;
88
+ hasSoulMd: boolean;
89
+ }
90
+ /**
91
+ * List all profiles
92
+ */
93
+ export declare function listProfiles(): Promise<HermesProfile[]>;
94
+ /**
95
+ * Get profile details
96
+ */
97
+ export declare function getProfile(name: string): Promise<HermesProfileDetail>;
98
+ /**
99
+ * Create a new profile
100
+ */
101
+ export declare function createProfile(name: string, clone?: boolean): Promise<string>;
102
+ /**
103
+ * Delete a profile
104
+ */
105
+ export declare function deleteProfile(name: string): Promise<boolean>;
106
+ /**
107
+ * Rename a profile
108
+ */
109
+ export declare function renameProfile(oldName: string, newName: string): Promise<boolean>;
110
+ /**
111
+ * Switch active profile
112
+ */
113
+ export declare function useProfile(name: string): Promise<string>;
114
+ /**
115
+ * Export profile to archive
116
+ */
117
+ export declare function exportProfile(name: string, outputPath?: string): Promise<string>;
118
+ /**
119
+ * Import profile from archive
120
+ */
121
+ export declare function importProfile(archivePath: string, name?: string): Promise<string>;
@@ -8,8 +8,17 @@ exports.getVersion = getVersion;
8
8
  exports.startGateway = startGateway;
9
9
  exports.startGatewayBackground = startGatewayBackground;
10
10
  exports.restartGateway = restartGateway;
11
+ exports.stopGateway = stopGateway;
11
12
  exports.listLogFiles = listLogFiles;
12
13
  exports.readLogs = readLogs;
14
+ exports.listProfiles = listProfiles;
15
+ exports.getProfile = getProfile;
16
+ exports.createProfile = createProfile;
17
+ exports.deleteProfile = deleteProfile;
18
+ exports.renameProfile = renameProfile;
19
+ exports.useProfile = useProfile;
20
+ exports.exportProfile = exportProfile;
21
+ exports.importProfile = importProfile;
13
22
  const child_process_1 = require("child_process");
14
23
  const util_1 = require("util");
15
24
  const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
@@ -201,6 +210,16 @@ async function restartGateway() {
201
210
  });
202
211
  return stdout || stderr;
203
212
  }
213
+ /**
214
+ * Stop Hermes gateway
215
+ */
216
+ async function stopGateway() {
217
+ const { stdout, stderr } = await execFileAsync('hermes', ['gateway', 'stop'], {
218
+ timeout: 30000,
219
+ ...execOpts,
220
+ });
221
+ return stdout || stderr;
222
+ }
204
223
  /**
205
224
  * List available log files
206
225
  */
@@ -253,3 +272,179 @@ async function readLogs(logName = 'agent', lines = 100, level, session, since) {
253
272
  throw new Error(`Failed to read logs: ${err.message}`);
254
273
  }
255
274
  }
275
+ /**
276
+ * List all profiles
277
+ */
278
+ async function listProfiles() {
279
+ try {
280
+ const { stdout } = await execFileAsync('hermes', ['profile', 'list'], {
281
+ timeout: 10000,
282
+ ...execOpts,
283
+ });
284
+ const lines = stdout.trim().split('\n').filter(Boolean);
285
+ const profiles = [];
286
+ // Skip header lines (starts with " Profile" or " ─")
287
+ for (const line of lines) {
288
+ if (line.startsWith(' Profile') || line.match(/^ ─/))
289
+ continue;
290
+ const match = line.match(/^\s+(◆)?(\S+)\s{2,}(\S+)\s{2,}(\S+)\s{2,}(.*)$/);
291
+ if (match) {
292
+ profiles.push({
293
+ name: match[2],
294
+ active: !!match[1],
295
+ model: match[3],
296
+ gateway: match[4],
297
+ alias: match[5].trim() === '—' ? '' : match[5].trim(),
298
+ });
299
+ }
300
+ }
301
+ return profiles;
302
+ }
303
+ catch (err) {
304
+ console.error('[Hermes CLI] profile list failed:', err.message);
305
+ throw new Error(`Failed to list profiles: ${err.message}`);
306
+ }
307
+ }
308
+ /**
309
+ * Get profile details
310
+ */
311
+ async function getProfile(name) {
312
+ try {
313
+ const { stdout } = await execFileAsync('hermes', ['profile', 'show', name], {
314
+ timeout: 10000,
315
+ ...execOpts,
316
+ });
317
+ const result = {};
318
+ for (const line of stdout.trim().split('\n')) {
319
+ const match = line.match(/^(\w[\w\s]*?):\s+(.+)$/);
320
+ if (match) {
321
+ result[match[1].trim().toLowerCase().replace(/\s+/g, '_')] = match[2].trim();
322
+ }
323
+ }
324
+ const modelFull = result.model || '';
325
+ const providerMatch = modelFull.match(/\((.+)\)/);
326
+ const model = providerMatch ? modelFull.replace(/\s*\(.+\)/, '').trim() : modelFull;
327
+ return {
328
+ name: result.profile || name,
329
+ path: result.path || '',
330
+ model,
331
+ provider: providerMatch ? providerMatch[1] : '',
332
+ gateway: result.gateway || '',
333
+ skills: parseInt(result.skills || '0', 10),
334
+ hasEnv: result['.env'] === 'exists',
335
+ hasSoulMd: result.soul_md === 'exists',
336
+ };
337
+ }
338
+ catch (err) {
339
+ if (err.code === 1 || err.status === 1) {
340
+ throw new Error(`Profile "${name}" not found`);
341
+ }
342
+ console.error('[Hermes CLI] profile show failed:', err.message);
343
+ throw new Error(`Failed to get profile: ${err.message}`);
344
+ }
345
+ }
346
+ /**
347
+ * Create a new profile
348
+ */
349
+ async function createProfile(name, clone) {
350
+ const args = ['profile', 'create', name];
351
+ if (clone)
352
+ args.push('--clone');
353
+ try {
354
+ const { stdout, stderr } = await execFileAsync('hermes', args, {
355
+ timeout: 15000,
356
+ ...execOpts,
357
+ });
358
+ return stdout || stderr;
359
+ }
360
+ catch (err) {
361
+ console.error('[Hermes CLI] profile create failed:', err.message);
362
+ throw new Error(`Failed to create profile: ${err.message}`);
363
+ }
364
+ }
365
+ /**
366
+ * Delete a profile
367
+ */
368
+ async function deleteProfile(name) {
369
+ try {
370
+ await execFileAsync('hermes', ['profile', 'delete', name, '--yes'], {
371
+ timeout: 10000,
372
+ ...execOpts,
373
+ });
374
+ return true;
375
+ }
376
+ catch (err) {
377
+ console.error('[Hermes CLI] profile delete failed:', err.message);
378
+ return false;
379
+ }
380
+ }
381
+ /**
382
+ * Rename a profile
383
+ */
384
+ async function renameProfile(oldName, newName) {
385
+ try {
386
+ await execFileAsync('hermes', ['profile', 'rename', oldName, newName], {
387
+ timeout: 10000,
388
+ ...execOpts,
389
+ });
390
+ return true;
391
+ }
392
+ catch (err) {
393
+ console.error('[Hermes CLI] profile rename failed:', err.message);
394
+ return false;
395
+ }
396
+ }
397
+ /**
398
+ * Switch active profile
399
+ */
400
+ async function useProfile(name) {
401
+ try {
402
+ const { stdout, stderr } = await execFileAsync('hermes', ['profile', 'use', name], {
403
+ timeout: 10000,
404
+ ...execOpts,
405
+ });
406
+ return stdout || stderr;
407
+ }
408
+ catch (err) {
409
+ console.error('[Hermes CLI] profile use failed:', err.message);
410
+ throw new Error(`Failed to switch profile: ${err.message}`);
411
+ }
412
+ }
413
+ /**
414
+ * Export profile to archive
415
+ */
416
+ async function exportProfile(name, outputPath) {
417
+ const args = ['profile', 'export', name];
418
+ if (outputPath)
419
+ args.push('--output', outputPath);
420
+ try {
421
+ const { stdout, stderr } = await execFileAsync('hermes', args, {
422
+ timeout: 60000,
423
+ ...execOpts,
424
+ });
425
+ return stdout || stderr;
426
+ }
427
+ catch (err) {
428
+ console.error('[Hermes CLI] profile export failed:', err.message);
429
+ throw new Error(`Failed to export profile: ${err.message}`);
430
+ }
431
+ }
432
+ /**
433
+ * Import profile from archive
434
+ */
435
+ async function importProfile(archivePath, name) {
436
+ const args = ['profile', 'import', archivePath];
437
+ if (name)
438
+ args.push('--name', name);
439
+ try {
440
+ const { stdout, stderr } = await execFileAsync('hermes', args, {
441
+ timeout: 60000,
442
+ ...execOpts,
443
+ });
444
+ return stdout || stderr;
445
+ }
446
+ catch (err) {
447
+ console.error('[Hermes CLI] profile import failed:', err.message);
448
+ throw new Error(`Failed to import profile: ${err.message}`);
449
+ }
450
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hermes-web-ui",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "Web dashboard for Hermes Agent — multi-platform AI chat, session management, scheduled jobs, usage analytics & channel configuration (Telegram, Discord, Slack, WhatsApp)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,8 +33,8 @@
33
33
  "start": "vite --host --port 8648",
34
34
  "dev": "concurrently \"npm run dev:server\" \"npm run dev:client\"",
35
35
  "dev:client": "vite --host",
36
- "dev:server": "nodemon --signal SIGTERM --watch server/src -e ts,tsx --exec node -r ts-node/register server/src/index.ts",
37
- "build": "vue-tsc -b && vite build && tsc -p server/tsconfig.json",
36
+ "dev:server": "nodemon --signal SIGTERM --watch packages/server/src -e ts,tsx --exec node -r ts-node/register packages/server/src/index.ts",
37
+ "build": "vue-tsc -b && vite build && tsc -p packages/server/tsconfig.json",
38
38
  "preview": "vite preview"
39
39
  },
40
40
  "files": [
@@ -44,7 +44,7 @@
44
44
  "dependencies": {
45
45
  "@koa/bodyparser": "^5.0.0",
46
46
  "@koa/cors": "^5.0.0",
47
- "@koa/router": "^13.1.0",
47
+ "@koa/router": "^15.4.0",
48
48
  "@xterm/addon-fit": "^0.11.0",
49
49
  "@xterm/addon-web-links": "^0.12.0",
50
50
  "@xterm/xterm": "^6.0.0",
@@ -68,7 +68,7 @@
68
68
  "@types/js-yaml": "^4.0.9",
69
69
  "@types/koa": "^2.15.0",
70
70
  "@types/koa__cors": "^5.0.0",
71
- "@types/koa__router": "^12.0.4",
71
+ "@types/koa__router": "^12.0.5",
72
72
  "@types/koa-send": "^4.1.6",
73
73
  "@types/koa-static": "^4.0.4",
74
74
  "@types/markdown-it": "^14.1.2",
@@ -1 +0,0 @@
1
- .platform-card[data-v-ee5f4168]{background-color:#fff;border:1px solid #e0e0e0;border-radius:10px;margin-bottom:12px;overflow:hidden}.platform-card.configured[data-v-ee5f4168]{border-color:#2e7d3233}.platform-card-header[data-v-ee5f4168]{cursor:pointer;-webkit-user-select:none;user-select:none;justify-content:space-between;align-items:center;padding:12px 16px;display:flex}.platform-card-header[data-v-ee5f4168]:hover{background-color:#1a1a1a08}.platform-info[data-v-ee5f4168]{align-items:center;gap:10px;display:flex}.platform-icon[data-v-ee5f4168]{color:#666;flex-shrink:0;width:18px;height:18px}.platform-name[data-v-ee5f4168]{color:#1a1a1a;font-size:14px;font-weight:500}.expand-icon[data-v-ee5f4168]{color:#999;font-size:12px;transition:transform .2s}.expand-icon.expanded[data-v-ee5f4168]{transform:rotate(0)}.expand-icon[data-v-ee5f4168]:not(.expanded){transform:rotate(-90deg)}.platform-card-body[data-v-ee5f4168]{border-top:1px solid #ebebeb;padding:0 16px 12px}.settings-section[data-v-9f4c95ee]{margin-top:16px}.weixin-qr-section[data-v-9f4c95ee]{margin-top:12px;margin-bottom:12px}.weixin-qr-loading[data-v-9f4c95ee]{color:#999;align-items:center;gap:8px;font-size:13px;display:flex}.weixin-qr-hint[data-v-9f4c95ee]{color:#666;font-size:13px}.channels-view[data-v-099b0c1b]{height:calc(100 * var(--vh));flex-direction:column;display:flex}.channels-content[data-v-099b0c1b]{flex:1;padding:20px;position:relative;overflow-y:auto}
@@ -1 +0,0 @@
1
- .chat-input-area[data-v-474a732e]{border-top:1px solid #e0e0e0;flex-shrink:0;padding:12px 20px 16px}.attachment-previews[data-v-474a732e]{flex-wrap:wrap;gap:8px;padding:0 0 10px;display:flex}.attachment-preview[data-v-474a732e]{background-color:#f0f0f0;border:1px solid #e0e0e0;border-radius:6px;position:relative;overflow:hidden}.attachment-preview.image[data-v-474a732e]{width:64px;height:64px}.attachment-thumb[data-v-474a732e]{object-fit:cover;width:100%;height:100%}.attachment-file[data-v-474a732e]{color:#666;flex-direction:column;justify-content:center;align-items:center;gap:2px;min-width:80px;max-width:140px;padding:8px 12px;display:flex}.attachment-file .file-name[data-v-474a732e]{white-space:nowrap;text-overflow:ellipsis;max-width:100%;font-size:11px;overflow:hidden}.attachment-file .file-size[data-v-474a732e]{color:#999;font-size:10px}.attachment-remove[data-v-474a732e]{color:#fff;cursor:pointer;opacity:0;background:#00000080;border:none;border-radius:50%;justify-content:center;align-items:center;width:18px;height:18px;transition:opacity .15s;display:flex;position:absolute;top:2px;right:2px}.attachment-preview:hover .attachment-remove[data-v-474a732e]{opacity:1}.file-input-hidden[data-v-474a732e]{display:none}.input-wrapper[data-v-474a732e]{background-color:#fff;border:1px solid #e0e0e0;border-radius:10px;align-items:center;gap:10px;padding:10px 12px;transition:border-color .15s;display:flex}.input-wrapper[data-v-474a732e]:focus-within{border-color:#333}.input-textarea[data-v-474a732e]{color:#1a1a1a;resize:none;background:0 0;border:none;outline:none;flex:1;min-height:20px;max-height:100px;font-family:Inter,system-ui,-apple-system,sans-serif;font-size:14px;line-height:1.5;overflow-y:auto}.input-textarea[data-v-474a732e]::placeholder{color:#999;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.input-actions[data-v-474a732e]{flex-shrink:0;align-items:center;gap:6px;display:flex}.input-wrapper.drag-over[data-v-474a732e]{background-color:#4a90d90a;border-style:dashed;border-color:#4a90d9}.message[data-v-6d591bdc]{flex-direction:column;display:flex}.message.user[data-v-6d591bdc]{align-items:flex-end}.message.user .msg-body[data-v-6d591bdc]{max-width:75%}.message.user .msg-content.user[data-v-6d591bdc]{align-items:flex-end}.message.user .message-bubble[data-v-6d591bdc]{background-color:#e8e8e8;border-radius:10px 10px 4px}.message.assistant[data-v-6d591bdc]{flex-direction:row;align-items:flex-start;gap:8px}.message.assistant .msg-body[data-v-6d591bdc]{max-width:80%}.message.assistant .msg-avatar[data-v-6d591bdc]{flex-shrink:0;width:40px;height:40px;margin-top:2px}.message.assistant .message-bubble[data-v-6d591bdc]{background-color:#f5f5f5;border-radius:10px 10px 10px 4px}.message.tool[data-v-6d591bdc],.message.system[data-v-6d591bdc]{align-items:flex-start}.message.system .message-bubble.system[data-v-6d591bdc]{background-color:#f57f170f;border-left:3px solid #f57f17;border-radius:6px;max-width:80%}.msg-body[data-v-6d591bdc]{align-items:flex-start;gap:8px;max-width:85%;display:flex}.msg-content[data-v-6d591bdc]{flex-direction:column;min-width:0;display:flex}.message-bubble[data-v-6d591bdc]{word-break:break-word;padding:10px 14px;font-size:14px;line-height:1.65}.msg-attachments[data-v-6d591bdc]{flex-wrap:wrap;gap:8px;margin-bottom:8px;display:flex}.msg-attachment[data-v-6d591bdc]{background-color:#0000000a;border:1px solid #ebebeb;border-radius:6px;overflow:hidden}.msg-attachment.image[data-v-6d591bdc]{max-width:200px}.msg-attachment-thumb[data-v-6d591bdc]{object-fit:contain;max-width:200px;max-height:160px;display:block}.msg-attachment-file[data-v-6d591bdc]{color:#666;align-items:center;gap:6px;padding:6px 10px;font-size:12px;display:flex}.msg-attachment-file .att-name[data-v-6d591bdc]{white-space:nowrap;text-overflow:ellipsis;max-width:160px;overflow:hidden}.msg-attachment-file .att-size[data-v-6d591bdc]{color:#999;flex-shrink:0;font-size:11px}.message-time[data-v-6d591bdc]{color:#999;margin-top:4px;padding:0 4px;font-size:11px}.tool-line[data-v-6d591bdc]{color:#999;border-radius:6px;align-items:center;gap:6px;padding:2px 4px;font-size:11px;display:flex}.tool-line.expandable[data-v-6d591bdc]{cursor:pointer}.tool-line.expandable[data-v-6d591bdc]:hover{background:#00000008}.tool-line .tool-name[data-v-6d591bdc]{flex-shrink:0;font-family:JetBrains Mono,Fira Code,Consolas,monospace}.tool-line .tool-preview[data-v-6d591bdc]{text-overflow:ellipsis;white-space:nowrap;max-width:400px;overflow:hidden}.tool-chevron[data-v-6d591bdc]{flex-shrink:0;transition:transform .15s}.tool-chevron.rotated[data-v-6d591bdc]{transform:rotate(90deg)}.tool-spinner[data-v-6d591bdc]{border:1.5px solid #999;border-top-color:#0000;border-radius:50%;flex-shrink:0;width:10px;height:10px;animation:.6s linear infinite spin-6d591bdc}.tool-error-badge[data-v-6d591bdc]{color:#c62828;background:#c6282814;border-radius:3px;padding:0 4px;font-size:9px;line-height:14px}.tool-details[data-v-6d591bdc]{border-left:2px solid #ebebeb;margin-top:2px;margin-left:16px;padding-left:10px}.tool-detail-section[data-v-6d591bdc]{margin-bottom:6px}.tool-detail-label[data-v-6d591bdc]{color:#999;text-transform:uppercase;letter-spacing:.3px;margin-bottom:2px;font-size:10px;font-weight:600}.tool-detail-code[data-v-6d591bdc]{color:#666;white-space:pre-wrap;word-break:break-all;background:#f4f4f4;border-radius:6px;max-height:300px;margin:0;padding:6px 8px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:11px;line-height:1.5;overflow:auto}@keyframes spin-6d591bdc{to{transform:rotate(360deg)}}.streaming-cursor[data-v-6d591bdc]{vertical-align:text-bottom;background-color:#999;width:2px;height:1em;margin-left:2px;animation:.8s infinite blink-6d591bdc;display:inline-block}.streaming-dots[data-v-6d591bdc]{gap:4px;padding:4px 0;display:flex}.streaming-dots span[data-v-6d591bdc]{background-color:#999;border-radius:50%;width:6px;height:6px;animation:1.4s ease-in-out infinite pulse-6d591bdc}.streaming-dots span[data-v-6d591bdc]:nth-child(2){animation-delay:.2s}.streaming-dots span[data-v-6d591bdc]:nth-child(3){animation-delay:.4s}@keyframes blink-6d591bdc{0%,50%{opacity:1}51%,to{opacity:0}}@keyframes pulse-6d591bdc{0%,80%,to{opacity:.3;transform:scale(.8)}40%{opacity:1;transform:scale(1)}}@media (width<=768px){.message.user .msg-body[data-v-6d591bdc],.message.assistant .msg-body[data-v-6d591bdc],.message.system .msg-body[data-v-6d591bdc]{max-width:100%}}.message-list[data-v-21c7a8d2]{background-color:#fff;flex-direction:column;flex:1;gap:16px;padding:20px;display:flex;overflow-y:auto}.empty-state[data-v-21c7a8d2]{color:#999;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:12px;display:flex}.empty-state .empty-logo[data-v-21c7a8d2]{opacity:.25;width:48px;height:48px}.empty-state p[data-v-21c7a8d2]{font-size:14px}.fade-enter-active[data-v-21c7a8d2],.fade-leave-active[data-v-21c7a8d2]{transition:opacity .4s}.fade-enter-from[data-v-21c7a8d2],.fade-leave-to[data-v-21c7a8d2]{opacity:0}.streaming-indicator[data-v-21c7a8d2]{align-items:flex-start;gap:12px;padding:4px;display:flex}.streaming-indicator .thinking-video[data-v-21c7a8d2]{object-fit:contain;border-radius:10px;flex-shrink:0;width:120px;height:120px}.tool-calls-panel[data-v-21c7a8d2]{scrollbar-width:none;-ms-overflow-style:none;flex-direction:column;gap:4px;max-height:120px;padding-top:4px;display:flex;overflow-y:auto}.tool-calls-panel[data-v-21c7a8d2]::-webkit-scrollbar{display:none}.tool-call-item[data-v-21c7a8d2]{color:#666;background:#00000008;border-radius:6px;align-items:center;gap:6px;padding:3px 8px;font-size:11px;display:flex}.tool-call-item .tool-call-icon[data-v-21c7a8d2]{color:#999;flex-shrink:0}.tool-call-item .tool-call-name[data-v-21c7a8d2]{flex-shrink:0;font-family:JetBrains Mono,Fira Code,Consolas,monospace}.tool-call-item .tool-call-preview[data-v-21c7a8d2]{text-overflow:ellipsis;white-space:nowrap;color:#999;max-width:300px;overflow:hidden}.tool-call-spinner[data-v-21c7a8d2]{border:1.5px solid #999;border-top-color:#0000;border-radius:50%;flex-shrink:0;width:10px;height:10px;animation:.6s linear infinite spin-21c7a8d2}.tool-call-error[data-v-21c7a8d2]{color:#c62828;background:#c6282814;border-radius:3px;padding:0 4px;font-size:9px;line-height:14px}@keyframes spin-21c7a8d2{to{transform:rotate(360deg)}}.chat-panel[data-v-db5d0963]{height:100%;display:flex;position:relative}.session-list[data-v-db5d0963]{border-right:1px solid #e0e0e0;flex-direction:column;flex-shrink:0;width:220px;transition:width .25s,opacity .25s;display:flex;overflow:hidden}.session-list.collapsed[data-v-db5d0963]{opacity:0;pointer-events:none;border-right:none;width:0}@media (width<=768px){.session-list[data-v-db5d0963]{z-index:10;background:#fff;width:280px;height:100%;position:absolute;top:0;left:0;box-shadow:2px 0 8px #0000001a}.session-list.collapsed[data-v-db5d0963]{opacity:0;transform:translate(-100%)}.session-close-btn[data-v-db5d0963]{display:flex}.session-backdrop[data-v-db5d0963]{z-index:9;opacity:0;pointer-events:none;background:#0006;transition:opacity .15s;position:absolute;inset:0}.session-backdrop.active[data-v-db5d0963]{opacity:1;pointer-events:auto}}.session-list-header[data-v-db5d0963]{flex-shrink:0;justify-content:space-between;align-items:center;padding:12px;display:flex}.session-list-actions[data-v-db5d0963]{align-items:center;gap:4px;display:flex}.session-close-btn[data-v-db5d0963]{cursor:pointer;color:#666;background:0 0;border:none;border-radius:6px;padding:4px;display:none}.session-close-btn[data-v-db5d0963]:hover{background:#3333330f}.session-list-title[data-v-db5d0963]{color:#999;text-transform:uppercase;letter-spacing:.5px;font-size:12px;font-weight:600}.session-group-header[data-v-db5d0963]{cursor:pointer;-webkit-user-select:none;user-select:none;align-items:center;gap:4px;padding:6px 10px 4px;display:flex}.group-chevron[data-v-db5d0963]{flex-shrink:0;transition:transform .15s;transform:rotate(90deg)}.group-chevron.collapsed[data-v-db5d0963]{transform:rotate(0)}.session-group-label[data-v-db5d0963]{color:#999;text-transform:uppercase;letter-spacing:.5px;font-size:10px;font-weight:600}.session-group-count[data-v-db5d0963]{color:#999;font-size:10px;font-weight:400}.session-items[data-v-db5d0963]{flex:1;padding:0 6px 12px;overflow-y:auto}.session-loading[data-v-db5d0963],.session-empty[data-v-db5d0963]{color:#999;text-align:center;padding:16px 10px;font-size:12px}.session-item[data-v-db5d0963]{cursor:pointer;text-align:left;color:#666;background:0 0;border:none;border-radius:6px;justify-content:space-between;align-items:center;width:100%;margin-bottom:2px;padding:8px 10px;transition:all .15s;display:flex}.session-item[data-v-db5d0963]:hover{color:#1a1a1a;background:#3333330f}.session-item:hover .session-item-delete[data-v-db5d0963]{opacity:1}.session-item.active[data-v-db5d0963]{color:#1a1a1a;background:#3333331a;font-weight:500}.session-item-content[data-v-db5d0963]{flex:1;overflow:hidden}.session-item-title[data-v-db5d0963]{white-space:nowrap;text-overflow:ellipsis;font-size:13px;display:block;overflow:hidden}.session-item-time[data-v-db5d0963]{color:#999;font-size:11px}.session-item-meta[data-v-db5d0963]{align-items:center;gap:6px;margin-top:2px;display:flex}.session-item-model[data-v-db5d0963]{color:#333;text-overflow:ellipsis;white-space:nowrap;background:#33333314;border-radius:3px;flex-shrink:0;max-width:100px;padding:0 5px;font-size:10px;line-height:16px;overflow:hidden}.session-item-delete[data-v-db5d0963]{opacity:.5;color:#999;cursor:pointer;background:0 0;border:none;border-radius:3px;flex-shrink:0;padding:2px;transition:all .15s}.session-item-delete[data-v-db5d0963]:hover{color:#c62828;background:#c628281a}.chat-main[data-v-db5d0963]{flex-direction:column;flex:1;min-width:0;display:flex;overflow:hidden}.chat-header[data-v-db5d0963]{border-bottom:1px solid #e0e0e0;flex-shrink:0;justify-content:space-between;align-items:center;padding:21px 20px;display:flex}.header-left[data-v-db5d0963]{flex:1;align-items:center;gap:8px;min-width:0;display:flex;overflow:hidden}.header-session-title[data-v-db5d0963]{color:#1a1a1a;white-space:nowrap;text-overflow:ellipsis;font-size:16px;font-weight:600;overflow:hidden}.source-badge[data-v-db5d0963]{color:#999;white-space:nowrap;background:#9999991f;border-radius:8px;flex-shrink:0;padding:1px 7px;font-size:10px;line-height:16px}.header-actions[data-v-db5d0963]{flex-shrink:0;align-items:center;gap:4px;display:flex}.context-info[data-v-db5d0963]{color:#999;flex-shrink:0;padding:0 20px 4px;font-size:11px}@media (width<=768px){.chat-header[data-v-db5d0963]{padding:16px 12px 16px 52px}.context-info[data-v-db5d0963]{padding:0 12px 4px}}.chat-view[data-v-9db9ee3f]{height:calc(100 * var(--vh));flex-direction:column;display:flex}
@@ -1 +0,0 @@
1
- .job-card[data-v-7c84751f]{background-color:#fff;border:1px solid #e0e0e0;border-radius:10px;padding:16px;transition:border-color .15s}.job-card[data-v-7c84751f]:hover{border-color:#3333334d}.card-header[data-v-7c84751f]{justify-content:space-between;align-items:center;margin-bottom:12px;display:flex}.job-name[data-v-7c84751f]{color:#1a1a1a;text-overflow:ellipsis;white-space:nowrap;max-width:70%;font-size:15px;font-weight:600;overflow:hidden}.status-badge[data-v-7c84751f]{border-radius:10px;padding:2px 8px;font-size:11px;font-weight:500}.status-badge.success[data-v-7c84751f]{color:#2e7d32;background:#2e7d321f}.status-badge.info[data-v-7c84751f]{color:#333;background:#3333331f}.status-badge.warning[data-v-7c84751f]{color:#f57f17;background:#f57f171f}.status-badge.error[data-v-7c84751f]{color:#c62828;background:#c628281f}.card-body[data-v-7c84751f]{flex-direction:column;gap:6px;margin-bottom:14px;display:flex}.info-row[data-v-7c84751f]{justify-content:space-between;align-items:center;display:flex}.info-label[data-v-7c84751f]{color:#999;font-size:12px}.info-value[data-v-7c84751f]{color:#666;font-size:12px}.run-status[data-v-7c84751f]{margin-left:6px;font-size:11px;font-weight:500}.run-status.ok[data-v-7c84751f]{color:#2e7d32}.run-status.err[data-v-7c84751f]{color:#c62828}.mono[data-v-7c84751f]{font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:12px}.card-actions[data-v-7c84751f]{border-top:1px solid #ebebeb;gap:4px;padding-top:10px;display:flex}.empty-state[data-v-b91b48f7]{color:#999;flex-direction:column;justify-content:center;align-items:center;gap:12px;height:100%;display:flex}.empty-state .empty-icon[data-v-b91b48f7]{opacity:.3}.empty-state p[data-v-b91b48f7]{font-size:14px}.jobs-grid[data-v-b91b48f7]{grid-template-columns:repeat(auto-fill,minmax(min(100%,360px),1fr));gap:14px;display:grid}.modal-footer[data-v-1cf63c17]{justify-content:flex-end;gap:8px;display:flex}.jobs-view[data-v-3d9d3ab7]{height:calc(100 * var(--vh));flex-direction:column;display:flex}.jobs-content[data-v-3d9d3ab7]{flex:1;padding:20px;overflow-y:auto}
@@ -1 +0,0 @@
1
- .login-view[data-v-c7ba61be]{height:calc(100 * var(--vh));background:#fafafa;justify-content:center;align-items:center;display:flex}.login-card[data-v-c7ba61be]{text-align:center;background:#fff;border:1px solid #e0e0e0;border-radius:14px;width:480px;max-width:calc(100vw - 32px);padding:56px}@media (width<=768px){.login-card[data-v-c7ba61be]{padding:32px 24px}}.login-logo[data-v-c7ba61be]{margin-bottom:24px}.login-title[data-v-c7ba61be]{color:#1a1a1a;margin:0 0 10px;font-size:26px;font-weight:600}.login-desc[data-v-c7ba61be]{color:#999;margin:0 0 40px;font-size:14px;line-height:1.6}.login-form[data-v-c7ba61be]{flex-direction:column;gap:14px;display:flex}.login-input[data-v-c7ba61be]{color:#1a1a1a;box-sizing:border-box;background:#fff;border:1px solid #e0e0e0;border-radius:6px;outline:none;width:100%;padding:14px 16px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:15px;transition:border-color .15s}.login-input[data-v-c7ba61be]::placeholder{color:#999}.login-input[data-v-c7ba61be]:focus{border-color:#333}.login-error[data-v-c7ba61be]{color:#c62828;text-align:left;font-size:13px}.login-btn[data-v-c7ba61be]{color:#fff;cursor:pointer;background:#1a1a1a;border:none;border-radius:6px;width:100%;padding:14px;font-size:15px;font-weight:500;transition:opacity .15s}.login-btn[data-v-c7ba61be]:hover{opacity:.85}.login-btn[data-v-c7ba61be]:disabled{opacity:.5;cursor:not-allowed}
@@ -1 +0,0 @@
1
- import{$ as e,D as t,E as n,G as r,_ as i,a,ct as o,gt as s,j as c,l,m as u,pt as d,s as f,w as p}from"./router-CpYvE976.js";import{r as m,t as h}from"./_plugin-vue_export-helper-NLzeiXdV.js";import"./logo-Cd-t_oGE.js";var g={class:`login-view`},_={class:`login-card`},v={class:`login-title`},y={class:`login-desc`},b=[`placeholder`],x={key:0,class:`login-error`},S=[`disabled`],C=h(c({__name:`LoginView`,setup(c){let{t:h}=m(),C=l(),w=o(window.__LOGIN_TOKEN__||``),T=o(!1),E=o(``);a()&&C.replace(`/chat`);async function D(){let e=w.value.trim();if(!e){E.value=h(`login.tokenRequired`);return}T.value=!0,E.value=``;try{if((await fetch(`/api/sessions`,{headers:{Authorization:`Bearer ${e}`}})).status===401){E.value=h(`login.invalidToken`),T.value=!1;return}f(e),C.replace(`/chat`)}catch{E.value=h(`login.connectionFailed`)}finally{T.value=!1}}return(a,o)=>(r(),t(`div`,g,[p(`div`,_,[o[1]||=p(`div`,{class:`login-logo`},[p(`img`,{src:`/logo.png`,alt:`Hermes`,width:`80`,height:`80`})],-1),p(`h1`,v,s(d(h)(`login.title`)),1),p(`p`,y,s(d(h)(`login.description`)),1),p(`form`,{class:`login-form`,onSubmit:i(D,[`prevent`])},[e(p(`input`,{"onUpdate:modelValue":o[0]||=e=>w.value=e,type:`password`,class:`login-input`,placeholder:d(h)(`login.placeholder`),autofocus:``},null,8,b),[[u,w.value]]),E.value?(r(),t(`div`,x,s(E.value),1)):n(``,!0),p(`button`,{type:`submit`,class:`login-btn`,disabled:T.value},s(T.value?`...`:d(h)(`login.submit`)),9,S)],32)])]))}}),[[`__scopeId`,`data-v-c7ba61be`]]);export{C as default};
@@ -1 +0,0 @@
1
- .logs-view[data-v-08b66b21]{height:calc(100 * var(--vh));flex-direction:column;display:flex}.page-header[data-v-08b66b21]{flex-wrap:wrap;gap:12px}.header-actions[data-v-08b66b21]{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.search-input[data-v-08b66b21]{color:#1a1a1a;background:#fff;border:1px solid #e0e0e0;border-radius:6px;outline:none;width:160px;padding:4px 10px;font-size:13px;transition:border-color .15s}.search-input[data-v-08b66b21]:focus{border-color:#333}.search-input[data-v-08b66b21]::placeholder{color:#999}.logs-body[data-v-08b66b21]{flex:1;min-height:0;overflow-y:auto}.logs-empty[data-v-08b66b21]{color:#999;justify-content:center;align-items:center;height:100%;font-size:13px;display:flex}.log-list[data-v-08b66b21]{padding:4px 0}.log-entry[data-v-08b66b21]{border-left:2px solid #0000;align-items:center;gap:8px;padding:3px 20px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:12px;line-height:1.6;display:flex}.log-entry[data-v-08b66b21]:hover{background-color:#33333308}.log-entry.level-error[data-v-08b66b21]{border-left-color:#c62828}.log-entry.level-error .log-message[data-v-08b66b21]{color:#c62828}.log-entry.level-warning[data-v-08b66b21]{border-left-color:#f57f17}.log-entry.level-warning .log-message[data-v-08b66b21]{color:#d9720f}.log-time[data-v-08b66b21]{color:#999;font-variant-numeric:tabular-nums;flex-shrink:0}.log-level[data-v-08b66b21]{text-align:center;border-radius:2px;flex-shrink:0;min-width:42px;padding:0 4px;font-size:10px;font-weight:600}.log-level.level-error[data-v-08b66b21]{color:#c62828;background:#c628281f}.log-level.level-warning[data-v-08b66b21]{color:#d9720f;background:#f57f171f}.log-level.level-debug[data-v-08b66b21],.log-level.level-info[data-v-08b66b21]{color:#999;background:#3333330f}.log-logger[data-v-08b66b21]{color:#999;text-overflow:ellipsis;white-space:nowrap;flex-shrink:0;max-width:160px;overflow:hidden}.log-message[data-v-08b66b21]{color:#666;text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.access-method[data-v-08b66b21]{color:#1a1a1a;flex-shrink:0;font-weight:600}.access-path[data-v-08b66b21]{color:#333;text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.access-status[data-v-08b66b21]{flex-shrink:0;font-size:11px;font-weight:600}.access-status.status-2[data-v-08b66b21]{color:#2e7d32}.access-status.status-3[data-v-08b66b21]{color:#f57f17}.access-status.status-4[data-v-08b66b21],.access-status.status-5[data-v-08b66b21]{color:#c62828}
@@ -1 +0,0 @@
1
- import{$ as e,A as t,C as n,D as r,E as ee,G as i,Q as a,U as o,ct as s,gt as c,j as l,k as u,m as d,mt as f,o as p,pt as m,q as h,w as g,y as _}from"./router-CpYvE976.js";import{r as v,t as y}from"./_plugin-vue_export-helper-NLzeiXdV.js";import{t as b}from"./Select-DLECSo9D.js";import{t as x}from"./Button-BHvh9zmj.js";import{t as S}from"./use-message-17mZlZe3.js";import{t as C}from"./Spin-BbbA3R-G.js";async function w(){return(await p(`/api/logs`)).files}async function T(e,t){let n=new URLSearchParams;t?.lines&&n.set(`lines`,String(t.lines)),t?.level&&n.set(`level`,t.level),t?.session&&n.set(`session`,t.session),t?.since&&n.set(`since`,t.since);let r=n.toString();return(await p(`/api/logs/${e}${r?`?${r}`:``}`)).entries.filter(e=>e!==null)}var E={class:`logs-view`},D={class:`page-header`},O={class:`header-title`},k={class:`header-actions`},A=[`placeholder`],j={class:`logs-body`},M={key:0,class:`logs-empty`},N={class:`log-list`},P={class:`log-time`},F={class:`log-logger`},I={class:`access-method`},L={class:`access-path`},R={key:1,class:`log-message`},z=y(l({__name:`LogsView`,setup(l){let{t:p}=v(),y=S(),z=s([]),B=s(`agent`),V=s([]),H=s(!1),U=s(100),W=s(``),G=s(``),K=n(()=>z.value.map(e=>({label:`${e.name} (${e.size})`,value:e.name}))),q=n(()=>[{label:p(`logs.all`),value:``},{label:`ERROR`,value:`ERROR`},{label:`WARNING`,value:`WARNING`},{label:`INFO`,value:`INFO`},{label:`DEBUG`,value:`DEBUG`}]),J=[{label:`50`,value:50},{label:`100`,value:100},{label:`200`,value:200},{label:`500`,value:500}],Y=n(()=>{if(!G.value)return V.value;let e=G.value.toLowerCase();return V.value.filter(t=>t.message.toLowerCase().includes(e)||t.logger.toLowerCase().includes(e)||t.raw.toLowerCase().includes(e))});function X(e){switch(e){case`ERROR`:return`level-error`;case`WARNING`:return`level-warning`;case`DEBUG`:return`level-debug`;default:return`level-info`}}function Z(e){let t=e.match(/\d{2}:\d{2}:\d{2}/);return t?t[0]:e}function Q(e){let t=e.match(/"(\w+)\s+(\S+)\s+HTTP\/[^"]+"\s+(\d+)/);return t?{method:t[1],path:t[2],status:t[3]}:null}async function $(){H.value=!0;try{V.value=(await T(B.value,{lines:U.value,level:W.value||void 0})).filter(e=>e!==null)}catch(e){y.error(e.message)}finally{H.value=!1}}return o(async()=>{z.value=await w(),await $()}),(n,o)=>(i(),r(`div`,E,[g(`header`,D,[g(`h2`,O,c(m(p)(`logs.title`)),1),g(`div`,k,[t(m(b),{value:B.value,"onUpdate:value":[o[0]||=e=>B.value=e,$],options:K.value,size:`small`,class:`input-md`},null,8,[`value`,`options`]),t(m(b),{value:W.value,options:q.value,size:`small`,class:`input-sm`,"onUpdate:value":o[1]||=e=>{W.value=e,$()}},null,8,[`value`,`options`]),t(m(b),{value:U.value,options:J,size:`small`,class:`input-sm`,"onUpdate:value":o[2]||=e=>{U.value=e,$()}},null,8,[`value`]),e(g(`input`,{"onUpdate:modelValue":o[3]||=e=>G.value=e,class:`search-input`,placeholder:m(p)(`logs.searchPlaceholder`)},null,8,A),[[d,G.value]]),t(m(x),{size:`small`,loading:H.value,onClick:$},{default:a(()=>[u(c(m(p)(`logs.refresh`)),1)]),_:1},8,[`loading`])])]),g(`div`,j,[t(m(C),{show:H.value},{default:a(()=>[Y.value.length===0&&!H.value?(i(),r(`div`,M,c(m(p)(`logs.noEntries`)),1)):ee(``,!0),g(`div`,N,[(i(!0),r(_,null,h(Y.value,(e,t)=>(i(),r(`div`,{key:t,class:f([`log-entry`,X(e.level)])},[g(`span`,P,c(Z(e.timestamp)),1),g(`span`,{class:f([`log-level`,X(e.level)])},c(e.level),3),g(`span`,F,c(e.logger),1),Q(e.message)?(i(),r(_,{key:0},[g(`span`,I,c(Q(e.message).method),1),g(`span`,L,c(Q(e.message).path),1),g(`span`,{class:f([`access-status`,`status-`+(Q(e.message).status?.[0]||`x`)])},c(Q(e.message).status),3)],64)):(i(),r(`span`,R,c(e.message),1))],2))),128))])]),_:1},8,[`show`])])]))}}),[[`__scopeId`,`data-v-08b66b21`]]);export{z as default};
@@ -1 +0,0 @@
1
- .memory-view[data-v-3ae22194]{height:calc(100 * var(--vh));flex-direction:column;display:flex}.memory-content[data-v-3ae22194]{flex-direction:column;flex:1;padding:20px;display:flex;overflow:hidden}.memory-loading[data-v-3ae22194]{color:#999;flex:1;justify-content:center;align-items:center;font-size:13px;display:flex}.memory-sections[data-v-3ae22194]{flex:1;gap:16px;min-height:0;display:flex}@media (width<=768px){.memory-sections[data-v-3ae22194]{flex-direction:column}}.memory-section[data-v-3ae22194]{border:1px solid #e0e0e0;border-radius:10px;flex-direction:column;flex:1;min-height:0;display:flex;overflow:hidden}.section-header[data-v-3ae22194]{background:#f0f0f0;border-bottom:1px solid #e0e0e0;flex-shrink:0;justify-content:space-between;align-items:center;padding:10px 16px;display:flex}.section-title-row[data-v-3ae22194]{align-items:center;gap:8px;display:flex}.section-icon[data-v-3ae22194]{color:#666;display:flex}.section-title[data-v-3ae22194]{color:#1a1a1a;font-size:14px;font-weight:600}.section-mtime[data-v-3ae22194]{color:#999;font-size:11px}.section-body[data-v-3ae22194]{flex:1;min-height:0;padding:16px;overflow-y:auto}.empty-text[data-v-3ae22194]{color:#999;font-size:13px;font-style:italic}.section-edit[data-v-3ae22194]{flex-direction:column;flex:1;min-height:0;padding:12px 16px;display:flex}.edit-textarea[data-v-3ae22194]{color:#1a1a1a;resize:none;background:#fff;border:1px solid #e0e0e0;border-radius:6px;outline:none;flex:1;width:100%;min-height:0;padding:12px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:13px;line-height:1.6}.edit-textarea[data-v-3ae22194]:focus{border-color:#333}.edit-actions[data-v-3ae22194]{justify-content:flex-end;gap:8px;margin-top:10px;display:flex}
@@ -1 +0,0 @@
1
- .provider-card[data-v-f94097d9]{background-color:#fff;border:1px solid #e0e0e0;border-radius:10px;padding:16px;transition:border-color .15s}.provider-card[data-v-f94097d9]:hover{border-color:#3333334d}.card-header[data-v-f94097d9]{justify-content:space-between;align-items:center;margin-bottom:12px;display:flex}.provider-name[data-v-f94097d9]{color:#1a1a1a;text-overflow:ellipsis;white-space:nowrap;max-width:70%;font-size:15px;font-weight:600;overflow:hidden}.type-badge[data-v-f94097d9]{border-radius:10px;padding:2px 8px;font-size:11px;font-weight:500}.type-badge.builtin[data-v-f94097d9]{color:#333;background:#3333331f}.type-badge.custom[data-v-f94097d9]{color:#2e7d32;background:#2e7d321f}.card-body[data-v-f94097d9]{flex-direction:column;gap:6px;margin-bottom:14px;display:flex}.info-row[data-v-f94097d9]{justify-content:space-between;align-items:center;display:flex}.info-label[data-v-f94097d9]{color:#999;font-size:12px}.info-value[data-v-f94097d9]{color:#666;font-size:12px}.mono[data-v-f94097d9]{font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:12px}.card-actions[data-v-f94097d9]{border-top:1px solid #ebebeb;gap:8px;padding-top:10px;display:flex}.empty-state[data-v-4dc0782f]{color:#999;flex-direction:column;justify-content:center;align-items:center;gap:12px;height:100%;display:flex}.empty-state .empty-icon[data-v-4dc0782f]{opacity:.3}.empty-state p[data-v-4dc0782f]{font-size:14px}.providers-grid[data-v-4dc0782f]{grid-template-columns:repeat(auto-fill,minmax(min(100%,420px),1fr));gap:14px;display:grid}.modal-footer[data-v-07ab2f92]{justify-content:flex-end;gap:8px;display:flex}.models-view[data-v-03cb44c1]{height:calc(100 * var(--vh));flex-direction:column;display:flex}.models-content[data-v-03cb44c1]{flex:1;padding:20px;overflow-y:auto}
@@ -1 +0,0 @@
1
- import{D as e,E as t,G as n,J as r,ct as i,gt as a,j as o,o as s,w as c}from"./router-CpYvE976.js";import{n as l}from"./pinia-DKSOddVw.js";import{t as u}from"./_plugin-vue_export-helper-NLzeiXdV.js";async function d(e){return s(`/api/config${e?`?sections=${e.join(`,`)}`:``}`)}async function f(e,t){await s(`/api/config`,{method:`PUT`,body:JSON.stringify({section:e,values:t})})}async function p(e,t){await s(`/api/config/credentials`,{method:`PUT`,body:JSON.stringify({platform:e,values:t})})}async function m(){return s(`/api/weixin/qrcode`)}async function h(e){return s(`/api/weixin/qrcode/status?qrcode=${encodeURIComponent(e)}`)}async function g(e){await s(`/api/weixin/save`,{method:`POST`,body:JSON.stringify(e)})}var _=l(`settings`,()=>{let e=i(!1),t=i(!1),n=i({}),r=i({}),a=i({}),o=i({}),s=i({}),c=i({}),l=i({}),u=i({}),p=i({}),m=i({}),h=i({}),g=i({}),_=i({}),v=i({}),y=i({});async function b(){e.value=!0;try{let e=await d();n.value=e.display||{},r.value=e.agent||{},a.value=e.memory||{},o.value=e.session_reset||{},s.value=e.privacy||{},c.value=e.telegram||{},l.value=e.discord||{},u.value=e.slack||{},p.value=e.whatsapp||{},m.value=e.matrix||{},h.value=e.wecom||{},g.value=e.feishu||{},_.value=e.dingtalk||{},v.value=e.weixin||{},y.value=e.platforms||{}}catch(e){console.error(`Failed to fetch settings:`,e)}finally{e.value=!1}}async function x(e,i){t.value=!0;try{switch(await f(e,i),e){case`display`:n.value={...n.value,...i};break;case`agent`:r.value={...r.value,...i};break;case`memory`:a.value={...a.value,...i};break;case`session_reset`:o.value={...o.value,...i};break;case`privacy`:s.value={...s.value,...i};break;case`telegram`:c.value={...c.value,...i};break;case`discord`:l.value={...l.value,...i};break;case`slack`:u.value={...u.value,...i};break;case`whatsapp`:p.value={...p.value,...i};break;case`matrix`:m.value={...m.value,...i};break;case`wechat`:case`wecom`:h.value={...h.value,...i};break;case`feishu`:g.value={...g.value,...i};break;case`dingtalk`:_.value={..._.value,...i};break;case`weixin`:v.value={...v.value,...i};break;case`platforms`:for(let[e,t]of Object.entries(i))y.value={...y.value,[e]:{...y.value[e]||{},...t}};break}}finally{t.value=!1}}return{loading:e,saving:t,display:n,agent:r,memory:a,sessionReset:o,privacy:s,telegram:c,discord:l,slack:u,whatsapp:p,matrix:m,wecom:h,feishu:g,dingtalk:_,weixin:v,platforms:y,fetchSettings:b,saveSection:x}}),v={class:`setting-row`},y={class:`setting-info`},b={class:`setting-label`},x={key:0,class:`setting-hint`},S={class:`setting-control`},C=u(o({__name:`SettingRow`,props:{label:{},hint:{}},setup(i){return(o,s)=>(n(),e(`div`,v,[c(`div`,y,[c(`label`,b,a(i.label),1),i.hint?(n(),e(`p`,x,a(i.hint),1)):t(``,!0)]),c(`div`,S,[r(o.$slots,`default`,{},void 0,!0)])]))}}),[[`__scopeId`,`data-v-7cdf9827`]]);export{p as a,h as i,_ as n,g as o,m as r,C as t};
@@ -1 +0,0 @@
1
- .setting-row[data-v-7cdf9827]{border-bottom:1px solid #ebebeb;justify-content:space-between;align-items:center;padding:10px 0;display:flex}.setting-row[data-v-7cdf9827]:last-child{border-bottom:none}.setting-info[data-v-7cdf9827]{flex:1;margin-right:16px}.setting-label[data-v-7cdf9827]{color:#1a1a1a;font-size:13px;display:block}.setting-hint[data-v-7cdf9827]{color:#999;margin-top:2px;font-size:12px}.setting-control[data-v-7cdf9827]{flex-shrink:0}@media (width<=768px){.setting-row[data-v-7cdf9827]{flex-direction:column;align-items:flex-start;gap:8px}.setting-info[data-v-7cdf9827]{margin-right:0}.setting-control[data-v-7cdf9827]{width:100%}}
@@ -1 +0,0 @@
1
- .settings-section[data-v-c8db8205],.settings-section[data-v-ef76d803],.settings-section[data-v-0dfe4428],.settings-section[data-v-b7d98a60],.settings-section[data-v-eecbcbf4]{margin-top:16px}.settings-view[data-v-8aa15ebe]{height:calc(100 * var(--vh));flex-direction:column;display:flex}.settings-content[data-v-8aa15ebe]{flex:1;padding:20px;overflow-y:auto}
@@ -1 +0,0 @@
1
- .skill-list[data-v-242ac691]{flex:1;padding:8px;overflow-y:auto}.skill-empty[data-v-242ac691]{color:#999;text-align:center;padding:24px 16px;font-size:13px}.skill-category[data-v-242ac691]{margin-bottom:4px}.category-header[data-v-242ac691]{color:#666;text-transform:uppercase;letter-spacing:.3px;cursor:pointer;background:0 0;border:none;border-radius:6px;align-items:center;gap:6px;width:100%;padding:6px 10px;font-size:12px;font-weight:600;display:flex}.category-header[data-v-242ac691]:hover{background:#3333330a}.category-arrow[data-v-242ac691]{flex-shrink:0;transition:transform .15s}.category-arrow.collapsed[data-v-242ac691]{transform:rotate(-90deg)}.category-name[data-v-242ac691]{text-align:left;text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.category-count[data-v-242ac691]{color:#999;background:#3333330f;border-radius:8px;padding:1px 6px;font-size:11px}.category-skills[data-v-242ac691]{padding:2px 0 4px}.skill-item[data-v-242ac691]{color:#666;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:6px;flex-direction:row;align-items:center;gap:8px;width:100%;padding:6px 10px 6px 28px;font-size:13px;transition:all .15s;display:flex}.skill-item[data-v-242ac691]:hover{color:#1a1a1a;background:#3333330f}.skill-item.active[data-v-242ac691]{color:#1a1a1a;background:#3333331a;font-weight:500}.skill-info[data-v-242ac691]{flex-direction:column;flex:1;min-width:0;display:flex}.skill-name[data-v-242ac691]{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.skill-desc[data-v-242ac691]{color:#999;white-space:nowrap;text-overflow:ellipsis;margin-top:1px;font-size:11px;overflow:hidden}.skill-detail[data-v-b84bbe48]{flex-direction:column;height:100%;display:flex}.detail-title[data-v-b84bbe48]{border-bottom:1px solid #e0e0e0;flex-shrink:0;margin-bottom:12px;padding-bottom:12px;font-size:15px}.detail-category[data-v-b84bbe48]{color:#999;font-size:13px}.detail-separator[data-v-b84bbe48]{color:#999;margin:0 6px}.detail-name[data-v-b84bbe48]{color:#1a1a1a;font-weight:600}.detail-loading[data-v-b84bbe48]{color:#999;flex:1;justify-content:center;align-items:center;font-size:13px;display:flex}.detail-breadcrumb[data-v-b84bbe48]{border-bottom:1px solid #e0e0e0;flex-shrink:0;align-items:center;gap:8px;margin-bottom:12px;padding:8px 0 12px;display:flex}.back-btn[data-v-b84bbe48]{color:#333;cursor:pointer;background:0 0;border:none;border-radius:4px;align-items:center;gap:4px;padding:2px 6px;font-size:13px;display:flex}.back-btn[data-v-b84bbe48]:hover{background:#3333330f}.breadcrumb-path[data-v-b84bbe48]{color:#999;font-size:13px}.detail-content[data-v-b84bbe48]{flex:1;min-height:0;padding-bottom:12px;overflow-y:auto}.detail-content[data-v-b84bbe48] hr{border:none;margin:12px 0}.detail-files[data-v-b84bbe48]{border-top:1px solid #e0e0e0;flex-shrink:0;margin-top:12px;padding-top:12px}.files-header[data-v-b84bbe48]{color:#999;text-transform:uppercase;letter-spacing:.3px;margin-bottom:6px;font-size:12px;font-weight:600}.files-list[data-v-b84bbe48]{flex-wrap:wrap;gap:4px;display:flex}.file-item[data-v-b84bbe48]{color:#666;cursor:pointer;background:#f0f0f0;border:1px solid #e0e0e0;border-radius:6px;align-items:center;gap:4px;padding:4px 8px;font-size:12px;transition:all .15s;display:flex}.file-item[data-v-b84bbe48]:hover{color:#333;border-color:#333}.skills-view[data-v-cb96a9e3]{height:calc(100 * var(--vh));flex-direction:column;display:flex}.search-input[data-v-cb96a9e3]{width:100px}@media (width<=768px){.search-input[data-v-cb96a9e3]{width:100%}}.skills-content[data-v-cb96a9e3]{flex:1;overflow:hidden}.skills-loading[data-v-cb96a9e3]{color:#999;justify-content:center;align-items:center;height:100%;font-size:13px;display:flex}.skills-layout[data-v-cb96a9e3]{height:100%;display:flex}.skills-sidebar[data-v-cb96a9e3]{border-right:1px solid #e0e0e0;flex-direction:column;flex-shrink:0;width:280px;min-height:0;display:flex;overflow:hidden}.skills-main[data-v-cb96a9e3]{flex:1;min-width:0;padding:16px 20px;overflow-y:auto}.sidebar-toggle[data-v-cb96a9e3]{cursor:pointer;color:#666;background:0 0;border:none;border-radius:6px;padding:4px;display:none}.sidebar-toggle[data-v-cb96a9e3]:hover{background:#3333330f}@media (width<=768px){.sidebar-toggle[data-v-cb96a9e3]{display:flex}.skills-sidebar[data-v-cb96a9e3]{z-index:10;background:#fff;height:100%;position:absolute;top:0;left:0;box-shadow:2px 0 8px #0000001a}.skills-layout[data-v-cb96a9e3]{position:relative}.mobile-backdrop[data-v-cb96a9e3]{z-index:9;opacity:0;pointer-events:none;background:#0006;transition:opacity .15s;display:block;position:absolute;inset:0}.mobile-backdrop.active[data-v-cb96a9e3]{opacity:1;pointer-events:auto}}.empty-detail[data-v-cb96a9e3]{color:#999;flex-direction:column;justify-content:center;align-items:center;gap:12px;height:100%;font-size:13px;display:flex}
@@ -1 +0,0 @@
1
- .stat-cards[data-v-6260002e]{grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:20px;display:grid}.stat-card[data-v-6260002e]{background:#fff;border:1px solid #e0e0e0;border-radius:10px;padding:16px}.stat-label[data-v-6260002e]{color:#999;margin-bottom:6px;font-size:12px}.stat-value[data-v-6260002e]{color:#1a1a1a;font-size:22px;font-weight:600;line-height:1.2}.stat-sub[data-v-6260002e]{color:#999;margin-top:4px;font-size:11px}@media (width<=768px){.stat-cards[data-v-6260002e]{grid-template-columns:repeat(2,1fr)}}@media (width<=480px){.stat-cards[data-v-6260002e]{grid-template-columns:1fr}}.model-breakdown[data-v-26d187bc]{background:#fff;border:1px solid #e0e0e0;border-radius:10px;margin-bottom:20px;padding:16px}.section-title[data-v-26d187bc]{color:#666;margin:0 0 12px;font-size:13px;font-weight:600}.model-list[data-v-26d187bc]{flex-direction:column;gap:8px;display:flex}.model-row[data-v-26d187bc]{align-items:center;gap:10px;display:flex}.model-name[data-v-26d187bc]{color:#666;text-overflow:ellipsis;white-space:nowrap;flex-shrink:0;width:140px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:12px;overflow:hidden}.model-bar-wrap[data-v-26d187bc]{background:#f0f0f0;border-radius:3px;flex:1;height:16px;overflow:hidden}.model-bar[data-v-26d187bc]{background:#1a1a1a;border-radius:3px;min-width:2px;height:100%;transition:width .3s}.model-tokens[data-v-26d187bc]{color:#999;text-align:right;flex-shrink:0;width:60px;font-size:12px}.daily-trend[data-v-42ea27be]{background:#fff;border:1px solid #e0e0e0;border-radius:10px;padding:16px}.section-title[data-v-42ea27be]{color:#666;margin:0 0 12px;font-size:13px;font-weight:600}.bar-chart[data-v-42ea27be]{gap:2px;margin-bottom:16px;display:flex}.bar-col[data-v-42ea27be]{flex-direction:column;flex:1;align-items:center;min-width:0;display:flex}.bar-track[data-v-42ea27be]{background:#f0f0f0;border-radius:2px 2px 0 0;align-items:flex-end;width:100%;height:140px;display:flex}.bar-fill[data-v-42ea27be]{background:#1a1a1a;border-radius:2px 2px 0 0;width:100%;min-height:0;transition:height .3s}.bar-col[data-v-42ea27be]{position:relative}.bar-tooltip[data-v-42ea27be]{color:#fff;white-space:nowrap;z-index:10;pointer-events:none;background:#1a1a1a;border-radius:6px;padding:6px 10px;font-size:11px;display:none;position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%)}.bar-tooltip[data-v-42ea27be]:after{content:"";border:5px solid #0000;border-top-color:#1a1a1a;position:absolute;top:100%;left:50%;transform:translate(-50%)}.bar-col:hover .bar-tooltip[data-v-42ea27be]{display:block}.tooltip-date[data-v-42ea27be]{margin-bottom:2px;font-weight:600}.tooltip-row[data-v-42ea27be]{opacity:.85;font-size:10px;line-height:1.5}.bar-label[data-v-42ea27be]{display:none}.bar-dates[data-v-42ea27be]{color:#999;justify-content:space-between;margin-top:4px;margin-bottom:16px;font-size:10px;display:flex}.trend-table[data-v-42ea27be]{overflow-x:auto}table[data-v-42ea27be]{border-collapse:collapse;width:100%;font-size:12px}thead[data-v-42ea27be]{position:sticky;top:0}th[data-v-42ea27be]{text-align:left;color:#999;text-transform:uppercase;letter-spacing:.3px;background:#fff;border-bottom:1px solid #e0e0e0;padding:8px 10px;font-size:11px;font-weight:600}td[data-v-42ea27be]{color:#666;border-bottom:1px solid #ebebeb;padding:6px 10px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:11px}tr:last-child td[data-v-42ea27be]{border-bottom:none}.usage-view[data-v-e14e424d]{flex-direction:column;height:100%;display:flex}.usage-content[data-v-e14e424d]{scrollbar-width:none;-ms-overflow-style:none;flex:1;width:100%;max-width:960px;margin:0 auto;padding:20px;overflow-y:auto}.usage-content[data-v-e14e424d]::-webkit-scrollbar{display:none}.usage-loading[data-v-e14e424d],.usage-empty[data-v-e14e424d]{text-align:center;color:#999;padding:60px 0;font-size:14px}
@@ -1 +0,0 @@
1
- import{ct as e,o as t}from"./router-CpYvE976.js";import{n}from"./pinia-DKSOddVw.js";async function r(){return t(`/health`)}async function i(){return t(`/api/available-models`)}async function a(e){await t(`/api/config/model`,{method:`PUT`,body:JSON.stringify(e)})}async function o(e){await t(`/api/config/providers`,{method:`POST`,body:JSON.stringify(e)})}async function s(e){await t(`/api/config/providers/${encodeURIComponent(e)}`,{method:`DELETE`})}var c=n(`app`,()=>{let t=e(!1),n=e(!1),o=e(``),s=e([]),c=e(``),l=e(),u=e(!0),d=e(!0),f=e(4096);async function p(){try{let e=await r();n.value=e.status===`ok`,e.version&&(o.value=e.version)}catch{n.value=!1}}async function m(){try{let e=await i();s.value=e.groups,c.value=e.default}catch{}}async function h(e,t){try{let n=s.value.find(t=>t.models.includes(e));await a({default:e,provider:t||n?.provider||``}),c.value=e}catch(e){console.error(`Failed to switch model:`,e)}}function g(e=3e4){_(),p(),l.value=setInterval(p,e)}function _(){l.value&&=(clearInterval(l.value),void 0)}function v(){t.value=!t.value}function y(){t.value=!1}return{sidebarOpen:t,toggleSidebar:v,closeSidebar:y,connected:n,serverVersion:o,modelGroups:s,selectedModel:c,streamEnabled:u,sessionPersistence:d,maxTokens:f,checkConnection:p,loadModels:m,switchModel:h,startHealthPolling:g,stopHealthPolling:_}});export{a,s as i,o as n,i as r,c as t};
@@ -1 +0,0 @@
1
- import{t as e}from"./app-CQZfHgyy.js";export{e as useAppStore};
@@ -1,6 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/app-DeeNNd_a.js","assets/app-CQZfHgyy.js","assets/router-CpYvE976.js","assets/pinia-DKSOddVw.js"])))=>i.map(i=>d[i]);
2
- import{C as e,ct as t,i as n,n as r,o as i,r as a}from"./router-CpYvE976.js";import{n as o}from"./pinia-DKSOddVw.js";import{t as s}from"./app-CQZfHgyy.js";import{n as c,r as l,t as u}from"./sessions-DTV2WuAE.js";async function d(e){return i(`/v1/runs`,{method:`POST`,body:JSON.stringify(e)})}function f(e,t,r,i){let o=n(),s=a(),c=`${o}/v1/runs/${e}/events${s?`?token=${encodeURIComponent(s)}`:``}`,l=!1,u=new EventSource(c);return u.onmessage=e=>{if(!l)try{let n=JSON.parse(e.data);t(n),(n.event===`run.completed`||n.event===`run.failed`)&&(l=!0,u.close(),r())}catch{t({event:`message`,delta:e.data})}},u.onerror=()=>{l||(l=!0,u.close(),i(Error(`SSE connection error`)))},{abort:()=>{l||(l=!0,u.close())}}}function p(){return Date.now().toString(36)+Math.random().toString(36).slice(2,8)}async function m(e){if(e.length===0)return[];let t=new FormData;for(let n of e)n.file&&t.append(`file`,n.file,n.name);let n=await fetch(`/upload`,{method:`POST`,body:t});if(!n.ok)throw Error(`Upload failed: ${n.status}`);return(await n.json()).files}function h(e){let t=new Map,n=new Map;for(let r of e)if(r.role===`assistant`&&r.tool_calls)for(let e of r.tool_calls)e.id&&(e.function?.name&&t.set(e.id,e.function.name),e.function?.arguments&&n.set(e.id,e.function.arguments));let r=[];for(let i of e){if(i.role===`assistant`&&i.tool_calls?.length&&!i.content?.trim()){for(let e of i.tool_calls)r.push({id:String(i.id)+`_`+e.id,role:`tool`,content:``,timestamp:Math.round(i.timestamp*1e3),toolName:e.function?.name||`tool`,toolArgs:e.function?.arguments||void 0,toolStatus:`done`});continue}if(i.role===`tool`){let e=i.tool_call_id||``,a=i.tool_name||t.get(e)||`tool`,o=n.get(e)||void 0,s=``;if(i.content)try{let e=JSON.parse(i.content);s=e.url||e.title||e.preview||e.summary||``}catch{s=i.content.slice(0,80)}let c=r.findIndex(t=>t.role===`tool`&&t.toolName===a&&!t.toolResult&&t.id.includes(`_`+e));c!==-1&&r.splice(c,1),r.push({id:String(i.id),role:`tool`,content:``,timestamp:Math.round(i.timestamp*1e3),toolName:a,toolArgs:o,toolPreview:typeof s==`string`&&s.slice(0,100)||void 0,toolResult:i.content||void 0,toolStatus:`done`});continue}r.push({id:String(i.id),role:i.role,content:i.content||``,timestamp:Math.round(i.timestamp*1e3)})}return r}function g(e){return{id:e.id,title:e.title||``,source:e.source||void 0,messages:[],createdAt:Math.round(e.started_at*1e3),updatedAt:Math.round((e.ended_at||e.started_at)*1e3),model:e.model,provider:e.billing_provider||``,messageCount:e.message_count,inputTokens:e.input_tokens,outputTokens:e.output_tokens}}var _=o(`chat`,()=>{let n=`hermes_active_session`,i=t([]),a=t(localStorage.getItem(n)),o=t(new Map),_=e(()=>a.value!=null&&o.value.has(a.value)),v=t(!1),y=t(!1),b=t(null),x=e(()=>b.value?.messages||[]);async function S(){v.value=!0;try{i.value=(await l()).map(g);let e=a.value,t=e&&i.value.some(t=>t.id===e)?e:i.value[0]?.id;t&&await w(t)}catch(e){console.error(`Failed to load sessions:`,e)}finally{v.value=!1}}function C(){let e={id:p(),title:``,source:`api_server`,messages:[],createdAt:Date.now(),updatedAt:Date.now()};return i.value.unshift(e),e}async function w(e){if(a.value=e,localStorage.setItem(n,e),b.value=i.value.find(t=>t.id===e)||null,b.value&&b.value.messages.length===0){y.value=!0;try{let t=await c(e);if(t&&t.messages){let e=h(t.messages);if(b.value.messages=e,b.value.inputTokens=t.input_tokens,b.value.outputTokens=t.output_tokens,t.title)b.value.title=t.title;else{let t=e.find(e=>e.role===`user`);if(t){let e=t.content.slice(0,40);b.value.title=e+(t.content.length>40?`...`:``)}}}}catch(e){console.error(`Failed to load session messages:`,e)}finally{y.value=!1}}}function T(){if(_.value)return;let e=C();e.model=s().selectedModel||void 0,w(e.id)}async function E(e,t){if(b.value&&(b.value.model=e,b.value.provider=t||``,t)){let{useAppStore:n}=await r(async()=>{let{useAppStore:e}=await import(`./app-DeeNNd_a.js`);return{useAppStore:e}},__vite__mapDeps([0,1,2,3]));await n().switchModel(e,t)}}async function D(e){await u(e),i.value=i.value.filter(t=>t.id!==e),a.value===e&&(i.value.length>0?await w(i.value[0].id):w(C().id))}function O(e){return i.value.find(t=>t.id===e)?.messages||[]}function k(e,t){let n=i.value.find(t=>t.id===e);n&&n.messages.push(t)}function A(e,t,n){let r=i.value.find(t=>t.id===e);if(!r)return;let a=r.messages.findIndex(e=>e.id===t);a!==-1&&(r.messages[a]={...r.messages[a],...n})}function j(e){let t=i.value.find(t=>t.id===e);if(t){if(!t.title){let e=t.messages.find(e=>e.role===`user`);if(e){let n=e.attachments?.length?e.attachments.map(e=>e.name).join(`, `):e.content;t.title=n.slice(0,40)+(n.length>40?`...`:``)}}t.updatedAt=Date.now()}}async function M(e,t){if(!e.trim()&&!(t&&t.length>0)||_.value)return;b.value||w(C().id);let n=a.value;k(n,{id:p(),role:`user`,content:e.trim(),timestamp:Date.now(),attachments:t&&t.length>0?t:void 0}),j(n);try{let r=O(n).filter(e=>(e.role===`user`||e.role===`assistant`)&&e.content.trim()).map(e=>({role:e.role,content:e.content})),i=e.trim();if(t&&t.length>0){let e=(await m(t)).map(e=>`[File: ${e.name}](${e.path})`);i=i?i+`
3
-
4
- `+e.join(`
5
- `):e.join(`
6
- `)}let a=s(),c=b.value?.model||a.selectedModel,l=await d({input:i,conversation_history:r,session_id:n,model:c||void 0}),u=l.run_id||l.id;if(!u){k(n,{id:p(),role:`system`,content:`Error: startRun returned no run ID. Response: ${JSON.stringify(l)}`,timestamp:Date.now()});return}let h=()=>{o.value.delete(n)},g=f(u,e=>{switch(e.event){case`run.started`:break;case`message.delta`:{let t=O(n),r=t[t.length-1];r?.role===`assistant`&&r.isStreaming?r.content+=e.delta||``:k(n,{id:p(),role:`assistant`,content:e.delta||``,timestamp:Date.now(),isStreaming:!0});break}case`tool.started`:{let t=O(n),r=t[t.length-1];r?.isStreaming&&A(n,r.id,{isStreaming:!1}),k(n,{id:p(),role:`tool`,content:``,timestamp:Date.now(),toolName:e.tool||e.name,toolPreview:e.preview,toolStatus:`running`});break}case`tool.completed`:{let e=O(n).filter(e=>e.role===`tool`&&e.toolStatus===`running`);if(e.length>0){let t=e[e.length-1];A(n,t.id,{toolStatus:`done`})}break}case`run.completed`:{let e=O(n),t=e[e.length-1];t?.isStreaming&&A(n,t.id,{isStreaming:!1}),h(),j(n);break}case`run.failed`:{let t=O(n),r=t[t.length-1];r?.isStreaming?A(n,r.id,{isStreaming:!1,content:e.error?`Error: ${e.error}`:`Run failed`,role:`system`}):k(n,{id:p(),role:`system`,content:e.error?`Error: ${e.error}`:`Run failed`,timestamp:Date.now()}),t.forEach((e,n)=>{e.role===`tool`&&e.toolStatus===`running`&&(t[n]={...e,toolStatus:`error`})}),h();break}}},()=>{let e=O(n),t=e[e.length-1];t?.isStreaming&&A(n,t.id,{isStreaming:!1}),h(),j(n)},e=>{let t=O(n),r=t[t.length-1];r?.isStreaming?A(n,r.id,{isStreaming:!1,content:`Error: ${e.message}`,role:`system`}):k(n,{id:p(),role:`system`,content:`Error: ${e.message}`,timestamp:Date.now()}),h()});o.value.set(n,g)}catch(e){k(n,{id:p(),role:`system`,content:`Error: ${e.message}`,timestamp:Date.now()})}}function N(){let e=a.value;if(!e)return;let t=o.value.get(e);if(t){t.abort();let n=O(e),r=n[n.length-1];r?.isStreaming&&A(e,r.id,{isStreaming:!1}),o.value.delete(e)}}return S(),{sessions:i,activeSessionId:a,activeSession:b,messages:x,isStreaming:_,isLoadingSessions:v,isLoadingMessages:y,newChat:T,switchSession:w,switchSessionModel:E,deleteSession:D,sendMessage:M,stopStreaming:N,loadSessions:S}});export{_ as t};
@@ -1 +0,0 @@
1
- import{Q as e}from"./browser-DNwI2j4X.js";var t=e(`n-message-api`),n=e(`n-message-provider`);export{n,t};
@@ -1 +0,0 @@
1
- import{o as e,vt as t}from"./router-CpYvE976.js";var n=t({createJob:()=>o,deleteJob:()=>c,getJob:()=>a,listJobs:()=>i,pauseJob:()=>l,resumeJob:()=>u,runJob:()=>d,updateJob:()=>s});function r(e){return e.job}async function i(){return(await e(`/api/jobs?include_disabled=true`)).jobs}async function a(t){return r(await e(`/api/jobs/${t}`))}async function o(t){return r(await e(`/api/jobs`,{method:`POST`,body:JSON.stringify(t)}))}async function s(t,n){return r(await e(`/api/jobs/${t}`,{method:`PATCH`,body:JSON.stringify(n)}))}async function c(t){return e(`/api/jobs/${t}`,{method:`DELETE`})}async function l(t){return r(await e(`/api/jobs/${t}/pause`,{method:`POST`}))}async function u(t){return r(await e(`/api/jobs/${t}/resume`,{method:`POST`}))}async function d(t){return r(await e(`/api/jobs/${t}/run`,{method:`POST`}))}export{l as a,s as c,i,c as n,u as o,n as r,d as s,o as t};
@@ -1 +0,0 @@
1
- import{o as e}from"./router-CpYvE976.js";async function t(t,n){let r=new URLSearchParams;t&&r.set(`source`,t),n&&r.set(`limit`,String(n));let i=r.toString();return(await e(`/api/sessions${i?`?${i}`:``}`)).sessions}async function n(t){try{return(await e(`/api/sessions/${t}`)).session}catch{return null}}async function r(t){try{return await e(`/api/sessions/${t}`,{method:`DELETE`}),!0}catch{return!1}}async function i(t,n){try{return await e(`/api/sessions/${t}/rename`,{method:`POST`,body:JSON.stringify({title:n})}),!0}catch{return!1}}export{i,n,t as r,r as t};
@@ -1 +0,0 @@
1
- import{o as e}from"./router-CpYvE976.js";async function t(){return(await e(`/api/skills`)).categories}async function n(t){return(await e(`/api/skills/${t}`)).content}async function r(t,n){return(await e(`/api/skills/${t}/${n}/files`)).files}async function i(){return e(`/api/memory`)}async function a(t,n){await e(`/api/memory`,{method:`POST`,body:JSON.stringify({section:t,content:n})})}async function o(t,n){await e(`/api/skills/toggle`,{method:`PUT`,body:JSON.stringify({name:t,enabled:n})})}export{a,t as i,n,o,r,i as t};
@@ -1 +0,0 @@
1
- import{C as e}from"./router-CpYvE976.js";function t(t,n){return e(()=>{for(let e of n)if(t[e]!==void 0)return t[e];return t[n[n.length-1]]})}export{t};
package/dist/index.html DELETED
@@ -1,38 +0,0 @@
1
- <!doctype html>
2
- <html lang="zh-CN">
3
-
4
- <head>
5
- <meta charset="UTF-8" />
6
- <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
- <title>Hermes</title>
9
- <script type="module" crossorigin src="/assets/index-DlNQjiQP.js"></script>
10
- <link rel="modulepreload" crossorigin href="/assets/router-CpYvE976.js">
11
- <link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-NLzeiXdV.js">
12
- <link rel="modulepreload" crossorigin href="/assets/browser-DNwI2j4X.js">
13
- <link rel="modulepreload" crossorigin href="/assets/Scrollbar-CA0Mq0os.js">
14
- <link rel="modulepreload" crossorigin href="/assets/use-compitable-D2-fMbL2.js">
15
- <link rel="modulepreload" crossorigin href="/assets/Popover-CRZpNb8Q.js">
16
- <link rel="modulepreload" crossorigin href="/assets/Close-DYPlamoH.js">
17
- <link rel="modulepreload" crossorigin href="/assets/Button-BHvh9zmj.js">
18
- <link rel="modulepreload" crossorigin href="/assets/Suffix-BMwB7UJK.js">
19
- <link rel="modulepreload" crossorigin href="/assets/fade-in-scale-up.cssr-BMJXPg-3.js">
20
- <link rel="modulepreload" crossorigin href="/assets/Tag-NMAaTGW7.js">
21
- <link rel="modulepreload" crossorigin href="/assets/Select-DLECSo9D.js">
22
- <link rel="modulepreload" crossorigin href="/assets/Warning-CmJYhk3M.js">
23
- <link rel="modulepreload" crossorigin href="/assets/Modal-mFCAbKPD.js">
24
- <link rel="modulepreload" crossorigin href="/assets/omit-C4dR5R2G.js">
25
- <link rel="modulepreload" crossorigin href="/assets/context-DLFTSrww.js">
26
- <link rel="modulepreload" crossorigin href="/assets/pinia-DKSOddVw.js">
27
- <link rel="modulepreload" crossorigin href="/assets/sessions-DTV2WuAE.js">
28
- <link rel="modulepreload" crossorigin href="/assets/app-CQZfHgyy.js">
29
- <link rel="modulepreload" crossorigin href="/assets/chat-DnFbBAAK.js">
30
- <link rel="modulepreload" crossorigin href="/assets/logo-Cd-t_oGE.js">
31
- <link rel="stylesheet" crossorigin href="/assets/index-TVVcuwR0.css">
32
- </head>
33
-
34
- <body>
35
- <div id="app"></div>
36
- </body>
37
-
38
- </html>
@@ -1,12 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.proxyRoutes = void 0;
7
- const router_1 = __importDefault(require("@koa/router"));
8
- const proxy_handler_1 = require("./proxy-handler");
9
- exports.proxyRoutes = new router_1.default();
10
- // Proxy all /api/*, /v1/* to upstream Hermes API
11
- exports.proxyRoutes.all('/api/(.*)', proxy_handler_1.proxy);
12
- exports.proxyRoutes.all('/v1/(.*)', proxy_handler_1.proxy);
File without changes
File without changes
File without changes
File without changes