@maudecode/talaria-web 1.16.1 → 1.18.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/_release.json +8 -8
- package/dist/api/auth-raw.d.ts +1 -1
- package/dist/api/auth-raw.js +4 -4
- package/dist/api/auth-raw.js.map +1 -1
- package/dist/api/automation-raw.d.ts +6 -0
- package/dist/api/automation-raw.js +59 -9
- package/dist/api/automation-raw.js.map +1 -1
- package/dist/api/automation-router.d.ts +163 -10
- package/dist/api/automation-router.js +25 -8
- package/dist/api/automation-router.js.map +1 -1
- package/dist/api/chat-router.d.ts +700 -15
- package/dist/api/chat-router.js +74 -55
- package/dist/api/chat-router.js.map +1 -1
- package/dist/api/git-router.d.ts +47 -2
- package/dist/api/git-router.js +31 -22
- package/dist/api/git-router.js.map +1 -1
- package/dist/api/raw-routes.d.ts +14 -0
- package/dist/api/raw-routes.js +277 -36
- package/dist/api/raw-routes.js.map +1 -1
- package/dist/api/router.d.ts +10 -0
- package/dist/api/router.js +10 -8
- package/dist/api/router.js.map +1 -1
- package/dist/api/sessions-router.d.ts +1710 -73
- package/dist/api/sessions-router.js +164 -10
- package/dist/api/sessions-router.js.map +1 -1
- package/dist/api/settings-router.d.ts +132 -2
- package/dist/api/settings-router.js +15 -5
- package/dist/api/settings-router.js.map +1 -1
- package/dist/api/sse-routes.d.ts +16 -3
- package/dist/api/sse-routes.js +194 -67
- package/dist/api/sse-routes.js.map +1 -1
- package/dist/api/tools-raw.js +12 -25
- package/dist/api/tools-raw.js.map +1 -1
- package/dist/api/tools-router.d.ts +425 -19
- package/dist/api/tools-router.js +157 -26
- package/dist/api/tools-router.js.map +1 -1
- package/dist/app.d.ts +0 -9377
- package/dist/app.js +42 -17
- package/dist/app.js.map +1 -1
- package/dist/auth/gate.js +8 -2
- package/dist/auth/gate.js.map +1 -1
- package/dist/auth/oidc.d.ts +5 -2
- package/dist/auth/oidc.js +8 -7
- package/dist/auth/oidc.js.map +1 -1
- package/dist/bin/talaria-web.js +1 -1
- package/dist/bin/talaria-web.js.map +1 -1
- package/dist/cli/dotenv.js +1 -0
- package/dist/cli/dotenv.js.map +1 -1
- package/dist/config/agent-config.d.ts +2 -0
- package/dist/config/agent-config.js +12 -2
- package/dist/config/agent-config.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.js +5 -1
- package/dist/config.js.map +1 -1
- package/dist/http/context.d.ts +20 -3
- package/dist/http/context.js +41 -8
- package/dist/http/context.js.map +1 -1
- package/dist/http/csp.d.ts +2 -1
- package/dist/http/csp.js +3 -2
- package/dist/http/csp.js.map +1 -1
- package/dist/onboarding.js +4 -0
- package/dist/onboarding.js.map +1 -1
- package/dist/profiles/profiles.d.ts +10 -0
- package/dist/profiles/profiles.js +40 -2
- package/dist/profiles/profiles.js.map +1 -1
- package/dist/providers/catalog.d.ts +101 -8
- package/dist/providers/catalog.js +463 -123
- package/dist/providers/catalog.js.map +1 -1
- package/dist/raster-image.d.ts +7 -0
- package/dist/raster-image.js +267 -0
- package/dist/raster-image.js.map +1 -0
- package/dist/redact.d.ts +1 -0
- package/dist/redact.js +354 -44
- package/dist/redact.js.map +1 -1
- package/dist/runtime.js +111 -27
- package/dist/runtime.js.map +1 -1
- package/dist/server.js +5 -0
- package/dist/server.js.map +1 -1
- package/dist/sessions/anchor.d.ts +2 -0
- package/dist/sessions/anchor.js +8 -3
- package/dist/sessions/anchor.js.map +1 -1
- package/dist/sessions/background-tasks.d.ts +2 -9
- package/dist/sessions/background-tasks.js +2 -12
- package/dist/sessions/background-tasks.js.map +1 -1
- package/dist/sessions/claude-code.d.ts +19 -0
- package/dist/sessions/claude-code.js +250 -0
- package/dist/sessions/claude-code.js.map +1 -0
- package/dist/sessions/cli-sessions.d.ts +15 -4
- package/dist/sessions/cli-sessions.js +120 -29
- package/dist/sessions/cli-sessions.js.map +1 -1
- package/dist/sessions/completions.d.ts +61 -9
- package/dist/sessions/completions.js +282 -34
- package/dist/sessions/completions.js.map +1 -1
- package/dist/sessions/compress.d.ts +14 -1
- package/dist/sessions/compress.js +52 -11
- package/dist/sessions/compress.js.map +1 -1
- package/dist/sessions/export.d.ts +5 -0
- package/dist/sessions/export.js +30 -0
- package/dist/sessions/export.js.map +1 -1
- package/dist/sessions/gateway-watcher.d.ts +7 -3
- package/dist/sessions/gateway-watcher.js +31 -19
- package/dist/sessions/gateway-watcher.js.map +1 -1
- package/dist/sessions/handoff.d.ts +32 -0
- package/dist/sessions/handoff.js +114 -0
- package/dist/sessions/handoff.js.map +1 -0
- package/dist/sessions/journal.d.ts +8 -0
- package/dist/sessions/journal.js +44 -10
- package/dist/sessions/journal.js.map +1 -1
- package/dist/sessions/list.d.ts +13 -3
- package/dist/sessions/list.js +46 -15
- package/dist/sessions/list.js.map +1 -1
- package/dist/sessions/merge.d.ts +53 -5
- package/dist/sessions/merge.js +219 -23
- package/dist/sessions/merge.js.map +1 -1
- package/dist/sessions/recovery.d.ts +22 -0
- package/dist/sessions/recovery.js +506 -0
- package/dist/sessions/recovery.js.map +1 -0
- package/dist/sessions/relay.d.ts +21 -2
- package/dist/sessions/relay.js +156 -11
- package/dist/sessions/relay.js.map +1 -1
- package/dist/sessions/service.d.ts +152 -8
- package/dist/sessions/service.js +640 -72
- package/dist/sessions/service.js.map +1 -1
- package/dist/sessions/session.d.ts +17 -1
- package/dist/sessions/session.js +63 -4
- package/dist/sessions/session.js.map +1 -1
- package/dist/sessions/state-db-worker.d.ts +1 -0
- package/dist/sessions/state-db-worker.js +33 -0
- package/dist/sessions/state-db-worker.js.map +1 -0
- package/dist/sessions/state-db.d.ts +87 -4
- package/dist/sessions/state-db.js +417 -8
- package/dist/sessions/state-db.js.map +1 -1
- package/dist/sessions/store.d.ts +7 -0
- package/dist/sessions/store.js +36 -22
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/streams.d.ts +10 -0
- package/dist/sessions/streams.js +14 -3
- package/dist/sessions/streams.js.map +1 -1
- package/dist/sessions/titles.d.ts +2 -0
- package/dist/sessions/titles.js +4 -0
- package/dist/sessions/titles.js.map +1 -1
- package/dist/sessions/todo.d.ts +6 -1
- package/dist/sessions/todo.js +11 -4
- package/dist/sessions/todo.js.map +1 -1
- package/dist/sessions/tool-display.d.ts +12 -1
- package/dist/sessions/tool-display.js +50 -1
- package/dist/sessions/tool-display.js.map +1 -1
- package/dist/sessions/turn-context.d.ts +1 -1
- package/dist/sessions/turn-context.js +11 -7
- package/dist/sessions/turn-context.js.map +1 -1
- package/dist/sessions/turn.d.ts +67 -11
- package/dist/sessions/turn.js +413 -111
- package/dist/sessions/turn.js.map +1 -1
- package/dist/sessions/wakeup-pause.d.ts +59 -0
- package/dist/sessions/wakeup-pause.js +181 -0
- package/dist/sessions/wakeup-pause.js.map +1 -0
- package/dist/settings.d.ts +20 -2
- package/dist/settings.js +45 -9
- package/dist/settings.js.map +1 -1
- package/dist/sidecar/fake.d.ts +4 -4
- package/dist/sidecar/fake.js +5 -2
- package/dist/sidecar/fake.js.map +1 -1
- package/dist/spa.js +2 -1
- package/dist/spa.js.map +1 -1
- package/dist/startup.d.ts +13 -5
- package/dist/startup.js +48 -0
- package/dist/startup.js.map +1 -1
- package/dist/test/harness.js +2 -0
- package/dist/test/harness.js.map +1 -1
- package/dist/test/ts-worker-hooks.d.ts +1 -0
- package/dist/test/ts-worker-hooks.js +24 -0
- package/dist/test/ts-worker-hooks.js.map +1 -0
- package/dist/text/diff.d.ts +9 -14
- package/dist/text/diff.js +74 -108
- package/dist/text/diff.js.map +1 -1
- package/dist/tools/crons.js +45 -8
- package/dist/tools/crons.js.map +1 -1
- package/dist/tools/dashboard-plugins.d.ts +53 -0
- package/dist/tools/dashboard-plugins.js +188 -0
- package/dist/tools/dashboard-plugins.js.map +1 -0
- package/dist/tools/extensions.d.ts +13 -1
- package/dist/tools/extensions.js +132 -60
- package/dist/tools/extensions.js.map +1 -1
- package/dist/tools/health.d.ts +32 -0
- package/dist/tools/health.js +111 -19
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/insights.d.ts +8 -2
- package/dist/tools/insights.js +18 -2
- package/dist/tools/insights.js.map +1 -1
- package/dist/tools/kanban.d.ts +41 -1
- package/dist/tools/kanban.js +113 -2
- package/dist/tools/kanban.js.map +1 -1
- package/dist/tools/mcp.d.ts +15 -1
- package/dist/tools/mcp.js +99 -5
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/project-os.d.ts +11 -0
- package/dist/tools/project-os.js +267 -0
- package/dist/tools/project-os.js.map +1 -0
- package/dist/tools/skills.d.ts +5 -1
- package/dist/tools/skills.js +5 -3
- package/dist/tools/skills.js.map +1 -1
- package/dist/tools/terminal.d.ts +1 -0
- package/dist/tools/terminal.js +1 -1
- package/dist/tools/terminal.js.map +1 -1
- package/dist/tools/updates.d.ts +33 -8
- package/dist/tools/updates.js +236 -57
- package/dist/tools/updates.js.map +1 -1
- package/dist/tools/wiki.d.ts +68 -0
- package/dist/tools/wiki.js +413 -0
- package/dist/tools/wiki.js.map +1 -0
- package/dist/workspace/escape.d.ts +61 -0
- package/dist/workspace/escape.js +149 -0
- package/dist/workspace/escape.js.map +1 -0
- package/dist/workspace/extract.d.ts +22 -0
- package/dist/workspace/extract.js +308 -0
- package/dist/workspace/extract.js.map +1 -0
- package/dist/workspace/fs.d.ts +19 -3
- package/dist/workspace/fs.js +96 -23
- package/dist/workspace/fs.js.map +1 -1
- package/dist/workspace/git.d.ts +18 -0
- package/dist/workspace/git.js +38 -25
- package/dist/workspace/git.js.map +1 -1
- package/dist/workspace/media.d.ts +4 -4
- package/dist/workspace/media.js +18 -45
- package/dist/workspace/media.js.map +1 -1
- package/dist/workspace/preview.d.ts +28 -0
- package/dist/workspace/preview.js +110 -0
- package/dist/workspace/preview.js.map +1 -0
- package/dist/workspace/rollback.d.ts +36 -21
- package/dist/workspace/rollback.js +179 -270
- package/dist/workspace/rollback.js.map +1 -1
- package/dist/workspace/unzip.js +4 -1
- package/dist/workspace/unzip.js.map +1 -1
- package/dist/workspace/upload.d.ts +9 -4
- package/dist/workspace/upload.js +9 -3
- package/dist/workspace/upload.js.map +1 -1
- package/dist/workspace/worktrees.d.ts +2 -1
- package/dist/workspace/worktrees.js +14 -15
- package/dist/workspace/worktrees.js.map +1 -1
- package/package.json +4 -2
- package/sidecar/agent_dependency.json +4 -4
- package/sidecar/scripts/replay_sidecar.py +25 -1
- package/sidecar/talaria_sidecar/__init__.py +1 -1
- package/sidecar/talaria_sidecar/__main__.py +7 -1
- package/sidecar/talaria_sidecar/home.py +52 -2
- package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
- package/sidecar/talaria_sidecar/methods/aux.py +39 -5
- package/sidecar/talaria_sidecar/methods/chat.py +431 -43
- package/sidecar/talaria_sidecar/methods/checkpoints.py +89 -0
- package/sidecar/talaria_sidecar/methods/commands.py +96 -2
- package/sidecar/talaria_sidecar/methods/cron.py +39 -8
- package/sidecar/talaria_sidecar/methods/gateway.py +32 -15
- package/sidecar/talaria_sidecar/methods/kanban.py +140 -19
- package/sidecar/talaria_sidecar/methods/mcp.py +1 -1
- package/sidecar/talaria_sidecar/methods/process.py +115 -2
- package/sidecar/talaria_sidecar/methods/profiles.py +84 -8
- package/sidecar/talaria_sidecar/methods/providers.py +27 -8
- package/sidecar/talaria_sidecar/methods/runtime.py +3 -0
- package/sidecar/talaria_sidecar/methods/state_db.py +39 -5
- package/sidecar/talaria_sidecar/methods/text.py +17 -1
- package/sidecar/talaria_sidecar/methods/usage.py +257 -4
- package/sidecar/talaria_sidecar/runtime.py +17 -1
- package/static/dist/FILES.txt +127 -125
- package/static/dist/assets/AppShell-g3bkgnvt.js +1 -0
- package/static/dist/assets/ChatPage-oo7bdan6.js +25 -0
- package/static/dist/assets/Dialog-g355qxhp.js +1 -0
- package/static/dist/assets/ExtensionRoute-i2y9fvjm.js +1 -0
- package/static/dist/assets/HubRoute-lmkrbw47.js +2 -0
- package/static/dist/assets/{Markdown-jqrx5es0.js → Markdown-j4kut4j2.js} +125 -125
- package/static/dist/assets/RightPanel-ohlsdzfl.js +1 -0
- package/static/dist/assets/Select-kddq75qc.js +1 -0
- package/static/dist/assets/SessionListPanel-lu3oy0hw.js +1 -0
- package/static/dist/assets/SettingsLayout-o9bv4mgb.js +1 -0
- package/static/dist/assets/States-eq6fe29m.js +1 -0
- package/static/dist/assets/Toaster-pc247u9f.js +1 -0
- package/static/dist/assets/_app-f8n1i0m1.js +1 -0
- package/static/dist/assets/_app.ext._extensionId-gfbzpoou.js +1 -0
- package/static/dist/assets/_app.index-bzzv80hk.js +1 -0
- package/static/dist/assets/_app.insights-dzixbryi.js +1 -0
- package/static/dist/assets/_app.kanban-c6hep2us.js +1 -0
- package/static/dist/assets/_app.logs-i69qds98.js +1 -0
- package/static/dist/assets/_app.memory-kl4vf0gd.js +1 -0
- package/static/dist/assets/_app.profiles-b8zinmyp.js +1 -0
- package/static/dist/assets/{_app.session._sessionId-hh27wwu2.js → _app.session._sessionId-fn1bhde6.js} +1 -1
- package/static/dist/assets/_app.settings-cg8plwmf.js +1 -0
- package/static/dist/assets/_app.settings._section-bkwbi9zn.js +3 -0
- package/static/dist/assets/_app.skills-cs47sbvs.js +1 -0
- package/static/dist/assets/_app.tasks-dwvk64tc.js +1 -0
- package/static/dist/assets/_app.todos-c8xjm8p3.js +1 -0
- package/static/dist/assets/_app.workspaces-ehvd1gds.js +1 -0
- package/static/dist/assets/{abnfDiagram-VCTEODGH-oity9y4o.js → abnfDiagram-VCTEODGH-c8kdixke.js} +1 -1
- package/static/dist/assets/architecture-7GRP2DOG-6crvnylg.js +1 -0
- package/static/dist/assets/{architectureDiagram-5GKGNRK7-ceaepnyr.js → architectureDiagram-5GKGNRK7-cku06x1p.js} +1 -1
- package/static/dist/assets/{back-eu64w89w.js → back-h7aun7ew.js} +1 -1
- package/static/dist/assets/{blockDiagram-I7D4REHJ-n79st4pj.js → blockDiagram-I7D4REHJ-jzthp1wa.js} +1 -1
- package/static/dist/assets/{c4Diagram-7LVT6UL2-mi73akzk.js → c4Diagram-7LVT6UL2-mwr67mt8.js} +1 -1
- package/static/dist/assets/{cancel-mzvkdjg8.js → cancel-fhi0vcnu.js} +1 -1
- package/static/dist/assets/channel-b2zo73z1.js +1 -0
- package/static/dist/assets/{chunk-4HAMMTFA-laat0g1q.js → chunk-4HAMMTFA-gpq1y228.js} +1 -1
- package/static/dist/assets/{chunk-75Z2AOVW-0psy1tr2.js → chunk-75Z2AOVW-ktje58c4.js} +1 -1
- package/static/dist/assets/{chunk-DU6HZSFF-lw8uox8x.js → chunk-DU6HZSFF-ofajdixh.js} +3 -3
- package/static/dist/assets/{chunk-F27PBJKO-erassib3.js → chunk-F27PBJKO-cmev85ti.js} +1 -1
- package/static/dist/assets/{chunk-GMAD6QVW-fz7rx619.js → chunk-GMAD6QVW-htjgt22y.js} +1 -1
- package/static/dist/assets/{chunk-GVQU2GXP-gdb0epb2.js → chunk-GVQU2GXP-qndvoxl7.js} +1 -1
- package/static/dist/assets/{chunk-IMKFNOWR-ea8t26qw.js → chunk-IMKFNOWR-e5bkd5q6.js} +1 -1
- package/static/dist/assets/{chunk-L3NEJ4N5-mb1gu9kz.js → chunk-L3NEJ4N5-mj1155r6.js} +1 -1
- package/static/dist/assets/{chunk-OSK3NFVY-eovmccvy.js → chunk-OSK3NFVY-e7gkikcw.js} +1 -1
- package/static/dist/assets/{chunk-P2QGCYS3-bo55zjo5.js → chunk-P2QGCYS3-f7t54xfm.js} +1 -1
- package/static/dist/assets/{chunk-POPQ4Y6H-ja7ohe4h.js → chunk-POPQ4Y6H-i927v9oa.js} +1 -1
- package/static/dist/assets/{chunk-PWAF6VOD-e30g9nus.js → chunk-PWAF6VOD-m84lmnyt.js} +1 -1
- package/static/dist/assets/{chunk-SHT3W25Y-gbb798f7.js → chunk-SHT3W25Y-mi0tlcu9.js} +1 -1
- package/static/dist/assets/{chunk-SVP7TREG-h2iw8urm.js → chunk-SVP7TREG-dnau702j.js} +1 -1
- package/static/dist/assets/{chunk-TICWLB2K-fd2cottz.js → chunk-TICWLB2K-edem1gkg.js} +1 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-oe99st8x.js +1 -0
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-oe99st8x.js +1 -0
- package/static/dist/assets/{copied-h65fc3cx.js → copied-hcplv46p.js} +1 -1
- package/static/dist/assets/copy-magtofyp.js +1 -0
- package/static/dist/assets/{cynefin-OW5HDTMX-lbltyl5j.js → cynefin-OW5HDTMX-siqlulkl.js} +1 -1
- package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-lxhsqq4a.js → cynefinDiagram-5FMLGOSQ-i648tah9.js} +1 -1
- package/static/dist/assets/{dagre-GXQ25YYZ-gn4nnaln.js → dagre-GXQ25YYZ-mwn6uc17.js} +1 -1
- package/static/dist/assets/{diagram-S7CK7UJ4-pa3ij6q7.js → diagram-S7CK7UJ4-l8abxaes.js} +1 -1
- package/static/dist/assets/{diagram-UQ7AKVKN-zbipyz57.js → diagram-UQ7AKVKN-mekq7zgq.js} +1 -1
- package/static/dist/assets/{diagram-VSXAHHWV-d1kbpzgf.js → diagram-VSXAHHWV-fnky6lvc.js} +1 -1
- package/static/dist/assets/{diagram-VX7I27RA-i3ty14xl.js → diagram-VX7I27RA-xe6r5qfw.js} +1 -1
- package/static/dist/assets/{diagram-Z3DM3KII-m8xefqa7.js → diagram-Z3DM3KII-nq07dg7k.js} +1 -1
- package/static/dist/assets/{ebnfDiagram-PWID7BFC-nz7wj05l.js → ebnfDiagram-PWID7BFC-c62ipm3g.js} +1 -1
- package/static/dist/assets/endpoints-klbxod4t.js +64 -0
- package/static/dist/assets/{erDiagram-RLTQ6QDP-fa41ib83.js → erDiagram-RLTQ6QDP-h39kmnzy.js} +1 -1
- package/static/dist/assets/eventmodeling-NTZA5JFV-obfede4u.js +1 -0
- package/static/dist/assets/flowDiagram-HODETNUW-kdpsp1je.js +1 -0
- package/static/dist/assets/{ganttDiagram-EL5Y4UJY-n7zq01qu.js → ganttDiagram-EL5Y4UJY-ngbsyp37.js} +1 -1
- package/static/dist/assets/{gitGraph-4MIJSDKK-c89emb07.js → gitGraph-4MIJSDKK-fr2i7caa.js} +1 -1
- package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-cz7cgr6w.js → gitGraphDiagram-WWUBYQGX-eravdti4.js} +1 -1
- package/static/dist/assets/{highlighted-body-KPVGNVTW-d9bapmni.js → highlighted-body-KPVGNVTW-jwpop9p8.js} +1 -1
- package/static/dist/assets/host-i828xuo7.js +1 -0
- package/static/dist/assets/index-eh8zilnv.css +2 -0
- package/static/dist/assets/index-r648f4o1.js +11 -0
- package/static/dist/assets/{info-A6RAGUB7-ndddhhhh.js → info-A6RAGUB7-h11x0dxo.js} +1 -1
- package/static/dist/assets/{infoDiagram-27XIBGKW-ccxigcpf.js → infoDiagram-27XIBGKW-dfh47dw9.js} +1 -1
- package/static/dist/assets/{ishikawaDiagram-5VMMS53U-le0z9vtc.js → ishikawaDiagram-5VMMS53U-i6ypq351.js} +1 -1
- package/static/dist/assets/{journeyDiagram-3NMN7TZE-ivsmb26o.js → journeyDiagram-3NMN7TZE-lduf1z95.js} +1 -1
- package/static/dist/assets/{kanban-definition-UXKFOSKX-h6n2awt0.js → kanban-definition-UXKFOSKX-e18bu4pg.js} +1 -1
- package/static/dist/assets/lazyRouteComponent-e1y4t2i9.js +1 -0
- package/static/dist/assets/{line-dmzlfe0u.js → line-meizqsvn.js} +1 -1
- package/static/dist/assets/link-oot2yn73.js +1 -0
- package/static/dist/assets/login-gu28l9ou.js +1 -0
- package/static/dist/assets/mermaid-HWGCJPDP-mtwrj8fn.js +1 -0
- package/static/dist/assets/{mermaid-parser.core-gwyd5bnq.js → mermaid-parser.core-ntne45i9.js} +3 -3
- package/static/dist/assets/{mindmap-definition-YA3MSWOX-l68gg5h7.js → mindmap-definition-YA3MSWOX-27b26eok.js} +1 -1
- package/static/dist/assets/onboarding-lkphzu1s.js +1 -0
- package/static/dist/assets/onboarding_model_label-ftpjdwqk.js +1 -0
- package/static/dist/assets/{packet-AYTQ26CC-gpv06065.js → packet-AYTQ26CC-l6jdka8p.js} +1 -1
- package/static/dist/assets/{pegDiagram-XKGWAZYB-e52vs23u.js → pegDiagram-XKGWAZYB-g1er3bxj.js} +1 -1
- package/static/dist/assets/{pie-WAS4IAKB-l6m7nz5s.js → pie-WAS4IAKB-i0ylcrt9.js} +1 -1
- package/static/dist/assets/{pieDiagram-E7YTZNPT-b4is36bq.js → pieDiagram-E7YTZNPT-fbz1e55z.js} +1 -1
- package/static/dist/assets/{quadrantDiagram-AXDQQJYC-m8vt2788.js → quadrantDiagram-AXDQQJYC-hhue7d8o.js} +1 -1
- package/static/dist/assets/{radar-RG4KPBEZ-nxbrhiov.js → radar-RG4KPBEZ-f9b70aa4.js} +1 -1
- package/static/dist/assets/{railroad-74A4TZTK-222mu9hi.js → railroad-74A4TZTK-lgsuoeda.js} +1 -1
- package/static/dist/assets/railroad-abnf-HS5TGJTU-nf9d6pdx.js +1 -0
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-f7ummkt5.js +1 -0
- package/static/dist/assets/railroad-peg-WCYAUIDC-oczq5tqs.js +1 -0
- package/static/dist/assets/{railroadDiagram-O6MQD6OU-o8lldfzv.js → railroadDiagram-O6MQD6OU-eqpy9fnz.js} +1 -1
- package/static/dist/assets/refresh-abtu93ke.js +1 -0
- package/static/dist/assets/refresh-cw-hlwb02qv.js +1 -0
- package/static/dist/assets/{requirementDiagram-BXWQKSXE-ovyq38kv.js → requirementDiagram-BXWQKSXE-ogf6puhi.js} +1 -1
- package/static/dist/assets/{sankeyDiagram-P5KCCOFB-ou7lznor.js → sankeyDiagram-P5KCCOFB-fqb8xcjf.js} +1 -1
- package/static/dist/assets/{saved-bazmcup9.js → saved-girnabkf.js} +1 -1
- package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-ovckdzf2.js → sequenceDiagram-WJ2MYXX4-dlcz6qjz.js} +1 -1
- package/static/dist/assets/{settings_section_extensions_title-ertwwhlx.js → settings_section_extensions_title-h14cwk6f.js} +1 -1
- package/static/dist/assets/share._token-kl0r7ido.js +2 -0
- package/static/dist/assets/sliders-horizontal-n1zm34qq.js +1 -0
- package/static/dist/assets/sse-iwku0sjo.js +1 -0
- package/static/dist/assets/{stateDiagram-D77RDMKH-fcrexkkv.js → stateDiagram-D77RDMKH-fyoznpcs.js} +1 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-ixhx8r46.js +1 -0
- package/static/dist/assets/{swimlanes-42K2YHIH-f7usu8fw.js → swimlanes-42K2YHIH-oefldhfy.js} +1 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-h9ersk2e.js +8 -0
- package/static/dist/assets/{timeline-definition-24CTP7MA-gp1hvz9f.js → timeline-definition-24CTP7MA-b1vl2zil.js} +1 -1
- package/static/dist/assets/todoStore-jjr5yr78.js +1 -0
- package/static/dist/assets/{treeView-Q6P3EWNA-gb9gf11u.js → treeView-Q6P3EWNA-f7hcci5o.js} +1 -1
- package/static/dist/assets/{treemap-WGGIJYW6-nuvfnvvi.js → treemap-WGGIJYW6-nl85071a.js} +1 -1
- package/static/dist/assets/units-kgxzxfhi.js +1 -0
- package/static/dist/assets/{untitled-htelhc68.js → untitled-cikfjntn.js} +1 -1
- package/static/dist/assets/{useForm-h2t0u14e.js → useForm-kqoqg0k9.js} +1 -1
- package/static/dist/assets/useLocale-o59tbiea.js +1 -0
- package/static/dist/assets/{useParams-dqd64jv7.js → useParams-b4dq6n4q.js} +1 -1
- package/static/dist/assets/{useSearch-j30pvsy7.js → useSearch-ipfmv3he.js} +1 -1
- package/static/dist/assets/{vennDiagram-4TSXK5OY-fzchbzaj.js → vennDiagram-4TSXK5OY-h5hzbk0n.js} +1 -1
- package/static/dist/assets/{wardley-WFR3VGLG-m47mhfbh.js → wardley-WFR3VGLG-jftvpm3e.js} +1 -1
- package/static/dist/assets/{wardleyDiagram-VM6X3IG4-odg6ct1z.js → wardleyDiagram-VM6X3IG4-hedh85ge.js} +1 -1
- package/static/dist/assets/{xychartDiagram-S5SC5T6Z-mrhms5um.js → xychartDiagram-S5SC5T6Z-e49523ab.js} +1 -1
- package/static/dist/index.html +1 -1
- package/static/dist/sw.js +2 -2
- package/static/dist/assets/AppShell-ef3bhu32.js +0 -1
- package/static/dist/assets/Button-nx37f4u1.js +0 -1
- package/static/dist/assets/ChatPage-cdcpykcg.js +0 -25
- package/static/dist/assets/Dialog-mec42hvb.js +0 -1
- package/static/dist/assets/HubRoute-ecb65zpr.js +0 -2
- package/static/dist/assets/RightPanel-d1lgvk4s.js +0 -1
- package/static/dist/assets/Select-h4ivl9qf.js +0 -1
- package/static/dist/assets/SessionListPanel-ewib046b.js +0 -1
- package/static/dist/assets/SettingsLayout-lx654cup.js +0 -1
- package/static/dist/assets/States-ehsb6lzo.js +0 -1
- package/static/dist/assets/Toaster-mch1pa3t.js +0 -1
- package/static/dist/assets/_app-m8d961ef.js +0 -1
- package/static/dist/assets/_app.ext._extensionId-mp33hbzi.js +0 -1
- package/static/dist/assets/_app.index-dk6zp7e0.js +0 -1
- package/static/dist/assets/_app.insights-jt2fk4i1.js +0 -1
- package/static/dist/assets/_app.kanban-if4pubeu.js +0 -1
- package/static/dist/assets/_app.logs-mfaw9m6g.js +0 -1
- package/static/dist/assets/_app.memory-h3eaarb6.js +0 -1
- package/static/dist/assets/_app.profiles-ienktovs.js +0 -1
- package/static/dist/assets/_app.settings-dpoe0bzf.js +0 -1
- package/static/dist/assets/_app.settings._section-l468ynag.js +0 -3
- package/static/dist/assets/_app.skills-kcbncc8i.js +0 -1
- package/static/dist/assets/_app.tasks-occdrqhw.js +0 -2
- package/static/dist/assets/_app.todos-nnke2rcc.js +0 -1
- package/static/dist/assets/_app.workspaces-cdlatvwj.js +0 -1
- package/static/dist/assets/architecture-7GRP2DOG-hj11333z.js +0 -1
- package/static/dist/assets/channel-mbvmf2vv.js +0 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-o8r05k0n.js +0 -1
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-o8r05k0n.js +0 -1
- package/static/dist/assets/copy-e6977uwq.js +0 -1
- package/static/dist/assets/endpoints-k7yf25m0.js +0 -64
- package/static/dist/assets/eventmodeling-NTZA5JFV-kpbq09bx.js +0 -1
- package/static/dist/assets/flowDiagram-HODETNUW-lcz0kx14.js +0 -1
- package/static/dist/assets/index-h00usru2.js +0 -11
- package/static/dist/assets/index-n73ijkv2.css +0 -2
- package/static/dist/assets/lazyRouteComponent-m1rtyk4t.js +0 -1
- package/static/dist/assets/link-budeg5t9.js +0 -1
- package/static/dist/assets/login-kjhasvp8.js +0 -1
- package/static/dist/assets/matchContext-f8oy3lo7.js +0 -1
- package/static/dist/assets/mermaid-HWGCJPDP-jb5d211j.js +0 -1
- package/static/dist/assets/onboarding-cdfrk0pj.js +0 -1
- package/static/dist/assets/railroad-abnf-HS5TGJTU-kdvgl6x8.js +0 -1
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-itiqslby.js +0 -1
- package/static/dist/assets/railroad-peg-WCYAUIDC-go7kov78.js +0 -1
- package/static/dist/assets/refresh-cw-kbcje1uy.js +0 -1
- package/static/dist/assets/search-jen74z4u.js +0 -1
- package/static/dist/assets/share._token-dan9hgvj.js +0 -2
- package/static/dist/assets/sliders-horizontal-f9cb3lh3.js +0 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-lcfraua2.js +0 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-ogmanni0.js +0 -8
- package/static/dist/assets/todoStore-eqtid4r4.js +0 -1
- package/static/dist/assets/useLocale-hcsb84pj.js +0 -1
- package/static/dist/assets/useNavigate-nwy70ztj.js +0 -1
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { existsSync, openSync, readSync, closeSync, statSync } from 'node:fs';
|
|
9
9
|
import { DatabaseSync } from 'node:sqlite';
|
|
10
|
+
import { Worker } from 'node:worker_threads';
|
|
10
11
|
import { str } from '../util.js';
|
|
11
12
|
import { MESSAGING_SOURCES } from './source-kind.js';
|
|
12
13
|
import { looksLikeDefaultCliTitle, normalizeSourceName } from './titles.js';
|
|
@@ -255,6 +256,9 @@ function tableColumns(db, table) {
|
|
|
255
256
|
}
|
|
256
257
|
}
|
|
257
258
|
const warnedNoSourceColumn = new Set();
|
|
259
|
+
let readDelayMs = 0;
|
|
260
|
+
/** Test hook: each listing read (and each listing worker request) blocks its thread this long first, standing in for a slow `state.db` (TAL-920). */
|
|
261
|
+
export function setStateDbReadDelayForTests(ms) { readDelayMs = ms; }
|
|
258
262
|
/**
|
|
259
263
|
* Python `read_importable_agent_session_rows`. The recency slice is bounded to
|
|
260
264
|
* `limit * 8` candidates before the messages aggregate runs; subagent parents
|
|
@@ -269,6 +273,8 @@ export function readImportableAgentSessionRows(dbPath, opts = {}) {
|
|
|
269
273
|
const limit = opts.limit === undefined ? 200 : opts.limit;
|
|
270
274
|
const exclude = opts.excludeSources === undefined ? ['cron', 'webui'] : opts.excludeSources;
|
|
271
275
|
const include = opts.includeSources ?? null;
|
|
276
|
+
if (readDelayMs > 0)
|
|
277
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, readDelayMs);
|
|
272
278
|
const db = openStateDbReadonly(dbPath);
|
|
273
279
|
try {
|
|
274
280
|
const sessionCols = tableColumns(db, 'sessions');
|
|
@@ -579,6 +585,114 @@ export function cheapChangeFingerprint(dbPath, onError) {
|
|
|
579
585
|
return null;
|
|
580
586
|
}
|
|
581
587
|
}
|
|
588
|
+
let listingWorker = null;
|
|
589
|
+
let nextCallId = 0;
|
|
590
|
+
/** Set while `stopStateDbWorker` waits for the worker to exit; calls then reject instead of starting another worker. */
|
|
591
|
+
let stoppingWorker = false;
|
|
592
|
+
/** Reject every call still waiting on `current` and forget it, so the next call starts a fresh worker. */
|
|
593
|
+
function retireListingWorker(current, error) {
|
|
594
|
+
if (listingWorker === current)
|
|
595
|
+
listingWorker = null;
|
|
596
|
+
for (const call of current.pending.values())
|
|
597
|
+
call.reject(error);
|
|
598
|
+
current.pending.clear();
|
|
599
|
+
}
|
|
600
|
+
/** The lazily started, long-lived listing worker; requests run one at a time in arrival order. */
|
|
601
|
+
function startedListingWorker() {
|
|
602
|
+
if (listingWorker)
|
|
603
|
+
return listingWorker;
|
|
604
|
+
// Source runs (vitest) load the TypeScript worker; the build runs the compiled one beside this module.
|
|
605
|
+
const ext = import.meta.url.endsWith('.ts') ? 'ts' : 'js';
|
|
606
|
+
const current = { worker: new Worker(new URL(`./state-db-worker.${ext}`, import.meta.url)), pending: new Map() };
|
|
607
|
+
current.worker.unref();
|
|
608
|
+
current.worker.on('message', (reply) => {
|
|
609
|
+
const call = current.pending.get(reply.id);
|
|
610
|
+
if (!call)
|
|
611
|
+
return;
|
|
612
|
+
current.pending.delete(reply.id);
|
|
613
|
+
if (!current.pending.size)
|
|
614
|
+
current.worker.unref();
|
|
615
|
+
call.resolve(reply);
|
|
616
|
+
});
|
|
617
|
+
current.worker.on('error', (error) => { retireListingWorker(current, error); });
|
|
618
|
+
current.worker.on('exit', (code) => { retireListingWorker(current, new Error(`state.db worker exited with code ${String(code)}`)); });
|
|
619
|
+
listingWorker = current;
|
|
620
|
+
return current;
|
|
621
|
+
}
|
|
622
|
+
function callListingWorker(call) {
|
|
623
|
+
// A multi-read caller the stop interrupted goes on to its next read; that read must not restart the worker.
|
|
624
|
+
if (stoppingWorker)
|
|
625
|
+
return Promise.reject(new Error('state.db worker stopped'));
|
|
626
|
+
const current = startedListingWorker();
|
|
627
|
+
const id = ++nextCallId;
|
|
628
|
+
return new Promise((resolve, reject) => {
|
|
629
|
+
current.pending.set(id, { resolve, reject });
|
|
630
|
+
// A call in flight keeps the process alive until it settles; an idle worker never does.
|
|
631
|
+
current.worker.ref();
|
|
632
|
+
current.worker.postMessage({ ...call, id, delayMs: readDelayMs });
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
/** `readImportableAgentSessionRows` on the listing worker, so a slow `state.db` never blocks the event loop. Rejects when the worker fails. */
|
|
636
|
+
export async function readImportableAgentSessionRowsAsync(dbPath, opts = {}) {
|
|
637
|
+
const { log, ...query } = opts;
|
|
638
|
+
const reply = await callListingWorker({ op: 'rows', dbPath, opts: query });
|
|
639
|
+
for (const line of reply.logs)
|
|
640
|
+
log?.(line);
|
|
641
|
+
if (reply.error !== undefined)
|
|
642
|
+
throw new Error(reply.error);
|
|
643
|
+
return reply.value;
|
|
644
|
+
}
|
|
645
|
+
/** `cheapChangeFingerprint` on the listing worker; a worker failure reports as a failed change check. */
|
|
646
|
+
export async function cheapChangeFingerprintAsync(dbPath, onError) {
|
|
647
|
+
let reply;
|
|
648
|
+
try {
|
|
649
|
+
reply = await callListingWorker({ op: 'fingerprint', dbPath });
|
|
650
|
+
}
|
|
651
|
+
catch (error) {
|
|
652
|
+
onError?.('change check failed', error);
|
|
653
|
+
return null;
|
|
654
|
+
}
|
|
655
|
+
for (const [reason, message] of reply.failures)
|
|
656
|
+
onError?.(reason, new Error(message));
|
|
657
|
+
return reply.value;
|
|
658
|
+
}
|
|
659
|
+
/** `stateDbSessionSources` on the listing worker; a worker failure is an unreadable state.db (null), so owners stay locked. */
|
|
660
|
+
export async function stateDbSessionSourcesAsync(dbPath, sessionIds) {
|
|
661
|
+
try {
|
|
662
|
+
return (await callListingWorker({ op: 'sources', dbPath, ids: [...sessionIds] })).value;
|
|
663
|
+
}
|
|
664
|
+
catch {
|
|
665
|
+
return null;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
/** `agentSessionRowsExisting` on the listing worker; a worker failure assumes every row present, so nothing is pruned. */
|
|
669
|
+
export async function agentSessionRowsExistingAsync(dbPath, sessionIds) {
|
|
670
|
+
const ids = [...sessionIds];
|
|
671
|
+
try {
|
|
672
|
+
return (await callListingWorker({ op: 'existing', dbPath, ids })).value;
|
|
673
|
+
}
|
|
674
|
+
catch {
|
|
675
|
+
return new Set(ids.map((s) => s.trim()).filter(Boolean));
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
/** Test hook: the listing worker exits abruptly while this call is in flight. */
|
|
679
|
+
export function crashStateDbWorkerForTests() {
|
|
680
|
+
return callListingWorker({ op: 'crash' });
|
|
681
|
+
}
|
|
682
|
+
/** Stop the listing worker (server shutdown). Calls in flight reject; a later call starts a new worker. */
|
|
683
|
+
export async function stopStateDbWorker() {
|
|
684
|
+
const current = listingWorker;
|
|
685
|
+
if (!current)
|
|
686
|
+
return;
|
|
687
|
+
stoppingWorker = true;
|
|
688
|
+
try {
|
|
689
|
+
retireListingWorker(current, new Error('state.db worker stopped'));
|
|
690
|
+
await current.worker.terminate();
|
|
691
|
+
}
|
|
692
|
+
finally {
|
|
693
|
+
stoppingWorker = false;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
582
696
|
// ── message reader ────────────────────────────────────────────────────────
|
|
583
697
|
const STATE_DB_CONTENT_JSON_PREFIX = '\0json:';
|
|
584
698
|
// `display_kind` / `display_metadata`: the Agent's own tag for rows it writes itself (steers, delivered notifications; TAL-371).
|
|
@@ -618,7 +732,8 @@ function projectStateDbMessage(row, hasId) {
|
|
|
618
732
|
continue;
|
|
619
733
|
msg[col] = JSON_MESSAGE_COLUMNS.has(col) ? jsonLoadsIfString(value) : value;
|
|
620
734
|
}
|
|
621
|
-
|
|
735
|
+
// TAL-493: the merge tells rows committed after the session's last read by this id.
|
|
736
|
+
if (hasId && row.id !== null && row.id !== undefined)
|
|
622
737
|
msg._state_db_row_id = row.id;
|
|
623
738
|
if (msg.role === 'tool' && msg.tool_name && !msg.name)
|
|
624
739
|
msg.name = msg.tool_name;
|
|
@@ -628,25 +743,44 @@ function projectStateDbMessage(row, hasId) {
|
|
|
628
743
|
* Python `get_state_db_session_messages(sid, stitch_continuations=True)`: the session's active rows in durable order,
|
|
629
744
|
* walking compatible compression/close parents so a continued CLI conversation reads as one transcript.
|
|
630
745
|
*/
|
|
746
|
+
/** The state.db file's identity (inode and creation time); a recreated or replaced database gets a new one. */
|
|
747
|
+
function stateDbGeneration(dbPath) {
|
|
748
|
+
try {
|
|
749
|
+
const st = statSync(dbPath);
|
|
750
|
+
return `${String(st.ino)}:${String(st.birthtimeMs)}`;
|
|
751
|
+
}
|
|
752
|
+
catch {
|
|
753
|
+
return null;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
631
756
|
export function stateDbSessionMessages(dbPath, sid, opts = {}) {
|
|
757
|
+
return stateDbSessionRead(dbPath, sid, opts).rows;
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* `stateDbSessionMessages`, whether the read succeeded (`ok`), and whether its `messages` table has an `id` column
|
|
761
|
+
* (TAL-493: an empty id-capable read is a baseline of 0; a missing database or a failed read says nothing).
|
|
762
|
+
*/
|
|
763
|
+
export function stateDbSessionRead(dbPath, sid, opts = {}) {
|
|
764
|
+
const none = { rows: [], idCapable: false, ok: false };
|
|
632
765
|
const id = sid.trim();
|
|
633
766
|
if (!id || !existsSync(dbPath))
|
|
634
|
-
return
|
|
767
|
+
return none;
|
|
635
768
|
let db;
|
|
636
769
|
try {
|
|
637
770
|
db = openStateDbReadonly(dbPath);
|
|
638
771
|
}
|
|
639
772
|
catch {
|
|
640
|
-
return
|
|
773
|
+
return none;
|
|
641
774
|
}
|
|
642
775
|
try {
|
|
643
776
|
const available = tableColumns(db, 'messages');
|
|
644
777
|
if (!['role', 'content', 'timestamp'].every((c) => available.has(c)))
|
|
645
|
-
return
|
|
778
|
+
return { ...none, ok: available.size > 0 };
|
|
646
779
|
const hasId = available.has('id');
|
|
647
780
|
const selected = [...(hasId ? ['id'] : []), 'role', 'content', 'timestamp', ...OPTIONAL_MESSAGE_COLUMNS.filter((c) => available.has(c))];
|
|
648
|
-
|
|
649
|
-
|
|
781
|
+
// TAL-529: an explicit lineage (the session and its compression continuations) replaces the parent walk.
|
|
782
|
+
const chain = opts.lineage?.length ? [...opts.lineage] : [id];
|
|
783
|
+
if (!opts.lineage?.length && (opts.stitch ?? true)) {
|
|
650
784
|
const sessionCols = tableColumns(db, 'sessions');
|
|
651
785
|
if (['parent_session_id', 'end_reason', 'started_at', 'source'].every((c) => sessionCols.has(c))) {
|
|
652
786
|
const select = db.prepare('SELECT id, source, started_at, parent_session_id, ended_at, end_reason FROM sessions WHERE id = ?');
|
|
@@ -668,10 +802,161 @@ export function stateDbSessionMessages(dbPath, sid, opts = {}) {
|
|
|
668
802
|
const activeClause = available.has('active') ? ' AND (active IS NULL OR active != 0)' : '';
|
|
669
803
|
const order = hasId ? 'id' : 'timestamp';
|
|
670
804
|
const rows = db.prepare(`SELECT ${selected.join(', ')}, session_id FROM messages WHERE session_id IN (${chain.map(() => '?').join(', ')})${activeClause} ORDER BY ${order} ASC`).all(...chain);
|
|
671
|
-
|
|
805
|
+
const projected = rows.map((row) => projectStateDbMessage(row, hasId));
|
|
806
|
+
// TAL-709: an in-place compaction archives the live rows and re-inserts each as a copy that keeps its role and timestamp
|
|
807
|
+
// (content may be pruned). A copy takes the id of the oldest archived row it copies, so the merge sees a row it has
|
|
808
|
+
// already read instead of a new one. Only a compaction archive (`compacted = 1`) vouches for a changed copy: a rewound
|
|
809
|
+
// row (`compacted = 0`, also the compaction's carried tail) counts only for the same tool call or the same content, so
|
|
810
|
+
// an edit that kept its timestamp stays new.
|
|
811
|
+
if (hasId && available.has('active')) {
|
|
812
|
+
// One indexed lookup per live row ((session_id, active, timestamp)): the archive is never loaded, however many
|
|
813
|
+
// compactions it holds.
|
|
814
|
+
const sameCall = available.has('tool_call_id') ? " AND COALESCE(a.tool_call_id, '') = COALESCE(m.tool_call_id, '')" : '';
|
|
815
|
+
const vouched = [available.has('compacted') ? 'a.compacted = 1' : '', available.has('tool_call_id') ? 'm.tool_call_id IS NOT NULL' : '', 'a.content = m.content'].filter(Boolean).join(' OR ');
|
|
816
|
+
const twins = db.prepare(`SELECT m.id AS id, MIN(a.id) AS twin FROM messages m JOIN messages a ON a.session_id = m.session_id AND a.active = 0 AND a.role = m.role AND a.timestamp = m.timestamp AND a.id < m.id${sameCall} WHERE m.session_id IN (${chain.map(() => '?').join(', ')}) AND (m.active IS NULL OR m.active != 0) AND (${vouched}) GROUP BY m.id`).all(...chain);
|
|
817
|
+
const twinOf = new Map(twins.map((row) => [row.id, row.twin]));
|
|
818
|
+
for (const [i, row] of rows.entries()) {
|
|
819
|
+
const twin = twinOf.get(row.id);
|
|
820
|
+
if (typeof twin === 'number')
|
|
821
|
+
projected[i]._state_db_row_id = twin;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
// TAL-493: the database file's identity, so a marker taken in a replaced state.db is never applied to its successor.
|
|
825
|
+
if (hasId) {
|
|
826
|
+
const generation = stateDbGeneration(dbPath);
|
|
827
|
+
for (const m of projected)
|
|
828
|
+
m._state_db_generation = generation;
|
|
829
|
+
}
|
|
830
|
+
return { rows: projected, idCapable: hasId, ok: true };
|
|
672
831
|
}
|
|
673
832
|
catch {
|
|
674
|
-
return
|
|
833
|
+
return none;
|
|
834
|
+
}
|
|
835
|
+
finally {
|
|
836
|
+
db.close();
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* TAL-529: `sid` and each compression continuation the Agent rotated it to, down to the live tip (Python
|
|
841
|
+
* `resolve_live_compression_tip`). The walk stops at the last unambiguous row: no continuation, several, a cycle, or 20
|
|
842
|
+
* hops. A missing or unreadable database is `[sid]`.
|
|
843
|
+
*/
|
|
844
|
+
export function stateDbCompressionLineage(dbPath, sid) {
|
|
845
|
+
const lineage = [sid.trim()];
|
|
846
|
+
if (!lineage[0] || !existsSync(dbPath))
|
|
847
|
+
return lineage;
|
|
848
|
+
let db;
|
|
849
|
+
try {
|
|
850
|
+
db = openStateDbReadonly(dbPath);
|
|
851
|
+
}
|
|
852
|
+
catch {
|
|
853
|
+
return lineage;
|
|
854
|
+
}
|
|
855
|
+
try {
|
|
856
|
+
const sessionCols = tableColumns(db, 'sessions');
|
|
857
|
+
if (!['id', 'parent_session_id', 'end_reason', 'ended_at', 'started_at', 'source'].every((c) => sessionCols.has(c)))
|
|
858
|
+
return lineage;
|
|
859
|
+
const sessionSource = sessionCols.has('session_source') ? 'session_source' : 'NULL AS session_source';
|
|
860
|
+
const cols = `id, source, ${sessionSource}, started_at, parent_session_id, ended_at, end_reason`;
|
|
861
|
+
let current = db.prepare(`SELECT ${cols} FROM sessions WHERE id = ?`).get(lineage[0]);
|
|
862
|
+
const children = db.prepare(`SELECT ${cols} FROM sessions WHERE parent_session_id = ?`);
|
|
863
|
+
for (let hop = 0; hop < 20 && current; hop += 1) {
|
|
864
|
+
const parent = current;
|
|
865
|
+
const next = children.all(str(parent.id)).filter((child) => isContinuationSession(parent, child));
|
|
866
|
+
if (next.length !== 1 || lineage.includes(str(next[0].id)))
|
|
867
|
+
break;
|
|
868
|
+
current = next[0];
|
|
869
|
+
lineage.push(str(current.id));
|
|
870
|
+
}
|
|
871
|
+
return lineage;
|
|
872
|
+
}
|
|
873
|
+
catch {
|
|
874
|
+
return lineage.slice(0, 1);
|
|
875
|
+
}
|
|
876
|
+
finally {
|
|
877
|
+
db.close();
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
function lineageReportRow(row, role) {
|
|
881
|
+
const ended = row.ended_at ?? null;
|
|
882
|
+
return {
|
|
883
|
+
session_id: row.id, role, title: row.title ?? null, source: row.source ?? null, started_at: row.started_at ?? null, updated_at: ended ?? row.started_at ?? null,
|
|
884
|
+
end_reason: row.end_reason ?? null, active: ended === null, archived: false,
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
const emptyLineageReport = (sid) => ({
|
|
888
|
+
mutation: false, found: false, session_id: sid, lineage_key: sid, tip_session_id: sid, total_segments: 0, materialized_segments: 0, segments: [], children: [], manual_review: false,
|
|
889
|
+
});
|
|
890
|
+
/**
|
|
891
|
+
* Python `read_session_lineage_report`: a read-only report of `sid`'s compression lineage. The walk follows up to
|
|
892
|
+
* `maxHops` continuation parents (the tip first, the root last), then lists each segment's non-continuation children,
|
|
893
|
+
* newest first. A cycle, a hop limit hit, or a continuation off the walked path marks `manual_review`. A missing,
|
|
894
|
+
* unreadable, or too-old database, or an unknown id, answers `found: false`.
|
|
895
|
+
*/
|
|
896
|
+
export function stateDbLineageReport(dbPath, rawSid, maxHops = 20) {
|
|
897
|
+
const sid = rawSid.trim();
|
|
898
|
+
if (!sid || !existsSync(dbPath))
|
|
899
|
+
return emptyLineageReport(sid);
|
|
900
|
+
let db;
|
|
901
|
+
try {
|
|
902
|
+
db = openStateDbReadonly(dbPath);
|
|
903
|
+
}
|
|
904
|
+
catch {
|
|
905
|
+
return emptyLineageReport(sid);
|
|
906
|
+
}
|
|
907
|
+
try {
|
|
908
|
+
const cols = tableColumns(db, 'sessions');
|
|
909
|
+
if (!['id', 'parent_session_id', 'end_reason'].every((c) => cols.has(c)))
|
|
910
|
+
return emptyLineageReport(sid);
|
|
911
|
+
const col = (name, fallback = 'NULL') => (cols.has(name) ? `s.${name}` : `${fallback} AS ${name}`);
|
|
912
|
+
const select = `SELECT s.id, ${col('source')}, ${col('session_source')}, ${col('title')}, ${col('started_at', '0')}, s.parent_session_id, ${col('ended_at')}, s.end_reason FROM sessions s`;
|
|
913
|
+
const byId = db.prepare(`${select} WHERE s.id = ?`);
|
|
914
|
+
const fetch = (id) => (id ? byId.get(str(id)) ?? null : null);
|
|
915
|
+
const target = fetch(sid);
|
|
916
|
+
if (!target)
|
|
917
|
+
return emptyLineageReport(sid);
|
|
918
|
+
const segments = [target];
|
|
919
|
+
const seen = new Set([sid]);
|
|
920
|
+
let manualReview = true;
|
|
921
|
+
for (let hop = 0; hop < maxHops; hop += 1) {
|
|
922
|
+
const current = segments[segments.length - 1];
|
|
923
|
+
const parentId = str(current.parent_session_id);
|
|
924
|
+
const parent = fetch(parentId);
|
|
925
|
+
if (!parent || seen.has(parentId)) {
|
|
926
|
+
manualReview = Boolean(parentId && seen.has(parentId));
|
|
927
|
+
break;
|
|
928
|
+
}
|
|
929
|
+
if (!isContinuationSession(parent, current)) {
|
|
930
|
+
manualReview = false;
|
|
931
|
+
break;
|
|
932
|
+
}
|
|
933
|
+
segments.push(parent);
|
|
934
|
+
seen.add(parentId);
|
|
935
|
+
}
|
|
936
|
+
const segmentIds = segments.map((row) => str(row.id));
|
|
937
|
+
const children = db.prepare(`${select} WHERE s.parent_session_id IN (${segmentIds.map(() => '?').join(', ')})`).all(...segmentIds);
|
|
938
|
+
const childRows = [];
|
|
939
|
+
for (const parent of segments) {
|
|
940
|
+
const own = children.filter((child) => str(child.parent_session_id) === str(parent.id) && !seen.has(str(child.id)));
|
|
941
|
+
own.sort((a, b) => (Number(b.started_at) || 0) - (Number(a.started_at) || 0));
|
|
942
|
+
for (const child of own) {
|
|
943
|
+
// A continuation off the walked path means a branched lineage or an older selected segment: flag it, list nothing.
|
|
944
|
+
if (isContinuationSession(parent, child))
|
|
945
|
+
manualReview = true;
|
|
946
|
+
else
|
|
947
|
+
childRows.push(child);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
return {
|
|
951
|
+
mutation: false, found: true, session_id: sid, lineage_key: segments[segments.length - 1].id, tip_session_id: segments[0].id,
|
|
952
|
+
total_segments: segments.length, materialized_segments: segments.length,
|
|
953
|
+
segments: segments.map((row, idx) => lineageReportRow(row, idx === 0 ? 'tip' : 'hidden_segment')),
|
|
954
|
+
children: childRows.map((row) => lineageReportRow(row, 'child_session')),
|
|
955
|
+
manual_review: manualReview,
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
catch {
|
|
959
|
+
return emptyLineageReport(sid);
|
|
675
960
|
}
|
|
676
961
|
finally {
|
|
677
962
|
db.close();
|
|
@@ -703,4 +988,128 @@ export function stateDbSessionRow(dbPath, sid) {
|
|
|
703
988
|
db.close();
|
|
704
989
|
}
|
|
705
990
|
}
|
|
991
|
+
/**
|
|
992
|
+
* TAL-550 (Python `_handle_insights`): usage of the non-Web sessions active since `cutoff`, shaped like session index
|
|
993
|
+
* entries. Activity is the latest of start, end, and last message, so a long-lived gateway session still counts.
|
|
994
|
+
* `webui` rows mirror index sessions and are skipped; a missing column reads as empty and a missing or unreadable
|
|
995
|
+
* state.db answers no rows.
|
|
996
|
+
*/
|
|
997
|
+
export function insightsSessionRows(dbPath, cutoff) {
|
|
998
|
+
if (!existsSync(dbPath))
|
|
999
|
+
return [];
|
|
1000
|
+
let db;
|
|
1001
|
+
try {
|
|
1002
|
+
db = openStateDbReadonly(dbPath);
|
|
1003
|
+
}
|
|
1004
|
+
catch {
|
|
1005
|
+
return [];
|
|
1006
|
+
}
|
|
1007
|
+
try {
|
|
1008
|
+
const cols = tableColumns(db, 'sessions');
|
|
1009
|
+
if (!cols.has('id') || !cols.has('started_at'))
|
|
1010
|
+
return [];
|
|
1011
|
+
const col = (name) => (cols.has(name) ? `s.${name}` : 'NULL');
|
|
1012
|
+
const messageCols = tableColumns(db, 'messages');
|
|
1013
|
+
const hasMessages = messageCols.has('session_id') && messageCols.has('timestamp');
|
|
1014
|
+
let indexed = false;
|
|
1015
|
+
try {
|
|
1016
|
+
indexed = hasMessages && db.prepare('PRAGMA index_list(messages)').all().some((r) => r.name === 'idx_messages_session');
|
|
1017
|
+
}
|
|
1018
|
+
catch {
|
|
1019
|
+
indexed = false;
|
|
1020
|
+
}
|
|
1021
|
+
// Without the index a per-session lookup scans messages once per session; one grouped scan replaces it.
|
|
1022
|
+
const lastMessage = !hasMessages ? 'NULL' : indexed ? '(SELECT MAX(m.timestamp) FROM messages m WHERE m.session_id = s.id)' : 'lm.last_message_at';
|
|
1023
|
+
const join = hasMessages && !indexed ? 'LEFT JOIN (SELECT session_id, MAX(timestamp) AS last_message_at FROM messages GROUP BY session_id) lm ON lm.session_id = s.id' : '';
|
|
1024
|
+
const source = cols.has('source') ? "LOWER(COALESCE(s.source, '')) != 'webui'" : '1';
|
|
1025
|
+
const rows = db.prepare(`SELECT * FROM (SELECT s.id AS id, ${col('model')} AS model, ${col('message_count')} AS message_count, ${col('input_tokens')} AS input_tokens,
|
|
1026
|
+
${col('output_tokens')} AS output_tokens, ${col('cache_read_tokens')} AS cache_read_tokens, ${col('estimated_cost_usd')} AS estimated_cost_usd, s.started_at AS started_at,
|
|
1027
|
+
MAX(COALESCE(s.started_at, 0), COALESCE(${col('ended_at')}, 0), COALESCE(${lastMessage}, 0)) AS last_activity
|
|
1028
|
+
FROM sessions s ${join} WHERE ${source}) WHERE last_activity >= ?`).all(cutoff);
|
|
1029
|
+
return rows.map((r) => ({
|
|
1030
|
+
session_id: str(r.id), model: r.model, message_count: r.message_count, input_tokens: r.input_tokens, output_tokens: r.output_tokens,
|
|
1031
|
+
cache_read_tokens: r.cache_read_tokens, estimated_cost: r.estimated_cost_usd, created_at: r.started_at, updated_at: r.last_activity,
|
|
1032
|
+
}));
|
|
1033
|
+
}
|
|
1034
|
+
catch {
|
|
1035
|
+
return [];
|
|
1036
|
+
}
|
|
1037
|
+
finally {
|
|
1038
|
+
db.close();
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
/** A state.db `timestamp` in unix seconds: a number, or an ISO-8601 string (Python `fromisoformat`); null when unreadable. */
|
|
1042
|
+
export function stateDbTimestampSeconds(value) {
|
|
1043
|
+
if (typeof value === 'number')
|
|
1044
|
+
return Number.isFinite(value) ? value : null;
|
|
1045
|
+
if (typeof value !== 'string' || !value.trim())
|
|
1046
|
+
return null;
|
|
1047
|
+
const ms = Date.parse(value.trim());
|
|
1048
|
+
return Number.isFinite(ms) ? ms / 1000 : null;
|
|
1049
|
+
}
|
|
1050
|
+
/** Python `CONVERSATION_ROUND_THRESHOLD`: the handoff dock is offered from this many rounds. */
|
|
1051
|
+
export const CONVERSATION_ROUND_THRESHOLD = 10;
|
|
1052
|
+
/**
|
|
1053
|
+
* Python `count_conversation_rounds` (TAL-258): a round is a user message answered by the assistant; consecutive user
|
|
1054
|
+
* messages merge into one. With `since`, only rows stamped after it count (an unreadable stamp still counts). A missing
|
|
1055
|
+
* or unreadable database is 0.
|
|
1056
|
+
*/
|
|
1057
|
+
export function countConversationRounds(dbPath, sid, since = null) {
|
|
1058
|
+
if (!existsSync(dbPath))
|
|
1059
|
+
return 0;
|
|
1060
|
+
let rows;
|
|
1061
|
+
try {
|
|
1062
|
+
const db = openStateDbReadonly(dbPath);
|
|
1063
|
+
try {
|
|
1064
|
+
rows = db.prepare('SELECT role, timestamp FROM messages WHERE session_id = ? ORDER BY timestamp ASC').all(sid);
|
|
1065
|
+
}
|
|
1066
|
+
finally {
|
|
1067
|
+
db.close();
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
catch {
|
|
1071
|
+
return 0;
|
|
1072
|
+
}
|
|
1073
|
+
let rounds = 0;
|
|
1074
|
+
let seenUser = false;
|
|
1075
|
+
let answered = false;
|
|
1076
|
+
for (const row of rows) {
|
|
1077
|
+
if (since !== null) {
|
|
1078
|
+
const ts = stateDbTimestampSeconds(row.timestamp);
|
|
1079
|
+
if (ts !== null && ts <= since)
|
|
1080
|
+
continue;
|
|
1081
|
+
}
|
|
1082
|
+
const role = lower(row.role);
|
|
1083
|
+
if (role === 'user') {
|
|
1084
|
+
if (seenUser && answered) {
|
|
1085
|
+
rounds += 1;
|
|
1086
|
+
answered = false;
|
|
1087
|
+
}
|
|
1088
|
+
seenUser = true;
|
|
1089
|
+
}
|
|
1090
|
+
else if (role === 'assistant' && seenUser) {
|
|
1091
|
+
answered = true;
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
return seenUser && answered ? rounds + 1 : rounds;
|
|
1095
|
+
}
|
|
1096
|
+
/** The content of the session's newest row when that row is a `tool` row (the handoff marker's tail dedupe, TAL-258); else null. */
|
|
1097
|
+
export function stateDbTailToolContent(dbPath, sid) {
|
|
1098
|
+
if (!existsSync(dbPath))
|
|
1099
|
+
return null;
|
|
1100
|
+
try {
|
|
1101
|
+
const db = openStateDbReadonly(dbPath);
|
|
1102
|
+
try {
|
|
1103
|
+
const row = db.prepare('SELECT role, content FROM messages WHERE session_id = ? ORDER BY rowid DESC LIMIT 1').get(sid);
|
|
1104
|
+
const content = row?.role === 'tool' ? decodeStateDbContent(row.content) : null;
|
|
1105
|
+
return typeof content === 'string' ? content : null;
|
|
1106
|
+
}
|
|
1107
|
+
finally {
|
|
1108
|
+
db.close();
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
catch {
|
|
1112
|
+
return null;
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
706
1115
|
//# sourceMappingURL=state-db.js.map
|