@runcore-sh/runcore 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (351) hide show
  1. package/dictionary.json +2 -2
  2. package/dist/activity/log.js +2 -2
  3. package/dist/activity/log.js.map +1 -1
  4. package/dist/agents/governed-spawn.d.ts.map +1 -1
  5. package/dist/cli.js +101 -11
  6. package/dist/cli.js.map +1 -1
  7. package/dist/extensions/cache.d.ts +57 -0
  8. package/dist/extensions/cache.d.ts.map +1 -0
  9. package/dist/extensions/cache.js +173 -0
  10. package/dist/extensions/cache.js.map +1 -0
  11. package/dist/extensions/client.d.ts +55 -0
  12. package/dist/extensions/client.d.ts.map +1 -0
  13. package/dist/extensions/client.js +120 -0
  14. package/dist/extensions/client.js.map +1 -0
  15. package/dist/extensions/index.d.ts +13 -0
  16. package/dist/extensions/index.d.ts.map +1 -0
  17. package/dist/extensions/index.js +12 -0
  18. package/dist/extensions/index.js.map +1 -0
  19. package/dist/extensions/loader.d.ts +50 -0
  20. package/dist/extensions/loader.d.ts.map +1 -0
  21. package/dist/extensions/loader.js +166 -0
  22. package/dist/extensions/loader.js.map +1 -0
  23. package/dist/extensions/manifest.d.ts +38 -0
  24. package/dist/extensions/manifest.d.ts.map +1 -0
  25. package/dist/extensions/manifest.js +17 -0
  26. package/dist/extensions/manifest.js.map +1 -0
  27. package/dist/extensions/stubs.d.ts +27 -0
  28. package/dist/extensions/stubs.d.ts.map +1 -0
  29. package/dist/extensions/stubs.js +45 -0
  30. package/dist/extensions/stubs.js.map +1 -0
  31. package/dist/lib/audit.js +2 -2
  32. package/dist/lib/audit.js.map +1 -1
  33. package/dist/lib/brain-migrate.d.ts +21 -0
  34. package/dist/lib/brain-migrate.d.ts.map +1 -0
  35. package/dist/lib/brain-migrate.js +137 -0
  36. package/dist/lib/brain-migrate.js.map +1 -0
  37. package/dist/lib/paths.d.ts +27 -0
  38. package/dist/lib/paths.d.ts.map +1 -1
  39. package/dist/lib/paths.js +65 -0
  40. package/dist/lib/paths.js.map +1 -1
  41. package/dist/llm/call-log.d.ts +40 -0
  42. package/dist/llm/call-log.d.ts.map +1 -0
  43. package/dist/llm/call-log.js +35 -0
  44. package/dist/llm/call-log.js.map +1 -0
  45. package/dist/llm/complete.d.ts +6 -0
  46. package/dist/llm/complete.d.ts.map +1 -1
  47. package/dist/llm/complete.js +27 -0
  48. package/dist/llm/complete.js.map +1 -1
  49. package/dist/mcp-server.js +118 -2
  50. package/dist/mcp-server.js.map +1 -1
  51. package/dist/memory/file-backed.d.ts +4 -0
  52. package/dist/memory/file-backed.d.ts.map +1 -1
  53. package/dist/memory/file-backed.js +4 -0
  54. package/dist/memory/file-backed.js.map +1 -1
  55. package/dist/memory/vector-index.d.ts +4 -12
  56. package/dist/memory/vector-index.d.ts.map +1 -1
  57. package/dist/memory/vector-index.js +11 -93
  58. package/dist/memory/vector-index.js.map +1 -1
  59. package/dist/search/brain-docs.d.ts +17 -7
  60. package/dist/search/brain-docs.d.ts.map +1 -1
  61. package/dist/search/brain-docs.js +170 -52
  62. package/dist/search/brain-docs.js.map +1 -1
  63. package/dist/search/brain-rag.d.ts +45 -0
  64. package/dist/search/brain-rag.d.ts.map +1 -0
  65. package/dist/search/brain-rag.js +275 -0
  66. package/dist/search/brain-rag.js.map +1 -0
  67. package/dist/search/chunker.d.ts +24 -0
  68. package/dist/search/chunker.d.ts.map +1 -0
  69. package/dist/search/chunker.js +95 -0
  70. package/dist/search/chunker.js.map +1 -0
  71. package/dist/search/embedder.d.ts +16 -0
  72. package/dist/search/embedder.d.ts.map +1 -0
  73. package/dist/search/embedder.js +108 -0
  74. package/dist/search/embedder.js.map +1 -0
  75. package/dist/search/file-watcher.d.ts +11 -0
  76. package/dist/search/file-watcher.d.ts.map +1 -0
  77. package/dist/search/file-watcher.js +86 -0
  78. package/dist/search/file-watcher.js.map +1 -0
  79. package/dist/server.d.ts.map +1 -1
  80. package/dist/server.js +168 -20
  81. package/dist/server.js.map +1 -1
  82. package/dist/sessions/store.d.ts +9 -0
  83. package/dist/sessions/store.d.ts.map +1 -1
  84. package/dist/sessions/store.js.map +1 -1
  85. package/dist/settings.d.ts +26 -0
  86. package/dist/settings.d.ts.map +1 -1
  87. package/dist/settings.js +78 -2
  88. package/dist/settings.js.map +1 -1
  89. package/dist/tracing/init.d.ts +1 -1
  90. package/dist/tracing/init.d.ts.map +1 -1
  91. package/dist/utils/logger.js +2 -2
  92. package/dist/utils/logger.js.map +1 -1
  93. package/module-tiers.json +164 -0
  94. package/package.json +9 -13
  95. package/public/avatar/cache/1184385ec5522b57.mp4 +0 -0
  96. package/public/avatar/cache/1f15f6a1ebd7e439.mp4 +0 -0
  97. package/public/avatar/cache/2c7e47ff0bdeb8d1.mp4 +0 -0
  98. package/public/avatar/cache/5f308566f7abb8f2.mp4 +0 -0
  99. package/public/avatar/cache/62f9cfba848d724e.mp4 +0 -0
  100. package/public/avatar/cache/6d64e657e6bf2aab.mp4 +0 -0
  101. package/public/avatar/cache/763ad0349e0b6f26.mp4 +0 -0
  102. package/public/avatar/cache/81a516cfd461b2b9.mp4 +0 -0
  103. package/public/avatar/cache/9366de15fd6910ca.mp4 +0 -0
  104. package/public/avatar/cache/ade41a846b283895.mp4 +0 -0
  105. package/public/avatar/cache/b6066e5c65383eec.mp4 +0 -0
  106. package/public/avatar/cache/edadb75d37891fc7.mp4 +0 -0
  107. package/public/avatar/cache/f0ae159640621dd9.mp4 +0 -0
  108. package/public/avatar/cache/fc2e5419adf29d96.mp4 +0 -0
  109. package/public/index.html +379 -59
  110. package/dist/agents/autonomous.js +0 -749
  111. package/dist/agents/autonomous.js.map +0 -1
  112. package/dist/agents/commit.js +0 -113
  113. package/dist/agents/commit.js.map +0 -1
  114. package/dist/agents/continue.js +0 -158
  115. package/dist/agents/continue.js.map +0 -1
  116. package/dist/agents/cooldown.js +0 -397
  117. package/dist/agents/cooldown.js.map +0 -1
  118. package/dist/agents/dedup-guard.js +0 -131
  119. package/dist/agents/dedup-guard.js.map +0 -1
  120. package/dist/agents/feed.js +0 -176
  121. package/dist/agents/feed.js.map +0 -1
  122. package/dist/agents/governance.js +0 -292
  123. package/dist/agents/governance.js.map +0 -1
  124. package/dist/agents/governed-spawn.js +0 -192
  125. package/dist/agents/governed-spawn.js.map +0 -1
  126. package/dist/agents/heartbeat.js +0 -324
  127. package/dist/agents/heartbeat.js.map +0 -1
  128. package/dist/agents/instance-manager.js +0 -850
  129. package/dist/agents/instance-manager.js.map +0 -1
  130. package/dist/agents/issue-reporter.js +0 -123
  131. package/dist/agents/issue-reporter.js.map +0 -1
  132. package/dist/agents/issues.js +0 -141
  133. package/dist/agents/issues.js.map +0 -1
  134. package/dist/agents/locks.js +0 -234
  135. package/dist/agents/locks.js.map +0 -1
  136. package/dist/agents/memory.js +0 -93
  137. package/dist/agents/memory.js.map +0 -1
  138. package/dist/agents/monitor.js +0 -235
  139. package/dist/agents/monitor.js.map +0 -1
  140. package/dist/agents/orchestration.js +0 -715
  141. package/dist/agents/orchestration.js.map +0 -1
  142. package/dist/agents/recover.js +0 -166
  143. package/dist/agents/recover.js.map +0 -1
  144. package/dist/agents/reflection.js +0 -199
  145. package/dist/agents/reflection.js.map +0 -1
  146. package/dist/agents/runtime/bus.js +0 -174
  147. package/dist/agents/runtime/bus.js.map +0 -1
  148. package/dist/agents/runtime/config.js +0 -101
  149. package/dist/agents/runtime/config.js.map +0 -1
  150. package/dist/agents/runtime/driver.js +0 -214
  151. package/dist/agents/runtime/driver.js.map +0 -1
  152. package/dist/agents/runtime/errors.js +0 -40
  153. package/dist/agents/runtime/errors.js.map +0 -1
  154. package/dist/agents/runtime/index.js +0 -54
  155. package/dist/agents/runtime/index.js.map +0 -1
  156. package/dist/agents/runtime/lifecycle.js +0 -116
  157. package/dist/agents/runtime/lifecycle.js.map +0 -1
  158. package/dist/agents/runtime/manager.js +0 -948
  159. package/dist/agents/runtime/manager.js.map +0 -1
  160. package/dist/agents/runtime/registry.js +0 -195
  161. package/dist/agents/runtime/registry.js.map +0 -1
  162. package/dist/agents/runtime/resources.js +0 -146
  163. package/dist/agents/runtime/resources.js.map +0 -1
  164. package/dist/agents/runtime/types.js +0 -24
  165. package/dist/agents/runtime/types.js.map +0 -1
  166. package/dist/agents/spawn-policy.js +0 -202
  167. package/dist/agents/spawn-policy.js.map +0 -1
  168. package/dist/agents/spawn.js +0 -970
  169. package/dist/agents/spawn.js.map +0 -1
  170. package/dist/agents/triage.js +0 -81
  171. package/dist/agents/triage.js.map +0 -1
  172. package/dist/agents/workflow.js +0 -543
  173. package/dist/agents/workflow.js.map +0 -1
  174. package/dist/avatar/client.js +0 -172
  175. package/dist/avatar/client.js.map +0 -1
  176. package/dist/avatar/sidecar.js +0 -125
  177. package/dist/avatar/sidecar.js.map +0 -1
  178. package/dist/browser/sessions.js +0 -122
  179. package/dist/browser/sessions.js.map +0 -1
  180. package/dist/capabilities/definitions/browser.js +0 -242
  181. package/dist/capabilities/definitions/browser.js.map +0 -1
  182. package/dist/channels/whatsapp.js +0 -200
  183. package/dist/channels/whatsapp.js.map +0 -1
  184. package/dist/credentials/store.js +0 -189
  185. package/dist/credentials/store.js.map +0 -1
  186. package/dist/files/deep-index.js +0 -337
  187. package/dist/files/deep-index.js.map +0 -1
  188. package/dist/files/extract.js +0 -33
  189. package/dist/files/extract.js.map +0 -1
  190. package/dist/files/gdrive.js +0 -246
  191. package/dist/files/gdrive.js.map +0 -1
  192. package/dist/github/client.js +0 -408
  193. package/dist/github/client.js.map +0 -1
  194. package/dist/github/commit-analysis.js +0 -276
  195. package/dist/github/commit-analysis.js.map +0 -1
  196. package/dist/github/contributor-stats.js +0 -119
  197. package/dist/github/contributor-stats.js.map +0 -1
  198. package/dist/github/issue-sla.js +0 -220
  199. package/dist/github/issue-sla.js.map +0 -1
  200. package/dist/github/issue-triage.js +0 -286
  201. package/dist/github/issue-triage.js.map +0 -1
  202. package/dist/github/pr-readiness.js +0 -197
  203. package/dist/github/pr-readiness.js.map +0 -1
  204. package/dist/github/pr-review.js +0 -410
  205. package/dist/github/pr-review.js.map +0 -1
  206. package/dist/github/release-notes.js +0 -227
  207. package/dist/github/release-notes.js.map +0 -1
  208. package/dist/github/repo-health.js +0 -303
  209. package/dist/github/repo-health.js.map +0 -1
  210. package/dist/github/retry.js +0 -117
  211. package/dist/github/retry.js.map +0 -1
  212. package/dist/github/types.js +0 -8
  213. package/dist/github/types.js.map +0 -1
  214. package/dist/github/webhooks.js +0 -153
  215. package/dist/github/webhooks.js.map +0 -1
  216. package/dist/google/auth.js +0 -325
  217. package/dist/google/auth.js.map +0 -1
  218. package/dist/google/calendar-timer.js +0 -91
  219. package/dist/google/calendar-timer.js.map +0 -1
  220. package/dist/google/calendar.js +0 -270
  221. package/dist/google/calendar.js.map +0 -1
  222. package/dist/google/docs.js +0 -309
  223. package/dist/google/docs.js.map +0 -1
  224. package/dist/google/gmail-send.js +0 -219
  225. package/dist/google/gmail-send.js.map +0 -1
  226. package/dist/google/gmail-timer.js +0 -223
  227. package/dist/google/gmail-timer.js.map +0 -1
  228. package/dist/google/gmail.js +0 -470
  229. package/dist/google/gmail.js.map +0 -1
  230. package/dist/google/plugin.js +0 -169
  231. package/dist/google/plugin.js.map +0 -1
  232. package/dist/google/tasks-timer.js +0 -107
  233. package/dist/google/tasks-timer.js.map +0 -1
  234. package/dist/google/tasks.js +0 -331
  235. package/dist/google/tasks.js.map +0 -1
  236. package/dist/google/temporal.js +0 -176
  237. package/dist/google/temporal.js.map +0 -1
  238. package/dist/integrations/gate.js +0 -100
  239. package/dist/integrations/gate.js.map +0 -1
  240. package/dist/integrations/github.js +0 -331
  241. package/dist/integrations/github.js.map +0 -1
  242. package/dist/integrations/google-tasks.js +0 -432
  243. package/dist/integrations/google-tasks.js.map +0 -1
  244. package/dist/mdns.js +0 -110
  245. package/dist/mdns.js.map +0 -1
  246. package/dist/notifications/channel.js +0 -83
  247. package/dist/notifications/channel.js.map +0 -1
  248. package/dist/notifications/channels/adapter.js +0 -55
  249. package/dist/notifications/channels/adapter.js.map +0 -1
  250. package/dist/notifications/channels/index.js +0 -6
  251. package/dist/notifications/channels/index.js.map +0 -1
  252. package/dist/notifications/channels/log.js +0 -29
  253. package/dist/notifications/channels/log.js.map +0 -1
  254. package/dist/notifications/email.js +0 -72
  255. package/dist/notifications/email.js.map +0 -1
  256. package/dist/notifications/engine.js +0 -198
  257. package/dist/notifications/engine.js.map +0 -1
  258. package/dist/notifications/index.js +0 -24
  259. package/dist/notifications/index.js.map +0 -1
  260. package/dist/notifications/phone.js +0 -48
  261. package/dist/notifications/phone.js.map +0 -1
  262. package/dist/notifications/sms.js +0 -65
  263. package/dist/notifications/sms.js.map +0 -1
  264. package/dist/notifications/types.js +0 -14
  265. package/dist/notifications/types.js.map +0 -1
  266. package/dist/notifications/webhook.js +0 -65
  267. package/dist/notifications/webhook.js.map +0 -1
  268. package/dist/resend/inbox.js +0 -199
  269. package/dist/resend/inbox.js.map +0 -1
  270. package/dist/resend/webhooks.js +0 -244
  271. package/dist/resend/webhooks.js.map +0 -1
  272. package/dist/search/browse.js +0 -225
  273. package/dist/search/browse.js.map +0 -1
  274. package/dist/search/perplexity.js +0 -41
  275. package/dist/search/perplexity.js.map +0 -1
  276. package/dist/slack/channels.js +0 -277
  277. package/dist/slack/channels.js.map +0 -1
  278. package/dist/slack/client.js +0 -468
  279. package/dist/slack/client.js.map +0 -1
  280. package/dist/slack/retry.js +0 -100
  281. package/dist/slack/retry.js.map +0 -1
  282. package/dist/slack/types.js +0 -52
  283. package/dist/slack/types.js.map +0 -1
  284. package/dist/slack/webhooks.js +0 -285
  285. package/dist/slack/webhooks.js.map +0 -1
  286. package/dist/stt/client.js +0 -66
  287. package/dist/stt/client.js.map +0 -1
  288. package/dist/stt/sidecar.js +0 -115
  289. package/dist/stt/sidecar.js.map +0 -1
  290. package/dist/tracing/bridge.js +0 -70
  291. package/dist/tracing/bridge.js.map +0 -1
  292. package/dist/tracing/correlation.js +0 -49
  293. package/dist/tracing/correlation.js.map +0 -1
  294. package/dist/tracing/index.js +0 -18
  295. package/dist/tracing/index.js.map +0 -1
  296. package/dist/tracing/init.js +0 -81
  297. package/dist/tracing/init.js.map +0 -1
  298. package/dist/tracing/instrument.js +0 -145
  299. package/dist/tracing/instrument.js.map +0 -1
  300. package/dist/tracing/middleware.js +0 -69
  301. package/dist/tracing/middleware.js.map +0 -1
  302. package/dist/tracing/tracer.js +0 -327
  303. package/dist/tracing/tracer.js.map +0 -1
  304. package/dist/tts/client.js +0 -48
  305. package/dist/tts/client.js.map +0 -1
  306. package/dist/tts/sidecar.js +0 -148
  307. package/dist/tts/sidecar.js.map +0 -1
  308. package/dist/twilio/call.js +0 -79
  309. package/dist/twilio/call.js.map +0 -1
  310. package/dist/vault/matcher.js +0 -197
  311. package/dist/vault/matcher.js.map +0 -1
  312. package/dist/vault/personal.js +0 -163
  313. package/dist/vault/personal.js.map +0 -1
  314. package/dist/vault/policy.js +0 -159
  315. package/dist/vault/policy.js.map +0 -1
  316. package/dist/vault/store.js +0 -122
  317. package/dist/vault/store.js.map +0 -1
  318. package/dist/vault/transfer.js +0 -188
  319. package/dist/vault/transfer.js.map +0 -1
  320. package/dist/volumes/index.js +0 -2
  321. package/dist/volumes/index.js.map +0 -1
  322. package/dist/volumes/manager.js +0 -462
  323. package/dist/volumes/manager.js.map +0 -1
  324. package/dist/volumes/types.js +0 -8
  325. package/dist/volumes/types.js.map +0 -1
  326. package/dist/webhooks/config.js +0 -214
  327. package/dist/webhooks/config.js.map +0 -1
  328. package/dist/webhooks/event-log.js +0 -132
  329. package/dist/webhooks/event-log.js.map +0 -1
  330. package/dist/webhooks/handler.js +0 -103
  331. package/dist/webhooks/handler.js.map +0 -1
  332. package/dist/webhooks/handlers.js +0 -231
  333. package/dist/webhooks/handlers.js.map +0 -1
  334. package/dist/webhooks/index.js +0 -33
  335. package/dist/webhooks/index.js.map +0 -1
  336. package/dist/webhooks/mount.js +0 -400
  337. package/dist/webhooks/mount.js.map +0 -1
  338. package/dist/webhooks/registry.js +0 -143
  339. package/dist/webhooks/registry.js.map +0 -1
  340. package/dist/webhooks/relay.js +0 -53
  341. package/dist/webhooks/relay.js.map +0 -1
  342. package/dist/webhooks/retry.js +0 -270
  343. package/dist/webhooks/retry.js.map +0 -1
  344. package/dist/webhooks/router.js +0 -290
  345. package/dist/webhooks/router.js.map +0 -1
  346. package/dist/webhooks/twilio.js +0 -129
  347. package/dist/webhooks/twilio.js.map +0 -1
  348. package/dist/webhooks/types.js +0 -8
  349. package/dist/webhooks/types.js.map +0 -1
  350. package/dist/webhooks/verify.js +0 -154
  351. package/dist/webhooks/verify.js.map +0 -1
