@maudecode/talaria-web 1.19.0 → 1.20.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 +8 -6
- package/dist/api/automation-router.js +7 -1
- package/dist/api/automation-router.js.map +1 -1
- package/dist/api/chat-router.d.ts +258 -33
- package/dist/api/chat-router.js +60 -25
- package/dist/api/chat-router.js.map +1 -1
- package/dist/api/git-router.d.ts +4 -0
- package/dist/api/git-router.js +1 -1
- 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 +2 -2
- package/dist/api/session-visibility.js +2 -2
- package/dist/api/session-visibility.js.map +1 -1
- package/dist/api/sessions-router.d.ts +787 -107
- package/dist/api/sessions-router.js +16 -4
- 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 +41 -19
- package/dist/api/sse-routes.js.map +1 -1
- package/dist/api/tools-router.d.ts +314 -32
- package/dist/api/tools-router.js +135 -38
- 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 +14 -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.js +38 -14
- package/dist/redact.js.map +1 -1
- package/dist/release.js +5 -3
- package/dist/release.js.map +1 -1
- package/dist/runtime.js +85 -21
- package/dist/runtime.js.map +1 -1
- package/dist/server.js +24 -21
- package/dist/server.js.map +1 -1
- package/dist/sessions/anchor.d.ts +2 -1
- package/dist/sessions/anchor.js +5 -1
- package/dist/sessions/anchor.js.map +1 -1
- package/dist/sessions/background-tasks.d.ts +23 -3
- package/dist/sessions/background-tasks.js +74 -4
- 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/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 +44 -4
- package/dist/sessions/gateway-sessions.js +626 -90
- 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 +11 -5
- package/dist/sessions/merge.js +59 -17
- package/dist/sessions/merge.js.map +1 -1
- package/dist/sessions/prefix-index.d.ts +7 -4
- package/dist/sessions/prefix-index.js +21 -10
- package/dist/sessions/prefix-index.js.map +1 -1
- 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/service.d.ts +107 -37
- package/dist/sessions/service.js +490 -156
- package/dist/sessions/service.js.map +1 -1
- package/dist/sessions/session.d.ts +2 -0
- package/dist/sessions/session.js +4 -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 +70 -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 +5 -1
- package/dist/sessions/store.js +67 -27
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/streams.d.ts +8 -7
- package/dist/sessions/streams.js +49 -14
- package/dist/sessions/streams.js.map +1 -1
- package/dist/sessions/tool-display.d.ts +3 -1
- package/dist/sessions/tool-display.js +6 -0
- 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 +23 -5
- package/dist/sessions/turn.js +168 -78
- 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/mcp-health.js +74 -24
- package/dist/tools/mcp-health.js.map +1 -1
- package/dist/tools/mcp.js +19 -1
- package/dist/tools/mcp.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 +73 -7
- package/dist/tools/update-notifications.js +277 -43
- package/dist/tools/update-notifications.js.map +1 -1
- package/dist/tools/updates.d.ts +8 -1
- package/dist/tools/updates.js +51 -17
- package/dist/tools/updates.js.map +1 -1
- 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 +17 -7
- 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 +17 -14
- 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 +159 -23
- package/sidecar/talaria_sidecar/agent_services.py +74 -11
- 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 +211 -27
- package/sidecar/talaria_sidecar/methods/kanban.py +2 -3
- package/sidecar/talaria_sidecar/methods/oauth.py +139 -11
- 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 +241 -213
- package/static/dist/THIRD_PARTY_LICENSES.md +6 -22
- package/static/dist/assets/AppShell-3isgvoro.js +8 -0
- package/static/dist/assets/Button-f4n6dapf.js +1 -0
- package/static/dist/assets/ChatPage-k7b6xfax.js +4 -0
- package/static/dist/assets/ConnectTargets-juqvt5lm.js +1 -0
- package/static/dist/assets/Dialog-hta5utr3.js +1 -0
- package/static/dist/assets/ExtensionRoute-zrhjn0wm.js +1 -0
- package/static/dist/assets/Field-b6ez48oz.js +1 -0
- package/static/dist/assets/HubRoute-iwvso2tz.js +2 -0
- package/static/dist/assets/LinkCheckContext-ix6zqqkk.js +1 -0
- package/static/dist/assets/Markdown-jdeth7zq.js +2 -0
- package/static/dist/assets/MarkdownRenderer-fbswsgld.js +302 -0
- package/static/dist/assets/MarkdownRenderer-i9o6nr38.css +1 -0
- package/static/dist/assets/OAuthSignIn-bpd8hom3.js +1 -0
- package/static/dist/assets/ResourceSwitch-odi6dy2o.js +1 -0
- package/static/dist/assets/RightPanel-eu6enlo6.js +1 -0
- package/static/dist/assets/Select-kr07928w.js +1 -0
- package/static/dist/assets/SessionListPanel-etb2i54l.js +1 -0
- package/static/dist/assets/SettingsLayout-eu3xxp23.js +1 -0
- package/static/dist/assets/States-icab19yg.js +1 -0
- package/static/dist/assets/TerminalPanel-hngmsr8b.js +16 -0
- package/static/dist/assets/Toaster-nb2uzjw1.js +1 -0
- package/static/dist/assets/_app-ga1moszl.js +1 -0
- package/static/dist/assets/_app.ext._extensionId-na62087t.js +1 -0
- package/static/dist/assets/_app.index-jypgdqoi.js +1 -0
- package/static/dist/assets/_app.insights-kabejdtm.js +1 -0
- package/static/dist/assets/_app.kanban-m19kfcmx.js +1 -0
- package/static/dist/assets/_app.logs-iw4m96sz.js +1 -0
- package/static/dist/assets/_app.memory-jq5frwcg.js +1 -0
- package/static/dist/assets/_app.profiles-kwa3m7rp.js +1 -0
- package/static/dist/assets/_app.session._sessionId-o5lyeipj.js +1 -0
- package/static/dist/assets/_app.settings-ckl8hdll.js +1 -0
- package/static/dist/assets/_app.settings._section-dtdjk98a.js +3 -0
- package/static/dist/assets/_app.skills-n016rihd.js +1 -0
- package/static/dist/assets/_app.tasks-n8zuqsqe.js +1 -0
- package/static/dist/assets/_app.todos-btew5v2s.js +1 -0
- package/static/dist/assets/_app.workspaces-lnfk95ch.js +1 -0
- package/static/dist/assets/abnfDiagram-VCTEODGH-dttheegb.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-ic435919.js +1 -0
- package/static/dist/assets/architectureDiagram-5GKGNRK7-8r3glgiq.js +36 -0
- package/static/dist/assets/archive-il7c6053.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-jenyos6c.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-nzlx7yc4.js} +1 -1
- package/static/dist/assets/cancel-bsnfo36u.js +1 -0
- package/static/dist/assets/channel-dsbtk01y.js +1 -0
- package/static/dist/assets/{chunk-4HAMMTFA-koouqbut.js → chunk-4HAMMTFA-g0cru63b.js} +20 -20
- package/static/dist/assets/{chunk-75Z2AOVW-bl4bhdnt.js → chunk-75Z2AOVW-7rkswkjw.js} +1 -1
- package/static/dist/assets/chunk-DU6HZSFF-fn73jzdo.js +128 -0
- package/static/dist/assets/{chunk-F27PBJKO-d8xxi0zi.js → chunk-F27PBJKO-oey8e72m.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-l2a32wiy.js} +6 -6
- package/static/dist/assets/{chunk-GVQU2GXP-djn6gbyu.js → chunk-GVQU2GXP-o9dwzh8h.js} +1 -1
- package/static/dist/assets/{chunk-IMKFNOWR-vw4p5p7o.js → chunk-IMKFNOWR-eblwj20b.js} +5 -5
- package/static/dist/assets/{chunk-L3NEJ4N5-n1hj77q8.js → chunk-L3NEJ4N5-o2mufspb.js} +1 -1
- package/static/dist/assets/chunk-OSK3NFVY-ijp9pw29.js +10 -0
- package/static/dist/assets/{chunk-P2QGCYS3-onf1hz6c.js → chunk-P2QGCYS3-hs9hqwl4.js} +1 -1
- package/static/dist/assets/{chunk-POPQ4Y6H-m8sqn7cs.js → chunk-POPQ4Y6H-bp9rsqez.js} +1 -1
- package/static/dist/assets/{chunk-PWAF6VOD-ek4smc8x.js → chunk-PWAF6VOD-brkprov6.js} +1 -1
- package/static/dist/assets/{chunk-SHT3W25Y-g9gfvefo.js → chunk-SHT3W25Y-gmpv0pxz.js} +13 -13
- package/static/dist/assets/{chunk-SVP7TREG-f9nfv2cu.js → chunk-SVP7TREG-oldm08fu.js} +4 -4
- package/static/dist/assets/{chunk-TICWLB2K-bnk3m1mq.js → chunk-TICWLB2K-ooqilfv7.js} +6 -6
- package/static/dist/assets/{chunk-XXDRQBXY-n40pf9vy.js → chunk-XXDRQBXY-jkmnqu65.js} +1 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-fvgcv24g.js +1 -0
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-fvgcv24g.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/copied-bz3gkazh.js +1 -0
- package/static/dist/assets/copy-jo006coq.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-d47op7qs.js +1 -0
- package/static/dist/assets/cynefinDiagram-5FMLGOSQ-doa7594y.js +62 -0
- package/static/dist/assets/cytoscape.esm-fjn2algp.js +321 -0
- package/static/dist/assets/dagre-GXQ25YYZ-os768dp4.js +4 -0
- package/static/dist/assets/dagre-o5jmjz46.js +1 -0
- package/static/dist/assets/{diagram-S7CK7UJ4-m6aeoe7c.js → diagram-S7CK7UJ4-fyi81nxd.js} +4 -4
- package/static/dist/assets/diagram-UQ7AKVKN-j3exggaq.js +41 -0
- package/static/dist/assets/{diagram-VSXAHHWV-hbawi7hn.js → diagram-VSXAHHWV-omo1en2l.js} +1 -1
- package/static/dist/assets/diagram-VX7I27RA-oro2cyu0.js +24 -0
- package/static/dist/assets/diagram-Z3DM3KII-byt9vdb7.js +24 -0
- package/static/dist/assets/dist-crc46di9.js +7 -0
- package/static/dist/assets/dist-etpoyscq.js +44 -0
- package/static/dist/assets/{dist-c4c2m3kv.js → dist-nb670eu6.js} +1 -1
- package/static/dist/assets/ebnfDiagram-PWID7BFC-ee3haugh.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-d1e93yff.js +99 -0
- package/static/dist/assets/{erb-idlyfheg.js → erb-flwsv146.js} +1 -1
- package/static/dist/assets/eventmodeling-NTZA5JFV-i1ihb40c.js +1 -0
- package/static/dist/assets/flowDiagram-HODETNUW-jahfpiod.js +1 -0
- package/static/dist/assets/folder-plus-ivoglq98.js +1 -0
- package/static/dist/assets/{ganttDiagram-EL5Y4UJY-ma6jxj5i.js → ganttDiagram-EL5Y4UJY-m7g0jud4.js} +1 -1
- package/static/dist/assets/{git-rebase-d9lpfpbn.js → git-rebase-bli19aoq.js} +1 -1
- package/static/dist/assets/gitGraph-4MIJSDKK-hzdj07yy.js +1 -0
- package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-hzltvsod.js → gitGraphDiagram-WWUBYQGX-dm9agbna.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-mmgz2czu.js +1 -0
- package/static/dist/assets/host-fr6lni1p.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-73649w7o.js +10 -0
- package/static/dist/assets/index-lhf1fsdf.css +2 -0
- package/static/dist/assets/info-A6RAGUB7-lll1dqmm.js +1 -0
- package/static/dist/assets/infoDiagram-27XIBGKW-k7esc639.js +2 -0
- package/static/dist/assets/{ishikawaDiagram-5VMMS53U-e7bnwq7h.js → ishikawaDiagram-5VMMS53U-lgr6k9wo.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-ndmbxuqk.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-mjxym0jp.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-cwb6l7xh.js +1 -0
- package/static/dist/assets/{line-h0ojzsvs.js → line-mtr5k6il.js} +1 -1
- package/static/dist/assets/linear-jlwrvvy6.js +1 -0
- package/static/dist/assets/link-iadw4ghw.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-lkhtzfcl.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-jx0q5dm2.js +1 -0
- package/static/dist/assets/mermaid-parser.core-k91vdnvi.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-ehztfea4.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-f67z0a2r.js +1 -0
- package/static/dist/assets/packet-AYTQ26CC-ok2xrblz.js +1 -0
- package/static/dist/assets/pegDiagram-XKGWAZYB-ec3rpj0m.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-iwkir23u.js +1 -0
- package/static/dist/assets/pieDiagram-E7YTZNPT-fcpqpekh.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-lqsync43.js} +1 -1
- package/static/dist/assets/queryKeys-ed4n2egc.js +9 -0
- package/static/dist/assets/{r-o3r9c7ao.js → r-epfzuw6q.js} +1 -1
- package/static/dist/assets/radar-RG4KPBEZ-hje4jbk6.js +1 -0
- package/static/dist/assets/railroad-74A4TZTK-gll9n6qi.js +1 -0
- package/static/dist/assets/railroad-abnf-HS5TGJTU-o6h6lpn4.js +1 -0
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-juaefj6o.js +1 -0
- package/static/dist/assets/railroad-peg-WCYAUIDC-cgfhvpah.js +1 -0
- package/static/dist/assets/railroadDiagram-O6MQD6OU-lp3w7awf.js +1 -0
- package/static/dist/assets/{razor-ilc585yr.js → razor-pea1u1d0.js} +1 -1
- package/static/dist/assets/refresh-cw-iccm7a4e.js +1 -0
- package/static/dist/assets/refresh-i9ya9dvl.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-ha8eibcf.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-oxf31pr9.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-jiq8lhyo.js} +11 -11
- package/static/dist/assets/settings_section_extensions_title-fadc7o65.js +1 -0
- package/static/dist/assets/share._token-o76ki0ly.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-ddcs88av.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-f3fslnon.js +1 -0
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-hlt6yphw.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-k1hmk7jf.js +1 -0
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-hd5t9tnt.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-n3ncfy9r.js} +8 -8
- package/static/dist/assets/toast-liparz2j.js +56 -0
- package/static/dist/assets/treeView-Q6P3EWNA-l3y2pejt.js +1 -0
- package/static/dist/assets/treemap-WGGIJYW6-jown9axh.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-o4uu74mx.js +1 -0
- package/static/dist/assets/{useParams-gjc70qru.js → useParams-ftsveu84.js} +1 -1
- package/static/dist/assets/{useSearch-e6ae539u.js → useSearch-crqueqga.js} +1 -1
- package/static/dist/assets/vennDiagram-4TSXK5OY-dh59uq1c.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-e6d74b0j.js +1 -0
- package/static/dist/assets/wardleyDiagram-VM6X3IG4-hnofh78f.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-bpymjelb.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,21 @@
|
|
|
1
1
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
2
|
import { readDocument } from '../sessions/storage/document.js';
|
|
3
|
-
|
|
3
|
+
import { str } from '../util.js';
|
|
4
|
+
export function updateNotificationOwner(session) {
|
|
5
|
+
const authType = str(session?.auth_type).trim();
|
|
6
|
+
if (authType === 'oidc') {
|
|
7
|
+
const issuer = str(session?.oidc_issuer).trim();
|
|
8
|
+
const subject = typeof session?.oidc_subject === 'string' ? session.oidc_subject : '';
|
|
9
|
+
if (issuer && subject.trim())
|
|
10
|
+
return `oidc:${createHash('sha256').update(JSON.stringify([issuer, subject]), 'utf8').digest('hex')}`;
|
|
11
|
+
const token = str(session?.token).trim();
|
|
12
|
+
if (token)
|
|
13
|
+
return `oidc-session:${createHash('sha256').update(JSON.stringify([token]), 'utf8').digest('hex')}`;
|
|
14
|
+
}
|
|
15
|
+
const username = str(session?.username).trim();
|
|
16
|
+
return username ? `${authType || 'auth'}:${username}` : 'local-owner';
|
|
17
|
+
}
|
|
18
|
+
const PHASES = new Set(['applying', 'awaiting_confirmation', 'waiting_for_idle', 'restarting', 'verifying', 'succeeded', 'blocked', 'failed', 'unknown']);
|
|
4
19
|
const REVISION = /^[a-f0-9]{40}$/;
|
|
5
20
|
const PER_SCOPE_LIMIT = 50;
|
|
6
21
|
const GLOBAL_LIMIT = 500;
|
|
@@ -14,21 +29,10 @@ const GATEWAY_RESTART_NOW_ACTION = { id: GATEWAY_RESTART_NOW, label: 'Restart no
|
|
|
14
29
|
/** 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
30
|
const TAB_TTL_MS = 60 * 60 * 1000;
|
|
16
31
|
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
|
-
});
|
|
32
|
+
const STEP_IDS = new Set(['install', 'web_restart', 'ready', 'gateway_wait', 'gateway_restart', 'agent_ready']);
|
|
33
|
+
/** Phases in which an update the user started presents its Updating dialog to every tab that can see it. */
|
|
34
|
+
const PRESENTING = new Set(['applying', 'restarting', 'verifying']);
|
|
35
|
+
const TERMINAL_FAILURE = new Set(['failed', 'blocked', 'unknown']);
|
|
32
36
|
/** TAL-953: the waiting gateway restart's message, with the running task count once one is known. */
|
|
33
37
|
const gatewayWaitingMessage = (tasks) => tasks > 0
|
|
34
38
|
? `Waiting for ${String(tasks)} running gateway task${tasks === 1 ? '' : 's'} to finish before restarting the gateway.`
|
|
@@ -40,6 +44,7 @@ const wording = (target, phase) => {
|
|
|
40
44
|
awaiting_confirmation: 'This Hermes Agent revision needs confirmation before it can be installed.',
|
|
41
45
|
waiting_for_idle: gatewayWaitingMessage(0),
|
|
42
46
|
restarting: target === 'webui' ? 'The update is installed. Talaria Web is restarting.' : 'The update is installed. The messaging gateway is restarting.',
|
|
47
|
+
verifying: 'The update is installed. Checking that Hermes Agent responds.',
|
|
43
48
|
succeeded: `${name} was updated successfully.`,
|
|
44
49
|
blocked: 'The update is waiting for active work to finish.',
|
|
45
50
|
failed: FAILED_MESSAGE,
|
|
@@ -47,6 +52,50 @@ const wording = (target, phase) => {
|
|
|
47
52
|
};
|
|
48
53
|
return { title: `${name} update`, message: messages[phase] };
|
|
49
54
|
};
|
|
55
|
+
const RELOAD_IN_DIALOG = { id: WEB_REFRESH_ACTION, label: 'Reload', style: 'primary', acknowledges: false };
|
|
56
|
+
/** Release tags name versions as `web-v1.2.3`; the dialog shows `1.2.3`. */
|
|
57
|
+
const shownVersion = (version) => version ? ` ${version.replace(/^web-(?:exp-)?v/, '')}` : '';
|
|
58
|
+
/** TAL-1138: the step an update is on, or null once it succeeded. `webPending`: its Talaria Web restart has not happened yet. */
|
|
59
|
+
function currentStep(row, webPending) {
|
|
60
|
+
if (TERMINAL_FAILURE.has(row.phase))
|
|
61
|
+
return row.failed_step ?? 'install';
|
|
62
|
+
if (row.phase === 'succeeded')
|
|
63
|
+
return null;
|
|
64
|
+
if (row.phase === 'restarting')
|
|
65
|
+
return row.target === 'webui' ? 'web_restart' : 'gateway_restart';
|
|
66
|
+
if (row.phase === 'waiting_for_idle')
|
|
67
|
+
return webPending ? 'web_restart' : 'gateway_wait';
|
|
68
|
+
if (row.phase === 'verifying')
|
|
69
|
+
return webPending ? 'web_restart' : 'agent_ready';
|
|
70
|
+
return 'install';
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* TAL-1138: the update's steps as the Updating dialog lists them. Web: Installing, Restarting Talaria Web, Ready.
|
|
74
|
+
* Agent: Installing, Restarting Talaria Web, Waiting for gateway tasks (only once the gateway was busy), Restarting
|
|
75
|
+
* gateway, Agent responding. An update that finished without restarting anything lists only the steps it ran.
|
|
76
|
+
*/
|
|
77
|
+
function updateSteps(row, webPending) {
|
|
78
|
+
if (row.kind !== 'update' || !row.target)
|
|
79
|
+
return [];
|
|
80
|
+
const current = currentStep(row, webPending);
|
|
81
|
+
const undecided = ['applying', 'awaiting_confirmation'].includes(row.phase);
|
|
82
|
+
// Each restart step needs its own evidence: a scheduled Web restart, or a gateway restart under way or recorded.
|
|
83
|
+
const webRestarts = undecided || row.web_restart_boot !== null || current === 'web_restart';
|
|
84
|
+
const gatewayRestarts = undecided || ['waiting_for_idle', 'restarting'].includes(row.phase) || row.gateway_baseline !== null || current === 'gateway_wait' || current === 'gateway_restart';
|
|
85
|
+
const succeeded = row.phase === 'succeeded';
|
|
86
|
+
const tasks = row.gateway_tasks ?? 0;
|
|
87
|
+
const plan = row.target === 'webui'
|
|
88
|
+
? [['install', 'Installing'], ...(webRestarts ? [['web_restart', 'Restarting Talaria Web']] : []), ['ready', succeeded ? `Talaria Web${shownVersion(row.verified_version)} is ready` : 'Ready']]
|
|
89
|
+
: [
|
|
90
|
+
['install', 'Installing'],
|
|
91
|
+
...(webRestarts ? [['web_restart', 'Restarting Talaria Web']] : []),
|
|
92
|
+
...(row.gateway_tasks !== null || current === 'gateway_wait' ? [['gateway_wait', tasks > 0 ? `Waiting for ${String(tasks)} gateway task${tasks === 1 ? '' : 's'}` : 'Waiting for gateway tasks']] : []),
|
|
93
|
+
...(gatewayRestarts ? [['gateway_restart', 'Restarting gateway']] : []),
|
|
94
|
+
['agent_ready', succeeded ? `Hermes Agent${shownVersion(row.verified_version)} is running` : 'Agent responding'],
|
|
95
|
+
];
|
|
96
|
+
const at = current === null ? plan.length : plan.findIndex(([id]) => id === current);
|
|
97
|
+
return plan.map(([id, label], index) => ({ id, label, state: index < at ? 'done' : index > at ? 'pending' : TERMINAL_FAILURE.has(row.phase) ? 'failed' : 'active' }));
|
|
98
|
+
}
|
|
50
99
|
export class UpdateNotificationStore {
|
|
51
100
|
documents;
|
|
52
101
|
now;
|
|
@@ -56,12 +105,42 @@ export class UpdateNotificationStore {
|
|
|
56
105
|
/** Last check-in per tab refresh notice; kept in memory so polling never rewrites the store. */
|
|
57
106
|
tabSeen = new Map();
|
|
58
107
|
loadedAt;
|
|
108
|
+
/** This server process; an update whose Web restart another process scheduled has restarted Web. */
|
|
109
|
+
boot = randomUUID();
|
|
59
110
|
constructor(documents, now = () => new Date()) {
|
|
60
111
|
this.documents = documents;
|
|
61
112
|
this.now = now;
|
|
62
113
|
this.loadedAt = this.now().valueOf();
|
|
63
114
|
}
|
|
64
115
|
async initialize() { this.rows = await this.load(); }
|
|
116
|
+
/** Startup warnings outlive any chat or Agent. Repeats retain read/dismissal state until the full text changes. */
|
|
117
|
+
async agentWarning(scope, key, notice) {
|
|
118
|
+
const row = this.rows.find((entry) => entry.kind === 'agent_warning' && entry.notice_key === key && entry.owner === scope.owner && entry.profile === scope.profile);
|
|
119
|
+
if (!notice) {
|
|
120
|
+
if (!row)
|
|
121
|
+
return;
|
|
122
|
+
this.rows = this.rows.filter((entry) => entry !== row);
|
|
123
|
+
return this.save();
|
|
124
|
+
}
|
|
125
|
+
const message = safeText(notice.text, '', 500);
|
|
126
|
+
if (!message)
|
|
127
|
+
return;
|
|
128
|
+
const textHash = createHash('sha256').update(notice.text).digest('hex');
|
|
129
|
+
const severity = notice.level === 'error' ? 'critical' : notice.level === 'warn' ? 'warning' : 'info';
|
|
130
|
+
if (!row) {
|
|
131
|
+
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 });
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
row.updated_at = this.now().toISOString();
|
|
135
|
+
if (row.notice_text_hash !== textHash) {
|
|
136
|
+
row.message = message;
|
|
137
|
+
row.severity = severity;
|
|
138
|
+
row.notice_text_hash = textHash;
|
|
139
|
+
row.read_at = null;
|
|
140
|
+
row.dismissed_at = null;
|
|
141
|
+
}
|
|
142
|
+
await this.save();
|
|
143
|
+
}
|
|
65
144
|
/**
|
|
66
145
|
* Compare the frontend build a tab loaded with the build this server now serves. A mismatch keeps one
|
|
67
146
|
* persistent, tab-scoped refresh notice per tab; a match resolves and removes it. Unknown builds change nothing.
|
|
@@ -84,6 +163,15 @@ export class UpdateNotificationStore {
|
|
|
84
163
|
return state;
|
|
85
164
|
}
|
|
86
165
|
state.refresh_required = true;
|
|
166
|
+
// TAL-1138: the Web update this tab started offers Reload in its own Updating dialog instead.
|
|
167
|
+
if (this.rows.some((row) => this.isVisible(row, scope) && this.reloadsInDialog(row, tab, true))) {
|
|
168
|
+
if (existing) {
|
|
169
|
+
this.rows = this.rows.filter((row) => row !== existing);
|
|
170
|
+
this.tabSeen.delete(existing.id);
|
|
171
|
+
await this.save();
|
|
172
|
+
}
|
|
173
|
+
return state;
|
|
174
|
+
}
|
|
87
175
|
const stamp = this.now().toISOString();
|
|
88
176
|
if (existing) {
|
|
89
177
|
this.tabSeen.set(existing.id, this.now().valueOf());
|
|
@@ -105,6 +193,7 @@ export class UpdateNotificationStore {
|
|
|
105
193
|
created_at: stamp, updated_at: stamp, read_at: null, acknowledged_at: null,
|
|
106
194
|
acknowledged_action_id: null, verified_revision: null, verified_version: null, detail: null,
|
|
107
195
|
performed_action_ids: [], dismissed_at: null, expected_identity: current, tab_id: tab, watchers: [],
|
|
196
|
+
web_restart_boot: null, gateway_tasks: null, gateway_baseline: null, failed_step: null,
|
|
108
197
|
};
|
|
109
198
|
if (!this.hasProtectedCapacity(row))
|
|
110
199
|
return state;
|
|
@@ -158,6 +247,59 @@ export class UpdateNotificationStore {
|
|
|
158
247
|
row.read_at = null;
|
|
159
248
|
await this.save();
|
|
160
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* A question the server asks about one profile (TAL-1274), seen by every server owner while that profile is active. Its
|
|
252
|
+
* open row is refreshed in place; null withdraws it once nothing asks it any more. An answered row stays as history.
|
|
253
|
+
*/
|
|
254
|
+
async profileQuestion(profile, kind, input) {
|
|
255
|
+
const open = this.rows.find((row) => row.kind === kind && row.owner === '*' && row.profile === profile && row.acknowledged_at === null);
|
|
256
|
+
if (!input) {
|
|
257
|
+
if (!open)
|
|
258
|
+
return;
|
|
259
|
+
this.rows = this.rows.filter((row) => row !== open);
|
|
260
|
+
return this.save();
|
|
261
|
+
}
|
|
262
|
+
if (!open) {
|
|
263
|
+
await this.create({ owner: '*', profile, serverOwner: true }, { ...input, kind, requiresAcknowledgement: true });
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
const message = safeText(input.message, '', 500);
|
|
267
|
+
const detail = safeDetail(input.detail);
|
|
268
|
+
if (!message || (open.message === message && open.detail === detail))
|
|
269
|
+
return;
|
|
270
|
+
open.message = message;
|
|
271
|
+
open.detail = detail;
|
|
272
|
+
open.updated_at = this.now().toISOString();
|
|
273
|
+
open.read_at = null;
|
|
274
|
+
await this.save();
|
|
275
|
+
}
|
|
276
|
+
/** Drop all profile-scoped state, including dismissed warning identities, when a profile is deleted. */
|
|
277
|
+
async forgetProfile(profile) {
|
|
278
|
+
const kept = this.rows.filter((row) => !(row.visibility === 'profile' && row.profile === profile));
|
|
279
|
+
if (kept.length === this.rows.length)
|
|
280
|
+
return;
|
|
281
|
+
this.rows = kept;
|
|
282
|
+
await this.save();
|
|
283
|
+
}
|
|
284
|
+
/** The open question `id` of `kind` this scope sees, or null. */
|
|
285
|
+
openQuestion(scope, id, kind) {
|
|
286
|
+
const row = this.visible(scope, id);
|
|
287
|
+
return row?.kind === kind && row.owner === '*' && row.acknowledged_at === null ? this.publish(row, scope.tab) : null;
|
|
288
|
+
}
|
|
289
|
+
/** Record the answer to an open question: its outcome replaces the question, which then leaves only Dismiss. */
|
|
290
|
+
async answerQuestion(scope, id, kind, actionId, outcome) {
|
|
291
|
+
const row = this.visible(scope, id);
|
|
292
|
+
if (row?.kind !== kind || row.owner !== '*' || row.acknowledged_at !== null || !row.actions.some((action) => action.id === actionId))
|
|
293
|
+
return null;
|
|
294
|
+
const stamp = this.now().toISOString();
|
|
295
|
+
Object.assign(row, {
|
|
296
|
+
phase: 'succeeded', severity: 'info', message: safeText(outcome, row.message, 500), detail: null, actions: [],
|
|
297
|
+
updated_at: stamp, read_at: row.read_at ?? stamp, acknowledged_at: stamp, acknowledged_action_id: actionId,
|
|
298
|
+
performed_action_ids: [...row.performed_action_ids, actionId],
|
|
299
|
+
});
|
|
300
|
+
await this.save();
|
|
301
|
+
return this.publish(row, scope.tab);
|
|
302
|
+
}
|
|
161
303
|
/** 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
304
|
async watch(scope, id) {
|
|
163
305
|
const tab = scope.tab && TAB_ID.test(scope.tab) ? scope.tab : null;
|
|
@@ -168,6 +310,9 @@ export class UpdateNotificationStore {
|
|
|
168
310
|
await this.save();
|
|
169
311
|
}
|
|
170
312
|
async create(scope, input) {
|
|
313
|
+
return this.publish(await this.createRow(scope, input));
|
|
314
|
+
}
|
|
315
|
+
async createRow(scope, input, notice = {}) {
|
|
171
316
|
const kind = safeToken(input.kind, '');
|
|
172
317
|
const phase = safeToken(input.phase, '');
|
|
173
318
|
const title = safeText(input.title, '', 160);
|
|
@@ -180,29 +325,37 @@ export class UpdateNotificationStore {
|
|
|
180
325
|
const stamp = this.now().toISOString();
|
|
181
326
|
const row = {
|
|
182
327
|
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',
|
|
328
|
+
...notice, kind, target: input.target ?? null, phase, severity: input.severity ?? 'info',
|
|
184
329
|
persistent: input.requiresAcknowledgement === true || input.persistent === true,
|
|
185
330
|
requires_acknowledgement: input.requiresAcknowledgement === true, actions,
|
|
186
331
|
destination: safeDestination(input.destination), title, message,
|
|
187
332
|
created_at: stamp, updated_at: stamp, read_at: null, acknowledged_at: null,
|
|
188
|
-
acknowledged_action_id: null, verified_revision: null, verified_version: null, detail:
|
|
333
|
+
acknowledged_action_id: null, verified_revision: null, verified_version: null, detail: safeDetail(input.detail),
|
|
189
334
|
performed_action_ids: [], dismissed_at: null, expected_identity: null, tab_id: null, watchers: [],
|
|
335
|
+
web_restart_boot: null, gateway_tasks: null, gateway_baseline: null, failed_step: null,
|
|
190
336
|
};
|
|
191
337
|
if (!this.hasProtectedCapacity(row))
|
|
192
338
|
throw new Error('Update notification protected capacity reached');
|
|
193
339
|
this.rows.push(row);
|
|
194
340
|
await this.save();
|
|
195
|
-
return
|
|
341
|
+
return row;
|
|
196
342
|
}
|
|
197
343
|
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 ?
|
|
344
|
+
const row = [...this.rows].reverse().find((entry) => this.isVisible(entry, scope) && entry.kind === 'update' && entry.target === target && ['applying', 'awaiting_confirmation', 'restarting', 'verifying'].includes(entry.phase));
|
|
345
|
+
return row ? this.publish(row) : null;
|
|
200
346
|
}
|
|
201
347
|
async transition(id, phase, expectedIdentity, verifiedIdentity, detail) {
|
|
202
348
|
const row = this.rows.find((entry) => entry.id === id);
|
|
203
349
|
if (!row)
|
|
204
350
|
return null;
|
|
205
351
|
const phaseChanged = row.phase !== phase;
|
|
352
|
+
// TAL-1138: a failure keeps the step it stopped at, so the dialog marks that step failed.
|
|
353
|
+
if (!TERMINAL_FAILURE.has(phase))
|
|
354
|
+
row.failed_step = null;
|
|
355
|
+
else if (!TERMINAL_FAILURE.has(row.phase))
|
|
356
|
+
row.failed_step = currentStep(row, this.webPending(row)) ?? 'install';
|
|
357
|
+
if (row.kind === 'update' && row.target === 'webui' && phase === 'restarting')
|
|
358
|
+
row.web_restart_boot = this.boot;
|
|
206
359
|
row.phase = phase;
|
|
207
360
|
if (row.target)
|
|
208
361
|
Object.assign(row, wording(row.target, phase));
|
|
@@ -212,7 +365,7 @@ export class UpdateNotificationStore {
|
|
|
212
365
|
if (phaseChanged)
|
|
213
366
|
row.read_at = null;
|
|
214
367
|
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;
|
|
368
|
+
row.detail = phase === 'applying' || phase === 'failed' || phase === 'blocked' || phase === 'succeeded' || phase === 'waiting_for_idle' || phase === 'verifying' ? safeDetail(detail) : null;
|
|
216
369
|
// The gateway restart is server-wide: every server owner sees the wait and can restart now, and a later update joins it.
|
|
217
370
|
if (row.kind === 'update' && phase === 'waiting_for_idle' && row.visibility === 'server')
|
|
218
371
|
row.owner = '*';
|
|
@@ -226,39 +379,63 @@ export class UpdateNotificationStore {
|
|
|
226
379
|
row.verified_version = safeText(verifiedIdentity.version, '', 80) || null;
|
|
227
380
|
}
|
|
228
381
|
await this.save();
|
|
229
|
-
return
|
|
382
|
+
return this.publish(row);
|
|
230
383
|
}
|
|
231
384
|
/** TAL-953: update the waiting gateway restart's message as its running task count changes. */
|
|
232
385
|
async gatewayWaiting(id, tasks) {
|
|
233
386
|
const row = this.rows.find((entry) => entry.id === id && entry.kind === 'update' && entry.phase === 'waiting_for_idle');
|
|
234
387
|
const message = gatewayWaitingMessage(tasks);
|
|
235
|
-
|
|
388
|
+
const counted = tasks > 0 ? tasks : row?.gateway_tasks ?? null;
|
|
389
|
+
if (!row || (row.message === message && row.gateway_tasks === counted))
|
|
236
390
|
return;
|
|
237
391
|
row.message = message;
|
|
392
|
+
row.gateway_tasks = counted;
|
|
238
393
|
row.updated_at = this.now().toISOString();
|
|
239
394
|
await this.save();
|
|
240
395
|
}
|
|
241
|
-
/** TAL-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
396
|
+
/** TAL-1138: this Agent update scheduled a Talaria Web restart; its gateway steps follow the restarted server. */
|
|
397
|
+
async markWebRestart(id) {
|
|
398
|
+
const row = this.rows.find((entry) => entry.id === id && entry.kind === 'update');
|
|
399
|
+
if (!row || row.web_restart_boot === this.boot)
|
|
400
|
+
return;
|
|
401
|
+
row.web_restart_boot = this.boot;
|
|
402
|
+
row.updated_at = this.now().toISOString();
|
|
403
|
+
await this.save();
|
|
245
404
|
}
|
|
246
|
-
|
|
405
|
+
/** TAL-1138: the live gateway processes a restart must replace before the update's check can pass. */
|
|
406
|
+
async recordGatewayBaseline(id, baseline) {
|
|
407
|
+
const row = this.rows.find((entry) => entry.id === id && entry.kind === 'update');
|
|
408
|
+
if (!row)
|
|
409
|
+
return;
|
|
410
|
+
row.gateway_baseline = baseline.slice(0, 8).map((entry) => ({ ...entry }));
|
|
411
|
+
await this.save();
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* TAL-953: gateway restarts still waiting for idle, and (TAL-1138) restarted gateways still being checked, newest
|
|
415
|
+
* first, with the profile each update ran under, so a restarted server resumes them.
|
|
416
|
+
*/
|
|
417
|
+
pendingGatewayRestarts() {
|
|
418
|
+
return this.rows.filter((row) => row.kind === 'update' && (row.phase === 'waiting_for_idle' || row.phase === 'verifying'))
|
|
419
|
+
.sort((a, b) => b.created_at.localeCompare(a.created_at))
|
|
420
|
+
.map((row) => ({ id: row.id, profile: row.profile, detail: row.detail, phase: row.phase, baseline: row.gateway_baseline }));
|
|
421
|
+
}
|
|
422
|
+
/** `stale`: the requesting tab runs an older frontend build than the server serves (`syncTabBuild`'s comparison). */
|
|
423
|
+
async list(scope, stale = false) {
|
|
247
424
|
await this.pruneClosedTabs();
|
|
248
425
|
const scoped = this.rows.filter((row) => this.isVisible(row, scope) && row.dismissed_at === null);
|
|
249
426
|
const ordered = scoped.sort((a, b) => b.updated_at.localeCompare(a.updated_at));
|
|
250
427
|
const protectedRows = ordered.filter(isProtected);
|
|
251
428
|
const visible = [...protectedRows, ...ordered.filter((row) => !isProtected(row)).slice(0, Math.max(0, PER_SCOPE_LIMIT - protectedRows.length))]
|
|
252
429
|
.sort((a, b) => b.updated_at.localeCompare(a.updated_at));
|
|
253
|
-
const notifications = visible.map(copy);
|
|
254
|
-
const clearableCount = scoped.filter(isDismissible).length;
|
|
255
430
|
const tab = scope.tab && TAB_ID.test(scope.tab) ? scope.tab : null;
|
|
431
|
+
const notifications = visible.map((row) => this.publish(row, tab, stale));
|
|
432
|
+
const clearableCount = scoped.filter(isDismissible).length;
|
|
256
433
|
const joinedAt = (row) => row.watchers.find((watcher) => watcher.tab === tab)?.at ?? '';
|
|
257
434
|
const tabUpdate = tab ? this.rows.filter((row) => row.kind === 'update' && joinedAt(row) !== '' && this.isVisible(row, scope))
|
|
258
435
|
.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 ?
|
|
436
|
+
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
437
|
}
|
|
261
|
-
async clear(scope) {
|
|
438
|
+
async clear(scope, stale = false) {
|
|
262
439
|
const stamp = this.now().toISOString();
|
|
263
440
|
let changed = false;
|
|
264
441
|
for (const row of this.rows) {
|
|
@@ -269,7 +446,7 @@ export class UpdateNotificationStore {
|
|
|
269
446
|
}
|
|
270
447
|
if (changed)
|
|
271
448
|
(await this.save());
|
|
272
|
-
return (await this.list(scope));
|
|
449
|
+
return (await this.list(scope, stale));
|
|
273
450
|
}
|
|
274
451
|
async read(scope, id) {
|
|
275
452
|
const row = this.visible(scope, id);
|
|
@@ -279,7 +456,7 @@ export class UpdateNotificationStore {
|
|
|
279
456
|
row.read_at = this.now().toISOString();
|
|
280
457
|
(await this.save());
|
|
281
458
|
}
|
|
282
|
-
return
|
|
459
|
+
return this.publish(row);
|
|
283
460
|
}
|
|
284
461
|
async dismiss(scope, id) {
|
|
285
462
|
const row = this.rows.find((entry) => entry.id === id && this.isVisible(entry, scope));
|
|
@@ -297,11 +474,12 @@ export class UpdateNotificationStore {
|
|
|
297
474
|
}
|
|
298
475
|
async action(scope, id, actionId) {
|
|
299
476
|
const row = this.visible(scope, id);
|
|
300
|
-
|
|
477
|
+
// A Reload in the Updating dialog is offered only while the tab is stale; the action itself never depends on it.
|
|
478
|
+
const action = row ? this.publish(row, scope.tab, true).actions.find((candidate) => candidate.id === actionId) : undefined;
|
|
301
479
|
if (!row || !action)
|
|
302
480
|
return null;
|
|
303
481
|
if (row.performed_action_ids.includes(action.id))
|
|
304
|
-
return
|
|
482
|
+
return this.publish(row, scope.tab, true);
|
|
305
483
|
const stamp = this.now().toISOString();
|
|
306
484
|
row.updated_at = stamp;
|
|
307
485
|
row.read_at ??= stamp;
|
|
@@ -311,14 +489,14 @@ export class UpdateNotificationStore {
|
|
|
311
489
|
row.acknowledged_action_id = action.id;
|
|
312
490
|
}
|
|
313
491
|
await this.save();
|
|
314
|
-
return
|
|
492
|
+
return this.publish(row, scope.tab, true);
|
|
315
493
|
}
|
|
316
494
|
async cancelUpdate(scope, id) {
|
|
317
495
|
const row = this.rows.find((entry) => entry.id === id && this.isVisible(entry, scope) && entry.kind === 'update');
|
|
318
496
|
if (!row)
|
|
319
497
|
return null;
|
|
320
498
|
if (row.phase === 'blocked' && row.message === 'The update was cancelled before installation.')
|
|
321
|
-
return
|
|
499
|
+
return this.publish(row);
|
|
322
500
|
if (row.phase !== 'awaiting_confirmation')
|
|
323
501
|
return null;
|
|
324
502
|
const stamp = this.now().toISOString();
|
|
@@ -327,7 +505,7 @@ export class UpdateNotificationStore {
|
|
|
327
505
|
row.updated_at = stamp;
|
|
328
506
|
row.read_at ??= stamp;
|
|
329
507
|
await this.save();
|
|
330
|
-
return
|
|
508
|
+
return this.publish(row);
|
|
331
509
|
}
|
|
332
510
|
async reconcileInterruptedUpdates(currentWebIdentity, currentWebVersion = null) {
|
|
333
511
|
let changed = false;
|
|
@@ -344,6 +522,7 @@ export class UpdateNotificationStore {
|
|
|
344
522
|
if (row.kind !== 'update' || (row.target !== 'webui' && row.target !== 'agent') || !['applying', 'restarting'].includes(row.phase))
|
|
345
523
|
continue;
|
|
346
524
|
const phase = row.target === 'webui' && row.phase === 'restarting' && currentWebIdentity && REVISION.test(currentWebIdentity) && row.expected_identity === currentWebIdentity ? 'succeeded' : 'unknown';
|
|
525
|
+
row.failed_step = phase === 'unknown' ? currentStep(row, false) ?? 'install' : null;
|
|
347
526
|
row.phase = phase;
|
|
348
527
|
Object.assign(row, wording(row.target, phase));
|
|
349
528
|
row.updated_at = this.now().toISOString();
|
|
@@ -357,6 +536,43 @@ export class UpdateNotificationStore {
|
|
|
357
536
|
if (changed)
|
|
358
537
|
(await this.save());
|
|
359
538
|
}
|
|
539
|
+
/** TAL-1138: this update's Talaria Web restart is scheduled but has not happened yet. */
|
|
540
|
+
webPending(row) { return row.web_restart_boot === this.boot; }
|
|
541
|
+
/**
|
|
542
|
+
* TAL-1138: a Web update that `tab` started finished while the tab still runs the old build. The tab's Updating
|
|
543
|
+
* dialog offers Reload in place of the separate refresh notice; a later Web update takes that over.
|
|
544
|
+
*/
|
|
545
|
+
reloadsInDialog(row, tab, stale) {
|
|
546
|
+
if (!stale || !tab || row.kind !== 'update' || row.target !== 'webui' || row.phase !== 'succeeded' || !row.watchers.some((watcher) => watcher.tab === tab))
|
|
547
|
+
return false;
|
|
548
|
+
return !this.rows.some((other) => other !== row && other.kind === 'update' && other.target === 'webui' && other.created_at > row.created_at);
|
|
549
|
+
}
|
|
550
|
+
/** The record as clients see it; `tab` and `stale` (its loaded build is not the one served) decide the Reload in its dialog. */
|
|
551
|
+
publish(row, tab = null, stale = false) {
|
|
552
|
+
const webPending = this.webPending(row);
|
|
553
|
+
const reload = this.reloadsInDialog(row, tab, stale);
|
|
554
|
+
const presents = reload || (row.kind === 'update' && row.watchers.length > 0 && (PRESENTING.has(row.phase) || (row.phase === 'waiting_for_idle' && webPending)));
|
|
555
|
+
return {
|
|
556
|
+
id: row.id, kind: row.kind, target: row.target, phase: row.phase, severity: row.severity,
|
|
557
|
+
persistent: row.persistent, requires_acknowledgement: row.requires_acknowledgement,
|
|
558
|
+
// The Restart now action waits for the restarted Web server, which runs the gateway restart.
|
|
559
|
+
actions: reload ? [RELOAD_IN_DIALOG] : row.kind === 'update' && row.phase === 'waiting_for_idle' && webPending ? [] : row.actions,
|
|
560
|
+
destination: row.kind === 'update' && row.phase === 'failed' && row.destination?.key === 'settings.system' ? null : row.destination,
|
|
561
|
+
title: row.title,
|
|
562
|
+
// Old persisted failures still carry the obsolete guidance; correct only that generic copy.
|
|
563
|
+
message: row.kind === 'update' && row.phase === 'failed' && row.message === `${FAILED_MESSAGE} Open System settings for details.` ? FAILED_MESSAGE : row.message,
|
|
564
|
+
created_at: row.created_at, updated_at: row.updated_at, read_at: row.read_at,
|
|
565
|
+
acknowledged_at: row.acknowledged_at, acknowledged_action_id: row.acknowledged_action_id,
|
|
566
|
+
verified_revision: row.verified_revision, verified_version: row.verified_version, detail: row.detail,
|
|
567
|
+
unread: row.read_at === null,
|
|
568
|
+
active: ['update', 'agent_recovery'].includes(row.kind) && ['applying', 'restarting', 'verifying'].includes(row.phase),
|
|
569
|
+
requires_interaction: row.requires_acknowledgement && row.acknowledged_at === null,
|
|
570
|
+
can_dismiss: isDismissible(row),
|
|
571
|
+
steps: updateSteps(row, webPending),
|
|
572
|
+
presents_dialog: presents,
|
|
573
|
+
dialog_close: presents ? 'none' : row.kind !== 'update' ? 'close' : row.phase === 'waiting_for_idle' ? 'restart_later' : row.phase === 'succeeded' ? 'auto' : 'close',
|
|
574
|
+
};
|
|
575
|
+
}
|
|
360
576
|
visible(scope, id) {
|
|
361
577
|
return this.rows.find((row) => row.id === id && this.isVisible(row, scope) && row.dismissed_at === null) ?? null;
|
|
362
578
|
}
|
|
@@ -365,6 +581,8 @@ export class UpdateNotificationStore {
|
|
|
365
581
|
return row.tab_id === scope.tab && row.owner === scope.owner && row.profile === scope.profile;
|
|
366
582
|
if (row.visibility === 'server')
|
|
367
583
|
return scope.serverOwner === true && (row.owner === scope.owner || row.owner === '*');
|
|
584
|
+
if (row.owner === '*')
|
|
585
|
+
return scope.serverOwner === true && (row.profile === scope.profile || (row.profile === 'default' && scope.rootProfile === true));
|
|
368
586
|
return row.owner === scope.owner && row.profile === scope.profile;
|
|
369
587
|
}
|
|
370
588
|
hasProtectedCapacity(row) {
|
|
@@ -399,9 +617,11 @@ export class UpdateNotificationStore {
|
|
|
399
617
|
return [];
|
|
400
618
|
const kind = safeToken(row.kind, 'update');
|
|
401
619
|
const target = row.target === 'webui' || row.target === 'agent' ? row.target : null;
|
|
402
|
-
|
|
620
|
+
// TAL-1138: `verifying` is stored as Stable's `restarting` plus a flag Stable ignores.
|
|
621
|
+
const phase = row.phase === 'restarting' && row.verifying === true ? 'verifying' : safeToken(row.phase, 'unknown');
|
|
403
622
|
const fallback = target && PHASES.has(phase) ? wording(target, phase) : { title: 'Server notification', message: 'This server needs your attention.' };
|
|
404
623
|
return [{
|
|
624
|
+
...(typeof row.notice_key === 'string' ? { notice_key: row.notice_key, notice_text_hash: typeof row.notice_text_hash === 'string' ? row.notice_text_hash : '' } : {}),
|
|
405
625
|
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
626
|
severity: row.severity === 'critical' || row.severity === 'warning' ? row.severity : 'info',
|
|
407
627
|
persistent: row.persistent === true,
|
|
@@ -421,6 +641,10 @@ export class UpdateNotificationStore {
|
|
|
421
641
|
expected_identity: typeof row.expected_identity === 'string' ? row.expected_identity.slice(0, 160) : null,
|
|
422
642
|
tab_id: typeof row.tab_id === 'string' ? row.tab_id : null,
|
|
423
643
|
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 }] : []) : [],
|
|
644
|
+
web_restart_boot: typeof row.web_restart_boot === 'string' ? row.web_restart_boot.slice(0, 64) : null,
|
|
645
|
+
gateway_tasks: typeof row.gateway_tasks === 'number' && Number.isInteger(row.gateway_tasks) && row.gateway_tasks > 0 ? row.gateway_tasks : null,
|
|
646
|
+
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,
|
|
647
|
+
failed_step: typeof row.failed_step === 'string' && STEP_IDS.has(row.failed_step) ? row.failed_step : null,
|
|
424
648
|
}];
|
|
425
649
|
});
|
|
426
650
|
}
|
|
@@ -452,7 +676,16 @@ export class UpdateNotificationStore {
|
|
|
452
676
|
kept.push(row);
|
|
453
677
|
}
|
|
454
678
|
this.rows = [...kept.reverse(), ...tabNotices];
|
|
455
|
-
|
|
679
|
+
// TAL-1138 fields are written only once set, so records that never use them keep their stored bytes. A check in
|
|
680
|
+
// progress is stored as `restarting`, which the current Stable release counts as active and reconciles on startup.
|
|
681
|
+
const rows = structuredClone(this.rows).map(({ web_restart_boot, gateway_tasks, gateway_baseline, failed_step, ...row }) => ({
|
|
682
|
+
...row,
|
|
683
|
+
...(row.phase === 'verifying' ? { phase: 'restarting', verifying: true } : {}),
|
|
684
|
+
...(web_restart_boot === null ? {} : { web_restart_boot }),
|
|
685
|
+
...(gateway_tasks === null ? {} : { gateway_tasks }),
|
|
686
|
+
...(gateway_baseline === null ? {} : { gateway_baseline }),
|
|
687
|
+
...(failed_step === null ? {} : { failed_step }),
|
|
688
|
+
}));
|
|
456
689
|
const write = this.writes.catch(() => undefined).then(async () => { this.revision = await this.documents.put('update-notifications', 'update-notifications', rows, this.revision); });
|
|
457
690
|
this.writes = write;
|
|
458
691
|
await write;
|
|
@@ -485,7 +718,8 @@ const isTabNotice = (row) => row.tab_id !== null;
|
|
|
485
718
|
/** A waiting gateway restart carries its Restart now action, so it stays until the restart runs. */
|
|
486
719
|
const isWaitingGatewayRestart = (row) => row.kind === 'update' && row.phase === 'waiting_for_idle';
|
|
487
720
|
const isDismissible = (row) => (!row.requires_acknowledgement || row.acknowledged_at !== null) && !isWaitingGatewayRestart(row);
|
|
488
|
-
|
|
721
|
+
/** Warning identities, including dismissed rows, must survive ordinary history pruning. */
|
|
722
|
+
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'].includes(row.phase));
|
|
489
723
|
const retentionBucket = (row) => `${row.owner}\u0000${row.visibility === 'server' ? '*' : row.profile}`;
|
|
490
724
|
export const updateNotificationScopeId = (scope) => createHash('sha256').update(`${scope.owner}\u0000${scope.profile}\u0000${scope.serverOwner === true ? 'owner' : 'member'}`).digest('hex').slice(0, 24);
|
|
491
725
|
//# sourceMappingURL=update-notifications.js.map
|