@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
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"""Exact manual-fire recovery. The Agent owns admission, delivery and bookkeeping formats.
|
|
2
|
+
|
|
3
|
+
Its admission journal lacks the Web caller's cancellation intent and tail ownership.
|
|
4
|
+
This additive record retains those two obligations across a lost submitter or sidecar.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import contextlib
|
|
10
|
+
import importlib
|
|
11
|
+
import json
|
|
12
|
+
import os
|
|
13
|
+
import time
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
from ..dependency_sync import _lock
|
|
17
|
+
from ..errors import RpcError
|
|
18
|
+
from ..home import scoped_home
|
|
19
|
+
|
|
20
|
+
SETTLEMENT_SECONDS = 30.0
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Unverified(RpcError):
|
|
24
|
+
def __init__(self, detail):
|
|
25
|
+
self.detail = str(detail)
|
|
26
|
+
super().__init__(f"Task outcome is unverified. {detail}",
|
|
27
|
+
condition="cron_execution_unverified")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def path(home, job_id):
|
|
31
|
+
return Path(home) / "cron" / "manual_runs" / (job_id + ".json")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _read_record(home, job_id):
|
|
35
|
+
try:
|
|
36
|
+
record = json.loads(path(home, job_id).read_text())
|
|
37
|
+
except FileNotFoundError:
|
|
38
|
+
return None
|
|
39
|
+
except (OSError, ValueError) as exc:
|
|
40
|
+
raise Unverified("The retained task record could not be read.") from exc
|
|
41
|
+
job = record.get("job") if isinstance(record, dict) else None
|
|
42
|
+
if not isinstance(job, dict) or job.get("id") != job_id:
|
|
43
|
+
raise Unverified("Recovery identity does not match this task.")
|
|
44
|
+
return record
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def pending_job(home, job_id):
|
|
48
|
+
"""The frozen job keeps an externally deleted execution reachable through Web's list/get preflight."""
|
|
49
|
+
record = _read_record(home, job_id)
|
|
50
|
+
if record is None:
|
|
51
|
+
return None
|
|
52
|
+
job = record["job"]
|
|
53
|
+
return dict(job, recovery_only=True, state="paused", enabled=False, last_run_at=None, last_status="error",
|
|
54
|
+
last_error="Task outcome is unverified. Use Run now to check it.")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def pending_jobs(home):
|
|
58
|
+
from .cron import _job_id
|
|
59
|
+
result = []
|
|
60
|
+
for file in sorted((Path(home) / "cron" / "manual_runs").glob("*.json")):
|
|
61
|
+
job = pending_job(home, _job_id({"job_id": file.stem}))
|
|
62
|
+
if job is not None:
|
|
63
|
+
result.append(job)
|
|
64
|
+
return result
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def supported(job, *, recovery=False):
|
|
68
|
+
if job.get("no_agent"):
|
|
69
|
+
return False
|
|
70
|
+
try:
|
|
71
|
+
authority = importlib.import_module("cron.scheduler_authority")
|
|
72
|
+
if recovery:
|
|
73
|
+
surfaces = ((authority, ("journal_path", "_lift_pause")),
|
|
74
|
+
(importlib.import_module("cron.scheduler_bookkeeping"), ("fail_empty_response", "finish_completed_run")),
|
|
75
|
+
(importlib.import_module("cron.executions"), ("give_up_execution", "recover_receipted_execution")),
|
|
76
|
+
(importlib.import_module("hermes_cli.gateway_client"), ("connect_gateway",)),
|
|
77
|
+
(importlib.import_module("hermes_cli.gateway_runtime"), ("discover_gateway_endpoint",)))
|
|
78
|
+
return all(callable(getattr(module, name, None)) for module, names in surfaces for name in names)
|
|
79
|
+
except ImportError as exc:
|
|
80
|
+
if recovery or (isinstance(exc, ModuleNotFoundError) and exc.name in {"cron.scheduler_authority", "cron"}):
|
|
81
|
+
return False
|
|
82
|
+
raise
|
|
83
|
+
return True
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def recover(job, execution_id, cancel_event):
|
|
87
|
+
"""Observe only. A lost submission reply never authorizes another submit."""
|
|
88
|
+
from hermes_cli.gateway_client import connect_gateway
|
|
89
|
+
|
|
90
|
+
async def observe():
|
|
91
|
+
endpoint = None
|
|
92
|
+
if not os.environ.get("HERMES_TUI_GATEWAY_URL", "").strip():
|
|
93
|
+
from hermes_cli.gateway_runtime import discover_gateway_endpoint
|
|
94
|
+
from hermes_constants import get_hermes_home
|
|
95
|
+
discovery = await asyncio.to_thread(discover_gateway_endpoint, get_hermes_home())
|
|
96
|
+
if discovery.state != "ready" or discovery.endpoint is None:
|
|
97
|
+
raise Unverified("The owning gateway is unavailable.")
|
|
98
|
+
endpoint = discovery.endpoint
|
|
99
|
+
async with connect_gateway(endpoint=endpoint) as client:
|
|
100
|
+
state = await client.rpc("cron.recover", job_id=job["id"], request_id=execution_id, extra_prompt=None)
|
|
101
|
+
if state["status"] == "missing":
|
|
102
|
+
return False, "", "", "Cron admission missing: the owner never admitted this fire"
|
|
103
|
+
if state["status"] == "unknown":
|
|
104
|
+
raise Unverified("The owner cannot prove this admission's outcome.")
|
|
105
|
+
receipt = {key: state[key] for key in ("session_id", "admission_id")}
|
|
106
|
+
while True:
|
|
107
|
+
if state["status"] == "terminal":
|
|
108
|
+
job.update(state.get("job_flags") or {})
|
|
109
|
+
return tuple(state["result"])
|
|
110
|
+
if state["status"] not in {"queued", "started"}:
|
|
111
|
+
raise Unverified(f"Owner status: {state['status']}")
|
|
112
|
+
if cancel_event.is_set():
|
|
113
|
+
await client.rpc("cron.cancel", **receipt)
|
|
114
|
+
await asyncio.sleep(.2)
|
|
115
|
+
state = await client.rpc("cron.status", **receipt)
|
|
116
|
+
return asyncio.run(observe())
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class ManualExecution:
|
|
120
|
+
def __init__(self, home, execution_home, job, owner):
|
|
121
|
+
self.home = Path(home)
|
|
122
|
+
self.file = path(home, job["id"])
|
|
123
|
+
self.execution_home = Path(execution_home or home)
|
|
124
|
+
self.job, self.owner = dict(job), owner
|
|
125
|
+
self.record = None
|
|
126
|
+
self.recovering = False
|
|
127
|
+
self.settled = False
|
|
128
|
+
|
|
129
|
+
def save(self):
|
|
130
|
+
from utils import atomic_json_write
|
|
131
|
+
atomic_json_write(self.file, self.record, mode=0o600, fsync_dir=True)
|
|
132
|
+
|
|
133
|
+
@contextlib.contextmanager
|
|
134
|
+
def acquire(self):
|
|
135
|
+
self.file.parent.mkdir(parents=True, exist_ok=True)
|
|
136
|
+
with self.file.with_suffix(".lock").open("a+b") as lease:
|
|
137
|
+
try:
|
|
138
|
+
_lock(lease)
|
|
139
|
+
except OSError as exc:
|
|
140
|
+
raise RpcError("This manual task is still being reconciled", condition="cron_execution_unverified") from exc
|
|
141
|
+
yield
|
|
142
|
+
|
|
143
|
+
def prepare(self, *, recovery_only=False):
|
|
144
|
+
from cron import executions, jobs
|
|
145
|
+
self.record = _read_record(self.home, self.job["id"])
|
|
146
|
+
if self.record is not None:
|
|
147
|
+
self.job, self.owner = self.record["job"], self.record["owner"]
|
|
148
|
+
self.execution_home = Path(self.record["execution_home"])
|
|
149
|
+
self.recovering = True
|
|
150
|
+
else:
|
|
151
|
+
if recovery_only:
|
|
152
|
+
raise Unverified("The retained task record is no longer available. Refresh its status.")
|
|
153
|
+
with scoped_home(self.execution_home):
|
|
154
|
+
row = executions.create_execution(self.job["id"], source="web-manual")
|
|
155
|
+
executions.mark_execution_running(row["id"])
|
|
156
|
+
self.record = {"job": self.job, "owner": self.owner, "execution_home": str(self.execution_home),
|
|
157
|
+
"execution_id": row["id"], "cancel_reason": None, "tail_started": False}
|
|
158
|
+
self.execution_id = row["id"]
|
|
159
|
+
self.save()
|
|
160
|
+
self.execution_id = self.record["execution_id"]
|
|
161
|
+
if self.recovering:
|
|
162
|
+
self.cancel("submitter interrupted")
|
|
163
|
+
# Pause before dispatch: a dead sidecar must not let claim expiry re-fire an accepted task.
|
|
164
|
+
# Only this exact pause is lifted. Existing operator pauses are never changed.
|
|
165
|
+
with jobs.use_cron_store(self.home):
|
|
166
|
+
from .cron import _owner_fence
|
|
167
|
+
with _owner_fence(jobs, self.job["id"], self.owner, protect_unclaimed=True) as owns:
|
|
168
|
+
current = jobs.get_job(self.job["id"])
|
|
169
|
+
if not owns and not self.recovering:
|
|
170
|
+
self.cancel("claim_lost")
|
|
171
|
+
self.record["result"] = [False, "", "", "Fire claim lost before submission"]
|
|
172
|
+
self.save()
|
|
173
|
+
if owns and current and jobs.is_job_runnable(current) and not self.recovering:
|
|
174
|
+
current = jobs.pause_job(self.job["id"], reason=f"Manual execution pending: {self.execution_id}")
|
|
175
|
+
# The job write may have committed before the submitter died saving its pause receipt.
|
|
176
|
+
if (current and current.get("state") == "paused" and not self.record.get("pause")
|
|
177
|
+
and current.get("paused_reason") == f"Manual execution pending: {self.execution_id}"):
|
|
178
|
+
self.record["pause"] = {"paused_at": current["paused_at"], "reason": current["paused_reason"]}
|
|
179
|
+
self.save()
|
|
180
|
+
|
|
181
|
+
def cancel(self, reason):
|
|
182
|
+
if self.record["cancel_reason"] is None:
|
|
183
|
+
self.record["cancel_reason"] = reason
|
|
184
|
+
self.save()
|
|
185
|
+
|
|
186
|
+
def finish(self, result):
|
|
187
|
+
from cron import executions, jobs, scheduler
|
|
188
|
+
from cron.scheduler_authority import journal_path
|
|
189
|
+
from .cron import _delivery_home, _owner_fence, _ClaimLost
|
|
190
|
+
|
|
191
|
+
success, output, answer, error = result
|
|
192
|
+
with scoped_home(self.execution_home), jobs.use_cron_store(self.home), _owner_fence(jobs, self.job["id"], self.owner, protect_unclaimed=True) as owns:
|
|
193
|
+
current = jobs.get_job(self.job["id"]) or {}
|
|
194
|
+
row = executions.get_execution(self.execution_id)
|
|
195
|
+
marked = self.execution_id in current.get("canonical_completions", [])
|
|
196
|
+
booked = marked or (row and row["status"] in {"completed", "failed"})
|
|
197
|
+
# Our own mark releases the claim before pause cleanup. A successor's claim never qualifies.
|
|
198
|
+
may_finish = bool(current) and (owns or (marked and not current.get("fire_claim")))
|
|
199
|
+
if not booked and self.record["tail_started"]:
|
|
200
|
+
raise Unverified("Bookkeeping was interrupted; its side effects will not be repeated.")
|
|
201
|
+
# Stop the Agent's orphan journal reader from replaying OUR tail after a crash.
|
|
202
|
+
# Our record now owns recovery, including the at-most-once tail barrier.
|
|
203
|
+
self.record["result"] = list(result)
|
|
204
|
+
self.save()
|
|
205
|
+
journal_path(self.job["id"], self.execution_id).unlink(missing_ok=True)
|
|
206
|
+
if not may_finish:
|
|
207
|
+
self._finish_ledger(False, "Fire claim ownership lost before terminal completion.")
|
|
208
|
+
elif booked:
|
|
209
|
+
self._finish_ledger(success, error)
|
|
210
|
+
else:
|
|
211
|
+
self.record["tail_started"] = True
|
|
212
|
+
self.save()
|
|
213
|
+
self.job["execution_id"] = self.execution_id
|
|
214
|
+
with _delivery_home(scheduler, self.home):
|
|
215
|
+
from cron.scheduler_bookkeeping import fail_empty_response, finish_completed_run
|
|
216
|
+
success, error, declared = scheduler._apply_agent_failure_marker(self.job, success, error, answer)
|
|
217
|
+
delivery = scheduler._RunDelivery(self.job, success, error, agent_declared=declared)
|
|
218
|
+
scheduler._save_compose_deliver(delivery, scheduler._FireOwnership(self.job), answer, output,
|
|
219
|
+
adapters=None, loop=None, verbose=False, execution_token=None)
|
|
220
|
+
fail_empty_response(delivery, answer)
|
|
221
|
+
if not finish_completed_run(delivery, self.owner, self.execution_id, recovered=self.recovering):
|
|
222
|
+
raise Unverified("A prior submitter still owns this execution's bookkeeping.")
|
|
223
|
+
success, error = delivery.success, delivery.error
|
|
224
|
+
pause = self.record.get("pause")
|
|
225
|
+
if may_finish and pause:
|
|
226
|
+
from cron.scheduler_authority import _lift_pause
|
|
227
|
+
_lift_pause(self.job["id"], pause)
|
|
228
|
+
self.file.unlink()
|
|
229
|
+
self.settled = True
|
|
230
|
+
reason = self.record["cancel_reason"]
|
|
231
|
+
if not may_finish or reason == "claim_lost":
|
|
232
|
+
return {"job_id": self.job["id"], "status": "failed", "success": False, "error": str(_ClaimLost())}
|
|
233
|
+
if reason == "cancelled" and not success:
|
|
234
|
+
raise RpcError("cancelled", condition="cancelled")
|
|
235
|
+
if reason and not success:
|
|
236
|
+
return {"job_id": self.job["id"], "status": "failed", "success": False, "error": reason}
|
|
237
|
+
return {"job_id": self.job["id"], "status": "completed", "success": bool(success), "error": error}
|
|
238
|
+
|
|
239
|
+
def _finish_ledger(self, success, error):
|
|
240
|
+
from cron import executions
|
|
241
|
+
finish = executions.recover_receipted_execution if self.recovering else executions.finish_execution
|
|
242
|
+
kwargs = {"job_id": self.job["id"]} if self.recovering else {}
|
|
243
|
+
finish(self.execution_id, success=success, error=error, **kwargs)
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def run(job, home, execution_home, ctx, owner, *, recovery_only=False):
|
|
247
|
+
from . import cron
|
|
248
|
+
# Refuse before prepare/cancel can rewrite retained evidence or cleanup can enter a removed owner API.
|
|
249
|
+
if (recovery_only or path(home, job["id"]).exists()) and not supported({}, recovery=True):
|
|
250
|
+
raise Unverified("This Agent has an unsupported recovery protocol. Reconcile the retained manual task "
|
|
251
|
+
"with a capable Agent before retrying. No task was resubmitted or settled.")
|
|
252
|
+
execution = ManualExecution(home, execution_home, job, owner)
|
|
253
|
+
with execution.acquire():
|
|
254
|
+
with cron._RUNNING_LOCK:
|
|
255
|
+
cron._RUNNING.setdefault(job["id"], time.time())
|
|
256
|
+
try:
|
|
257
|
+
execution.prepare(recovery_only=recovery_only)
|
|
258
|
+
if recovery_only:
|
|
259
|
+
ctx.emit("started", {"job_id": job["id"]})
|
|
260
|
+
heartbeat = cron._heartbeat(home, execution.job["id"], execution.owner) if execution.owner else None
|
|
261
|
+
if execution.record.get("result") is not None:
|
|
262
|
+
result = execution.record["result"]
|
|
263
|
+
else:
|
|
264
|
+
result = cron._run_in_child(execution.job, execution.execution_home, ctx, heartbeat, execution)
|
|
265
|
+
return execution.finish(result)
|
|
266
|
+
except Exception as exc:
|
|
267
|
+
if execution.settled:
|
|
268
|
+
raise
|
|
269
|
+
if execution.record is not None and hasattr(execution, "execution_id"):
|
|
270
|
+
execution.cancel(execution.record["cancel_reason"] or "submitter interrupted")
|
|
271
|
+
# The Web record, not the Agent's generic orphan replay, now owns cancellation.
|
|
272
|
+
# Give up only our own audit row; this never releases or stamps a fire claim.
|
|
273
|
+
with scoped_home(execution.execution_home):
|
|
274
|
+
from cron.scheduler_authority import journal_path
|
|
275
|
+
from cron.executions import give_up_execution
|
|
276
|
+
journal_path(job["id"], execution.execution_id).unlink(missing_ok=True)
|
|
277
|
+
give_up_execution(execution.execution_id, reason=str(exc))
|
|
278
|
+
if isinstance(exc, Unverified):
|
|
279
|
+
raise
|
|
280
|
+
raise Unverified(str(exc)) from exc
|
|
281
|
+
finally:
|
|
282
|
+
# The durable record guards an unverified owner; this map guards only an active call.
|
|
283
|
+
with cron._RUNNING_LOCK:
|
|
284
|
+
cron._RUNNING.pop(job["id"], None)
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
"""Agent-owned dashboard discovery, consent and buffered HTTP. Never imports plugin code here."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import base64
|
|
5
|
+
import hashlib
|
|
6
|
+
import inspect
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
import re
|
|
10
|
+
import stat
|
|
11
|
+
import tempfile
|
|
12
|
+
import threading
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from urllib.parse import parse_qsl, urlencode
|
|
15
|
+
|
|
16
|
+
from .. import home as homes
|
|
17
|
+
from ..errors import InvalidParams, RpcError
|
|
18
|
+
|
|
19
|
+
_NAME = re.compile(r'^[a-z][a-z0-9_-]{0,63}$')
|
|
20
|
+
_MIME = {'.html': 'text/html; charset=utf-8', '.js': 'application/javascript; charset=utf-8',
|
|
21
|
+
'.css': 'text/css; charset=utf-8', '.svg': 'image/svg+xml', '.png': 'image/png',
|
|
22
|
+
'.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.gif': 'image/gif', '.webp': 'image/webp',
|
|
23
|
+
'.ico': 'image/x-icon', '.woff': 'font/woff', '.woff2': 'font/woff2', '.ttf': 'font/ttf',
|
|
24
|
+
'.otf': 'font/otf', '.txt': 'text/plain; charset=utf-8'}
|
|
25
|
+
# An allowlist, rather than a denylist, keeps current and future gateway/Talaria credentials out.
|
|
26
|
+
_HEADERS = {'accept', 'content-type', 'if-none-match', 'if-modified-since'}
|
|
27
|
+
_QUERY_CREDENTIALS = {'token', 'ticket', 'internal', 'display_ticket', 'attach', 'profile', 'native_dial', 'api_key', 'access_token'}
|
|
28
|
+
_MAX_ASSET = 8 * 1024 * 1024
|
|
29
|
+
_MAX_API = 512 * 1024
|
|
30
|
+
# Resolve only the operator-selected launch home, never a plugin-controlled descendant.
|
|
31
|
+
_RAW_BASE_HOME = homes._PROCESS_HOME.parent.parent if homes._PROCESS_HOME.parent.name == 'profiles' else homes._PROCESS_HOME
|
|
32
|
+
_BASE_HOME = _RAW_BASE_HOME.resolve()
|
|
33
|
+
_SOURCE_LOCK = threading.Lock()
|
|
34
|
+
_SOURCE_DIRECTORY = None
|
|
35
|
+
_SOURCES = {}
|
|
36
|
+
_SOURCE_BYTES = 0
|
|
37
|
+
_SOURCE_CLOSED = False
|
|
38
|
+
_MAX_SOURCE_BYTES = 64 * 1024 * 1024
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def close_dashboard_sources():
|
|
42
|
+
"""Release the native loader's source cache after the RPC server has stopped admitting calls."""
|
|
43
|
+
global _SOURCE_DIRECTORY, _SOURCE_BYTES, _SOURCE_CLOSED
|
|
44
|
+
with _SOURCE_LOCK:
|
|
45
|
+
_SOURCE_CLOSED = True
|
|
46
|
+
if _SOURCE_DIRECTORY is not None:
|
|
47
|
+
_SOURCE_DIRECTORY.cleanup()
|
|
48
|
+
_SOURCE_DIRECTORY = None
|
|
49
|
+
_SOURCES.clear()
|
|
50
|
+
_SOURCE_BYTES = 0
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _api_source(root, api, source):
|
|
54
|
+
"""Give the unchanged native loader a private, stable copy of the bytes we verified.
|
|
55
|
+
|
|
56
|
+
Preserve the plugin module's original location for relative resources and tracebacks.
|
|
57
|
+
Content-addressing reuses its cached app; retain files through timeouts/late host work,
|
|
58
|
+
bounded by count/bytes and owned by the sidecar until shutdown.
|
|
59
|
+
"""
|
|
60
|
+
global _SOURCE_DIRECTORY, _SOURCE_BYTES
|
|
61
|
+
origin = str(Path(root) / api)
|
|
62
|
+
key = hashlib.sha256(os.fsencode(origin) + b'\0' + source).hexdigest()
|
|
63
|
+
with _SOURCE_LOCK:
|
|
64
|
+
if _SOURCE_CLOSED:
|
|
65
|
+
raise RpcError('Agent dashboard source cache is shutting down', condition='plugin_host_unavailable')
|
|
66
|
+
if key in _SOURCES:
|
|
67
|
+
return _SOURCES[key]
|
|
68
|
+
payload = (f'__talaria_source__ = {source!r}\n'
|
|
69
|
+
f'__file__ = {origin!r}\n'
|
|
70
|
+
"__loader__ = __import__('importlib.machinery', fromlist=['SourceFileLoader']).SourceFileLoader(__name__, __file__)\n"
|
|
71
|
+
"__cached__ = __import__('importlib.util', fromlist=['cache_from_source']).cache_from_source(__file__)\n"
|
|
72
|
+
"if __spec__ is not None:\n __spec__.origin = __file__\n __spec__.loader = __loader__\n __spec__.cached = __cached__\n"
|
|
73
|
+
"exec(compile(globals().pop('__talaria_source__'), __file__, 'exec'), globals())\n").encode()
|
|
74
|
+
if len(_SOURCES) >= 512 or _SOURCE_BYTES + len(payload) > _MAX_SOURCE_BYTES:
|
|
75
|
+
raise RpcError('Agent dashboard source cache is full', condition='plugin_host_unavailable')
|
|
76
|
+
path = None
|
|
77
|
+
try:
|
|
78
|
+
if _SOURCE_DIRECTORY is None:
|
|
79
|
+
_SOURCE_DIRECTORY = tempfile.TemporaryDirectory(prefix='talaria-dashboard-source-')
|
|
80
|
+
path = Path(_SOURCE_DIRECTORY.name) / f'{key}.py'
|
|
81
|
+
with path.open('xb') as file:
|
|
82
|
+
file.write(payload)
|
|
83
|
+
path.chmod(0o400)
|
|
84
|
+
except OSError as exc:
|
|
85
|
+
if path is not None:
|
|
86
|
+
path.unlink(missing_ok=True)
|
|
87
|
+
raise RpcError('Agent dashboard source unavailable', condition='plugin_host_unavailable') from exc
|
|
88
|
+
_SOURCES[key] = (str(path.parent), path.name)
|
|
89
|
+
_SOURCE_BYTES += len(payload)
|
|
90
|
+
return _SOURCES[key]
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _path(raw):
|
|
94
|
+
if not isinstance(raw, str) or not raw or len(raw) > 512 or re.search(r'[\s\\?#\x00-\x1f]', raw):
|
|
95
|
+
return None
|
|
96
|
+
# No encoded path components: the caller decodes once before this trust boundary.
|
|
97
|
+
if '%' in raw or any(not p or p.startswith('.') for p in raw.split('/')):
|
|
98
|
+
return None
|
|
99
|
+
return raw
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _asset_root(plugin, home):
|
|
103
|
+
root = Path(plugin['_dir'])
|
|
104
|
+
if plugin.get('source') == 'user':
|
|
105
|
+
allowed = {Path(home) / 'plugins', _RAW_BASE_HOME / 'plugins', _BASE_HOME / 'plugins'}
|
|
106
|
+
if root.parent.parent not in allowed:
|
|
107
|
+
return None
|
|
108
|
+
for base in (_RAW_BASE_HOME, _BASE_HOME):
|
|
109
|
+
try:
|
|
110
|
+
relative = root.relative_to(base)
|
|
111
|
+
except ValueError:
|
|
112
|
+
continue
|
|
113
|
+
return _BASE_HOME / relative, _BASE_HOME
|
|
114
|
+
return None
|
|
115
|
+
from hermes_cli.plugins import get_bundled_plugins_dir
|
|
116
|
+
bundled = Path(get_bundled_plugins_dir())
|
|
117
|
+
if root.parent.parent not in {bundled, bundled / 'memory'}:
|
|
118
|
+
return None
|
|
119
|
+
# The Agent source is trusted; its plugins directory and every descendant are still opened no-follow.
|
|
120
|
+
anchor = bundled.parent.resolve()
|
|
121
|
+
return anchor / root.relative_to(bundled.parent), anchor
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _read(root: Path, rel: str, limit=_MAX_ASSET, *, anchor: Path):
|
|
125
|
+
"""Open from the trusted home/source, rejecting symlinks in every root and asset component."""
|
|
126
|
+
if not _path(rel):
|
|
127
|
+
return None
|
|
128
|
+
fd = None
|
|
129
|
+
try:
|
|
130
|
+
relative = root.relative_to(anchor)
|
|
131
|
+
if any(part == '..' for part in relative.parts):
|
|
132
|
+
return None
|
|
133
|
+
# Even an ancestor replaced after anchor canonicalization cannot redirect this traversal.
|
|
134
|
+
parts = [*anchor.parts[1:], *relative.parts, *rel.split('/')]
|
|
135
|
+
fd = os.open(anchor.anchor, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW)
|
|
136
|
+
for i, part in enumerate(parts):
|
|
137
|
+
child = os.open(part, os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK |
|
|
138
|
+
(os.O_DIRECTORY if i < len(parts) - 1 else 0), dir_fd=fd)
|
|
139
|
+
os.close(fd)
|
|
140
|
+
fd = child
|
|
141
|
+
if not stat.S_ISREG(os.fstat(fd).st_mode) or os.fstat(fd).st_size > limit:
|
|
142
|
+
return None
|
|
143
|
+
with os.fdopen(fd, 'rb') as file:
|
|
144
|
+
fd = None
|
|
145
|
+
body = file.read(limit + 1)
|
|
146
|
+
return body if len(body) <= limit else None
|
|
147
|
+
except (OSError, ValueError):
|
|
148
|
+
return None
|
|
149
|
+
finally:
|
|
150
|
+
if fd is not None:
|
|
151
|
+
os.close(fd)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def _supported():
|
|
155
|
+
if not getattr(os, 'O_NOFOLLOW', 0) or os.open not in os.supports_dir_fd:
|
|
156
|
+
return False
|
|
157
|
+
try:
|
|
158
|
+
from hermes_cli.plugin_host import PluginHost
|
|
159
|
+
from hermes_cli.web_server_plugin_profiles import _scan_profile_plugins # noqa: F401
|
|
160
|
+
return 'authenticated' in inspect.signature(PluginHost.asgi_request).parameters
|
|
161
|
+
except (ImportError, AttributeError, ValueError):
|
|
162
|
+
return False
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def _plugins(home):
|
|
166
|
+
from hermes_cli.web_server_plugin_profiles import _scan_profile_plugins
|
|
167
|
+
from hermes_cli.web_server_dashboard import _plugin_api_mount_skip_reason, _plugin_enable_sets_here
|
|
168
|
+
enabled, disabled = _plugin_enable_sets_here()
|
|
169
|
+
out = []
|
|
170
|
+
for plugin in _scan_profile_plugins(home):
|
|
171
|
+
name = plugin.get('name')
|
|
172
|
+
if not isinstance(name, str) or not _NAME.fullmatch(name) or plugin.get('source') not in ('user', 'bundled'):
|
|
173
|
+
continue
|
|
174
|
+
located = _asset_root(plugin, home)
|
|
175
|
+
if located is None:
|
|
176
|
+
continue
|
|
177
|
+
root, anchor = located
|
|
178
|
+
raw = _read(root, 'manifest.json', 64 * 1024, anchor=anchor)
|
|
179
|
+
try:
|
|
180
|
+
manifest = json.loads(raw) if raw else {}
|
|
181
|
+
except (ValueError, UnicodeDecodeError):
|
|
182
|
+
continue
|
|
183
|
+
if not isinstance(manifest, dict):
|
|
184
|
+
continue
|
|
185
|
+
# The existing Web protocol's panel opt-in distinguishes Web documents from native Desktop SDK bundles.
|
|
186
|
+
panel = manifest.get('panel')
|
|
187
|
+
compatible = isinstance(panel, str) and len(panel) <= 256 and _path(panel) and panel.startswith(('dist/', 'static/')) and panel.endswith('.html')
|
|
188
|
+
out.append({**plugin, '_dir': str(root), '_asset_anchor': str(anchor), 'panel': panel if compatible else None,
|
|
189
|
+
'enabled': _plugin_api_mount_skip_reason(plugin, enabled, disabled) is None})
|
|
190
|
+
return out
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _named(home, name):
|
|
194
|
+
return next((p for p in _plugins(home) if p['name'] == name and p['enabled'] and p['panel']), None)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def _reply(status=404, body=b'', content_type='application/octet-stream'):
|
|
198
|
+
return {'status': status, 'body': base64.b64encode(body).decode('ascii'), 'content_type': content_type}
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def _request(ctx, plugin, params):
|
|
202
|
+
ctx.check_cancelled()
|
|
203
|
+
if params.get('authenticated') is not True:
|
|
204
|
+
return _reply()
|
|
205
|
+
path = params.get('path', '')
|
|
206
|
+
rel = path.lstrip('/')
|
|
207
|
+
if path != '/' and (_path(rel) is None or path != '/' + rel):
|
|
208
|
+
return _reply()
|
|
209
|
+
headers = [(k.lower(), str(v)) for k, v in params.get('headers', {}).items() if k.lower() in _HEADERS]
|
|
210
|
+
if params.get('websocket') or any(k == 'accept' and 'text/event-stream' in v.lower() for k, v in headers):
|
|
211
|
+
return _reply(501, b'Agent plugin host supports buffered HTTP only', 'text/plain; charset=utf-8')
|
|
212
|
+
api = plugin.get('_api_file')
|
|
213
|
+
if not isinstance(api, str) or not _path(api):
|
|
214
|
+
return _reply()
|
|
215
|
+
source = _read(Path(plugin['_dir']), api, anchor=Path(plugin['_asset_anchor']))
|
|
216
|
+
if source is None:
|
|
217
|
+
return _reply()
|
|
218
|
+
from hermes_cli.plugins import get_plugin_manager
|
|
219
|
+
body = base64.b64decode(params.get('body') or '', validate=True)
|
|
220
|
+
if len(body) > _MAX_API:
|
|
221
|
+
return _reply(413)
|
|
222
|
+
query = urlencode([(k, v) for k, v in parse_qsl(params.get('query', ''), keep_blank_values=True)
|
|
223
|
+
if k.lower() not in _QUERY_CREDENTIALS])
|
|
224
|
+
method = params.get('method', 'GET')
|
|
225
|
+
if method not in {'GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'}:
|
|
226
|
+
raise InvalidParams('Unsupported plugin HTTP method')
|
|
227
|
+
root, snapshot_api = _api_source(plugin['_dir'], api, source)
|
|
228
|
+
ctx.check_cancelled()
|
|
229
|
+
try:
|
|
230
|
+
result = get_plugin_manager()._plugin_host().asgi_request(
|
|
231
|
+
plugin['name'], root, snapshot_api, method, path, query, headers, body,
|
|
232
|
+
timeout=10.0, authenticated=True)
|
|
233
|
+
except TimeoutError:
|
|
234
|
+
ctx.check_cancelled()
|
|
235
|
+
return _reply(504)
|
|
236
|
+
except Exception as exc:
|
|
237
|
+
# Third-party errors may contain credentials or file paths.
|
|
238
|
+
raise RpcError('Agent plugin request failed', condition='plugin_host_unavailable') from exc
|
|
239
|
+
ctx.check_cancelled()
|
|
240
|
+
content_type = next((v for k, v in result.get('headers', []) if k.lower() == 'content-type'), 'application/octet-stream')
|
|
241
|
+
if 'text/event-stream' in content_type.lower():
|
|
242
|
+
return _reply(501, b'Agent plugin host supports buffered HTTP only', 'text/plain; charset=utf-8')
|
|
243
|
+
if _named(homes.profile_home_param(params), plugin['name']) is None:
|
|
244
|
+
return _reply()
|
|
245
|
+
raw = result.get('body', b'')
|
|
246
|
+
if not isinstance(raw, bytes) or len(raw) > _MAX_API:
|
|
247
|
+
return _reply(502)
|
|
248
|
+
status = result.get('status', 502)
|
|
249
|
+
return _reply(status if isinstance(status, int) and 200 <= status <= 599 else 502, raw, content_type)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def register(registry):
|
|
253
|
+
def run(ctx, params, action):
|
|
254
|
+
ctx.check_cancelled()
|
|
255
|
+
if not _supported():
|
|
256
|
+
if action == 'list':
|
|
257
|
+
return {'supported': False, 'plugins': []}
|
|
258
|
+
if action == 'toggle':
|
|
259
|
+
raise RpcError('Agent dashboard host unsupported', condition='agent_incompatible')
|
|
260
|
+
return _reply(501)
|
|
261
|
+
home = homes.profile_home_param(params)
|
|
262
|
+
with homes.scoped_home(home, load_plugins=False):
|
|
263
|
+
if action == 'list':
|
|
264
|
+
return {'supported': True, 'plugins': [
|
|
265
|
+
{'name': p['name'], 'label': str(p.get('label') or p['name'])[:80],
|
|
266
|
+
'version': str(p.get('version') or '')[:40], 'description': str(p.get('description') or '')[:300],
|
|
267
|
+
'enabled': p['enabled'], 'panel': p['panel'], 'has_api': bool(p.get('_api_file'))}
|
|
268
|
+
for p in _plugins(home)]}
|
|
269
|
+
name = params.get('name')
|
|
270
|
+
if not isinstance(name, str) or not _NAME.fullmatch(name):
|
|
271
|
+
if action == 'toggle':
|
|
272
|
+
raise InvalidParams('Unknown Web dashboard plugin')
|
|
273
|
+
return _reply()
|
|
274
|
+
if action == 'toggle':
|
|
275
|
+
plugin = next((p for p in _plugins(home) if p['name'] == name and p['panel']), None)
|
|
276
|
+
if plugin is None or not isinstance(params.get('enabled'), bool):
|
|
277
|
+
raise InvalidParams('Unknown Web dashboard plugin or invalid enablement')
|
|
278
|
+
from hermes_cli.plugins_cmd import _activate_key, _resolve_plugin_key
|
|
279
|
+
key = _resolve_plugin_key(name)
|
|
280
|
+
if key is None:
|
|
281
|
+
raise InvalidParams('Plugin is not installed')
|
|
282
|
+
# Use the Agent admission transaction, without activate_plugin_now (in-process imports).
|
|
283
|
+
_activate_key(key, enable=params['enabled'])
|
|
284
|
+
return {'ok': True}
|
|
285
|
+
plugin = _named(home, name)
|
|
286
|
+
if plugin is None:
|
|
287
|
+
return _reply()
|
|
288
|
+
if action == 'request':
|
|
289
|
+
return _request(ctx, plugin, params)
|
|
290
|
+
path = params.get('path', '')
|
|
291
|
+
if not isinstance(path, str) or not path.startswith(('dist/', 'static/')):
|
|
292
|
+
return _reply()
|
|
293
|
+
content_type = _MIME.get(Path(path).suffix.lower())
|
|
294
|
+
body = _read(Path(plugin['_dir']), path, anchor=Path(plugin['_asset_anchor'])) if content_type else None
|
|
295
|
+
ctx.check_cancelled()
|
|
296
|
+
return _reply(200, body, content_type) if body is not None else _reply()
|
|
297
|
+
|
|
298
|
+
for action in ('list', 'toggle', 'asset', 'request'):
|
|
299
|
+
def handler(ctx, params, action=action):
|
|
300
|
+
return run(ctx, params, action)
|
|
301
|
+
registry.method(f'plugins.dashboard_{action}')(handler)
|