@songsid/agend 2.2.0-beta.9 → 2.3.0-beta.1
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/README.md +40 -24
- package/README.zh-TW.md +40 -24
- package/dist/agent-cli.js +248 -2
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.d.ts +2 -0
- package/dist/agent-endpoint.js +28 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-file-read.d.ts +30 -0
- package/dist/agent-file-read.js +129 -0
- package/dist/agent-file-read.js.map +1 -0
- package/dist/agent-whats-new.js +20 -1
- 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 +3 -1
- package/dist/auth-api.js +32 -1
- package/dist/auth-api.js.map +1 -1
- package/dist/backend/antigravity.d.ts +33 -0
- package/dist/backend/antigravity.js +129 -21
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.d.ts +3 -0
- package/dist/backend/claude-code.js +9 -0
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-metadata.d.ts +33 -0
- package/dist/backend/codex-metadata.js +122 -18
- package/dist/backend/codex-metadata.js.map +1 -1
- package/dist/backend/codex.d.ts +3 -0
- package/dist/backend/codex.js +17 -1
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/effort-metadata.d.ts +37 -1
- package/dist/backend/effort-metadata.js +86 -15
- package/dist/backend/effort-metadata.js.map +1 -1
- package/dist/backend/grok.d.ts +3 -0
- package/dist/backend/grok.js +9 -0
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/kiro.d.ts +3 -1
- package/dist/backend/kiro.js +7 -3
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/launch-effort.d.ts +61 -0
- package/dist/backend/launch-effort.js +170 -0
- package/dist/backend/launch-effort.js.map +1 -0
- package/dist/backend/muse.js +10 -2
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/types.d.ts +24 -0
- package/dist/backend/types.js +12 -1
- package/dist/backend/types.js.map +1 -1
- package/dist/backend-command.d.ts +91 -0
- package/dist/backend-command.js +122 -0
- package/dist/backend-command.js.map +1 -0
- package/dist/channel/adapters/discord.d.ts +14 -0
- package/dist/channel/adapters/discord.js +66 -4
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +26 -1
- package/dist/channel/adapters/telegram.js +98 -7
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-tools.js +36 -0
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/tool-router.d.ts +2 -0
- package/dist/channel/tool-router.js +1 -1
- package/dist/channel/tool-router.js.map +1 -1
- package/dist/channel/types.d.ts +31 -0
- package/dist/cli.js +124 -24
- package/dist/cli.js.map +1 -1
- package/dist/command-table.d.ts +2 -2
- package/dist/command-table.js +5 -2
- package/dist/command-table.js.map +1 -1
- package/dist/compact-watch.d.ts +86 -0
- package/dist/compact-watch.js +288 -0
- package/dist/compact-watch.js.map +1 -0
- package/dist/config-validator.js +55 -0
- package/dist/config-validator.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/daemon.d.ts +9 -0
- package/dist/daemon.js +394 -29
- package/dist/daemon.js.map +1 -1
- package/dist/delivery-outbox.d.ts +8 -1
- package/dist/delivery-outbox.js +6 -2
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/doctor.js +7 -0
- package/dist/doctor.js.map +1 -1
- package/dist/fleet-context.d.ts +12 -0
- package/dist/fleet-manager.d.ts +247 -9
- package/dist/fleet-manager.js +1227 -142
- package/dist/fleet-manager.js.map +1 -1
- package/dist/forged-envelope-scan.d.ts +4 -3
- package/dist/forged-envelope-scan.js +4 -3
- package/dist/forged-envelope-scan.js.map +1 -1
- package/dist/general-knowledge/skills/model-discovery/SKILL.md +4 -1
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +258 -0
- package/dist/install-lock.d.ts +18 -1
- package/dist/install-lock.js +30 -3
- package/dist/install-lock.js.map +1 -1
- package/dist/instance-avatar.d.ts +5 -4
- package/dist/instance-avatar.js +15 -8
- package/dist/instance-avatar.js.map +1 -1
- package/dist/instance-config-impact.js +3 -0
- 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/instructions.js +2 -2
- package/dist/instructions.js.map +1 -1
- package/dist/kiro-compact-pane.d.ts +38 -0
- package/dist/kiro-compact-pane.js +57 -0
- package/dist/kiro-compact-pane.js.map +1 -0
- package/dist/launchd-handoff.d.ts +43 -0
- package/dist/launchd-handoff.js +56 -0
- package/dist/launchd-handoff.js.map +1 -0
- package/dist/locale.js +202 -30
- package/dist/locale.js.map +1 -1
- package/dist/log-service.js +10 -2
- package/dist/log-service.js.map +1 -1
- package/dist/login-shell.d.ts +21 -0
- package/dist/login-shell.js +98 -0
- package/dist/login-shell.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 +32 -0
- package/dist/outbound-handlers.js +150 -45
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +76 -0
- package/dist/outbound-schemas.js +65 -4
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/provider-probe.d.ts +29 -0
- package/dist/provider-probe.js +198 -2
- package/dist/provider-probe.js.map +1 -1
- package/dist/public-web-gateway.d.ts +2 -0
- package/dist/public-web-gateway.js +25 -1
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/quickstart-api.d.ts +1 -1
- package/dist/quickstart-api.js +8 -6
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +12 -0
- package/dist/quickstart.js +36 -6
- package/dist/quickstart.js.map +1 -1
- package/dist/reply-buttons-controller.d.ts +86 -5
- package/dist/reply-buttons-controller.js +271 -7
- package/dist/reply-buttons-controller.js.map +1 -1
- package/dist/reply-buttons.d.ts +48 -3
- package/dist/reply-buttons.js +105 -10
- package/dist/reply-buttons.js.map +1 -1
- package/dist/reply-polls.d.ts +85 -0
- package/dist/reply-polls.js +154 -0
- package/dist/reply-polls.js.map +1 -0
- 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-guard.d.ts +6 -3
- package/dist/restart-guard.js +6 -3
- package/dist/restart-guard.js.map +1 -1
- package/dist/restart-progress.d.ts +0 -2
- package/dist/restart-progress.js +0 -2
- package/dist/restart-progress.js.map +1 -1
- package/dist/scheduler/scheduler.d.ts +58 -1
- package/dist/scheduler/scheduler.js +176 -10
- package/dist/scheduler/scheduler.js.map +1 -1
- package/dist/sd-notify.d.ts +22 -1
- package/dist/sd-notify.js +63 -10
- package/dist/sd-notify.js.map +1 -1
- package/dist/service-activation.d.ts +15 -7
- package/dist/service-activation.js +42 -26
- package/dist/service-activation.js.map +1 -1
- package/dist/service-installer.d.ts +24 -0
- package/dist/service-installer.js +49 -1
- package/dist/service-installer.js.map +1 -1
- package/dist/service-plan.d.ts +11 -0
- package/dist/service-plan.js +23 -0
- package/dist/service-plan.js.map +1 -1
- package/dist/settings-api.js +74 -1
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +8 -0
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.js +16 -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/systemd-peer-bus.d.ts +95 -0
- package/dist/systemd-peer-bus.js +430 -0
- package/dist/systemd-peer-bus.js.map +1 -0
- package/dist/systemd-runtime.d.ts +27 -1
- package/dist/systemd-runtime.js +69 -7
- package/dist/systemd-runtime.js.map +1 -1
- package/dist/tool-permissions.js +53 -3
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.d.ts +72 -2
- package/dist/topic-commands.js +156 -38
- 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/transcript-jsonl.d.ts +7 -2
- package/dist/transcript-jsonl.js +13 -7
- package/dist/transcript-jsonl.js.map +1 -1
- package/dist/transcript-sources.js +6 -1
- package/dist/transcript-sources.js.map +1 -1
- package/dist/types.d.ts +21 -0
- package/dist/ui/app-effects.js +187 -0
- package/dist/ui/chat-commands.js +1 -0
- package/dist/ui/chat-effect-posters.js +42 -0
- package/dist/ui/chat-effects.js +72 -0
- package/dist/ui/chat-live-replies.js +58 -0
- package/dist/ui/chat-render.js +59 -14
- package/dist/ui/chat-store.js +78 -8
- package/dist/ui/chat-strings.js +43 -16
- package/dist/ui/chat-thread.js +175 -31
- package/dist/ui/chat-tour.js +18 -15
- package/dist/ui/effect-trial-controller.js +119 -0
- package/dist/ui/effect-trial-offer.js +31 -0
- package/dist/ui/effect-trial-panel.js +37 -0
- package/dist/ui/image-lightbox.js +1 -1
- package/dist/ui/panel-chat.js +101 -27
- package/dist/ui/panel-details.js +18 -5
- package/dist/ui/panel-fleet.js +18 -5
- package/dist/ui/panel-log.js +10 -10
- package/dist/ui/panel-needs.js +13 -10
- package/dist/ui/panel-settings.js +66 -12
- package/dist/ui/preview-panel.js +25 -9
- package/dist/ui/settings-appearance.js +325 -0
- package/dist/ui/settings-dialogs.js +11 -6
- package/dist/ui/settings-effects.js +201 -0
- package/dist/ui/settings-model.js +3 -1
- package/dist/ui/settings-mods.js +257 -0
- package/dist/ui/settings-owner-effects.js +80 -0
- package/dist/ui/settings-strings.js +269 -10
- package/dist/ui/settings-token.js +7 -0
- package/dist/ui/settings-wizard.js +5 -3
- package/dist/ui/shared/agend-auth.js +27 -3
- package/dist/ui/shared/agent-widget.js +248 -0
- package/dist/ui/shared/app-i18n.js +3 -1
- package/dist/ui/shared/app-prefs.js +30 -10
- package/dist/ui/shared/app-route.js +23 -1
- package/dist/ui/shared/app-session.js +1 -1
- package/dist/ui/shared/app-shell.js +29 -16
- package/dist/ui/shared/app-store.js +2 -0
- package/dist/ui/shared/app-stream.js +15 -7
- package/dist/ui/shared/app-themes.js +188 -0
- package/dist/ui/shared/app.css +266 -11
- package/dist/ui/shared/app.js +6 -0
- package/dist/ui/shared/card-strings.js +28 -0
- package/dist/ui/shared/effect-app-runtime.js +248 -0
- package/dist/ui/shared/effect-baseline.js +64 -0
- package/dist/ui/shared/effect-chat-runtime.js +154 -0
- package/dist/ui/shared/effect-cursor.js +125 -0
- package/dist/ui/shared/effect-frame.js +127 -0
- package/dist/ui/shared/effect-geometry.js +122 -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 +137 -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 +162 -0
- package/dist/ui/shared/effect-profiles.js +65 -0
- package/dist/ui/shared/effect-registry.js +496 -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 +34 -0
- package/dist/ui/shared/effect-stock-trust.js +165 -0
- package/dist/ui/shared/effect-trial-source.js +103 -0
- package/dist/ui/shared/effect-trial-stage.js +147 -0
- package/dist/ui/shared/header-tools.js +35 -15
- package/dist/ui/shared/identity-card.js +202 -0
- package/dist/ui/shared/identity-color.js +261 -0
- package/dist/ui/shared/instance-nav.js +22 -14
- package/dist/ui/shared/instance-switch.js +5 -2
- 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 +96 -12
- package/dist/ui/shared/signin.js +17 -9
- 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/view-strings.js +40 -2
- package/dist/ui/signin.html +9 -3
- package/dist/update-check.d.ts +31 -0
- package/dist/update-check.js +47 -0
- package/dist/update-check.js.map +1 -1
- package/dist/update-launch.d.ts +48 -1
- package/dist/update-launch.js +159 -5
- package/dist/update-launch.js.map +1 -1
- package/dist/usage/providers.d.ts +28 -8
- package/dist/usage/providers.js +96 -41
- package/dist/usage/providers.js.map +1 -1
- package/dist/view-api.d.ts +29 -0
- package/dist/view-api.js +214 -17
- package/dist/view-api.js.map +1 -1
- package/dist/web-api.d.ts +86 -2
- package/dist/web-api.js +1160 -92
- 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 +66 -0
- package/dist/web-appearance-policy.js +94 -0
- package/dist/web-appearance-policy.js.map +1 -0
- package/dist/web-appearance-tools.d.ts +50 -0
- package/dist/web-appearance-tools.js +105 -0
- package/dist/web-appearance-tools.js.map +1 -0
- package/dist/web-appearance-view.d.ts +99 -0
- package/dist/web-appearance-view.js +163 -0
- package/dist/web-appearance-view.js.map +1 -0
- package/dist/web-appearance.d.ts +79 -0
- package/dist/web-appearance.js +298 -0
- package/dist/web-appearance.js.map +1 -0
- package/dist/web-asset-parts.d.ts +98 -0
- package/dist/web-asset-parts.js +133 -0
- package/dist/web-asset-parts.js.map +1 -0
- package/dist/web-auth.js +17 -1
- package/dist/web-auth.js.map +1 -1
- package/dist/web-card.d.ts +96 -0
- package/dist/web-card.js +232 -0
- package/dist/web-card.js.map +1 -0
- package/dist/web-chat-history.d.ts +39 -1
- package/dist/web-chat-history.js +69 -9
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-commands.d.ts +39 -3
- package/dist/web-commands.js +22 -5
- package/dist/web-commands.js.map +1 -1
- package/dist/web-effect-bundle.d.ts +28 -0
- package/dist/web-effect-bundle.js +126 -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-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 +86 -0
- package/dist/web-effect-service.js +312 -0
- package/dist/web-effect-service.js.map +1 -0
- package/dist/web-effect-tools.d.ts +47 -0
- package/dist/web-effect-tools.js +126 -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 +29 -0
- package/dist/web-effect-upload.js +190 -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 +89 -0
- package/dist/web-effect.js +132 -0
- package/dist/web-effect.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 +14 -0
- package/dist/web-login.js +4 -2
- package/dist/web-login.js.map +1 -1
- package/dist/web-mod-agent.d.ts +50 -0
- package/dist/web-mod-agent.js +203 -0
- package/dist/web-mod-agent.js.map +1 -0
- package/dist/web-mod-bundle.d.ts +144 -0
- package/dist/web-mod-bundle.js +464 -0
- package/dist/web-mod-bundle.js.map +1 -0
- package/dist/web-mod-export.d.ts +59 -0
- package/dist/web-mod-export.js +79 -0
- package/dist/web-mod-export.js.map +1 -0
- package/dist/web-mod-store.d.ts +283 -0
- package/dist/web-mod-store.js +624 -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 +66 -0
- package/dist/web-prefs.js +243 -35
- package/dist/web-prefs.js.map +1 -1
- package/dist/web-preview.d.ts +9 -1
- package/dist/web-preview.js +24 -7
- package/dist/web-preview.js.map +1 -1
- package/dist/web-profile.d.ts +32 -0
- package/dist/web-profile.js +132 -0
- package/dist/web-profile.js.map +1 -0
- package/dist/web-session.d.ts +14 -0
- package/dist/web-session.js +10 -0
- package/dist/web-session.js.map +1 -1
- package/dist/web-settings-patch.d.ts +18 -0
- package/dist/web-settings-patch.js +51 -0
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-shell-routes.d.ts +1 -1
- package/dist/web-shell-routes.js +1 -1
- package/dist/web-shell-routes.js.map +1 -1
- package/dist/web-theme-store.d.ts +218 -0
- package/dist/web-theme-store.js +516 -0
- package/dist/web-theme-store.js.map +1 -0
- package/dist/web-theme.d.ts +121 -0
- package/dist/web-theme.js +407 -0
- package/dist/web-theme.js.map +1 -0
- package/dist/web-upload.d.ts +119 -4
- package/dist/web-upload.js +252 -39
- package/dist/web-upload.js.map +1 -1
- package/dist/web-widget.d.ts +72 -0
- package/dist/web-widget.js +245 -0
- package/dist/web-widget.js.map +1 -0
- package/launcher/install-admission.cjs +61 -6
- package/package.json +3 -3
package/dist/ui/panel-needs.js
CHANGED
|
@@ -23,25 +23,25 @@ import { notifyStore, notifySupport, reasonText, refreshNotify, setNotify } from
|
|
|
23
23
|
|
|
24
24
|
register("needs", {
|
|
25
25
|
en: {
|
|
26
|
-
title: "Needs you", empty: "Nothing needs you right now", emptyHint: "When an agent waits for you, it shows here — and in
|
|
26
|
+
title: "Needs you", empty: "Nothing needs you right now", emptyHint: "When an agent waits for you, it shows here — and in your chat app's General.", emptyHintWeb: "When an agent waits for you, it shows here.",
|
|
27
27
|
open: "Open chat", acknowledge: "Acknowledge", acknowledging: "Acknowledging…", answering: "Answering…",
|
|
28
28
|
ageNow: "just now", ageMin: "{0} min", ageHour: "{0} h", ageDay: "{0} d",
|
|
29
29
|
notifyTitle: "Notify me on this device", notifyOn: "Notifications are on for this browser while a tab is open.",
|
|
30
30
|
notifyOff: "Get a desktop notification when something new needs you while this tab is in the background.",
|
|
31
31
|
notifyDenied: "This browser blocked notifications for AgEnD. Allow them in the site settings to turn this on.",
|
|
32
|
-
notifyMobile: "On a phone, rely on
|
|
32
|
+
notifyMobile: "On a phone, rely on your chat app's notification: a new item is a new post in General.", notifyMobileWeb: "On a phone, open this page to see what needs you.",
|
|
33
33
|
notifyInsecure: "Notifications need a secure address (localhost or the HTTPS public link), not a plain-HTTP LAN address.",
|
|
34
34
|
notifyUnsupported: "This browser cannot show notifications.", turnOn: "Turn on", turnOff: "Turn off",
|
|
35
35
|
typePrompt: "Fleet prompt", typeAwaiting: "At its terminal", typeInstance: "Instance", typeDelivery: "Delivery",
|
|
36
36
|
},
|
|
37
37
|
"zh-TW": {
|
|
38
|
-
title: "等你處理", empty: "目前沒有需要你處理的事", emptyHint: "agent
|
|
38
|
+
title: "等你處理", empty: "目前沒有需要你處理的事", emptyHint: "agent 在等你時,會出現在這裡——也會出現在聊天 app 的 General。", emptyHintWeb: "agent 在等你時,會出現在這裡。",
|
|
39
39
|
open: "開啟聊天", acknowledge: "確認", acknowledging: "確認中…", answering: "回覆中…",
|
|
40
40
|
ageNow: "剛剛", ageMin: "{0} 分鐘", ageHour: "{0} 小時", ageDay: "{0} 天",
|
|
41
41
|
notifyTitle: "在這台裝置通知我", notifyOn: "這個瀏覽器的通知已開啟(需要開著分頁)。",
|
|
42
42
|
notifyOff: "分頁在背景時,有新的事等你處理就跳出桌面通知。",
|
|
43
43
|
notifyDenied: "這個瀏覽器封鎖了 AgEnD 的通知。請在網站設定中允許後再開啟。",
|
|
44
|
-
notifyMobile: "
|
|
44
|
+
notifyMobile: "在手機上請以聊天 app 的通知為主:每個新項目都會在 General 發一則新訊息。", notifyMobileWeb: "在手機上請打開這個頁面查看等你處理的事。",
|
|
45
45
|
notifyInsecure: "通知需要安全的網址(localhost 或 HTTPS 公開連結),區網的一般 HTTP 網址不行。",
|
|
46
46
|
notifyUnsupported: "這個瀏覽器無法顯示通知。", turnOn: "開啟", turnOff: "關閉",
|
|
47
47
|
typePrompt: "Fleet 提示", typeAwaiting: "在終端機上", typeInstance: "Instance", typeDelivery: "傳送",
|
|
@@ -108,7 +108,9 @@ export function groupNeeds(items) {
|
|
|
108
108
|
|
|
109
109
|
export function NeedsPanel({ navKey }) {
|
|
110
110
|
const lease = useLease(navKey);
|
|
111
|
-
const { needs, chatOwner: owner, instances } = useStore(appStore);
|
|
111
|
+
const { needs, chatOwner: owner, instances, connections } = useStore(appStore);
|
|
112
|
+
// #1854: a fleet with no chat connection (web only, or not known yet) has no General to point at.
|
|
113
|
+
const chatApp = connections > 0;
|
|
112
114
|
const names = useStore(namesStore);
|
|
113
115
|
// #1630/#1722: a group is headed by the instance's leading name (the "Names" preference), as the sidebar shows it.
|
|
114
116
|
const nameFor = (instance) => { const it = (instances || []).find((i) => i && i.name === instance); return it ? namesOf(it, names.primary).primary : instance; };
|
|
@@ -121,10 +123,10 @@ export function NeedsPanel({ navKey }) {
|
|
|
121
123
|
useEffect(() => { if (owner) return owner.subscribe(() => tick((n) => n + 1)); return undefined; }, [owner, lease]);
|
|
122
124
|
const groups = groupNeeds(items);
|
|
123
125
|
const nowMs = Date.now();
|
|
124
|
-
return html`<div class="panel p-needs">
|
|
126
|
+
return html`<div data-effect-panel="needs" class="panel p-needs">
|
|
125
127
|
<${PanelHeader} title=${tn("title")} sub=${items.length ? t("app.needsCount", items.length) : null} />
|
|
126
|
-
<div class="panel-body"><div class="col">
|
|
127
|
-
${!items.length ? html`<${Empty} icon="check" title=${tn("empty")} hint=${tn("emptyHint")} />`
|
|
128
|
+
<div data-trust="panel-content" class="panel-body"><div class="col">
|
|
129
|
+
${!items.length ? html`<${Empty} icon="check" title=${tn("empty")} hint=${tn(chatApp ? "emptyHint" : "emptyHintWeb")} />`
|
|
128
130
|
: groups.map((g) => html`<section key=${g.instance} class="n-group" aria-label=${g.instance}>
|
|
129
131
|
<h2 class="n-group-head"><a href=${chatPath(g.instance)} title=${g.instance}>${nameFor(g.instance)}</a></h2>
|
|
130
132
|
${g.items.map((item) => html`<${NeedsItem} key=${item.id} item=${item} nowMs=${nowMs} owner=${owner} />`)}
|
|
@@ -173,7 +175,7 @@ function NeedsItem({ item, nowMs, owner }) {
|
|
|
173
175
|
setClaim("acks", item.id, res && res.ok ? "done" : null);
|
|
174
176
|
toast((body && (body.message || body.error)) || t("app.failed"), !!(res && res.ok));
|
|
175
177
|
};
|
|
176
|
-
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" : ""}`}>
|
|
177
179
|
<span class="n-icon"><${Icon} name=${ICON[item.type] || "alert"} size=${18} /></span>
|
|
178
180
|
<div class="n-body">
|
|
179
181
|
<div class="n-title"><strong>${reasonText(item)}</strong><span class="n-age">${age(item.since, nowMs)}</span></div>
|
|
@@ -196,7 +198,8 @@ function NotifyToggle() {
|
|
|
196
198
|
useEffect(() => { refreshNotify(); }, []);
|
|
197
199
|
const on = state === "on";
|
|
198
200
|
const toggle = () => { setNotify(!on); };
|
|
199
|
-
const
|
|
201
|
+
const { connections } = useStore(appStore);
|
|
202
|
+
const note = support === "mobile" ? tn(connections > 0 ? "notifyMobile" : "notifyMobileWeb") : support === "insecure" ? tn("notifyInsecure")
|
|
200
203
|
: support !== "ok" ? tn("notifyUnsupported") : state === "denied" ? tn("notifyDenied") : on ? tn("notifyOn") : tn("notifyOff");
|
|
201
204
|
return html`<section class="card n-notify"><h3>${tn("notifyTitle")}</h3>
|
|
202
205
|
<p class="note">${note}</p>
|
|
@@ -24,7 +24,7 @@ import "./settings-strings.js";
|
|
|
24
24
|
import { api, attach, confirmedWrite, newKey } from "./settings-confirm.js";
|
|
25
25
|
import { dismissOperation, operationActive, restartFleet, startOperation, takeLeftover } from "./settings-apply.js";
|
|
26
26
|
import {
|
|
27
|
-
ACCESS_MODES, AGENT_MODES, DEFAULT_SCHEMA, LOG_LEVELS, TOOL_PROGRESS, TOOL_SETS, VISIBILITY_MODES, batchImpact,
|
|
27
|
+
ACCESS_MODES, AGENT_MODES, DEFAULT_SCHEMA, HANG_TIMEOUT_DEFAULT_MINUTES, LOG_LEVELS, TOOL_PROGRESS, TOOL_SETS, VISIBILITY_MODES, batchImpact,
|
|
28
28
|
changedFields, channelId, channelsOf, chLabel, connectionState, effectiveSummary, fleetModel, fromYaml, fullModelRequests, groupAgents,
|
|
29
29
|
hasOwn, impactOf, localeOptions, defaultsImpact, requestImpact, nonNegative, positive, replyGuardSupported, shortName, STATUS_ORDER, toYaml,
|
|
30
30
|
visibilityDefault, worstImpact,
|
|
@@ -41,9 +41,10 @@ import { takeAgentRequest } from "./settings-request.js";
|
|
|
41
41
|
import { setPreviewOptIn } from "./panel-chat.js";
|
|
42
42
|
import { startTour } from "./chat-tour.js";
|
|
43
43
|
import "./chat-strings.js";
|
|
44
|
+
import { AppearanceSection } from "./settings-appearance.js";
|
|
44
45
|
|
|
45
46
|
const tn = (k, ...v) => t(`settings.${k}`, ...v);
|
|
46
|
-
const ICONS = { device: "user", agents: "bot", bots: "plug", classic: "room", general: "sliders", web: "globe", advanced: "code" };
|
|
47
|
+
const ICONS = { device: "user", appearance: "palette", agents: "bot", bots: "plug", classic: "room", general: "sliders", web: "globe", advanced: "code" };
|
|
47
48
|
const RELEASES = "https://github.com/songsid/AgEnD/releases";
|
|
48
49
|
|
|
49
50
|
/** GET under the panel's lease → { ok, status, body }. */
|
|
@@ -224,6 +225,8 @@ export function SettingsPanel({ route, navKey }) {
|
|
|
224
225
|
}, [!!ctx, navKey]);
|
|
225
226
|
// #1604: This device needs no configuration: shown at once, whatever the configuration read does.
|
|
226
227
|
const sectionBody = section === "device" ? html`<${DeviceSection} />`
|
|
228
|
+
// #1629 r4 §3: Appearance is the person's own (no configuration read): shown at once, like Preferences.
|
|
229
|
+
: section === "appearance" ? html`<${AppearanceSection} />`
|
|
227
230
|
: !data ? html`<${Skeleton} lines=${6} />`
|
|
228
231
|
: data.error ? html`<${ErrorState} message=${tn("configLoadFailed")} onRetry=${reload} />`
|
|
229
232
|
: section === "agents" ? html`<${Agents} ctx=${ctx} search=${search} openDialog=${(d) => setDialog({ ...d, key: navKey })} />`
|
|
@@ -236,14 +239,14 @@ export function SettingsPanel({ route, navKey }) {
|
|
|
236
239
|
const open = dialog && dialog.key === navKey ? dialog : null;
|
|
237
240
|
const close = () => setDialog(null);
|
|
238
241
|
const searchable = section === "agents" || section === "bots" || section === "classic";
|
|
239
|
-
return html`<div class="panel p-settings">
|
|
242
|
+
return html`<div data-effect-panel="settings" class="panel p-settings">
|
|
240
243
|
<${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
244
|
<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
245
|
<button type="button" class="icon-btn" aria-label=${tn("helpButton")} title=${tn("helpButton")} onClick=${() => setDialog({ kind: "help", key: navKey })}><${Icon} name="info" /></button>
|
|
243
246
|
</${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" : ""}`}
|
|
247
|
+
<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
248
|
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">
|
|
249
|
+
<div data-trust="panel-content" class="panel-body"><div class="col">
|
|
247
250
|
${searchable ? html`<div class="s-toolbar"><label class="s-search"><${Icon} name="search" size=${14} /><span class="sr-only">${tn("searchAll")}</span>
|
|
248
251
|
<input type="search" value=${search} placeholder=${tn("searchAll")} onInput=${(e) => setSearch(e.target.value)} /></label></div>` : null}
|
|
249
252
|
${op ? html`<${OperationCard} op=${op} schema=${data && data.schema} />` : null}
|
|
@@ -270,7 +273,11 @@ export function DeviceSection() {
|
|
|
270
273
|
const replay = () => {
|
|
271
274
|
let last = null;
|
|
272
275
|
try { last = localStorage.getItem("agend_last_instance"); } catch { /* none */ }
|
|
273
|
-
|
|
276
|
+
// #1854: the tour is about an agent's chat — with no agent to open (none remembered, or it is gone), say so instead
|
|
277
|
+
// of opening an empty chat that waits ~3 s and shows nothing.
|
|
278
|
+
const { instances } = appStore.get();
|
|
279
|
+
if (!last || !(instances || []).some((i) => i && i.name === last)) { toast(t("chat.tourNoAgent"), false); return; }
|
|
280
|
+
navigate(chatPath(last));
|
|
274
281
|
// This replay belongs to the navigation it just made — that one, by its sequence number, not by URL (A → B → A, or
|
|
275
282
|
// the same path again, is a new navigation). It did not happen (a leave guard said no) or it is not the chat:
|
|
276
283
|
// nothing. Left meanwhile (another page, another navigation): nothing (#1609 review).
|
|
@@ -285,7 +292,7 @@ export function DeviceSection() {
|
|
|
285
292
|
let tries = 0;
|
|
286
293
|
const go = () => {
|
|
287
294
|
if (!current()) return;
|
|
288
|
-
if (!document.getElementById("sendBtn")) { if (++tries <= 30) setTimeout(go, 100); return; }
|
|
295
|
+
if (!document.getElementById("sendBtn")) { if (++tries <= 30) setTimeout(go, 100); else toast(t("chat.tourNoAgent"), false); return; }
|
|
289
296
|
const here = document.getElementById("msgIn") || document.getElementById("main");
|
|
290
297
|
if (here && typeof here.focus === "function") here.focus();
|
|
291
298
|
if (current()) startTour();
|
|
@@ -293,7 +300,8 @@ export function DeviceSection() {
|
|
|
293
300
|
setTimeout(go, 0);
|
|
294
301
|
};
|
|
295
302
|
const publicLink = typeof document !== "undefined" && document.body && document.body.dataset.publicLink === "1";
|
|
296
|
-
return html
|
|
303
|
+
return html`<${ProfileCard} />
|
|
304
|
+
<section class="card s-device s-synced"><h3>${tn("syncedTitle")}</h3>
|
|
297
305
|
<p class="sub">${publicLink ? tn("syncedPublicLink") : tn("syncedLead")}</p>
|
|
298
306
|
<${DevicePrefs} labels=${true} />
|
|
299
307
|
${P() ? html`<label class="check"><input type="checkbox" checked=${on} onChange=${(e) => { const want = e.target.checked; setPreviewOptIn(want).then(setOn); }} />
|
|
@@ -305,6 +313,52 @@ export function DeviceSection() {
|
|
|
305
313
|
</section>`;
|
|
306
314
|
}
|
|
307
315
|
|
|
316
|
+
/**
|
|
317
|
+
* #1827: who agents see when this person writes from the web. Signed in with a code sent to their Discord or Telegram
|
|
318
|
+
* account, they are that account — its user id, and its name unless they choose another (it follows them to every
|
|
319
|
+
* device, the public link included). Otherwise "web-user", as before. The host checks a name in full and says why it
|
|
320
|
+
* refuses one; this only shows what it says.
|
|
321
|
+
*/
|
|
322
|
+
const view = (b) => ({ phase: "ready", name: b.name || "", shown: b.shown || "", id: b.id || "", bound: b.bound === true, platform: b.platform_name || "", error: "" });
|
|
323
|
+
export function ProfileCard() {
|
|
324
|
+
const [state, setState] = useState({ phase: "loading", name: "", shown: "", id: "", bound: false, platform: "", error: "" });
|
|
325
|
+
const [draft, setDraft] = useState("");
|
|
326
|
+
const lease = useLease();
|
|
327
|
+
useEffect(() => {
|
|
328
|
+
let live = true;
|
|
329
|
+
api("/ui/profile").then((r) => {
|
|
330
|
+
if (!live) return;
|
|
331
|
+
if (!r.ok || !r.body) { setState((s) => ({ ...s, phase: "unavailable" })); return; }
|
|
332
|
+
setState(view(r.body));
|
|
333
|
+
setDraft(r.body.name || "");
|
|
334
|
+
}).catch(() => { if (live) setState((s) => ({ ...s, phase: "unavailable" })); });
|
|
335
|
+
return () => { live = false; };
|
|
336
|
+
}, []);
|
|
337
|
+
if (state.phase === "unavailable") return null;
|
|
338
|
+
const save = (clear) => {
|
|
339
|
+
setState((s) => ({ ...s, phase: "saving", error: "" }));
|
|
340
|
+
api("/ui/profile", { method: "POST", body: JSON.stringify({ name: clear ? null : draft }) }).then((r) => {
|
|
341
|
+
if (lease && !lease.current()) return;
|
|
342
|
+
if (!r.ok) { setState((s) => ({ ...s, phase: "ready", error: (r.body && r.body.error) || tn("profileFailed") })); return; }
|
|
343
|
+
setState(view(r.body));
|
|
344
|
+
setDraft(r.body.name || "");
|
|
345
|
+
toast(tn("profileSaved", r.body.shown || "web-user"));
|
|
346
|
+
}).catch(() => setState((s) => ({ ...s, phase: "ready", error: tn("profileFailed") })));
|
|
347
|
+
};
|
|
348
|
+
const busy = state.phase !== "ready";
|
|
349
|
+
const changed = draft.trim() !== state.name;
|
|
350
|
+
return html`<section class="card s-device s-profile"><h3>${tn("profileTitle")}</h3>
|
|
351
|
+
<p class="sub">${state.bound ? tn("profileLeadBound") : tn("profileLeadUnbound")}</p>
|
|
352
|
+
<div class="field"><label for="profile-name">${tn("profileName")}</label>
|
|
353
|
+
<input id="profile-name" type="text" maxlength="200" autocomplete="nickname" value=${draft} disabled=${busy}
|
|
354
|
+
placeholder=${state.platform || "web-user"} aria-invalid=${state.error ? "true" : "false"} aria-describedby="profile-help"
|
|
355
|
+
onInput=${(e) => setDraft(e.target.value)} onKeyDown=${(e) => { if (e.key === "Enter" && changed && draft.trim()) save(false); }} />
|
|
356
|
+
<p class="sub" id="profile-help">${state.error ? html`<span class="err" role="alert">${state.error}</span>` : tn("profileHelp", state.shown || "web-user", state.id)}</p></div>
|
|
357
|
+
<div class="s-device-row"><button type="button" class="btn primary" disabled=${busy || !changed || !draft.trim()} onClick=${() => save(false)}>${tn("profileSave")}</button>
|
|
358
|
+
${state.name ? html`<button type="button" class="btn" disabled=${busy} onClick=${() => save(true)}>${state.bound ? tn("profileUseAccount", state.platform || "web-user") : tn("profileClear")}</button>` : null}</div>
|
|
359
|
+
</section>`;
|
|
360
|
+
}
|
|
361
|
+
|
|
308
362
|
/** The operation in hand still owns Apply: its writes and job, or a restart of AgEnD from the press to its end. */
|
|
309
363
|
const opBusy = (op) => !!op && (["writing", "posting", "watching"].includes(op.phase) || op.restart === "busy");
|
|
310
364
|
function dropSecrets(staged) { for (const c of staged.values()) if (c.connectionSecret) c.connectionSecret.secret = ""; }
|
|
@@ -588,7 +642,7 @@ function General({ ctx }) {
|
|
|
588
642
|
backend: d.backend || "claude-code", model: d.model || "", locale: d.locale || "", auto: String(d.auto_pause_after ?? 0),
|
|
589
643
|
agent_mode: d.agent_mode || "mcp", tool_set: d.tool_set || "full", tool_progress: d.tool_progress ?? "off",
|
|
590
644
|
visibility: visibilityDefault(d), reply: d.reply_completion_guard ?? true, log_level: d.log_level || "info",
|
|
591
|
-
hangOn: hang.enabled !== false, hang: String(hang.timeout_minutes ??
|
|
645
|
+
hangOn: hang.enabled !== false, hang: String(hang.timeout_minutes ?? HANG_TIMEOUT_DEFAULT_MINUTES),
|
|
592
646
|
concurrency: String(startup.concurrency ?? 10), stagger: String(startup.stagger_delay_ms ?? 500),
|
|
593
647
|
classicBackend: c.backend || d.backend || "claude-code",
|
|
594
648
|
classicToolProgress: c.tool_progress ?? d.tool_progress ?? "off", classicToolProgressInherit: !hasOwn(c, "tool_progress"),
|
|
@@ -617,7 +671,7 @@ function General({ ctx }) {
|
|
|
617
671
|
backend: d.backend || "claude-code", model: d.model || undefined, locale: d.locale || null, auto_pause_after: d.auto_pause_after ?? 0,
|
|
618
672
|
agent_mode: d.agent_mode || "mcp", tool_set: d.tool_set || "full", tool_progress: d.tool_progress ?? "off",
|
|
619
673
|
cross_instance_visibility: visibilityDefault(d), reply_completion_guard: d.reply_completion_guard ?? true, log_level: d.log_level || "info",
|
|
620
|
-
hang_detector: { enabled: hang.enabled !== false, timeout_minutes: hang.timeout_minutes ??
|
|
674
|
+
hang_detector: { enabled: hang.enabled !== false, timeout_minutes: hang.timeout_minutes ?? HANG_TIMEOUT_DEFAULT_MINUTES },
|
|
621
675
|
startup: { concurrency: startup.concurrency ?? 10, stagger_delay_ms: startup.stagger_delay_ms ?? 500 },
|
|
622
676
|
});
|
|
623
677
|
const oc = original.c;
|
|
@@ -710,7 +764,7 @@ function General({ ctx }) {
|
|
|
710
764
|
*/
|
|
711
765
|
export const WEB_READ_ONLY = [
|
|
712
766
|
"web.allowed_hosts", "web.view_access", "web.notify_login", "web.preview", "web.preview_port", "web.preview_origin", "web.preview_on_public_link",
|
|
713
|
-
"web.usage_panel", "web.provider_secrets", "web_terminal.bind", "web_terminal.tunnel",
|
|
767
|
+
"web.usage_panel", "web.provider_secrets", "web.upload_max_file_mb", "web.upload_max_total_mb", "web_terminal.bind", "web_terminal.tunnel",
|
|
714
768
|
];
|
|
715
769
|
function WebSection({ ctx, staged }) {
|
|
716
770
|
const { schema } = ctx;
|
|
@@ -864,7 +918,7 @@ function Developer({ ctx }) {
|
|
|
864
918
|
/** Staged, not applied: the count, what it will cost, Discard and Apply. */
|
|
865
919
|
function PendingBar({ staged, busy, onApply, onDiscard }) {
|
|
866
920
|
const kinds = [...new Set([...staged.values()].map((c) => c.impact))];
|
|
867
|
-
return html`<div class="s-pending" role="region" aria-label=${tn("pendingRegion")}>
|
|
921
|
+
return html`<div data-trust="panel-controls" class="s-pending" role="region" aria-label=${tn("pendingRegion")}>
|
|
868
922
|
<strong>${tn("changesPending", staged.size)}</strong>
|
|
869
923
|
<span class="note">${kinds.map(impactText).join(" · ")}</span>
|
|
870
924
|
<span class="grow"></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>
|