failproofai 0.0.13-beta.0 → 0.0.13-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page.js +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  14. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  15. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  21. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  22. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  23. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  24. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  25. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  26. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  27. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  28. package/.next/standalone/.next/server/app/api/audit/invite/route.js +2 -2
  29. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/audit/run/route.js +3 -2
  31. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +1 -1
  33. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +2 -2
  35. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/auth/logout/route.js +2 -2
  37. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/auth/reminder/route.js +2 -2
  39. package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/auth/status/route.js +2 -2
  41. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +1 -1
  43. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  45. package/.next/standalone/.next/server/app/audit/page.js +1 -1
  46. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  48. package/.next/standalone/.next/server/app/index.html +1 -1
  49. package/.next/standalone/.next/server/app/index.rsc +15 -15
  50. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  51. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  52. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  53. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  54. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  55. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  56. package/.next/standalone/.next/server/app/page.js +1 -1
  57. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  58. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  59. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
  60. package/.next/standalone/.next/server/app/policies/page.js +2 -2
  61. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  64. package/.next/standalone/.next/server/app/project/[name]/page.js +3 -2
  65. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  68. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  69. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +3 -2
  70. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  71. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  73. package/.next/standalone/.next/server/app/projects/page.js +2 -2
  74. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  75. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  76. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0xu5z._.js +1 -1
  77. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cefjd9._.js +3 -0
  78. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ekj92q._.js +3 -0
  79. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0hv08mx._.js +3 -0
  80. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0obaznk._.js +3 -0
  81. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xvsnvt._.js +3 -0
  82. package/.next/standalone/.next/server/chunks/[root-of-the-server]__12v-lma._.js +3 -0
  83. package/.next/standalone/.next/server/chunks/[root-of-the-server]__136y39g._.js +3 -0
  84. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13h8pzr._.js +1 -1
  85. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +3 -0
  86. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1hkdkmz._.js +3 -0
  87. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1i9rknc._.js +3 -0
  88. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1mrihkj._.js +3 -0
  89. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +3 -0
  90. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0cycwg6._.js → [root-of-the-server]__1tvn4wf._.js} +2 -2
  91. package/.next/standalone/.next/server/chunks/_1z062h5._.js +3 -0
  92. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +5 -5
  93. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  94. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__015_i4t._.js +4 -0
  95. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__03lv-pe._.js +4 -0
  96. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04bqvos._.js +3 -0
  97. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1-m1rhq._.js → [root-of-the-server]__099afy6._.js} +2 -2
  98. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0dqgs96._.js +3 -0
  99. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1uvfwgr._.js → [root-of-the-server]__0hdsupo._.js} +3 -3
  100. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0q5rfxg._.js +3 -0
  101. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qeuy9c._.js +4 -0
  102. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qukut7._.js +4 -0
  103. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s89hoe._.js +4 -0
  104. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ehe24g._.js → [root-of-the-server]__0ynf7tx._.js} +3 -3
  105. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__170799-._.js +245 -0
  106. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1d8omgc._.js +1 -1
  107. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ql-mch._.js +3 -0
  108. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0bbpv2d._.js → [root-of-the-server]__1qlh4jx._.js} +2 -2
  109. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tkjqka._.js +4 -0
  110. package/.next/standalone/.next/server/chunks/ssr/_05whahf._.js +1 -1
  111. package/.next/standalone/.next/server/chunks/ssr/_0ul5rf_._.js +3 -0
  112. package/.next/standalone/.next/server/chunks/ssr/_11_p9y8._.js +1 -1
  113. package/.next/standalone/.next/server/chunks/ssr/_11v0g3z._.js +3 -0
  114. package/.next/standalone/.next/server/chunks/ssr/_1p0-leb._.js +1 -1
  115. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  116. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  117. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  118. package/.next/standalone/.next/server/chunks/ssr/lib_hermes-projects_ts_05b8-it._.js +3 -0
  119. package/.next/standalone/.next/server/chunks/ssr/{node_modules_html-to-image_es_index_1u91ynr.js → node_modules_html-to-image_es_index_0pv57nx.js} +1 -1
  120. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  121. package/.next/standalone/.next/server/pages/404.html +1 -1
  122. package/.next/standalone/.next/server/pages/500.html +1 -1
  123. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  124. package/.next/standalone/.next/server/server-reference-manifest.json +10 -10
  125. package/.next/standalone/.next/static/chunks/{0azkpcy8eb1gr.js → 0b6rdtcge_3ec.js} +1 -1
  126. package/.next/standalone/.next/static/chunks/{1zxtyef-iqede.js → 0pj_6lbbjd000.js} +1 -1
  127. package/.next/standalone/.next/static/chunks/{1h569gia53ant.js → 0xnrgonfdeivm.js} +1 -1
  128. package/.next/standalone/.next/static/chunks/{39rn602wszcbd.js → 105w_oznq-van.js} +1 -1
  129. package/.next/standalone/.next/static/chunks/{0byua6ng1f_ka.js → 13tbm6i1swiru.js} +1 -1
  130. package/.next/standalone/.next/static/chunks/{41mhnhfkmglpp.js → 1fhuj4fjovzp5.js} +1 -1
  131. package/.next/standalone/.next/static/chunks/209ful1jrphvy.js +1 -0
  132. package/.next/standalone/.next/static/chunks/{3jka0hvhqouyv.js → 23odnajn2ltwu.js} +1 -1
  133. package/.next/standalone/.next/static/chunks/25s52un3k_wht.css +2 -0
  134. package/.next/standalone/.next/static/chunks/36r2vgi6854za.js +6 -0
  135. package/.next/standalone/.next/static/chunks/3b77kulbdbrqw.js +1 -0
  136. package/.next/standalone/.next/static/chunks/3rjg-1s5ouu5r.js +1 -0
  137. package/.next/standalone/app/components/sessions-list.tsx +19 -0
  138. package/.next/standalone/app/project/[name]/page.tsx +9 -4
  139. package/.next/standalone/app/project/[name]/session/[sessionId]/page.tsx +26 -5
  140. package/.next/standalone/assets/logos/hermes-dark.svg +1 -0
  141. package/.next/standalone/assets/logos/hermes-light.svg +1 -0
  142. package/.next/standalone/lib/cli-registry.ts +6 -1
  143. package/.next/standalone/lib/download-session.ts +16 -0
  144. package/.next/standalone/lib/hermes-projects.ts +164 -0
  145. package/.next/standalone/lib/hermes-sessions.ts +273 -0
  146. package/.next/standalone/lib/projects.ts +14 -3
  147. package/.next/standalone/lib/sqlite-reader.ts +102 -0
  148. package/.next/standalone/package.json +5 -3
  149. package/.next/standalone/server.js +1 -1
  150. package/README.md +10 -1
  151. package/bin/failproofai.mjs +17 -16
  152. package/dist/cli.mjs +7762 -226
  153. package/lib/cli-registry.ts +6 -1
  154. package/lib/download-session.ts +16 -0
  155. package/lib/hermes-projects.ts +164 -0
  156. package/lib/hermes-sessions.ts +273 -0
  157. package/lib/projects.ts +14 -3
  158. package/lib/sql-js-asm.d.ts +26 -0
  159. package/lib/sqlite-reader.ts +102 -0
  160. package/package.json +5 -3
  161. package/src/audit/cli-adapters/hermes.ts +58 -0
  162. package/src/audit/cli-adapters/index.ts +6 -0
  163. package/src/hooks/handler.ts +8 -0
  164. package/src/hooks/install-prompt.ts +7 -3
  165. package/src/hooks/integrations.ts +179 -5
  166. package/src/hooks/policy-evaluator.ts +42 -0
  167. package/src/hooks/resolve-transcript-path.ts +4 -0
  168. package/src/hooks/tool-name-canonicalize.ts +6 -0
  169. package/src/hooks/types.ts +67 -1
  170. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0dwpg-h._.js +0 -3
  171. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0lnenda._.js +0 -3
  172. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13i_sva._.js +0 -3
  173. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1_mqemn._.js +0 -3
  174. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1m2_4t0._.js +0 -3
  175. package/.next/standalone/.next/server/chunks/node_modules_0-tu4ot._.js +0 -3
  176. package/.next/standalone/.next/server/chunks/node_modules_0ttxbz7._.js +0 -3
  177. package/.next/standalone/.next/server/chunks/node_modules_1bnh1y0._.js +0 -3
  178. package/.next/standalone/.next/server/chunks/node_modules_1epycqa._.js +0 -3
  179. package/.next/standalone/.next/server/chunks/node_modules_1wpdcgo._.js +0 -3
  180. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0808sha._.js +0 -4
  181. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e4-6d8._.js +0 -4
  182. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0f62vu9._.js +0 -3
  183. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g253ve._.js +0 -4
  184. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0k65l27._.js +0 -3
  185. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0vxf0_g._.js +0 -4
  186. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12mcauo._.js +0 -4
  187. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1e-x7j4._.js +0 -3
  188. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1mt35_w._.js +0 -221
  189. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pcxxwg._.js +0 -4
  190. package/.next/standalone/.next/static/chunks/03zg3ms7uaoq3.js +0 -1
  191. package/.next/standalone/.next/static/chunks/0f7d7hnbh4djs.js +0 -1
  192. package/.next/standalone/.next/static/chunks/1o0xa47736gi9.css +0 -2
  193. package/.next/standalone/.next/static/chunks/2ks4pzu5b-l_q.js +0 -6
  194. package/.next/standalone/.next/static/chunks/2wbuxnsvux4di.js +0 -1
  195. /package/.next/standalone/.next/static/{W6ELw5VwHTFy2amS2px6e → 31ZoDDYKHEIN_TrgKv85t}/_buildManifest.js +0 -0
  196. /package/.next/standalone/.next/static/{W6ELw5VwHTFy2amS2px6e → 31ZoDDYKHEIN_TrgKv85t}/_clientMiddlewareManifest.js +0 -0
  197. /package/.next/standalone/.next/static/{W6ELw5VwHTFy2amS2px6e → 31ZoDDYKHEIN_TrgKv85t}/_ssgManifest.js +0 -0
@@ -9,6 +9,7 @@ import { getCachedCursorSessionLog } from "@/lib/cursor-sessions";
9
9
  import { getCachedOpenCodeSessionLog } from "@/lib/opencode-sessions";
10
10
  import { getCachedPiSessionLog } from "@/lib/pi-sessions";
11
11
  import { getCachedGeminiSessionLog } from "@/lib/gemini-sessions";
12
+ import { getCachedHermesSessionLog } from "@/lib/hermes-sessions";
12
13
  import { decodeFolderName } from "@/lib/paths";
13
14
  import { baseSessionId } from "@/lib/utils/session-id";
14
15
  import { resolveProjectPath, UUID_RE } from "@/lib/projects";
@@ -39,12 +40,20 @@ export default async function SessionPage({ params }: SessionPageProps) {
39
40
  // `ses_21ad60d14ffewMeRRKMLdS7vOI`). The other four CLIs use UUIDs. Accept
40
41
  // either; the per-CLI loader returns null for unknown IDs anyway.
41
42
  const OPENCODE_SESSION_RE = /^ses_[A-Za-z0-9]+$/;
42
- if (!UUID_RE.test(decodedSessionId) && !OPENCODE_SESSION_RE.test(decodedSessionId)) notFound();
43
+ // Hermes session IDs — same permissive shape as the loader/download validator
44
+ // (a stricter pattern would 404 real sessions that the loader would happily open).
45
+ const HERMES_SESSION_RE = /^[A-Za-z0-9_-]+$/;
46
+ if (
47
+ !UUID_RE.test(decodedSessionId) &&
48
+ !OPENCODE_SESSION_RE.test(decodedSessionId) &&
49
+ !HERMES_SESSION_RE.test(decodedSessionId)
50
+ )
51
+ notFound();
43
52
 
44
53
  let entries: LogEntry[] | null = null;
45
54
  let rawLines: Record<string, unknown>[] | null = null;
46
55
  let error: string | null = null;
47
- let cli: "claude" | "codex" | "copilot" | "cursor" | "opencode" | "pi" | "gemini" = "claude";
56
+ let cli: "claude" | "codex" | "copilot" | "cursor" | "opencode" | "pi" | "gemini" | "hermes" = "claude";
48
57
  let externalCwd: string | undefined;
49
58
 
50
59
  try {
@@ -100,7 +109,15 @@ export default async function SessionPage({ params }: SessionPageProps) {
100
109
  externalCwd = gemini.cwd;
101
110
  cli = "gemini";
102
111
  } else {
103
- error = "Session log file not found.";
112
+ const hermes = await getCachedHermesSessionLog(decodedSessionId);
113
+ if (hermes) {
114
+ entries = hermes.entries;
115
+ rawLines = hermes.rawLines;
116
+ externalCwd = hermes.cwd;
117
+ cli = "hermes";
118
+ } else {
119
+ error = "Session log file not found.";
120
+ }
104
121
  }
105
122
  }
106
123
  }
