@songsid/agend 2.2.1 → 2.3.0-beta.10
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/dist/agent-cli-instructions.md +5 -2
- package/dist/agent-cli.js +284 -2
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.d.ts +2 -0
- package/dist/agent-endpoint.js +29 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-file-read.d.ts +38 -0
- package/dist/agent-file-read.js +317 -0
- package/dist/agent-file-read.js.map +1 -0
- package/dist/agent-whats-new.d.ts +11 -0
- package/dist/agent-whats-new.js +29 -2
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/atomic-write.js +9 -1
- package/dist/atomic-write.js.map +1 -1
- package/dist/auth-api.d.ts +30 -1
- package/dist/auth-api.js +61 -12
- package/dist/auth-api.js.map +1 -1
- package/dist/authority/authority-state.d.ts +38 -0
- package/dist/authority/authority-state.js +114 -0
- package/dist/authority/authority-state.js.map +1 -0
- package/dist/authority/session-authorizations.d.ts +43 -0
- package/dist/authority/session-authorizations.js +102 -0
- package/dist/authority/session-authorizations.js.map +1 -0
- package/dist/authority/web-authority.d.ts +120 -0
- package/dist/authority/web-authority.js +157 -0
- package/dist/authority/web-authority.js.map +1 -0
- package/dist/backend/antigravity.js +3 -3
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.d.ts +2 -2
- package/dist/backend/claude-code.js +10 -5
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/launch-effort.js +1 -1
- package/dist/backend/launch-effort.js.map +1 -1
- package/dist/backend/muse.js +10 -2
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/types.d.ts +14 -0
- package/dist/backend/types.js +25 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/backend-availability.d.ts +120 -0
- package/dist/backend-availability.js +396 -0
- package/dist/backend-availability.js.map +1 -0
- package/dist/backend-command.d.ts +21 -3
- package/dist/backend-command.js +23 -4
- package/dist/backend-command.js.map +1 -1
- package/dist/bundled-skills.d.ts +14 -0
- package/dist/bundled-skills.js +29 -0
- package/dist/bundled-skills.js.map +1 -0
- package/dist/cache-analysis.d.ts +47 -1
- package/dist/cache-analysis.js +68 -8
- package/dist/cache-analysis.js.map +1 -1
- package/dist/cache-ledger.d.ts +16 -3
- package/dist/cache-ledger.js +33 -13
- package/dist/cache-ledger.js.map +1 -1
- package/dist/cache-report-tool.d.ts +17 -0
- package/dist/cache-report-tool.js +40 -0
- package/dist/cache-report-tool.js.map +1 -0
- package/dist/cache-service.d.ts +70 -3
- package/dist/cache-service.js +178 -17
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +9 -0
- package/dist/channel/adapters/discord.js +52 -2
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +8 -1
- package/dist/channel/adapters/telegram.js +74 -4
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-tools.js +48 -2
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/types.d.ts +21 -0
- package/dist/classic-channel-manager.d.ts +10 -5
- package/dist/classic-channel-manager.js +12 -9
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +130 -31
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.js +119 -4
- package/dist/config-validator.js.map +1 -1
- package/dist/daemon.d.ts +5 -0
- package/dist/daemon.js +273 -22
- package/dist/daemon.js.map +1 -1
- package/dist/decision-list.d.ts +25 -0
- package/dist/decision-list.js +30 -0
- package/dist/decision-list.js.map +1 -0
- package/dist/delivery-outbox.d.ts +10 -0
- package/dist/delivery-outbox.js +12 -1
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/fleet-context.d.ts +15 -0
- package/dist/fleet-manager.d.ts +506 -11
- package/dist/fleet-manager.js +1784 -130
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-traffic.d.ts +74 -0
- package/dist/fleet-traffic.js +196 -0
- package/dist/fleet-traffic.js.map +1 -0
- package/dist/general-knowledge/skills/credential-profiles/SKILL.md +20 -5
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +6 -1
- package/dist/general-knowledge/skills/multi-channel/SKILL.md +3 -2
- package/dist/general-knowledge/skills/persona-emoji/SKILL.md +1 -1
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +492 -0
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +476 -0
- package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
- package/dist/human-delivery-receipts.d.ts +24 -1
- package/dist/human-delivery-receipts.js +64 -11
- package/dist/human-delivery-receipts.js.map +1 -1
- package/dist/instance-avatar.js +3 -0
- package/dist/instance-avatar.js.map +1 -1
- package/dist/instance-config-impact.js +6 -1
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.js +9 -4
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instance-names.d.ts +4 -0
- package/dist/instance-names.js +12 -0
- package/dist/instance-names.js.map +1 -0
- package/dist/instructions.d.ts +12 -1
- package/dist/instructions.js +13 -2
- package/dist/instructions.js.map +1 -1
- package/dist/locale.js +100 -8
- package/dist/locale.js.map +1 -1
- package/dist/ls-attach-resolve.d.ts +95 -0
- package/dist/ls-attach-resolve.js +174 -0
- package/dist/ls-attach-resolve.js.map +1 -0
- package/dist/memory-hogs.d.ts +27 -0
- package/dist/memory-hogs.js +124 -0
- package/dist/memory-hogs.js.map +1 -0
- package/dist/needs-you-hub.d.ts +4 -0
- package/dist/needs-you-hub.js +31 -6
- package/dist/needs-you-hub.js.map +1 -1
- package/dist/needs-you.d.ts +1 -13
- package/dist/needs-you.js +3 -37
- package/dist/needs-you.js.map +1 -1
- package/dist/outbound-handlers.d.ts +15 -0
- package/dist/outbound-handlers.js +152 -11
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +228 -4
- package/dist/outbound-schemas.js +147 -1
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +21 -1
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/public-web-link.d.ts +9 -0
- package/dist/public-web-link.js +8 -0
- package/dist/public-web-link.js.map +1 -1
- package/dist/quickstart-api.d.ts +10 -1
- package/dist/quickstart-api.js +12 -4
- package/dist/quickstart-api.js.map +1 -1
- package/dist/reply-buttons-controller.d.ts +4 -0
- package/dist/reply-buttons-controller.js +2 -2
- package/dist/reply-buttons-controller.js.map +1 -1
- package/dist/repo-worktree-guard.d.ts +36 -0
- package/dist/repo-worktree-guard.js +143 -0
- package/dist/repo-worktree-guard.js.map +1 -0
- package/dist/restart-progress.d.ts +65 -1
- package/dist/restart-progress.js +236 -10
- package/dist/restart-progress.js.map +1 -1
- package/dist/rollout-index.d.ts +5 -0
- package/dist/rollout-index.js +26 -5
- package/dist/rollout-index.js.map +1 -1
- package/dist/scheduler/scheduler.d.ts +70 -1
- package/dist/scheduler/scheduler.js +256 -17
- package/dist/scheduler/scheduler.js.map +1 -1
- package/dist/service-installer.d.ts +2 -1
- package/dist/service-installer.js +18 -3
- package/dist/service-installer.js.map +1 -1
- package/dist/settings-api.d.ts +19 -0
- package/dist/settings-api.js +210 -2
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +112 -0
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.js +32 -2
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.js +5 -0
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/tmux-manager.d.ts +5 -0
- package/dist/tmux-manager.js +16 -0
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tool-permissions.d.ts +4 -6
- package/dist/tool-permissions.js +100 -2
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.d.ts +17 -7
- package/dist/topic-commands.js +39 -21
- package/dist/topic-commands.js.map +1 -1
- package/dist/topic-link.d.ts +128 -0
- package/dist/topic-link.js +269 -0
- package/dist/topic-link.js.map +1 -0
- package/dist/types.d.ts +61 -1
- package/dist/ui/app-effects.js +233 -0
- package/dist/ui/chat-ambient.js +307 -0
- package/dist/ui/chat-effect-posters.js +42 -0
- package/dist/ui/chat-effects.js +160 -0
- package/dist/ui/chat-live-replies.js +58 -0
- package/dist/ui/chat-render.js +9 -6
- package/dist/ui/chat-store.js +9 -3
- package/dist/ui/chat-strings.js +70 -2
- package/dist/ui/chat-thread.js +191 -37
- package/dist/ui/chat-tour.js +1 -1
- package/dist/ui/effect-trial-controller.js +124 -0
- package/dist/ui/effect-trial-offer.js +31 -0
- package/dist/ui/effect-trial-panel.js +40 -0
- package/dist/ui/fleet-cache.js +23 -1
- package/dist/ui/fleet-canvas-layout.js +111 -0
- package/dist/ui/fleet-canvas.js +525 -0
- package/dist/ui/fleet-org.js +27 -12
- package/dist/ui/fleet-traffic.js +343 -0
- package/dist/ui/fleet-usage.js +401 -0
- package/dist/ui/image-lightbox.js +1 -1
- package/dist/ui/panel-chat.js +203 -57
- package/dist/ui/panel-details.js +20 -6
- package/dist/ui/panel-fleet.js +43 -18
- package/dist/ui/panel-log.js +6 -6
- package/dist/ui/panel-needs.js +3 -3
- package/dist/ui/panel-settings.js +34 -13
- package/dist/ui/preview-panel.js +25 -9
- package/dist/ui/preview.js +3 -2
- package/dist/ui/settings-appearance.js +349 -0
- package/dist/ui/settings-catalog.js +92 -0
- package/dist/ui/settings-dialogs.js +40 -12
- package/dist/ui/settings-effects.js +202 -0
- package/dist/ui/settings-guests.js +117 -0
- package/dist/ui/settings-learn.js +25 -0
- package/dist/ui/settings-model.js +15 -6
- package/dist/ui/settings-mods.js +271 -0
- package/dist/ui/settings-owner-effects.js +80 -0
- package/dist/ui/settings-strings.js +333 -10
- package/dist/ui/settings-web-authority.js +91 -0
- package/dist/ui/shared/agend-auth.js +28 -4
- package/dist/ui/shared/agent-widget.js +248 -0
- package/dist/ui/shared/app-i18n.js +6 -2
- package/dist/ui/shared/app-prefs.js +34 -13
- package/dist/ui/shared/app-route.js +24 -2
- package/dist/ui/shared/app-session.js +3 -1
- package/dist/ui/shared/app-shell.js +102 -23
- package/dist/ui/shared/app-store.js +28 -1
- package/dist/ui/shared/app-stream.js +14 -7
- package/dist/ui/shared/app-themes.js +206 -0
- package/dist/ui/shared/app.css +565 -4
- package/dist/ui/shared/app.js +23 -10
- package/dist/ui/shared/card-strings.js +32 -0
- package/dist/ui/shared/effect-app-runtime.js +297 -0
- package/dist/ui/shared/effect-baseline.js +64 -0
- package/dist/ui/shared/effect-chat-runtime.js +167 -0
- package/dist/ui/shared/effect-cursor.js +125 -0
- package/dist/ui/shared/effect-frame.js +146 -0
- package/dist/ui/shared/effect-geometry.js +137 -0
- package/dist/ui/shared/effect-host-style.js +10 -0
- package/dist/ui/shared/effect-owner-regions.js +74 -0
- package/dist/ui/shared/effect-owner-source.js +115 -0
- package/dist/ui/shared/effect-policy.js +151 -0
- package/dist/ui/shared/effect-poster-reader.js +98 -0
- package/dist/ui/shared/effect-posters.js +117 -0
- package/dist/ui/shared/effect-profiler.js +184 -0
- package/dist/ui/shared/effect-profiles.js +65 -0
- package/dist/ui/shared/effect-registry.js +535 -0
- package/dist/ui/shared/effect-runtime-loader.js +234 -0
- package/dist/ui/shared/effect-safety.js +153 -0
- package/dist/ui/shared/effect-stock-snapshot.js +43 -0
- package/dist/ui/shared/effect-stock-trust.js +217 -0
- package/dist/ui/shared/effect-trial-shadow.js +62 -0
- package/dist/ui/shared/effect-trial-source.js +103 -0
- package/dist/ui/shared/effect-trial-stage.js +170 -0
- package/dist/ui/shared/effect-trial.css +40 -0
- package/dist/ui/shared/fx-motion.js +67 -0
- package/dist/ui/shared/header-tools.js +1 -1
- package/dist/ui/shared/identity-card.js +273 -0
- package/dist/ui/shared/identity-color.js +261 -0
- package/dist/ui/shared/instance-nav.js +215 -41
- package/dist/ui/shared/owner-css.js +221 -0
- package/dist/ui/shared/owner-effect-prefs.js +117 -0
- package/dist/ui/shared/panel-view.js +103 -10
- package/dist/ui/shared/signin.js +2 -0
- package/dist/ui/shared/tokens.css +9 -3
- package/dist/ui/shared/ui-dialog.js +1 -1
- package/dist/ui/shared/ui-icons.js +3 -0
- package/dist/ui/shared/ui-menu.js +1 -1
- package/dist/ui/shared/ui-toast.js +1 -1
- package/dist/ui/shared/usage-dialog.js +22 -2
- package/dist/ui/shared/view-strings.js +98 -2
- package/dist/ui/shared/web-authorize.js +151 -0
- package/dist/ui/signin.html +1 -0
- package/dist/ui/web-terminal/terminal.css +4 -4
- package/dist/usage/providers.d.ts +28 -0
- package/dist/usage/providers.js +126 -36
- package/dist/usage/providers.js.map +1 -1
- package/dist/usage-report.d.ts +158 -0
- package/dist/usage-report.js +226 -0
- package/dist/usage-report.js.map +1 -0
- package/dist/usage-rollup.d.ts +51 -0
- package/dist/usage-rollup.js +168 -0
- package/dist/usage-rollup.js.map +1 -0
- package/dist/view-api.d.ts +68 -0
- package/dist/view-api.js +249 -8
- package/dist/view-api.js.map +1 -1
- package/dist/web-ambient.d.ts +72 -0
- package/dist/web-ambient.js +161 -0
- package/dist/web-ambient.js.map +1 -0
- package/dist/web-api.d.ts +111 -5
- package/dist/web-api.js +1235 -58
- package/dist/web-api.js.map +1 -1
- package/dist/web-appearance-limits.d.ts +82 -0
- package/dist/web-appearance-limits.js +83 -0
- package/dist/web-appearance-limits.js.map +1 -0
- package/dist/web-appearance-policy.d.ts +64 -0
- package/dist/web-appearance-policy.js +87 -0
- package/dist/web-appearance-policy.js.map +1 -0
- package/dist/web-appearance-tools.d.ts +53 -0
- package/dist/web-appearance-tools.js +124 -0
- package/dist/web-appearance-tools.js.map +1 -0
- package/dist/web-appearance-view.d.ts +124 -0
- package/dist/web-appearance-view.js +278 -0
- package/dist/web-appearance-view.js.map +1 -0
- package/dist/web-appearance.d.ts +93 -0
- package/dist/web-appearance.js +373 -0
- package/dist/web-appearance.js.map +1 -0
- package/dist/web-asset-parts.d.ts +93 -0
- package/dist/web-asset-parts.js +133 -0
- package/dist/web-asset-parts.js.map +1 -0
- package/dist/web-auth.js +20 -2
- package/dist/web-auth.js.map +1 -1
- package/dist/web-card.d.ts +110 -0
- package/dist/web-card.js +266 -0
- package/dist/web-card.js.map +1 -0
- package/dist/web-channel-echo.d.ts +7 -1
- package/dist/web-channel-echo.js +6 -2
- package/dist/web-channel-echo.js.map +1 -1
- package/dist/web-chat-history.d.ts +59 -0
- package/dist/web-chat-history.js +102 -4
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-commands.d.ts +1 -0
- package/dist/web-effect-bootstrap.d.ts +12 -0
- package/dist/web-effect-bootstrap.js +49 -0
- package/dist/web-effect-bootstrap.js.map +1 -0
- package/dist/web-effect-bundle.d.ts +28 -0
- package/dist/web-effect-bundle.js +171 -0
- package/dist/web-effect-bundle.js.map +1 -0
- package/dist/web-effect-canonical.d.ts +8 -0
- package/dist/web-effect-canonical.js +27 -0
- package/dist/web-effect-canonical.js.map +1 -0
- package/dist/web-effect-library.d.ts +114 -0
- package/dist/web-effect-library.js +530 -0
- package/dist/web-effect-library.js.map +1 -0
- package/dist/web-effect-playback.d.ts +30 -0
- package/dist/web-effect-playback.js +71 -0
- package/dist/web-effect-playback.js.map +1 -0
- package/dist/web-effect-poster.d.ts +8 -0
- package/dist/web-effect-poster.js +52 -0
- package/dist/web-effect-poster.js.map +1 -0
- package/dist/web-effect-profiles.d.ts +118 -0
- package/dist/web-effect-profiles.js +180 -0
- package/dist/web-effect-profiles.js.map +1 -0
- package/dist/web-effect-service.d.ts +93 -0
- package/dist/web-effect-service.js +335 -0
- package/dist/web-effect-service.js.map +1 -0
- package/dist/web-effect-tools.d.ts +48 -0
- package/dist/web-effect-tools.js +129 -0
- package/dist/web-effect-tools.js.map +1 -0
- package/dist/web-effect-trials.d.ts +86 -0
- package/dist/web-effect-trials.js +204 -0
- package/dist/web-effect-trials.js.map +1 -0
- package/dist/web-effect-upload.d.ts +27 -0
- package/dist/web-effect-upload.js +185 -0
- package/dist/web-effect-upload.js.map +1 -0
- package/dist/web-effect-worker.d.ts +8 -0
- package/dist/web-effect-worker.js +170 -0
- package/dist/web-effect-worker.js.map +1 -0
- package/dist/web-effect.d.ts +103 -0
- package/dist/web-effect.js +153 -0
- package/dist/web-effect.js.map +1 -0
- package/dist/web-guest-access.d.ts +125 -0
- package/dist/web-guest-access.js +234 -0
- package/dist/web-guest-access.js.map +1 -0
- package/dist/web-guest-rooms.d.ts +82 -0
- package/dist/web-guest-rooms.js +135 -0
- package/dist/web-guest-rooms.js.map +1 -0
- package/dist/web-identity-color.d.ts +87 -0
- package/dist/web-identity-color.js +209 -0
- package/dist/web-identity-color.js.map +1 -0
- package/dist/web-identity-palette.d.ts +113 -0
- package/dist/web-identity-palette.js +84 -0
- package/dist/web-identity-palette.js.map +1 -0
- package/dist/web-image-meta.d.ts +25 -0
- package/dist/web-image-meta.js +200 -0
- package/dist/web-image-meta.js.map +1 -0
- package/dist/web-login.d.ts +47 -0
- package/dist/web-login.js +115 -0
- package/dist/web-login.js.map +1 -1
- package/dist/web-mod-agent.d.ts +50 -0
- package/dist/web-mod-agent.js +207 -0
- package/dist/web-mod-agent.js.map +1 -0
- package/dist/web-mod-bundle.d.ts +157 -0
- package/dist/web-mod-bundle.js +529 -0
- package/dist/web-mod-bundle.js.map +1 -0
- package/dist/web-mod-export.d.ts +68 -0
- package/dist/web-mod-export.js +100 -0
- package/dist/web-mod-export.js.map +1 -0
- package/dist/web-mod-store.d.ts +289 -0
- package/dist/web-mod-store.js +638 -0
- package/dist/web-mod-store.js.map +1 -0
- package/dist/web-org.d.ts +3 -3
- package/dist/web-org.js +11 -17
- package/dist/web-org.js.map +1 -1
- package/dist/web-owner-css-store.d.ts +180 -0
- package/dist/web-owner-css-store.js +384 -0
- package/dist/web-owner-css-store.js.map +1 -0
- package/dist/web-owner-css.d.ts +58 -0
- package/dist/web-owner-css.js +552 -0
- package/dist/web-owner-css.js.map +1 -0
- package/dist/web-prefs.d.ts +62 -0
- package/dist/web-prefs.js +232 -36
- package/dist/web-prefs.js.map +1 -1
- package/dist/web-preview.d.ts +15 -3
- package/dist/web-preview.js +28 -9
- package/dist/web-preview.js.map +1 -1
- package/dist/web-returning-device.d.ts +41 -0
- package/dist/web-returning-device.js +57 -5
- package/dist/web-returning-device.js.map +1 -1
- package/dist/web-session-authorization.d.ts +132 -0
- package/dist/web-session-authorization.js +193 -0
- package/dist/web-session-authorization.js.map +1 -0
- package/dist/web-session.d.ts +70 -10
- package/dist/web-session.js +137 -22
- package/dist/web-session.js.map +1 -1
- package/dist/web-settings-patch.d.ts +67 -2
- package/dist/web-settings-patch.js +196 -1
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-settings-tools.d.ts +89 -0
- package/dist/web-settings-tools.js +270 -0
- package/dist/web-settings-tools.js.map +1 -0
- package/dist/web-shell-routes.d.ts +2 -2
- package/dist/web-shell-routes.js +2 -2
- package/dist/web-shell-routes.js.map +1 -1
- package/dist/web-theme-store.d.ts +257 -0
- package/dist/web-theme-store.js +627 -0
- package/dist/web-theme-store.js.map +1 -0
- package/dist/web-theme.d.ts +123 -0
- package/dist/web-theme.js +416 -0
- package/dist/web-theme.js.map +1 -0
- package/dist/web-widget.d.ts +72 -0
- package/dist/web-widget.js +245 -0
- package/dist/web-widget.js.map +1 -0
- package/dist/workflow-templates/default.md +1 -1
- package/package.json +1 -1
- package/templates/systemd.service.ejs +8 -0
package/dist/ui/panel-fleet.js
CHANGED
|
@@ -18,15 +18,26 @@ import { Icon } from "/assets/ui-icons.js";
|
|
|
18
18
|
import { toast } from "/assets/ui-toast.js";
|
|
19
19
|
import { confirmDialog } from "/assets/ui-confirm.js";
|
|
20
20
|
import { confirmedWrite } from "./settings-confirm.js";
|
|
21
|
-
import {
|
|
21
|
+
import { OrgCanvas } from "./fleet-canvas.js";
|
|
22
22
|
import { labelOf } from "/assets/instance-nav.js";
|
|
23
23
|
import { CacheReport } from "./fleet-cache.js";
|
|
24
|
+
import { UsageTab } from "./fleet-usage.js";
|
|
25
|
+
import { BackendSelect, ModelSelect } from "./settings-dialogs.js";
|
|
26
|
+
|
|
27
|
+
/** #2015: one of the largest processes as text: "python3 18.1 GB (dev-a)". */
|
|
28
|
+
export function memoryHogText(p) {
|
|
29
|
+
const size = p.rssBytes >= 1024 ** 3 ? `${(p.rssBytes / 1024 ** 3).toFixed(1)} GB` : `${Math.round(p.rssBytes / 1024 ** 2)} MB`;
|
|
30
|
+
const owner = p.owner === "instance" && p.instance ? p.instance
|
|
31
|
+
: t(p.owner === "fleet" ? "fleet.hostMemory_ownerFleet" : p.owner === "tmux" ? "fleet.hostMemory_ownerTmux" : "fleet.hostMemory_ownerOther");
|
|
32
|
+
return `${p.name} ${size} (${owner})`;
|
|
33
|
+
}
|
|
24
34
|
|
|
25
35
|
register("fleet", {
|
|
26
36
|
en: {
|
|
27
37
|
hostMemory_elevated: "Host memory pressure: elevated — new agents start one at a time, at least 5 s apart",
|
|
28
38
|
hostMemory_critical: "Host memory pressure: critical — new agents wait for memory to recover",
|
|
29
|
-
|
|
39
|
+
hostMemory_top: "Largest: {0}", hostMemory_ownerFleet: "the fleet", hostMemory_ownerTmux: "tmux", hostMemory_ownerOther: "not an instance",
|
|
40
|
+
title: "Fleet", tasks: "Tasks", schedules: "Schedules", teams: "Teams", org: "Org chart", cache: "Cache", usage: "Usage", config: "Config",
|
|
30
41
|
docs: "Docs", docsNewTab: "Docs (opens in a new tab)",
|
|
31
42
|
newTask: "New task", newSchedule: "New schedule", newTeam: "New team",
|
|
32
43
|
noTasks: "No tasks yet", noTasksHint: "Create one to coordinate fleet work.", noSchedules: "No schedules yet", noSchedulesHint: "Automate recurring work with cron.",
|
|
@@ -52,12 +63,13 @@ register("fleet", {
|
|
|
52
63
|
newInstance: "New instance", directory: "Directory", directoryHint: "Optional — a workspace is created if empty", topic: "Name", topicHint: "From the directory name",
|
|
53
64
|
topicRequired: "Name is required when Directory is empty", description: "Description", descriptionHint: "What this instance does", model: "Model", modelHint: "e.g. sonnet, opus, gpt-5",
|
|
54
65
|
branch: "Branch (git worktree)", branchHint: "e.g. feature-x", tags: "Tags", tagsHint: "comma-separated, e.g. dev, review", systemPrompt: "System prompt", systemPromptHint: "Custom instructions for this instance",
|
|
55
|
-
fleetDefault: "Use the fleet default", notInstalled: "(not installed)", deprecated: "(deprecated)", instanceCreated: "Instance created",
|
|
66
|
+
fleetDefault: "Use the fleet default", notInstalled: "(not installed)", notSignedIn: "(not signed in — use /login)", tooOld: "(needs {0} or newer)", unchecked: "(not checked yet)", deprecated: "(deprecated)", instanceCreated: "Instance created",
|
|
56
67
|
},
|
|
57
68
|
"zh-TW": {
|
|
58
69
|
hostMemory_elevated: "主機記憶體壓力偏高:新的 agent 一次啟動一個,至少間隔 5 秒",
|
|
59
70
|
hostMemory_critical: "主機記憶體壓力嚴重:新的 agent 會等記憶體恢復再啟動",
|
|
60
|
-
|
|
71
|
+
hostMemory_top: "最大:{0}", hostMemory_ownerFleet: "fleet 本身", hostMemory_ownerTmux: "tmux", hostMemory_ownerOther: "不屬於任何 instance",
|
|
72
|
+
title: "Fleet", tasks: "Tasks", schedules: "排程", teams: "Teams", org: "組織圖", cache: "快取", usage: "用量", config: "設定",
|
|
61
73
|
docs: "文件", docsNewTab: "文件(在新分頁開啟)",
|
|
62
74
|
newTask: "新增 task", newSchedule: "新增排程", newTeam: "新增 team",
|
|
63
75
|
noTasks: "還沒有 task", noTasksHint: "建立一個來協調 fleet 的工作。", noSchedules: "還沒有排程", noSchedulesHint: "用 cron 自動執行例行工作。",
|
|
@@ -82,7 +94,7 @@ register("fleet", {
|
|
|
82
94
|
newInstance: "新增 instance", directory: "目錄", directoryHint: "可留空——留空會自動建立工作區", topic: "名稱", topicHint: "預設取自目錄名稱",
|
|
83
95
|
topicRequired: "目錄留空時必須填寫名稱", description: "說明", descriptionHint: "這個 instance 做什麼", model: "模型", modelHint: "例如 sonnet、opus、gpt-5",
|
|
84
96
|
branch: "分支(git worktree)", branchHint: "例如 feature-x", tags: "標籤", tagsHint: "以逗號分隔,例如 dev, review", systemPrompt: "System prompt", systemPromptHint: "這個 instance 的自訂指示",
|
|
85
|
-
fleetDefault: "使用 fleet 預設", notInstalled: "(未安裝)", deprecated: "(已淘汰)", instanceCreated: "Instance 已建立",
|
|
97
|
+
fleetDefault: "使用 fleet 預設", notInstalled: "(未安裝)", notSignedIn: "(未登入,請用 /login)", tooOld: "(需要 {0} 以上版本)", unchecked: "(尚未檢查)", deprecated: "(已淘汰)", instanceCreated: "Instance 已建立",
|
|
86
98
|
},
|
|
87
99
|
});
|
|
88
100
|
|
|
@@ -91,7 +103,7 @@ const DOCS_SITE = "https://songsid.github.io/AgEnD";
|
|
|
91
103
|
export function docsUrl(language = lang()) {
|
|
92
104
|
return `${DOCS_SITE}${language === "zh-TW" ? "/zh-tw" : ""}/docs/web-guide/`;
|
|
93
105
|
}
|
|
94
|
-
const ICONS = { tasks: "tasks", schedules: "clock", teams: "team", org: "org", cache: "chart", config: "sliders" };
|
|
106
|
+
const ICONS = { tasks: "tasks", schedules: "clock", teams: "team", org: "org", cache: "chart", usage: "chart", config: "sliders" };
|
|
95
107
|
const BACKENDS = ["claude-code", "codex", "opencode", "kiro-cli", "antigravity", "grok", "muse"];
|
|
96
108
|
|
|
97
109
|
async function api(method, path, body, lease) {
|
|
@@ -130,15 +142,17 @@ export function FleetPanel({ route, navKey }) {
|
|
|
130
142
|
const lease = useLease(navKey);
|
|
131
143
|
const tab = route.tab;
|
|
132
144
|
useEffect(() => { setTitle(`${t("fleet.title")} · ${t(`fleet.${tab}`)}`); }, [tab, navKey]);
|
|
133
|
-
const Body = { tasks: Tasks, schedules: Schedules, teams: Teams, org: Org, cache: Cache, config: Config }[tab] || Tasks;
|
|
145
|
+
const Body = { tasks: Tasks, schedules: Schedules, teams: Teams, org: Org, cache: Cache, usage: UsageTab, config: Config }[tab] || Tasks;
|
|
134
146
|
// #1685: host memory pressure slowing or holding new agents — shown here, where macOS's routine "elevated" is not a chat notice.
|
|
135
|
-
const { hostMemory } = useStore(appStore);
|
|
136
|
-
|
|
137
|
-
|
|
147
|
+
const { hostMemory, hostMemoryTop } = useStore(appStore);
|
|
148
|
+
// #2015: and which processes hold the most, and whose — text only (never chat, #1712).
|
|
149
|
+
const top = hostMemory && hostMemoryTop?.length ? t("fleet.hostMemory_top", hostMemoryTop.map(memoryHogText).join(" · ")) : "";
|
|
150
|
+
const sub = hostMemory ? html`<span class=${`status host-mem ${hostMemory}`} role="status"><span class=${`dot ${hostMemory === "critical" ? "bad" : "warn"}`} aria-hidden="true"></span>${t(`fleet.hostMemory_${hostMemory}`)}${top ? html`<span class="host-mem-top">${top}</span>` : null}</span>` : null;
|
|
151
|
+
return html`<div data-effect-panel="fleet" class="panel p-fleet">
|
|
138
152
|
<${PanelHeader} title=${t("fleet.title")} sub=${sub}><${DocsLink} /><${HeaderTools} navKey=${navKey} /></${PanelHeader}>
|
|
139
|
-
<nav class="seg" aria-label=${t("fleet.title")}>${FLEET_TABS.map(k => html`<a key=${k} href=${fleetPath(k)} class=${`seg-item${k === tab ? " active" : ""}`}
|
|
153
|
+
<nav data-trust="panel-navigation" class="seg" aria-label=${t("fleet.title")}>${FLEET_TABS.map(k => html`<a key=${k} href=${fleetPath(k)} class=${`seg-item${k === tab ? " active" : ""}`}
|
|
140
154
|
aria-current=${k === tab ? "page" : undefined}><${Icon} name=${ICONS[k]} size=${16} /><span>${t(`fleet.${k}`)}</span></a>`)}</nav>
|
|
141
|
-
<div class="panel-body"><div class=${`col${tab === "org" || tab === "cache" ? " col-wide" : ""}`}><${Body} lease=${lease} /></div></div>
|
|
155
|
+
<div data-trust="panel-content" class="panel-body"><div class=${`col${tab === "org" || tab === "cache" || tab === "usage" ? " col-wide" : ""}`}><${Body} lease=${lease} /></div></div>
|
|
142
156
|
</div>`;
|
|
143
157
|
}
|
|
144
158
|
|
|
@@ -255,11 +269,11 @@ function Teams({ lease }) {
|
|
|
255
269
|
${editing ? html`<${CreateTeam} team=${editing} onClose=${() => setEditing(null)} onDone=${() => setVersion(v => v + 1)} />` : null}`;
|
|
256
270
|
}
|
|
257
271
|
|
|
258
|
-
/** #1389: the org chart — its structure read once per opening, its live state from the app store (fleet-
|
|
272
|
+
/** #1389: the org chart — its structure read once per opening, its live state from the app store. #1918: a canvas, or the list (fleet-canvas.js). */
|
|
259
273
|
function Org({ lease }) {
|
|
260
274
|
const state = useLoad(lease, "/ui/org", 0);
|
|
261
275
|
const app = useStore(appStore);
|
|
262
|
-
return html`<${Loaded} state=${state}>${(org) => html`<${
|
|
276
|
+
return html`<${Loaded} state=${state}>${(org) => html`<${OrgCanvas} org=${org} app=${app} lease=${lease} />`}</${Loaded}>`;
|
|
263
277
|
}
|
|
264
278
|
|
|
265
279
|
/** #1468: the prompt-cache analysis — one read per opening and per window chosen; Refresh reads again (fleet-cache.js). */
|
|
@@ -322,8 +336,7 @@ function Config({ lease }) {
|
|
|
322
336
|
<div class="field"><label for="cfg-users">${t("fleet.allowedUsers")}</label><${Secret} id="cfg-users" value=${form.users} onInput=${set("users")} label=${t("fleet.allowedUsers")} />
|
|
323
337
|
<p class="note">${t("fleet.allowedUsersNote")}</p></div></section>
|
|
324
338
|
<section class="card"><h3>${t("fleet.defaults")}</h3>
|
|
325
|
-
<
|
|
326
|
-
${[...(BACKENDS.includes(form.backend) ? [] : [form.backend]), ...BACKENDS].map(b => html`<option key=${b} value=${b}>${b}</option>`)}</select></label></section>
|
|
339
|
+
<div class="field"><label for="cfg-be">${t("fleet.backend")}</label><${BackendSelect} id="cfg-be" value=${form.backend} onChange=${(v) => setForm({ ...form, backend: v })} /></div></section>
|
|
327
340
|
<section class="card"><h3>${t("fleet.roots")}</h3>
|
|
328
341
|
${form.roots.map((r, i) => html`<div key=${i} class="field-row"><input value=${r} placeholder="/path/to/projects" aria-label=${t("fleet.roots")}
|
|
329
342
|
onInput=${(e) => { const roots = [...form.roots]; roots[i] = e.target.value; setForm({ ...form, roots }); }} />
|
|
@@ -510,6 +523,8 @@ function CreateTeam({ onClose, onDone, team = null }) {
|
|
|
510
523
|
export function CreateInstanceDialog({ onClose }) {
|
|
511
524
|
const lease = useLease("create-instance");
|
|
512
525
|
const [backends, setBackends] = useState(null);
|
|
526
|
+
// The backend "fleet default" means (#2098 review P3-3): its models are the ones the model list offers then.
|
|
527
|
+
const [defaultBackend, setDefaultBackend] = useState("claude-code");
|
|
513
528
|
const [f, setF] = useState({ dir: "", topic: "", desc: "", backend: "", model: "", branch: "", tags: "", prompt: "" });
|
|
514
529
|
useEffect(() => {
|
|
515
530
|
(async () => {
|
|
@@ -518,6 +533,7 @@ export function CreateInstanceDialog({ onClose }) {
|
|
|
518
533
|
if (!lease.current()) return;
|
|
519
534
|
const list = bd.backends || [];
|
|
520
535
|
const first = list.find(b => b.installed && !b.deprecated) || list.find(b => b.installed);
|
|
536
|
+
if (typeof bd.defaultBackend === "string" && bd.defaultBackend) setDefaultBackend(bd.defaultBackend);
|
|
521
537
|
setBackends(list);
|
|
522
538
|
setF(x => ({ ...x, backend: first ? first.name : "" }));
|
|
523
539
|
} catch {
|
|
@@ -547,14 +563,23 @@ export function CreateInstanceDialog({ onClose }) {
|
|
|
547
563
|
${field(`${t("fleet.topic")}${f.dir.trim() ? "" : " *"}`, html`<input value=${f.topic} onInput=${set("topic")} placeholder=${t("fleet.topicHint")} />`)}
|
|
548
564
|
${field(t("fleet.description"), html`<input value=${f.desc} onInput=${set("desc")} placeholder=${t("fleet.descriptionHint")} />`)}
|
|
549
565
|
${field(t("fleet.backend"), backends ? html`<select value=${f.backend} onChange=${set("backend")}><option value="">${t("fleet.fleetDefault")}</option>
|
|
550
|
-
${backends.map(b => html`<option key=${b.name} value=${b.name} disabled=${
|
|
551
|
-
${field(t("fleet.model"), html
|
|
566
|
+
${backends.map(b => html`<option key=${b.name} value=${b.name} disabled=${backendBlocked(b)}>${b.name}${b.deprecated ? ` ${t("fleet.deprecated")}` : ""}${backendNote(b)}</option>`)}</select>` : html`<${Skeleton} lines=${1} />`)}
|
|
567
|
+
${field(t("fleet.model"), html`<${ModelSelect} value=${f.model} onChange=${(v) => setF(x => ({ ...x, model: v }))} backend=${f.backend || defaultBackend} inherit=${t("fleet.fleetDefault")} />`)}
|
|
552
568
|
${field(t("fleet.branch"), html`<input value=${f.branch} onInput=${set("branch")} placeholder=${t("fleet.branchHint")} />`)}
|
|
553
569
|
${field(t("fleet.tags"), html`<input value=${f.tags} onInput=${set("tags")} placeholder=${t("fleet.tagsHint")} />`)}
|
|
554
570
|
${field(t("fleet.systemPrompt"), html`<textarea rows="3" value=${f.prompt} onInput=${set("prompt")} placeholder=${t("fleet.systemPromptHint")}></textarea>`)}
|
|
555
571
|
</${FormDialog}>`;
|
|
556
572
|
}
|
|
557
573
|
|
|
574
|
+
// #2072: a backend this host cannot run is shown, disabled, with why; one not checked yet stays selectable.
|
|
575
|
+
const backendState = (b) => b.state ?? (b.installed ? "usable" : b.unknown ? "unknown" : "not_installed");
|
|
576
|
+
function backendBlocked(b) { return ["not_installed", "not_signed_in", "too_old"].includes(backendState(b)); }
|
|
577
|
+
function backendNote(b) {
|
|
578
|
+
const s = backendState(b);
|
|
579
|
+
return s === "not_installed" ? ` ${t("fleet.notInstalled")}` : s === "not_signed_in" ? ` ${t("fleet.notSignedIn")}`
|
|
580
|
+
: s === "too_old" ? ` ${t("fleet.tooOld", b.minVersion ?? "?")}` : s === "unknown" ? ` ${t("fleet.unchecked")}` : "";
|
|
581
|
+
}
|
|
582
|
+
|
|
558
583
|
// ── Cron in words (#1724: in the page's language) ──
|
|
559
584
|
/**
|
|
560
585
|
* A cron expression as a person says it — "Weekdays 18:00", 「每週一到五 18:00」, "Every 15 minutes" — or the expression
|
package/dist/ui/panel-log.js
CHANGED
|
@@ -200,10 +200,10 @@ export function LogPanel({ route, navKey }) {
|
|
|
200
200
|
const name = route.instance;
|
|
201
201
|
const inst = app.instances.find((i) => i.name === name) || null;
|
|
202
202
|
useEffect(() => { setTitle(`${name} · ${t("app.log")}`); }, [name, navKey]);
|
|
203
|
-
if (!app.ready) return html`<div class="panel p-log"><${PanelHeader} title=${name} /><div class="panel-body"><${Skeleton} lines=${6} /></div></div>`;
|
|
203
|
+
if (!app.ready) return html`<div data-effect-panel="log" class="panel p-log"><${PanelHeader} title=${name} /><div data-trust="panel-content" class="panel-body"><${Skeleton} lines=${6} /></div></div>`;
|
|
204
204
|
if (!inst) {
|
|
205
|
-
return html`<div class="panel p-log"><${PanelHeader} title=${name} />
|
|
206
|
-
<div class="panel-body center"><${Empty} icon="alert" title=${t("chat.notFound", name)} hint=${t("chat.notFoundHint")}
|
|
205
|
+
return html`<div data-effect-panel="log" class="panel p-log"><${PanelHeader} title=${name} />
|
|
206
|
+
<div data-trust="panel-content" class="panel-body center"><${Empty} icon="alert" title=${t("chat.notFound", name)} hint=${t("chat.notFoundHint")}
|
|
207
207
|
action=${html`<button type="button" class="btn only-narrow" onClick=${openDrawer}>${t("chat.backToList")}</button>`} /></div></div>`;
|
|
208
208
|
}
|
|
209
209
|
return html`<${LogView} key=${name} name=${name} inst=${inst} navKey=${navKey} exec=${app.exec[name]}
|
|
@@ -372,13 +372,13 @@ function LogView({ name, inst, navKey, exec, awaiting }) {
|
|
|
372
372
|
${items.length ? html`<ol class="log-list" role="log" aria-label=${t("app.log")}>${items.map((x, i) => html`<${Row} key=${`${x.kind}:${x.id}`} x=${x} prev=${items[i - 1]} />`)}</ol>`
|
|
373
373
|
: html`<p class="note log-empty">${tl("empty")}</p>`}`;
|
|
374
374
|
}
|
|
375
|
-
const tools = state.phase === "on" ? html`<div class="log-bar" role="group" aria-label=${tl("filter")}>
|
|
375
|
+
const tools = state.phase === "on" ? html`<div data-trust="panel-controls" class="log-bar" role="group" aria-label=${tl("filter")}>
|
|
376
376
|
${["all", "tools", "errors"].map((k) => html`<button key=${k} type="button" class=${`chip-btn${filter === k ? " on" : ""}`} aria-pressed=${filter === k ? "true" : "false"} onClick=${() => setFilter(k)}>${tl(k)}</button>`)}
|
|
377
377
|
<span class="grow"></span><span class="log-live" title=${tl("live")}><span class="dot running" aria-hidden="true"></span>${tl("live")}</span></div>` : null;
|
|
378
|
-
return html`<div class="panel p-log">
|
|
378
|
+
return html`<div data-effect-panel="log" class="panel p-log">
|
|
379
379
|
<${PanelHeader} title=${name} sub=${sub} nav=${html`<${InstanceSwitch} name=${name} current="log" />`}><${HeaderTools} navKey=${navKey} /><${HeaderSlot} /></${PanelHeader}>
|
|
380
380
|
${tools}
|
|
381
|
-
<div class="panel-body log-body" ref=${scroller} onScroll=${onScroll}><div class="col log-col">${content}</div></div>
|
|
381
|
+
<div data-trust="panel-content" class="panel-body log-body" ref=${scroller} onScroll=${onScroll}><div class="col log-col">${content}</div></div>
|
|
382
382
|
</div>`;
|
|
383
383
|
}
|
|
384
384
|
|
package/dist/ui/panel-needs.js
CHANGED
|
@@ -123,9 +123,9 @@ export function NeedsPanel({ navKey }) {
|
|
|
123
123
|
useEffect(() => { if (owner) return owner.subscribe(() => tick((n) => n + 1)); return undefined; }, [owner, lease]);
|
|
124
124
|
const groups = groupNeeds(items);
|
|
125
125
|
const nowMs = Date.now();
|
|
126
|
-
return html`<div class="panel p-needs">
|
|
126
|
+
return html`<div data-effect-panel="needs" class="panel p-needs">
|
|
127
127
|
<${PanelHeader} title=${tn("title")} sub=${items.length ? t("app.needsCount", items.length) : null} />
|
|
128
|
-
<div class="panel-body"><div class="col">
|
|
128
|
+
<div data-trust="panel-content" class="panel-body"><div class="col">
|
|
129
129
|
${!items.length ? html`<${Empty} icon="check" title=${tn("empty")} hint=${tn(chatApp ? "emptyHint" : "emptyHintWeb")} />`
|
|
130
130
|
: groups.map((g) => html`<section key=${g.instance} class="n-group" aria-label=${g.instance}>
|
|
131
131
|
<h2 class="n-group-head"><a href=${chatPath(g.instance)} title=${g.instance}>${nameFor(g.instance)}</a></h2>
|
|
@@ -175,7 +175,7 @@ function NeedsItem({ item, nowMs, owner }) {
|
|
|
175
175
|
setClaim("acks", item.id, res && res.ok ? "done" : null);
|
|
176
176
|
toast((body && (body.message || body.error)) || t("app.failed"), !!(res && res.ok));
|
|
177
177
|
};
|
|
178
|
-
return html`<article class=${`n-item${BAD.has(item.reason) ? " bad" : ""}`}>
|
|
178
|
+
return html`<article data-trust="permission" class=${`n-item${BAD.has(item.reason) ? " bad" : ""}`}>
|
|
179
179
|
<span class="n-icon"><${Icon} name=${ICON[item.type] || "alert"} size=${18} /></span>
|
|
180
180
|
<div class="n-body">
|
|
181
181
|
<div class="n-title"><strong>${reasonText(item)}</strong><span class="n-age">${age(item.since, nowMs)}</span></div>
|
|
@@ -20,6 +20,7 @@ import { Empty, ErrorState, Skeleton } from "/assets/ui-states.js";
|
|
|
20
20
|
import { Icon } from "/assets/ui-icons.js";
|
|
21
21
|
import { Menu } from "/assets/ui-menu.js";
|
|
22
22
|
import { toast } from "/assets/ui-toast.js";
|
|
23
|
+
import { GroupMark, groupLabel, groupOf as navGroupOf, modelText } from "/assets/instance-nav.js";
|
|
23
24
|
import "./settings-strings.js";
|
|
24
25
|
import { api, attach, confirmedWrite, newKey } from "./settings-confirm.js";
|
|
25
26
|
import { dismissOperation, operationActive, restartFleet, startOperation, takeLeftover } from "./settings-apply.js";
|
|
@@ -30,7 +31,7 @@ import {
|
|
|
30
31
|
visibilityDefault, worstImpact,
|
|
31
32
|
} from "./settings-model.js";
|
|
32
33
|
import {
|
|
33
|
-
AgentDialog, BackendSelect, BotDialog, ChipList, ClassicDialog, Drawer, Feedback, Impact, Label, NewBotDialog, Override,
|
|
34
|
+
AgentDialog, BackendSelect, BotDialog, ChipList, ClassicDialog, Drawer, Feedback, Impact, Label, ModelSelect, NewBotDialog, Override,
|
|
34
35
|
Select, ask, impactText,
|
|
35
36
|
} from "./settings-dialogs.js";
|
|
36
37
|
import { SetupWizard } from "./settings-wizard.js";
|
|
@@ -41,9 +42,16 @@ import { takeAgentRequest } from "./settings-request.js";
|
|
|
41
42
|
import { setPreviewOptIn } from "./panel-chat.js";
|
|
42
43
|
import { startTour } from "./chat-tour.js";
|
|
43
44
|
import "./chat-strings.js";
|
|
45
|
+
import { AppearanceSection } from "./settings-appearance.js";
|
|
46
|
+
import { GuestsCard } from "./settings-guests.js";
|
|
47
|
+
import { WebAuthorityCard } from "./settings-web-authority.js";
|
|
44
48
|
|
|
45
49
|
const tn = (k, ...v) => t(`settings.${k}`, ...v);
|
|
46
|
-
|
|
50
|
+
/** What a refused change says to a person: the server's code in words (the code itself only for one not listed). */
|
|
51
|
+
const APPLY_ERRORS = new Set(["unsupported_sensitive_effect", "confirmation_diff_too_large", "session_required", "admin_required", "settings_changed",
|
|
52
|
+
"request_no_longer_current", "too_many_pending_changes", "fleet_unavailable", "invalid_settings_effect", "settings_confirmation_unavailable", "failed"]);
|
|
53
|
+
export const applyErrorText = (code) => (APPLY_ERRORS.has(code) ? tn(`applyError_${code}`) : tn("applyErrorOther", String(code)));
|
|
54
|
+
const ICONS = { device: "user", appearance: "palette", agents: "bot", bots: "plug", classic: "room", general: "sliders", web: "globe", advanced: "code" };
|
|
47
55
|
const RELEASES = "https://github.com/songsid/AgEnD/releases";
|
|
48
56
|
|
|
49
57
|
/** GET under the panel's lease → { ok, status, body }. */
|
|
@@ -86,7 +94,7 @@ async function loadLive(lease) {
|
|
|
86
94
|
if (!lease.current()) return null;
|
|
87
95
|
const live = {}, classicLive = {};
|
|
88
96
|
if (f.ok && f.body && Array.isArray(f.body.instances)) for (const i of f.body.instances) {
|
|
89
|
-
live[i.name] = { status: i.status, state: i.state, backend: i.backend, model: i.model, model_display: i.model_display, effort: i.effort, effort_supported: i.effort_supported };
|
|
97
|
+
live[i.name] = { status: i.status, state: i.state, backend: i.backend, model: i.model, model_display: modelText(i, i.model_display), effort: i.effort, effort_supported: i.effort_supported };
|
|
90
98
|
if (i.classic) classicLive[i.name] = { status: i.status, state: i.state };
|
|
91
99
|
}
|
|
92
100
|
// /api/fleet carries live state for ClassicBot rooms; the profiles are the fallback for one not listed there yet.
|
|
@@ -224,6 +232,8 @@ export function SettingsPanel({ route, navKey }) {
|
|
|
224
232
|
}, [!!ctx, navKey]);
|
|
225
233
|
// #1604: This device needs no configuration: shown at once, whatever the configuration read does.
|
|
226
234
|
const sectionBody = section === "device" ? html`<${DeviceSection} />`
|
|
235
|
+
// #1629 r4 §3: Appearance is the person's own (no configuration read): shown at once, like Preferences.
|
|
236
|
+
: section === "appearance" ? html`<${AppearanceSection} />`
|
|
227
237
|
: !data ? html`<${Skeleton} lines=${6} />`
|
|
228
238
|
: data.error ? html`<${ErrorState} message=${tn("configLoadFailed")} onRetry=${reload} />`
|
|
229
239
|
: section === "agents" ? html`<${Agents} ctx=${ctx} search=${search} openDialog=${(d) => setDialog({ ...d, key: navKey })} />`
|
|
@@ -236,14 +246,14 @@ export function SettingsPanel({ route, navKey }) {
|
|
|
236
246
|
const open = dialog && dialog.key === navKey ? dialog : null;
|
|
237
247
|
const close = () => setDialog(null);
|
|
238
248
|
const searchable = section === "agents" || section === "bots" || section === "classic";
|
|
239
|
-
return html`<div class="panel p-settings">
|
|
249
|
+
return html`<div data-effect-panel="settings" class="panel p-settings">
|
|
240
250
|
<${PanelHeader} title=${tn("title")} sub=${data && data.version ? html`<a class="pill ver" href=${data.version.includes("-") ? `${RELEASES}/latest` : `${RELEASES}/tag/v${data.version}`} target="_blank" rel="noopener">v${data.version}</a>` : null}>
|
|
241
251
|
<button type="button" class="btn btn-ghost btn-sm" disabled=${!ctx} onClick=${() => setDialog({ kind: "wizard", key: navKey })}><${Icon} name="wand" size=${16} /><span class="hide-narrow">${tn("wizardButton")}</span></button>
|
|
242
252
|
<button type="button" class="icon-btn" aria-label=${tn("helpButton")} title=${tn("helpButton")} onClick=${() => setDialog({ kind: "help", key: navKey })}><${Icon} name="info" /></button>
|
|
243
253
|
</${PanelHeader}>
|
|
244
|
-
<nav class="seg" aria-label=${tn("title")}>${SETTINGS_SECTIONS.map((k) => html`<a key=${k} href=${settingsPath(k)} class=${`seg-item${k === section ? " active" : ""}`}
|
|
254
|
+
<nav data-trust="panel-navigation" class="seg" aria-label=${tn("title")}>${SETTINGS_SECTIONS.map((k) => html`<a key=${k} href=${settingsPath(k)} class=${`seg-item${k === section ? " active" : ""}`}
|
|
245
255
|
aria-current=${k === section ? "page" : undefined}><${Icon} name=${ICONS[k]} size=${16} /><span>${tn(`sec_${k}`)}</span></a>`)}</nav>
|
|
246
|
-
<div class="panel-body"><div class="col">
|
|
256
|
+
<div data-trust="panel-content" class="panel-body"><div class="col">
|
|
247
257
|
${searchable ? html`<div class="s-toolbar"><label class="s-search"><${Icon} name="search" size=${14} /><span class="sr-only">${tn("searchAll")}</span>
|
|
248
258
|
<input type="search" value=${search} placeholder=${tn("searchAll")} onInput=${(e) => setSearch(e.target.value)} /></label></div>` : null}
|
|
249
259
|
${op ? html`<${OperationCard} op=${op} schema=${data && data.schema} />` : null}
|
|
@@ -454,7 +464,9 @@ function Agents({ ctx, search, openDialog }) {
|
|
|
454
464
|
const [collapsed, setCollapsed] = useState(() => new Set());
|
|
455
465
|
const [busy, setBusy] = useState(() => new Map()); // name → the action under way
|
|
456
466
|
const chs = channelsOf(ctx.fleet);
|
|
457
|
-
|
|
467
|
+
// #2172: the sidebar's grouping — an agent in a team under its team, else under its first tag.
|
|
468
|
+
const teamsOf = (name) => Object.keys(ctx.fleet.teams || {}).filter((t) => Array.isArray(ctx.fleet.teams[t]?.members) && ctx.fleet.teams[t].members.includes(name));
|
|
469
|
+
const groups = groupAgents(insts, ctx.live, search, (name) => navGroupOf({ tags: insts[name]?.tags, teams: teamsOf(name) }), groupLabel);
|
|
458
470
|
// One action per agent at a time: the whole row is off (Settings and ⋯ too), and the pressed button says it is working.
|
|
459
471
|
const run = async (name, action, work) => {
|
|
460
472
|
if (busy.has(name)) return;
|
|
@@ -470,7 +482,7 @@ function Agents({ ctx, search, openDialog }) {
|
|
|
470
482
|
return html`<section key=${group} class="s-group">
|
|
471
483
|
<button type="button" class="s-group-head" aria-expanded=${folded ? "false" : "true"}
|
|
472
484
|
onClick=${() => setCollapsed((c) => { const n = new Set(c); n.has(group) ? n.delete(group) : n.add(group); return n; })}>
|
|
473
|
-
<${Icon} name="chevron" size=${14} cls=${folded ? "caret folded" : "caret"} /><span class="grow">${group}</span><span class="count">${names.length}</span></button>
|
|
485
|
+
<${Icon} name="chevron" size=${14} cls=${folded ? "caret folded" : "caret"} /><${GroupMark} group=${group} /><span class="grow">${groupLabel(group)}</span><span class="count">${names.length}</span></button>
|
|
474
486
|
${folded ? null : names.map((name) => {
|
|
475
487
|
const inst = insts[name];
|
|
476
488
|
const st = (ctx.live[name] && ctx.live[name].status) || "stopped";
|
|
@@ -703,7 +715,8 @@ function General({ ctx }) {
|
|
|
703
715
|
<div class="field">${L(tn("language"), "defaults.locale", "g-locale")}<${Select} id="g-locale" value=${f.locale} onChange=${set("locale")}
|
|
704
716
|
options=${localeOptions(f.locale).map((o) => (o.auto ? { value: "", label: tn("localeAuto") } : o))} /></div>
|
|
705
717
|
<div class="field">${L(tn("defaultBackend"), "defaults.backend", "g-be")}<${BackendSelect} id="g-be" value=${f.backend} onChange=${set("backend")} /></div>
|
|
706
|
-
<div class="field">${L(tn("defaultModel"), "defaults.model", "g-model")}
|
|
718
|
+
<div class="field">${L(tn("defaultModel"), "defaults.model", "g-model")}<${ModelSelect} id="g-model" value=${f.model} onChange=${set("model")}
|
|
719
|
+
backend=${f.backend || "claude-code"} inherit=${tn("modelCliDefault")} /></div>
|
|
707
720
|
<div class="field">${L(`${tn("autoPause")} (${tn("minutes")})`, "defaults.auto_pause_after", "g-auto")}<input id="g-auto" type="number" min="0" step="1" class=${errors.auto ? "invalid" : ""} value=${f.auto} onInput=${(e) => set("auto")(e.target.value)} /><${Feedback} error=${errors.auto} /></div>
|
|
708
721
|
<div class="field">${L(tn("toolProgress"), "defaults.tool_progress", "g-tp")}<${Select} id="g-tp" value=${f.tool_progress} onChange=${set("tool_progress")} options=${TOOL_PROGRESS} /></div>
|
|
709
722
|
<div class="field">${L(tn("crossInstanceVisibility"), "defaults.cross_instance_visibility", "g-vis")}<${Select} id="g-vis" value=${f.visibility} onChange=${set("visibility")} options=${VISIBILITY_MODES} />
|
|
@@ -766,17 +779,20 @@ export const WEB_READ_ONLY = [
|
|
|
766
779
|
function WebSection({ ctx, staged }) {
|
|
767
780
|
const { schema } = ctx;
|
|
768
781
|
const web = ctx.fleet.web || {}, local = (web.session && web.session.local) || {}, term = ctx.fleet.web_terminal || {};
|
|
782
|
+
// Over the public link the fields read only; the Guests and Web authority cards are not offered (the server never
|
|
783
|
+
// serves their reads there).
|
|
769
784
|
const overPublicLink = globalThis.document?.body?.dataset?.publicLink === "1";
|
|
770
785
|
const original = useMemo(() => ({
|
|
771
786
|
echo: web.echo_to_channel ?? true,
|
|
772
787
|
log: web.log_tab === true, // #1218: off by default
|
|
788
|
+
usagePub: web.usage_report_on_public_link === true, // #2122: off by default
|
|
773
789
|
pub: { allow_public: (web.public_link && web.public_link.allow_public) ?? true, ttl_minutes: (web.public_link && web.public_link.ttl_minutes) ?? 120, protocol: (web.public_link && web.public_link.protocol) ?? "http2" },
|
|
774
790
|
session: { absolute_hours: local.absolute_hours ?? null, idle_hours: local.idle_hours ?? null },
|
|
775
791
|
terminal: { enabled: term.enabled ?? null, ttl_minutes: term.ttl_minutes ?? null },
|
|
776
792
|
}), []);
|
|
777
793
|
const text = (v) => (v === null || v === undefined ? "" : String(v));
|
|
778
794
|
const [f, setF] = useState(() => ({
|
|
779
|
-
echo: original.echo, log: original.log, pub: original.pub.allow_public, ttl: String(original.pub.ttl_minutes), protocol: original.pub.protocol,
|
|
795
|
+
echo: original.echo, log: original.log, usagePub: original.usagePub, pub: original.pub.allow_public, ttl: String(original.pub.ttl_minutes), protocol: original.pub.protocol,
|
|
780
796
|
abs: text(original.session.absolute_hours), idle: text(original.session.idle_hours),
|
|
781
797
|
termOn: original.terminal.enabled !== false, termTtl: text(original.terminal.ttl_minutes),
|
|
782
798
|
}));
|
|
@@ -805,6 +821,7 @@ function WebSection({ ctx, staged }) {
|
|
|
805
821
|
const body = {
|
|
806
822
|
...(f.echo !== original.echo ? { echo_to_channel: f.echo } : {}),
|
|
807
823
|
...(f.log !== original.log ? { log_tab: f.log } : {}),
|
|
824
|
+
...(f.usagePub !== original.usagePub ? { usage_report_on_public_link: f.usagePub } : {}),
|
|
808
825
|
...(Object.keys(publicPatch).length ? { public_link: publicPatch } : {}),
|
|
809
826
|
...(Object.keys(sessionPatch).length ? { session: { local: sessionPatch } } : {}),
|
|
810
827
|
...(Object.keys(terminalPatch).length ? { web_terminal: terminalPatch } : {}),
|
|
@@ -812,6 +829,7 @@ function WebSection({ ctx, staged }) {
|
|
|
812
829
|
const fields = [
|
|
813
830
|
...(body.echo_to_channel !== undefined ? ["web.echo_to_channel"] : []),
|
|
814
831
|
...(body.log_tab !== undefined ? ["web.log_tab"] : []),
|
|
832
|
+
...(body.usage_report_on_public_link !== undefined ? ["web.usage_report_on_public_link"] : []),
|
|
815
833
|
...Object.keys(publicPatch).map((k) => `web.public_link.${k}`),
|
|
816
834
|
...Object.keys(sessionPatch).map((k) => `web.session.local.${k}`),
|
|
817
835
|
...Object.keys(terminalPatch).map((k) => `web_terminal.${k}`),
|
|
@@ -853,6 +871,8 @@ function WebSection({ ctx, staged }) {
|
|
|
853
871
|
<p class="note">${tn("webEchoHint")}</p>
|
|
854
872
|
<label class="check"><input id="webLogTab" type="checkbox" checked=${f.log} onChange=${(e) => set("log")(e.target.checked)} /><span>${tn("webLogTab")}</span><${Impact} schema=${schema} field="web.log_tab" /></label>
|
|
855
873
|
<p class="note">${tn("webLogTabHint")}</p>
|
|
874
|
+
<label class="check"><input id="webUsagePublic" type="checkbox" checked=${f.usagePub} onChange=${(e) => set("usagePub")(e.target.checked)} /><span>${tn("webUsagePublic")}</span><${Impact} schema=${schema} field="web.usage_report_on_public_link" /></label>
|
|
875
|
+
<p class="note">${tn("webUsagePublicHint")}</p>
|
|
856
876
|
<label class="check"><input id="publicWebLink" type="checkbox" checked=${f.pub} onChange=${(e) => set("pub")(e.target.checked)} /><span>${tn("publicLink")}</span><${Impact} schema=${schema} field="web.public_link.allow_public" /></label>
|
|
857
877
|
<p class="note">${tn("publicLinkHint")}</p>
|
|
858
878
|
<div class="grid2">
|
|
@@ -861,6 +881,7 @@ function WebSection({ ctx, staged }) {
|
|
|
861
881
|
</div>
|
|
862
882
|
</section>
|
|
863
883
|
</fieldset>
|
|
884
|
+
${overPublicLink ? null : html`<${GuestsCard} ctx=${ctx} staged=${staged} /><${WebAuthorityCard} ctx=${ctx} staged=${staged} />`}
|
|
864
885
|
<section class="card s-web-readonly"><h3>${tn("webReadOnlyTitle")}</h3>
|
|
865
886
|
<p class="note">${tn("webReadOnlyLead")}</p>
|
|
866
887
|
<dl class="s-web-ro">${WEB_READ_ONLY.map((k) => html`<div key=${k}><dt><code>${k}</code></dt><dd>${shown(k)}</dd></div>`)}</dl>
|
|
@@ -915,7 +936,7 @@ function Developer({ ctx }) {
|
|
|
915
936
|
/** Staged, not applied: the count, what it will cost, Discard and Apply. */
|
|
916
937
|
function PendingBar({ staged, busy, onApply, onDiscard }) {
|
|
917
938
|
const kinds = [...new Set([...staged.values()].map((c) => c.impact))];
|
|
918
|
-
return html`<div class="s-pending" role="region" aria-label=${tn("pendingRegion")}>
|
|
939
|
+
return html`<div data-trust="panel-controls" class="s-pending" role="region" aria-label=${tn("pendingRegion")}>
|
|
919
940
|
<strong>${tn("changesPending", staged.size)}</strong>
|
|
920
941
|
<span class="note">${kinds.map(impactText).join(" · ")}</span>
|
|
921
942
|
<span class="grow"></span>
|
|
@@ -938,7 +959,7 @@ function OperationCard({ op, schema }) {
|
|
|
938
959
|
const mismatch = schema && schema.fleet_signature_mismatch;
|
|
939
960
|
const title = op.phase === "failed" ? tn("applyPartial") : fleetRestarting ? tn("restartFleetTitle") : busy ? tn("applying")
|
|
940
961
|
: failedRows ? tn("applyPartial") : needsRestart ? tn("applyRestartNeeded") : tn("applyDone");
|
|
941
|
-
const note = op.phase === "failed" ? (op.error === "busy" ? tn("applyBusy") : op.error ? tn("applyStepFailed", op.error) : "")
|
|
962
|
+
const note = op.phase === "failed" ? (op.error === "busy" ? tn("applyBusy") : op.error ? tn("applyStepFailed", applyErrorText(op.error)) : "")
|
|
942
963
|
: fleetRestarting ? tn("restartFleetWaiting") : op.lostJob ? tn("applyLostJob")
|
|
943
964
|
: job && job.overdue ? tn("applyStillWorking", Math.round((job.elapsed_ms || 0) / 1000))
|
|
944
965
|
: mismatch && needsRestart ? tn("signatureMismatch", mismatch.join(", ")) : needsRestart ? tn("applyRestartHint") : "";
|
|
@@ -965,7 +986,7 @@ function OperationCard({ op, schema }) {
|
|
|
965
986
|
${op.steps.length ? html`<ul class="s-op-steps">${op.steps.map((s, i) => html`<li key=${i} class=${`s-step ${s.status}`}>
|
|
966
987
|
<span class="s-step-icon" aria-hidden="true">${icon(s.status) ? html`<${Icon} name=${icon(s.status)} size=${14} />` : "·"}</span>
|
|
967
988
|
<span class="grow">${s.label}</span>
|
|
968
|
-
<span class="note">${s.status === "waiting" ? tn("stepWaiting") : s.status === "skipped" ? tn("stepSkipped") : s.status === "failed" ? (s.error
|
|
989
|
+
<span class="note">${s.status === "waiting" ? tn("stepWaiting") : s.status === "skipped" ? tn("stepSkipped") : s.status === "failed" ? (s.error ? applyErrorText(s.error) : tn("applyFailed")) : s.note || impactText(s.impact)}</span></li>`)}</ul>` : null}
|
|
969
990
|
${rows.length ? html`<ul class="s-op-steps">${rows.map((r) => html`<li key=${r.target} class=${`s-step ${r.status}`}>
|
|
970
991
|
<span class="s-step-icon" aria-hidden="true">${r.status === "done" ? html`<${Icon} name="check" size=${14} />` : r.status === "failed" ? html`<${Icon} name="alert" size=${14} />` : r.status === "restart-required" ? html`<${Icon} name="restart" size=${14} />` : "·"}</span>
|
|
971
992
|
<span class="grow">${r.target === "fleet" ? "AgEnD" : shortName(r.target, {})}</span>
|
package/dist/ui/preview-panel.js
CHANGED
|
@@ -16,6 +16,7 @@ import { Icon } from "/assets/ui-icons.js";
|
|
|
16
16
|
import "./chat-render.js";
|
|
17
17
|
import "./preview.js";
|
|
18
18
|
import { loadHtmlAttachment } from "./html-attachment.js";
|
|
19
|
+
import { EffectTrialPanel } from "./effect-trial-panel.js";
|
|
19
20
|
import { chatTime, onDayChange } from "./chat-time.js";
|
|
20
21
|
|
|
21
22
|
const R = () => globalThis.AgendChatRender;
|
|
@@ -43,14 +44,25 @@ export const panelClaims = () => claims;
|
|
|
43
44
|
/** The frame's key in preview.js: its own, so the card that opened it keeps its own state. */
|
|
44
45
|
export const frameKey = (key) => `panel:${key}`;
|
|
45
46
|
/** Show `spec` in the panel; `run`: start it there (the card's "Open in panel" click). The block shown before stops. */
|
|
47
|
+
function retire(open) {
|
|
48
|
+
if (!open) return;
|
|
49
|
+
if (open.kind === "trial") { try { open.handle.stop(); } catch { /* host controller owns cleanup */ } }
|
|
50
|
+
else if (P()) P().stop(frameKey(open.key), "stopped", "");
|
|
51
|
+
}
|
|
46
52
|
export function openPanel(spec, { run = false } = {}) {
|
|
47
|
-
|
|
48
|
-
set({ open: { ...spec }, run: run ? ++runs : 0 });
|
|
53
|
+
const old = state.open;
|
|
54
|
+
set({ open: { ...spec, kind: "html" }, run: run ? ++runs : 0 });
|
|
55
|
+
retire(old); // State changes first: cleanup reentry cannot close a newer panel.
|
|
56
|
+
}
|
|
57
|
+
/** A checked controller handle enters the existing component slot; no HTML run token is issued. */
|
|
58
|
+
export function openTrialPanel(spec) {
|
|
59
|
+
const old = state.open;
|
|
60
|
+
set({ open: { ...spec, kind: "trial" }, run: 0 }); retire(old);
|
|
49
61
|
}
|
|
50
|
-
/** Close the
|
|
62
|
+
/** Close publishes the empty slot before old-owner callbacks can reenter. */
|
|
51
63
|
export function closePanel() {
|
|
52
|
-
|
|
53
|
-
|
|
64
|
+
const old = state.open; if (!old) return;
|
|
65
|
+
set({ open: null, run: 0 }); retire(old);
|
|
54
66
|
}
|
|
55
67
|
/** The card key the panel shows, or null. */
|
|
56
68
|
export const shownKey = () => (state.open ? state.open.key : null);
|
|
@@ -67,7 +79,7 @@ export function htmlTitle(code) {
|
|
|
67
79
|
* without one, the newest block does. `msgs` in order; `keyOf` makes a message's key.
|
|
68
80
|
*/
|
|
69
81
|
export function newerVersion(open, msgs, keyOf) {
|
|
70
|
-
if (!open || !Array.isArray(msgs)) return null;
|
|
82
|
+
if (!open || open.kind === "trial" || !Array.isArray(msgs)) return null;
|
|
71
83
|
const at = msgs.findIndex(x => keyOf(x) === open.msgKey);
|
|
72
84
|
if (at < 0) return null;
|
|
73
85
|
// An attached file: a later agent reply attaching a file of the same name is its newer version. Its HTML is read
|
|
@@ -132,7 +144,8 @@ export function PreviewPanel({ name, split, msgs, subscribe, keyOf, reveal, down
|
|
|
132
144
|
const pending = useRef(0); // #1704: the card's click, waiting for this device's Allow (the st.run it came with)
|
|
133
145
|
const ownAllow = useRef(0); // while this panel's own Allow commits its choice: the click it answers (not cancelled by it)
|
|
134
146
|
const holder = useRef(null), divider = useRef(null), panel = useRef(null);
|
|
135
|
-
const
|
|
147
|
+
const trial = st.open?.kind === "trial" && st.open.instance === name ? st.open : null;
|
|
148
|
+
const open = st.open?.kind !== "trial" && st.open?.instance === name ? st.open : null;
|
|
136
149
|
|
|
137
150
|
useEffect(() => panelStore.subscribe(setSt), []);
|
|
138
151
|
// This device's choice (here or in another tab) decides whether Preview is offered: re-read it when it changes.
|
|
@@ -231,6 +244,9 @@ export function PreviewPanel({ name, split, msgs, subscribe, keyOf, reveal, down
|
|
|
231
244
|
// Esc in the panel closes it (and is not the chat's "stop the reply").
|
|
232
245
|
const onPanelKey = (e) => { if (e.key === "Escape" && !e.isComposing) { e.preventDefault(); closePanel(); } };
|
|
233
246
|
|
|
247
|
+
if (trial) return html`<${EffectTrialPanel} binding=${trial.binding} title=${trial.handle.reply.offer.title}
|
|
248
|
+
current=${trial.handle.current} ownerCss=${trial.ownerCss} onStage=${trial.onStage}
|
|
249
|
+
onStop=${trial.handle.stop} onClose=${() => { if (panelStore.get().open === trial) closePanel(); }} />`;
|
|
234
250
|
if (!open) return null;
|
|
235
251
|
const going = run.state === "starting" || run.state === "running";
|
|
236
252
|
const a = P().availability();
|
|
@@ -250,9 +266,9 @@ export function PreviewPanel({ name, split, msgs, subscribe, keyOf, reveal, down
|
|
|
250
266
|
if (want && pending.current === want && panelStore.get().run === want) start();
|
|
251
267
|
};
|
|
252
268
|
const source = t("chat.pvSource", open.sender || name, timeOf(open.ts));
|
|
253
|
-
return html`<div class="pv-divider" ref=${divider} role="separator" aria-orientation="vertical" tabindex="0" aria-label=${t("chat.pvResize")}
|
|
269
|
+
return html`<div data-trust="preview" class="pv-divider" ref=${divider} role="separator" aria-orientation="vertical" tabindex="0" aria-label=${t("chat.pvResize")}
|
|
254
270
|
aria-valuemin=${String(MIN_PANEL)} onKeyDown=${onKey} onPointerDown=${onDown}></div>
|
|
255
|
-
<aside class="pv-panel" ref=${panel} aria-label=${t("chat.pvPanel")} onKeyDown=${onPanelKey}>
|
|
271
|
+
<aside data-trust="preview" class="pv-panel" ref=${panel} aria-label=${t("chat.pvPanel")} onKeyDown=${onPanelKey}>
|
|
256
272
|
<div class="pv-panel-head">
|
|
257
273
|
<button type="button" class="icon-btn only-narrow pv-panel-close" title=${t("chat.pvBack")} aria-label=${t("chat.pvBack")} onClick=${closePanel}><${Icon} name="back" size=${18} /></button>
|
|
258
274
|
<div class="pv-panel-title"><strong>${t("chat.pvPanel")}</strong>
|
package/dist/ui/preview.js
CHANGED
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
notify();
|
|
101
101
|
return true;
|
|
102
102
|
}
|
|
103
|
-
if (j && (j.code === "publicLinkPreviewFailed" || j.code === "publicLink" || j.code === "fleetOff")) {
|
|
103
|
+
if (j && (j.code === "publicLinkPreviewFailed" || j.code === "publicLink" || j.code === "fleetOff" || j.code === "listenFailed" || j.code === "notListening")) {
|
|
104
104
|
cfg.reasonCode = j.code; cfg.reason = ""; cfg.detail = typeof j.detail === "string" ? j.detail : "";
|
|
105
105
|
notify();
|
|
106
106
|
return true;
|
|
@@ -191,7 +191,8 @@
|
|
|
191
191
|
if (!cfg.previewOrigin || !cfg.boot) {
|
|
192
192
|
// The server's reason, in the page's language when the server named it (a code), else as the server wrote it.
|
|
193
193
|
// #1723: a failed public-link preview names why ({0} is the reason, in the page's words).
|
|
194
|
-
var arg = cfg.reasonCode === "publicLinkPreviewFailed" ? say("pvFail_" + (cfg.detail || "unknown"), Object.prototype.hasOwnProperty.call(FAIL_EN, cfg.detail) ? FAIL_EN[cfg.detail] : "an unexpected error")
|
|
194
|
+
var arg = cfg.reasonCode === "publicLinkPreviewFailed" ? say("pvFail_" + (cfg.detail || "unknown"), Object.prototype.hasOwnProperty.call(FAIL_EN, cfg.detail) ? FAIL_EN[cfg.detail] : "an unexpected error")
|
|
195
|
+
: cfg.reasonCode === "listenFailed" ? cfg.detail : cfg.dashboardOrigin;
|
|
195
196
|
var english = cfg.reasonCode === "publicLinkPreviewFailed" ? "Previews are unavailable on this public link: {0}. The link itself keeps working."
|
|
196
197
|
: cfg.reason || "Previews are not available here.";
|
|
197
198
|
var server = cfg.reasonCode ? say("pvServer_" + cfg.reasonCode, english, arg) : "";
|