@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
|
@@ -7,17 +7,20 @@ server; the sidecar receives typed params.
|
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
|
+
import functools
|
|
10
11
|
import json
|
|
11
12
|
import secrets
|
|
12
13
|
import time
|
|
13
14
|
from dataclasses import asdict, is_dataclass
|
|
14
|
-
from typing import Any
|
|
15
|
+
from typing import Any, NamedTuple
|
|
15
16
|
|
|
16
17
|
from ..errors import InvalidParams, RpcError
|
|
17
18
|
from ..home import profile_home_param, scoped_home
|
|
18
19
|
from ..rpc import CallContext
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
# Agent 2026.9.24 predates ``kanban_workflow``; its ``VALID_STATUSES`` set holds these columns, in this board order.
|
|
22
|
+
# Delete with that release's entry in ``agent_support.json``.
|
|
23
|
+
_LEGACY_COLUMNS = ("triage", "todo", "scheduled", "ready", "running", "blocked", "review", "done")
|
|
21
24
|
|
|
22
25
|
|
|
23
26
|
class NotFound(RpcError):
|
|
@@ -38,6 +41,27 @@ def _kb():
|
|
|
38
41
|
return kb
|
|
39
42
|
|
|
40
43
|
|
|
44
|
+
class _Workflow(NamedTuple):
|
|
45
|
+
columns: tuple[tuple[str, str], ...] # (key, label) in board order
|
|
46
|
+
manual: dict | None # src -> [dst]; None on an Agent without a move table
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@functools.cache
|
|
50
|
+
def _workflow() -> _Workflow:
|
|
51
|
+
"""The Agent's board columns and manual move table from ``kanban_workflow.DEFAULT_WORKFLOW`` (Agent 0.21.6+, TAL-796)."""
|
|
52
|
+
try:
|
|
53
|
+
from hermes_cli.kanban_workflow import DEFAULT_WORKFLOW
|
|
54
|
+
except ImportError:
|
|
55
|
+
statuses = getattr(_kb(), "VALID_STATUSES", _LEGACY_COLUMNS)
|
|
56
|
+
return _Workflow(tuple((key, key.title()) for key in _LEGACY_COLUMNS if key in statuses), None)
|
|
57
|
+
workflow = DEFAULT_WORKFLOW.to_dict()
|
|
58
|
+
return _Workflow(tuple((c["key"], c["label"]) for c in workflow["columns"]), workflow["manual"])
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _columns() -> list[str]:
|
|
62
|
+
return [key for key, _ in _workflow().columns]
|
|
63
|
+
|
|
64
|
+
|
|
41
65
|
def _board(params: dict):
|
|
42
66
|
raw = params.get("board")
|
|
43
67
|
if raw is None or (isinstance(raw, str) and raw.strip() == ""):
|
|
@@ -49,9 +73,16 @@ def _board(params: dict):
|
|
|
49
73
|
raise InvalidParams(f"invalid board slug: {raw!r}") from exc
|
|
50
74
|
if not normed:
|
|
51
75
|
return None
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
76
|
+
if normed == getattr(kb, "DEFAULT_BOARD", "default"):
|
|
77
|
+
return normed
|
|
78
|
+
return _live_board(kb, normed, normed)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _live_board(kb, normed: str, shown, *, archived_ok: bool = False) -> str:
|
|
82
|
+
"""``normed`` when it names a live board. Agent 0.21.6 leaves an ``archived`` ``board.json`` tombstone at an
|
|
83
|
+
archived board's slug, so ``board_exists`` alone would let a stale link reach it (TAL-795)."""
|
|
84
|
+
if not kb.board_exists(normed) or (not archived_ok and kb.read_board_metadata(normed).get("archived")):
|
|
85
|
+
raise NotFound(f"board {shown!r} does not exist")
|
|
55
86
|
return normed
|
|
56
87
|
|
|
57
88
|
|
|
@@ -66,8 +97,6 @@ def _connect_module():
|
|
|
66
97
|
|
|
67
98
|
|
|
68
99
|
def _conn(board=None):
|
|
69
|
-
kb = _kb()
|
|
70
|
-
kb.init_db(board=board)
|
|
71
100
|
module = _connect_module()
|
|
72
101
|
closing = getattr(module, "connect_closing", None)
|
|
73
102
|
return closing(board=board) if closing is not None else module.connect(board=board)
|
|
@@ -197,6 +226,8 @@ def _task_dict(task, conn):
|
|
|
197
226
|
# stored or supplied evidence, and refuses to release a live worker's claim.
|
|
198
227
|
data["claim_live"] = data.get("status") == "running" and _claim_live(conn, data.get("id"))
|
|
199
228
|
data["has_completion_evidence"] = bool(str(data.get("result") or "").strip())
|
|
229
|
+
manual = _workflow().manual
|
|
230
|
+
data["agent_move_targets"] = None if manual is None else list(manual.get(data.get("status"), []))
|
|
200
231
|
try:
|
|
201
232
|
age = _kb().task_age(task)
|
|
202
233
|
except Exception: # noqa: BLE001
|
|
@@ -237,8 +268,13 @@ def _comment_counts(conn):
|
|
|
237
268
|
|
|
238
269
|
def _validate_status(status: str) -> str:
|
|
239
270
|
value = str(status or "").strip().lower()
|
|
240
|
-
if value not in
|
|
271
|
+
if value not in {*_columns(), "archived"}:
|
|
241
272
|
raise InvalidParams(f"invalid status: {value}")
|
|
273
|
+
if value == "running":
|
|
274
|
+
raise InvalidParams("Cannot set status to 'running' directly; use the dispatcher/claim path")
|
|
275
|
+
if value in ("scheduled", "review"):
|
|
276
|
+
# The Agent reaches these through verbs with extra input (a wake time, a reviewer), which Talaria does not offer.
|
|
277
|
+
raise InvalidParams(f"Cannot set status to {value!r} directly")
|
|
242
278
|
return value
|
|
243
279
|
|
|
244
280
|
|
|
@@ -327,19 +363,21 @@ def _patch_task(conn, task_id: str, body: dict) -> None:
|
|
|
327
363
|
elif status == "archived":
|
|
328
364
|
if not _fenced(conn, task_id, lambda: kb.archive_task(conn, task_id), confirm_running_exit=confirm, releases_claim=False):
|
|
329
365
|
raise NotFound("task not found")
|
|
330
|
-
|
|
331
|
-
raise InvalidParams("Cannot set status to 'running' directly; use the dispatcher/claim path")
|
|
332
|
-
elif status == "ready":
|
|
366
|
+
else:
|
|
333
367
|
current = kb.get_task(conn, task_id)
|
|
334
368
|
if not current:
|
|
335
369
|
raise NotFound("task not found")
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
370
|
+
# Like the Agent's dashboard: leaving review reopens it, and blocked/scheduled -> ready unblocks; both re-gate on
|
|
371
|
+
# parents. Triage is a direct write there too. The reopen lands in ready whatever the target, so todo is refused.
|
|
372
|
+
if current.status == "review" and status == "todo":
|
|
373
|
+
raise Conflict("A task in review reopens to ready")
|
|
374
|
+
if current.status == "review" and status == "ready":
|
|
375
|
+
ok = kb.reopen_review_task(conn, task_id)
|
|
376
|
+
elif status == "ready" and current.status in ("blocked", "scheduled"):
|
|
377
|
+
ok = kb.unblock_task(conn, task_id)
|
|
378
|
+
else:
|
|
379
|
+
ok = _set_status_direct(conn, task_id, status, confirm_running_exit=confirm)
|
|
380
|
+
if not ok:
|
|
343
381
|
raise NotFound("task not found")
|
|
344
382
|
|
|
345
383
|
|
|
@@ -373,15 +411,15 @@ def _board_counts(slug):
|
|
|
373
411
|
pass
|
|
374
412
|
|
|
375
413
|
|
|
376
|
-
def _normalize_existing_slug(slug) -> str:
|
|
414
|
+
def _normalize_existing_slug(slug, *, archived_ok: bool = False) -> str:
|
|
377
415
|
kb = _kb()
|
|
378
416
|
try:
|
|
379
417
|
normed = kb._normalize_board_slug(slug)
|
|
380
418
|
except (ValueError, AttributeError) as exc:
|
|
381
419
|
raise InvalidParams(f"invalid board slug: {slug!r}") from exc
|
|
382
|
-
if not normed
|
|
420
|
+
if not normed:
|
|
383
421
|
raise NotFound(f"board {slug!r} does not exist")
|
|
384
|
-
return normed
|
|
422
|
+
return _live_board(kb, normed, slug, archived_ok=archived_ok)
|
|
385
423
|
|
|
386
424
|
|
|
387
425
|
def _current_board() -> str:
|
|
@@ -449,9 +487,9 @@ def board_payload(params: dict) -> dict:
|
|
|
449
487
|
data["comment_count"] = comment_counts.get(task.id, 0)
|
|
450
488
|
return data
|
|
451
489
|
|
|
452
|
-
columns = [{"name":
|
|
490
|
+
columns = [{"name": key, "label": label, "tasks": [row(t) for t in tasks if t.status == key]} for key, label in _workflow().columns]
|
|
453
491
|
if include_archived:
|
|
454
|
-
columns.append({"name": "archived", "tasks": [row(t) for t in tasks if t.status == "archived"]})
|
|
492
|
+
columns.append({"name": "archived", "label": "Archived", "tasks": [row(t) for t in tasks if t.status == "archived"]})
|
|
455
493
|
return {
|
|
456
494
|
"columns": columns,
|
|
457
495
|
"tenants": sorted({t.tenant for t in tasks if getattr(t, "tenant", None)}),
|
|
@@ -472,6 +510,8 @@ def create_task_payload(params: dict) -> dict:
|
|
|
472
510
|
priority = int(body.get("priority") or 0)
|
|
473
511
|
except (TypeError, ValueError):
|
|
474
512
|
raise InvalidParams("priority must be an integer")
|
|
513
|
+
# Checked before the insert, so a refused status leaves no task behind.
|
|
514
|
+
status = _validate_status(body.get("status")) if body.get("status") else None
|
|
475
515
|
kb = _kb()
|
|
476
516
|
with _conn(board=_board(params)) as conn:
|
|
477
517
|
task_id = kb.create_task(
|
|
@@ -480,8 +520,8 @@ def create_task_payload(params: dict) -> dict:
|
|
|
480
520
|
workspace_kind=body.get("workspace_kind") or "scratch", workspace_path=body.get("workspace_path") or None,
|
|
481
521
|
idempotency_key=body.get("idempotency_key") or None, max_runtime_seconds=body.get("max_runtime_seconds") or None, skills=body.get("skills") or None,
|
|
482
522
|
)
|
|
483
|
-
if
|
|
484
|
-
_patch_task(conn, task_id, {"status":
|
|
523
|
+
if status:
|
|
524
|
+
_patch_task(conn, task_id, {"status": status})
|
|
485
525
|
return {"task": _task_dict(kb.get_task(conn, task_id), conn), "read_only": False}
|
|
486
526
|
|
|
487
527
|
|
|
@@ -534,11 +574,17 @@ def task_detail_payload(params: dict) -> dict:
|
|
|
534
574
|
task = kb.get_task(conn, task_id)
|
|
535
575
|
if not task:
|
|
536
576
|
raise NotFound("task not found")
|
|
577
|
+
data = _task_dict(task, conn)
|
|
578
|
+
# ``started_at`` is the first-ever start; a retried task's run clock counts from its current run (TAL-809).
|
|
579
|
+
data["current_run_started_at"] = kb.current_run_started_ats(conn, [task_id]).get(task_id)
|
|
580
|
+
links = {"parents": kb.parent_ids(conn, task_id), "children": kb.child_ids(conn, task_id)}
|
|
581
|
+
linked = (kb.get_task(conn, link_id) for link_id in dict.fromkeys([*links["parents"], *links["children"]]))
|
|
537
582
|
return {
|
|
538
|
-
"task":
|
|
583
|
+
"task": data,
|
|
539
584
|
"comments": [_obj_dict(c) for c in kb.list_comments(conn, task_id)],
|
|
540
585
|
"events": [_obj_dict(e) for e in kb.list_events(conn, task_id)],
|
|
541
|
-
"links":
|
|
586
|
+
"links": links,
|
|
587
|
+
"link_tasks": [{"id": t.id, "title": t.title, "status": t.status} for t in linked if t],
|
|
542
588
|
"runs": [_obj_dict(r) for r in kb.list_runs(conn, task_id)],
|
|
543
589
|
"read_only": False,
|
|
544
590
|
}
|
|
@@ -547,6 +593,7 @@ def task_detail_payload(params: dict) -> dict:
|
|
|
547
593
|
def events_payload(params: dict) -> dict:
|
|
548
594
|
since = _int(params, "since", 0, minimum=0)
|
|
549
595
|
limit = _int(params, "limit", 200, minimum=1, maximum=200)
|
|
596
|
+
kb = _kb()
|
|
550
597
|
with _conn(board=_board(params)) as conn:
|
|
551
598
|
rows = conn.execute(
|
|
552
599
|
"SELECT id, task_id, run_id, kind, payload, created_at FROM task_events WHERE id > ? ORDER BY id ASC LIMIT ?", (since, limit)
|
|
@@ -557,7 +604,7 @@ def events_payload(params: dict) -> dict:
|
|
|
557
604
|
payload = json.loads(row["payload"]) if row["payload"] else None
|
|
558
605
|
except Exception: # noqa: BLE001
|
|
559
606
|
payload = None
|
|
560
|
-
events.append({"id": row["id"], "task_id": row["task_id"], "run_id": row["run_id"], "kind": row["kind"], "payload": payload, "created_at": row["created_at"]})
|
|
607
|
+
events.append({"id": row["id"], "task_id": row["task_id"], "run_id": row["run_id"], "kind": row["kind"], "payload": payload, "created_at": kb._to_epoch(row["created_at"])})
|
|
561
608
|
cursor = int(row["id"])
|
|
562
609
|
latest = _latest_event_id(conn)
|
|
563
610
|
if not events:
|
|
@@ -583,13 +630,17 @@ def config_payload(params: dict) -> dict:
|
|
|
583
630
|
cfg = {}
|
|
584
631
|
k = ((cfg.get("dashboard") or {}).get("kanban") or {})
|
|
585
632
|
return {
|
|
586
|
-
"columns":
|
|
633
|
+
"columns": _columns(), "assignees": assignees, "default_tenant": k.get("default_tenant") or "",
|
|
587
634
|
"lane_by_profile": bool(k.get("lane_by_profile", True)), "include_archived_by_default": bool(k.get("include_archived_by_default", False)),
|
|
588
635
|
"render_markdown": bool(k.get("render_markdown", True)), "read_only": False,
|
|
589
636
|
}
|
|
590
637
|
|
|
591
638
|
|
|
592
639
|
def stats_payload(params: dict) -> dict:
|
|
640
|
+
return {**_stats(params), "column_order": _columns()}
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
def _stats(params: dict) -> dict:
|
|
593
644
|
kb = _kb()
|
|
594
645
|
with _conn(board=_board(params)) as conn:
|
|
595
646
|
if hasattr(kb, "board_stats"):
|
|
@@ -761,7 +812,8 @@ def create_board_payload(params: dict) -> dict:
|
|
|
761
812
|
def update_board_payload(params: dict) -> dict:
|
|
762
813
|
kb = _kb()
|
|
763
814
|
body = params.get("board_spec") or {}
|
|
764
|
-
|
|
815
|
+
# Metadata edits stay open on an archived board: clearing ``archived`` is how one archived in place comes back.
|
|
816
|
+
normed = _normalize_existing_slug(params.get("slug"), archived_ok=True)
|
|
765
817
|
kwargs = {}
|
|
766
818
|
if "default_workdir" in body:
|
|
767
819
|
kwargs["default_workdir"] = str(body.get("default_workdir") or "")
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""``memory.*``: the Agent's ``MemoryStore`` reading of a memory page save (TAL-886) and its compare-and-write (TAL-784)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import errno
|
|
6
|
+
import hashlib
|
|
7
|
+
import os
|
|
8
|
+
import stat
|
|
9
|
+
import threading
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
from ..errors import InvalidParams, RpcError
|
|
13
|
+
from ..home import profile_home_param, scoped_home
|
|
14
|
+
from ..rpc import CallContext
|
|
15
|
+
|
|
16
|
+
# Agents without the per-file lock helper: this sidecar's saves still run one at a time.
|
|
17
|
+
_SAVE_LOCK = threading.Lock()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def check(target: str, content: str) -> dict:
|
|
21
|
+
"""``content``'s char count as the Agent's memory tool parses it, and the profile's limit for ``target``."""
|
|
22
|
+
from hermes_cli.config import load_config
|
|
23
|
+
from tools.memory_tool_store import ENTRY_DELIMITER, MemoryStore
|
|
24
|
+
|
|
25
|
+
mem = (load_config() or {}).get("memory") or {}
|
|
26
|
+
store = MemoryStore(**{key: int(mem[key]) for key in ("memory_char_limit", "user_char_limit") if mem.get(key) is not None})
|
|
27
|
+
# The store keeps each entry once (first occurrence wins), as its load and write paths do.
|
|
28
|
+
entries = list(dict.fromkeys(MemoryStore._parse_entries(content)))
|
|
29
|
+
return {"count": len(ENTRY_DELIMITER.join(entries)), "limit": store._char_limit(target)}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _digest(path: Path) -> str | None:
|
|
33
|
+
"""SHA-256 hex of the regular file at ``path`` (of no bytes when there is none), never following a link; None otherwise."""
|
|
34
|
+
try:
|
|
35
|
+
fd = os.open(path, os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0) | getattr(os, "O_NONBLOCK", 0))
|
|
36
|
+
except FileNotFoundError:
|
|
37
|
+
return hashlib.sha256(b"").hexdigest()
|
|
38
|
+
except OSError as exc:
|
|
39
|
+
if exc.errno == errno.ELOOP:
|
|
40
|
+
return None
|
|
41
|
+
raise
|
|
42
|
+
with os.fdopen(fd, "rb") as handle:
|
|
43
|
+
if not stat.S_ISREG(os.fstat(handle.fileno()).st_mode):
|
|
44
|
+
return None
|
|
45
|
+
return hashlib.sha256(handle.read()).hexdigest()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def write(home: Path, section: str, base: str, content: str) -> dict:
|
|
49
|
+
"""Replace ``section``'s file with ``content`` only while its bytes still hash to ``base``, the server's read.
|
|
50
|
+
|
|
51
|
+
Each file is checked and written under the Agent's own per-file lock (``<file>.lock``), so neither a memory tool
|
|
52
|
+
call nor a concurrent save can land between the two; an Agent without the lock helper gets this sidecar's lock.
|
|
53
|
+
"""
|
|
54
|
+
from tools.memory_tool_store import MemoryStore
|
|
55
|
+
from utils import atomic_write_text
|
|
56
|
+
|
|
57
|
+
if section not in ("memory", "user", "soul"):
|
|
58
|
+
raise InvalidParams("section must be memory, user, or soul")
|
|
59
|
+
# The files the server read: SOUL.md in the profile home, MEMORY.md / USER.md in its memories folder.
|
|
60
|
+
path = home / "SOUL.md" if section == "soul" else home / "memories" / ("USER.md" if section == "user" else "MEMORY.md")
|
|
61
|
+
file_lock = getattr(MemoryStore, "_file_lock", None)
|
|
62
|
+
try:
|
|
63
|
+
with file_lock(path) if file_lock else _SAVE_LOCK:
|
|
64
|
+
if _digest(path) != base:
|
|
65
|
+
return {"written": False}
|
|
66
|
+
atomic_write_text(path, content, tmp_prefix=".mem_", preserve_mode=True)
|
|
67
|
+
except OSError as exc:
|
|
68
|
+
if exc.errno not in (errno.EACCES, errno.EPERM, errno.EROFS):
|
|
69
|
+
raise
|
|
70
|
+
raise RpcError(f"{path.name} is not writable: {exc.strerror}", condition="memory_not_writable") from exc
|
|
71
|
+
return {"written": True}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def register(registry) -> None:
|
|
75
|
+
@registry.method("memory.check")
|
|
76
|
+
def check_(ctx: CallContext, params: dict) -> dict:
|
|
77
|
+
with scoped_home(profile_home_param(params)):
|
|
78
|
+
return check(str(params["target"]), str(params["content"]))
|
|
79
|
+
|
|
80
|
+
@registry.method("memory.write")
|
|
81
|
+
def write_(ctx: CallContext, params: dict) -> dict:
|
|
82
|
+
home = profile_home_param(params)
|
|
83
|
+
with scoped_home(home):
|
|
84
|
+
return write(home, str(params["section"]), str(params["base"]), str(params["content"]))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
"""``oauth.*``: the Agent's device-code sign-ins for Nous Portal, OpenAI Codex, xAI and MiniMax (TAL-398)
|
|
1
|
+
"""``oauth.*``: the Agent's device-code sign-ins for Nous Portal, OpenAI Codex, xAI and MiniMax (TAL-398), and the
|
|
2
|
+
browser sign-in of a plugin-declared OAuth client (``plugin:<key>:<id>``, TAL-1276, in ``plugin_oauth``).
|
|
2
3
|
|
|
3
4
|
``oauth.start`` asks the provider for a code and answers what the user has to see; a daemon thread then waits for the
|
|
4
5
|
approval and saves the credential with the Agent's own auth-store helpers under the flow's profile home, the steps its
|
|
@@ -9,9 +10,12 @@ Flows live in this process only.
|
|
|
9
10
|
|
|
10
11
|
from __future__ import annotations
|
|
11
12
|
|
|
13
|
+
import contextlib
|
|
14
|
+
import inspect
|
|
12
15
|
import logging
|
|
13
16
|
import os
|
|
14
17
|
import secrets
|
|
18
|
+
import ssl
|
|
15
19
|
import threading
|
|
16
20
|
import time
|
|
17
21
|
from dataclasses import dataclass, field
|
|
@@ -22,6 +26,7 @@ from typing import Any, Callable
|
|
|
22
26
|
from ..errors import InvalidParams, RpcError
|
|
23
27
|
from ..home import profile_home_param, scoped_home
|
|
24
28
|
from ..rpc import CallContext
|
|
29
|
+
from . import plugin_oauth
|
|
25
30
|
|
|
26
31
|
log = logging.getLogger("talaria_sidecar.oauth")
|
|
27
32
|
|
|
@@ -31,6 +36,8 @@ _CODEX_EXPIRES_IN = 15 * 60 # OpenAI's device-code lifetime, as the Agent dashb
|
|
|
31
36
|
_ENDED_TTL = 10 * 60
|
|
32
37
|
# A pending flow past its code's expiry by this much ends expired even if its provider call has not returned yet.
|
|
33
38
|
_EXPIRY_GRACE = 60
|
|
39
|
+
# How long a start waits for the flows it replaces to close their loopback listeners.
|
|
40
|
+
_RELEASE_WAIT = 5.0
|
|
34
41
|
|
|
35
42
|
_DENIED = "Sign-in was declined."
|
|
36
43
|
_EXPIRED = "The sign-in code expired before it was approved."
|
|
@@ -55,6 +62,17 @@ class Flow:
|
|
|
55
62
|
cancelled: threading.Event = field(default_factory=threading.Event)
|
|
56
63
|
# Serialises the cancel check with the credential save: a cancel cannot land between them.
|
|
57
64
|
lock: threading.Lock = field(default_factory=threading.Lock)
|
|
65
|
+
# The credential is saved but the sign-in has not finished (a guest sign-in still settles the account): a cancel or
|
|
66
|
+
# an expiry can no longer undo it, and the flow stays pending until its own ending.
|
|
67
|
+
committed: bool = False
|
|
68
|
+
# A browser sign-in also finishes from the redirect address the user pastes (``oauth.submit_redirect``).
|
|
69
|
+
submit: Callable[[str], None] | None = None
|
|
70
|
+
# Set once a browser sign-in's loopback listener is closed, so a replacing start can bind the same fixed port.
|
|
71
|
+
closed: threading.Event | None = None
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def stoppable(self) -> bool:
|
|
75
|
+
return self.status == "pending" and not self.committed
|
|
58
76
|
|
|
59
77
|
def end(self, status: str, error: str | None = None) -> None:
|
|
60
78
|
self.status, self.error, self.ended_at = status, error, time.time()
|
|
@@ -107,9 +125,24 @@ def _now_z() -> str:
|
|
|
107
125
|
|
|
108
126
|
|
|
109
127
|
def _client(timeout: float, **kwargs: Any) -> Any:
|
|
128
|
+
"""Every flow's HTTP client, verifying TLS as the Agent's own sign-in does: the OS trust store, and (v0.22.3+) a
|
|
129
|
+
certifi bundle an install-environment rotation deleted under this process, re-derived process-wide."""
|
|
110
130
|
import httpx
|
|
111
131
|
|
|
112
|
-
return httpx.Client(timeout=httpx.Timeout(timeout), headers={"Accept": "application/json"}, **kwargs)
|
|
132
|
+
return httpx.Client(timeout=httpx.Timeout(timeout), headers={"Accept": "application/json"}, verify=_verify(), **kwargs)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def _verify() -> Any:
|
|
136
|
+
try:
|
|
137
|
+
from agent.ssl_verify import resolve_httpx_verify
|
|
138
|
+
except ImportError: # an Agent without it keeps httpx's default
|
|
139
|
+
return True
|
|
140
|
+
verify = resolve_httpx_verify()
|
|
141
|
+
# The resolver hands over the platform store alone when SSL_CERT_FILE/SSL_CERT_DIR is set; httpx's default trusted
|
|
142
|
+
# that bundle, so keep it, on top of the platform store the resolver installed (as ``platform_ssl_context`` does).
|
|
143
|
+
cafile, capath = os.environ.get("SSL_CERT_FILE", "").strip(), os.environ.get("SSL_CERT_DIR", "").strip()
|
|
144
|
+
cafile, capath = (cafile if os.path.isfile(cafile) else None), (capath if os.path.isdir(capath) else None)
|
|
145
|
+
return ssl.create_default_context(cafile=cafile, capath=capath) if cafile or capath else verify
|
|
113
146
|
|
|
114
147
|
|
|
115
148
|
# ── providers: (begin, wait, save) over the Agent's own steps ──────────
|
|
@@ -121,10 +154,14 @@ def _nous_begin() -> tuple[dict, dict]:
|
|
|
121
154
|
from hermes_cli import anon_auth
|
|
122
155
|
from hermes_cli.auth import PROVIDER_REGISTRY, _request_device_code
|
|
123
156
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
157
|
+
# v0.22.0 replaced ``guest_enabled`` with ``guest_allowed``; 0.21.x releases only have the former.
|
|
158
|
+
guest_gate = getattr(anon_auth, "guest_allowed", None) or getattr(anon_auth, "guest_enabled")
|
|
159
|
+
if guest_gate() and anon_auth.has_guest():
|
|
160
|
+
# The native sign-in owns the guest's connector handoff for its installed protocol.
|
|
161
|
+
if hasattr(anon_auth, "run_sign_in"):
|
|
162
|
+
return _nous_sign_in(anon_auth)
|
|
163
|
+
hint = getattr(anon_auth, "UPGRADE_HINT", None) or "Sign in from Hermes with `hermes auth upgrade`."
|
|
164
|
+
raise RpcError(f"This profile uses the Nous free tier. {hint}", condition="oauth_unsupported")
|
|
128
165
|
pconfig = PROVIDER_REGISTRY["nous"]
|
|
129
166
|
portal = (os.getenv("HERMES_PORTAL_BASE_URL") or os.getenv("NOUS_PORTAL_BASE_URL") or pconfig.portal_base_url).rstrip("/")
|
|
130
167
|
with _client(15.0) as client:
|
|
@@ -133,7 +170,63 @@ def _nous_begin() -> tuple[dict, dict]:
|
|
|
133
170
|
return display, {"portal": portal, "client_id": pconfig.client_id, "scope": pconfig.scope, "device_code": str(data["device_code"])}
|
|
134
171
|
|
|
135
172
|
|
|
173
|
+
def _nous_sign_in(anon_auth: Any) -> tuple[dict, dict]:
|
|
174
|
+
"""Over a guest, the Agent's own sign-in (``anon_auth.run_sign_in``, as its dashboard runs it): it moves the guest's
|
|
175
|
+
connected apps to the account, then persists and settles the account itself. Its cancel check, persist guard and
|
|
176
|
+
home scope read the flow ``_nous_wait`` binds into the state; before that only ``start``'s first step runs, already
|
|
177
|
+
under the flow's home."""
|
|
178
|
+
state: dict = {}
|
|
179
|
+
|
|
180
|
+
def cancelled() -> bool:
|
|
181
|
+
flow = state.get("flow")
|
|
182
|
+
return flow is not None and flow.cancelled.is_set()
|
|
183
|
+
|
|
184
|
+
@contextlib.contextmanager
|
|
185
|
+
def persist_guard():
|
|
186
|
+
# As ``_run`` does for a plain save, the final cancel check and the save share the flow's lock; the flow ends
|
|
187
|
+
# approved only when the Agent has also settled the account, through ``_run``.
|
|
188
|
+
flow = state["flow"]
|
|
189
|
+
with flow.lock:
|
|
190
|
+
may_persist = flow.status == "pending"
|
|
191
|
+
yield may_persist
|
|
192
|
+
if may_persist:
|
|
193
|
+
flow.committed = True
|
|
194
|
+
|
|
195
|
+
def scope():
|
|
196
|
+
flow = state.get("flow")
|
|
197
|
+
return scoped_home(flow.home) if flow is not None else contextlib.nullcontext()
|
|
198
|
+
|
|
199
|
+
# Older Agents use promotion; v0.22.5 removed its option in favor of plain device login and native handoff.
|
|
200
|
+
options = {"cancel_wins_after_promotion": True} if "cancel_wins_after_promotion" in inspect.signature(anon_auth.run_sign_in).parameters else {}
|
|
201
|
+
sign_in = anon_auth.run_sign_in(cancelled=cancelled, persist_guard=persist_guard, scope=scope, **options)
|
|
202
|
+
first = next(sign_in)
|
|
203
|
+
if first.kind != "code":
|
|
204
|
+
sign_in.close()
|
|
205
|
+
raise RpcError(first.copy_terminal, condition="oauth_unsupported" if first.precondition else "oauth_failed")
|
|
206
|
+
state["sign_in"] = sign_in
|
|
207
|
+
return {"user_code": first.code, "verification_url": first.link, "expires_in": first.expires_in, "interval": first.interval}, state
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
class _SignInEnded(Exception):
|
|
211
|
+
"""A guest sign-in that ended without an account; ``code`` lets ``_ending`` classify a decline and an expiry."""
|
|
212
|
+
|
|
213
|
+
def __init__(self, ended: Any):
|
|
214
|
+
super().__init__(ended.copy)
|
|
215
|
+
self.code = {"declined": "access_denied", "timed_out": "expired_token"}.get(ended.kind, ended.kind)
|
|
216
|
+
|
|
217
|
+
|
|
136
218
|
def _nous_wait(flow: Flow, state: dict) -> dict:
|
|
219
|
+
sign_in = state.get("sign_in")
|
|
220
|
+
if sign_in is not None:
|
|
221
|
+
state["flow"] = flow
|
|
222
|
+
try:
|
|
223
|
+
for ended in sign_in: # the generator always ends on one terminal state
|
|
224
|
+
pass
|
|
225
|
+
finally:
|
|
226
|
+
sign_in.close()
|
|
227
|
+
if not ended.ok:
|
|
228
|
+
raise _SignInEnded(ended)
|
|
229
|
+
return {}
|
|
137
230
|
from hermes_cli.auth import _poll_for_token
|
|
138
231
|
|
|
139
232
|
with _client(15.0) as client:
|
|
@@ -142,6 +235,8 @@ def _nous_wait(flow: Flow, state: dict) -> dict:
|
|
|
142
235
|
|
|
143
236
|
|
|
144
237
|
def _nous_save(flow: Flow, state: dict, token_data: dict) -> None:
|
|
238
|
+
if "sign_in" in state: # the guest sign-in persisted and settled the account itself
|
|
239
|
+
return
|
|
145
240
|
from hermes_cli import anon_auth
|
|
146
241
|
from hermes_cli.auth import persist_nous_credentials, refresh_nous_oauth_from_state
|
|
147
242
|
|
|
@@ -210,8 +305,10 @@ def _codex_save(flow: Flow, state: dict, tokens: dict) -> None:
|
|
|
210
305
|
def _xai_begin() -> tuple[dict, dict]:
|
|
211
306
|
from hermes_cli.auth import _xai_oauth_discovery, _xai_oauth_request_device_code
|
|
212
307
|
|
|
213
|
-
discovery = _xai_oauth_discovery(20.0)
|
|
214
308
|
with _client(20.0) as client:
|
|
309
|
+
# The Agent's discovery is a bare ``httpx.get``: building the client first gives it the platform store and a
|
|
310
|
+
# certifi re-derived after a rotation.
|
|
311
|
+
discovery = _xai_oauth_discovery(20.0)
|
|
215
312
|
data = _xai_oauth_request_device_code(client)
|
|
216
313
|
display = {"user_code": str(data["user_code"]), "verification_url": str(data.get("verification_uri_complete") or data["verification_uri"]),
|
|
217
314
|
"expires_in": int(data["expires_in"]), "interval": int(data["interval"])}
|
|
@@ -320,9 +417,16 @@ def _run(flow: Flow, wait: Callable[[Flow, dict], dict], save: Callable[[Flow, d
|
|
|
320
417
|
log.info("oauth: %s sign-in ended %s (flow=%s)", flow.provider, flow.status, flow.flow_id[:6])
|
|
321
418
|
|
|
322
419
|
|
|
420
|
+
def _discard(state: dict) -> None:
|
|
421
|
+
"""Releases a begun sign-in that is never published: a guest sign-in's generator holds its HTTP client."""
|
|
422
|
+
if "sign_in" in state:
|
|
423
|
+
state["sign_in"].close()
|
|
424
|
+
plugin_oauth.discard(state)
|
|
425
|
+
|
|
426
|
+
|
|
323
427
|
def _cancel(flow: Flow) -> None:
|
|
324
428
|
with flow.lock:
|
|
325
|
-
if flow.
|
|
429
|
+
if flow.stoppable:
|
|
326
430
|
flow.cancelled.set()
|
|
327
431
|
flow.end("cancelled")
|
|
328
432
|
|
|
@@ -354,7 +458,7 @@ def _pending(home: Path, provider: str) -> list[Flow]:
|
|
|
354
458
|
|
|
355
459
|
|
|
356
460
|
def start(home: Path, provider: str, *, providers: dict[str, Provider] | None = None) -> dict:
|
|
357
|
-
steps = (providers or PROVIDERS).get(provider)
|
|
461
|
+
steps = (providers or PROVIDERS).get(provider) or plugin_oauth.steps(provider)
|
|
358
462
|
if steps is None:
|
|
359
463
|
raise InvalidParams(f"{provider} has no device-code sign-in")
|
|
360
464
|
begin, wait, save = steps
|
|
@@ -366,6 +470,11 @@ def start(home: Path, provider: str, *, providers: dict[str, Provider] | None =
|
|
|
366
470
|
# old code that lands while the provider answers can no longer save.
|
|
367
471
|
for old in _pending(home, provider):
|
|
368
472
|
_cancel(old)
|
|
473
|
+
# A cancelled browser sign-in closes its listener from its own thread; a fixed redirect port is free only after that.
|
|
474
|
+
with _FLOWS_LOCK:
|
|
475
|
+
listening = [f for f in _FLOWS.values() if f.provider == provider and f.closed is not None and not f.closed.is_set() and _same_home(f.home, home)]
|
|
476
|
+
for old in listening:
|
|
477
|
+
old.closed.wait(_RELEASE_WAIT)
|
|
369
478
|
try:
|
|
370
479
|
with scoped_home(home):
|
|
371
480
|
display, state = begin()
|
|
@@ -376,11 +485,13 @@ def start(home: Path, provider: str, *, providers: dict[str, Provider] | None =
|
|
|
376
485
|
raise RpcError(_first_line(exc), condition="oauth_failed") from exc
|
|
377
486
|
if not str(display["verification_url"]).lower().startswith(("https://", "http://")):
|
|
378
487
|
# The browser opens this link: anything but a web address is refused before a flow exists.
|
|
488
|
+
_discard(state)
|
|
379
489
|
raise RpcError("The provider answered an invalid sign-in link.", condition="oauth_failed")
|
|
380
|
-
flow = Flow(secrets.token_urlsafe(16), provider, home, time.time() + int(display["expires_in"]), max(1, int(display["interval"])))
|
|
490
|
+
flow = Flow(secrets.token_urlsafe(16), provider, home, time.time() + int(display["expires_in"]), max(1, int(display["interval"])), submit=state.get("submit"), closed=state.get("closed"))
|
|
381
491
|
with _FLOWS_LOCK:
|
|
382
492
|
if _GENERATIONS.get(key) != generation:
|
|
383
493
|
# A newer start for this home and provider began while this one waited on the provider: it owns the sign-in.
|
|
494
|
+
_discard(state)
|
|
384
495
|
raise RpcError("A newer sign-in for this provider replaced this one.", condition="oauth_superseded")
|
|
385
496
|
superseded = [f for f in _FLOWS.values() if f.provider == provider and f.status == "pending" and _same_home(f.home, home)]
|
|
386
497
|
_FLOWS[flow.flow_id] = flow
|
|
@@ -400,10 +511,10 @@ def _flow(home: Path, flow_id: str) -> Flow:
|
|
|
400
511
|
|
|
401
512
|
def poll(home: Path, flow_id: str) -> dict:
|
|
402
513
|
flow = _flow(home, flow_id)
|
|
403
|
-
if flow.
|
|
514
|
+
if flow.stoppable and time.time() > flow.expires_at + _EXPIRY_GRACE:
|
|
404
515
|
# The provider call outlived its code: end it now, and a late approval can no longer save.
|
|
405
516
|
with flow.lock:
|
|
406
|
-
if flow.
|
|
517
|
+
if flow.stoppable:
|
|
407
518
|
flow.cancelled.set()
|
|
408
519
|
flow.end("expired", _EXPIRED)
|
|
409
520
|
return flow.view()
|
|
@@ -415,6 +526,18 @@ def cancel(home: Path, flow_id: str) -> dict:
|
|
|
415
526
|
return flow.view()
|
|
416
527
|
|
|
417
528
|
|
|
529
|
+
def submit_redirect(home: Path, flow_id: str, url: str) -> dict:
|
|
530
|
+
"""Finish a browser sign-in with the address its redirect reached, when the browser runs on another machine."""
|
|
531
|
+
flow = _flow(home, flow_id)
|
|
532
|
+
if flow.submit is None:
|
|
533
|
+
raise InvalidParams("This sign-in takes no redirect address.")
|
|
534
|
+
with flow.lock:
|
|
535
|
+
if not flow.stoppable or time.time() >= flow.expires_at:
|
|
536
|
+
raise RpcError("This sign-in already ended.", condition="oauth_flow_ended")
|
|
537
|
+
flow.submit(url)
|
|
538
|
+
return flow.view()
|
|
539
|
+
|
|
540
|
+
|
|
418
541
|
def _flow_id(params: dict) -> str:
|
|
419
542
|
flow_id = str(params.get("flow_id") or "").strip()
|
|
420
543
|
if not flow_id:
|
|
@@ -425,7 +548,8 @@ def _flow_id(params: dict) -> str:
|
|
|
425
548
|
def register(reg) -> None:
|
|
426
549
|
@reg.method("oauth.start")
|
|
427
550
|
def start_(ctx: CallContext, params: dict) -> dict:
|
|
428
|
-
provider = str(params.get("provider") or "").strip()
|
|
551
|
+
provider = str(params.get("provider") or "").strip()
|
|
552
|
+
provider = provider if provider.startswith(plugin_oauth.PREFIX) else provider.lower()
|
|
429
553
|
if not provider:
|
|
430
554
|
raise InvalidParams("provider is required")
|
|
431
555
|
return start(profile_home_param(params), provider)
|
|
@@ -437,3 +561,10 @@ def register(reg) -> None:
|
|
|
437
561
|
@reg.method("oauth.cancel", requires_agent=False)
|
|
438
562
|
def cancel_(ctx: CallContext, params: dict) -> dict:
|
|
439
563
|
return cancel(profile_home_param(params), _flow_id(params))
|
|
564
|
+
|
|
565
|
+
@reg.method("oauth.submit_redirect", requires_agent=False)
|
|
566
|
+
def submit_(ctx: CallContext, params: dict) -> dict:
|
|
567
|
+
url = str(params.get("url") or "").strip()
|
|
568
|
+
if not url:
|
|
569
|
+
raise InvalidParams("url is required")
|
|
570
|
+
return submit_redirect(profile_home_param(params), _flow_id(params), url)
|