failproofai 1.0.4-beta.8 → 1.0.5-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js +2 -2
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js +2 -2
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +13 -13
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js +4 -4
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +4 -37
- package/.next/standalone/.next/server/app/audit/page.js +2 -2
- package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +13 -13
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js +2 -2
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
- package/.next/standalone/.next/server/app/policies/page.js +4 -4
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js +4 -4
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +5 -5
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +3 -3
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -15
- package/.next/standalone/.next/server/app/settings/page.js +4 -4
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__0hmcwgg._.js → [externals]__0-9ti7z._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__14b7cc6._.js → [externals]__0u3wrvq._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-219ec._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__04_h-a5._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__08dchfu._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rv7m0k._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__17g9wh7._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1le9jqc._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1legmza._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1p-qi2t._.js +5 -0
- package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
- package/.next/standalone/.next/server/chunks/{_1_eakl4._.js → _1-akg6w._.js} +2 -2
- package/.next/standalone/.next/server/chunks/_1ek68ln._.js +10 -10
- package/.next/standalone/.next/server/chunks/_1vslkoe._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_telemetry_ts_0dctyyw._.js +1 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_fp-home_ts_09kv0bn._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__187jks6._.js → [root-of-the-server]__00-s7h8._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__04px77e._.js → [root-of-the-server]__013jr2b._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0i0l1di._.js → [root-of-the-server]__01wy8d-._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0r3c1_0._.js → [root-of-the-server]__02npjtd._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1ckpmkk._.js → [root-of-the-server]__0da85px._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__17xnxlx._.js → [root-of-the-server]__0ftmoxc._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0kokc8z._.js → [root-of-the-server]__0n_lxhg._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0-4ja6q._.js → [root-of-the-server]__0p-5p8u._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0egr5s1._.js → [root-of-the-server]__0s740oi._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1fa1jd9._.js → [root-of-the-server]__0x1aj1_._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1kpd1za._.js → [root-of-the-server]__190won8._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ctpynv._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1nq7ivq._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__00cr3xu._.js → [root-of-the-server]__1p2otjt._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__00y9ww2._.js → [root-of-the-server]__1sc84bb._.js} +2 -21
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_0s-77v5._.js → _0h_douw._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_00bqkhj._.js → _0u3xxgc._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_0zs_4uu._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1_ozgif._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1ddpc5g._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1es2j7i._.js +14 -51
- package/.next/standalone/.next/server/chunks/ssr/{_14c6q09._.js → _1if9ixi._.js} +2 -21
- package/.next/standalone/.next/server/chunks/ssr/{_07t3jol._.js → _1u8-lu2._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1ylae7o._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +69 -1
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/lib_openclaw-projects_ts_0qxq3bp._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_13n822a._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_html-to-image_es_index_1ao30b1.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +21 -65
- package/.next/standalone/.next/static/chunks/0hw6-c206lsma.js +1 -0
- package/.next/standalone/.next/static/chunks/{2mizt96igig1y.js → 0m9sx3khjrl1q.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1302duobnz07l.js → 0oos8qpc1ugos.js} +1 -1
- package/.next/standalone/.next/static/chunks/0u64yey446k4f.css +1 -0
- package/.next/standalone/.next/static/chunks/{2ukucf6g-kbs5.js → 0unrx9g_x0u7j.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0jpd8dv2vk930.css → 29-iqnp9v_axt.css} +1 -1
- package/.next/standalone/.next/static/chunks/{3uyhmm01g64k4.css → 2k9f4tyv04809.css} +0 -1
- package/.next/standalone/.next/static/chunks/{0vm4wdx3w-2_w.js → 2qjn-leir0x_s.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1chm9piluggc-.js → 2xbxkaszi1xnw.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2n85g-crgcx5j.js → 33umhy-x204qj.js} +2 -2
- package/.next/standalone/.next/static/chunks/3nux7kkrc3eps.js +69 -0
- package/.next/standalone/.next/static/chunks/3qfoeqhy5l10x.js +1 -0
- package/.next/standalone/.next/static/chunks/3zkg2s2vzxc3d.js +1 -0
- package/.next/standalone/.next/static/chunks/{3a4gth64hwtwf.js → 40tpgs4fjct5p.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1_x7pqemw5n_w.js → 40uih96wnkowy.js} +1 -1
- package/.next/standalone/.next/static/chunks/{turbopack-3s3c-u_u_l0u9.js → turbopack-3p73obe0xmrxm.js} +1 -1
- package/.next/standalone/.opencode/plugins/failproofai.mjs +27 -51
- package/.next/standalone/app/actions/get-scheduled-audit.ts +0 -5
- package/.next/standalone/app/actions/update-scheduled-audit.ts +57 -18
- package/.next/standalone/app/api/auth/status/route.ts +2 -3
- package/.next/standalone/app/audit/_components/audit-dashboard.tsx +34 -140
- package/.next/standalone/app/audit/_components/audit-poster.tsx +10 -29
- package/.next/standalone/app/audit/_components/come-back-better-section.tsx +1 -6
- package/.next/standalone/app/audit/_components/empty-state.tsx +1 -4
- package/.next/standalone/app/audit/_components/how-to-improve-section.tsx +5 -19
- package/.next/standalone/app/audit/_components/share-templates.ts +44 -110
- package/.next/standalone/app/audit/audit-styles.css +1 -132
- package/.next/standalone/app/settings/page.tsx +1 -1
- package/.next/standalone/app/settings/settings-client.tsx +45 -50
- package/.next/standalone/lib/auth/api-server-client.ts +5 -33
- package/.next/standalone/lib/claude-sessions.ts +27 -101
- package/.next/standalone/lib/codex-sessions.ts +4 -20
- package/.next/standalone/lib/copilot-sessions.ts +1 -32
- package/.next/standalone/lib/cursor-sessions.ts +5 -62
- package/.next/standalone/lib/download-session.ts +13 -58
- package/.next/standalone/lib/openclaw-projects.ts +18 -54
- package/.next/standalone/lib/openclaw-sessions.ts +17 -75
- package/.next/standalone/lib/sqlite-reader.ts +1 -78
- package/.next/standalone/package.json +9 -9
- package/.next/standalone/sdk/python/CHANGELOG.md +32 -9
- package/.next/standalone/sdk/python/failproofai_sdk/_events.py +20 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_redact.py +233 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_writer.py +4 -1
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/llama_index.py +5 -5
- package/.next/standalone/sdk/python/tests/integrations/test_llama_index.py +2 -2
- package/.next/standalone/sdk/python/tests/test_redaction.py +140 -0
- package/.next/standalone/sdk/python/tests/test_sdk.py +87 -0
- package/.next/standalone/sdk/python/tests/test_server_contract.py +60 -0
- package/.next/standalone/sdk/python/tests/test_site_docs.py +2 -2
- package/.next/standalone/server.js +1 -1
- package/bin/failproofai.mjs +1 -1
- package/dist/cli.mjs +664 -2121
- package/dist/worker.mjs +105 -422
- package/lib/auth/api-server-client.ts +5 -33
- package/lib/claude-sessions.ts +27 -101
- package/lib/codex-sessions.ts +4 -20
- package/lib/copilot-sessions.ts +1 -32
- package/lib/cursor-sessions.ts +5 -62
- package/lib/download-session.ts +13 -58
- package/lib/openclaw-projects.ts +18 -54
- package/lib/openclaw-sessions.ts +17 -75
- package/lib/sqlite-reader.ts +1 -78
- package/package.json +9 -9
- package/pi-extension/index.ts +5 -50
- package/src/audit/cache.ts +0 -6
- package/src/audit/cli-adapters/claude.ts +0 -13
- package/src/audit/cli-login.ts +1 -4
- package/src/audit/cli.ts +7 -157
- package/src/audit/harm-report.ts +4 -111
- package/src/audit/index.ts +15 -286
- package/src/audit/machine-store.ts +9 -8
- package/src/audit/redact-example.ts +15 -324
- package/src/audit/report-harm.ts +37 -33
- package/src/audit/report.ts +3 -6
- package/src/audit/schedule-cli.ts +33 -54
- package/src/audit/scoring.ts +0 -49
- package/src/audit/types.ts +0 -52
- package/src/hooks/builtin-policies.ts +2 -67
- package/src/hooks/configure-wizard.ts +0 -55
- package/src/hooks/fp-config.ts +48 -83
- package/src/hooks/fp-home.ts +0 -27
- package/src/hooks/integrations.ts +14 -51
- package/src/hooks/uninstall-cli.ts +2 -17
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0faqz9x._.js +0 -22
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zyc_nm._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__112b4go._.js +0 -24
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1l71g3y._.js +0 -22
- package/.next/standalone/.next/server/chunks/lib_openclaw-projects_ts_0gc-p24._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n2txhk._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1kaotix._.js +0 -22
- package/.next/standalone/.next/server/chunks/ssr/_04ng_6x._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0l2hi_d._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_rerun-button_tsx_0blihgw._.js +0 -3
- package/.next/standalone/.next/static/chunks/0igq884ziuv-8.js +0 -1
- package/.next/standalone/.next/static/chunks/349jkb79v5g6z.js +0 -1
- package/.next/standalone/app/actions/get-leaks.ts +0 -104
- package/.next/standalone/app/audit/_components/leak-section.tsx +0 -192
- package/.next/standalone/lib/openclaw-db.ts +0 -271
- package/lib/openclaw-db.ts +0 -271
- package/src/audit/desktop-notify.ts +0 -420
- package/src/audit/leak-fingerprint.ts +0 -198
- package/src/audit/leak-record.ts +0 -248
- package/src/audit/leak-scan.ts +0 -268
- package/src/audit/leak-store.ts +0 -220
- package/src/audit/macos-notifier.ts +0 -298
- package/src/hooks/notice.ts +0 -24
- /package/.next/standalone/.next/static/{DNhaAH8iPGH0tIuxee5_2 → 4_QeL7mSPYsuiSVJmBOTj}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{DNhaAH8iPGH0tIuxee5_2 → 4_QeL7mSPYsuiSVJmBOTj}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{DNhaAH8iPGH0tIuxee5_2 → 4_QeL7mSPYsuiSVJmBOTj}/_ssgManifest.js +0 -0
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Read OpenClaw 2026.9.2+ transcripts from the per-agent SQLite databases at
|
|
3
|
-
* `agents/<agentId>/agent/openclaw-agent.sqlite`.
|
|
4
|
-
*
|
|
5
|
-
* `event_json` is the exact logical JSONL record, so the dashboard can feed it
|
|
6
|
-
* through the same parser and download format used by archived JSONL files.
|
|
7
|
-
*/
|
|
8
|
-
import { existsSync } from "node:fs";
|
|
9
|
-
import { join } from "node:path";
|
|
10
|
-
import { openSqliteReadonly, type SqliteReader } from "./sqlite-reader";
|
|
11
|
-
|
|
12
|
-
const DB_NAME = "openclaw-agent.sqlite";
|
|
13
|
-
|
|
14
|
-
export interface OpenClawSqliteSession {
|
|
15
|
-
sessionId: string;
|
|
16
|
-
agentId: string;
|
|
17
|
-
dbPath: string;
|
|
18
|
-
transcriptPath: string;
|
|
19
|
-
mtimeMs: number;
|
|
20
|
-
sizeBytes: number;
|
|
21
|
-
channel: string;
|
|
22
|
-
label?: string;
|
|
23
|
-
chatId?: string;
|
|
24
|
-
chatType?: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface OpenClawSqliteTranscript {
|
|
28
|
-
agentId: string;
|
|
29
|
-
dbPath: string;
|
|
30
|
-
filePath: string;
|
|
31
|
-
rawLines: Record<string, unknown>[];
|
|
32
|
-
eventJsonLines: string[];
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
interface WindowRow {
|
|
36
|
-
session_id: string;
|
|
37
|
-
session_key: string;
|
|
38
|
-
updated_at: number;
|
|
39
|
-
transcript_updated_at: number | null;
|
|
40
|
-
ended_at: number | null;
|
|
41
|
-
channel: string | null;
|
|
42
|
-
chat_type: string | null;
|
|
43
|
-
display_name: string | null;
|
|
44
|
-
event_updated_at: number;
|
|
45
|
-
size_bytes: number;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
interface NodeRow {
|
|
49
|
-
current_session_id: string;
|
|
50
|
-
entry_json: string;
|
|
51
|
-
label: string | null;
|
|
52
|
-
display_name: string | null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
interface ConversationRow {
|
|
56
|
-
session_id: string;
|
|
57
|
-
channel: string;
|
|
58
|
-
kind: string;
|
|
59
|
-
peer_id: string;
|
|
60
|
-
delivery_target: string;
|
|
61
|
-
label: string | null;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
interface EventRow {
|
|
65
|
-
event_json: string;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
interface SessionMeta {
|
|
69
|
-
channel?: string;
|
|
70
|
-
label?: string;
|
|
71
|
-
chatId?: string;
|
|
72
|
-
chatType?: string;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function str(value: unknown): string | undefined {
|
|
76
|
-
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function parseObject(value: string): Record<string, unknown> | undefined {
|
|
80
|
-
try {
|
|
81
|
-
const parsed: unknown = JSON.parse(value);
|
|
82
|
-
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
83
|
-
? (parsed as Record<string, unknown>)
|
|
84
|
-
: undefined;
|
|
85
|
-
} catch {
|
|
86
|
-
return undefined;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function syntheticPath(agentId: string, sessionId: string): string {
|
|
91
|
-
return `openclaw-sqlite://${encodeURIComponent(agentId)}/${sessionId}`;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/** Existing per-agent SQLite databases, derived from the configured agents. */
|
|
95
|
-
export function listOpenClawDatabases(
|
|
96
|
-
home: string,
|
|
97
|
-
agentIds: string[],
|
|
98
|
-
): Array<{ agentId: string; dbPath: string }> {
|
|
99
|
-
const out: Array<{ agentId: string; dbPath: string }> = [];
|
|
100
|
-
for (const agentId of agentIds) {
|
|
101
|
-
const dbPath = join(home, "agents", agentId, "agent", DB_NAME);
|
|
102
|
-
if (existsSync(dbPath)) out.push({ agentId, dbPath });
|
|
103
|
-
}
|
|
104
|
-
return out;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function readNodeMetadata(db: SqliteReader): Map<string, SessionMeta> {
|
|
108
|
-
const out = new Map<string, SessionMeta>();
|
|
109
|
-
let rows: NodeRow[];
|
|
110
|
-
try {
|
|
111
|
-
rows = db.query<NodeRow>(
|
|
112
|
-
`SELECT current_session_id, entry_json, label, display_name
|
|
113
|
-
FROM session_nodes`,
|
|
114
|
-
);
|
|
115
|
-
} catch {
|
|
116
|
-
return out;
|
|
117
|
-
}
|
|
118
|
-
for (const row of rows) {
|
|
119
|
-
const entry = parseObject(row.entry_json) ?? {};
|
|
120
|
-
const origin =
|
|
121
|
-
entry.origin &&
|
|
122
|
-
typeof entry.origin === "object" &&
|
|
123
|
-
!Array.isArray(entry.origin)
|
|
124
|
-
? (entry.origin as Record<string, unknown>)
|
|
125
|
-
: {};
|
|
126
|
-
out.set(row.current_session_id, {
|
|
127
|
-
channel:
|
|
128
|
-
str(entry.lastChannel) ?? str(origin.provider) ?? str(origin.surface),
|
|
129
|
-
label:
|
|
130
|
-
str(row.label) ??
|
|
131
|
-
str(row.display_name) ??
|
|
132
|
-
str(entry.displayName) ??
|
|
133
|
-
str(origin.label),
|
|
134
|
-
chatId: str(entry.lastTo) ?? str(origin.from),
|
|
135
|
-
chatType: str(entry.chatType) ?? str(origin.chatType),
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
return out;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function readConversationMetadata(db: SqliteReader): Map<string, SessionMeta> {
|
|
142
|
-
const out = new Map<string, SessionMeta>();
|
|
143
|
-
let rows: ConversationRow[];
|
|
144
|
-
try {
|
|
145
|
-
rows = db.query<ConversationRow>(
|
|
146
|
-
`SELECT sc.session_id, c.channel, c.kind, c.peer_id,
|
|
147
|
-
c.delivery_target, c.label
|
|
148
|
-
FROM session_conversations sc
|
|
149
|
-
JOIN conversations c ON c.conversation_id = sc.conversation_id
|
|
150
|
-
ORDER BY CASE sc.role WHEN 'primary' THEN 0 ELSE 1 END, sc.last_seen_at DESC`,
|
|
151
|
-
);
|
|
152
|
-
} catch {
|
|
153
|
-
return out;
|
|
154
|
-
}
|
|
155
|
-
for (const row of rows) {
|
|
156
|
-
if (out.has(row.session_id)) continue;
|
|
157
|
-
out.set(row.session_id, {
|
|
158
|
-
channel: str(row.channel),
|
|
159
|
-
label: str(row.label),
|
|
160
|
-
chatId: str(row.delivery_target) ?? str(row.peer_id),
|
|
161
|
-
chatType: str(row.kind),
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
return out;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/** List every transcript-bearing session in all per-agent databases. */
|
|
168
|
-
export async function listOpenClawSqliteSessions(
|
|
169
|
-
home: string,
|
|
170
|
-
agentIds: string[],
|
|
171
|
-
): Promise<OpenClawSqliteSession[]> {
|
|
172
|
-
const sessions: OpenClawSqliteSession[] = [];
|
|
173
|
-
for (const { agentId, dbPath } of listOpenClawDatabases(home, agentIds)) {
|
|
174
|
-
const db = await openSqliteReadonly(dbPath);
|
|
175
|
-
if (!db) continue;
|
|
176
|
-
try {
|
|
177
|
-
let rows: WindowRow[];
|
|
178
|
-
try {
|
|
179
|
-
rows = db.query<WindowRow>(
|
|
180
|
-
`SELECT w.session_id, w.session_key, w.updated_at,
|
|
181
|
-
w.transcript_updated_at, w.ended_at, w.channel,
|
|
182
|
-
w.chat_type, w.display_name,
|
|
183
|
-
COALESCE((SELECT MAX(e.created_at)
|
|
184
|
-
FROM transcript_events e
|
|
185
|
-
WHERE e.session_id = w.session_id), 0) AS event_updated_at,
|
|
186
|
-
COALESCE((SELECT SUM(length(e.event_json) + 1)
|
|
187
|
-
FROM transcript_events e
|
|
188
|
-
WHERE e.session_id = w.session_id), 0) AS size_bytes
|
|
189
|
-
FROM session_windows w
|
|
190
|
-
WHERE EXISTS (SELECT 1 FROM transcript_events e
|
|
191
|
-
WHERE e.session_id = w.session_id)`,
|
|
192
|
-
);
|
|
193
|
-
} catch {
|
|
194
|
-
continue;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const nodes = readNodeMetadata(db);
|
|
198
|
-
const conversations = readConversationMetadata(db);
|
|
199
|
-
for (const row of rows) {
|
|
200
|
-
const node = nodes.get(row.session_id);
|
|
201
|
-
const conversation = conversations.get(row.session_id);
|
|
202
|
-
sessions.push({
|
|
203
|
-
sessionId: row.session_id,
|
|
204
|
-
agentId,
|
|
205
|
-
dbPath,
|
|
206
|
-
transcriptPath: syntheticPath(agentId, row.session_id),
|
|
207
|
-
mtimeMs: Math.max(
|
|
208
|
-
Number(row.updated_at) || 0,
|
|
209
|
-
Number(row.transcript_updated_at) || 0,
|
|
210
|
-
Number(row.ended_at) || 0,
|
|
211
|
-
Number(row.event_updated_at) || 0,
|
|
212
|
-
),
|
|
213
|
-
sizeBytes: Number(row.size_bytes) || 0,
|
|
214
|
-
channel:
|
|
215
|
-
str(row.channel) ??
|
|
216
|
-
conversation?.channel ??
|
|
217
|
-
node?.channel ??
|
|
218
|
-
"local",
|
|
219
|
-
label: str(row.display_name) ?? conversation?.label ?? node?.label,
|
|
220
|
-
chatId: conversation?.chatId ?? node?.chatId,
|
|
221
|
-
chatType:
|
|
222
|
-
str(row.chat_type) ?? conversation?.chatType ?? node?.chatType,
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
} finally {
|
|
226
|
-
db.close();
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
return sessions;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/** Read one SQLite transcript by UUID. The first matching agent wins. */
|
|
233
|
-
export async function readOpenClawSqliteTranscript(
|
|
234
|
-
home: string,
|
|
235
|
-
agentIds: string[],
|
|
236
|
-
sessionId: string,
|
|
237
|
-
): Promise<OpenClawSqliteTranscript | null> {
|
|
238
|
-
for (const { agentId, dbPath } of listOpenClawDatabases(home, agentIds)) {
|
|
239
|
-
const db = await openSqliteReadonly(dbPath);
|
|
240
|
-
if (!db) continue;
|
|
241
|
-
try {
|
|
242
|
-
let rows: EventRow[];
|
|
243
|
-
try {
|
|
244
|
-
rows = db.query<EventRow>(
|
|
245
|
-
`SELECT event_json
|
|
246
|
-
FROM transcript_events
|
|
247
|
-
WHERE session_id = ?
|
|
248
|
-
ORDER BY seq ASC`,
|
|
249
|
-
[sessionId],
|
|
250
|
-
);
|
|
251
|
-
} catch {
|
|
252
|
-
continue;
|
|
253
|
-
}
|
|
254
|
-
if (rows.length === 0) continue;
|
|
255
|
-
const eventJsonLines = rows.map((row) => row.event_json);
|
|
256
|
-
const rawLines = eventJsonLines
|
|
257
|
-
.map(parseObject)
|
|
258
|
-
.filter((line): line is Record<string, unknown> => line !== undefined);
|
|
259
|
-
return {
|
|
260
|
-
agentId,
|
|
261
|
-
dbPath,
|
|
262
|
-
filePath: syntheticPath(agentId, sessionId),
|
|
263
|
-
rawLines,
|
|
264
|
-
eventJsonLines,
|
|
265
|
-
};
|
|
266
|
-
} finally {
|
|
267
|
-
db.close();
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
return null;
|
|
271
|
-
}
|
package/lib/openclaw-db.ts
DELETED
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Read OpenClaw 2026.9.2+ transcripts from the per-agent SQLite databases at
|
|
3
|
-
* `agents/<agentId>/agent/openclaw-agent.sqlite`.
|
|
4
|
-
*
|
|
5
|
-
* `event_json` is the exact logical JSONL record, so the dashboard can feed it
|
|
6
|
-
* through the same parser and download format used by archived JSONL files.
|
|
7
|
-
*/
|
|
8
|
-
import { existsSync } from "node:fs";
|
|
9
|
-
import { join } from "node:path";
|
|
10
|
-
import { openSqliteReadonly, type SqliteReader } from "./sqlite-reader";
|
|
11
|
-
|
|
12
|
-
const DB_NAME = "openclaw-agent.sqlite";
|
|
13
|
-
|
|
14
|
-
export interface OpenClawSqliteSession {
|
|
15
|
-
sessionId: string;
|
|
16
|
-
agentId: string;
|
|
17
|
-
dbPath: string;
|
|
18
|
-
transcriptPath: string;
|
|
19
|
-
mtimeMs: number;
|
|
20
|
-
sizeBytes: number;
|
|
21
|
-
channel: string;
|
|
22
|
-
label?: string;
|
|
23
|
-
chatId?: string;
|
|
24
|
-
chatType?: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface OpenClawSqliteTranscript {
|
|
28
|
-
agentId: string;
|
|
29
|
-
dbPath: string;
|
|
30
|
-
filePath: string;
|
|
31
|
-
rawLines: Record<string, unknown>[];
|
|
32
|
-
eventJsonLines: string[];
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
interface WindowRow {
|
|
36
|
-
session_id: string;
|
|
37
|
-
session_key: string;
|
|
38
|
-
updated_at: number;
|
|
39
|
-
transcript_updated_at: number | null;
|
|
40
|
-
ended_at: number | null;
|
|
41
|
-
channel: string | null;
|
|
42
|
-
chat_type: string | null;
|
|
43
|
-
display_name: string | null;
|
|
44
|
-
event_updated_at: number;
|
|
45
|
-
size_bytes: number;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
interface NodeRow {
|
|
49
|
-
current_session_id: string;
|
|
50
|
-
entry_json: string;
|
|
51
|
-
label: string | null;
|
|
52
|
-
display_name: string | null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
interface ConversationRow {
|
|
56
|
-
session_id: string;
|
|
57
|
-
channel: string;
|
|
58
|
-
kind: string;
|
|
59
|
-
peer_id: string;
|
|
60
|
-
delivery_target: string;
|
|
61
|
-
label: string | null;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
interface EventRow {
|
|
65
|
-
event_json: string;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
interface SessionMeta {
|
|
69
|
-
channel?: string;
|
|
70
|
-
label?: string;
|
|
71
|
-
chatId?: string;
|
|
72
|
-
chatType?: string;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function str(value: unknown): string | undefined {
|
|
76
|
-
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function parseObject(value: string): Record<string, unknown> | undefined {
|
|
80
|
-
try {
|
|
81
|
-
const parsed: unknown = JSON.parse(value);
|
|
82
|
-
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
83
|
-
? (parsed as Record<string, unknown>)
|
|
84
|
-
: undefined;
|
|
85
|
-
} catch {
|
|
86
|
-
return undefined;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function syntheticPath(agentId: string, sessionId: string): string {
|
|
91
|
-
return `openclaw-sqlite://${encodeURIComponent(agentId)}/${sessionId}`;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/** Existing per-agent SQLite databases, derived from the configured agents. */
|
|
95
|
-
export function listOpenClawDatabases(
|
|
96
|
-
home: string,
|
|
97
|
-
agentIds: string[],
|
|
98
|
-
): Array<{ agentId: string; dbPath: string }> {
|
|
99
|
-
const out: Array<{ agentId: string; dbPath: string }> = [];
|
|
100
|
-
for (const agentId of agentIds) {
|
|
101
|
-
const dbPath = join(home, "agents", agentId, "agent", DB_NAME);
|
|
102
|
-
if (existsSync(dbPath)) out.push({ agentId, dbPath });
|
|
103
|
-
}
|
|
104
|
-
return out;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function readNodeMetadata(db: SqliteReader): Map<string, SessionMeta> {
|
|
108
|
-
const out = new Map<string, SessionMeta>();
|
|
109
|
-
let rows: NodeRow[];
|
|
110
|
-
try {
|
|
111
|
-
rows = db.query<NodeRow>(
|
|
112
|
-
`SELECT current_session_id, entry_json, label, display_name
|
|
113
|
-
FROM session_nodes`,
|
|
114
|
-
);
|
|
115
|
-
} catch {
|
|
116
|
-
return out;
|
|
117
|
-
}
|
|
118
|
-
for (const row of rows) {
|
|
119
|
-
const entry = parseObject(row.entry_json) ?? {};
|
|
120
|
-
const origin =
|
|
121
|
-
entry.origin &&
|
|
122
|
-
typeof entry.origin === "object" &&
|
|
123
|
-
!Array.isArray(entry.origin)
|
|
124
|
-
? (entry.origin as Record<string, unknown>)
|
|
125
|
-
: {};
|
|
126
|
-
out.set(row.current_session_id, {
|
|
127
|
-
channel:
|
|
128
|
-
str(entry.lastChannel) ?? str(origin.provider) ?? str(origin.surface),
|
|
129
|
-
label:
|
|
130
|
-
str(row.label) ??
|
|
131
|
-
str(row.display_name) ??
|
|
132
|
-
str(entry.displayName) ??
|
|
133
|
-
str(origin.label),
|
|
134
|
-
chatId: str(entry.lastTo) ?? str(origin.from),
|
|
135
|
-
chatType: str(entry.chatType) ?? str(origin.chatType),
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
return out;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function readConversationMetadata(db: SqliteReader): Map<string, SessionMeta> {
|
|
142
|
-
const out = new Map<string, SessionMeta>();
|
|
143
|
-
let rows: ConversationRow[];
|
|
144
|
-
try {
|
|
145
|
-
rows = db.query<ConversationRow>(
|
|
146
|
-
`SELECT sc.session_id, c.channel, c.kind, c.peer_id,
|
|
147
|
-
c.delivery_target, c.label
|
|
148
|
-
FROM session_conversations sc
|
|
149
|
-
JOIN conversations c ON c.conversation_id = sc.conversation_id
|
|
150
|
-
ORDER BY CASE sc.role WHEN 'primary' THEN 0 ELSE 1 END, sc.last_seen_at DESC`,
|
|
151
|
-
);
|
|
152
|
-
} catch {
|
|
153
|
-
return out;
|
|
154
|
-
}
|
|
155
|
-
for (const row of rows) {
|
|
156
|
-
if (out.has(row.session_id)) continue;
|
|
157
|
-
out.set(row.session_id, {
|
|
158
|
-
channel: str(row.channel),
|
|
159
|
-
label: str(row.label),
|
|
160
|
-
chatId: str(row.delivery_target) ?? str(row.peer_id),
|
|
161
|
-
chatType: str(row.kind),
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
return out;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/** List every transcript-bearing session in all per-agent databases. */
|
|
168
|
-
export async function listOpenClawSqliteSessions(
|
|
169
|
-
home: string,
|
|
170
|
-
agentIds: string[],
|
|
171
|
-
): Promise<OpenClawSqliteSession[]> {
|
|
172
|
-
const sessions: OpenClawSqliteSession[] = [];
|
|
173
|
-
for (const { agentId, dbPath } of listOpenClawDatabases(home, agentIds)) {
|
|
174
|
-
const db = await openSqliteReadonly(dbPath);
|
|
175
|
-
if (!db) continue;
|
|
176
|
-
try {
|
|
177
|
-
let rows: WindowRow[];
|
|
178
|
-
try {
|
|
179
|
-
rows = db.query<WindowRow>(
|
|
180
|
-
`SELECT w.session_id, w.session_key, w.updated_at,
|
|
181
|
-
w.transcript_updated_at, w.ended_at, w.channel,
|
|
182
|
-
w.chat_type, w.display_name,
|
|
183
|
-
COALESCE((SELECT MAX(e.created_at)
|
|
184
|
-
FROM transcript_events e
|
|
185
|
-
WHERE e.session_id = w.session_id), 0) AS event_updated_at,
|
|
186
|
-
COALESCE((SELECT SUM(length(e.event_json) + 1)
|
|
187
|
-
FROM transcript_events e
|
|
188
|
-
WHERE e.session_id = w.session_id), 0) AS size_bytes
|
|
189
|
-
FROM session_windows w
|
|
190
|
-
WHERE EXISTS (SELECT 1 FROM transcript_events e
|
|
191
|
-
WHERE e.session_id = w.session_id)`,
|
|
192
|
-
);
|
|
193
|
-
} catch {
|
|
194
|
-
continue;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const nodes = readNodeMetadata(db);
|
|
198
|
-
const conversations = readConversationMetadata(db);
|
|
199
|
-
for (const row of rows) {
|
|
200
|
-
const node = nodes.get(row.session_id);
|
|
201
|
-
const conversation = conversations.get(row.session_id);
|
|
202
|
-
sessions.push({
|
|
203
|
-
sessionId: row.session_id,
|
|
204
|
-
agentId,
|
|
205
|
-
dbPath,
|
|
206
|
-
transcriptPath: syntheticPath(agentId, row.session_id),
|
|
207
|
-
mtimeMs: Math.max(
|
|
208
|
-
Number(row.updated_at) || 0,
|
|
209
|
-
Number(row.transcript_updated_at) || 0,
|
|
210
|
-
Number(row.ended_at) || 0,
|
|
211
|
-
Number(row.event_updated_at) || 0,
|
|
212
|
-
),
|
|
213
|
-
sizeBytes: Number(row.size_bytes) || 0,
|
|
214
|
-
channel:
|
|
215
|
-
str(row.channel) ??
|
|
216
|
-
conversation?.channel ??
|
|
217
|
-
node?.channel ??
|
|
218
|
-
"local",
|
|
219
|
-
label: str(row.display_name) ?? conversation?.label ?? node?.label,
|
|
220
|
-
chatId: conversation?.chatId ?? node?.chatId,
|
|
221
|
-
chatType:
|
|
222
|
-
str(row.chat_type) ?? conversation?.chatType ?? node?.chatType,
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
} finally {
|
|
226
|
-
db.close();
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
return sessions;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/** Read one SQLite transcript by UUID. The first matching agent wins. */
|
|
233
|
-
export async function readOpenClawSqliteTranscript(
|
|
234
|
-
home: string,
|
|
235
|
-
agentIds: string[],
|
|
236
|
-
sessionId: string,
|
|
237
|
-
): Promise<OpenClawSqliteTranscript | null> {
|
|
238
|
-
for (const { agentId, dbPath } of listOpenClawDatabases(home, agentIds)) {
|
|
239
|
-
const db = await openSqliteReadonly(dbPath);
|
|
240
|
-
if (!db) continue;
|
|
241
|
-
try {
|
|
242
|
-
let rows: EventRow[];
|
|
243
|
-
try {
|
|
244
|
-
rows = db.query<EventRow>(
|
|
245
|
-
`SELECT event_json
|
|
246
|
-
FROM transcript_events
|
|
247
|
-
WHERE session_id = ?
|
|
248
|
-
ORDER BY seq ASC`,
|
|
249
|
-
[sessionId],
|
|
250
|
-
);
|
|
251
|
-
} catch {
|
|
252
|
-
continue;
|
|
253
|
-
}
|
|
254
|
-
if (rows.length === 0) continue;
|
|
255
|
-
const eventJsonLines = rows.map((row) => row.event_json);
|
|
256
|
-
const rawLines = eventJsonLines
|
|
257
|
-
.map(parseObject)
|
|
258
|
-
.filter((line): line is Record<string, unknown> => line !== undefined);
|
|
259
|
-
return {
|
|
260
|
-
agentId,
|
|
261
|
-
dbPath,
|
|
262
|
-
filePath: syntheticPath(agentId, sessionId),
|
|
263
|
-
rawLines,
|
|
264
|
-
eventJsonLines,
|
|
265
|
-
};
|
|
266
|
-
} finally {
|
|
267
|
-
db.close();
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
return null;
|
|
271
|
-
}
|