@@ -127,7 +144,9 @@ export default async function SessionPage({ params }: SessionPageProps) {
127
144
  ? `Pi${externalCwd ? ` · ${externalCwd}` : ""}`
128
145
  : cli === "gemini"
129
146
  ? `Gemini CLI${externalCwd ? ` · ${externalCwd}` : ""}`
130
- : decodedName;
147
+ : cli === "hermes"
148
+ ? `Hermes${externalCwd ? ` · ${externalCwd}` : ""}`
149
+ : decodedName;
131
150
 
132
151
  return (
133
152
  <main className="min-h-screen bg-background">
@@ -195,7 +214,9 @@ export default async function SessionPage({ params }: SessionPageProps) {
195
214
  ? "OpenCode"
196
215
  : cli === "pi"
197
216
  ? "Pi"
198
- : "Gemini CLI"))
217
+ : cli === "hermes"
218
+ ? "Hermes"
219
+ : "Gemini CLI"))
199
220
  : decodedName
200
221
  }
201
222
  sessionId={decodedSessionId}
@@ -0,0 +1 @@
1
+ <svg fill="#ffffff" fill-rule="evenodd" height="64" style="flex:none;line-height:1" viewBox="0 0 24 24" width="64" xmlns="http://www.w3.org/2000/svg"><title>Hermes Agent</title><path d="M5.938 12.835c.127-.039.285.02.373.143.028.038.036.092.046.14.003.014-.02.033-.04.05-.124-.098-.24-.194-.354-.291-.011-.01-.016-.027-.025-.042zM8.396 9.412c.195-.032.39-.06.588-.05a.54.54 0 01.148.026c.202.071.402.147.601.224.028.01.05.036.075.055l-.013.027a9.203 9.203 0 01-.26-.089c-.115-.038-.213-.077-.315-.098-.25-.05-.25-.046-.292-.014l.574.144c.275.139.55.276.823.417.042.022.09.057.107.098.026.06.063.076.117.072.066-.006.132-.017.213-.027l-.04.086c.051.08.142.02.216.064-.074.13-.247.09-.334.199l.061.074-.12.087c0 .106-.038.168-.306.243l.026.085-.196.042.07.124h-.25l-.007.137c-.081-.01-.161-.018-.244-.027l-.053.123c-.027-.008-.052-.011-.073-.023-.067-.038-.128-.056-.195.006-.019.017-.063.014-.093.008-.026-.006-.05-.029-.07-.042-.11.095-.11.095-.208.003-.057.046-.12.074-.186.011-.063.027-.123-.02-.178-.014-.07.007-.097-.035-.133-.07l-.13.033c-.013-.236-.194-.19-.34-.203.005-.072.05-.092.095-.094a.474.474 0 01.159.022c.164.05.32.12.496.138.203.021.405.029.601-.015.265-.059.52-.149.707-.365.049-.056.083-.127.117-.195.019-.038.02-.084-.02-.116a1.397 1.397 0 00-.382-.217c.024.12-.031.182-.115.221 0 .014-.004.025 0 .03.08.115.084.16-.007.267a1.39 1.39 0 01-.218.211.477.477 0 01-.641-.05 1.36 1.36 0 01-.133-.152c-.078-.107-.076-.108-.033-.236-.165-.08-.128-.226-.104-.364.008-.05.028-.096.049-.163-.04.014-.067.017-.087.032a.897.897 0 00-.316.357c-.007.016-.01.034-.02.047-.012.015-.034.038-.045.035-.02-.006-.037-.027-.05-.045-.008-.012-.007-.032-.012-.057h-.126l.053-.172a14.82 14.82 0 00-.039-.049l.11-.284c-.06.026-.091.044-.124.051-.03.007-.064 0-.095 0 0-.031-.01-.07.004-.092.149-.22.305-.428.593-.476z"></path><path d="M8.06 10.788c-.003-.038-.004-.075.037-.062.016.006.034.048.028.067-.01.04-.038.032-.064-.005z"></path><path clip-rule="evenodd" d="M11.981.009c.226-.012.453-.011.679 0 .247.01.495.024.74.062.401.064.798.157 1.19.273.463.138.92.299 1.356.511a7.31 7.31 0 012.948 2.642c.292.469.536.963.739 1.479.219.556.446 1.11.623 1.683.204.654.329 1.326.458 1.997.097.504.182 1.01.29 1.511.156.722.329 1.44.494 2.16.186.812.4 1.615.63 2.415.102.355.193.713.282 1.072.11.436.202.876.254 1.323.031.278.066.557.073.837a7.56 7.56 0 01-.017.88c-.037.413-.1.818-.226 1.212a5.017 5.017 0 01-.915 1.649l-.13.156.018.023c.043-.023.088-.041.127-.068.2-.138.373-.307.531-.49.4-.46.721-.973.975-1.529a3.59 3.59 0 00.325-1.72c-.024-.424-.097-.834-.3-1.213-.013-.027-.015-.06-.03-.121.05.035.082.048.101.072.107.13.22.258.315.398.33.494.46 1.052.486 1.64a3.75 3.75 0 01-.47 1.97c-.36.655-.887 1.14-1.526 1.506-.193.111-.394.21-.595.308-.157.078-.248.211-.318.365a.522.522 0 00-.033.406.359.359 0 01.013.139c-.005.077-.077.155-.14.162-.054.006-.125-.043-.15-.116a1.206 1.206 0 01-.06-.233c-.04-.314-.155-.6-.308-.87a3.906 3.906 0 00-.73-.91 2.129 2.129 0 00-.897-.524 4.093 4.093 0 00-.692-.131c-.075-.008-.15-.04-.22.01.18.06.363.11.538.18.434.173.82.43 1.18.728.308.255.58.543.794.884.098.155.186.315.227.496.027.123.042.25.067.375.013.062-.002.109-.053.144-.047.033-.122.034-.163-.01a.455.455 0 01-.08-.14c-.03-.073-.038-.159-.078-.225a7.314 7.314 0 00-1.423-1.664c-.16-.137-.329-.26-.537-.323-.376-.114-.753-.203-1.15-.154-.213.025-.427.032-.64.053a1.6 1.6 0 00-.736.278 5.14 5.14 0 00-.834.72c-.329.342-.642.699-.955 1.055-.136.155-.264.319-.314.531a5.227 5.227 0 00-.012.051.096.096 0 01-.09.076h-.31c-.046 0-.082-.048-.072-.094.023-.108.045-.216.07-.324.075-.325.19-.635.368-.917.024-.039.04-.088.104-.08l.01.049.027.077c.28-.435.571-.834.996-1.135.283-.204.584-.378.89-.55a.196.196 0 00-.098-.002c-.162.043-.325.084-.485.134-.402.124-.764.33-1.11.566-.147.1-.298.193-.414.333a7.314 7.314 0 00-1.07 1.767.845.845 0 00-.04.12.075.075 0 01-.072.056h-.494c-.04 0-.062-.051-.036-.082.123-.14.246-.282.377-.415.275-.281.58-.532.777-.884.027-.048.063-.09.095-.135.238-.333.54-.607.818-.902.082-.086.175-.16.26-.24.029-.027.053-.057.079-.085l-.018-.025-.135.041c-.034.017-.07.031-.102.05-.248.144-.494.292-.743.433-.408.23-.825.439-1.209.711-.281.2-.591.358-.889.533-.02.012-.044.015-.08.028-.015-.135.143-.201.108-.336-.033.014-.064.02-.085.038-.111.096-.227.19-.328.296-.148.157-.284.325-.425.488-.125.143-.25.286-.373.431A.153.153 0 019.89 24H8.762a.316.316 0 00.016-.042c.028-.09.085-.172.083-.28-.091-.018-.162.001-.212.077a4.45 4.45 0 00-.136.215c-.01.016-.024.03-.042.03h-.093c-.019 0-.029-.022-.017-.037.071-.088.14-.178.209-.268.001-.002-.006-.012-.012-.024-.014.004-.03.006-.045.013-.176.09-.352.181-.527.274a.363.363 0 01-.168.042H5.202c-.026 0-.039-.036-.019-.053.21-.178.402-.374.558-.605.335-.496.538-1.047.667-1.629.004-.02-.003-.043-.006-.091-.037.048-.059.072-.076.1a1.943 1.943 0 01-.334.415c-.28.258-.59.448-.983.464-.297.012-.588 0-.865-.127-.46-.21-.722-.57-.794-1.072-.025-.17-.017-.171-.182-.219A3.513 3.513 0 011.97 20.6a2.286 2.286 0 01-.808-1.13 3.569 3.569 0 01-.16-1.245c.002-.034.016-.067.024-.1.032.023.046.043.05.066.033.153.059.308.096.46.086.355.257.664.516.92.258.256.571.419.91.532.358.118.717.138 1.07-.016a1.89 1.89 0 00.621-.452c.328-.348.533-.76.648-1.223.009-.034.005-.071.007-.11-.015.006-.026.006-.03.011-.031.05-.064.1-.093.152-.284.502-.679.887-1.196 1.135-.351.17-.718.255-1.11.159a1.607 1.607 0 01-.971-.64 2.006 2.006 0 01-.368-.924 2.903 2.903 0 01.02-.886c.05-.439.466-1.17.742-1.271-.02.063-.035.112-.053.16-.043.116-.097.227-.13.345a1.901 1.901 0 00-.05.82c.033.212.09.416.204.6.147.236.346.407.62.465.11.023.225.014.338.018a.576.576 0 00.386-.131c.164-.128.282-.292.366-.481.168-.375.24-.777.309-1.179.05-.296.093-.594.133-.893.039-.281.071-.563.104-.845.026-.232.048-.464.074-.696.024-.228.052-.455.076-.683.024-.227.047-.455.069-.683.013-.14.022-.28.034-.42l.037-.417c.022-.25.041-.5.065-.748.008-.082-.02-.132-.09-.177a2.46 2.46 0 01-.492-.418c-.1-.109-.188-.228-.282-.342-.035-.042-.056-.097-.116-.118a2.084 2.084 0 00.275.597c.06.092.131.176.196.265.063.086.182.115.234.226-.028.003-.046.01-.06.006a4.74 4.74 0 01-.22-.057 2.71 2.71 0 01-1.287-.819c-.435-.487-.656-1.076-.71-1.723a5.206 5.206 0 01.014-1.06c.072-.602.22-1.186.45-1.745.155-.376.338-.741.526-1.102.205-.393.466-.75.765-1.076.512-.559 1.104-1.024 1.726-1.448.717-.49 1.478-.898 2.277-1.233C8.244.828 8.767.632 9.31.494c.655-.166 1.31-.33 1.982-.415.229-.03.458-.058.688-.07zm-1.847 22.82c-.07.06-.147.111-.207.18-.238.27-.464.549-.668.869l-.044.108a.177.177 0 00.093-.057c.174-.19.351-.378.519-.574.104-.122.195-.255.288-.386.024-.034.03-.08.046-.12l-.027-.02zm1.65-3.695a5.51 5.51 0 00-.653.593l-.37.386a.963.963 0 01-.377.25 1.372 1.372 0 01-.467.09c-.044 0-.087.006-.151.012.028.058.043.097.064.131.15.242.301.482.45.724.136.22.276.438.399.666.068.125.105.267.156.404.077.027.14-.018.202-.048.29-.135.579-.274.867-.412.213-.101.437-.186.636-.31.347-.215.68-.455 1.018-.685.015-.01.026-.028.042-.046-.023-.019-.038-.037-.056-.044-.287-.111-.527-.3-.77-.482a5.319 5.319 0 01-.506-.42 1.757 1.757 0 01-.41-.653c-.019-.049-.045-.095-.075-.156zm-5.847.264c-.06.096-.097.194-.132.293a3.38 3.38 0 01-.555 1.01c-.2.25-.455.412-.762.493-.23.06-.464.076-.7.07-.048-.002-.097.002-.158.005.016.04.021.066.035.085.1.145.23.246.4.295.157.046.316.034.498.023.181-.037.343-.115.485-.234.238-.199.402-.454.536-.732.175-.363.264-.751.342-1.144.01-.053.008-.11.011-.164zm14.945-4.586c.008.029.016.057.027.107.024.155.051.31.072.464.03.219.067.437.078.657.017.344.027.689-.014 1.033-.037.315-.063.633-.116.946a6.153 6.153 0 01-.46 1.518c-.008.018-.01.039-.02.082.047-.03.077-.042.098-.064.085-.083.17-.167.248-.255.271-.305.458-.66.596-1.043.18-.498.228-1.011.145-1.531-.103-.65-.33-1.263-.597-1.881a9.055 9.055 0 00-.024-.055l-.033.022zM5.797 8.29a.26.26 0 00.018.153c.124.251.25.501.379.75.025.049.066.09.03.163-.284.06-.578.119-.88.255.059.038.097.06.132.087.042.032.112.058.09.12-.01.033-.075.048-.117.072.017.01.043.021.067.036.166.102.33.207.447.368.138.192.229.404.188.644-.079.469-.306.85-.69 1.132-.054.04-.106.083-.161.122a.243.243 0 00-.103.245.77.77 0 00.055.195c.083.196.22.35.375.492.083.076.159.164.222.257a.37.37 0 01.025.377c-.023.05-.05.099-.076.148-.03.06-.028.111.022.162.041.042.08.089.112.138.038.058.078.079.147.05a.486.486 0 01.333-.006c.16.046.302.126.444.21.13.077.264.149.4.219.067.035.14.05.219.026.071-.022.124.01.145.076.02.064-.003.108-.074.139-.07.03-.137.063-.209.088-.1.035-.201.073-.314.077-.013-.107.11-.088.127-.159-.206-.126-.643-.145-.801-.034.063.112.035.21-.096.313-.13-.1-.025-.202.002-.3a.209.209 0 00-.249.17c-.015.101.067.216.178.224.108.007.218-.005.326-.012.06-.005.12-.027.199 0-.103.123-.248.127-.357.19.002.05.07.086.019.131-.053.048-.095-.001-.132-.03-.08-.063-.16-.126-.231-.197a.474.474 0 01-.157-.311.52.52 0 00-.043-.172c-.032-.074-.032-.137.033-.19-.018-.03-.028-.053-.045-.072a1.222 1.222 0 01-.196-.369c-.053-.137-.046-.264.048-.381.024-.03.05-.06.064-.095a.664.664 0 00.047-.168c.017-.165-.064-.287-.182-.387-.186-.156-.36-.322-.46-.551-.005-.011-.024-.017-.037-.026-.011.017-.024.027-.025.038-.019.185-.045.37-.052.557-.014.377.058.743.162 1.104.118.41.289.798.488 1.173.267.502.537 1.002.812 1.5.055.098.13.189.208.27.198.202.452.272.724.273.202 0 .404-.006.605-.026.295-.03.59-.073.884-.113.183-.025.365-.057.548-.08.21-.026.38.073.522.21.16.156.305.327.447.5.22.265.397.56.554.867.05.098.07.1.147.03.13-.121.26-.242.394-.36.067-.059.088-.12.067-.213a3.535 3.535 0 01-.085-.796c.002-.157.006-.314.018-.471.015-.224.03-.45.06-.672a59.114 59.114 0 01.362-2.298c.087-.493.182-.984.268-1.477.06-.347.118-.694.162-1.043.034-.273.055-.55.063-.825.011-.332.003-.665.002-.998 0-.077.004-.155-.01-.23-.028-.142-.01-.155-.162-.19a5.826 5.826 0 00-.607-.107c-.146-.018-.207-.053-.221-.19-.006-.049-.025-.098-.041-.146-.009-.025-.024-.048-.046-.09l-.025.264c-.009.096-.029.116-.127.115-.055 0-.11-.008-.164-.008-.476 0-.952-.008-1.426.032-.095.008-.173-.015-.226-.103-.04-.066-.088-.126-.134-.186-.063-.084-.086-.093-.182-.06-.195.068-.388.138-.582.21a2.71 2.71 0 00-.675.394.986.986 0 01-.323.168c-.033.01-.07.008-.127.013.02-.066.024-.114.047-.15.064-.105.135-.205.205-.306.023-.033.049-.063.073-.095l-.015-.023-.201.037c-.146.04-.296.07-.437.122-.148.053-.266.023-.386-.072a3.623 3.623 0 01-.733-.786l-.093-.132zm8.592 8.963l-.147.09c-.22.134-.44.266-.659.402-.093.058-.184.12-.27.188-.085.07-.124.161-.072.272.047.1.093.2.147.294.047.08.124.138.213.147.11.01.228.012.336-.012.217-.05.372-.205.528-.357a.291.291 0 00.087-.308c-.046-.18-.079-.365-.118-.547-.011-.052-.027-.103-.045-.169zm-.257-2.409c-.12.291-.205.597-.325.91-.151.433-.294.87-.435 1.323.036-.01.054-.01.067-.018.261-.16.522-.324.785-.484.054-.033.071-.078.065-.138-.012-.13-.024-.262-.034-.393l-.068-.886c-.008-.103-.02-.206-.029-.31-.009 0-.017-.002-.026-.004zm3.081-8.13l.099.285c.08.231.159.463.24.714l.58 1.952c.187.63.372 1.262.558 1.893.114.382.235.762.343 1.146.072.257.126.519.186.799.044.206.087.413.127.64.034.106.023.226.077.325l.025-.006-.068-.362c-.038-.206-.077-.412-.113-.638-.015-.07-.029-.141-.046-.211-.095-.396-.177-.796-.29-1.187-.196-.685-.413-1.364-.618-2.046-.165-.549-.322-1.1-.488-1.648-.069-.227-.15-.45-.226-.695l-.117-.336c-.037-.107-.075-.216-.115-.322-.04-.106-.084-.21-.127-.314a7.558 7.558 0 01-.027.01zM6.225 14.304c-.063-.001-.115.014-.134.083a.35.35 0 00.41.012 4.533 4.533 0 00-.276-.095zM5.23 11.98c-.026-.027-.057-.048-.075.002-.012.032-.007.07-.01.113.082-.037.082-.037.085-.115zm.062-1.189a.135.135 0 00-.088.056.197.197 0 00-.025.11c.005.152.01.306.026.457a.751.751 0 00.066.218c.061.136.157.167.288.101.055-.027.06-.054.025-.11a4.52 4.52 0 01-.129-.211c-.015-.068-.066-.131-.033-.207.04-.09-.076-.116-.074-.19V10.874c-.003-.038-.006-.087-.056-.083zm-.017-.968a.867.867 0 00-.467.127c-.076.045-.084.07-.05.158.034.087.07.173.115.254.064.117.09.125.21.077a.657.657 0 01.336-.053c.202.022.357.136.504.264l.092.077c.007-.006.014-.013.022-.018-.019-.105-.035-.226-.149-.264-.157-.053-.324-.075-.508-.117l-.24-.005c.24-.169.452-.044.687.009-.063-.115-.153-.147-.23-.193-.082-.05-.17-.092-.25-.144-.06-.037-.12-.08-.072-.172zm10.233.325c-.23-.01-.427.08-.608.211-.034.026-.06.065-.105.117.087.026.15.046.232.065.044-.015.088-.03.13-.046.306-.114.61-.115.904.031.126.063.237.04.366-.005-.02-.031-.03-.054-.045-.071a.986.986 0 00-.448-.273c-.14-.044-.284-.024-.426-.03zM7.99 6.483a.308.308 0 00.002.133c.08.321.156.643.242.962.104.387.27.75.456 1.103.02.037.061.08.098.087a.404.404 0 00.253-.051l-.472-.84c-.23-.448-.405-.92-.579-1.394zM10.397.497c-.2-.008-.405.004-.603.034-.236.035-.47.087-.7.152-.287.08-.569.18-.852.273-.04.013-.074.038-.11.058.028.014.05.018.07.014.287-.068.58-.085.873-.09.134-.002.269.009.402.025.19.024.382.048.57.09.456.104.874.3 1.265.556.464.306.888.66 1.257 1.078.205.232.395.475.56.739.17.274.315.561.449.856.273.601.456 1.232.6 1.876.04.173.07.348.1.524.017.104.065.167.17.19.122.028.2.105.22.251-.003.102-.06.174-.129.24a1.065 1.065 0 00-.268.358.164.164 0 00.083-.039c.08-.086.162-.172.235-.265a.56.56 0 00.13-.333c.009-.05.022-.1.024-.15.007-.124-.017-.15-.143-.168-.025-.004-.049-.014-.073-.015-.082-.007-.125-.063-.137-.131-.033-.198-.004-.355.247-.408.086-.018.174-.03.26-.042.158-.023.315-.053.473-.067.14-.012.19.033.226.167.008.029.018.057.021.087.019.179-.008.225-.141.288-.027.013-.055.024-.078.042a.148.148 0 00-.051.067c-.039.144.073.382.206.445l.673.32c.023.011.05.015.075.023l.018-.026c-.015-.008-.032-.013-.044-.024a2.27 2.27 0 00-.544-.32 4.898 4.898 0 00-.173-.075.203.203 0 01-.126-.191c-.003-.085.045-.154.128-.187l.059-.025c.099-.044.118-.076.112-.187a.384.384 0 00-.008-.063c-.067-.294-.123-.59-.205-.88a9.478 9.478 0 00-.826-2.036 7.465 7.465 0 00-1.39-1.805 4.536 4.536 0 00-1.177-.824 3.656 3.656 0 00-1.016-.328 6.155 6.155 0 00-.712-.074zm6.719 5.955c.01.014.018.028.038.034l-.022-.044-.016.01zM4.103 3.917a.062.062 0 01-.03.012.455.455 0 01-.04.039c-.01.01-.02.02-.045.04l-.363.354c-.088.085-.17.178-.266.253-.284.22-.425.53-.544.855a.132.132 0 00-.007.071c.013.055.033.108.052.168l.074.026c-.017.056-.03.105-.047.152-.058.164-.118.327-.175.491-.005.015.008.036.019.077.08-.175.158-.33.225-.489.228-.544.484-1.074.819-1.561.09-.133.182-.266.283-.401.004-.006.007-.013.022-.03.001-.016.003-.032.015-.04l.008-.017zm12.976 2.408a.023.023 0 01.009.019.073.073 0 00-.006.01.188.188 0 00.007.02l.018.022c.002-.007.007-.016.005-.021-.003-.01-.012-.018-.02-.038a1.331 1.331 0 01-.013-.012zM4.199 4.48c-.003.004-.008.008-.027.014-.005.013-.011.025-.031.047a2.085 2.085 0 01-.124.167c-.048.07-.116.055-.181.041-.134-.028-.228.016-.287.143-.089.187-.187.37-.273.56-.049.108-.11.216-.118.36.081.003.154.007.228.008h.228a2.563 2.563 0 01-.079.264c-.01.052-.022.103-.033.155l.02.004c.018-.046.037-.092.067-.153.066-.142.13-.285.2-.426.02-.04.034-.1.116-.092 0 .043.004.084 0 .124-.005.045-.017.09-.028.143.141.043.086.174.115.269.102-.022.104-.195.248-.144v.205l.017.002.439-1.059c-.13 0-.246-.02-.358.033-.024.011-.058-.001-.108-.004.075-.15.139-.278.211-.417a.128.128 0 01.025-.036c0-.015-.001-.03.008-.038l.006-.02c-.005.006-.01.011-.028.017-.004.012-.009.024-.026.045a.085.085 0 01-.032.033c-.123.157-.09.164-.258.106-.079-.027-.078-.028-.047-.144.028-.046.056-.093.098-.15 0-.016-.001-.032.007-.042L4.2 4.48zm2.073-.67c-.003.006-.007.011-.027.016-.094.125-.194.246-.28.377-.155.238-.301.481-.451.723-.14.224-.345.368-.575.481-.017.008-.04.006-.079.011.012-.059.016-.109.033-.153a6.076 6.076 0 01.229-.518l-.007-.02a.138.138 0 01-.035.025c-.028.05-.055.1-.093.164-.26.424-.443.817-.442.95.024.004.048.011.073.013.177.013.188.007.26-.165.03-.07.077-.12.147-.15l.175-.07c.044-.018.085-.057.146-.032.003.05-.01.11.014.145.042.062.044.125.047.193.002.049.017.098.026.147.029-.034.039-.065.05-.097.142-.39.277-.782.428-1.17.1-.256.22-.504.33-.756.013-.03.013-.067.03-.092V3.81zm3.987-.34c0 .045.01.084.021.123.042.16.094.318.124.48.024.133.023.27.028.406 0 .033-.019.067-.032.11-.094-.058-.047-.158-.106-.215h-.125c-.015.072-.01.152-.046.2-.066.085-.155.154-.236.227-.043.038-.078.018-.103-.025l-.046-.087c-.065.035-.117.069-.172.093-.116.051-.235.095-.35.147-.085.038-.09.053-.07.147.014.075.034.148.047.223.013.072.05.109.123.124.233.05.462.115.657.265.058-.102.058-.102.168-.151.03-.014.06-.03.092-.042.08-.03.115-.017.15.06.023.048.041.098.066.158.06-.14-.042-.267.017-.416.157.18.24.39.375.567a.235.235 0 00.022-.098c.002-.124 0-.247.002-.371 0-.034.013-.067.02-.1l.032-.003c.11.155.13.354.226.52a3.036 3.036 0 00-.01-.392c-.004-.045 0-.074.05-.088.08.036.116.14.215.158-.03-.275-.423-1.137-.798-1.635-.114-.127-.2-.28-.34-.386zm-2.667.696c-.019.034-.03.05-.037.067-.061.185-.125.37-.18.556-.031.105-.087.169-.195.19-.09.019-.178.052-.268.073-.038.009-.089.015-.118-.003-.024-.016-.025-.069-.036-.106-.064.076-.082.087-.17.047-.133-.062-.262-.135-.393-.201-.048-.025-.093-.063-.17-.03-.043.12-.091.25-.137.382-.099.28-.087.242.095.453.046.048.102.03.154.023.054-.009.106-.03.16-.036.13-.013.26-.08.367-.015.204-.064.387-.122.571-.178.05-.015.089.005.114.054.022.042.034.093.082.121.038-.056-.013-.128.063-.178l.14.241-.042-1.46zm.278.358c-.096-.01-.107.01-.11.108-.002.038-.003.078.002.115.03.2.099.386.174.57.002.006.012.01.022.015l.078-.05c.052.036.081.088.153.088.205-.002.41.014.616.012.099-.001.158.042.205.12.018.03.024.077.088.066l-.08-.394c-.05-.195-.085-.395-.172-.589-.057.057-.114.068-.18.046a.72.72 0 00-.135-.028c-.22-.028-.44-.059-.66-.08zm10.254-1.727c.089.163.155.316.139.491-.016.168.026.342-.044.516-.047-.033-.088-.082-.112-.075-.117.035-.164-.057-.227-.115a4.772 4.772 0 01-.286-.29l-.104-.113a4.856 4.856 0 01-.023.019c.035.046.07.093.11.156.04.064.084.127.122.193.034.058.065.118.031.205-.082-.01-.164-.019-.246-.032-.06-.01-.101 0-.124.07-.031.098-.037.096-.15.09.02.042.036.08.057.116.041.074.03.138-.03.196-.06.06-.118.122-.178.181a.175.175 0 01-.185.046c-.222-.061-.447-.113-.67-.174-.032-.009-.063-.04-.086-.068-.03-.04-.052-.087-.08-.13-.044-.07-.09-.138-.136-.207a.18.18 0 00-.014.105c.012.127.03.253.035.38.005.1-.024.12-.121.104-.104-.017-.206-.04-.31-.058-.064-.012-.131-.028-.202.03l.081.208c.09 0 .166-.01.237.002a.819.819 0 01.458.251c.078.083.154.168.241.26l.018-.005c-.004-.006-.008-.013-.01-.04.014-.056-.062-.118.018-.178.031.03.064.057.088.09.058.078.111.159.169.257l.089.141.024-.013a2093.819 2093.819 0 01-.427-.934c.055.007.083.007.108.016.193.07.385.142.577.216.074.028.147.06.219.094.062.028.112.018.157-.033.05-.056.102-.112.154-.167.05-.051.095-.046.132.014.016.025.026.053.04.08.071.138.143.277.217.433l.159.308.025-.011c-.044-.106-.07-.218-.138-.334-.057-.182-.168-.346-.206-.545.136.034.362.326.567.732l.057.074.018-.011a1.563 1.563 0 01-.052-.127c-.046-.145-.097-.29-.136-.436-.022-.083-.036-.173.022-.26l.109.058-.026-.207.027-.016c.022.02.05.036.065.06.073.108.143.22.215.33.01.016.029.029.043.043-.036-.217-.2-.38-.229-.626l.155.112c.014-.166.012-.319.042-.465.032-.158-.023-.297-.063-.445.024.004.036.006.055.025.092.124.183.249.277.371.02.027.05.047.069.087l.04.063.019-.015a.293.293 0 01-.053-.082 27.922 27.922 0 01-.332-.49c-.221-.311-.363-.467-.485-.521zm-6.57.327c-.003.161.092.275.069.415l-.368.087c.09.139.032.237-.052.331-.05.057-.092.122-.143.178-.037.04-.046.078-.018.126l.16.275c.029.048.072.066.128.064.076-.003.152 0 .228-.001.116-.003.216.022.275.137.006.014.02.024.044.052.004-.059-.003-.098.01-.13.016-.04.04-.099.072-.108.084-.023.173-.024.26-.03.013-.001.027.018.04.029l.071.065c.019-.11-.082-.198-.024-.31l.126.04c-.026-.123-.07-.245-.071-.366 0-.123.051-.243.115-.36.107.062.16.156.234.253.183.265.36.533.494.834.165-.078.27.068.407.088-.003-.106-.133-.441-.197-.492a.142.142 0 00-.102-.028c-.06.011-.119.039-.191.063-.025-.039-.056-.078-.077-.122a3.936 3.936 0 00-.473-.783c-.076-.094-.16-.182-.228-.26l-.391.285c-.049.035-.094.03-.132-.017l-.169-.207c-.025-.03-.053-.059-.097-.108z"></path></svg>
@@ -0,0 +1 @@
1
+ <svg fill="#181818" fill-rule="evenodd" height="64" style="flex:none;line-height:1" viewBox="0 0 24 24" width="64" xmlns="http://www.w3.org/2000/svg"><title>Hermes Agent</title><path d="M5.938 12.835c.127-.039.285.02.373.143.028.038.036.092.046.14.003.014-.02.033-.04.05-.124-.098-.24-.194-.354-.291-.011-.01-.016-.027-.025-.042zM8.396 9.412c.195-.032.39-.06.588-.05a.54.54 0 01.148.026c.202.071.402.147.601.224.028.01.05.036.075.055l-.013.027a9.203 9.203 0 01-.26-.089c-.115-.038-.213-.077-.315-.098-.25-.05-.25-.046-.292-.014l.574.144c.275.139.55.276.823.417.042.022.09.057.107.098.026.06.063.076.117.072.066-.006.132-.017.213-.027l-.04.086c.051.08.142.02.216.064-.074.13-.247.09-.334.199l.061.074-.12.087c0 .106-.038.168-.306.243l.026.085-.196.042.07.124h-.25l-.007.137c-.081-.01-.161-.018-.244-.027l-.053.123c-.027-.008-.052-.011-.073-.023-.067-.038-.128-.056-.195.006-.019.017-.063.014-.093.008-.026-.006-.05-.029-.07-.042-.11.095-.11.095-.208.003-.057.046-.12.074-.186.011-.063.027-.123-.02-.178-.014-.07.007-.097-.035-.133-.07l-.13.033c-.013-.236-.194-.19-.34-.203.005-.072.05-.092.095-.094a.474.474 0 01.159.022c.164.05.32.12.496.138.203.021.405.029.601-.015.265-.059.52-.149.707-.365.049-.056.083-.127.117-.195.019-.038.02-.084-.02-.116a1.397 1.397 0 00-.382-.217c.024.12-.031.182-.115.221 0 .014-.004.025 0 .03.08.115.084.16-.007.267a1.39 1.39 0 01-.218.211.477.477 0 01-.641-.05 1.36 1.36 0 01-.133-.152c-.078-.107-.076-.108-.033-.236-.165-.08-.128-.226-.104-.364.008-.05.028-.096.049-.163-.04.014-.067.017-.087.032a.897.897 0 00-.316.357c-.007.016-.01.034-.02.047-.012.015-.034.038-.045.035-.02-.006-.037-.027-.05-.045-.008-.012-.007-.032-.012-.057h-.126l.053-.172a14.82 14.82 0 00-.039-.049l.11-.284c-.06.026-.091.044-.124.051-.03.007-.064 0-.095 0 0-.031-.01-.07.004-.092.149-.22.305-.428.593-.476z"></path><path d="M8.06 10.788c-.003-.038-.004-.075.037-.062.016.006.034.048.028.067-.01.04-.038.032-.064-.005z"></path><path clip-rule="evenodd" d="M11.981.009c.226-.012.453-.011.679 0 .247.01.495.024.74.062.401.064.798.157 1.19.273.463.138.92.299 1.356.511a7.31 7.31 0 012.948 2.642c.292.469.536.963.739 1.479.219.556.446 1.11.623 1.683.204.654.329 1.326.458 1.997.097.504.182 1.01.29 1.511.156.722.329 1.44.494 2.16.186.812.4 1.615.63 2.415.102.355.193.713.282 1.072.11.436.202.876.254 1.323.031.278.066.557.073.837a7.56 7.56 0 01-.017.88c-.037.413-.1.818-.226 1.212a5.017 5.017 0 01-.915 1.649l-.13.156.018.023c.043-.023.088-.041.127-.068.2-.138.373-.307.531-.49.4-.46.721-.973.975-1.529a3.59 3.59 0 00.325-1.72c-.024-.424-.097-.834-.3-1.213-.013-.027-.015-.06-.03-.121.05.035.082.048.101.072.107.13.22.258.315.398.33.494.46 1.052.486 1.64a3.75 3.75 0 01-.47 1.97c-.36.655-.887 1.14-1.526 1.506-.193.111-.394.21-.595.308-.157.078-.248.211-.318.365a.522.522 0 00-.033.406.359.359 0 01.013.139c-.005.077-.077.155-.14.162-.054.006-.125-.043-.15-.116a1.206 1.206 0 01-.06-.233c-.04-.314-.155-.6-.308-.87a3.906 3.906 0 00-.73-.91 2.129 2.129 0 00-.897-.524 4.093 4.093 0 00-.692-.131c-.075-.008-.15-.04-.22.01.18.06.363.11.538.18.434.173.82.43 1.18.728.308.255.58.543.794.884.098.155.186.315.227.496.027.123.042.25.067.375.013.062-.002.109-.053.144-.047.033-.122.034-.163-.01a.455.455 0 01-.08-.14c-.03-.073-.038-.159-.078-.225a7.314 7.314 0 00-1.423-1.664c-.16-.137-.329-.26-.537-.323-.376-.114-.753-.203-1.15-.154-.213.025-.427.032-.64.053a1.6 1.6 0 00-.736.278 5.14 5.14 0 00-.834.72c-.329.342-.642.699-.955 1.055-.136.155-.264.319-.314.531a5.227 5.227 0 00-.012.051.096.096 0 01-.09.076h-.31c-.046 0-.082-.048-.072-.094.023-.108.045-.216.07-.324.075-.325.19-.635.368-.917.024-.039.04-.088.104-.08l.01.049.027.077c.28-.435.571-.834.996-1.135.283-.204.584-.378.89-.55a.196.196 0 00-.098-.002c-.162.043-.325.084-.485.134-.402.124-.764.33-1.11.566-.147.1-.298.193-.414.333a7.314 7.314 0 00-1.07 1.767.845.845 0 00-.04.12.075.075 0 01-.072.056h-.494c-.04 0-.062-.051-.036-.082.123-.14.246-.282.377-.415.275-.281.58-.532.777-.884.027-.048.063-.09.095-.135.238-.333.54-.607.818-.902.082-.086.175-.16.26-.24.029-.027.053-.057.079-.085l-.018-.025-.135.041c-.034.017-.07.031-.102.05-.248.144-.494.292-.743.433-.408.23-.825.439-1.209.711-.281.2-.591.358-.889.533-.02.012-.044.015-.08.028-.015-.135.143-.201.108-.336-.033.014-.064.02-.085.038-.111.096-.227.19-.328.296-.148.157-.284.325-.425.488-.125.143-.25.286-.373.431A.153.153 0 019.89 24H8.762a.316.316 0 00.016-.042c.028-.09.085-.172.083-.28-.091-.018-.162.001-.212.077a4.45 4.45 0 00-.136.215c-.01.016-.024.03-.042.03h-.093c-.019 0-.029-.022-.017-.037.071-.088.14-.178.209-.268.001-.002-.006-.012-.012-.024-.014.004-.03.006-.045.013-.176.09-.352.181-.527.274a.363.363 0 01-.168.042H5.202c-.026 0-.039-.036-.019-.053.21-.178.402-.374.558-.605.335-.496.538-1.047.667-1.629.004-.02-.003-.043-.006-.091-.037.048-.059.072-.076.1a1.943 1.943 0 01-.334.415c-.28.258-.59.448-.983.464-.297.012-.588 0-.865-.127-.46-.21-.722-.57-.794-1.072-.025-.17-.017-.171-.182-.219A3.513 3.513 0 011.97 20.6a2.286 2.286 0 01-.808-1.13 3.569 3.569 0 01-.16-1.245c.002-.034.016-.067.024-.1.032.023.046.043.05.066.033.153.059.308.096.46.086.355.257.664.516.92.258.256.571.419.91.532.358.118.717.138 1.07-.016a1.89 1.89 0 00.621-.452c.328-.348.533-.76.648-1.223.009-.034.005-.071.007-.11-.015.006-.026.006-.03.011-.031.05-.064.1-.093.152-.284.502-.679.887-1.196 1.135-.351.17-.718.255-1.11.159a1.607 1.607 0 01-.971-.64 2.006 2.006 0 01-.368-.924 2.903 2.903 0 01.02-.886c.05-.439.466-1.17.742-1.271-.02.063-.035.112-.053.16-.043.116-.097.227-.13.345a1.901 1.901 0 00-.05.82c.033.212.09.416.204.6.147.236.346.407.62.465.11.023.225.014.338.018a.576.576 0 00.386-.131c.164-.128.282-.292.366-.481.168-.375.24-.777.309-1.179.05-.296.093-.594.133-.893.039-.281.071-.563.104-.845.026-.232.048-.464.074-.696.024-.228.052-.455.076-.683.024-.227.047-.455.069-.683.013-.14.022-.28.034-.42l.037-.417c.022-.25.041-.5.065-.748.008-.082-.02-.132-.09-.177a2.46 2.46 0 01-.492-.418c-.1-.109-.188-.228-.282-.342-.035-.042-.056-.097-.116-.118a2.084 2.084 0 00.275.597c.06.092.131.176.196.265.063.086.182.115.234.226-.028.003-.046.01-.06.006a4.74 4.74 0 01-.22-.057 2.71 2.71 0 01-1.287-.819c-.435-.487-.656-1.076-.71-1.723a5.206 5.206 0 01.014-1.06c.072-.602.22-1.186.45-1.745.155-.376.338-.741.526-1.102.205-.393.466-.75.765-1.076.512-.559 1.104-1.024 1.726-1.448.717-.49 1.478-.898 2.277-1.233C8.244.828 8.767.632 9.31.494c.655-.166 1.31-.33 1.982-.415.229-.03.458-.058.688-.07zm-1.847 22.82c-.07.06-.147.111-.207.18-.238.27-.464.549-.668.869l-.044.108a.177.177 0 00.093-.057c.174-.19.351-.378.519-.574.104-.122.195-.255.288-.386.024-.034.03-.08.046-.12l-.027-.02zm1.65-3.695a5.51 5.51 0 00-.653.593l-.37.386a.963.963 0 01-.377.25 1.372 1.372 0 01-.467.09c-.044 0-.087.006-.151.012.028.058.043.097.064.131.15.242.301.482.45.724.136.22.276.438.399.666.068.125.105.267.156.404.077.027.14-.018.202-.048.29-.135.579-.274.867-.412.213-.101.437-.186.636-.31.347-.215.68-.455 1.018-.685.015-.01.026-.028.042-.046-.023-.019-.038-.037-.056-.044-.287-.111-.527-.3-.77-.482a5.319 5.319 0 01-.506-.42 1.757 1.757 0 01-.41-.653c-.019-.049-.045-.095-.075-.156zm-5.847.264c-.06.096-.097.194-.132.293a3.38 3.38 0 01-.555 1.01c-.2.25-.455.412-.762.493-.23.06-.464.076-.7.07-.048-.002-.097.002-.158.005.016.04.021.066.035.085.1.145.23.246.4.295.157.046.316.034.498.023.181-.037.343-.115.485-.234.238-.199.402-.454.536-.732.175-.363.264-.751.342-1.144.01-.053.008-.11.011-.164zm14.945-4.586c.008.029.016.057.027.107.024.155.051.31.072.464.03.219.067.437.078.657.017.344.027.689-.014 1.033-.037.315-.063.633-.116.946a6.153 6.153 0 01-.46 1.518c-.008.018-.01.039-.02.082.047-.03.077-.042.098-.064.085-.083.17-.167.248-.255.271-.305.458-.66.596-1.043.18-.498.228-1.011.145-1.531-.103-.65-.33-1.263-.597-1.881a9.055 9.055 0 00-.024-.055l-.033.022zM5.797 8.29a.26.26 0 00.018.153c.124.251.25.501.379.75.025.049.066.09.03.163-.284.06-.578.119-.88.255.059.038.097.06.132.087.042.032.112.058.09.12-.01.033-.075.048-.117.072.017.01.043.021.067.036.166.102.33.207.447.368.138.192.229.404.188.644-.079.469-.306.85-.69 1.132-.054.04-.106.083-.161.122a.243.243 0 00-.103.245.77.77 0 00.055.195c.083.196.22.35.375.492.083.076.159.164.222.257a.37.37 0 01.025.377c-.023.05-.05.099-.076.148-.03.06-.028.111.022.162.041.042.08.089.112.138.038.058.078.079.147.05a.486.486 0 01.333-.006c.16.046.302.126.444.21.13.077.264.149.4.219.067.035.14.05.219.026.071-.022.124.01.145.076.02.064-.003.108-.074.139-.07.03-.137.063-.209.088-.1.035-.201.073-.314.077-.013-.107.11-.088.127-.159-.206-.126-.643-.145-.801-.034.063.112.035.21-.096.313-.13-.1-.025-.202.002-.3a.209.209 0 00-.249.17c-.015.101.067.216.178.224.108.007.218-.005.326-.012.06-.005.12-.027.199 0-.103.123-.248.127-.357.19.002.05.07.086.019.131-.053.048-.095-.001-.132-.03-.08-.063-.16-.126-.231-.197a.474.474 0 01-.157-.311.52.52 0 00-.043-.172c-.032-.074-.032-.137.033-.19-.018-.03-.028-.053-.045-.072a1.222 1.222 0 01-.196-.369c-.053-.137-.046-.264.048-.381.024-.03.05-.06.064-.095a.664.664 0 00.047-.168c.017-.165-.064-.287-.182-.387-.186-.156-.36-.322-.46-.551-.005-.011-.024-.017-.037-.026-.011.017-.024.027-.025.038-.019.185-.045.37-.052.557-.014.377.058.743.162 1.104.118.41.289.798.488 1.173.267.502.537 1.002.812 1.5.055.098.13.189.208.27.198.202.452.272.724.273.202 0 .404-.006.605-.026.295-.03.59-.073.884-.113.183-.025.365-.057.548-.08.21-.026.38.073.522.21.16.156.305.327.447.5.22.265.397.56.554.867.05.098.07.1.147.03.13-.121.26-.242.394-.36.067-.059.088-.12.067-.213a3.535 3.535 0 01-.085-.796c.002-.157.006-.314.018-.471.015-.224.03-.45.06-.672a59.114 59.114 0 01.362-2.298c.087-.493.182-.984.268-1.477.06-.347.118-.694.162-1.043.034-.273.055-.55.063-.825.011-.332.003-.665.002-.998 0-.077.004-.155-.01-.23-.028-.142-.01-.155-.162-.19a5.826 5.826 0 00-.607-.107c-.146-.018-.207-.053-.221-.19-.006-.049-.025-.098-.041-.146-.009-.025-.024-.048-.046-.09l-.025.264c-.009.096-.029.116-.127.115-.055 0-.11-.008-.164-.008-.476 0-.952-.008-1.426.032-.095.008-.173-.015-.226-.103-.04-.066-.088-.126-.134-.186-.063-.084-.086-.093-.182-.06-.195.068-.388.138-.582.21a2.71 2.71 0 00-.675.394.986.986 0 01-.323.168c-.033.01-.07.008-.127.013.02-.066.024-.114.047-.15.064-.105.135-.205.205-.306.023-.033.049-.063.073-.095l-.015-.023-.201.037c-.146.04-.296.07-.437.122-.148.053-.266.023-.386-.072a3.623 3.623 0 01-.733-.786l-.093-.132zm8.592 8.963l-.147.09c-.22.134-.44.266-.659.402-.093.058-.184.12-.27.188-.085.07-.124.161-.072.272.047.1.093.2.147.294.047.08.124.138.213.147.11.01.228.012.336-.012.217-.05.372-.205.528-.357a.291.291 0 00.087-.308c-.046-.18-.079-.365-.118-.547-.011-.052-.027-.103-.045-.169zm-.257-2.409c-.12.291-.205.597-.325.91-.151.433-.294.87-.435 1.323.036-.01.054-.01.067-.018.261-.16.522-.324.785-.484.054-.033.071-.078.065-.138-.012-.13-.024-.262-.034-.393l-.068-.886c-.008-.103-.02-.206-.029-.31-.009 0-.017-.002-.026-.004zm3.081-8.13l.099.285c.08.231.159.463.24.714l.58 1.952c.187.63.372 1.262.558 1.893.114.382.235.762.343 1.146.072.257.126.519.186.799.044.206.087.413.127.64.034.106.023.226.077.325l.025-.006-.068-.362c-.038-.206-.077-.412-.113-.638-.015-.07-.029-.141-.046-.211-.095-.396-.177-.796-.29-1.187-.196-.685-.413-1.364-.618-2.046-.165-.549-.322-1.1-.488-1.648-.069-.227-.15-.45-.226-.695l-.117-.336c-.037-.107-.075-.216-.115-.322-.04-.106-.084-.21-.127-.314a7.558 7.558 0 01-.027.01zM6.225 14.304c-.063-.001-.115.014-.134.083a.35.35 0 00.41.012 4.533 4.533 0 00-.276-.095zM5.23 11.98c-.026-.027-.057-.048-.075.002-.012.032-.007.07-.01.113.082-.037.082-.037.085-.115zm.062-1.189a.135.135 0 00-.088.056.197.197 0 00-.025.11c.005.152.01.306.026.457a.751.751 0 00.066.218c.061.136.157.167.288.101.055-.027.06-.054.025-.11a4.52 4.52 0 01-.129-.211c-.015-.068-.066-.131-.033-.207.04-.09-.076-.116-.074-.19V10.874c-.003-.038-.006-.087-.056-.083zm-.017-.968a.867.867 0 00-.467.127c-.076.045-.084.07-.05.158.034.087.07.173.115.254.064.117.09.125.21.077a.657.657 0 01.336-.053c.202.022.357.136.504.264l.092.077c.007-.006.014-.013.022-.018-.019-.105-.035-.226-.149-.264-.157-.053-.324-.075-.508-.117l-.24-.005c.24-.169.452-.044.687.009-.063-.115-.153-.147-.23-.193-.082-.05-.17-.092-.25-.144-.06-.037-.12-.08-.072-.172zm10.233.325c-.23-.01-.427.08-.608.211-.034.026-.06.065-.105.117.087.026.15.046.232.065.044-.015.088-.03.13-.046.306-.114.61-.115.904.031.126.063.237.04.366-.005-.02-.031-.03-.054-.045-.071a.986.986 0 00-.448-.273c-.14-.044-.284-.024-.426-.03zM7.99 6.483a.308.308 0 00.002.133c.08.321.156.643.242.962.104.387.27.75.456 1.103.02.037.061.08.098.087a.404.404 0 00.253-.051l-.472-.84c-.23-.448-.405-.92-.579-1.394zM10.397.497c-.2-.008-.405.004-.603.034-.236.035-.47.087-.7.152-.287.08-.569.18-.852.273-.04.013-.074.038-.11.058.028.014.05.018.07.014.287-.068.58-.085.873-.09.134-.002.269.009.402.025.19.024.382.048.57.09.456.104.874.3 1.265.556.464.306.888.66 1.257 1.078.205.232.395.475.56.739.17.274.315.561.449.856.273.601.456 1.232.6 1.876.04.173.07.348.1.524.017.104.065.167.17.19.122.028.2.105.22.251-.003.102-.06.174-.129.24a1.065 1.065 0 00-.268.358.164.164 0 00.083-.039c.08-.086.162-.172.235-.265a.56.56 0 00.13-.333c.009-.05.022-.1.024-.15.007-.124-.017-.15-.143-.168-.025-.004-.049-.014-.073-.015-.082-.007-.125-.063-.137-.131-.033-.198-.004-.355.247-.408.086-.018.174-.03.26-.042.158-.023.315-.053.473-.067.14-.012.19.033.226.167.008.029.018.057.021.087.019.179-.008.225-.141.288-.027.013-.055.024-.078.042a.148.148 0 00-.051.067c-.039.144.073.382.206.445l.673.32c.023.011.05.015.075.023l.018-.026c-.015-.008-.032-.013-.044-.024a2.27 2.27 0 00-.544-.32 4.898 4.898 0 00-.173-.075.203.203 0 01-.126-.191c-.003-.085.045-.154.128-.187l.059-.025c.099-.044.118-.076.112-.187a.384.384 0 00-.008-.063c-.067-.294-.123-.59-.205-.88a9.478 9.478 0 00-.826-2.036 7.465 7.465 0 00-1.39-1.805 4.536 4.536 0 00-1.177-.824 3.656 3.656 0 00-1.016-.328 6.155 6.155 0 00-.712-.074zm6.719 5.955c.01.014.018.028.038.034l-.022-.044-.016.01zM4.103 3.917a.062.062 0 01-.03.012.455.455 0 01-.04.039c-.01.01-.02.02-.045.04l-.363.354c-.088.085-.17.178-.266.253-.284.22-.425.53-.544.855a.132.132 0 00-.007.071c.013.055.033.108.052.168l.074.026c-.017.056-.03.105-.047.152-.058.164-.118.327-.175.491-.005.015.008.036.019.077.08-.175.158-.33.225-.489.228-.544.484-1.074.819-1.561.09-.133.182-.266.283-.401.004-.006.007-.013.022-.03.001-.016.003-.032.015-.04l.008-.017zm12.976 2.408a.023.023 0 01.009.019.073.073 0 00-.006.01.188.188 0 00.007.02l.018.022c.002-.007.007-.016.005-.021-.003-.01-.012-.018-.02-.038a1.331 1.331 0 01-.013-.012zM4.199 4.48c-.003.004-.008.008-.027.014-.005.013-.011.025-.031.047a2.085 2.085 0 01-.124.167c-.048.07-.116.055-.181.041-.134-.028-.228.016-.287.143-.089.187-.187.37-.273.56-.049.108-.11.216-.118.36.081.003.154.007.228.008h.228a2.563 2.563 0 01-.079.264c-.01.052-.022.103-.033.155l.02.004c.018-.046.037-.092.067-.153.066-.142.13-.285.2-.426.02-.04.034-.1.116-.092 0 .043.004.084 0 .124-.005.045-.017.09-.028.143.141.043.086.174.115.269.102-.022.104-.195.248-.144v.205l.017.002.439-1.059c-.13 0-.246-.02-.358.033-.024.011-.058-.001-.108-.004.075-.15.139-.278.211-.417a.128.128 0 01.025-.036c0-.015-.001-.03.008-.038l.006-.02c-.005.006-.01.011-.028.017-.004.012-.009.024-.026.045a.085.085 0 01-.032.033c-.123.157-.09.164-.258.106-.079-.027-.078-.028-.047-.144.028-.046.056-.093.098-.15 0-.016-.001-.032.007-.042L4.2 4.48zm2.073-.67c-.003.006-.007.011-.027.016-.094.125-.194.246-.28.377-.155.238-.301.481-.451.723-.14.224-.345.368-.575.481-.017.008-.04.006-.079.011.012-.059.016-.109.033-.153a6.076 6.076 0 01.229-.518l-.007-.02a.138.138 0 01-.035.025c-.028.05-.055.1-.093.164-.26.424-.443.817-.442.95.024.004.048.011.073.013.177.013.188.007.26-.165.03-.07.077-.12.147-.15l.175-.07c.044-.018.085-.057.146-.032.003.05-.01.11.014.145.042.062.044.125.047.193.002.049.017.098.026.147.029-.034.039-.065.05-.097.142-.39.277-.782.428-1.17.1-.256.22-.504.33-.756.013-.03.013-.067.03-.092V3.81zm3.987-.34c0 .045.01.084.021.123.042.16.094.318.124.48.024.133.023.27.028.406 0 .033-.019.067-.032.11-.094-.058-.047-.158-.106-.215h-.125c-.015.072-.01.152-.046.2-.066.085-.155.154-.236.227-.043.038-.078.018-.103-.025l-.046-.087c-.065.035-.117.069-.172.093-.116.051-.235.095-.35.147-.085.038-.09.053-.07.147.014.075.034.148.047.223.013.072.05.109.123.124.233.05.462.115.657.265.058-.102.058-.102.168-.151.03-.014.06-.03.092-.042.08-.03.115-.017.15.06.023.048.041.098.066.158.06-.14-.042-.267.017-.416.157.18.24.39.375.567a.235.235 0 00.022-.098c.002-.124 0-.247.002-.371 0-.034.013-.067.02-.1l.032-.003c.11.155.13.354.226.52a3.036 3.036 0 00-.01-.392c-.004-.045 0-.074.05-.088.08.036.116.14.215.158-.03-.275-.423-1.137-.798-1.635-.114-.127-.2-.28-.34-.386zm-2.667.696c-.019.034-.03.05-.037.067-.061.185-.125.37-.18.556-.031.105-.087.169-.195.19-.09.019-.178.052-.268.073-.038.009-.089.015-.118-.003-.024-.016-.025-.069-.036-.106-.064.076-.082.087-.17.047-.133-.062-.262-.135-.393-.201-.048-.025-.093-.063-.17-.03-.043.12-.091.25-.137.382-.099.28-.087.242.095.453.046.048.102.03.154.023.054-.009.106-.03.16-.036.13-.013.26-.08.367-.015.204-.064.387-.122.571-.178.05-.015.089.005.114.054.022.042.034.093.082.121.038-.056-.013-.128.063-.178l.14.241-.042-1.46zm.278.358c-.096-.01-.107.01-.11.108-.002.038-.003.078.002.115.03.2.099.386.174.57.002.006.012.01.022.015l.078-.05c.052.036.081.088.153.088.205-.002.41.014.616.012.099-.001.158.042.205.12.018.03.024.077.088.066l-.08-.394c-.05-.195-.085-.395-.172-.589-.057.057-.114.068-.18.046a.72.72 0 00-.135-.028c-.22-.028-.44-.059-.66-.08zm10.254-1.727c.089.163.155.316.139.491-.016.168.026.342-.044.516-.047-.033-.088-.082-.112-.075-.117.035-.164-.057-.227-.115a4.772 4.772 0 01-.286-.29l-.104-.113a4.856 4.856 0 01-.023.019c.035.046.07.093.11.156.04.064.084.127.122.193.034.058.065.118.031.205-.082-.01-.164-.019-.246-.032-.06-.01-.101 0-.124.07-.031.098-.037.096-.15.09.02.042.036.08.057.116.041.074.03.138-.03.196-.06.06-.118.122-.178.181a.175.175 0 01-.185.046c-.222-.061-.447-.113-.67-.174-.032-.009-.063-.04-.086-.068-.03-.04-.052-.087-.08-.13-.044-.07-.09-.138-.136-.207a.18.18 0 00-.014.105c.012.127.03.253.035.38.005.1-.024.12-.121.104-.104-.017-.206-.04-.31-.058-.064-.012-.131-.028-.202.03l.081.208c.09 0 .166-.01.237.002a.819.819 0 01.458.251c.078.083.154.168.241.26l.018-.005c-.004-.006-.008-.013-.01-.04.014-.056-.062-.118.018-.178.031.03.064.057.088.09.058.078.111.159.169.257l.089.141.024-.013a2093.819 2093.819 0 01-.427-.934c.055.007.083.007.108.016.193.07.385.142.577.216.074.028.147.06.219.094.062.028.112.018.157-.033.05-.056.102-.112.154-.167.05-.051.095-.046.132.014.016.025.026.053.04.08.071.138.143.277.217.433l.159.308.025-.011c-.044-.106-.07-.218-.138-.334-.057-.182-.168-.346-.206-.545.136.034.362.326.567.732l.057.074.018-.011a1.563 1.563 0 01-.052-.127c-.046-.145-.097-.29-.136-.436-.022-.083-.036-.173.022-.26l.109.058-.026-.207.027-.016c.022.02.05.036.065.06.073.108.143.22.215.33.01.016.029.029.043.043-.036-.217-.2-.38-.229-.626l.155.112c.014-.166.012-.319.042-.465.032-.158-.023-.297-.063-.445.024.004.036.006.055.025.092.124.183.249.277.371.02.027.05.047.069.087l.04.063.019-.015a.293.293 0 01-.053-.082 27.922 27.922 0 01-.332-.49c-.221-.311-.363-.467-.485-.521zm-6.57.327c-.003.161.092.275.069.415l-.368.087c.09.139.032.237-.052.331-.05.057-.092.122-.143.178-.037.04-.046.078-.018.126l.16.275c.029.048.072.066.128.064.076-.003.152 0 .228-.001.116-.003.216.022.275.137.006.014.02.024.044.052.004-.059-.003-.098.01-.13.016-.04.04-.099.072-.108.084-.023.173-.024.26-.03.013-.001.027.018.04.029l.071.065c.019-.11-.082-.198-.024-.31l.126.04c-.026-.123-.07-.245-.071-.366 0-.123.051-.243.115-.36.107.062.16.156.234.253.183.265.36.533.494.834.165-.078.27.068.407.088-.003-.106-.133-.441-.197-.492a.142.142 0 00-.102-.028c-.06.011-.119.039-.191.063-.025-.039-.056-.078-.077-.122a3.936 3.936 0 00-.473-.783c-.076-.094-.16-.182-.228-.26l-.391.285c-.049.035-.094.03-.132-.017l-.169-.207c-.025-.03-.053-.059-.097-.108z"></path></svg>
@@ -27,7 +27,7 @@
27
27
  import type { IntegrationType } from "@/src/hooks/types";