@@ -1,172 +0,0 @@
1
- /**
2
- * Avatar client — communicates with the MuseTalk FastAPI sidecar.
3
- * Handles photo preparation, video generation, and MP4 caching.
4
- */
5
- import { createHash } from "node:crypto";
6
- import { readFile, writeFile, readdir, stat, unlink, mkdir } from "node:fs/promises";
7
- import { join } from "node:path";
8
- import { getAvatarConfig } from "../settings.js";
9
- import { createLogger } from "../utils/logger.js";
10
- const log = createLogger("avatar-client");
11
- const CACHE_DIR = join(process.cwd(), "public", "avatar", "cache");
12
- const MAX_CACHE_ENTRIES = 50;
13
- /** In-flight guard — only one generate request at a time. */
14
- let generating = false;
15
- function baseUrl() {
16
- return `http://127.0.0.1:${getAvatarConfig().port}`;
17
- }
18
- /**
19
- * Health probe — GET /health, 3-second timeout.
20
- */
21
- export async function checkAvatarSidecar() {
22
- try {
23
- const res = await fetch(`${baseUrl()}/health`, {
24
- signal: AbortSignal.timeout(3000),
25
- });
26
- if (!res.ok)
27
- return false;
28
- const data = await res.json();
29
- return !!data.ready;
30
- }
31
- catch {
32
- return false;
33
- }
34
- }
35
- /**
36
- * Prepare a reference photo for lip-sync generation.
37
- * POST /prepare with the photo file. Runs face detection + VAE encode (cached on sidecar side).
38
- */
39
- export async function preparePhoto(photoPath) {
40
- try {
41
- const photoBytes = await readFile(photoPath);
42
- const formData = new FormData();
43
- formData.append("photo", new Blob([photoBytes]), "photo.png");
44
- const res = await fetch(`${baseUrl()}/prepare`, {
45
- method: "POST",
46
- body: formData,
47
- signal: AbortSignal.timeout(120_000),
48
- });
49
- if (!res.ok) {
50
- const err = await res.json().catch(() => ({}));
51
- log.warn(` Prepare failed: ${err.error ?? res.statusText}`);
52
- return false;
53
- }
54
- return true;
55
- }
56
- catch (err) {
57
- const msg = err instanceof Error ? err.message : String(err);
58
- log.warn(` Prepare error: ${msg}`);
59
- return false;
60
- }
61
- }
62
- /**
63
- * Generate a lip-synced MP4 from WAV audio.
64
- * POST /generate with WAV bytes. Returns MP4 Buffer or null.
65
- * Timeout: 120s (generation time ≈ audio duration).
66
- */
67
- export async function generateVideo(wavBuffer) {
68
- if (generating) {
69
- log.warn(` Skipped — generation already in flight`);
70
- return null;
71
- }
72
- generating = true;
73
- try {
74
- const formData = new FormData();
75
- formData.append("audio", new Blob([wavBuffer]), "audio.wav");
76
- const res = await fetch(`${baseUrl()}/generate`, {
77
- method: "POST",
78
- body: formData,
79
- signal: AbortSignal.timeout(120_000),
80
- });
81
- if (!res.ok) {
82
- const err = await res.json().catch(() => ({}));
83
- log.warn(` Generate failed: ${err.error ?? res.statusText}`);
84
- return null;
85
- }
86
- const arrayBuf = await res.arrayBuffer();
87
- return Buffer.from(arrayBuf);
88
- }
89
- catch (err) {
90
- const msg = err instanceof Error ? err.message : String(err);
91
- log.warn(` Generate error: ${msg}`);
92
- return null;
93
- }
94
- finally {
95
- generating = false;
96
- }
97
- }
98
- /** Compute SHA-256 hash of a buffer (for cache keys). */
99
- function hashBuffer(buf) {
100
- return createHash("sha256").update(buf).digest("hex").slice(0, 16);
101
- }
102
- /**
103
- * Check if a video is already cached for the given WAV audio.
104
- * Returns the cache filename (hash.mp4) if found, null otherwise.
105
- */
106
- export async function getCachedVideo(wavBuffer) {
107
- const hash = hashBuffer(wavBuffer);
108
- const cachePath = join(CACHE_DIR, `${hash}.mp4`);
109
- try {
110
- await stat(cachePath);
111
- return `${hash}.mp4`;
112
- }
113
- catch {
114
- return null;
115
- }
116
- }
117
- /**
118
- * Cache an MP4 video, keyed by WAV audio hash.
119
- * Returns the cache filename (hash.mp4).
120
- */
121
- export async function cacheVideo(mp4Buffer, wavBuffer) {
122
- await mkdir(CACHE_DIR, { recursive: true });
123
- const hash = hashBuffer(wavBuffer);
124
- const filename = `${hash}.mp4`;
125
- await writeFile(join(CACHE_DIR, filename), mp4Buffer);
126
- await pruneCache();
127
- return filename;
128
- }
129
- /**
130
- * Prune the cache directory to keep at most MAX_CACHE_ENTRIES files.
131
- * Removes oldest files by modification time.
132
- */
133
- async function pruneCache() {
134
- try {
135
- const files = await readdir(CACHE_DIR);
136
- const mp4Files = files.filter((f) => f.endsWith(".mp4"));
137
- if (mp4Files.length <= MAX_CACHE_ENTRIES)
138
- return;
139
- // Get mtimes for sorting
140
- const withStats = await Promise.all(mp4Files.map(async (f) => {
141
- const s = await stat(join(CACHE_DIR, f));
142
- return { name: f, mtime: s.mtimeMs };
143
- }));
144
- // Sort oldest first
145
- withStats.sort((a, b) => a.mtime - b.mtime);
146
- // Remove oldest entries beyond the limit
147
- const toRemove = withStats.slice(0, withStats.length - MAX_CACHE_ENTRIES);
148
- for (const f of toRemove) {
149
- await unlink(join(CACHE_DIR, f.name)).catch(() => { });
150
- }
151
- }
152
- catch {
153
- // Cache dir may not exist yet — that's fine
154
- }
155
- }
156
- /**
157
- * Clear all cached videos. Used when the reference photo changes.
158
- */
159
- export async function clearVideoCache() {
160
- try {
161
- const files = await readdir(CACHE_DIR);
162
- for (const f of files) {
163
- if (f.endsWith(".mp4")) {
164
- await unlink(join(CACHE_DIR, f)).catch(() => { });
165
- }
166
- }
167
- }
168
- catch {
169
- // Cache dir may not exist yet
170
- }
171
- }
172
- //# sourceMappingURL=client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/avatar/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,GAAG,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;AAE1C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACnE,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B,6DAA6D;AAC7D,IAAI,UAAU,GAAG,KAAK,CAAC;AAEvB,SAAS,OAAO;IACd,OAAO,oBAAoB,eAAe,EAAE,CAAC,IAAI,EAAE,CAAC;AACtD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,EAAE,SAAS,EAAE;YAC7C,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;QAC1B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAyB,CAAC;QACrD,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB;IAClD,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;QAChC,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;QAE9D,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,EAAE,UAAU,EAAE;YAC9C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC;SACrC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAuB,CAAC;YACrE,GAAG,CAAC,IAAI,CAAC,oBAAoB,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;YAC5D,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,GAAG,CAAC,IAAI,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB;IACnD,IAAI,UAAU,EAAE,CAAC;QACf,GAAG,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,UAAU,GAAG,IAAI,CAAC;IAClB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;QAChC,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;QAE7D,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,EAAE,WAAW,EAAE;YAC/C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC;SACrC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAuB,CAAC;YACrE,GAAG,CAAC,IAAI,CAAC,qBAAqB,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;YAC7D,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;QACzC,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,GAAG,CAAC,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,UAAU,GAAG,KAAK,CAAC;IACrB,CAAC;AACH,CAAC;AAED,yDAAyD;AACzD,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAAiB;IACpD,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,MAAM,CAAC,CAAC;IACjD,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,OAAO,GAAG,IAAI,MAAM,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,SAAiB,EAAE,SAAiB;IACnE,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,GAAG,IAAI,MAAM,CAAC;IAC/B,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC;IACtD,MAAM,UAAU,EAAE,CAAC;IACnB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,UAAU;IACvB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAEzD,IAAI,QAAQ,CAAC,MAAM,IAAI,iBAAiB;YAAE,OAAO;QAEjD,yBAAyB;QACzB,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;YACvB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;YACzC,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QACvC,CAAC,CAAC,CACH,CAAC;QAEF,oBAAoB;QACpB,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAE5C,yCAAyC;QACzC,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,iBAAiB,CAAC,CAAC;QAC1E,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4CAA4C;IAC9C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;QACvC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvB,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;IAChC,CAAC;AACH,CAAC"}
@@ -1,125 +0,0 @@
1
- /**
2
- * Avatar sidecar lifecycle manager.
3
- * Spawns the MuseTalk FastAPI server and monitors its health.
4
- * Graceful degradation — if MuseTalk isn't installed, Core falls back to TalkingHead/placeholder.
5
- */
6
- import { spawn } from "node:child_process";
7
- import { access } from "node:fs/promises";
8
- import { join } from "node:path";
9
- import { getAvatarConfig } from "../settings.js";
10
- import { checkAvatarSidecar } from "./client.js";
11
- import { createLogger } from "../utils/logger.js";
12
- const log = createLogger("avatar-sidecar");
13
- const HEALTH_POLL_INTERVAL = 1000; // ms
14
- const HEALTH_POLL_TIMEOUT = 60_000; // ms — model loading is slow on first run
15
- let sidecarProcess = null;
16
- let available = false;
17
- function pythonCommand() {
18
- // Use the MuseTalk venv Python if it exists (has all the right deps)
19
- const config = getAvatarConfig();
20
- if (config.musetalkPath) {
21
- const venvPython = process.platform === "win32"
22
- ? join(config.musetalkPath, ".venv", "Scripts", "python.exe")
23
- : join(config.musetalkPath, ".venv", "bin", "python");
24
- return venvPython;
25
- }
26
- return process.platform === "win32" ? "python" : "python3";
27
- }
28
- /**
29
- * Start the MuseTalk avatar sidecar.
30
- * Verifies the MuseTalk path exists, spawns the FastAPI server, polls for health.
31
- * Returns true if sidecar is available after startup.
32
- */
33
- export async function startAvatarSidecar() {
34
- const config = getAvatarConfig();
35
- if (!config.enabled) {
36
- available = false;
37
- return false;
38
- }
39
- if (!config.musetalkPath) {
40
- log.info(" No musetalkPath configured — avatar disabled");
41
- available = false;
42
- return false;
43
- }
44
- // Check if already running externally
45
- if (await checkAvatarSidecar()) {
46
- available = true;
47
- return true;
48
- }
49
- // Verify MuseTalk path exists
50
- try {
51
- await access(config.musetalkPath);
52
- }
53
- catch {
54
- log.info(` MuseTalk path not found: ${config.musetalkPath}`);
55
- available = false;
56
- return false;
57
- }
58
- const python = pythonCommand();
59
- const port = String(config.port);
60
- const serverScript = join(process.cwd(), "sidecar", "avatar", "server.py");
61
- try {
62
- sidecarProcess = spawn(python, [serverScript, "--port", port, "--musetalk-path", config.musetalkPath], {
63
- stdio: ["ignore", "pipe", "pipe"],
64
- detached: false,
65
- env: { ...process.env, PYTHONUTF8: "1", PYTHONIOENCODING: "utf-8" },
66
- });
67
- sidecarProcess.stdout?.on("data", (data) => {
68
- const msg = data.toString().trim();
69
- if (msg)
70
- log.info(` ${msg}`);
71
- });
72
- sidecarProcess.stderr?.on("data", (data) => {
73
- const msg = data.toString().trim();
74
- if (msg)
75
- log.info(` ${msg}`);
76
- });
77
- sidecarProcess.on("error", (err) => {
78
- log.info(` Failed to start: ${err.message}`);
79
- available = false;
80
- sidecarProcess = null;
81
- });
82
- sidecarProcess.on("exit", (code) => {
83
- if (code !== null && code !== 0) {
84
- log.info(` Exited with code ${code}`);
85
- }
86
- available = false;
87
- sidecarProcess = null;
88
- });
89
- // Poll until ready or timeout
90
- const start = Date.now();
91
- while (Date.now() - start < HEALTH_POLL_TIMEOUT) {
92
- if (await checkAvatarSidecar()) {
93
- available = true;
94
- return true;
95
- }
96
- await new Promise((r) => setTimeout(r, HEALTH_POLL_INTERVAL));
97
- }
98
- log.info(" Timed out waiting for health check");
99
- stopAvatarSidecar();
100
- return false;
101
- }
102
- catch (err) {
103
- const msg = err instanceof Error ? err.message : String(err);
104
- log.info(` Spawn failed: ${msg}`);
105
- return false;
106
- }
107
- }
108
- /** Check if the avatar sidecar is currently available. */
109
- export function isAvatarAvailable() {
110
- return available;
111
- }
112
- /** Stop the avatar sidecar process. */
113
- export function stopAvatarSidecar() {
114
- if (sidecarProcess) {
115
- try {
116
- sidecarProcess.kill();
117
- }
118
- catch {
119
- // Already dead
120
- }
121
- sidecarProcess = null;
122
- }
123
- available = false;
124
- }
125
- //# sourceMappingURL=sidecar.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../../src/avatar/sidecar.ts"],"names":[],"mappings":"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"}
@@ -1,122 +0,0 @@
1
- /**
2
- * Browser session manager — persist and reuse Playwright storageState per domain.
3
- *
4
- * Sessions are stored as AES-256-GCM encrypted JSON in brain/browser/sessions/.
5
- * Each session is keyed by domain with a 7-day expiry.
6
- */
7
- import { readFile, writeFile, readdir, unlink, mkdir } from "node:fs/promises";
8
- import { join } from "node:path";
9
- import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
10
- import { createLogger } from "../utils/logger.js";
11
- import { getEncryptionKey } from "../lib/key-store.js";
12
- import { BRAIN_DIR } from "../lib/paths.js";
13
- const log = createLogger("browser-sessions");
14
- const SESSIONS_DIR = join(BRAIN_DIR, "browser", "sessions");
15
- const SESSION_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
16
- // ── Crypto helpers ───────────────────────────────────────────────────────────
17
- function deriveSessionKey() {
18
- const masterKey = getEncryptionKey();
19
- if (!masterKey)
20
- throw new Error("No encryption key available — not authenticated");
21
- // Use first 32 bytes of the master key (AES-256)
22
- return masterKey.subarray(0, 32);
23
- }
24
- function encrypt(plaintext) {
25
- const key = deriveSessionKey();
26
- const iv = randomBytes(16);
27
- const cipher = createCipheriv("aes-256-gcm", key, iv);
28
- const encrypted = Buffer.concat([cipher.update(plaintext, "utf-8"), cipher.final()]);
29
- const tag = cipher.getAuthTag();
30
- return { iv: iv.toString("hex"), tag: tag.toString("hex"), data: encrypted.toString("hex") };
31
- }
32
- function decrypt(iv, tag, data) {
33
- const key = deriveSessionKey();
34
- const decipher = createDecipheriv("aes-256-gcm", key, Buffer.from(iv, "hex"));
35
- decipher.setAuthTag(Buffer.from(tag, "hex"));
36
- return decipher.update(data, "hex", "utf-8") + decipher.final("utf-8");
37
- }
38
- // ── File helpers ─────────────────────────────────────────────────────────────
39
- function sessionPath(domain) {
40
- // Sanitize domain for filesystem: replace dots/colons with underscores
41
- const safe = domain.replace(/[^a-zA-Z0-9-]/g, "_");
42
- return join(SESSIONS_DIR, `${safe}.session.json`);
43
- }
44
- async function ensureDir() {
45
- await mkdir(SESSIONS_DIR, { recursive: true });
46
- }
47
- // ── Public API ───────────────────────────────────────────────────────────────
48
- /**
49
- * Save a Playwright storageState (cookies, localStorage, etc.) for a domain.
50
- */
51
- export async function saveSession(domain, storageState) {
52
- await ensureDir();
53
- const plaintext = JSON.stringify(storageState);
54
- const { iv, tag, data } = encrypt(plaintext);
55
- const now = new Date();
56
- const envelope = {
57
- domain,
58
- createdAt: now.toISOString(),
59
- expiresAt: new Date(now.getTime() + SESSION_TTL_MS).toISOString(),
60
- iv,
61
- tag,
62
- data,
63
- };
64
- await writeFile(sessionPath(domain), JSON.stringify(envelope, null, 2), "utf-8");
65
- log.info(`Saved browser session for ${domain}`);
66
- }
67
- /**
68
- * Load a stored session for a domain, or null if missing/expired/corrupted.
69
- */
70
- export async function loadSession(domain) {
71
- try {
72
- const raw = await readFile(sessionPath(domain), "utf-8");
73
- const envelope = JSON.parse(raw);
74
- // Check expiry
75
- if (new Date(envelope.expiresAt).getTime() < Date.now()) {
76
- log.info(`Session expired for ${domain} — removing`);
77
- await unlink(sessionPath(domain)).catch(() => { });
78
- return null;
79
- }
80
- const plaintext = decrypt(envelope.iv, envelope.tag, envelope.data);
81
- return JSON.parse(plaintext);
82
- }
83
- catch {
84
- return null;
85
- }
86
- }
87
- /**
88
- * Delete a stored session for a domain.
89
- */
90
- export async function deleteSession(domain) {
91
- await unlink(sessionPath(domain)).catch(() => { });
92
- log.info(`Deleted browser session for ${domain}`);
93
- }
94
- /**
95
- * Purge all expired sessions from disk.
96
- */
97
- export async function purgeExpiredSessions() {
98
- await ensureDir();
99
- let purged = 0;
100
- const files = await readdir(SESSIONS_DIR);
101
- for (const file of files) {
102
- if (!file.endsWith(".session.json"))
103
- continue;
104
- try {
105
- const raw = await readFile(join(SESSIONS_DIR, file), "utf-8");
106
- const envelope = JSON.parse(raw);
107
- if (new Date(envelope.expiresAt).getTime() < Date.now()) {
108
- await unlink(join(SESSIONS_DIR, file));
109
- purged++;
110
- }
111
- }
112
- catch {
113
- // Corrupted file — remove it
114
- await unlink(join(SESSIONS_DIR, file)).catch(() => { });
115
- purged++;
116
- }
117
- }
118
- if (purged > 0)
119
- log.info(`Purged ${purged} expired browser session(s)`);
120
- return purged;
121
- }
122
- //# sourceMappingURL=sessions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/browser/sessions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,GAAG,GAAG,YAAY,CAAC,kBAAkB,CAAC,CAAC;AAE7C,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAC5D,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,SAAS;AAczD,gFAAgF;AAEhF,SAAS,gBAAgB;IACvB,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAC;IACrC,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACnF,iDAAiD;IACjD,OAAO,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,OAAO,CAAC,SAAiB;IAChC,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAC;IAC/B,MAAM,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,cAAc,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACrF,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IAChC,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;AAC/F,CAAC;AAED,SAAS,OAAO,CAAC,EAAU,EAAE,GAAW,EAAE,IAAY;IACpD,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;IAC9E,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IAC7C,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACzE,CAAC;AAED,gFAAgF;AAEhF,SAAS,WAAW,CAAC,MAAc;IACjC,uEAAuE;IACvE,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IACnD,OAAO,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,eAAe,CAAC,CAAC;AACpD,CAAC;AAED,KAAK,UAAU,SAAS;IACtB,MAAM,KAAK,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,gFAAgF;AAEhF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc,EAAE,YAAqB;IACrE,MAAM,SAAS,EAAE,CAAC;IAClB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC/C,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,QAAQ,GAAoB;QAChC,MAAM;QACN,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE;QAC5B,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,cAAc,CAAC,CAAC,WAAW,EAAE;QACjE,EAAE;QACF,GAAG;QACH,IAAI;KACL,CAAC;IACF,MAAM,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACjF,GAAG,CAAC,IAAI,CAAC,6BAA6B,MAAM,EAAE,CAAC,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc;IAC9C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;QACzD,MAAM,QAAQ,GAAoB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAElD,eAAe;QACf,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YACxD,GAAG,CAAC,IAAI,CAAC,uBAAuB,MAAM,aAAa,CAAC,CAAC;YACrD,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAClD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAc;IAChD,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAClD,GAAG,CAAC,IAAI,CAAC,+BAA+B,MAAM,EAAE,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,MAAM,SAAS,EAAE,CAAC;IAClB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;YAAE,SAAS;QAC9C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;YAC9D,MAAM,QAAQ,GAAoB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAClD,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBACxD,MAAM,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC;gBACvC,MAAM,EAAE,CAAC;YACX,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,6BAA6B;YAC7B,MAAM,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACvD,MAAM,EAAE,CAAC;QACX,CAAC;IACH,CAAC;IACD,IAAI,MAAM,GAAG,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,UAAU,MAAM,6BAA6B,CAAC,CAAC;IACxE,OAAO,MAAM,CAAC;AAChB,CAAC"}