@maudecode/talaria-web 1.18.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/auth-raw.js +16 -16
- package/dist/api/auth-raw.js.map +1 -1
- package/dist/api/automation-raw.d.ts +2 -2
- package/dist/api/automation-raw.js +93 -38
- package/dist/api/automation-raw.js.map +1 -1
- package/dist/api/automation-router.d.ts +99 -17
- package/dist/api/automation-router.js +22 -14
- package/dist/api/automation-router.js.map +1 -1
- package/dist/api/chat-router.d.ts +1433 -37
- package/dist/api/chat-router.js +205 -90
- package/dist/api/chat-router.js.map +1 -1
- package/dist/api/git-router.d.ts +6 -2
- package/dist/api/git-router.js +30 -30
- package/dist/api/git-router.js.map +1 -1
- package/dist/api/raw-routes.d.ts +3 -3
- package/dist/api/raw-routes.js +76 -62
- package/dist/api/raw-routes.js.map +1 -1
- package/dist/api/router.d.ts +5 -5
- package/dist/api/router.js +22 -22
- package/dist/api/router.js.map +1 -1
- package/dist/api/session-visibility.d.ts +4 -4
- package/dist/api/session-visibility.js +26 -16
- package/dist/api/session-visibility.js.map +1 -1
- package/dist/api/sessions-router.d.ts +2635 -151
- package/dist/api/sessions-router.js +193 -177
- package/dist/api/sessions-router.js.map +1 -1
- package/dist/api/settings-router.d.ts +450 -11
- package/dist/api/settings-router.js +102 -49
- package/dist/api/settings-router.js.map +1 -1
- package/dist/api/sse-routes.d.ts +2 -2
- package/dist/api/sse-routes.js +102 -80
- package/dist/api/sse-routes.js.map +1 -1
- package/dist/api/tools-raw.d.ts +5 -0
- package/dist/api/tools-raw.js +58 -33
- package/dist/api/tools-raw.js.map +1 -1
- package/dist/api/tools-router.d.ts +963 -109
- package/dist/api/tools-router.js +426 -72
- package/dist/api/tools-router.js.map +1 -1
- package/dist/api/transcribe-stream.d.ts +16 -0
- package/dist/api/transcribe-stream.js +172 -0
- package/dist/api/transcribe-stream.js.map +1 -0
- package/dist/app.d.ts +4 -1
- package/dist/app.js +80 -57
- 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 +14 -9
- package/dist/auth/gate.js.map +1 -1
- package/dist/auth/passkeys.d.ts +15 -14
- package/dist/auth/passkeys.js +89 -91
- package/dist/auth/passkeys.js.map +1 -1
- package/dist/auth/store.d.ts +17 -7
- package/dist/auth/store.js +93 -52
- package/dist/auth/store.js.map +1 -1
- package/dist/bin/talaria-web.js +12 -81
- package/dist/bin/talaria-web.js.map +1 -1
- package/dist/cli/ctl.js +8 -2
- package/dist/cli/ctl.js.map +1 -1
- package/dist/cli/dotenv.d.ts +5 -0
- package/dist/cli/dotenv.js +14 -2
- package/dist/cli/dotenv.js.map +1 -1
- package/dist/cli/launcher.js +5 -5
- package/dist/cli/launcher.js.map +1 -1
- package/dist/cli/main.d.ts +1 -0
- package/dist/cli/main.js +90 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/supervise.d.ts +24 -0
- package/dist/cli/supervise.js +147 -6
- package/dist/cli/supervise.js.map +1 -1
- package/dist/config/agent-config.d.ts +37 -11
- package/dist/config/agent-config.js +146 -64
- package/dist/config/agent-config.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.js +14 -5
- package/dist/config.js.map +1 -1
- package/dist/fs/atomic.d.ts +4 -0
- package/dist/fs/atomic.js +19 -2
- package/dist/fs/atomic.js.map +1 -1
- package/dist/fs/stat.d.ts +7 -0
- package/dist/fs/stat.js +27 -0
- package/dist/fs/stat.js.map +1 -0
- package/dist/http/context.d.ts +28 -9
- package/dist/http/context.js +77 -25
- package/dist/http/context.js.map +1 -1
- package/dist/onboarding.d.ts +2 -2
- package/dist/onboarding.js +10 -8
- package/dist/onboarding.js.map +1 -1
- package/dist/profiles/profiles.d.ts +12 -4
- package/dist/profiles/profiles.js +78 -30
- package/dist/profiles/profiles.js.map +1 -1
- package/dist/projects.d.ts +15 -6
- package/dist/projects.js +55 -47
- package/dist/projects.js.map +1 -1
- package/dist/providers/catalog.d.ts +85 -14
- package/dist/providers/catalog.js +502 -146
- package/dist/providers/catalog.js.map +1 -1
- package/dist/providers/env-file.d.ts +10 -3
- package/dist/providers/env-file.js +24 -75
- package/dist/providers/env-file.js.map +1 -1
- package/dist/providers/runtime-env.d.ts +4 -2
- package/dist/providers/runtime-env.js +9 -6
- package/dist/providers/runtime-env.js.map +1 -1
- package/dist/providers/tables.d.ts +3 -1
- package/dist/providers/tables.js +4 -2
- package/dist/providers/tables.js.map +1 -1
- package/dist/redact.js +56 -23
- package/dist/redact.js.map +1 -1
- package/dist/release.d.ts +7 -0
- package/dist/release.js +19 -3
- package/dist/release.js.map +1 -1
- package/dist/runtime.d.ts +5 -1
- package/dist/runtime.js +303 -96
- package/dist/runtime.js.map +1 -1
- package/dist/server.js +31 -18
- package/dist/server.js.map +1 -1
- package/dist/sessions/anchor.d.ts +11 -4
- package/dist/sessions/anchor.js +33 -37
- package/dist/sessions/anchor.js.map +1 -1
- package/dist/sessions/background-events.d.ts +2 -0
- package/dist/sessions/background-events.js +10 -0
- package/dist/sessions/background-events.js.map +1 -0
- package/dist/sessions/background-tasks.d.ts +49 -23
- package/dist/sessions/background-tasks.js +161 -89
- package/dist/sessions/background-tasks.js.map +1 -1
- package/dist/sessions/background-updates.d.ts +15 -8
- package/dist/sessions/background-updates.js +101 -25
- package/dist/sessions/background-updates.js.map +1 -1
- package/dist/sessions/cli-sessions.d.ts +23 -6
- package/dist/sessions/cli-sessions.js +84 -84
- package/dist/sessions/cli-sessions.js.map +1 -1
- package/dist/sessions/completions.d.ts +38 -2
- package/dist/sessions/completions.js +348 -77
- package/dist/sessions/completions.js.map +1 -1
- package/dist/sessions/compress.d.ts +8 -0
- package/dist/sessions/compress.js +2 -2
- package/dist/sessions/compress.js.map +1 -1
- package/dist/sessions/drafts.d.ts +14 -10
- package/dist/sessions/drafts.js +38 -43
- package/dist/sessions/drafts.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 +86 -0
- package/dist/sessions/gateway-sessions.js +914 -0
- package/dist/sessions/gateway-sessions.js.map +1 -0
- 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/goals.d.ts +31 -0
- package/dist/sessions/goals.js +75 -0
- package/dist/sessions/goals.js.map +1 -0
- package/dist/sessions/journal.d.ts +5 -79
- package/dist/sessions/journal.js +15 -606
- package/dist/sessions/journal.js.map +1 -1
- package/dist/sessions/list.d.ts +34 -18
- package/dist/sessions/list.js +161 -147
- package/dist/sessions/list.js.map +1 -1
- package/dist/sessions/merge.d.ts +77 -13
- package/dist/sessions/merge.js +315 -65
- package/dist/sessions/merge.js.map +1 -1
- package/dist/sessions/notices.d.ts +22 -0
- package/dist/sessions/notices.js +72 -0
- package/dist/sessions/notices.js.map +1 -0
- package/dist/sessions/pending.d.ts +10 -4
- package/dist/sessions/pending.js +83 -7
- package/dist/sessions/pending.js.map +1 -1
- package/dist/sessions/prefix-index.d.ts +85 -0
- package/dist/sessions/prefix-index.js +243 -0
- package/dist/sessions/prefix-index.js.map +1 -0
- package/dist/sessions/recovery.d.ts +4 -7
- package/dist/sessions/recovery.js +100 -283
- package/dist/sessions/recovery.js.map +1 -1
- package/dist/sessions/relay.d.ts +20 -20
- package/dist/sessions/relay.js +205 -127
- package/dist/sessions/relay.js.map +1 -1
- package/dist/sessions/service.d.ts +251 -78
- package/dist/sessions/service.js +1510 -564
- package/dist/sessions/service.js.map +1 -1
- package/dist/sessions/session.d.ts +20 -2
- package/dist/sessions/session.js +33 -5
- package/dist/sessions/session.js.map +1 -1
- package/dist/sessions/shares.d.ts +7 -6
- package/dist/sessions/shares.js +22 -45
- package/dist/sessions/shares.js.map +1 -1
- package/dist/sessions/source-kind.js +1 -0
- package/dist/sessions/source-kind.js.map +1 -1
- package/dist/sessions/state-db-identity.d.ts +18 -0
- package/dist/sessions/state-db-identity.js +67 -0
- package/dist/sessions/state-db-identity.js.map +1 -0
- package/dist/sessions/state-db-worker.js +24 -5
- package/dist/sessions/state-db-worker.js.map +1 -1
- package/dist/sessions/state-db.d.ts +157 -21
- package/dist/sessions/state-db.js +1145 -204
- 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 +171 -0
- package/dist/sessions/storage/backend.js +19 -0
- package/dist/sessions/storage/backend.js.map +1 -0
- package/dist/sessions/storage/conformance.d.ts +20 -0
- package/dist/sessions/storage/conformance.js +237 -0
- package/dist/sessions/storage/conformance.js.map +1 -0
- package/dist/sessions/storage/document.d.ts +16 -0
- package/dist/sessions/storage/document.js +44 -0
- package/dist/sessions/storage/document.js.map +1 -0
- package/dist/sessions/storage/json-documents.d.ts +25 -0
- package/dist/sessions/storage/json-documents.js +277 -0
- package/dist/sessions/storage/json-documents.js.map +1 -0
- package/dist/sessions/storage/json-files.d.ts +23 -0
- package/dist/sessions/storage/json-files.js +244 -0
- package/dist/sessions/storage/json-files.js.map +1 -0
- package/dist/sessions/storage/json-installation.d.ts +3 -0
- package/dist/sessions/storage/json-installation.js +31 -0
- package/dist/sessions/storage/json-installation.js.map +1 -0
- package/dist/sessions/storage/json-journal.d.ts +113 -0
- package/dist/sessions/storage/json-journal.js +756 -0
- package/dist/sessions/storage/json-journal.js.map +1 -0
- package/dist/sessions/storage/json-recovery.d.ts +4 -0
- package/dist/sessions/storage/json-recovery.js +195 -0
- package/dist/sessions/storage/json-recovery.js.map +1 -0
- package/dist/sessions/storage/json.d.ts +82 -0
- package/dist/sessions/storage/json.js +350 -0
- package/dist/sessions/storage/json.js.map +1 -0
- package/dist/sessions/storage/row.d.ts +6 -0
- package/dist/sessions/storage/row.js +49 -0
- package/dist/sessions/storage/row.js.map +1 -0
- package/dist/sessions/storage/search-text.d.ts +4 -0
- package/dist/sessions/storage/search-text.js +16 -0
- package/dist/sessions/storage/search-text.js.map +1 -0
- package/dist/sessions/store.d.ts +67 -73
- package/dist/sessions/store.js +341 -607
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/streams.d.ts +12 -7
- package/dist/sessions/streams.js +58 -15
- package/dist/sessions/streams.js.map +1 -1
- package/dist/sessions/titles.js +1 -1
- package/dist/sessions/titles.js.map +1 -1
- package/dist/sessions/todo.d.ts +5 -0
- package/dist/sessions/todo.js +28 -21
- package/dist/sessions/todo.js.map +1 -1
- package/dist/sessions/tool-display.d.ts +8 -5
- package/dist/sessions/tool-display.js +28 -16
- package/dist/sessions/tool-display.js.map +1 -1
- package/dist/sessions/turn-context.d.ts +10 -1
- package/dist/sessions/turn-context.js +13 -6
- package/dist/sessions/turn-context.js.map +1 -1
- package/dist/sessions/turn.d.ts +110 -22
- package/dist/sessions/turn.js +918 -380
- package/dist/sessions/turn.js.map +1 -1
- package/dist/sessions/wakeup-pause.d.ts +8 -13
- package/dist/sessions/wakeup-pause.js +31 -49
- package/dist/sessions/wakeup-pause.js.map +1 -1
- package/dist/sessions/window.js +13 -12
- package/dist/sessions/window.js.map +1 -1
- package/dist/settings.d.ts +19 -7
- package/dist/settings.js +179 -183
- package/dist/settings.js.map +1 -1
- package/dist/sidecar/client.d.ts +41 -4
- package/dist/sidecar/client.js +192 -42
- package/dist/sidecar/client.js.map +1 -1
- package/dist/sidecar/discover.d.ts +2 -1
- package/dist/sidecar/discover.js +93 -10
- package/dist/sidecar/discover.js.map +1 -1
- package/dist/sidecar/env.d.ts +4 -0
- package/dist/sidecar/env.js +3 -0
- package/dist/sidecar/env.js.map +1 -0
- package/dist/sidecar/fake.d.ts +6 -2
- package/dist/sidecar/fake.js +34 -4
- 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/env-file.d.ts +5 -0
- package/dist/test/env-file.js +88 -0
- package/dist/test/env-file.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/test/harness.d.ts +1 -0
- package/dist/test/harness.js +1 -1
- package/dist/test/harness.js.map +1 -1
- package/dist/test/passkeys.d.ts +22 -0
- package/dist/test/passkeys.js +62 -0
- package/dist/test/passkeys.js.map +1 -0
- package/dist/test/storage.d.ts +15 -0
- package/dist/test/storage.js +26 -0
- package/dist/test/storage.js.map +1 -0
- package/dist/tools/commands.d.ts +6 -1
- package/dist/tools/commands.js +8 -2
- package/dist/tools/commands.js.map +1 -1
- package/dist/tools/connectors.d.ts +33 -0
- package/dist/tools/connectors.js +121 -0
- package/dist/tools/connectors.js.map +1 -0
- package/dist/tools/crons.d.ts +46 -5
- package/dist/tools/crons.js +100 -26
- package/dist/tools/crons.js.map +1 -1
- package/dist/tools/dashboard-plugins.d.ts +34 -5
- package/dist/tools/dashboard-plugins.js +146 -14
- package/dist/tools/dashboard-plugins.js.map +1 -1
- package/dist/tools/extensions.d.ts +5 -4
- package/dist/tools/extensions.js +213 -207
- package/dist/tools/extensions.js.map +1 -1
- package/dist/tools/gateway-restart.d.ts +82 -0
- package/dist/tools/gateway-restart.js +222 -0
- package/dist/tools/gateway-restart.js.map +1 -0
- package/dist/tools/health.d.ts +28 -4
- package/dist/tools/health.js +171 -50
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/hygiene.d.ts +4 -3
- package/dist/tools/hygiene.js +23 -9
- package/dist/tools/hygiene.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 +4 -2
- package/dist/tools/kanban.js +28 -19
- 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.js +19 -1
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/memory-masks.d.ts +5 -0
- package/dist/tools/memory-masks.js +256 -0
- package/dist/tools/memory-masks.js.map +1 -0
- package/dist/tools/memory.d.ts +29 -3
- package/dist/tools/memory.js +69 -27
- 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/plugin-settings.d.ts +15 -0
- package/dist/tools/plugin-settings.js +90 -0
- package/dist/tools/plugin-settings.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 +13 -5
- package/dist/tools/skills.js +53 -19
- package/dist/tools/skills.js.map +1 -1
- package/dist/tools/update-notifications.d.ts +102 -17
- package/dist/tools/update-notifications.js +400 -82
- package/dist/tools/update-notifications.js.map +1 -1
- package/dist/tools/update-rollback.d.ts +11 -0
- package/dist/tools/update-rollback.js +28 -0
- package/dist/tools/update-rollback.js.map +1 -0
- package/dist/tools/updates.d.ts +100 -33
- package/dist/tools/updates.js +1085 -345
- package/dist/tools/updates.js.map +1 -1
- package/dist/util.d.ts +2 -0
- package/dist/util.js +5 -0
- package/dist/util.js.map +1 -1
- package/dist/workspace/git.d.ts +16 -1
- package/dist/workspace/git.js +291 -11
- package/dist/workspace/git.js.map +1 -1
- package/dist/workspace/media.d.ts +12 -9
- package/dist/workspace/media.js +98 -38
- 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 +8 -4
- package/dist/workspace/rollback.js +22 -12
- package/dist/workspace/rollback.js.map +1 -1
- package/dist/workspace/workspaces.d.ts +15 -19
- package/dist/workspace/workspaces.js +55 -127
- package/dist/workspace/workspaces.js.map +1 -1
- package/dist/workspace/worktrees.js +170 -32
- package/dist/workspace/worktrees.js.map +1 -1
- package/package.json +6 -4
- package/sidecar/agent_dependency.json +4 -4
- package/sidecar/agent_support.json +29 -0
- package/sidecar/scripts/record-fixtures.py +12 -3
- package/sidecar/scripts/replay_sidecar.py +8 -0
- package/sidecar/scripts/suite_runner.py +458 -0
- package/sidecar/scripts/test.sh +11 -5
- package/sidecar/talaria_sidecar/__init__.py +6 -1
- package/sidecar/talaria_sidecar/__main__.py +13 -4
- package/sidecar/talaria_sidecar/agent_mutation.py +1111 -0
- package/sidecar/talaria_sidecar/agent_services.py +1116 -0
- package/sidecar/talaria_sidecar/context_detail.py +59 -0
- package/sidecar/talaria_sidecar/dependency_sync.py +85 -0
- package/sidecar/talaria_sidecar/home.py +133 -14
- package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
- package/sidecar/talaria_sidecar/methods/aux.py +211 -41
- package/sidecar/talaria_sidecar/methods/chat.py +1378 -200
- package/sidecar/talaria_sidecar/methods/checkpoints.py +29 -4
- package/sidecar/talaria_sidecar/methods/commands.py +483 -13
- package/sidecar/talaria_sidecar/methods/config.py +195 -6
- package/sidecar/talaria_sidecar/methods/connectors.py +375 -0
- package/sidecar/talaria_sidecar/methods/cron.py +374 -36
- package/sidecar/talaria_sidecar/methods/cron_execution.py +284 -0
- package/sidecar/talaria_sidecar/methods/dashboard_plugins.py +301 -0
- package/sidecar/talaria_sidecar/methods/gateway.py +215 -55
- package/sidecar/talaria_sidecar/methods/gateway_sessions.py +418 -0
- package/sidecar/talaria_sidecar/methods/goals.py +81 -41
- package/sidecar/talaria_sidecar/methods/kanban.py +82 -30
- package/sidecar/talaria_sidecar/methods/memory.py +84 -0
- package/sidecar/talaria_sidecar/methods/oauth.py +144 -13
- 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 +229 -16
- package/sidecar/talaria_sidecar/methods/profiles.py +48 -9
- package/sidecar/talaria_sidecar/methods/providers.py +196 -26
- package/sidecar/talaria_sidecar/methods/runtime.py +71 -1
- package/sidecar/talaria_sidecar/methods/skills.py +83 -5
- package/sidecar/talaria_sidecar/methods/state_db.py +405 -112
- package/sidecar/talaria_sidecar/methods/stt.py +159 -78
- package/sidecar/talaria_sidecar/methods/text.py +14 -1
- package/sidecar/talaria_sidecar/methods/toolsets.py +51 -0
- package/sidecar/talaria_sidecar/methods/usage.py +113 -14
- package/sidecar/talaria_sidecar/methods/worktree.py +145 -19
- package/sidecar/talaria_sidecar/methods/write_approval.py +181 -0
- package/sidecar/talaria_sidecar/rpc.py +70 -7
- package/sidecar/talaria_sidecar/runtime.py +122 -14
- package/sidecar/talaria_sidecar/speed.py +47 -0
- package/sidecar/talaria_sidecar/startup_timing.py +119 -0
- package/static/dist/FILES.txt +242 -215
- 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-jzthp1wa.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-mwr67mt8.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-gpq1y228.js → chunk-4HAMMTFA-g0cru63b.js} +20 -20
- package/static/dist/assets/{chunk-75Z2AOVW-ktje58c4.js → chunk-75Z2AOVW-7rkswkjw.js} +1 -1
- package/static/dist/assets/chunk-DU6HZSFF-fn73jzdo.js +128 -0
- package/static/dist/assets/{chunk-F27PBJKO-cmev85ti.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-htjgt22y.js → chunk-GMAD6QVW-l2a32wiy.js} +6 -6
- package/static/dist/assets/{chunk-GVQU2GXP-qndvoxl7.js → chunk-GVQU2GXP-o9dwzh8h.js} +1 -1
- package/static/dist/assets/{chunk-IMKFNOWR-e5bkd5q6.js → chunk-IMKFNOWR-eblwj20b.js} +5 -5
- package/static/dist/assets/{chunk-L3NEJ4N5-mj1155r6.js → chunk-L3NEJ4N5-o2mufspb.js} +1 -1
- package/static/dist/assets/chunk-OSK3NFVY-ijp9pw29.js +10 -0
- package/static/dist/assets/{chunk-P2QGCYS3-f7t54xfm.js → chunk-P2QGCYS3-hs9hqwl4.js} +1 -1
- package/static/dist/assets/{chunk-POPQ4Y6H-i927v9oa.js → chunk-POPQ4Y6H-bp9rsqez.js} +1 -1
- package/static/dist/assets/{chunk-PWAF6VOD-m84lmnyt.js → chunk-PWAF6VOD-brkprov6.js} +1 -1
- package/static/dist/assets/{chunk-SHT3W25Y-mi0tlcu9.js → chunk-SHT3W25Y-gmpv0pxz.js} +13 -13
- package/static/dist/assets/{chunk-SVP7TREG-dnau702j.js → chunk-SVP7TREG-oldm08fu.js} +4 -4
- package/static/dist/assets/{chunk-TICWLB2K-edem1gkg.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-l8abxaes.js → diagram-S7CK7UJ4-fyi81nxd.js} +4 -4
- package/static/dist/assets/diagram-UQ7AKVKN-j3exggaq.js +41 -0
- package/static/dist/assets/{diagram-VSXAHHWV-fnky6lvc.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-ngbsyp37.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-eravdti4.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-i6ypq351.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-lduf1z95.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-e18bu4pg.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-meizqsvn.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-27b26eok.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/pcmTap.worklet-74EKjWAZ.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-hhue7d8o.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-fqb8xcjf.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-dlcz6qjz.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-b1vl2zil.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-b4dq6n4q.js → useParams-ftsveu84.js} +1 -1
- package/static/dist/assets/{useSearch-ipfmv3he.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-e49523ab.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-g3bkgnvt.js +0 -1
- package/static/dist/assets/ChatPage-oo7bdan6.js +0 -25
- package/static/dist/assets/Dialog-g355qxhp.js +0 -1
- package/static/dist/assets/ExtensionRoute-i2y9fvjm.js +0 -1
- package/static/dist/assets/HubRoute-lmkrbw47.js +0 -2
- package/static/dist/assets/Markdown-j4kut4j2.js +0 -598
- package/static/dist/assets/Markdown-lwviulmg.css +0 -1
- package/static/dist/assets/RightPanel-ohlsdzfl.js +0 -1
- package/static/dist/assets/Select-kddq75qc.js +0 -1
- package/static/dist/assets/SessionListPanel-lu3oy0hw.js +0 -1
- package/static/dist/assets/SettingsLayout-o9bv4mgb.js +0 -1
- package/static/dist/assets/States-eq6fe29m.js +0 -1
- package/static/dist/assets/Toaster-pc247u9f.js +0 -1
- package/static/dist/assets/_app-f8n1i0m1.js +0 -1
- package/static/dist/assets/_app.ext._extensionId-gfbzpoou.js +0 -1
- package/static/dist/assets/_app.index-bzzv80hk.js +0 -1
- package/static/dist/assets/_app.insights-dzixbryi.js +0 -1
- package/static/dist/assets/_app.kanban-c6hep2us.js +0 -1
- package/static/dist/assets/_app.logs-i69qds98.js +0 -1
- package/static/dist/assets/_app.memory-kl4vf0gd.js +0 -1
- package/static/dist/assets/_app.profiles-b8zinmyp.js +0 -1
- package/static/dist/assets/_app.session._sessionId-fn1bhde6.js +0 -1
- package/static/dist/assets/_app.settings-cg8plwmf.js +0 -1
- package/static/dist/assets/_app.settings._section-bkwbi9zn.js +0 -3
- package/static/dist/assets/_app.skills-cs47sbvs.js +0 -1
- package/static/dist/assets/_app.tasks-dwvk64tc.js +0 -1
- package/static/dist/assets/_app.todos-c8xjm8p3.js +0 -1
- package/static/dist/assets/_app.workspaces-ehvd1gds.js +0 -1
- package/static/dist/assets/abnfDiagram-VCTEODGH-c8kdixke.js +0 -1
- package/static/dist/assets/architecture-7GRP2DOG-6crvnylg.js +0 -1
- package/static/dist/assets/architectureDiagram-5GKGNRK7-cku06x1p.js +0 -36
- package/static/dist/assets/back-h7aun7ew.js +0 -1
- package/static/dist/assets/cancel-fhi0vcnu.js +0 -1
- package/static/dist/assets/channel-b2zo73z1.js +0 -1
- package/static/dist/assets/chunk-DU6HZSFF-ofajdixh.js +0 -128
- package/static/dist/assets/chunk-OSK3NFVY-e7gkikcw.js +0 -10
- package/static/dist/assets/classDiagram-ZZMXUADV-oe99st8x.js +0 -1
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-oe99st8x.js +0 -1
- package/static/dist/assets/copied-hcplv46p.js +0 -1
- package/static/dist/assets/copy-magtofyp.js +0 -1
- package/static/dist/assets/cose-bilkent-JH36ORCC-eclcy6ja.js +0 -1
- package/static/dist/assets/cynefin-OW5HDTMX-siqlulkl.js +0 -1
- package/static/dist/assets/cynefinDiagram-5FMLGOSQ-i648tah9.js +0 -62
- package/static/dist/assets/cytoscape.esm-bqu53u12.js +0 -321
- package/static/dist/assets/dagre-GXQ25YYZ-mwn6uc17.js +0 -4
- package/static/dist/assets/dagre-lkoknbjn.js +0 -1
- package/static/dist/assets/diagram-UQ7AKVKN-mekq7zgq.js +0 -41
- package/static/dist/assets/diagram-VX7I27RA-xe6r5qfw.js +0 -24
- package/static/dist/assets/diagram-Z3DM3KII-nq07dg7k.js +0 -24
- package/static/dist/assets/ebnfDiagram-PWID7BFC-c62ipm3g.js +0 -1
- package/static/dist/assets/endpoints-klbxod4t.js +0 -64
- package/static/dist/assets/erDiagram-RLTQ6QDP-h39kmnzy.js +0 -99
- package/static/dist/assets/eventmodeling-NTZA5JFV-obfede4u.js +0 -1
- package/static/dist/assets/flowDiagram-HODETNUW-kdpsp1je.js +0 -1
- package/static/dist/assets/gitGraph-4MIJSDKK-fr2i7caa.js +0 -1
- package/static/dist/assets/highlighted-body-KPVGNVTW-jwpop9p8.js +0 -1
- package/static/dist/assets/host-i828xuo7.js +0 -1
- package/static/dist/assets/index-eh8zilnv.css +0 -2
- package/static/dist/assets/index-r648f4o1.js +0 -11
- package/static/dist/assets/info-A6RAGUB7-h11x0dxo.js +0 -1
- package/static/dist/assets/infoDiagram-27XIBGKW-dfh47dw9.js +0 -2
- package/static/dist/assets/lazyRouteComponent-e1y4t2i9.js +0 -1
- package/static/dist/assets/linear-becwlnhk.js +0 -1
- package/static/dist/assets/link-oot2yn73.js +0 -1
- package/static/dist/assets/login-gu28l9ou.js +0 -1
- package/static/dist/assets/mermaid-HWGCJPDP-mtwrj8fn.js +0 -1
- package/static/dist/assets/mermaid-parser.core-ntne45i9.js +0 -7
- package/static/dist/assets/not-found-ccnnac39.js +0 -1
- package/static/dist/assets/onboarding-lkphzu1s.js +0 -1
- package/static/dist/assets/onboarding_model_label-ftpjdwqk.js +0 -1
- package/static/dist/assets/packet-AYTQ26CC-l6jdka8p.js +0 -1
- package/static/dist/assets/pegDiagram-XKGWAZYB-g1er3bxj.js +0 -1
- package/static/dist/assets/pie-WAS4IAKB-i0ylcrt9.js +0 -1
- package/static/dist/assets/pieDiagram-E7YTZNPT-fbz1e55z.js +0 -39
- package/static/dist/assets/radar-RG4KPBEZ-f9b70aa4.js +0 -1
- package/static/dist/assets/railroad-74A4TZTK-lgsuoeda.js +0 -1
- package/static/dist/assets/railroad-abnf-HS5TGJTU-nf9d6pdx.js +0 -1
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-f7ummkt5.js +0 -1
- package/static/dist/assets/railroad-peg-WCYAUIDC-oczq5tqs.js +0 -1
- package/static/dist/assets/railroadDiagram-O6MQD6OU-eqpy9fnz.js +0 -1
- package/static/dist/assets/refresh-abtu93ke.js +0 -1
- package/static/dist/assets/refresh-cw-hlwb02qv.js +0 -1
- package/static/dist/assets/requirementDiagram-BXWQKSXE-ogf6puhi.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-girnabkf.js +0 -1
- package/static/dist/assets/settings_section_extensions_title-h14cwk6f.js +0 -1
- package/static/dist/assets/share._token-kl0r7ido.js +0 -2
- package/static/dist/assets/sizeCapture-INFHLROL-g612l48j.js +0 -1
- package/static/dist/assets/sliders-horizontal-n1zm34qq.js +0 -1
- package/static/dist/assets/src-hjyib4mu.js +0 -1
- package/static/dist/assets/sse-iwku0sjo.js +0 -1
- package/static/dist/assets/stateDiagram-D77RDMKH-fyoznpcs.js +0 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-ixhx8r46.js +0 -1
- package/static/dist/assets/swimlanes-42K2YHIH-oefldhfy.js +0 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-h9ersk2e.js +0 -8
- package/static/dist/assets/todoStore-jjr5yr78.js +0 -1
- package/static/dist/assets/treeView-Q6P3EWNA-f7hcci5o.js +0 -1
- package/static/dist/assets/treemap-WGGIJYW6-nl85071a.js +0 -1
- package/static/dist/assets/units-kgxzxfhi.js +0 -1
- package/static/dist/assets/untitled-cikfjntn.js +0 -1
- package/static/dist/assets/useForm-kqoqg0k9.js +0 -1
- package/static/dist/assets/useLocale-o59tbiea.js +0 -1
- package/static/dist/assets/vennDiagram-4TSXK5OY-h5hzbk0n.js +0 -34
- package/static/dist/assets/wardley-WFR3VGLG-jftvpm3e.js +0 -1
- package/static/dist/assets/wardleyDiagram-VM6X3IG4-hedh85ge.js +0 -78
- /package/static/dist/assets/{ChatPage-gmu5c7lf.css → TerminalPanel-gmu5c7lf.css} +0 -0
|
@@ -1,8 +1,21 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
2
|
-
import { dirname, resolve } from 'node:path';
|
|
3
1
|
import { createHash, randomUUID } from 'node:crypto';
|
|
4
|
-
import {
|
|
5
|
-
|
|
2
|
+
import { readDocument } from '../sessions/storage/document.js';
|
|
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']);
|
|
6
19
|
const REVISION = /^[a-f0-9]{40}$/;
|
|
7
20
|
const PER_SCOPE_LIMIT = 50;
|
|
8
21
|
const GLOBAL_LIMIT = 500;
|
|
@@ -10,52 +23,130 @@ export const FRONTEND_BUILD = /^[a-f0-9]{64}$/;
|
|
|
10
23
|
export const TAB_ID = /^[A-Za-z0-9_-]{8,64}$/;
|
|
11
24
|
export const WEB_REFRESH_KIND = 'web_refresh';
|
|
12
25
|
export const WEB_REFRESH_ACTION = 'reload';
|
|
26
|
+
/** TAL-953: restart the gateway now instead of waiting for its running work to finish. */
|
|
27
|
+
export const GATEWAY_RESTART_NOW = 'restart_gateway_now';
|
|
28
|
+
const GATEWAY_RESTART_NOW_ACTION = { id: GATEWAY_RESTART_NOW, label: 'Restart now', style: 'destructive', acknowledges: false };
|
|
13
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. */
|
|
14
30
|
const TAB_TTL_MS = 60 * 60 * 1000;
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
requires_interaction: row.requires_acknowledgement && row.acknowledged_at === null,
|
|
25
|
-
can_dismiss: isDismissible(row),
|
|
26
|
-
});
|
|
31
|
+
const FAILED_MESSAGE = 'The update could not be completed.';
|
|
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']);
|
|
36
|
+
/** TAL-953: the waiting gateway restart's message, with the running task count once one is known. */
|
|
37
|
+
const gatewayWaitingMessage = (tasks) => tasks > 0
|
|
38
|
+
? `Waiting for ${String(tasks)} running gateway task${tasks === 1 ? '' : 's'} to finish before restarting the gateway.`
|
|
39
|
+
: 'Waiting for running gateway tasks to finish before restarting the gateway.';
|
|
27
40
|
const wording = (target, phase) => {
|
|
28
41
|
const name = target === 'webui' ? 'Talaria Web' : 'Hermes Agent';
|
|
29
42
|
const messages = {
|
|
30
43
|
applying: `Installing the selected ${name} update.`,
|
|
31
44
|
awaiting_confirmation: 'This Hermes Agent revision needs confirmation before it can be installed.',
|
|
32
|
-
|
|
45
|
+
waiting_for_idle: gatewayWaitingMessage(0),
|
|
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.',
|
|
33
48
|
succeeded: `${name} was updated successfully.`,
|
|
34
49
|
blocked: 'The update is waiting for active work to finish.',
|
|
35
|
-
failed:
|
|
50
|
+
failed: FAILED_MESSAGE,
|
|
36
51
|
unknown: 'The connection closed before completion could be verified. Check the installed version before trying again.',
|
|
37
52
|
};
|
|
38
53
|
return { title: `${name} update`, message: messages[phase] };
|
|
39
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
|
+
}
|
|
40
99
|
export class UpdateNotificationStore {
|
|
100
|
+
documents;
|
|
41
101
|
now;
|
|
42
|
-
rows;
|
|
43
|
-
|
|
102
|
+
rows = [];
|
|
103
|
+
revision = null;
|
|
104
|
+
writes = Promise.resolve();
|
|
44
105
|
/** Last check-in per tab refresh notice; kept in memory so polling never rewrites the store. */
|
|
45
106
|
tabSeen = new Map();
|
|
46
107
|
loadedAt;
|
|
47
|
-
|
|
108
|
+
/** This server process; an update whose Web restart another process scheduled has restarted Web. */
|
|
109
|
+
boot = randomUUID();
|
|
110
|
+
constructor(documents, now = () => new Date()) {
|
|
111
|
+
this.documents = documents;
|
|
48
112
|
this.now = now;
|
|
49
|
-
this.file = resolve(stateDir, 'update-notifications.json');
|
|
50
|
-
this.rows = this.load();
|
|
51
113
|
this.loadedAt = this.now().valueOf();
|
|
52
114
|
}
|
|
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
|
+
}
|
|
53
144
|
/**
|
|
54
145
|
* Compare the frontend build a tab loaded with the build this server now serves. A mismatch keeps one
|
|
55
146
|
* persistent, tab-scoped refresh notice per tab; a match resolves and removes it. Unknown builds change nothing.
|
|
56
147
|
*/
|
|
57
|
-
syncTabBuild(scope, loadedBuild, currentBuild) {
|
|
58
|
-
this.pruneClosedTabs();
|
|
148
|
+
async syncTabBuild(scope, loadedBuild, currentBuild) {
|
|
149
|
+
await this.pruneClosedTabs();
|
|
59
150
|
const tab = scope.tab && TAB_ID.test(scope.tab) ? scope.tab : null;
|
|
60
151
|
const loaded = loadedBuild && FRONTEND_BUILD.test(loadedBuild) ? loadedBuild : null;
|
|
61
152
|
const current = currentBuild && FRONTEND_BUILD.test(currentBuild) ? currentBuild : null;
|
|
@@ -67,11 +158,20 @@ export class UpdateNotificationStore {
|
|
|
67
158
|
if (existing) {
|
|
68
159
|
this.rows = this.rows.filter((row) => row !== existing);
|
|
69
160
|
this.tabSeen.delete(existing.id);
|
|
70
|
-
this.save();
|
|
161
|
+
await this.save();
|
|
71
162
|
}
|
|
72
163
|
return state;
|
|
73
164
|
}
|
|
74
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
|
+
}
|
|
75
175
|
const stamp = this.now().toISOString();
|
|
76
176
|
if (existing) {
|
|
77
177
|
this.tabSeen.set(existing.id, this.now().valueOf());
|
|
@@ -79,7 +179,7 @@ export class UpdateNotificationStore {
|
|
|
79
179
|
existing.expected_identity = current;
|
|
80
180
|
existing.updated_at = stamp;
|
|
81
181
|
existing.read_at = null;
|
|
82
|
-
this.save();
|
|
182
|
+
await this.save();
|
|
83
183
|
}
|
|
84
184
|
state.notification_id = existing.id;
|
|
85
185
|
return state;
|
|
@@ -93,35 +193,126 @@ export class UpdateNotificationStore {
|
|
|
93
193
|
created_at: stamp, updated_at: stamp, read_at: null, acknowledged_at: null,
|
|
94
194
|
acknowledged_action_id: null, verified_revision: null, verified_version: null, detail: null,
|
|
95
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,
|
|
96
197
|
};
|
|
97
198
|
if (!this.hasProtectedCapacity(row))
|
|
98
199
|
return state;
|
|
99
200
|
this.rows.push(row);
|
|
100
201
|
this.tabSeen.set(row.id, this.now().valueOf());
|
|
101
|
-
this.save();
|
|
202
|
+
await this.save();
|
|
102
203
|
state.notification_id = row.id;
|
|
103
204
|
return state;
|
|
104
205
|
}
|
|
105
|
-
begin(scope, target) {
|
|
206
|
+
async begin(scope, target) {
|
|
106
207
|
const text = wording(target, 'applying');
|
|
107
|
-
const created = this.create(scope, {
|
|
208
|
+
const created = (await this.create(scope, {
|
|
108
209
|
kind: 'update', target, phase: 'applying', ...text,
|
|
109
210
|
destination: { key: 'settings.system', label: 'Open System settings' },
|
|
110
211
|
visibility: 'server',
|
|
111
|
-
});
|
|
112
|
-
this.watch(scope, created.id);
|
|
212
|
+
}));
|
|
213
|
+
await this.watch(scope, created.id);
|
|
113
214
|
return created;
|
|
114
215
|
}
|
|
216
|
+
/** A retained notice still needs loaded-readiness verification after native debt clears. */
|
|
217
|
+
hasPendingAgentRecovery() {
|
|
218
|
+
const row = this.rows.findLast((entry) => entry.kind === 'agent_recovery');
|
|
219
|
+
return row !== undefined && row.phase !== 'succeeded';
|
|
220
|
+
}
|
|
221
|
+
/** Recovery has its own row, so it can never rewrite the initiating update's failed outcome. */
|
|
222
|
+
async agentRecovery(state) {
|
|
223
|
+
if (state.phase === 'idle')
|
|
224
|
+
return;
|
|
225
|
+
const phase = state.phase === 'complete' ? 'succeeded' : state.phase === 'running' ? 'applying' : 'blocked';
|
|
226
|
+
const title = 'Hermes Agent recovery';
|
|
227
|
+
const message = state.phase === 'complete' ? 'Hermes Agent is usable again. The original update result is unchanged.'
|
|
228
|
+
: state.phase === 'running' ? 'Recovering Hermes Agent after an interrupted update.'
|
|
229
|
+
: state.phase === 'waiting' ? 'Hermes Agent recovery will retry automatically.' : 'Hermes Agent recovery needs attention.';
|
|
230
|
+
const row = this.rows.findLast((entry) => entry.kind === 'agent_recovery');
|
|
231
|
+
if (!row) {
|
|
232
|
+
await this.create({ owner: '*', profile: 'default', serverOwner: true }, {
|
|
233
|
+
kind: 'agent_recovery', target: 'agent', phase, title, message, visibility: 'server',
|
|
234
|
+
severity: state.phase === 'blocked' ? 'warning' : 'info',
|
|
235
|
+
});
|
|
236
|
+
return this.agentRecovery(state);
|
|
237
|
+
}
|
|
238
|
+
if (row.phase === phase && row.message === message && row.detail === safeDetail(state.detail))
|
|
239
|
+
return;
|
|
240
|
+
row.phase = phase;
|
|
241
|
+
row.title = title;
|
|
242
|
+
row.message = message;
|
|
243
|
+
row.detail = safeDetail(state.detail);
|
|
244
|
+
row.severity = state.phase === 'blocked' ? 'warning' : 'info';
|
|
245
|
+
row.updated_at = this.now().toISOString();
|
|
246
|
+
row.dismissed_at = null;
|
|
247
|
+
row.read_at = null;
|
|
248
|
+
await this.save();
|
|
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
|
+
}
|
|
115
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. */
|
|
116
|
-
watch(scope, id) {
|
|
304
|
+
async watch(scope, id) {
|
|
117
305
|
const tab = scope.tab && TAB_ID.test(scope.tab) ? scope.tab : null;
|
|
118
306
|
const row = this.rows.find((entry) => entry.id === id && entry.kind === 'update' && this.isVisible(entry, scope));
|
|
119
307
|
if (!tab || !row)
|
|
120
308
|
return;
|
|
121
309
|
row.watchers = [...row.watchers.filter((watcher) => watcher.tab !== tab), { tab, at: this.now().toISOString() }];
|
|
122
|
-
this.save();
|
|
310
|
+
await this.save();
|
|
311
|
+
}
|
|
312
|
+
async create(scope, input) {
|
|
313
|
+
return this.publish(await this.createRow(scope, input));
|
|
123
314
|
}
|
|
124
|
-
|
|
315
|
+
async createRow(scope, input, notice = {}) {
|
|
125
316
|
const kind = safeToken(input.kind, '');
|
|
126
317
|
const phase = safeToken(input.phase, '');
|
|
127
318
|
const title = safeText(input.title, '', 160);
|
|
@@ -134,60 +325,117 @@ export class UpdateNotificationStore {
|
|
|
134
325
|
const stamp = this.now().toISOString();
|
|
135
326
|
const row = {
|
|
136
327
|
id: randomUUID(), owner: scope.owner.slice(0, 256), profile: scope.profile.slice(0, 64), visibility: input.visibility ?? 'profile',
|
|
137
|
-
kind, target: input.target ?? null, phase, severity: input.severity ?? 'info',
|
|
328
|
+
...notice, kind, target: input.target ?? null, phase, severity: input.severity ?? 'info',
|
|
138
329
|
persistent: input.requiresAcknowledgement === true || input.persistent === true,
|
|
139
330
|
requires_acknowledgement: input.requiresAcknowledgement === true, actions,
|
|
140
331
|
destination: safeDestination(input.destination), title, message,
|
|
141
332
|
created_at: stamp, updated_at: stamp, read_at: null, acknowledged_at: null,
|
|
142
|
-
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),
|
|
143
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,
|
|
144
336
|
};
|
|
145
337
|
if (!this.hasProtectedCapacity(row))
|
|
146
338
|
throw new Error('Update notification protected capacity reached');
|
|
147
339
|
this.rows.push(row);
|
|
148
|
-
this.save();
|
|
149
|
-
return
|
|
340
|
+
await this.save();
|
|
341
|
+
return row;
|
|
150
342
|
}
|
|
151
343
|
activeUpdate(scope, target) {
|
|
152
|
-
const row = [...this.rows].reverse().find((entry) => this.isVisible(entry, scope) && entry.kind === 'update' && entry.target === target && ['applying', 'awaiting_confirmation', 'restarting'].includes(entry.phase));
|
|
153
|
-
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;
|
|
154
346
|
}
|
|
155
|
-
transition(id, phase, expectedIdentity, verifiedIdentity, detail) {
|
|
347
|
+
async transition(id, phase, expectedIdentity, verifiedIdentity, detail) {
|
|
156
348
|
const row = this.rows.find((entry) => entry.id === id);
|
|
157
349
|
if (!row)
|
|
158
350
|
return null;
|
|
159
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;
|
|
160
359
|
row.phase = phase;
|
|
161
360
|
if (row.target)
|
|
162
361
|
Object.assign(row, wording(row.target, phase));
|
|
362
|
+
if (phase === 'awaiting_confirmation')
|
|
363
|
+
row.message = safeText(detail, row.message, 500);
|
|
163
364
|
row.updated_at = this.now().toISOString();
|
|
164
365
|
if (phaseChanged)
|
|
165
366
|
row.read_at = null;
|
|
166
367
|
row.expected_identity = expectedIdentity?.trim().slice(0, 160) || null;
|
|
167
|
-
row.detail = phase === 'failed' || phase === 'blocked' || phase === 'succeeded' ? safeDetail(detail) : null;
|
|
368
|
+
row.detail = phase === 'applying' || phase === 'failed' || phase === 'blocked' || phase === 'succeeded' || phase === 'waiting_for_idle' || phase === 'verifying' ? safeDetail(detail) : null;
|
|
369
|
+
// The gateway restart is server-wide: every server owner sees the wait and can restart now, and a later update joins it.
|
|
370
|
+
if (row.kind === 'update' && phase === 'waiting_for_idle' && row.visibility === 'server')
|
|
371
|
+
row.owner = '*';
|
|
372
|
+
// Only a waiting gateway restart offers an action; entering the wait offers it afresh.
|
|
373
|
+
if (row.kind === 'update') {
|
|
374
|
+
row.actions = phase === 'waiting_for_idle' ? [GATEWAY_RESTART_NOW_ACTION] : [];
|
|
375
|
+
row.performed_action_ids = row.performed_action_ids.filter((action) => action !== GATEWAY_RESTART_NOW);
|
|
376
|
+
}
|
|
168
377
|
if (verifiedIdentity) {
|
|
169
378
|
row.verified_revision = typeof verifiedIdentity.revision === 'string' && REVISION.test(verifiedIdentity.revision) ? verifiedIdentity.revision : null;
|
|
170
379
|
row.verified_version = safeText(verifiedIdentity.version, '', 80) || null;
|
|
171
380
|
}
|
|
172
|
-
this.save();
|
|
173
|
-
return
|
|
381
|
+
await this.save();
|
|
382
|
+
return this.publish(row);
|
|
383
|
+
}
|
|
384
|
+
/** TAL-953: update the waiting gateway restart's message as its running task count changes. */
|
|
385
|
+
async gatewayWaiting(id, tasks) {
|
|
386
|
+
const row = this.rows.find((entry) => entry.id === id && entry.kind === 'update' && entry.phase === 'waiting_for_idle');
|
|
387
|
+
const message = gatewayWaitingMessage(tasks);
|
|
388
|
+
const counted = tasks > 0 ? tasks : row?.gateway_tasks ?? null;
|
|
389
|
+
if (!row || (row.message === message && row.gateway_tasks === counted))
|
|
390
|
+
return;
|
|
391
|
+
row.message = message;
|
|
392
|
+
row.gateway_tasks = counted;
|
|
393
|
+
row.updated_at = this.now().toISOString();
|
|
394
|
+
await this.save();
|
|
395
|
+
}
|
|
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();
|
|
404
|
+
}
|
|
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();
|
|
174
412
|
}
|
|
175
|
-
|
|
176
|
-
|
|
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) {
|
|
424
|
+
await this.pruneClosedTabs();
|
|
177
425
|
const scoped = this.rows.filter((row) => this.isVisible(row, scope) && row.dismissed_at === null);
|
|
178
426
|
const ordered = scoped.sort((a, b) => b.updated_at.localeCompare(a.updated_at));
|
|
179
427
|
const protectedRows = ordered.filter(isProtected);
|
|
180
428
|
const visible = [...protectedRows, ...ordered.filter((row) => !isProtected(row)).slice(0, Math.max(0, PER_SCOPE_LIMIT - protectedRows.length))]
|
|
181
429
|
.sort((a, b) => b.updated_at.localeCompare(a.updated_at));
|
|
182
|
-
const notifications = visible.map(copy);
|
|
183
|
-
const clearableCount = scoped.filter(isDismissible).length;
|
|
184
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;
|
|
185
433
|
const joinedAt = (row) => row.watchers.find((watcher) => watcher.tab === tab)?.at ?? '';
|
|
186
434
|
const tabUpdate = tab ? this.rows.filter((row) => row.kind === 'update' && joinedAt(row) !== '' && this.isVisible(row, scope))
|
|
187
435
|
.sort((a, b) => joinedAt(b).localeCompare(joinedAt(a)) || b.created_at.localeCompare(a.created_at))[0] : undefined;
|
|
188
|
-
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 };
|
|
189
437
|
}
|
|
190
|
-
clear(scope) {
|
|
438
|
+
async clear(scope, stale = false) {
|
|
191
439
|
const stamp = this.now().toISOString();
|
|
192
440
|
let changed = false;
|
|
193
441
|
for (const row of this.rows) {
|
|
@@ -197,40 +445,41 @@ export class UpdateNotificationStore {
|
|
|
197
445
|
changed = true;
|
|
198
446
|
}
|
|
199
447
|
if (changed)
|
|
200
|
-
this.save();
|
|
201
|
-
return this.list(scope);
|
|
448
|
+
(await this.save());
|
|
449
|
+
return (await this.list(scope, stale));
|
|
202
450
|
}
|
|
203
|
-
read(scope, id) {
|
|
451
|
+
async read(scope, id) {
|
|
204
452
|
const row = this.visible(scope, id);
|
|
205
453
|
if (!row)
|
|
206
454
|
return null;
|
|
207
455
|
if (row.read_at === null) {
|
|
208
456
|
row.read_at = this.now().toISOString();
|
|
209
|
-
this.save();
|
|
457
|
+
(await this.save());
|
|
210
458
|
}
|
|
211
|
-
return
|
|
459
|
+
return this.publish(row);
|
|
212
460
|
}
|
|
213
|
-
dismiss(scope, id) {
|
|
461
|
+
async dismiss(scope, id) {
|
|
214
462
|
const row = this.rows.find((entry) => entry.id === id && this.isVisible(entry, scope));
|
|
215
463
|
if (!row)
|
|
216
464
|
return 'not_found';
|
|
217
|
-
if (row
|
|
465
|
+
if (!isDismissible(row))
|
|
218
466
|
return 'acknowledgement_required';
|
|
219
467
|
if (row.dismissed_at === null) {
|
|
220
468
|
const stamp = this.now().toISOString();
|
|
221
469
|
row.dismissed_at = stamp;
|
|
222
470
|
row.read_at ??= stamp;
|
|
223
|
-
this.save();
|
|
471
|
+
(await this.save());
|
|
224
472
|
}
|
|
225
473
|
return 'dismissed';
|
|
226
474
|
}
|
|
227
|
-
action(scope, id, actionId) {
|
|
475
|
+
async action(scope, id, actionId) {
|
|
228
476
|
const row = this.visible(scope, id);
|
|
229
|
-
|
|
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;
|
|
230
479
|
if (!row || !action)
|
|
231
480
|
return null;
|
|
232
481
|
if (row.performed_action_ids.includes(action.id))
|
|
233
|
-
return
|
|
482
|
+
return this.publish(row, scope.tab, true);
|
|
234
483
|
const stamp = this.now().toISOString();
|
|
235
484
|
row.updated_at = stamp;
|
|
236
485
|
row.read_at ??= stamp;
|
|
@@ -239,15 +488,15 @@ export class UpdateNotificationStore {
|
|
|
239
488
|
row.acknowledged_at = stamp;
|
|
240
489
|
row.acknowledged_action_id = action.id;
|
|
241
490
|
}
|
|
242
|
-
this.save();
|
|
243
|
-
return
|
|
491
|
+
await this.save();
|
|
492
|
+
return this.publish(row, scope.tab, true);
|
|
244
493
|
}
|
|
245
|
-
cancelUpdate(scope, id) {
|
|
494
|
+
async cancelUpdate(scope, id) {
|
|
246
495
|
const row = this.rows.find((entry) => entry.id === id && this.isVisible(entry, scope) && entry.kind === 'update');
|
|
247
496
|
if (!row)
|
|
248
497
|
return null;
|
|
249
498
|
if (row.phase === 'blocked' && row.message === 'The update was cancelled before installation.')
|
|
250
|
-
return
|
|
499
|
+
return this.publish(row);
|
|
251
500
|
if (row.phase !== 'awaiting_confirmation')
|
|
252
501
|
return null;
|
|
253
502
|
const stamp = this.now().toISOString();
|
|
@@ -255,15 +504,25 @@ export class UpdateNotificationStore {
|
|
|
255
504
|
row.message = 'The update was cancelled before installation.';
|
|
256
505
|
row.updated_at = stamp;
|
|
257
506
|
row.read_at ??= stamp;
|
|
258
|
-
this.save();
|
|
259
|
-
return
|
|
507
|
+
await this.save();
|
|
508
|
+
return this.publish(row);
|
|
260
509
|
}
|
|
261
|
-
reconcileInterruptedUpdates(currentWebIdentity, currentWebVersion = null) {
|
|
510
|
+
async reconcileInterruptedUpdates(currentWebIdentity, currentWebVersion = null) {
|
|
262
511
|
let changed = false;
|
|
263
512
|
for (const row of this.rows) {
|
|
513
|
+
if (row.kind === 'agent_recovery' && row.phase === 'applying') {
|
|
514
|
+
row.phase = 'unknown';
|
|
515
|
+
row.message = 'Agent recovery was interrupted. Current readiness has not been verified.';
|
|
516
|
+
row.severity = 'warning';
|
|
517
|
+
row.updated_at = this.now().toISOString();
|
|
518
|
+
row.read_at = null;
|
|
519
|
+
changed = true;
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
264
522
|
if (row.kind !== 'update' || (row.target !== 'webui' && row.target !== 'agent') || !['applying', 'restarting'].includes(row.phase))
|
|
265
523
|
continue;
|
|
266
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;
|
|
267
526
|
row.phase = phase;
|
|
268
527
|
Object.assign(row, wording(row.target, phase));
|
|
269
528
|
row.updated_at = this.now().toISOString();
|
|
@@ -275,7 +534,44 @@ export class UpdateNotificationStore {
|
|
|
275
534
|
changed = true;
|
|
276
535
|
}
|
|
277
536
|
if (changed)
|
|
278
|
-
this.save();
|
|
537
|
+
(await this.save());
|
|
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
|
+
};
|
|
279
575
|
}
|
|
280
576
|
visible(scope, id) {
|
|
281
577
|
return this.rows.find((row) => row.id === id && this.isVisible(row, scope) && row.dismissed_at === null) ?? null;
|
|
@@ -285,13 +581,15 @@ export class UpdateNotificationStore {
|
|
|
285
581
|
return row.tab_id === scope.tab && row.owner === scope.owner && row.profile === scope.profile;
|
|
286
582
|
if (row.visibility === 'server')
|
|
287
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));
|
|
288
586
|
return row.owner === scope.owner && row.profile === scope.profile;
|
|
289
587
|
}
|
|
290
588
|
hasProtectedCapacity(row) {
|
|
291
589
|
const peers = this.rows.filter((entry) => isProtected(entry) && isTabNotice(entry) === isTabNotice(row));
|
|
292
590
|
return peers.filter((entry) => retentionBucket(entry) === retentionBucket(row)).length < PER_SCOPE_LIMIT && peers.length < GLOBAL_LIMIT;
|
|
293
591
|
}
|
|
294
|
-
pruneClosedTabs() {
|
|
592
|
+
async pruneClosedTabs() {
|
|
295
593
|
const cutoff = this.now().valueOf() - TAB_TTL_MS;
|
|
296
594
|
const closed = this.rows.filter((row) => row.tab_id !== null && (this.tabSeen.get(row.id) ?? this.loadedAt) < cutoff);
|
|
297
595
|
if (closed.length === 0)
|
|
@@ -299,13 +597,13 @@ export class UpdateNotificationStore {
|
|
|
299
597
|
for (const row of closed)
|
|
300
598
|
this.tabSeen.delete(row.id);
|
|
301
599
|
this.rows = this.rows.filter((row) => !closed.includes(row));
|
|
302
|
-
this.save();
|
|
600
|
+
await this.save();
|
|
303
601
|
}
|
|
304
|
-
load() {
|
|
305
|
-
if (!existsSync(this.file))
|
|
306
|
-
return [];
|
|
602
|
+
async load() {
|
|
307
603
|
try {
|
|
308
|
-
const
|
|
604
|
+
const record = await readDocument(this.documents, 'update-notifications', 'update-notifications', { replaceInvalid: true });
|
|
605
|
+
this.revision = record?.revision ?? null;
|
|
606
|
+
const parsed = record?.value;
|
|
309
607
|
if (!Array.isArray(parsed))
|
|
310
608
|
return [];
|
|
311
609
|
return parsed.flatMap((value) => {
|
|
@@ -319,9 +617,11 @@ export class UpdateNotificationStore {
|
|
|
319
617
|
return [];
|
|
320
618
|
const kind = safeToken(row.kind, 'update');
|
|
321
619
|
const target = row.target === 'webui' || row.target === 'agent' ? row.target : null;
|
|
322
|
-
|
|
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');
|
|
323
622
|
const fallback = target && PHASES.has(phase) ? wording(target, phase) : { title: 'Server notification', message: 'This server needs your attention.' };
|
|
324
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 : '' } : {}),
|
|
325
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,
|
|
326
626
|
severity: row.severity === 'critical' || row.severity === 'warning' ? row.severity : 'info',
|
|
327
627
|
persistent: row.persistent === true,
|
|
@@ -341,6 +641,10 @@ export class UpdateNotificationStore {
|
|
|
341
641
|
expected_identity: typeof row.expected_identity === 'string' ? row.expected_identity.slice(0, 160) : null,
|
|
342
642
|
tab_id: typeof row.tab_id === 'string' ? row.tab_id : null,
|
|
343
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,
|
|
344
648
|
}];
|
|
345
649
|
});
|
|
346
650
|
}
|
|
@@ -349,7 +653,7 @@ export class UpdateNotificationStore {
|
|
|
349
653
|
}
|
|
350
654
|
}
|
|
351
655
|
/** Tab refresh notices are bounded by `hasProtectedCapacity` and kept apart, so they never evict or block other notifications. */
|
|
352
|
-
save() {
|
|
656
|
+
async save() {
|
|
353
657
|
const tabNotices = this.rows.filter(isTabNotice);
|
|
354
658
|
const sorted = this.rows.filter((row) => !isTabNotice(row)).sort((a, b) => b.updated_at.localeCompare(a.updated_at));
|
|
355
659
|
const protectedRows = sorted.filter(isProtected);
|
|
@@ -372,8 +676,19 @@ export class UpdateNotificationStore {
|
|
|
372
676
|
kept.push(row);
|
|
373
677
|
}
|
|
374
678
|
this.rows = [...kept.reverse(), ...tabNotices];
|
|
375
|
-
|
|
376
|
-
|
|
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
|
+
}));
|
|
689
|
+
const write = this.writes.catch(() => undefined).then(async () => { this.revision = await this.documents.put('update-notifications', 'update-notifications', rows, this.revision); });
|
|
690
|
+
this.writes = write;
|
|
691
|
+
await write;
|
|
377
692
|
}
|
|
378
693
|
}
|
|
379
694
|
const safeToken = (value, fallback) => typeof value === 'string' && /^[a-z0-9][a-z0-9_-]{0,63}$/.test(value) ? value : fallback;
|
|
@@ -400,8 +715,11 @@ const safeDestination = (value) => {
|
|
|
400
715
|
return key && label ? { key, label } : null;
|
|
401
716
|
};
|
|
402
717
|
const isTabNotice = (row) => row.tab_id !== null;
|
|
403
|
-
|
|
404
|
-
const
|
|
718
|
+
/** A waiting gateway restart carries its Restart now action, so it stays until the restart runs. */
|
|
719
|
+
const isWaitingGatewayRestart = (row) => row.kind === 'update' && row.phase === 'waiting_for_idle';
|
|
720
|
+
const isDismissible = (row) => (!row.requires_acknowledgement || row.acknowledged_at !== null) && !isWaitingGatewayRestart(row);
|
|
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));
|
|
405
723
|
const retentionBucket = (row) => `${row.owner}\u0000${row.visibility === 'server' ? '*' : row.profile}`;
|
|
406
724
|
export const updateNotificationScopeId = (scope) => createHash('sha256').update(`${scope.owner}\u0000${scope.profile}\u0000${scope.serverOwner === true ? 'owner' : 'member'}`).digest('hex').slice(0, 24);
|
|
407
725
|
//# sourceMappingURL=update-notifications.js.map
|