28
28
 
29
29
  /** Canonical CLI ids the registry knows about. Mirrors `INTEGRATION_TYPES`. */
30
- export const KNOWN_CLI_IDS = ["claude", "codex", "copilot", "cursor", "opencode", "pi", "gemini"] as const satisfies readonly IntegrationType[];
30
+ export const KNOWN_CLI_IDS = ["claude", "codex", "copilot", "cursor", "opencode", "pi", "gemini", "hermes"] as const satisfies readonly IntegrationType[];
31
31
  export type CliId = (typeof KNOWN_CLI_IDS)[number];
32
32
 
33
33
  /** Per-CLI metadata consumed by the dashboard. */
@@ -74,6 +74,11 @@ const CLI_ENTRIES: Record<CliId, CliEntry> = {
74
74
  label: "Gemini CLI",
75
75
  badgeClasses: "bg-sky-500/10 text-sky-400 border-sky-500/20",
76
76
  },
77
+ hermes: {
78
+ id: "hermes",
79
+ label: "Hermes",
80
+ badgeClasses: "bg-indigo-500/10 text-indigo-400 border-indigo-500/20",
81
+ },
77
82
  };
78
83
 
79
84
  export function getCliEntry(id: string): CliEntry | undefined {
@@ -14,6 +14,11 @@ import { resolveSessionFilePath, UUID_RE } from "./projects";
14
14
  import type { CliId } from "./cli-registry";
15
15
 
16
16
  export const OPENCODE_SESSION_RE = /^ses_[A-Za-z0-9]+$/;
17
+ /** Hermes session IDs (e.g. `YYYYMMDD_HHMMSS_<hash>` / `cron_<hash>_...`). Kept
18
+ * in sync with `getHermesSessionLog`'s validator in lib/hermes-sessions.ts —
19
+ * a stricter pattern here would let a session list/open in the viewer yet fail
20
+ * its download with `RangeError("Invalid session ID")`. */
21
+ export const HERMES_SESSION_RE = /^[A-Za-z0-9_-]+$/;
17
22
 
18
23
  export type DownloadSource =
19
24
  | { kind: "file"; path: string }
@@ -23,6 +28,7 @@ export type DownloadSource =
23
28
  * prefixes; everyone else is a UUID. */
24
29
  export function isValidSessionId(cli: CliId, sessionId: string): boolean {
25
30
  if (cli === "opencode") return OPENCODE_SESSION_RE.test(sessionId);
31
+ if (cli === "hermes") return HERMES_SESSION_RE.test(sessionId);
26
32
  return UUID_RE.test(sessionId);
27
33
  }
28
34
 
@@ -85,6 +91,16 @@ export async function resolveDownloadSource(
85
91
  return { kind: "synthesized", body, contentType: "application/json", extension: "json" };
86
92
  }
87
93
 
94
+ if (cli === "hermes") {
95
+ // Hermes keeps sessions in SQLite (~/.hermes/state.db). Synthesize a JSONL
96
+ // export of the session's raw `messages` rows.
97
+ const { getHermesSessionLog } = await import("./hermes-sessions");
98
+ const result = await getHermesSessionLog(sessionId);
99
+ if (!result) return null;
100
+ const body = result.rawLines.map((r) => JSON.stringify(r)).join("\n") + "\n";
101
+ return { kind: "synthesized", body, contentType: "application/x-ndjson", extension: "jsonl" };
102
+ }
103
+
88
104
  // Exhaustive — but TypeScript can't always see CliId is exhausted across the
89
105
  // if-chain above, so guard with a runtime fallback.
90
106
  const _exhaustive: never = cli;
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Hermes (hermes-agent) session enumeration — AUDIT-ONLY.
3
+ *
4
+ * Reads the `sessions` table directly from `~/.hermes/state.db` via the bundled
5
+ * sql.js reader. All gateway users' sessions live in the one DB → "audit
6
+ * everyone from one place". Because we query the table (not a text `sessions
7
+ * list`), we get `source`/`cwd`/`message_count` up front — enough to group by
8
+ * channel and to build a real per-transcript cache key.
9
+ */
10
+ import { openSqliteReadonly } from "./sqlite-reader";
11
+ import { hermesDbPath, epochToMs } from "./hermes-sessions";
12
+ import { runtimeCache } from "./runtime-cache";
13
+ import type { ProjectFolder, SessionFile } from "./projects";
14
+ import { formatDate } from "./format-date";
15
+
16
+ export interface HermesSessionRef {
17
+ sessionId: string;
18
+ source?: string;
19
+ cwd?: string;
20
+ title?: string;
21
+ /** Slack/Telegram user that drove the session. */
22
+ userId?: string;
23
+ /** Channel id + type (group/dm) the session ran in. */
24
+ chatId?: string;
25
+ chatType?: string;
26
+ /** From `ended_at` (falls back to `started_at`) — epoch ms. */
27
+ mtimeMs: number;
28
+ /** `message_count` — a stable cache key for an ended session. Can lag (Hermes
29
+ * may write it lazily / only at session end), so don't use it alone to decide
30
+ * emptiness. */
31
+ messageCount: number;
32
+ /** True when the session has ≥1 real message row (`MAX(messages.timestamp)`
33
+ * non-null). Reliable "non-empty" signal even when `message_count` is a
34
+ * stale `0` for an in-progress session. */
35
+ hasMessages: boolean;
36
+ }
37
+
38
+ interface SessionRow {
39
+ id: string;
40
+ source: string | null;
41
+ cwd: string | null;
42
+ title: string | null;
43
+ user_id: string | null;
44
+ chat_id: string | null;
45
+ chat_type: string | null;
46
+ started_at: number | null;
47
+ ended_at: number | null;
48
+ message_count: number | null;
49
+ /** MAX(messages.timestamp) — the real last-activity time; advances on every
50
+ * new message even while the session is still open (ended_at is null). */
51
+ last_activity: number | null;
52
+ }
53
+
54
+ /**
55
+ * List every Hermes session (all users). Returns `[]` when the DB is missing or
56
+ * unreadable (fail-open — the audit just skips Hermes).
57
+ */
58
+ export async function getHermesSessions(): Promise<HermesSessionRef[]> {
59
+ const db = await openSqliteReadonly(hermesDbPath());
60
+ if (!db) return [];
61
+ try {
62
+ const rows = db.query<SessionRow>(
63
+ "SELECT s.id, s.source, s.cwd, s.title, s.user_id, s.chat_id, s.chat_type, " +
64
+ "s.started_at, s.ended_at, s.message_count, lm.last_activity " +
65
+ "FROM sessions s " +
66
+ "LEFT JOIN (SELECT session_id, MAX(timestamp) AS last_activity FROM messages GROUP BY session_id) lm " +
67
+ "ON lm.session_id = s.id " +
68
+ "ORDER BY lm.last_activity DESC",
69
+ );
70
+ return rows.map((r) => ({
71
+ sessionId: r.id,
72
+ source: r.source ?? undefined,
73
+ cwd: r.cwd ?? undefined,
74
+ title: r.title ?? undefined,
75
+ userId: r.user_id ?? undefined,
76
+ chatId: r.chat_id ?? undefined,
77
+ chatType: r.chat_type ?? undefined,
78
+ // Prefer the latest message time (advances live); fall back to ended/started.
79
+ mtimeMs: epochToMs(r.last_activity ?? r.ended_at ?? r.started_at),
80
+ messageCount: typeof r.message_count === "number" ? r.message_count : 0,
81
+ hasMessages: r.last_activity != null,
82
+ }));
83
+ } catch {
84
+ return [];
85
+ } finally {
86
+ db.close();
87
+ }
88
+ }
89
+
90
+ export const getCachedHermesSessions = runtimeCache(getHermesSessions, 2);
91
+
92
+ // ── Dashboard history browser (projects list + project-detail sessions) ──
93
+
94
+ /**
95
+ * Surface Hermes gateway sessions as synthetic "projects" grouped by `source`
96
+ * (slack/telegram/cli/cron) — gateway sessions have no cwd to group by. One
97
+ * ProjectFolder per source; its `name` is `hermes-<source>`, reversed in
98
+ * `getHermesSessionsByEncodedName`.
99
+ */
100
+ export async function getHermesProjects(): Promise<ProjectFolder[]> {
101
+ const sessions = await getHermesSessions();
102
+ const latestBySource = new Map<string, number>();
103
+ for (const s of sessions) {
104
+ if (s.messageCount <= 0 && !s.hasMessages) continue; // skip empty (message_count can lag; trust real messages)
105
+ const src = s.source ?? "unknown";
106
+ latestBySource.set(src, Math.max(latestBySource.get(src) ?? 0, s.mtimeMs));
107
+ }
108
+ const out: ProjectFolder[] = [];
109
+ for (const [src, latest] of latestBySource) {
110
+ const lastModified = new Date(latest);
111
+ out.push({
112
+ name: `hermes-${src}`,
113
+ path: `hermes:${src}`,
114
+ isDirectory: true,
115
+ lastModified,
116
+ lastModifiedFormatted: formatDate(lastModified),
117
+ cli: ["hermes"],
118
+ });
119
+ }
120
+ out.sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime());
121
+ return out;
122
+ }
123
+
124
+ export interface HermesProjectByName {
125
+ cwd: string | null;
126
+ sessions: SessionFile[];
127
+ }
128
+
129
+ /**
130
+ * Resolve the Hermes sessions for a synthetic project name (`hermes-<source>`),
131
+ * for the project-detail page. Non-Hermes names resolve to empty.
132
+ */
133
+ export async function getHermesSessionsByEncodedName(
134
+ name: string,
135
+ ): Promise<HermesProjectByName> {
136
+ if (!name.startsWith("hermes-")) return { cwd: null, sessions: [] };
137
+ const source = name.slice("hermes-".length);
138
+ const sessions = await getHermesSessions();
139
+ const matched = sessions.filter((s) => (s.messageCount > 0 || s.hasMessages) && (s.source ?? "unknown") === source);
140
+ return {
141
+ cwd: `hermes:${source}`,
142
+ sessions: matched.map((s) => {
143
+ const lastModified = new Date(s.mtimeMs);
144
+ return {
145
+ name: s.title ?? s.sessionId,
146
+ path: `hermes://${s.sessionId}`,
147
+ lastModified,
148
+ lastModifiedFormatted: formatDate(lastModified),
149
+ sessionId: s.sessionId,
150
+ cli: "hermes" as const,
151
+ userId: s.userId,
152
+ channelId: s.chatId,
153
+ channelType: s.chatType,
154
+ };
155
+ }),
156
+ };
157
+ }
158
+
159
+ export const getCachedHermesProjects = runtimeCache(getHermesProjects, 2);
160
+ export const getCachedHermesSessionsByEncodedName = runtimeCache(
161
+ (name: string) => getHermesSessionsByEncodedName(name),
162
+ 2,
163
+ { maxSize: 50 },
164
+ );
@@ -0,0 +1,273 @@
1
+ /**
2
+ * Hermes (hermes-agent) session transcript loader + parser.
3
+ *
4
+ * AUDIT-ONLY (Pillar 2). Hermes stores every gateway user's sessions in one
5
+ * SQLite DB (`~/.hermes/state.db`). We read it DIRECTLY via the bundled sql.js
6
+ * driver (lib/sqlite-reader.ts) — a reusable path for SQLite-backed agents.
7
+ * (opencode and the already-shipped CLIs keep their CLI shell-out unchanged.)
8
+ *
9
+ * Message shape is OpenAI Chat-Completions style (verified live): assistant tool
10
+ * calls are `tool_calls[].function.{name, arguments}` (stored as a JSON string
11
+ * column) and results are separate `role:"tool"` rows keyed by `tool_call_id`.
12
+ * `hermesRowsToLogEntries` pairs them (mirrors `lib/codex-sessions.ts`) and is a
13
+ * PURE function of the message rows, so it is unit-testable without a DB.
14
+ *
15
+ * DB path override: set `HERMES_DB_PATH` (used by tests and to point at a copied
16
+ * or remote state.db).
17
+ */
18
+ import { homedir } from "node:os";
19
+ import { join } from "node:path";
20
+ import { openSqliteReadonly } from "./sqlite-reader";
21
+ import { runtimeCache } from "./runtime-cache";
22
+ import {
23
+ baseEntry,
24
+ formatTimestamp,
25
+ type LogEntry,
26
+ type UserEntry,
27
+ type AssistantEntry,
28
+ type GenericEntry,
29
+ type ContentBlock,
30
+ type ToolUseBlock,
31
+ type LogSource,
32
+ } from "./log-entries";
33
+ import { formatDuration } from "./format-duration";
34
+
35
+ /** Absolute path to Hermes's SQLite DB (override with HERMES_DB_PATH). */
36
+ export function hermesDbPath(): string {
37
+ return process.env.HERMES_DB_PATH || join(homedir(), ".hermes", "state.db");
38
+ }
39
+
40
+ /** Coerce a Hermes epoch value (seconds or ms) to epoch ms. Hermes stores
41
+ * `started_at`/`ended_at`/`timestamp` as REAL epoch seconds. */
42
+ export function epochToMs(value: unknown): number {
43
+ if (typeof value === "number" && Number.isFinite(value)) {
44
+ if (value > 1e12) return value; // already ms
45
+ if (value > 1e9) return value * 1000; // seconds
46
+ }
47
+ return Date.now();
48
+ }
49
+
50
+ // ── Parsing helpers ──
51
+
52
+ function safeJsonParse(s: unknown): unknown {
53
+ if (typeof s !== "string" || s.length === 0) return undefined;
54
+ try {
55
+ return JSON.parse(s);
56
+ } catch {
57
+ return undefined;
58
+ }
59
+ }
60
+
61
+ function isPlainObject(v: unknown): v is Record<string, unknown> {
62
+ return !!v && typeof v === "object" && !Array.isArray(v);
63
+ }
64
+
65
+ /** Text from a `content` field that may be a string or an array of
66
+ * `{ type:"text", text }` blocks. */
67
+ function extractText(content: unknown): string {
68
+ if (typeof content === "string") return content;
69
+ if (Array.isArray(content)) {
70
+ return content
71
+ .map((c) => (isPlainObject(c) && typeof c.text === "string" ? (c.text as string) : ""))
72
+ .filter(Boolean)
73
+ .join("\n");
74
+ }
75
+ return "";
76
+ }
77
+
78
+ function toDate(value: unknown, fallbackMs: number): Date {
79
+ if (typeof value === "number" && Number.isFinite(value)) {
80
+ if (value > 1e12) return new Date(value);
81
+ if (value > 1e9) return new Date(value * 1000);
82
+ }
83
+ if (typeof value === "string") {
84
+ const ms = Date.parse(value);
85
+ if (!Number.isNaN(ms)) return new Date(ms);
86
+ }
87
+ return new Date(fallbackMs);
88
+ }
89
+
90
+ interface NormalizedToolCall {
91
+ id: string;
92
+ name: string;
93
+ input: Record<string, unknown>;
94
+ }
95
+
96
+ /** Normalize `tool_calls` (array, or the JSON-string column Hermes stores) into
97
+ * `{ id, name, input }[]`. OpenAI shape: `{ id|call_id, function:{ name,
98
+ * arguments } }` where `arguments` is itself a JSON string. */
99
+ function normalizeToolCalls(raw: unknown): NormalizedToolCall[] {
100
+ const arr = Array.isArray(raw) ? raw : safeJsonParse(raw);
101
+ if (!Array.isArray(arr)) return [];
102
+ const out: NormalizedToolCall[] = [];
103
+ for (const tc of arr) {
104
+ if (!isPlainObject(tc)) continue;
105
+ const fn = isPlainObject(tc.function) ? tc.function : {};
106
+ const name =
107
+ typeof fn.name === "string"
108
+ ? fn.name
109
+ : typeof tc.name === "string"
110
+ ? (tc.name as string)
111
+ : "tool";
112
+ const id =
113
+ (typeof tc.id === "string" && tc.id) ||
114
+ (typeof tc.call_id === "string" && tc.call_id) ||
115
+ `${name}-${out.length}`;
116
+ const parsedArgs = isPlainObject(fn.arguments) ? fn.arguments : safeJsonParse(fn.arguments);
117
+ out.push({ id, name, input: isPlainObject(parsedArgs) ? parsedArgs : {} });
118
+ }
119
+ return out;
120
+ }
121
+
122
+ // ── Pure parser: message rows → LogEntry[] ──
123
+
124
+ /**
125
+ * Convert `messages`-table rows (ordered by timestamp) into `LogEntry[]`.
126
+ * Pairs each assistant `tool_calls` entry with its later `role:"tool"` result
127
+ * by `tool_call_id`. Roles other than user/assistant/tool (e.g. Hermes's
128
+ * `session_meta`) become generic system entries so nothing is dropped. Pure —
129
+ * unit-testable with plain row objects.
130
+ */
131
+ export function hermesRowsToLogEntries(
132
+ rows: Record<string, unknown>[],
133
+ source: LogSource = "session",
134
+ ): LogEntry[] {
135
+ const entries: LogEntry[] = [];
136
+ const toolUseById = new Map<string, ToolUseBlock>();
137
+ const toolUseStartMs = new Map<string, number>();
138
+ const baseMs = Date.now();
139
+
140
+ for (let i = 0; i < rows.length; i++) {
141
+ const m = rows[i];
142
+ if (!isPlainObject(m)) continue;
143
+
144
+ const role = typeof m.role === "string" ? m.role : "system";
145
+ const date = toDate(m.timestamp ?? m.time_created, baseMs + i);
146
+ const timestamp = date.toISOString();
147
+ const raw: Record<string, unknown> = {
148
+ uuid: m.id != null ? String(m.id) : `hermes-${i}`,
149
+ parentUuid: null,
150
+ };
151
+ const base = baseEntry(raw, timestamp, date, source);
152
+
153
+ if (role === "user") {
154
+ entries.push({
155
+ type: "user",
156
+ ...base,
157
+ message: { role: "user", content: extractText(m.content) },
158
+ } satisfies UserEntry);
159
+ continue;
160
+ }
161
+
162
+ if (role === "assistant") {
163
+ const blocks: ContentBlock[] = [];
164
+ const text = extractText(m.content);
165
+ if (text) blocks.push({ type: "text", text });
166
+ for (const tc of normalizeToolCalls(m.tool_calls)) {
167
+ const block: ToolUseBlock = { type: "tool_use", id: tc.id, name: tc.name, input: tc.input };
168
+ blocks.push(block);
169
+ toolUseById.set(tc.id, block);
170
+ toolUseStartMs.set(tc.id, date.getTime());
171
+ }
172
+ if (blocks.length === 0) continue; // empty assistant turn
173
+ entries.push({
174
+ type: "assistant",
175
+ ...base,
176
+ message: { role: "assistant", content: blocks },
177
+ } satisfies AssistantEntry);
178
+ continue;
179
+ }
180
+
181
+ if (role === "tool") {
182
+ const callId = typeof m.tool_call_id === "string" ? m.tool_call_id : undefined;
183
+ const block = callId ? toolUseById.get(callId) : undefined;
184
+ if (block) {
185
+ const startMs = (callId && toolUseStartMs.get(callId)) || date.getTime();
186
+ const durationMs = Math.max(0, date.getTime() - startMs);
187
+ block.result = {
188
+ timestamp,
189
+ timestampFormatted: formatTimestamp(date),
190
+ content: extractText(m.content),
191
+ durationMs,
192
+ durationFormatted: formatDuration(durationMs),
193
+ };
194
+ continue;
195
+ }
196
+ // Orphan tool result — fall through to a system entry.
197
+ }
198
+
199
+ entries.push({ type: "system", ...base, raw } satisfies GenericEntry);
200
+ }
201
+
202
+ entries.sort((a, b) => a.timestampMs - b.timestampMs);
203
+ return entries;
204
+ }
205
+
206
+ // ── DB loader ──
207
+
208
+ export interface HermesSessionLogData {
209
+ entries: LogEntry[];
210
+ rawLines: Record<string, unknown>[];
211
+ cwd?: string;
212
+ filePath: string; // synthetic — hermes keeps sessions in a DB; we use hermes://<id>
213
+ }
214
+
215
+ interface HermesMessageRow {
216
+ id: number | null;
217
+ role: string | null;
218
+ content: string | null;
219
+ tool_call_id: string | null;
220
+ tool_calls: string | null;
221
+ tool_name: string | null;
222
+ timestamp: number | null;
223
+ }
224
+
225
+ /**
226
+ * Load one session by ID from `state.db`. Returns `null` when the DB is
227
+ * unavailable or the session doesn't exist.
228
+ */
229
+ export async function getHermesSessionLog(
230
+ sessionId: string,
231
+ ): Promise<HermesSessionLogData | null> {
232
+ if (!sessionId || !/^[A-Za-z0-9_-]+$/.test(sessionId)) return null;
233
+ const db = await openSqliteReadonly(hermesDbPath());
234
+ if (!db) return null;
235
+ try {
236
+ const sessionRows = db.query<{ source: string | null; cwd: string | null }>(
237
+ "SELECT source, cwd FROM sessions WHERE id = ?",
238
+ [sessionId],
239
+ );
240
+ if (sessionRows.length === 0) return null;
241
+ const { source, cwd: realCwd } = sessionRows[0];
242
+
243
+ const msgRows = db.query<HermesMessageRow>(
244
+ "SELECT id, role, content, tool_call_id, tool_calls, tool_name, timestamp " +
245
+ "FROM messages WHERE session_id = ? ORDER BY timestamp ASC",
246
+ [sessionId],
247
+ );
248
+
249
+ const entries = hermesRowsToLogEntries(
250
+ msgRows as unknown as Record<string, unknown>[],
251
+ "session",
252
+ );
253
+ // Gateway sessions have no cwd → group by source (slack/telegram/cli/cron).
254
+ const cwd =
255
+ realCwd && realCwd.length > 0 ? realCwd : source ? `hermes:${source}` : undefined;
256
+ return {
257
+ entries,
258
+ rawLines: msgRows as unknown as Record<string, unknown>[],
259
+ cwd,
260
+ filePath: `hermes://${sessionId}`,
261
+ };
262
+ } catch {
263
+ return null;
264
+ } finally {
265
+ db.close();
266
+ }
267
+ }
268
+
269
+ export const getCachedHermesSessionLog = runtimeCache(
270
+ (sessionId: string) => getHermesSessionLog(sessionId),
271
+ 2,
272
+ { maxSize: 50 },
273
+ );