@maudecode/talaria-web 1.19.0 → 1.21.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/automation-raw.js +61 -6
- package/dist/api/automation-raw.js.map +1 -1
- package/dist/api/automation-router.d.ts +309 -2
- package/dist/api/automation-router.js +28 -2
- package/dist/api/automation-router.js.map +1 -1
- package/dist/api/chat-router.d.ts +646 -24
- package/dist/api/chat-router.js +54 -167
- package/dist/api/chat-router.js.map +1 -1
- package/dist/api/git-router.d.ts +54 -0
- package/dist/api/git-router.js +18 -5
- package/dist/api/git-router.js.map +1 -1
- package/dist/api/raw-routes.js +13 -1
- package/dist/api/raw-routes.js.map +1 -1
- package/dist/api/router.d.ts +3 -3
- package/dist/api/session-visibility.js +2 -2
- package/dist/api/session-visibility.js.map +1 -1
- package/dist/api/sessions-router.d.ts +1868 -79
- package/dist/api/sessions-router.js +72 -43
- package/dist/api/sessions-router.js.map +1 -1
- package/dist/api/settings-router.d.ts +34 -13
- package/dist/api/settings-router.js +54 -17
- package/dist/api/settings-router.js.map +1 -1
- package/dist/api/sse-routes.js +45 -21
- package/dist/api/sse-routes.js.map +1 -1
- package/dist/api/tools-router.d.ts +773 -39
- package/dist/api/tools-router.js +167 -45
- package/dist/api/tools-router.js.map +1 -1
- package/dist/app.js +15 -11
- package/dist/app.js.map +1 -1
- package/dist/auth/crypto.d.ts +3 -0
- package/dist/auth/crypto.js +18 -0
- package/dist/auth/crypto.js.map +1 -1
- package/dist/auth/gate.js +5 -1
- package/dist/auth/gate.js.map +1 -1
- package/dist/cli/ctl.js +6 -1
- package/dist/cli/ctl.js.map +1 -1
- package/dist/cli/main.js +23 -18
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/supervise.d.ts +22 -0
- package/dist/cli/supervise.js +80 -2
- package/dist/cli/supervise.js.map +1 -1
- package/dist/config/agent-config.d.ts +3 -0
- package/dist/config/agent-config.js +36 -9
- package/dist/config/agent-config.js.map +1 -1
- package/dist/fs/atomic.d.ts +3 -0
- package/dist/fs/atomic.js +19 -5
- package/dist/fs/atomic.js.map +1 -1
- package/dist/fs/stat.d.ts +6 -0
- package/dist/fs/stat.js +18 -2
- package/dist/fs/stat.js.map +1 -1
- package/dist/http/context.d.ts +16 -0
- package/dist/http/context.js +48 -5
- package/dist/http/context.js.map +1 -1
- package/dist/profiles/profiles.d.ts +2 -0
- package/dist/profiles/profiles.js +1 -0
- package/dist/profiles/profiles.js.map +1 -1
- package/dist/providers/catalog.d.ts +11 -6
- package/dist/providers/catalog.js +76 -24
- package/dist/providers/catalog.js.map +1 -1
- package/dist/redact.d.ts +2 -0
- package/dist/redact.js +55 -16
- package/dist/redact.js.map +1 -1
- package/dist/release.js +5 -3
- package/dist/release.js.map +1 -1
- package/dist/runtime.js +118 -26
- package/dist/runtime.js.map +1 -1
- package/dist/server.js +25 -21
- package/dist/server.js.map +1 -1
- package/dist/sessions/admission.d.ts +21 -0
- package/dist/sessions/admission.js +176 -0
- package/dist/sessions/admission.js.map +1 -0
- package/dist/sessions/anchor.d.ts +4 -1
- package/dist/sessions/anchor.js +9 -5
- package/dist/sessions/anchor.js.map +1 -1
- package/dist/sessions/background-tasks.d.ts +41 -3
- package/dist/sessions/background-tasks.js +110 -10
- package/dist/sessions/background-tasks.js.map +1 -1
- package/dist/sessions/cli-sessions.d.ts +9 -2
- package/dist/sessions/cli-sessions.js +38 -57
- package/dist/sessions/cli-sessions.js.map +1 -1
- package/dist/sessions/completions.d.ts +8 -0
- package/dist/sessions/completions.js +55 -25
- package/dist/sessions/completions.js.map +1 -1
- package/dist/sessions/events.d.ts +3 -0
- package/dist/sessions/events.js +4 -0
- package/dist/sessions/events.js.map +1 -1
- package/dist/sessions/export.d.ts +2 -0
- package/dist/sessions/export.js +6 -2
- package/dist/sessions/export.js.map +1 -1
- package/dist/sessions/gateway-sessions.d.ts +92 -4
- package/dist/sessions/gateway-sessions.js +762 -93
- package/dist/sessions/gateway-sessions.js.map +1 -1
- package/dist/sessions/gateway-watcher.d.ts +10 -11
- package/dist/sessions/gateway-watcher.js +25 -21
- package/dist/sessions/gateway-watcher.js.map +1 -1
- package/dist/sessions/list.d.ts +9 -2
- package/dist/sessions/list.js +38 -26
- package/dist/sessions/list.js.map +1 -1
- package/dist/sessions/merge.d.ts +12 -5
- package/dist/sessions/merge.js +65 -18
- package/dist/sessions/merge.js.map +1 -1
- package/dist/sessions/prefix-index.d.ts +15 -4
- package/dist/sessions/prefix-index.js +35 -13
- package/dist/sessions/prefix-index.js.map +1 -1
- package/dist/sessions/prompt-queues.d.ts +36 -0
- package/dist/sessions/prompt-queues.js +318 -0
- package/dist/sessions/prompt-queues.js.map +1 -0
- package/dist/sessions/recovery.d.ts +1 -1
- package/dist/sessions/recovery.js +4 -3
- package/dist/sessions/recovery.js.map +1 -1
- package/dist/sessions/relay.d.ts +12 -1
- package/dist/sessions/relay.js +75 -17
- package/dist/sessions/relay.js.map +1 -1
- package/dist/sessions/service.d.ts +132 -37
- package/dist/sessions/service.js +688 -160
- package/dist/sessions/service.js.map +1 -1
- package/dist/sessions/session.d.ts +2 -0
- package/dist/sessions/session.js +5 -0
- package/dist/sessions/session.js.map +1 -1
- package/dist/sessions/state-db-worker.js +22 -5
- package/dist/sessions/state-db-worker.js.map +1 -1
- package/dist/sessions/state-db.d.ts +106 -15
- package/dist/sessions/state-db.js +651 -236
- package/dist/sessions/state-db.js.map +1 -1
- package/dist/sessions/state-saved.d.ts +1 -1
- package/dist/sessions/state-saved.js +35 -11
- package/dist/sessions/state-saved.js.map +1 -1
- package/dist/sessions/storage/backend.d.ts +10 -1
- package/dist/sessions/storage/backend.js.map +1 -1
- package/dist/sessions/storage/conformance.js +1 -1
- package/dist/sessions/storage/conformance.js.map +1 -1
- package/dist/sessions/storage/json-documents.d.ts +2 -0
- package/dist/sessions/storage/json-documents.js +71 -26
- package/dist/sessions/storage/json-documents.js.map +1 -1
- package/dist/sessions/storage/json-files.d.ts +13 -2
- package/dist/sessions/storage/json-files.js +126 -6
- package/dist/sessions/storage/json-files.js.map +1 -1
- package/dist/sessions/storage/json-journal.d.ts +6 -7
- package/dist/sessions/storage/json-journal.js +143 -73
- package/dist/sessions/storage/json-journal.js.map +1 -1
- package/dist/sessions/storage/json.d.ts +15 -1
- package/dist/sessions/storage/json.js +125 -33
- package/dist/sessions/storage/json.js.map +1 -1
- package/dist/sessions/store.d.ts +6 -1
- package/dist/sessions/store.js +68 -27
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/streams.d.ts +10 -7
- package/dist/sessions/streams.js +49 -14
- package/dist/sessions/streams.js.map +1 -1
- package/dist/sessions/tool-display.d.ts +11 -2
- package/dist/sessions/tool-display.js +45 -4
- package/dist/sessions/tool-display.js.map +1 -1
- package/dist/sessions/turn-context.js +6 -2
- package/dist/sessions/turn-context.js.map +1 -1
- package/dist/sessions/turn.d.ts +27 -6
- package/dist/sessions/turn.js +186 -89
- package/dist/sessions/turn.js.map +1 -1
- package/dist/sidecar/client.d.ts +24 -1
- package/dist/sidecar/client.js +118 -38
- package/dist/sidecar/client.js.map +1 -1
- package/dist/sidecar/fake.d.ts +6 -2
- package/dist/sidecar/fake.js +15 -2
- package/dist/sidecar/fake.js.map +1 -1
- package/dist/spa.d.ts +9 -4
- package/dist/spa.js +36 -12
- package/dist/spa.js.map +1 -1
- package/dist/startup-timing.d.ts +66 -0
- package/dist/startup-timing.js +129 -0
- package/dist/startup-timing.js.map +1 -0
- package/dist/test/fs-handles.d.ts +11 -0
- package/dist/test/fs-handles.js +31 -0
- package/dist/test/fs-handles.js.map +1 -0
- package/dist/tools/connectors.d.ts +1 -1
- package/dist/tools/connectors.js +2 -2
- package/dist/tools/connectors.js.map +1 -1
- package/dist/tools/crons.d.ts +8 -4
- package/dist/tools/crons.js +25 -18
- package/dist/tools/crons.js.map +1 -1
- package/dist/tools/dashboard-plugins.d.ts +29 -0
- package/dist/tools/dashboard-plugins.js +132 -0
- package/dist/tools/dashboard-plugins.js.map +1 -1
- package/dist/tools/gateway-restart.d.ts +25 -5
- package/dist/tools/gateway-restart.js +103 -23
- package/dist/tools/gateway-restart.js.map +1 -1
- package/dist/tools/health.d.ts +13 -1
- package/dist/tools/health.js +80 -22
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/insights.d.ts +1 -1
- package/dist/tools/insights.js +2 -2
- package/dist/tools/insights.js.map +1 -1
- package/dist/tools/kanban.d.ts +10 -1
- package/dist/tools/kanban.js +73 -1
- package/dist/tools/kanban.js.map +1 -1
- package/dist/tools/mcp-health.js +74 -24
- package/dist/tools/mcp-health.js.map +1 -1
- package/dist/tools/mcp.d.ts +3 -1
- package/dist/tools/mcp.js +92 -1
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/memory.d.ts +28 -0
- package/dist/tools/memory.js +120 -14
- package/dist/tools/memory.js.map +1 -1
- package/dist/tools/plugin-oauth.d.ts +14 -0
- package/dist/tools/plugin-oauth.js +53 -0
- package/dist/tools/plugin-oauth.js.map +1 -0
- package/dist/tools/prune-advice.d.ts +50 -0
- package/dist/tools/prune-advice.js +114 -0
- package/dist/tools/prune-advice.js.map +1 -0
- package/dist/tools/skills.d.ts +5 -2
- package/dist/tools/skills.js +9 -6
- package/dist/tools/skills.js.map +1 -1
- package/dist/tools/update-notifications.d.ts +77 -9
- package/dist/tools/update-notifications.js +390 -46
- package/dist/tools/update-notifications.js.map +1 -1
- package/dist/tools/updates.d.ts +29 -3
- package/dist/tools/updates.js +166 -34
- package/dist/tools/updates.js.map +1 -1
- package/dist/workspace/managed-buffers.d.ts +58 -0
- package/dist/workspace/managed-buffers.js +76 -0
- package/dist/workspace/managed-buffers.js.map +1 -0
- package/dist/workspace/media.js +69 -20
- package/dist/workspace/media.js.map +1 -1
- package/dist/workspace/preview.js +4 -14
- package/dist/workspace/preview.js.map +1 -1
- package/dist/workspace/rollback.d.ts +6 -2
- package/dist/workspace/rollback.js +18 -8
- package/dist/workspace/rollback.js.map +1 -1
- package/package.json +3 -3
- package/sidecar/agent_dependency.json +4 -4
- package/sidecar/agent_support.json +30 -15
- package/sidecar/scripts/suite_runner.py +183 -27
- package/sidecar/scripts/test.sh +5 -7
- package/sidecar/talaria_sidecar/__init__.py +1 -1
- package/sidecar/talaria_sidecar/__main__.py +10 -3
- package/sidecar/talaria_sidecar/agent_mutation.py +246 -32
- package/sidecar/talaria_sidecar/agent_services.py +157 -34
- package/sidecar/talaria_sidecar/context_detail.py +59 -0
- package/sidecar/talaria_sidecar/home.py +97 -20
- package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
- package/sidecar/talaria_sidecar/methods/aux.py +80 -18
- package/sidecar/talaria_sidecar/methods/chat.py +571 -106
- package/sidecar/talaria_sidecar/methods/checkpoints.py +29 -4
- package/sidecar/talaria_sidecar/methods/commands.py +277 -16
- package/sidecar/talaria_sidecar/methods/config.py +73 -3
- package/sidecar/talaria_sidecar/methods/connectors.py +45 -13
- package/sidecar/talaria_sidecar/methods/cron.py +8 -2
- package/sidecar/talaria_sidecar/methods/dashboard_plugins.py +301 -0
- package/sidecar/talaria_sidecar/methods/gateway.py +24 -4
- package/sidecar/talaria_sidecar/methods/gateway_sessions.py +304 -30
- package/sidecar/talaria_sidecar/methods/kanban.py +50 -3
- package/sidecar/talaria_sidecar/methods/managed_buffers.py +110 -0
- package/sidecar/talaria_sidecar/methods/mcp.py +55 -0
- package/sidecar/talaria_sidecar/methods/oauth.py +139 -11
- package/sidecar/talaria_sidecar/methods/outbound_drafts.py +165 -0
- package/sidecar/talaria_sidecar/methods/plugin_catalog.py +198 -0
- package/sidecar/talaria_sidecar/methods/plugin_oauth.py +234 -0
- package/sidecar/talaria_sidecar/methods/process.py +70 -6
- package/sidecar/talaria_sidecar/methods/profiles.py +4 -3
- package/sidecar/talaria_sidecar/methods/runtime.py +2 -0
- package/sidecar/talaria_sidecar/methods/skills.py +22 -7
- package/sidecar/talaria_sidecar/methods/state_db.py +128 -42
- package/sidecar/talaria_sidecar/methods/toolsets.py +4 -2
- package/sidecar/talaria_sidecar/methods/worktree.py +121 -2
- package/sidecar/talaria_sidecar/rpc.py +25 -3
- package/sidecar/talaria_sidecar/runtime.py +42 -3
- package/sidecar/talaria_sidecar/speed.py +13 -1
- package/sidecar/talaria_sidecar/startup_timing.py +119 -0
- package/static/dist/FILES.txt +240 -213
- package/static/dist/THIRD_PARTY_LICENSES.md +6 -22
- package/static/dist/assets/AppShell-c5989995.js +8 -0
- package/static/dist/assets/Button-nuaikybd.js +1 -0
- package/static/dist/assets/ChatPage-bfg4khph.js +6 -0
- package/static/dist/assets/ConnectTargets-k5wo9yo8.js +1 -0
- package/static/dist/assets/Dialog-o8vo2aws.js +1 -0
- package/static/dist/assets/ExtensionRoute-l1yjrso4.js +1 -0
- package/static/dist/assets/Field-j7o8cfps.js +1 -0
- package/static/dist/assets/HubRoute-efnwe4xz.js +2 -0
- package/static/dist/assets/LinkCheckContext-ix6zqqkk.js +1 -0
- package/static/dist/assets/Markdown-clqf5m22.js +2 -0
- package/static/dist/assets/MarkdownRenderer-ccgqrza3.js +302 -0
- package/static/dist/assets/MarkdownRenderer-i9o6nr38.css +1 -0
- package/static/dist/assets/OAuthSignIn-h7bjaqp6.js +1 -0
- package/static/dist/assets/ResourceSwitch-oai2zqaj.js +1 -0
- package/static/dist/assets/RightPanel-ho161a45.js +1 -0
- package/static/dist/assets/Select-d1g5a8bm.js +1 -0
- package/static/dist/assets/SessionListPanel-i7kaokhi.js +1 -0
- package/static/dist/assets/SettingsLayout-lnecm87w.js +1 -0
- package/static/dist/assets/States-easntmry.js +1 -0
- package/static/dist/assets/TerminalPanel-lxhwd4jl.js +16 -0
- package/static/dist/assets/Toaster-l4sciy8t.js +1 -0
- package/static/dist/assets/_app-mqexqbg8.js +1 -0
- package/static/dist/assets/_app.ext._extensionId-n797jp72.js +1 -0
- package/static/dist/assets/_app.index-ne43mdw2.js +1 -0
- package/static/dist/assets/_app.insights-fqonovb4.js +1 -0
- package/static/dist/assets/_app.kanban-kysliv19.js +1 -0
- package/static/dist/assets/_app.logs-febut82r.js +1 -0
- package/static/dist/assets/_app.memory-ha86oj1c.js +1 -0
- package/static/dist/assets/_app.profiles-cnu3gxxq.js +1 -0
- package/static/dist/assets/_app.session._sessionId-ifzjpcgn.js +1 -0
- package/static/dist/assets/_app.settings-nmakdiaf.js +1 -0
- package/static/dist/assets/_app.settings._section-djglnjmi.js +3 -0
- package/static/dist/assets/_app.skills-f3wad8yo.js +1 -0
- package/static/dist/assets/_app.tasks-l10py1c0.js +1 -0
- package/static/dist/assets/_app.todos-bml1m3r1.js +1 -0
- package/static/dist/assets/_app.workspaces-f3d066lx.js +1 -0
- package/static/dist/assets/abnfDiagram-VCTEODGH-i53jc4yp.js +1 -0
- package/static/dist/assets/{angular-html-nu6l31w3.js → angular-html-l28bd5fo.js} +1 -1
- package/static/dist/assets/{angular-ts-fbx4f8mm.js → angular-ts-ffzx1vj0.js} +1 -1
- package/static/dist/assets/{apl-bx2xr7dh.js → apl-b7h7mmy4.js} +1 -1
- package/static/dist/assets/{arc-7popfhbk.js → arc-fk1b21lm.js} +1 -1
- package/static/dist/assets/architecture-7GRP2DOG-e3bv5m6f.js +1 -0
- package/static/dist/assets/architectureDiagram-5GKGNRK7-pakekxu2.js +36 -0
- package/static/dist/assets/archive-ihqi7z2x.js +1 -0
- package/static/dist/assets/{astro-g77i97cb.js → astro-k117fy0t.js} +1 -1
- package/static/dist/assets/back-gu3nu279.js +1 -0
- package/static/dist/assets/{blade-boo0u92y.js → blade-npefsmn8.js} +1 -1
- package/static/dist/assets/{blockDiagram-I7D4REHJ-joedghi3.js → blockDiagram-I7D4REHJ-bc6bo1n6.js} +4 -4
- package/static/dist/assets/{c-cat0w3sc.js → c-2umg6kbn.js} +1 -1
- package/static/dist/assets/{c4Diagram-7LVT6UL2-hyrjrohe.js → c4Diagram-7LVT6UL2-btvwk2qx.js} +1 -1
- package/static/dist/assets/channel-jn4f8443.js +1 -0
- package/static/dist/assets/{chunk-4HAMMTFA-koouqbut.js → chunk-4HAMMTFA-dlwab11c.js} +20 -20
- package/static/dist/assets/{chunk-75Z2AOVW-bl4bhdnt.js → chunk-75Z2AOVW-dp5gh7i8.js} +1 -1
- package/static/dist/assets/chunk-DU6HZSFF-bi06zl1c.js +128 -0
- package/static/dist/assets/{chunk-F27PBJKO-d8xxi0zi.js → chunk-F27PBJKO-kvv1rnlh.js} +1 -1
- package/static/dist/assets/{chunk-FOHPRMQF-opuflp73.js → chunk-FOHPRMQF-ipewusgj.js} +8 -8
- package/static/dist/assets/{chunk-GMAD6QVW-jro0hl73.js → chunk-GMAD6QVW-ji0rx9by.js} +6 -6
- package/static/dist/assets/{chunk-GVQU2GXP-djn6gbyu.js → chunk-GVQU2GXP-nmz0j82p.js} +1 -1
- package/static/dist/assets/{chunk-IMKFNOWR-vw4p5p7o.js → chunk-IMKFNOWR-kmi1qx88.js} +5 -5
- package/static/dist/assets/{chunk-L3NEJ4N5-n1hj77q8.js → chunk-L3NEJ4N5-xhb7mebj.js} +1 -1
- package/static/dist/assets/chunk-OSK3NFVY-5a9sgscq.js +10 -0
- package/static/dist/assets/{chunk-P2QGCYS3-onf1hz6c.js → chunk-P2QGCYS3-dfezp4vu.js} +1 -1
- package/static/dist/assets/{chunk-POPQ4Y6H-m8sqn7cs.js → chunk-POPQ4Y6H-gd2vq3c0.js} +1 -1
- package/static/dist/assets/{chunk-PWAF6VOD-ek4smc8x.js → chunk-PWAF6VOD-wvw2nksf.js} +1 -1
- package/static/dist/assets/{chunk-SHT3W25Y-g9gfvefo.js → chunk-SHT3W25Y-f58q97px.js} +13 -13
- package/static/dist/assets/{chunk-SVP7TREG-f9nfv2cu.js → chunk-SVP7TREG-abgwpyz9.js} +4 -4
- package/static/dist/assets/{chunk-TICWLB2K-bnk3m1mq.js → chunk-TICWLB2K-h4sbs8ds.js} +6 -6
- package/static/dist/assets/{chunk-XXDRQBXY-n40pf9vy.js → chunk-XXDRQBXY-jkmnqu65.js} +1 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-dzrw66se.js +1 -0
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-dzrw66se.js +1 -0
- package/static/dist/assets/{cobol-go622aep.js → cobol-ssf9hkh7.js} +1 -1
- package/static/dist/assets/{coffee-jwo1xjhq.js → coffee-lsi9fwae.js} +1 -1
- package/static/dist/assets/completionAudio-ce86msbu.js +1 -0
- package/static/dist/assets/copied-bz3gkazh.js +1 -0
- package/static/dist/assets/copy-m9h56qa8.js +1 -0
- package/static/dist/assets/cose-bilkent-JH36ORCC-layy2r27.js +1 -0
- package/static/dist/assets/{cpp-nre7j0kq.js → cpp-lfrh4y55.js} +1 -1
- package/static/dist/assets/{crystal-lviso2je.js → crystal-efh4pte7.js} +1 -1
- package/static/dist/assets/{css-ywz9j4hb.js → css-i82qdo89.js} +1 -1
- package/static/dist/assets/cynefin-OW5HDTMX-g081vffs.js +1 -0
- package/static/dist/assets/cynefinDiagram-5FMLGOSQ-odxvjesk.js +62 -0
- package/static/dist/assets/cytoscape.esm-fjn2algp.js +321 -0
- package/static/dist/assets/dagre-GXQ25YYZ-cpdwzjs4.js +4 -0
- package/static/dist/assets/dagre-o5jmjz46.js +1 -0
- package/static/dist/assets/{diagram-S7CK7UJ4-m6aeoe7c.js → diagram-S7CK7UJ4-clv5mxvu.js} +4 -4
- package/static/dist/assets/diagram-UQ7AKVKN-m2ia1mbf.js +41 -0
- package/static/dist/assets/{diagram-VSXAHHWV-hbawi7hn.js → diagram-VSXAHHWV-ea6zv636.js} +1 -1
- package/static/dist/assets/diagram-VX7I27RA-oqlef685.js +24 -0
- package/static/dist/assets/diagram-Z3DM3KII-kjubcbwu.js +24 -0
- package/static/dist/assets/dist-carq1azj.js +44 -0
- package/static/dist/assets/dist-crc46di9.js +7 -0
- package/static/dist/assets/{dist-c4c2m3kv.js → dist-nb670eu6.js} +1 -1
- package/static/dist/assets/ebnfDiagram-PWID7BFC-fg0zri3e.js +1 -0
- package/static/dist/assets/{edge-dvv35byi.js → edge-lrob635n.js} +1 -1
- package/static/dist/assets/{elixir-i2f1ki1g.js → elixir-kdpxeq93.js} +1 -1
- package/static/dist/assets/{elm-cpepyjm4.js → elm-c8irj9uh.js} +1 -1
- package/static/dist/assets/erDiagram-RLTQ6QDP-eb7pmk3x.js +99 -0
- package/static/dist/assets/{erb-idlyfheg.js → erb-flwsv146.js} +1 -1
- package/static/dist/assets/eventmodeling-NTZA5JFV-gvi1fxhn.js +1 -0
- package/static/dist/assets/flowDiagram-HODETNUW-abekab15.js +1 -0
- package/static/dist/assets/folder-plus-ksaons88.js +1 -0
- package/static/dist/assets/{ganttDiagram-EL5Y4UJY-ma6jxj5i.js → ganttDiagram-EL5Y4UJY-jmisowrc.js} +1 -1
- package/static/dist/assets/{git-rebase-d9lpfpbn.js → git-rebase-bli19aoq.js} +1 -1
- package/static/dist/assets/gitGraph-4MIJSDKK-m7kt3u6e.js +1 -0
- package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-hzltvsod.js → gitGraphDiagram-WWUBYQGX-nq7vfzh2.js} +1 -1
- package/static/dist/assets/{glimmer-js-39i0urfb.js → glimmer-js-d4icg38p.js} +1 -1
- package/static/dist/assets/{glimmer-ts-gdtd6n73.js → glimmer-ts-bk75772u.js} +1 -1
- package/static/dist/assets/{glsl-o1djm5pp.js → glsl-lqormp2b.js} +1 -1
- package/static/dist/assets/{graphql-kj6rz55t.js → graphql-hw6s5qzd.js} +1 -1
- package/static/dist/assets/{hack-pe1qqr2i.js → hack-ozrv6l4d.js} +1 -1
- package/static/dist/assets/{haml-cknnbcqs.js → haml-gytfosdt.js} +1 -1
- package/static/dist/assets/{handlebars-hwq64orh.js → handlebars-b6g7jffd.js} +1 -1
- package/static/dist/assets/highlighted-body-KPVGNVTW-gcu017ay.js +1 -0
- package/static/dist/assets/host-ipp4e84c.js +1 -0
- package/static/dist/assets/{html-derivative-h2i2pyjc.js → html-derivative-f1tqcroo.js} +1 -1
- package/static/dist/assets/{html-ha05xtvt.js → html-on6oj6yj.js} +1 -1
- package/static/dist/assets/{http-cf94zu27.js → http-odhufsl7.js} +1 -1
- package/static/dist/assets/{hurl-lslax568.js → hurl-mu680336.js} +1 -1
- package/static/dist/assets/index-d6vbxlra.js +13 -0
- package/static/dist/assets/index-ey6qo0zx.css +2 -0
- package/static/dist/assets/info-A6RAGUB7-idazwfqe.js +1 -0
- package/static/dist/assets/infoDiagram-27XIBGKW-bb9jh8gl.js +2 -0
- package/static/dist/assets/{ishikawaDiagram-5VMMS53U-e7bnwq7h.js → ishikawaDiagram-5VMMS53U-nqc132rv.js} +6 -6
- package/static/dist/assets/{java-ndjf2o89.js → java-nxbe8uju.js} +1 -1
- package/static/dist/assets/{javascript-coftlwy3.js → javascript-lz3kxcyz.js} +1 -1
- package/static/dist/assets/{jinja-etei9wy7.js → jinja-l5pk84gt.js} +1 -1
- package/static/dist/assets/{jison-hyekgft1.js → jison-jdutdwyy.js} +1 -1
- package/static/dist/assets/{journeyDiagram-3NMN7TZE-etd1bi6p.js → journeyDiagram-3NMN7TZE-fpvnhy44.js} +1 -1
- package/static/dist/assets/{json-lok0yaho.js → json-dnge4ssf.js} +1 -1
- package/static/dist/assets/{jsx-b64w0nbx.js → jsx-c3lwhkep.js} +1 -1
- package/static/dist/assets/{jsx-runtime-eu92a5pu.js → jsx-runtime-o40ukmjl.js} +1 -1
- package/static/dist/assets/{julia-jxxzz2yn.js → julia-hwd4rrcb.js} +1 -1
- package/static/dist/assets/{just-mc29iw9t.js → just-nka3oxdx.js} +1 -1
- package/static/dist/assets/{kanban-definition-UXKFOSKX-emb1g9dz.js → kanban-definition-UXKFOSKX-ndzqm6fu.js} +28 -28
- package/static/dist/assets/katex-cbdd1ohw.css +1 -0
- package/static/dist/assets/katex-pbij2oo6.js +257 -0
- package/static/dist/assets/{latex-pafa03ft.js → latex-iqmr7e40.js} +1 -1
- package/static/dist/assets/lazyRouteComponent-javud235.js +1 -0
- package/static/dist/assets/{line-h0ojzsvs.js → line-g625e7cj.js} +1 -1
- package/static/dist/assets/linear-jlwrvvy6.js +1 -0
- package/static/dist/assets/link-gfdaho08.js +2 -0
- package/static/dist/assets/{liquid-hz5c2pov.js → liquid-okmk9tbp.js} +1 -1
- package/static/dist/assets/locale-cs-n41hptse.js +5 -0
- package/static/dist/assets/locale-de-k7ht47ew.js +5 -0
- package/static/dist/assets/locale-es-ih078lco.js +5 -0
- package/static/dist/assets/locale-fr-ojabnf41.js +5 -0
- package/static/dist/assets/locale-it-kb96jufy.js +5 -0
- package/static/dist/assets/locale-ja-jpsp3xs1.js +7 -0
- package/static/dist/assets/locale-ko-cpzuy0n7.js +5 -0
- package/static/dist/assets/locale-pl-dbap4leu.js +5 -0
- package/static/dist/assets/locale-pt-nci7w72x.js +5 -0
- package/static/dist/assets/locale-ru-soghe4cs.js +7 -0
- package/static/dist/assets/locale-tr-ks00mu68.js +5 -0
- package/static/dist/assets/locale-vi-ij7twfm6.js +5 -0
- package/static/dist/assets/locale-zh-Hant-feakwr7a.js +5 -0
- package/static/dist/assets/locale-zh-ren0vjyv.js +7 -0
- package/static/dist/assets/login-iv6yq4xf.js +1 -0
- package/static/dist/assets/{lua-leyf8mlb.js → lua-krx4xj5h.js} +1 -1
- package/static/dist/assets/{marko-cn1fzpdv.js → marko-gbvpfehz.js} +1 -1
- package/static/dist/assets/{mdc-huhy88df.js → mdc-c21zlyi5.js} +1 -1
- package/static/dist/assets/mermaid-HWGCJPDP-cwj5cl6k.js +1 -0
- package/static/dist/assets/mermaid-parser.core-plzkuzov.js +7 -0
- package/static/dist/assets/micromark-factory-space-fnmnpi6s.js +1 -0
- package/static/dist/assets/{mindmap-definition-YA3MSWOX-o1vathns.js → mindmap-definition-YA3MSWOX-ojrgs569.js} +28 -28
- package/static/dist/assets/{nginx-e7lvhsmn.js → nginx-f3d68ed4.js} +1 -1
- package/static/dist/assets/{nim-dun5d8mk.js → nim-dw0jcy70.js} +1 -1
- package/static/dist/assets/onboarding-ff4emacu.js +1 -0
- package/static/dist/assets/packet-AYTQ26CC-gyaf9s8h.js +1 -0
- package/static/dist/assets/pegDiagram-XKGWAZYB-bf6xj8mq.js +1 -0
- package/static/dist/assets/{perl-bj3oqtet.js → perl-3c0r45c8.js} +1 -1
- package/static/dist/assets/{php-buzp12r0.js → php-rznhidvp.js} +1 -1
- package/static/dist/assets/pie-WAS4IAKB-f5ymzelo.js +1 -0
- package/static/dist/assets/pieDiagram-E7YTZNPT-d0qjl3zi.js +39 -0
- package/static/dist/assets/{pug-mjad7he9.js → pug-f2le4f3y.js} +1 -1
- package/static/dist/assets/{qml-d1gdp10s.js → qml-e2wbq9cr.js} +1 -1
- package/static/dist/assets/{quadrantDiagram-AXDQQJYC-owqc4uqn.js → quadrantDiagram-AXDQQJYC-oqy1mras.js} +1 -1
- package/static/dist/assets/queryKeys-x8fjxhut.js +9 -0
- package/static/dist/assets/{r-o3r9c7ao.js → r-epfzuw6q.js} +1 -1
- package/static/dist/assets/radar-RG4KPBEZ-b6jcjvda.js +1 -0
- package/static/dist/assets/railroad-74A4TZTK-e3a6lk5k.js +1 -0
- package/static/dist/assets/railroad-abnf-HS5TGJTU-ff5hocrx.js +1 -0
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-exkhyw4n.js +1 -0
- package/static/dist/assets/railroad-peg-WCYAUIDC-jefk9b7c.js +1 -0
- package/static/dist/assets/railroadDiagram-O6MQD6OU-e4amks1i.js +1 -0
- package/static/dist/assets/{razor-ilc585yr.js → razor-pea1u1d0.js} +1 -1
- package/static/dist/assets/refresh-cw-lfp4u1oh.js +1 -0
- package/static/dist/assets/{regexp-mpjtcvwm.js → regexp-hzte0a5x.js} +1 -1
- package/static/dist/assets/registry-g7w3353u.js +1 -0
- package/static/dist/assets/requirementDiagram-BXWQKSXE-c77k1e2y.js +84 -0
- package/static/dist/assets/rolldown-runtime-bnnw9q4a.js +1 -0
- package/static/dist/assets/{rst-jrkwjdyi.js → rst-m6tugj5o.js} +1 -1
- package/static/dist/assets/{ruby-n4tjcbpz.js → ruby-l19vq3w1.js} +1 -1
- package/static/dist/assets/runtime-nlxpnegr.js +1 -0
- package/static/dist/assets/{sankeyDiagram-P5KCCOFB-iqc02emv.js → sankeyDiagram-P5KCCOFB-oa1cc52s.js} +1 -1
- package/static/dist/assets/{sas-hjo6y93k.js → sas-ktdxo397.js} +1 -1
- package/static/dist/assets/{scss-ncidjv48.js → scss-kn3oxfwf.js} +1 -1
- package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-i0v116q0.js → sequenceDiagram-WJ2MYXX4-j20gqt22.js} +11 -11
- package/static/dist/assets/settings_section_extensions_title-fadc7o65.js +1 -0
- package/static/dist/assets/share._token-kmfoflw6.js +2 -0
- package/static/dist/assets/{shellscript-m8whjpqd.js → shellscript-l100jtrg.js} +1 -1
- package/static/dist/assets/{shellsession-i5bj6syz.js → shellsession-m5qukwow.js} +1 -1
- package/static/dist/assets/sizeCapture-INFHLROL-dk1io13w.js +1 -0
- package/static/dist/assets/sliders-horizontal-g5jkzd9k.js +1 -0
- package/static/dist/assets/{soy-hhh36ysq.js → soy-mexlscur.js} +1 -1
- package/static/dist/assets/{sql-j21bzcl6.js → sql-o0ho5suh.js} +1 -1
- package/static/dist/assets/src-h89s0hs4.js +1 -0
- package/static/dist/assets/{stata-bbu2onh1.js → stata-be9ck1q3.js} +1 -1
- package/static/dist/assets/stateDiagram-D77RDMKH-co2ghkdp.js +1 -0
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-faw1opgh.js +1 -0
- package/static/dist/assets/{surrealql-l5vczuco.js → surrealql-gk1xkkyy.js} +1 -1
- package/static/dist/assets/{svelte-idn422g6.js → svelte-k6ecjilf.js} +1 -1
- package/static/dist/assets/swimlanes-42K2YHIH-m30cktqe.js +1 -0
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-hfil433g.js +8 -0
- package/static/dist/assets/{templ-e22qou3c.js → templ-gf3bftk6.js} +1 -1
- package/static/dist/assets/{tex-deqpc5ee.js → tex-d21fqv1z.js} +1 -1
- package/static/dist/assets/{timeline-definition-24CTP7MA-ol2hnvma.js → timeline-definition-24CTP7MA-liuep6fl.js} +8 -8
- package/static/dist/assets/toast-zmb35u3r.js +56 -0
- package/static/dist/assets/treeView-Q6P3EWNA-np5d2jv2.js +1 -0
- package/static/dist/assets/treemap-WGGIJYW6-cmpltxh1.js +1 -0
- package/static/dist/assets/{ts-tags-ctnibc27.js → ts-tags-n0g61gr6.js} +1 -1
- package/static/dist/assets/{tsx-i163n32g.js → tsx-cvv7wv6q.js} +1 -1
- package/static/dist/assets/{twig-x0fi7wm8.js → twig-n1f67204.js} +1 -1
- package/static/dist/assets/{typescript-g18c34xz.js → typescript-og7o55cx.js} +1 -1
- package/static/dist/assets/untitled-mj86r4gz.js +1 -0
- package/static/dist/assets/useDebounced-g8r0ggve.js +1 -0
- package/static/dist/assets/useForm-f1udzsjf.js +1 -0
- package/static/dist/assets/{useParams-gjc70qru.js → useParams-ierevvts.js} +1 -1
- package/static/dist/assets/{useSearch-e6ae539u.js → useSearch-i7nr9ypl.js} +1 -1
- package/static/dist/assets/vennDiagram-4TSXK5OY-b2g42qrg.js +34 -0
- package/static/dist/assets/{vue-mwu5l1bb.js → vue-ej4xpwqw.js} +1 -1
- package/static/dist/assets/{vue-html-nskj3du0.js → vue-html-d48xsjuo.js} +1 -1
- package/static/dist/assets/{vue-vine-cqe77smq.js → vue-vine-pev88ip6.js} +1 -1
- package/static/dist/assets/wardley-WFR3VGLG-lb0eqbff.js +1 -0
- package/static/dist/assets/wardleyDiagram-VM6X3IG4-ermwaqha.js +78 -0
- package/static/dist/assets/with-selector-nu1b5z0v.js +1 -0
- package/static/dist/assets/{xml-gau7gvrv.js → xml-ifxp6gqb.js} +1 -1
- package/static/dist/assets/{xsl-ew09zq8b.js → xsl-fug2cckc.js} +1 -1
- package/static/dist/assets/{xychartDiagram-S5SC5T6Z-aqbgvujg.js → xychartDiagram-S5SC5T6Z-dll0jldk.js} +6 -6
- package/static/dist/assets/{yaml-ofnrxtvf.js → yaml-fjmafnlo.js} +1 -1
- package/static/dist/extension-sdk.js +1 -1
- package/static/dist/index.html +1 -1
- package/static/dist/sw.js +180 -136
- package/static/dist/assets/AppShell-cey33v9s.js +0 -8
- package/static/dist/assets/ChatPage-i8wnugr7.js +0 -18
- package/static/dist/assets/ConnectTargets-hg19553x.js +0 -1
- package/static/dist/assets/ExtensionRoute-cly4apm5.js +0 -1
- package/static/dist/assets/Field-j8uqoigz.js +0 -9
- package/static/dist/assets/HubRoute-e4bgz41j.js +0 -2
- package/static/dist/assets/Markdown-lahuichm.js +0 -598
- package/static/dist/assets/Markdown-lwviulmg.css +0 -1
- package/static/dist/assets/RightPanel-lbo4i0fn.js +0 -1
- package/static/dist/assets/Select-gqatm2e0.js +0 -1
- package/static/dist/assets/SessionListPanel-mfqayfjh.js +0 -1
- package/static/dist/assets/SettingsLayout-b8980u7k.js +0 -1
- package/static/dist/assets/States-e7dkgtxf.js +0 -1
- package/static/dist/assets/Toaster-bfqqy786.js +0 -1
- package/static/dist/assets/_app-n1n6pfx1.js +0 -1
- package/static/dist/assets/_app.ext._extensionId-buxjxav3.js +0 -1
- package/static/dist/assets/_app.index-jt8zwiu2.js +0 -1
- package/static/dist/assets/_app.insights-cv76ml71.js +0 -1
- package/static/dist/assets/_app.kanban-h6ts53j7.js +0 -1
- package/static/dist/assets/_app.logs-dm873z90.js +0 -1
- package/static/dist/assets/_app.memory-glk5y6m8.js +0 -1
- package/static/dist/assets/_app.profiles-ka6zpstq.js +0 -1
- package/static/dist/assets/_app.session._sessionId-g2vzghvc.js +0 -1
- package/static/dist/assets/_app.settings-hgjdhzcd.js +0 -1
- package/static/dist/assets/_app.settings._section-jf2kmhae.js +0 -3
- package/static/dist/assets/_app.skills-cii852yq.js +0 -1
- package/static/dist/assets/_app.tasks-fp9q7atm.js +0 -1
- package/static/dist/assets/_app.todos-dw94qzue.js +0 -1
- package/static/dist/assets/_app.workspaces-inyygzze.js +0 -1
- package/static/dist/assets/abnfDiagram-VCTEODGH-gjayq3ra.js +0 -1
- package/static/dist/assets/architecture-7GRP2DOG-lp56972r.js +0 -1
- package/static/dist/assets/architectureDiagram-5GKGNRK7-nwb3xovn.js +0 -36
- package/static/dist/assets/archive-b1j004vn.js +0 -1
- package/static/dist/assets/back-g74gkozu.js +0 -1
- package/static/dist/assets/channel-es95o4y8.js +0 -1
- package/static/dist/assets/chunk-DU6HZSFF-gpedttsp.js +0 -128
- package/static/dist/assets/chunk-OSK3NFVY-oy0gwn2n.js +0 -10
- package/static/dist/assets/classDiagram-ZZMXUADV-kmihoqxh.js +0 -1
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-kmihoqxh.js +0 -1
- package/static/dist/assets/copied-bli9tbcx.js +0 -1
- package/static/dist/assets/copy-jamtd1pf.js +0 -1
- package/static/dist/assets/cose-bilkent-JH36ORCC-eclcy6ja.js +0 -1
- package/static/dist/assets/cynefin-OW5HDTMX-f8xfdd3f.js +0 -1
- package/static/dist/assets/cynefinDiagram-5FMLGOSQ-n9lb99h9.js +0 -62
- package/static/dist/assets/cytoscape.esm-bqu53u12.js +0 -321
- package/static/dist/assets/dagre-GXQ25YYZ-dgailddi.js +0 -4
- package/static/dist/assets/dagre-lkoknbjn.js +0 -1
- package/static/dist/assets/diagram-UQ7AKVKN-jall3j0x.js +0 -41
- package/static/dist/assets/diagram-VX7I27RA-hendl2tt.js +0 -24
- package/static/dist/assets/diagram-Z3DM3KII-igwc35p3.js +0 -24
- package/static/dist/assets/ebnfDiagram-PWID7BFC-c64knz08.js +0 -1
- package/static/dist/assets/erDiagram-RLTQ6QDP-brdu9lcm.js +0 -99
- package/static/dist/assets/eventmodeling-NTZA5JFV-njk1j8wl.js +0 -1
- package/static/dist/assets/flowDiagram-HODETNUW-nma6f0ga.js +0 -1
- package/static/dist/assets/folder-plus-lvt9kudb.js +0 -1
- package/static/dist/assets/gitGraph-4MIJSDKK-naa9w6xa.js +0 -1
- package/static/dist/assets/highlighted-body-KPVGNVTW-ghoavj8d.js +0 -1
- package/static/dist/assets/host-hzm8n85n.js +0 -1
- package/static/dist/assets/index-drdcaqeq.css +0 -2
- package/static/dist/assets/index-jzm844he.js +0 -11
- package/static/dist/assets/info-A6RAGUB7-mn2ut5ko.js +0 -1
- package/static/dist/assets/infoDiagram-27XIBGKW-h6kuqvsb.js +0 -2
- package/static/dist/assets/lazyRouteComponent-o816ytzl.js +0 -1
- package/static/dist/assets/linear-becwlnhk.js +0 -1
- package/static/dist/assets/link-k01ryaf9.js +0 -1
- package/static/dist/assets/login-bsae49ew.js +0 -1
- package/static/dist/assets/mermaid-HWGCJPDP-ihl34s74.js +0 -1
- package/static/dist/assets/mermaid-parser.core-bnre27u8.js +0 -7
- package/static/dist/assets/not-found-ccnnac39.js +0 -1
- package/static/dist/assets/onboarding-c65tysya.js +0 -1
- package/static/dist/assets/onboarding_model_label-gpn28uix.js +0 -1
- package/static/dist/assets/packet-AYTQ26CC-hatq7m2e.js +0 -1
- package/static/dist/assets/pegDiagram-XKGWAZYB-gwisz8jv.js +0 -1
- package/static/dist/assets/pie-WAS4IAKB-fpftf0mk.js +0 -1
- package/static/dist/assets/pieDiagram-E7YTZNPT-khm1o9a6.js +0 -39
- package/static/dist/assets/radar-RG4KPBEZ-cntfwjpq.js +0 -1
- package/static/dist/assets/railroad-74A4TZTK-a7t5eibp.js +0 -1
- package/static/dist/assets/railroad-abnf-HS5TGJTU-ol8cdktf.js +0 -1
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-i8vzd429.js +0 -1
- package/static/dist/assets/railroad-peg-WCYAUIDC-nw3ulewz.js +0 -1
- package/static/dist/assets/railroadDiagram-O6MQD6OU-etuh0qa0.js +0 -1
- package/static/dist/assets/refresh-cw-mqbkv2a3.js +0 -1
- package/static/dist/assets/refresh-l29ljp76.js +0 -1
- package/static/dist/assets/requirementDiagram-BXWQKSXE-oq2ulk22.js +0 -84
- package/static/dist/assets/rolldown-runtime-b9miacsj.js +0 -1
- package/static/dist/assets/root-mbklpuv4.js +0 -1
- package/static/dist/assets/saved-ndd4t2xb.js +0 -1
- package/static/dist/assets/settings_section_extensions_title-jhfo6o8z.js +0 -1
- package/static/dist/assets/share._token-c1ri0hy1.js +0 -2
- package/static/dist/assets/sizeCapture-INFHLROL-g612l48j.js +0 -1
- package/static/dist/assets/sliders-horizontal-j3jjt9tv.js +0 -1
- package/static/dist/assets/src-hjyib4mu.js +0 -1
- package/static/dist/assets/stateDiagram-D77RDMKH-dnpt1ato.js +0 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-bxjacpk6.js +0 -1
- package/static/dist/assets/swimlanes-42K2YHIH-loqbdazb.js +0 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-id62p9hz.js +0 -8
- package/static/dist/assets/toast-i3h34v6o.js +0 -64
- package/static/dist/assets/treeView-Q6P3EWNA-idrj6iox.js +0 -1
- package/static/dist/assets/treemap-WGGIJYW6-lzr49vv5.js +0 -1
- package/static/dist/assets/untitled-oaoya4qj.js +0 -1
- package/static/dist/assets/useForm-nfaxgmsk.js +0 -1
- package/static/dist/assets/vennDiagram-4TSXK5OY-bvwr9o2z.js +0 -34
- package/static/dist/assets/wardley-WFR3VGLG-31ui8tma.js +0 -1
- package/static/dist/assets/wardleyDiagram-VM6X3IG4-k5wqtx4b.js +0 -78
- /package/static/dist/assets/{ChatPage-gmu5c7lf.css → TerminalPanel-gmu5c7lf.css} +0 -0
|
@@ -1,6 +1,22 @@
|
|
|
1
|
+
import { UpdateNotificationPhaseSchema, UpdateStepSchema, AgentUpdateOperationSchema, AgentUpdateRecoverySchema } from '@maudecode/talaria-web-contracts';
|
|
1
2
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
3
|
import { readDocument } from '../sessions/storage/document.js';
|
|
3
|
-
|
|
4
|
+
import { str } from '../util.js';
|
|
5
|
+
export function updateNotificationOwner(session) {
|
|
6
|
+
const authType = str(session?.auth_type).trim();
|
|
7
|
+
if (authType === 'oidc') {
|
|
8
|
+
const issuer = str(session?.oidc_issuer).trim();
|
|
9
|
+
const subject = typeof session?.oidc_subject === 'string' ? session.oidc_subject : '';
|
|
10
|
+
if (issuer && subject.trim())
|
|
11
|
+
return `oidc:${createHash('sha256').update(JSON.stringify([issuer, subject]), 'utf8').digest('hex')}`;
|
|
12
|
+
const token = str(session?.token).trim();
|
|
13
|
+
if (token)
|
|
14
|
+
return `oidc-session:${createHash('sha256').update(JSON.stringify([token]), 'utf8').digest('hex')}`;
|
|
15
|
+
}
|
|
16
|
+
const username = str(session?.username).trim();
|
|
17
|
+
return username ? `${authType || 'auth'}:${username}` : 'local-owner';
|
|
18
|
+
}
|
|
19
|
+
const PHASES = new Set(UpdateNotificationPhaseSchema.options);
|
|
4
20
|
const REVISION = /^[a-f0-9]{40}$/;
|
|
5
21
|
const PER_SCOPE_LIMIT = 50;
|
|
6
22
|
const GLOBAL_LIMIT = 500;
|
|
@@ -14,21 +30,10 @@ const GATEWAY_RESTART_NOW_ACTION = { id: GATEWAY_RESTART_NOW, label: 'Restart no
|
|
|
14
30
|
/** A closed tab stops checking in; its refresh notice is dropped once unseen this long. An open tab recreates it on its next check. */
|
|
15
31
|
const TAB_TTL_MS = 60 * 60 * 1000;
|
|
16
32
|
const FAILED_MESSAGE = 'The update could not be completed.';
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
title: row.title,
|
|
22
|
-
// Old persisted failures still carry the obsolete guidance; correct only that generic copy.
|
|
23
|
-
message: row.kind === 'update' && row.phase === 'failed' && row.message === `${FAILED_MESSAGE} Open System settings for details.` ? FAILED_MESSAGE : row.message,
|
|
24
|
-
created_at: row.created_at, updated_at: row.updated_at, read_at: row.read_at,
|
|
25
|
-
acknowledged_at: row.acknowledged_at, acknowledged_action_id: row.acknowledged_action_id,
|
|
26
|
-
verified_revision: row.verified_revision, verified_version: row.verified_version, detail: row.detail,
|
|
27
|
-
unread: row.read_at === null,
|
|
28
|
-
active: ['update', 'agent_recovery'].includes(row.kind) && ['applying', 'restarting'].includes(row.phase),
|
|
29
|
-
requires_interaction: row.requires_acknowledgement && row.acknowledged_at === null,
|
|
30
|
-
can_dismiss: isDismissible(row),
|
|
31
|
-
});
|
|
33
|
+
const STEP_IDS = new Set(UpdateStepSchema.shape.id.options);
|
|
34
|
+
/** Phases in which an update the user started presents its Updating dialog to every tab that can see it. */
|
|
35
|
+
const PRESENTING = new Set(['applying', 'restarting', 'verifying', 'recovering']);
|
|
36
|
+
const TERMINAL_FAILURE = new Set(['failed', 'blocked', 'unknown']);
|
|
32
37
|
/** TAL-953: the waiting gateway restart's message, with the running task count once one is known. */
|
|
33
38
|
const gatewayWaitingMessage = (tasks) => tasks > 0
|
|
34
39
|
? `Waiting for ${String(tasks)} running gateway task${tasks === 1 ? '' : 's'} to finish before restarting the gateway.`
|
|
@@ -40,6 +45,8 @@ const wording = (target, phase) => {
|
|
|
40
45
|
awaiting_confirmation: 'This Hermes Agent revision needs confirmation before it can be installed.',
|
|
41
46
|
waiting_for_idle: gatewayWaitingMessage(0),
|
|
42
47
|
restarting: target === 'webui' ? 'The update is installed. Talaria Web is restarting.' : 'The update is installed. The messaging gateway is restarting.',
|
|
48
|
+
verifying: 'The update is installed. Checking that Hermes Agent responds.',
|
|
49
|
+
recovering: 'Attempting recovery',
|
|
43
50
|
succeeded: `${name} was updated successfully.`,
|
|
44
51
|
blocked: 'The update is waiting for active work to finish.',
|
|
45
52
|
failed: FAILED_MESSAGE,
|
|
@@ -47,6 +54,56 @@ const wording = (target, phase) => {
|
|
|
47
54
|
};
|
|
48
55
|
return { title: `${name} update`, message: messages[phase] };
|
|
49
56
|
};
|
|
57
|
+
const RELOAD_IN_DIALOG = { id: WEB_REFRESH_ACTION, label: 'Reload', style: 'primary', acknowledges: false };
|
|
58
|
+
/** Release tags name versions as `web-v1.2.3`; the dialog shows `1.2.3`. */
|
|
59
|
+
const shownVersion = (version) => version ? ` ${version.replace(/^web-(?:exp-)?v/, '')}` : '';
|
|
60
|
+
/** TAL-1138: the step an update is on, or null once it succeeded. `webPending`: its Talaria Web restart has not happened yet. */
|
|
61
|
+
function currentStep(row, webPending) {
|
|
62
|
+
if (TERMINAL_FAILURE.has(row.phase))
|
|
63
|
+
return row.failed_step ?? 'install';
|
|
64
|
+
if (row.phase === 'succeeded')
|
|
65
|
+
return null;
|
|
66
|
+
if (row.phase === 'recovering')
|
|
67
|
+
return 'recovery';
|
|
68
|
+
if (row.phase === 'restarting')
|
|
69
|
+
return row.target === 'webui' ? 'web_restart' : 'gateway_restart';
|
|
70
|
+
if (row.phase === 'waiting_for_idle')
|
|
71
|
+
return webPending ? 'web_restart' : 'gateway_wait';
|
|
72
|
+
if (row.phase === 'verifying')
|
|
73
|
+
return webPending ? 'web_restart' : 'agent_ready';
|
|
74
|
+
return 'install';
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* TAL-1138: the update's steps as the Updating dialog lists them. Web: Installing, Restarting Talaria Web, Ready.
|
|
78
|
+
* Agent: Installing, Restarting Talaria Web, Waiting for gateway tasks (only once the gateway was busy), Restarting
|
|
79
|
+
* gateway, Agent responding. An update that finished without restarting anything lists only the steps it ran.
|
|
80
|
+
*/
|
|
81
|
+
function updateSteps(row, webPending) {
|
|
82
|
+
if (row.kind !== 'update' || !row.target)
|
|
83
|
+
return [];
|
|
84
|
+
const current = currentStep(row, webPending);
|
|
85
|
+
const undecided = ['applying', 'awaiting_confirmation'].includes(row.phase);
|
|
86
|
+
// Each restart step needs its own evidence: a scheduled Web restart, or a gateway restart under way or recorded.
|
|
87
|
+
const webRestarts = undecided || row.web_restart_boot !== null || current === 'web_restart';
|
|
88
|
+
const gatewayRestarts = row.recovery?.operation.failed_stage === 'gateway_restart' || undecided || ['waiting_for_idle', 'restarting'].includes(row.phase) || row.gateway_baseline !== null || current === 'gateway_wait' || current === 'gateway_restart';
|
|
89
|
+
const succeeded = row.phase === 'succeeded';
|
|
90
|
+
const recovered = row.recovery && ['target_installed', 'baseline_restored', 'other_revision'].includes(row.recovery.outcome);
|
|
91
|
+
const tasks = row.gateway_tasks ?? 0;
|
|
92
|
+
const plan = row.target === 'webui'
|
|
93
|
+
? [['install', 'Installing'], ...(webRestarts ? [['web_restart', 'Restarting Talaria Web']] : []), ['ready', succeeded ? `Talaria Web${shownVersion(row.verified_version)} is ready` : 'Ready']]
|
|
94
|
+
: [
|
|
95
|
+
['install', 'Installing'],
|
|
96
|
+
...(webRestarts ? [['web_restart', 'Restarting Talaria Web']] : []),
|
|
97
|
+
...(row.gateway_tasks !== null || current === 'gateway_wait' ? [['gateway_wait', tasks > 0 ? `Waiting for ${String(tasks)} gateway task${tasks === 1 ? '' : 's'}` : 'Waiting for gateway tasks']] : []),
|
|
98
|
+
...(gatewayRestarts ? [['gateway_restart', 'Restarting gateway']] : []),
|
|
99
|
+
...(row.recovery || current === 'recovery' ? [['recovery', 'Attempting recovery']] : []),
|
|
100
|
+
['agent_ready', succeeded || recovered ? `Hermes Agent${shownVersion(row.verified_version)} is running` : 'Agent responding'],
|
|
101
|
+
];
|
|
102
|
+
const at = current === null ? plan.length : plan.findIndex(([id]) => id === current);
|
|
103
|
+
if (recovered && !succeeded)
|
|
104
|
+
return plan.map(([id, label]) => ({ id, label, state: id === (row.recovery?.operation.failed_stage ?? 'install') ? 'failed' : 'done' }));
|
|
105
|
+
return plan.map(([id, label], index) => ({ id, label, state: row.phase === 'recovering' && id === row.recovery?.operation.failed_stage ? 'failed' : index < at ? 'done' : index > at ? 'pending' : TERMINAL_FAILURE.has(row.phase) ? 'failed' : 'active' }));
|
|
106
|
+
}
|
|
50
107
|
export class UpdateNotificationStore {
|
|
51
108
|
documents;
|
|
52
109
|
now;
|
|
@@ -56,12 +113,42 @@ export class UpdateNotificationStore {
|
|
|
56
113
|
/** Last check-in per tab refresh notice; kept in memory so polling never rewrites the store. */
|
|
57
114
|
tabSeen = new Map();
|
|
58
115
|
loadedAt;
|
|
116
|
+
/** This server process; an update whose Web restart another process scheduled has restarted Web. */
|
|
117
|
+
boot = randomUUID();
|
|
59
118
|
constructor(documents, now = () => new Date()) {
|
|
60
119
|
this.documents = documents;
|
|
61
120
|
this.now = now;
|
|
62
121
|
this.loadedAt = this.now().valueOf();
|
|
63
122
|
}
|
|
64
123
|
async initialize() { this.rows = await this.load(); }
|
|
124
|
+
/** Startup warnings outlive any chat or Agent. Repeats retain read/dismissal state until the full text changes. */
|
|
125
|
+
async agentWarning(scope, key, notice) {
|
|
126
|
+
const row = this.rows.find((entry) => entry.kind === 'agent_warning' && entry.notice_key === key && entry.owner === scope.owner && entry.profile === scope.profile);
|
|
127
|
+
if (!notice) {
|
|
128
|
+
if (!row)
|
|
129
|
+
return;
|
|
130
|
+
this.rows = this.rows.filter((entry) => entry !== row);
|
|
131
|
+
return this.save();
|
|
132
|
+
}
|
|
133
|
+
const message = safeText(notice.text, '', 500);
|
|
134
|
+
if (!message)
|
|
135
|
+
return;
|
|
136
|
+
const textHash = createHash('sha256').update(notice.text).digest('hex');
|
|
137
|
+
const severity = notice.level === 'error' ? 'critical' : notice.level === 'warn' ? 'warning' : 'info';
|
|
138
|
+
if (!row) {
|
|
139
|
+
await this.createRow(scope, { kind: 'agent_warning', target: 'agent', phase: 'active', severity, persistent: true, title: 'Agent warning', message }, { notice_key: key, notice_text_hash: textHash });
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
row.updated_at = this.now().toISOString();
|
|
143
|
+
if (row.notice_text_hash !== textHash) {
|
|
144
|
+
row.message = message;
|
|
145
|
+
row.severity = severity;
|
|
146
|
+
row.notice_text_hash = textHash;
|
|
147
|
+
row.read_at = null;
|
|
148
|
+
row.dismissed_at = null;
|
|
149
|
+
}
|
|
150
|
+
await this.save();
|
|
151
|
+
}
|
|
65
152
|
/**
|
|
66
153
|
* Compare the frontend build a tab loaded with the build this server now serves. A mismatch keeps one
|
|
67
154
|
* persistent, tab-scoped refresh notice per tab; a match resolves and removes it. Unknown builds change nothing.
|
|
@@ -84,6 +171,15 @@ export class UpdateNotificationStore {
|
|
|
84
171
|
return state;
|
|
85
172
|
}
|
|
86
173
|
state.refresh_required = true;
|
|
174
|
+
// TAL-1138: the Web update this tab started offers Reload in its own Updating dialog instead.
|
|
175
|
+
if (this.rows.some((row) => this.isVisible(row, scope) && this.reloadsInDialog(row, tab, true))) {
|
|
176
|
+
if (existing) {
|
|
177
|
+
this.rows = this.rows.filter((row) => row !== existing);
|
|
178
|
+
this.tabSeen.delete(existing.id);
|
|
179
|
+
await this.save();
|
|
180
|
+
}
|
|
181
|
+
return state;
|
|
182
|
+
}
|
|
87
183
|
const stamp = this.now().toISOString();
|
|
88
184
|
if (existing) {
|
|
89
185
|
this.tabSeen.set(existing.id, this.now().valueOf());
|
|
@@ -105,6 +201,7 @@ export class UpdateNotificationStore {
|
|
|
105
201
|
created_at: stamp, updated_at: stamp, read_at: null, acknowledged_at: null,
|
|
106
202
|
acknowledged_action_id: null, verified_revision: null, verified_version: null, detail: null,
|
|
107
203
|
performed_action_ids: [], dismissed_at: null, expected_identity: current, tab_id: tab, watchers: [],
|
|
204
|
+
web_restart_boot: null, gateway_tasks: null, gateway_baseline: null, failed_step: null,
|
|
108
205
|
};
|
|
109
206
|
if (!this.hasProtectedCapacity(row))
|
|
110
207
|
return state;
|
|
@@ -124,15 +221,97 @@ export class UpdateNotificationStore {
|
|
|
124
221
|
await this.watch(scope, created.id);
|
|
125
222
|
return created;
|
|
126
223
|
}
|
|
224
|
+
/** Saved before the native lease can change source; the row ID is the operation ID. */
|
|
225
|
+
async bindAgentOperation(id, baseline, target) {
|
|
226
|
+
const row = this.rows.find((entry) => entry.id === id && entry.target === 'agent' && entry.phase === 'applying');
|
|
227
|
+
if (!row)
|
|
228
|
+
throw new Error('The initiating Agent update is no longer active.');
|
|
229
|
+
const operation = AgentUpdateOperationSchema.parse({ operation_id: id, baseline_revision: baseline, target_revision: target, stage: 'install' });
|
|
230
|
+
if (row.agent_operation && (row.agent_operation.baseline_revision !== baseline || row.agent_operation.target_revision !== target))
|
|
231
|
+
throw new Error('The update target changed within the same operation.');
|
|
232
|
+
row.agent_operation = operation;
|
|
233
|
+
await this.save();
|
|
234
|
+
}
|
|
235
|
+
async handoffAgentRecovery(id, detail, identity) {
|
|
236
|
+
const row = this.rows.find((entry) => entry.id === id && entry.agent_operation);
|
|
237
|
+
if (!row)
|
|
238
|
+
return false;
|
|
239
|
+
if (TERMINAL_FAILURE.has(row.phase) || row.phase === 'succeeded')
|
|
240
|
+
return true;
|
|
241
|
+
row.recovery ??= { operation: row.agent_operation, attempt_error: safeDetail(detail), runtime_revision: null, outcome: 'recovering' };
|
|
242
|
+
row.recovery.attempt_error ??= safeDetail(detail);
|
|
243
|
+
await this.transition(id, 'recovering', null, identity, row.recovery.attempt_error);
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
pendingAgentOperation() {
|
|
247
|
+
return this.rows.findLast((row) => row.kind === 'update' && row.target === 'agent' && row.agent_operation && ['applying', 'recovering'].includes(row.phase))?.id;
|
|
248
|
+
}
|
|
127
249
|
/** A retained notice still needs loaded-readiness verification after native debt clears. */
|
|
128
250
|
hasPendingAgentRecovery() {
|
|
129
251
|
const row = this.rows.findLast((entry) => entry.kind === 'agent_recovery');
|
|
130
|
-
return row !== undefined && row.phase !== 'succeeded';
|
|
252
|
+
return this.pendingAgentOperation() !== undefined || (row !== undefined && row.phase !== 'succeeded');
|
|
131
253
|
}
|
|
132
|
-
/**
|
|
254
|
+
/** Only a transaction-bound active operation can absorb recovery; orphan receipts retain their own notice. */
|
|
133
255
|
async agentRecovery(state) {
|
|
134
256
|
if (state.phase === 'idle')
|
|
135
257
|
return;
|
|
258
|
+
const id = state.operation_id ?? state.operation?.operation_id;
|
|
259
|
+
const original = id ? this.rows.find((row) => row.id === id && row.agent_operation && ['applying', 'recovering'].includes(row.phase)) : undefined;
|
|
260
|
+
if (original) {
|
|
261
|
+
const expected = original.agent_operation;
|
|
262
|
+
const evidence = state.operation;
|
|
263
|
+
const bound = evidence?.operation_id === expected.operation_id && evidence.baseline_revision === expected.baseline_revision && evidence.target_revision === expected.target_revision;
|
|
264
|
+
original.recovery ??= { operation: expected, attempt_error: original.detail, runtime_revision: null, outcome: 'recovering' };
|
|
265
|
+
const recovery = original.recovery;
|
|
266
|
+
if (bound) {
|
|
267
|
+
const failedStage = evidence.failed_stage ?? recovery.operation.failed_stage;
|
|
268
|
+
recovery.operation = { ...evidence, ...(failedStage ? { failed_stage: failedStage } : {}) };
|
|
269
|
+
recovery.attempt_error ??= safeDetail(evidence.attempt_error);
|
|
270
|
+
original.failed_step = failedStage ?? evidence.stage;
|
|
271
|
+
}
|
|
272
|
+
recovery.runtime_revision = state.runtime_revision ?? null;
|
|
273
|
+
const identity = state.verified_revision ? { revision: state.verified_revision, version: state.verified_version ?? null } : state.phase === 'complete' ? { revision: null, version: null } : undefined;
|
|
274
|
+
if (state.phase === 'complete') {
|
|
275
|
+
const verified = bound && evidence.recovered_revision === state.verified_revision && state.runtime_revision === state.verified_revision;
|
|
276
|
+
const actual = state.verified_version || state.verified_revision || 'unknown version';
|
|
277
|
+
recovery.rollback = verified && state.verified_revision === expected.baseline_revision ? evidence.source_moved ?? null : verified ? false : null;
|
|
278
|
+
recovery.outcome = !verified ? 'unknown' : state.verified_revision === expected.target_revision ? 'target_installed' : state.verified_revision === expected.baseline_revision ? 'baseline_restored' : 'other_revision';
|
|
279
|
+
await this.transition(original.id, recovery.outcome === 'target_installed' ? 'succeeded' : recovery.outcome === 'unknown' ? 'unknown' : 'failed', null, identity, recovery.attempt_error);
|
|
280
|
+
if (recovery.outcome === 'target_installed')
|
|
281
|
+
original.message = `Hermes Agent ${actual} is running after automatic recovery.`;
|
|
282
|
+
else if (recovery.outcome === 'baseline_restored') {
|
|
283
|
+
if (recovery.rollback === true)
|
|
284
|
+
original.message = `The requested update failed. Automatic recovery rolled back to the previous revision, ${actual}.`;
|
|
285
|
+
else if (recovery.rollback === false)
|
|
286
|
+
original.message = `The requested update failed. Service recovered on the unchanged previous revision, ${actual}; no rollback occurred.`;
|
|
287
|
+
else
|
|
288
|
+
original.message = `The requested update failed. Service recovered on the previous revision, ${actual}; rollback could not be verified.`;
|
|
289
|
+
}
|
|
290
|
+
else if (recovery.outcome === 'other_revision')
|
|
291
|
+
original.message = `The requested update failed. Service recovered on ${actual}; the selected target was not installed.`;
|
|
292
|
+
else
|
|
293
|
+
original.message = `The update outcome could not be verified after recovery. ${state.verified_revision ? 'Current version' : 'Loaded version'}: ${actual}.`;
|
|
294
|
+
}
|
|
295
|
+
else if (state.phase === 'blocked') {
|
|
296
|
+
recovery.outcome = 'blocked';
|
|
297
|
+
await this.transition(original.id, 'blocked', null, identity, [recovery.attempt_error, state.detail].filter(Boolean).join('\n'));
|
|
298
|
+
original.message = 'Automatic recovery could not finish. ' + (state.verified_version ? `Current version: ${state.verified_version}. ` : '') + 'Check the recovery details before retrying.';
|
|
299
|
+
original.failed_step = 'recovery';
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
await this.transition(original.id, 'recovering', null, identity, [recovery.attempt_error, state.detail].filter(Boolean).join('\n'));
|
|
303
|
+
}
|
|
304
|
+
if (state.phase === 'complete' || state.phase === 'blocked')
|
|
305
|
+
original.detail = safeDetail([original.message, original.detail, recovery.attempt_error].filter((value, index, values) => Boolean(value) && values.indexOf(value) === index).join('\n'));
|
|
306
|
+
await this.save();
|
|
307
|
+
if (state.phase === 'complete' && this.rows.some((row) => row.kind === 'agent_recovery' && row.phase !== 'succeeded')) {
|
|
308
|
+
await this.agentRecovery({ phase: state.phase, attempt: state.attempt, detail: state.detail, retry_at: state.retry_at });
|
|
309
|
+
}
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
// A stale callback cannot rewrite a terminal attempt or create a second notice for that operation.
|
|
313
|
+
if (id && this.rows.some((row) => row.id === id) && (state.phase !== 'complete' || !this.rows.some((row) => row.kind === 'agent_recovery' && row.phase !== 'succeeded')))
|
|
314
|
+
return;
|
|
136
315
|
const phase = state.phase === 'complete' ? 'succeeded' : state.phase === 'running' ? 'applying' : 'blocked';
|
|
137
316
|
const title = 'Hermes Agent recovery';
|
|
138
317
|
const message = state.phase === 'complete' ? 'Hermes Agent is usable again. The original update result is unchanged.'
|
|
@@ -158,6 +337,59 @@ export class UpdateNotificationStore {
|
|
|
158
337
|
row.read_at = null;
|
|
159
338
|
await this.save();
|
|
160
339
|
}
|
|
340
|
+
/**
|
|
341
|
+
* A question the server asks about one profile (TAL-1274), seen by every server owner while that profile is active. Its
|
|
342
|
+
* open row is refreshed in place; null withdraws it once nothing asks it any more. An answered row stays as history.
|
|
343
|
+
*/
|
|
344
|
+
async profileQuestion(profile, kind, input) {
|
|
345
|
+
const open = this.rows.find((row) => row.kind === kind && row.owner === '*' && row.profile === profile && row.acknowledged_at === null);
|
|
346
|
+
if (!input) {
|
|
347
|
+
if (!open)
|
|
348
|
+
return;
|
|
349
|
+
this.rows = this.rows.filter((row) => row !== open);
|
|
350
|
+
return this.save();
|
|
351
|
+
}
|
|
352
|
+
if (!open) {
|
|
353
|
+
await this.create({ owner: '*', profile, serverOwner: true }, { ...input, kind, requiresAcknowledgement: true });
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
const message = safeText(input.message, '', 500);
|
|
357
|
+
const detail = safeDetail(input.detail);
|
|
358
|
+
if (!message || (open.message === message && open.detail === detail))
|
|
359
|
+
return;
|
|
360
|
+
open.message = message;
|
|
361
|
+
open.detail = detail;
|
|
362
|
+
open.updated_at = this.now().toISOString();
|
|
363
|
+
open.read_at = null;
|
|
364
|
+
await this.save();
|
|
365
|
+
}
|
|
366
|
+
/** Drop all profile-scoped state, including dismissed warning identities, when a profile is deleted. */
|
|
367
|
+
async forgetProfile(profile) {
|
|
368
|
+
const kept = this.rows.filter((row) => !(row.visibility === 'profile' && row.profile === profile));
|
|
369
|
+
if (kept.length === this.rows.length)
|
|
370
|
+
return;
|
|
371
|
+
this.rows = kept;
|
|
372
|
+
await this.save();
|
|
373
|
+
}
|
|
374
|
+
/** The open question `id` of `kind` this scope sees, or null. */
|
|
375
|
+
openQuestion(scope, id, kind) {
|
|
376
|
+
const row = this.visible(scope, id);
|
|
377
|
+
return row?.kind === kind && row.owner === '*' && row.acknowledged_at === null ? this.publish(row, scope.tab) : null;
|
|
378
|
+
}
|
|
379
|
+
/** Record the answer to an open question: its outcome replaces the question, which then leaves only Dismiss. */
|
|
380
|
+
async answerQuestion(scope, id, kind, actionId, outcome) {
|
|
381
|
+
const row = this.visible(scope, id);
|
|
382
|
+
if (row?.kind !== kind || row.owner !== '*' || row.acknowledged_at !== null || !row.actions.some((action) => action.id === actionId))
|
|
383
|
+
return null;
|
|
384
|
+
const stamp = this.now().toISOString();
|
|
385
|
+
Object.assign(row, {
|
|
386
|
+
phase: 'succeeded', severity: 'info', message: safeText(outcome, row.message, 500), detail: null, actions: [],
|
|
387
|
+
updated_at: stamp, read_at: row.read_at ?? stamp, acknowledged_at: stamp, acknowledged_action_id: actionId,
|
|
388
|
+
performed_action_ids: [...row.performed_action_ids, actionId],
|
|
389
|
+
});
|
|
390
|
+
await this.save();
|
|
391
|
+
return this.publish(row, scope.tab);
|
|
392
|
+
}
|
|
161
393
|
/** Let the requesting tab follow an update operation it started or rejoined. Watchers live as long as the record; only a server owner's Update click adds one. */
|
|
162
394
|
async watch(scope, id) {
|
|
163
395
|
const tab = scope.tab && TAB_ID.test(scope.tab) ? scope.tab : null;
|
|
@@ -168,6 +400,9 @@ export class UpdateNotificationStore {
|
|
|
168
400
|
await this.save();
|
|
169
401
|
}
|
|
170
402
|
async create(scope, input) {
|
|
403
|
+
return this.publish(await this.createRow(scope, input));
|
|
404
|
+
}
|
|
405
|
+
async createRow(scope, input, notice = {}) {
|
|
171
406
|
const kind = safeToken(input.kind, '');
|
|
172
407
|
const phase = safeToken(input.phase, '');
|
|
173
408
|
const title = safeText(input.title, '', 160);
|
|
@@ -180,29 +415,45 @@ export class UpdateNotificationStore {
|
|
|
180
415
|
const stamp = this.now().toISOString();
|
|
181
416
|
const row = {
|
|
182
417
|
id: randomUUID(), owner: scope.owner.slice(0, 256), profile: scope.profile.slice(0, 64), visibility: input.visibility ?? 'profile',
|
|
183
|
-
kind, target: input.target ?? null, phase, severity: input.severity ?? 'info',
|
|
418
|
+
...notice, kind, target: input.target ?? null, phase, severity: input.severity ?? 'info',
|
|
184
419
|
persistent: input.requiresAcknowledgement === true || input.persistent === true,
|
|
185
420
|
requires_acknowledgement: input.requiresAcknowledgement === true, actions,
|
|
186
421
|
destination: safeDestination(input.destination), title, message,
|
|
187
422
|
created_at: stamp, updated_at: stamp, read_at: null, acknowledged_at: null,
|
|
188
|
-
acknowledged_action_id: null, verified_revision: null, verified_version: null, detail:
|
|
423
|
+
acknowledged_action_id: null, verified_revision: null, verified_version: null, detail: safeDetail(input.detail),
|
|
189
424
|
performed_action_ids: [], dismissed_at: null, expected_identity: null, tab_id: null, watchers: [],
|
|
425
|
+
web_restart_boot: null, gateway_tasks: null, gateway_baseline: null, failed_step: null,
|
|
190
426
|
};
|
|
191
427
|
if (!this.hasProtectedCapacity(row))
|
|
192
428
|
throw new Error('Update notification protected capacity reached');
|
|
193
429
|
this.rows.push(row);
|
|
194
430
|
await this.save();
|
|
195
|
-
return
|
|
431
|
+
return row;
|
|
196
432
|
}
|
|
197
433
|
activeUpdate(scope, target) {
|
|
198
|
-
const row = [...this.rows].reverse().find((entry) => this.isVisible(entry, scope) && entry.kind === 'update' && entry.target === target && ['applying', 'awaiting_confirmation', 'restarting'].includes(entry.phase));
|
|
199
|
-
return row ?
|
|
434
|
+
const row = [...this.rows].reverse().find((entry) => this.isVisible(entry, scope) && entry.kind === 'update' && entry.target === target && ['applying', 'awaiting_confirmation', 'restarting', 'verifying', 'recovering'].includes(entry.phase));
|
|
435
|
+
return row ? this.publish(row) : null;
|
|
200
436
|
}
|
|
201
437
|
async transition(id, phase, expectedIdentity, verifiedIdentity, detail) {
|
|
202
438
|
const row = this.rows.find((entry) => entry.id === id);
|
|
203
439
|
if (!row)
|
|
204
440
|
return null;
|
|
441
|
+
if (phase === 'applying' && !['applying', 'awaiting_confirmation'].includes(row.phase))
|
|
442
|
+
return this.publish(row);
|
|
443
|
+
const failedStep = currentStep(row, this.webPending(row));
|
|
444
|
+
if (phase === 'failed' && row.target === 'agent' && row.agent_operation && ['restarting', 'verifying'].includes(row.phase)
|
|
445
|
+
&& (failedStep === 'gateway_restart' || failedStep === 'agent_ready')) {
|
|
446
|
+
row.recovery ??= { operation: { ...row.agent_operation, failed_stage: failedStep }, attempt_error: safeDetail(detail), runtime_revision: null, outcome: 'recovering' };
|
|
447
|
+
phase = 'recovering';
|
|
448
|
+
}
|
|
205
449
|
const phaseChanged = row.phase !== phase;
|
|
450
|
+
// TAL-1138: a failure keeps the step it stopped at, so the dialog marks that step failed.
|
|
451
|
+
if (!TERMINAL_FAILURE.has(phase))
|
|
452
|
+
row.failed_step = null;
|
|
453
|
+
else if (!TERMINAL_FAILURE.has(row.phase))
|
|
454
|
+
row.failed_step = currentStep(row, this.webPending(row)) ?? 'install';
|
|
455
|
+
if (row.kind === 'update' && row.target === 'webui' && phase === 'restarting')
|
|
456
|
+
row.web_restart_boot = this.boot;
|
|
206
457
|
row.phase = phase;
|
|
207
458
|
if (row.target)
|
|
208
459
|
Object.assign(row, wording(row.target, phase));
|
|
@@ -212,7 +463,7 @@ export class UpdateNotificationStore {
|
|
|
212
463
|
if (phaseChanged)
|
|
213
464
|
row.read_at = null;
|
|
214
465
|
row.expected_identity = expectedIdentity?.trim().slice(0, 160) || null;
|
|
215
|
-
row.detail = phase === 'failed' || phase === 'blocked' || phase === 'succeeded' || phase === 'waiting_for_idle' ? safeDetail(detail) : null;
|
|
466
|
+
row.detail = phase === 'applying' || phase === 'failed' || phase === 'blocked' || phase === 'succeeded' || phase === 'waiting_for_idle' || phase === 'verifying' || phase === 'recovering' || phase === 'unknown' ? safeDetail(detail) : null;
|
|
216
467
|
// The gateway restart is server-wide: every server owner sees the wait and can restart now, and a later update joins it.
|
|
217
468
|
if (row.kind === 'update' && phase === 'waiting_for_idle' && row.visibility === 'server')
|
|
218
469
|
row.owner = '*';
|
|
@@ -226,39 +477,63 @@ export class UpdateNotificationStore {
|
|
|
226
477
|
row.verified_version = safeText(verifiedIdentity.version, '', 80) || null;
|
|
227
478
|
}
|
|
228
479
|
await this.save();
|
|
229
|
-
return
|
|
480
|
+
return this.publish(row);
|
|
230
481
|
}
|
|
231
482
|
/** TAL-953: update the waiting gateway restart's message as its running task count changes. */
|
|
232
483
|
async gatewayWaiting(id, tasks) {
|
|
233
484
|
const row = this.rows.find((entry) => entry.id === id && entry.kind === 'update' && entry.phase === 'waiting_for_idle');
|
|
234
485
|
const message = gatewayWaitingMessage(tasks);
|
|
235
|
-
|
|
486
|
+
const counted = tasks > 0 ? tasks : row?.gateway_tasks ?? null;
|
|
487
|
+
if (!row || (row.message === message && row.gateway_tasks === counted))
|
|
236
488
|
return;
|
|
237
489
|
row.message = message;
|
|
490
|
+
row.gateway_tasks = counted;
|
|
238
491
|
row.updated_at = this.now().toISOString();
|
|
239
492
|
await this.save();
|
|
240
493
|
}
|
|
241
|
-
/** TAL-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
494
|
+
/** TAL-1138: this Agent update scheduled a Talaria Web restart; its gateway steps follow the restarted server. */
|
|
495
|
+
async markWebRestart(id) {
|
|
496
|
+
const row = this.rows.find((entry) => entry.id === id && entry.kind === 'update');
|
|
497
|
+
if (!row || row.web_restart_boot === this.boot)
|
|
498
|
+
return;
|
|
499
|
+
row.web_restart_boot = this.boot;
|
|
500
|
+
row.updated_at = this.now().toISOString();
|
|
501
|
+
await this.save();
|
|
245
502
|
}
|
|
246
|
-
|
|
503
|
+
/** TAL-1138: the live gateway processes a restart must replace before the update's check can pass. */
|
|
504
|
+
async recordGatewayBaseline(id, baseline) {
|
|
505
|
+
const row = this.rows.find((entry) => entry.id === id && entry.kind === 'update');
|
|
506
|
+
if (!row)
|
|
507
|
+
return;
|
|
508
|
+
row.gateway_baseline = baseline.slice(0, 8).map((entry) => ({ ...entry }));
|
|
509
|
+
await this.save();
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* TAL-953: gateway restarts still waiting for idle, and (TAL-1138) restarted gateways still being checked, newest
|
|
513
|
+
* first, with the profile each update ran under, so a restarted server resumes them.
|
|
514
|
+
*/
|
|
515
|
+
pendingGatewayRestarts() {
|
|
516
|
+
return this.rows.filter((row) => row.kind === 'update' && (row.phase === 'waiting_for_idle' || row.phase === 'verifying'))
|
|
517
|
+
.sort((a, b) => b.created_at.localeCompare(a.created_at))
|
|
518
|
+
.map((row) => ({ id: row.id, profile: row.profile, detail: row.detail, phase: row.phase, baseline: row.gateway_baseline }));
|
|
519
|
+
}
|
|
520
|
+
/** `stale`: the requesting tab runs an older frontend build than the server serves (`syncTabBuild`'s comparison). */
|
|
521
|
+
async list(scope, stale = false) {
|
|
247
522
|
await this.pruneClosedTabs();
|
|
248
523
|
const scoped = this.rows.filter((row) => this.isVisible(row, scope) && row.dismissed_at === null);
|
|
249
524
|
const ordered = scoped.sort((a, b) => b.updated_at.localeCompare(a.updated_at));
|
|
250
525
|
const protectedRows = ordered.filter(isProtected);
|
|
251
526
|
const visible = [...protectedRows, ...ordered.filter((row) => !isProtected(row)).slice(0, Math.max(0, PER_SCOPE_LIMIT - protectedRows.length))]
|
|
252
527
|
.sort((a, b) => b.updated_at.localeCompare(a.updated_at));
|
|
253
|
-
const notifications = visible.map(copy);
|
|
254
|
-
const clearableCount = scoped.filter(isDismissible).length;
|
|
255
528
|
const tab = scope.tab && TAB_ID.test(scope.tab) ? scope.tab : null;
|
|
529
|
+
const notifications = visible.map((row) => this.publish(row, tab, stale));
|
|
530
|
+
const clearableCount = scoped.filter(isDismissible).length;
|
|
256
531
|
const joinedAt = (row) => row.watchers.find((watcher) => watcher.tab === tab)?.at ?? '';
|
|
257
532
|
const tabUpdate = tab ? this.rows.filter((row) => row.kind === 'update' && joinedAt(row) !== '' && this.isVisible(row, scope))
|
|
258
533
|
.sort((a, b) => joinedAt(b).localeCompare(joinedAt(a)) || b.created_at.localeCompare(a.created_at))[0] : undefined;
|
|
259
|
-
return { scope_id: updateNotificationScopeId(scope), notifications, tab_update: tabUpdate ?
|
|
534
|
+
return { scope_id: updateNotificationScopeId(scope), notifications, tab_update: tabUpdate ? this.publish(tabUpdate, tab, stale) : null, tab_joined_at: tabUpdate ? joinedAt(tabUpdate) : null, unread_count: visible.filter((row) => row.read_at === null).length, clearable_count: clearableCount, can_clear: clearableCount > 0 };
|
|
260
535
|
}
|
|
261
|
-
async clear(scope) {
|
|
536
|
+
async clear(scope, stale = false) {
|
|
262
537
|
const stamp = this.now().toISOString();
|
|
263
538
|
let changed = false;
|
|
264
539
|
for (const row of this.rows) {
|
|
@@ -269,7 +544,7 @@ export class UpdateNotificationStore {
|
|
|
269
544
|
}
|
|
270
545
|
if (changed)
|
|
271
546
|
(await this.save());
|
|
272
|
-
return (await this.list(scope));
|
|
547
|
+
return (await this.list(scope, stale));
|
|
273
548
|
}
|
|
274
549
|
async read(scope, id) {
|
|
275
550
|
const row = this.visible(scope, id);
|
|
@@ -279,7 +554,7 @@ export class UpdateNotificationStore {
|
|
|
279
554
|
row.read_at = this.now().toISOString();
|
|
280
555
|
(await this.save());
|
|
281
556
|
}
|
|
282
|
-
return
|
|
557
|
+
return this.publish(row);
|
|
283
558
|
}
|
|
284
559
|
async dismiss(scope, id) {
|
|
285
560
|
const row = this.rows.find((entry) => entry.id === id && this.isVisible(entry, scope));
|
|
@@ -297,11 +572,12 @@ export class UpdateNotificationStore {
|
|
|
297
572
|
}
|
|
298
573
|
async action(scope, id, actionId) {
|
|
299
574
|
const row = this.visible(scope, id);
|
|
300
|
-
|
|
575
|
+
// A Reload in the Updating dialog is offered only while the tab is stale; the action itself never depends on it.
|
|
576
|
+
const action = row ? this.publish(row, scope.tab, true).actions.find((candidate) => candidate.id === actionId) : undefined;
|
|
301
577
|
if (!row || !action)
|
|
302
578
|
return null;
|
|
303
579
|
if (row.performed_action_ids.includes(action.id))
|
|
304
|
-
return
|
|
580
|
+
return this.publish(row, scope.tab, true);
|
|
305
581
|
const stamp = this.now().toISOString();
|
|
306
582
|
row.updated_at = stamp;
|
|
307
583
|
row.read_at ??= stamp;
|
|
@@ -311,14 +587,14 @@ export class UpdateNotificationStore {
|
|
|
311
587
|
row.acknowledged_action_id = action.id;
|
|
312
588
|
}
|
|
313
589
|
await this.save();
|
|
314
|
-
return
|
|
590
|
+
return this.publish(row, scope.tab, true);
|
|
315
591
|
}
|
|
316
592
|
async cancelUpdate(scope, id) {
|
|
317
593
|
const row = this.rows.find((entry) => entry.id === id && this.isVisible(entry, scope) && entry.kind === 'update');
|
|
318
594
|
if (!row)
|
|
319
595
|
return null;
|
|
320
596
|
if (row.phase === 'blocked' && row.message === 'The update was cancelled before installation.')
|
|
321
|
-
return
|
|
597
|
+
return this.publish(row);
|
|
322
598
|
if (row.phase !== 'awaiting_confirmation')
|
|
323
599
|
return null;
|
|
324
600
|
const stamp = this.now().toISOString();
|
|
@@ -327,7 +603,7 @@ export class UpdateNotificationStore {
|
|
|
327
603
|
row.updated_at = stamp;
|
|
328
604
|
row.read_at ??= stamp;
|
|
329
605
|
await this.save();
|
|
330
|
-
return
|
|
606
|
+
return this.publish(row);
|
|
331
607
|
}
|
|
332
608
|
async reconcileInterruptedUpdates(currentWebIdentity, currentWebVersion = null) {
|
|
333
609
|
let changed = false;
|
|
@@ -341,9 +617,18 @@ export class UpdateNotificationStore {
|
|
|
341
617
|
changed = true;
|
|
342
618
|
continue;
|
|
343
619
|
}
|
|
620
|
+
if (row.kind === 'update' && row.agent_operation && row.phase === 'applying') {
|
|
621
|
+
row.phase = 'recovering';
|
|
622
|
+
Object.assign(row, wording('agent', 'recovering'));
|
|
623
|
+
row.updated_at = this.now().toISOString();
|
|
624
|
+
row.read_at = null;
|
|
625
|
+
changed = true;
|
|
626
|
+
continue;
|
|
627
|
+
}
|
|
344
628
|
if (row.kind !== 'update' || (row.target !== 'webui' && row.target !== 'agent') || !['applying', 'restarting'].includes(row.phase))
|
|
345
629
|
continue;
|
|
346
630
|
const phase = row.target === 'webui' && row.phase === 'restarting' && currentWebIdentity && REVISION.test(currentWebIdentity) && row.expected_identity === currentWebIdentity ? 'succeeded' : 'unknown';
|
|
631
|
+
row.failed_step = phase === 'unknown' ? currentStep(row, false) ?? 'install' : null;
|
|
347
632
|
row.phase = phase;
|
|
348
633
|
Object.assign(row, wording(row.target, phase));
|
|
349
634
|
row.updated_at = this.now().toISOString();
|
|
@@ -357,6 +642,44 @@ export class UpdateNotificationStore {
|
|
|
357
642
|
if (changed)
|
|
358
643
|
(await this.save());
|
|
359
644
|
}
|
|
645
|
+
/** TAL-1138: this update's Talaria Web restart is scheduled but has not happened yet. */
|
|
646
|
+
webPending(row) { return row.web_restart_boot === this.boot; }
|
|
647
|
+
/**
|
|
648
|
+
* TAL-1138: a Web update that `tab` started finished while the tab still runs the old build. The tab's Updating
|
|
649
|
+
* dialog offers Reload in place of the separate refresh notice; a later Web update takes that over.
|
|
650
|
+
*/
|
|
651
|
+
reloadsInDialog(row, tab, stale) {
|
|
652
|
+
if (!stale || !tab || row.kind !== 'update' || row.target !== 'webui' || row.phase !== 'succeeded' || !row.watchers.some((watcher) => watcher.tab === tab))
|
|
653
|
+
return false;
|
|
654
|
+
return !this.rows.some((other) => other !== row && other.kind === 'update' && other.target === 'webui' && other.created_at > row.created_at);
|
|
655
|
+
}
|
|
656
|
+
/** The record as clients see it; `tab` and `stale` (its loaded build is not the one served) decide the Reload in its dialog. */
|
|
657
|
+
publish(row, tab = null, stale = false) {
|
|
658
|
+
const webPending = this.webPending(row);
|
|
659
|
+
const reload = this.reloadsInDialog(row, tab, stale);
|
|
660
|
+
const presents = reload || (row.kind === 'update' && row.watchers.length > 0 && (PRESENTING.has(row.phase) || (row.phase === 'waiting_for_idle' && webPending)));
|
|
661
|
+
return {
|
|
662
|
+
id: row.id, kind: row.kind, target: row.target, phase: row.phase, severity: row.severity,
|
|
663
|
+
persistent: row.persistent, requires_acknowledgement: row.requires_acknowledgement,
|
|
664
|
+
// The Restart now action waits for the restarted Web server, which runs the gateway restart.
|
|
665
|
+
actions: reload ? [RELOAD_IN_DIALOG] : row.kind === 'update' && row.phase === 'waiting_for_idle' && webPending ? [] : row.actions,
|
|
666
|
+
destination: row.kind === 'update' && row.phase === 'failed' && row.destination?.key === 'settings.system' ? null : row.destination,
|
|
667
|
+
title: row.title,
|
|
668
|
+
// Old persisted failures still carry the obsolete guidance; correct only that generic copy.
|
|
669
|
+
message: row.kind === 'update' && row.phase === 'failed' && row.message === `${FAILED_MESSAGE} Open System settings for details.` ? FAILED_MESSAGE : row.message,
|
|
670
|
+
created_at: row.created_at, updated_at: row.updated_at, read_at: row.read_at,
|
|
671
|
+
acknowledged_at: row.acknowledged_at, acknowledged_action_id: row.acknowledged_action_id,
|
|
672
|
+
verified_revision: row.verified_revision, verified_version: row.verified_version, detail: row.detail,
|
|
673
|
+
...(row.recovery ? { recovery: row.recovery } : {}),
|
|
674
|
+
unread: row.read_at === null,
|
|
675
|
+
active: ['update', 'agent_recovery'].includes(row.kind) && PRESENTING.has(row.phase),
|
|
676
|
+
requires_interaction: row.requires_acknowledgement && row.acknowledged_at === null,
|
|
677
|
+
can_dismiss: isDismissible(row),
|
|
678
|
+
steps: updateSteps(row, webPending),
|
|
679
|
+
presents_dialog: presents,
|
|
680
|
+
dialog_close: presents ? 'none' : row.kind !== 'update' ? 'close' : row.phase === 'waiting_for_idle' ? 'restart_later' : row.phase === 'succeeded' ? 'auto' : 'close',
|
|
681
|
+
};
|
|
682
|
+
}
|
|
360
683
|
visible(scope, id) {
|
|
361
684
|
return this.rows.find((row) => row.id === id && this.isVisible(row, scope) && row.dismissed_at === null) ?? null;
|
|
362
685
|
}
|
|
@@ -365,6 +688,8 @@ export class UpdateNotificationStore {
|
|
|
365
688
|
return row.tab_id === scope.tab && row.owner === scope.owner && row.profile === scope.profile;
|
|
366
689
|
if (row.visibility === 'server')
|
|
367
690
|
return scope.serverOwner === true && (row.owner === scope.owner || row.owner === '*');
|
|
691
|
+
if (row.owner === '*')
|
|
692
|
+
return scope.serverOwner === true && (row.profile === scope.profile || (row.profile === 'default' && scope.rootProfile === true));
|
|
368
693
|
return row.owner === scope.owner && row.profile === scope.profile;
|
|
369
694
|
}
|
|
370
695
|
hasProtectedCapacity(row) {
|
|
@@ -399,9 +724,11 @@ export class UpdateNotificationStore {
|
|
|
399
724
|
return [];
|
|
400
725
|
const kind = safeToken(row.kind, 'update');
|
|
401
726
|
const target = row.target === 'webui' || row.target === 'agent' ? row.target : null;
|
|
402
|
-
|
|
727
|
+
// TAL-1138: `verifying` is stored as Stable's `restarting` plus a flag Stable ignores.
|
|
728
|
+
const phase = row.phase === 'restarting' && row.recovering === true ? 'recovering' : row.phase === 'restarting' && row.verifying === true ? 'verifying' : safeToken(row.phase, 'unknown');
|
|
403
729
|
const fallback = target && PHASES.has(phase) ? wording(target, phase) : { title: 'Server notification', message: 'This server needs your attention.' };
|
|
404
730
|
return [{
|
|
731
|
+
...(typeof row.notice_key === 'string' ? { notice_key: row.notice_key, notice_text_hash: typeof row.notice_text_hash === 'string' ? row.notice_text_hash : '' } : {}),
|
|
405
732
|
id: row.id, owner: row.owner.slice(0, 256), profile: row.profile.slice(0, 64), visibility: row.visibility === 'profile' ? 'profile' : 'server', kind, target, phase,
|
|
406
733
|
severity: row.severity === 'critical' || row.severity === 'warning' ? row.severity : 'info',
|
|
407
734
|
persistent: row.persistent === true,
|
|
@@ -421,6 +748,12 @@ export class UpdateNotificationStore {
|
|
|
421
748
|
expected_identity: typeof row.expected_identity === 'string' ? row.expected_identity.slice(0, 160) : null,
|
|
422
749
|
tab_id: typeof row.tab_id === 'string' ? row.tab_id : null,
|
|
423
750
|
watchers: Array.isArray(row.watchers) ? row.watchers.flatMap((watcher) => isRecord(watcher) && typeof watcher.tab === 'string' && TAB_ID.test(watcher.tab) && typeof watcher.at === 'string' ? [{ tab: watcher.tab, at: watcher.at }] : []) : [],
|
|
751
|
+
web_restart_boot: typeof row.web_restart_boot === 'string' ? row.web_restart_boot.slice(0, 64) : null,
|
|
752
|
+
gateway_tasks: typeof row.gateway_tasks === 'number' && Number.isInteger(row.gateway_tasks) && row.gateway_tasks > 0 ? row.gateway_tasks : null,
|
|
753
|
+
gateway_baseline: Array.isArray(row.gateway_baseline) ? row.gateway_baseline.slice(0, 8).flatMap((entry) => isRecord(entry) && typeof entry.dir === 'string' && typeof entry.pid === 'number' && Number.isInteger(entry.pid) && entry.pid > 0 && (entry.start_time === null || typeof entry.start_time === 'number') ? [{ dir: entry.dir, pid: entry.pid, start_time: entry.start_time }] : []) : null,
|
|
754
|
+
...(AgentUpdateOperationSchema.safeParse(row.agent_operation).success ? { agent_operation: AgentUpdateOperationSchema.parse(row.agent_operation) } : {}),
|
|
755
|
+
...(AgentUpdateRecoverySchema.safeParse(row.recovery).success ? { recovery: AgentUpdateRecoverySchema.parse(row.recovery) } : {}),
|
|
756
|
+
failed_step: typeof row.failed_step === 'string' && STEP_IDS.has(row.failed_step) ? row.failed_step : null,
|
|
424
757
|
}];
|
|
425
758
|
});
|
|
426
759
|
}
|
|
@@ -452,7 +785,17 @@ export class UpdateNotificationStore {
|
|
|
452
785
|
kept.push(row);
|
|
453
786
|
}
|
|
454
787
|
this.rows = [...kept.reverse(), ...tabNotices];
|
|
455
|
-
|
|
788
|
+
// TAL-1138 fields are written only once set, so records that never use them keep their stored bytes. A check in
|
|
789
|
+
// progress is stored as `restarting`, which the current Stable release counts as active and reconciles on startup.
|
|
790
|
+
const rows = structuredClone(this.rows).map(({ web_restart_boot, gateway_tasks, gateway_baseline, failed_step, ...row }) => ({
|
|
791
|
+
...row,
|
|
792
|
+
...(row.phase === 'verifying' ? { phase: 'restarting', verifying: true } : {}),
|
|
793
|
+
...(row.phase === 'recovering' ? { phase: 'restarting', recovering: true } : {}),
|
|
794
|
+
...(web_restart_boot === null ? {} : { web_restart_boot }),
|
|
795
|
+
...(gateway_tasks === null ? {} : { gateway_tasks }),
|
|
796
|
+
...(gateway_baseline === null ? {} : { gateway_baseline }),
|
|
797
|
+
...(failed_step === null ? {} : { failed_step }),
|
|
798
|
+
}));
|
|
456
799
|
const write = this.writes.catch(() => undefined).then(async () => { this.revision = await this.documents.put('update-notifications', 'update-notifications', rows, this.revision); });
|
|
457
800
|
this.writes = write;
|
|
458
801
|
await write;
|
|
@@ -484,8 +827,9 @@ const safeDestination = (value) => {
|
|
|
484
827
|
const isTabNotice = (row) => row.tab_id !== null;
|
|
485
828
|
/** A waiting gateway restart carries its Restart now action, so it stays until the restart runs. */
|
|
486
829
|
const isWaitingGatewayRestart = (row) => row.kind === 'update' && row.phase === 'waiting_for_idle';
|
|
487
|
-
const isDismissible = (row) => (!row.requires_acknowledgement || row.acknowledged_at !== null) && !isWaitingGatewayRestart(row);
|
|
488
|
-
|
|
830
|
+
const isDismissible = (row) => (!row.requires_acknowledgement || row.acknowledged_at !== null) && !isWaitingGatewayRestart(row) && !(row.kind === 'update' && row.phase === 'recovering');
|
|
831
|
+
/** Warning identities, including dismissed rows, must survive ordinary history pruning. */
|
|
832
|
+
const isProtected = (row) => row.kind === 'agent_warning' || (row.requires_acknowledgement && row.acknowledged_at === null) || (row.kind === 'update' && ['applying', 'awaiting_confirmation', 'waiting_for_idle', 'restarting', 'verifying', 'recovering'].includes(row.phase));
|
|
489
833
|
const retentionBucket = (row) => `${row.owner}\u0000${row.visibility === 'server' ? '*' : row.profile}`;
|
|
490
834
|
export const updateNotificationScopeId = (scope) => createHash('sha256').update(`${scope.owner}\u0000${scope.profile}\u0000${scope.serverOwner === true ? 'owner' : 'member'}`).digest('hex').slice(0, 24);
|
|
491
835
|
//# sourceMappingURL=update-notifications.js.map
|