@songsid/agend 2.3.0-beta.1 → 2.3.0-beta.11
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 +43 -7
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +4 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-file-read.d.ts +14 -6
- package/dist/agent-file-read.js +207 -19
- package/dist/agent-file-read.js.map +1 -1
- package/dist/agent-whats-new.d.ts +11 -0
- package/dist/agent-whats-new.js +29 -15
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/auth-api.d.ts +30 -1
- package/dist/auth-api.js +45 -13
- 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/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/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 +7 -0
- package/dist/channel/adapters/discord.js +35 -0
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/mcp-tools.js +22 -10
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/types.d.ts +6 -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 +103 -4
- package/dist/config-validator.js.map +1 -1
- package/dist/daemon.d.ts +7 -0
- package/dist/daemon.js +63 -16
- 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 +10 -0
- package/dist/fleet-manager.d.ts +417 -11
- package/dist/fleet-manager.js +1387 -109
- 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 +257 -23
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +478 -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-config-impact.js +3 -1
- package/dist/instance-config-impact.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/outbound-handlers.d.ts +10 -0
- package/dist/outbound-handlers.js +122 -2
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +164 -4
- package/dist/outbound-schemas.js +99 -3
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +8 -2
- 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/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 +12 -0
- package/dist/scheduler/scheduler.js +83 -10
- 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 +137 -2
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +104 -0
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.js +17 -1
- package/dist/settings-effect.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 +53 -5
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.d.ts +7 -1
- package/dist/topic-commands.js +18 -4
- package/dist/topic-commands.js.map +1 -1
- package/dist/types.d.ts +48 -1
- package/dist/ui/app-effects.js +77 -31
- package/dist/ui/chat-ambient.js +307 -0
- package/dist/ui/chat-effect-posters.js +8 -8
- package/dist/ui/chat-effects.js +101 -13
- package/dist/ui/chat-render.js +21 -3
- package/dist/ui/chat-strings.js +59 -6
- package/dist/ui/chat-thread.js +159 -21
- package/dist/ui/effect-trial-controller.js +13 -8
- package/dist/ui/effect-trial-panel.js +19 -16
- 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/panel-chat.js +154 -49
- package/dist/ui/panel-details.js +2 -1
- package/dist/ui/panel-fleet.js +43 -17
- package/dist/ui/panel-settings.js +26 -8
- package/dist/ui/preview.js +3 -2
- package/dist/ui/settings-appearance.js +42 -18
- package/dist/ui/settings-catalog.js +92 -0
- package/dist/ui/settings-dialogs.js +40 -12
- package/dist/ui/settings-effects.js +4 -3
- 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 +23 -9
- package/dist/ui/settings-owner-effects.js +9 -9
- package/dist/ui/settings-strings.js +120 -42
- package/dist/ui/settings-web-authority.js +91 -0
- package/dist/ui/shared/agend-auth.js +1 -1
- package/dist/ui/shared/app-i18n.js +4 -2
- package/dist/ui/shared/app-prefs.js +5 -4
- package/dist/ui/shared/app-route.js +19 -1
- package/dist/ui/shared/app-session.js +2 -0
- package/dist/ui/shared/app-shell.js +92 -27
- package/dist/ui/shared/app-store.js +26 -1
- package/dist/ui/shared/app-stream.js +3 -1
- package/dist/ui/shared/app-themes.js +24 -6
- package/dist/ui/shared/app.css +365 -17
- package/dist/ui/shared/app.js +21 -14
- package/dist/ui/shared/card-strings.js +4 -0
- package/dist/ui/shared/effect-app-runtime.js +68 -19
- package/dist/ui/shared/effect-chat-runtime.js +16 -3
- package/dist/ui/shared/effect-frame.js +26 -7
- package/dist/ui/shared/effect-geometry.js +24 -9
- package/dist/ui/shared/effect-policy.js +21 -7
- package/dist/ui/shared/effect-profiler.js +31 -9
- package/dist/ui/shared/effect-registry.js +87 -48
- package/dist/ui/shared/effect-stock-snapshot.js +9 -0
- package/dist/ui/shared/effect-stock-trust.js +62 -10
- package/dist/ui/shared/effect-trial-shadow.js +62 -0
- package/dist/ui/shared/effect-trial-source.js +1 -1
- package/dist/ui/shared/effect-trial-stage.js +54 -31
- package/dist/ui/shared/effect-trial.css +40 -0
- package/dist/ui/shared/fx-motion.js +67 -0
- package/dist/ui/shared/identity-card.js +75 -4
- package/dist/ui/shared/identity-color.js +3 -3
- package/dist/ui/shared/instance-nav.js +194 -28
- package/dist/ui/shared/panel-view.js +24 -4
- package/dist/ui/shared/tokens.css +9 -3
- package/dist/ui/shared/ui-icons.js +1 -0
- package/dist/ui/shared/usage-dialog.js +22 -2
- package/dist/ui/shared/view-strings.js +68 -2
- package/dist/ui/shared/web-authorize.js +151 -0
- package/dist/ui/signin.html +1 -1
- 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 +39 -0
- package/dist/view-api.js +65 -4
- 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 +69 -5
- package/dist/web-api.js +362 -45
- package/dist/web-api.js.map +1 -1
- package/dist/web-appearance-policy.d.ts +4 -6
- package/dist/web-appearance-policy.js +5 -12
- package/dist/web-appearance-policy.js.map +1 -1
- package/dist/web-appearance-tools.d.ts +3 -0
- package/dist/web-appearance-tools.js +22 -3
- package/dist/web-appearance-tools.js.map +1 -1
- package/dist/web-appearance-view.d.ts +27 -2
- package/dist/web-appearance-view.js +129 -14
- package/dist/web-appearance-view.js.map +1 -1
- package/dist/web-appearance.d.ts +17 -3
- package/dist/web-appearance.js +82 -7
- package/dist/web-appearance.js.map +1 -1
- package/dist/web-asset-parts.d.ts +5 -10
- package/dist/web-asset-parts.js +3 -3
- package/dist/web-asset-parts.js.map +1 -1
- package/dist/web-auth.js +3 -1
- package/dist/web-auth.js.map +1 -1
- package/dist/web-card.d.ts +14 -0
- package/dist/web-card.js +40 -6
- package/dist/web-card.js.map +1 -1
- 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 +50 -0
- package/dist/web-chat-history.js +87 -5
- 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.js +46 -1
- package/dist/web-effect-bundle.js.map +1 -1
- 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-profiles.d.ts +4 -4
- package/dist/web-effect-service.d.ts +11 -4
- package/dist/web-effect-service.js +28 -5
- package/dist/web-effect-service.js.map +1 -1
- package/dist/web-effect-tools.d.ts +1 -0
- package/dist/web-effect-tools.js +8 -5
- package/dist/web-effect-tools.js.map +1 -1
- package/dist/web-effect-trials.d.ts +4 -4
- package/dist/web-effect-trials.js +6 -6
- package/dist/web-effect-trials.js.map +1 -1
- package/dist/web-effect-upload.d.ts +2 -4
- package/dist/web-effect-upload.js +3 -8
- package/dist/web-effect-upload.js.map +1 -1
- package/dist/web-effect-worker.d.ts +1 -1
- package/dist/web-effect-worker.js +2 -2
- package/dist/web-effect-worker.js.map +1 -1
- package/dist/web-effect.d.ts +14 -0
- package/dist/web-effect.js +21 -0
- package/dist/web-effect.js.map +1 -1
- 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 +1 -1
- package/dist/web-identity-color.js +2 -2
- package/dist/web-identity-color.js.map +1 -1
- package/dist/web-identity-palette.d.ts +1 -1
- package/dist/web-identity-palette.js +2 -2
- package/dist/web-identity-palette.js.map +1 -1
- package/dist/web-image-meta.d.ts +13 -0
- package/dist/web-image-meta.js +62 -0
- package/dist/web-image-meta.js.map +1 -1
- 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 +1 -1
- package/dist/web-mod-agent.js +12 -8
- package/dist/web-mod-agent.js.map +1 -1
- package/dist/web-mod-bundle.d.ts +14 -1
- package/dist/web-mod-bundle.js +68 -3
- package/dist/web-mod-bundle.js.map +1 -1
- package/dist/web-mod-export.d.ts +9 -0
- package/dist/web-mod-export.js +21 -0
- package/dist/web-mod-export.js.map +1 -1
- package/dist/web-mod-store.d.ts +7 -1
- package/dist/web-mod-store.js +21 -7
- package/dist/web-mod-store.js.map +1 -1
- package/dist/web-prefs.d.ts +14 -0
- package/dist/web-prefs.js +24 -4
- package/dist/web-prefs.js.map +1 -1
- package/dist/web-preview.d.ts +6 -2
- package/dist/web-preview.js +4 -2
- 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 +49 -2
- package/dist/web-settings-patch.js +145 -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 +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 +39 -0
- package/dist/web-theme-store.js +122 -11
- package/dist/web-theme-store.js.map +1 -1
- package/dist/web-theme.d.ts +2 -0
- package/dist/web-theme.js +10 -1
- package/dist/web-theme.js.map +1 -1
- package/dist/web-upload.d.ts +13 -0
- package/dist/web-upload.js +39 -3
- package/dist/web-upload.js.map +1 -1
- package/dist/workflow-templates/default.md +1 -1
- package/package.json +1 -1
- package/templates/systemd.service.ejs +8 -0
package/dist/ui/chat-effects.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// #1629: Chat contributes a committed lease to the one app owner; no private pool or server polling.
|
|
2
|
-
import { html, useLayoutEffect, useRef, useState } from "/assets/app-html.js";
|
|
2
|
+
import { html, useEffect, useLayoutEffect, useRef, useState } from "/assets/app-html.js";
|
|
3
3
|
import { register, t } from "/assets/app-i18n.js";
|
|
4
4
|
import { appStore, useStore } from "/assets/app-store.js";
|
|
5
5
|
import { ownerCssLifecycle } from "/assets/owner-css.js";
|
|
@@ -7,18 +7,84 @@ import { chatEffectState, chatEffectIdentity } from "/assets/effect-chat-runtime
|
|
|
7
7
|
import { Dialog } from "/assets/ui-dialog.js";
|
|
8
8
|
import { navigate } from "/assets/app-nav.js";
|
|
9
9
|
import { toast } from "/assets/ui-toast.js";
|
|
10
|
+
import { setThemesShown, themesShown, themesStore } from "/assets/app-themes.js";
|
|
11
|
+
import { setFollowsReducedMotion } from "/assets/fx-motion.js";
|
|
10
12
|
import { getAppEffects } from "./app-effects.js";
|
|
11
13
|
|
|
12
14
|
register("chatFx", {
|
|
13
|
-
en: {
|
|
14
|
-
|
|
15
|
+
en: { stock: "Off: the page layout could not be verified ({0}). Reload and report this code if it persists.", transport: "Off: the isolated effect frame could not start. Reload to try again.", enableHere: "Turn effects on here", playMotion: "Play effects anyway", leaveSafe: "Leave safe mode", viewerShow: "Show themes, effects and widgets here", clock: "Off: the page timing clock is unavailable. Reload to try again.", gatesUnknown: "Off: the playback conditions could not be verified.", resource: "Off: this effect could not be loaded or verified. Reload to try again.", frontQueue: "Waiting for a foreground slot.", consent: "This page has older playback information. Reload to use the isolated effect player.", previewMissing: "Off: the isolated effect frame is unavailable. Reload to try again.", unsupported: "Off: this browser lacks required Canvas Worker or layout support.", calibration: "Starting the effect.", baseline: "This page has older playback information. Reload to try again.", safetyUnknown: "Stopped: this device's safety history could not be verified. Reload to check it.", rawReason: "Playback blocked: {0}", missingRow: "Playback state is unavailable (runtime_unavailable).", region: "Off: this effect does not declare the chat region.", blocked: "Placed effects are blocked for this viewer:", deviceSetting: "Open device preferences", webSetting: "Open Web settings", reloadHint: "Reload page",
|
|
16
|
+
title: "Effects", loading: "Checking effects…", empty: "No effects in this chat.", failed: "Effects stopped because their resources could not be verified. Reload the page to try again.", reload: "Reload page", pause: "Pause", resume: "Resume", remove: "Remove from chat", removeFailed: "Could not remove this effect. Reload the page to check its state.", css: "Agent foreground effects are paused while your custom CSS is on or cannot be verified.", setting: "Open Web appearance settings", running: "Running", starting: "Starting", off: "Stopped", resumeFailed: "This effect cannot resume: the page or its safety history is not ready. Reload the page or choose another effect.", queued: "Waiting for a slot", unknown: "Playback is off or unavailable here.", budget: "Paused to protect page responsiveness. Resume keeps the three-pauses safety limit.", pauseHelp: "Resume keeps this device’s automatic-pause history and three-pause safety limit.", paused: "Paused", low: "Reduced quality",
|
|
17
|
+
typing: "Waiting while you type — it plays when you leave the message box.", covered: "Waiting while a menu or panel covers the chat.",
|
|
18
|
+
dialogOpen: "Paused while this dialog is open.", wasRunning: "Was running; paused while this dialog is open.", modal: "Waiting while a dialog is open.",
|
|
19
|
+
off3: "Turned off on this device after three automatic pauses. Resume cannot restart it here.", interrupted: "Stopped: the page closed while it was playing. Resume to play it again.",
|
|
20
|
+
cssOff: "Off while your custom CSS is on.", reducedMotion: "Off: you chose to follow the system's reduced motion setting.", saveData: "This page has older playback information. Reload to try again.",
|
|
21
|
+
hiddenTab: "Waiting until this tab is visible.", offscreen: "Waiting until the chat is on screen.",
|
|
22
|
+
safeMode: "Off in safe mode.", publicLink: "Off on a public link.", disabled: "Effects are switched off." },
|
|
23
|
+
"zh-TW": { stock: "已關閉:無法驗證頁面版面({0})。請重新載入;若持續發生,請回報此代碼。", transport: "已關閉:無法啟動隔離效果框架。請重新載入再試。", enableHere: "在這裡開啟效果", playMotion: "仍然播放效果", leaveSafe: "離開安全模式", viewerShow: "在這裡顯示主題、效果與小工具", clock: "已關閉:頁面計時無法使用。請重新載入再試。", gatesUnknown: "已關閉:無法確認播放條件。", resource: "已關閉:無法載入或驗證此效果。請重新載入再試。", frontQueue: "等待前景空位。", consent: "這個頁面的播放資訊已過期。請重新載入以使用隔離效果播放器。", previewMissing: "已關閉:隔離效果框架無法使用。請重新載入再試。", unsupported: "已關閉:這個瀏覽器缺少 Canvas Worker 或版面驗證支援。", calibration: "正在啟動效果。", baseline: "這個頁面的播放資訊已過期,請重新載入再試。", safetyUnknown: "已停止:無法確認這台裝置的安全紀錄。請重新載入確認。", rawReason: "播放受阻:{0}", missingRow: "無法取得播放狀態(runtime_unavailable)。", region: "已關閉:此效果未宣告聊天區域。", blocked: "放置的效果目前無法在這個畫面播放:", deviceSetting: "開啟裝置偏好設定", webSetting: "開啟網頁設定", reloadHint: "重新載入頁面",
|
|
24
|
+
title: "效果", loading: "正在確認效果…", empty: "這個聊天沒有放置效果。", failed: "無法確認效果資源,已停止播放。重新載入頁面後再試。", reload: "重新載入頁面", pause: "暫停", resume: "恢復", remove: "從聊天移除", removeFailed: "無法移除效果。請重新載入頁面確認狀態。", css: "自訂 CSS 開啟或無法確認時,代理的前景效果會暫停。", setting: "開啟網頁外觀設定", running: "播放中", starting: "啟動中", off: "已停止", resumeFailed: "頁面或安全紀錄尚未就緒,無法恢復此效果。請重新載入頁面,或選擇其他效果。", queued: "等待空位", unknown: "這裡已關閉播放,或無法播放效果。", budget: "為維持頁面順暢,已暫停效果。恢復仍保留三次暫停的安全上限。", pauseHelp: "恢復仍保留這台裝置的自動暫停紀錄與三次暫停安全上限。", paused: "已暫停", low: "降低畫質",
|
|
25
|
+
typing: "輸入時暫停,離開訊息輸入框就會播放。", covered: "選單或面板蓋住聊天時暫停。",
|
|
26
|
+
dialogOpen: "開著這個對話框時暫停。", wasRunning: "原本在播放;開著這個對話框時暫停。", modal: "有對話框開著時暫停。",
|
|
27
|
+
off3: "已自動暫停三次,這台裝置已關閉此效果,無法在這裡恢復。", interrupted: "播放時頁面被關閉而停止。按「恢復」再播放一次。",
|
|
28
|
+
cssOff: "自訂 CSS 開啟時關閉。", reducedMotion: "已關閉:效果跟隨這台裝置的「減少動態效果」設定。", saveData: "這個頁面的播放資訊已過期,請重新載入再試。",
|
|
29
|
+
hiddenTab: "等這個分頁顯示時再播放。", offscreen: "等聊天顯示在畫面上時再播放。",
|
|
30
|
+
safeMode: "安全模式下關閉。", publicLink: "公開連結上關閉。", disabled: "效果已關閉。" },
|
|
15
31
|
});
|
|
16
32
|
|
|
17
|
-
/**
|
|
33
|
+
/** Read/admin dashboard sessions keep management controls; public/guest Chat playback has no owner identity. */
|
|
18
34
|
export function chatEffectsMenuAvailable() { return chatEffectIdentity(window) !== null; }
|
|
19
35
|
|
|
20
|
-
|
|
36
|
+
// #2055: what a row's state means, in words — never only "Stopped" when the runtime knows why.
|
|
37
|
+
const RECENT_MS = 5000;
|
|
38
|
+
const REASON_KEY = { __proto__: null, transport_unavailable: "chatFx.transport", owner_css: "chatFx.cssOff", reduced_motion: "chatFx.reducedMotion", save_data: "chatFx.saveData", preview_unavailable: "chatFx.previewMissing", preview_not_consented: "chatFx.consent", unsupported_host: "chatFx.unsupported", registry_unsupported: "chatFx.unsupported",
|
|
39
|
+
baseline_unsupported: "chatFx.baseline", baseline_unavailable: "chatFx.baseline", baseline_timeout: "chatFx.baseline", calibrating: "chatFx.calibration", safety_unknown: "chatFx.safetyUnknown", region_unavailable: "chatFx.region",
|
|
40
|
+
hidden: "chatFx.hiddenTab", offscreen: "chatFx.offscreen", safe_mode: "chatFx.safeMode", public_link: "chatFx.publicLink", disabled: "chatFx.disabled",
|
|
41
|
+
clock_unavailable: "chatFx.clock", gates_unknown: "chatFx.gatesUnknown", runtime_unavailable: "chatFx.missingRow", resource_unavailable: "chatFx.resource", resource_timeout: "chatFx.resource", front_limit: "chatFx.frontQueue",
|
|
42
|
+
safety_off: "chatFx.off3", interrupted: "chatFx.interrupted" };
|
|
43
|
+
/** `ownOpen`: this Effects dialog is open; `wasRunning`: the effect was running when it opened (shown as past, never as current). */
|
|
44
|
+
export function effectRowText(row, { ownOpen = false, wasRunning = false, doc = typeof document === "undefined" ? null : document } = {}) {
|
|
45
|
+
if (!row) return t("chatFx.missingRow");
|
|
46
|
+
if (typeof row.reason === "string" && row.reason !== "stock_overlay" && /^(stock_|trust_|geometry_)/.test(row.reason)) return t("chatFx.stock", row.reason.replace(/[\u0000-\u001f\u007f]/g, "").slice(0, 80));
|
|
47
|
+
// The sticky history first (it is what Resume answers), then a pause, then what is playing or queued.
|
|
48
|
+
if (row.reason === "safety_off" || row.reason === "interrupted") return t(REASON_KEY[row.reason]);
|
|
49
|
+
if (row.reason === "paused" || row.reason === "host_budget") return t("chatFx.paused");
|
|
50
|
+
if (REASON_KEY[row.reason]) return t(REASON_KEY[row.reason]);
|
|
51
|
+
if (row.reason != null && !["stock_overlay", "modal", "frame_limit"].includes(row.reason))
|
|
52
|
+
return t("chatFx.rawReason", typeof row.reason === "string" ? row.reason.replace(/[\u0000-\u001f\u007f]/g, "").slice(0, 80) : "invalid_reason_type");
|
|
53
|
+
if (row.phase === "running") return t("chatFx.running");
|
|
54
|
+
if (row.phase) return t("chatFx.starting");
|
|
55
|
+
if (row.verdict === "queued") return t("chatFx.queued");
|
|
56
|
+
if (row.reason === "stock_overlay" || row.reason === "modal") {
|
|
57
|
+
if (ownOpen) return t(wasRunning ? "chatFx.wasRunning" : "chatFx.dialogOpen");
|
|
58
|
+
if (row.reason === "modal") return t("chatFx.modal");
|
|
59
|
+
return t("chatFx.covered");
|
|
60
|
+
}
|
|
61
|
+
return t("chatFx.rawReason", typeof row.reason === "string" ? row.reason.replace(/[\u0000-\u001f\u007f]/g, "").slice(0, 80) : "invalid_reason_type");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Fixed local actions: no server/Worker-provided destination or raw reason in a URL. */
|
|
65
|
+
export function effectReasonAction(reason) {
|
|
66
|
+
if (reason === "preview_not_consented" || reason === "preview_unavailable") return { reload: true, label: "chatFx.reloadHint" };
|
|
67
|
+
if (["disabled", "owner_css"].includes(reason)) return { href: "/settings/appearance", label: "chatFx.setting" };
|
|
68
|
+
if (["transport_unavailable", "baseline_unsupported", "baseline_unavailable", "baseline_timeout", "runtime_unavailable", "resource_unavailable", "resource_timeout", "clock_unavailable", "safety_unknown"].includes(reason)) return { reload: true, label: "chatFx.reloadHint" };
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const localViewer = () => document.body.dataset.publicLink === "1" || document.body.dataset.tier === "guest";
|
|
72
|
+
function ReasonAction({ reason, onClose = () => {} }) {
|
|
73
|
+
if (reason === "safe_mode") return html`<button type="button" class="btn" onClick=${() => { onClose(); const url = new URL(location.href); url.searchParams.delete("safe"); location.assign(url.href); }}>${t("chatFx.leaveSafe")}</button>`;
|
|
74
|
+
if (reason === "reduced_motion") return html`<button type="button" class="btn" onClick=${() => { onClose(); setFollowsReducedMotion(false); }}>${t("chatFx.playMotion")}</button>`;
|
|
75
|
+
if (reason === "disabled" && localViewer()) return html`<button type="button" class="btn" onClick=${() => { onClose(); setThemesShown(true); }}>${t("chatFx.enableHere")}</button>`;
|
|
76
|
+
const action = document.body.dataset.tier === "guest" && reason === "owner_css" ? { reload: true, label: "chatFx.reloadHint" } : effectReasonAction(reason);
|
|
77
|
+
return action ? html`<button type="button" class="btn" onClick=${() => { onClose(); if (action.reload) location.reload(); else navigate(action.href); }}>${t(action.label)}</button>` : null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const NO_PLAYBACK = () => {};
|
|
81
|
+
export function ChatEffects({ name, lease, element, store, open, onClose, onPlayback = NO_PLAYBACK }) {
|
|
21
82
|
const cssLife = useStore(ownerCssLifecycle);
|
|
83
|
+
useStore(themesStore); // Viewer-local off/on is visible immediately, independent of runtime callbacks.
|
|
84
|
+
// Which effects were running just before this dialog opened ("was running" is said in the past, never shown as
|
|
85
|
+
// current). The ⋯ menu that opens it is a barrier too, so "just before" is within RECENT_MS of the observed stop.
|
|
86
|
+
// Tracked where updates arrive (an unchanged snapshot is not republished while an effect keeps running).
|
|
87
|
+
const before = useRef(null), wasOpen = useRef(false), playing = useRef(new Map());
|
|
22
88
|
const runtime = useRef(null), [state, setState] = useState(null), [canWrite, setCanWrite] = useState(false), [busy, setBusy] = useState(false);
|
|
23
89
|
useLayoutEffect(() => {
|
|
24
90
|
let live = true, api = null;
|
|
@@ -36,18 +102,29 @@ export function ChatEffects({ name, lease, element, store, open, onClose }) {
|
|
|
36
102
|
setBusy(false); onClose(); setCanWrite(false); setState(null);
|
|
37
103
|
const host = window, owner = getAppEffects(host);
|
|
38
104
|
const current = () => live && lease.current();
|
|
39
|
-
if (!owner) { setState({ error: null, rows: [], effects: [], unavailable: true }); return cleanup; }
|
|
105
|
+
if (!owner) { setState({ error: null, rows: [], effects: [], unavailable: true, reason: typeof host.OffscreenCanvas !== "function" || typeof host.Worker !== "function" ? "unsupported_host" : "runtime_unavailable" }); return cleanup; }
|
|
40
106
|
releases.push(owner.onEnd(() => { if (current()) setState({ error: "resource_unavailable", rows: [], effects: [], unavailable: true }); }));
|
|
107
|
+
playing.current = new Map(); // evidence belongs to this name and lease only
|
|
108
|
+
const track = rows => {
|
|
109
|
+
const now = performance.now(), seen = new Set();
|
|
110
|
+
for (const r of Array.isArray(rows) ? rows : []) {
|
|
111
|
+
seen.add(r.id);
|
|
112
|
+
if (r.phase === "running") playing.current.set(r.id, null);
|
|
113
|
+
else if (playing.current.get(r.id) === null) playing.current.set(r.id, now);
|
|
114
|
+
}
|
|
115
|
+
for (const [id, at] of playing.current) if (!seen.has(id) && at === null) playing.current.set(id, now);
|
|
116
|
+
};
|
|
41
117
|
const changed = value => {
|
|
42
118
|
if (!current()) return;
|
|
119
|
+
track(value?.rows);
|
|
43
120
|
const g = owner.gates();
|
|
44
|
-
setState({ ...value, unavailable: !g.enabled || !g.show || !g.
|
|
121
|
+
setState({ ...value, unavailable: !g.enabled || !g.show || !g.transportReady || g.safe || g.reducedMotion });
|
|
45
122
|
};
|
|
46
123
|
api = owner.attachChat({ name, element: element.current, current,
|
|
47
124
|
observe: () => ({ state: chatEffectState(appStore.get(), name) }), onChange: changed });
|
|
48
125
|
runtime.current = api;
|
|
49
|
-
if (!api?.ok) { setState({ error: null, rows: [], effects: [], unavailable: true }); return cleanup; }
|
|
50
|
-
host.AgendAuth?.canWrite?.().then(value => { if (current()) setCanWrite(value === true); }).catch(() => {});
|
|
126
|
+
if (!api?.ok) { setState({ error: null, rows: [], effects: [], unavailable: true, reason: "runtime_unavailable" }); return cleanup; }
|
|
127
|
+
if (chatEffectIdentity(host)) host.AgendAuth?.canWrite?.().then(value => { if (current()) setCanWrite(value === true); }).catch(() => {});
|
|
51
128
|
api.sync();
|
|
52
129
|
return cleanup;
|
|
53
130
|
} catch {
|
|
@@ -57,16 +134,27 @@ export function ChatEffects({ name, lease, element, store, open, onClose }) {
|
|
|
57
134
|
}
|
|
58
135
|
}, [name, lease]);
|
|
59
136
|
const rows = state?.rows ?? [], effects = state?.effects ?? [];
|
|
137
|
+
if (open && !wasOpen.current) {
|
|
138
|
+
const now = performance.now();
|
|
139
|
+
before.current = new Map([...playing.current].map(([id, stoppedAt]) => [id, stoppedAt === null || now - stoppedAt < RECENT_MS]));
|
|
140
|
+
}
|
|
141
|
+
if (!open) before.current = null;
|
|
142
|
+
wasOpen.current = open;
|
|
60
143
|
const css = cssLife.state !== "off" && effects.some(p => p.by !== "human" && p.manifest.layer === "front");
|
|
61
144
|
const remove = async id => { if (busy) return; setBusy(true); const api = runtime.current; const ok = await api?.remove?.(id); if (!lease.current() || runtime.current !== api) return; setBusy(false); if (!ok) toast(t("chatFx.removeFailed"), false); };
|
|
62
|
-
|
|
145
|
+
const playingNow = !state?.unavailable && !state?.error && rows.some(row => row.phase === "running" && row.reason == null);
|
|
146
|
+
useEffect(() => { onPlayback({ name, playing: playingNow }); return () => onPlayback({ name, playing: false }); }, [name, playingNow, onPlayback]);
|
|
147
|
+
const blocked = effects.flatMap(p => { const row = rows.find(r => r.id === p.id); return row?.phase === "running" && row.reason == null ? [] : [{ p, row }]; });
|
|
148
|
+
return html`${!open && localViewer() && effects.length ? html`<div class="chat-fx-notice"><label><input type="checkbox" checked=${themesShown()} onChange=${e => setThemesShown(e.currentTarget.checked)} /> ${t("chatFx.viewerShow")}</label></div>` : null}${!open && state?.error && !effects.length ? html`<div class="chat-fx-notice" role="status">${effectRowText({ reason: state.error })} <${ReasonAction} reason=${state.error} /></div>` : null}${!open && state?.reason ? html`<div class="chat-fx-notice" role="status">${effectRowText({ reason: state.reason })} <${ReasonAction} reason=${state.reason} /></div>` : null}${!open && blocked.length ? html`<div class="chat-fx-notice" role="status"><strong>${t("chatFx.blocked")}</strong>
|
|
149
|
+
${blocked.map(({ p, row }) => html`<span key=${p.id}>${p.manifest.title}: ${effectRowText(row)} ${["paused", "host_budget"].includes(row?.reason) ? html`<small>${t(row.reason === "host_budget" ? "chatFx.budget" : "chatFx.pauseHelp")}</small>` : null} <${ReasonAction} reason=${row?.reason} /></span>`)}</div>` : null}${open ? html`<${Dialog} title=${t("chatFx.title")} onClose=${onClose} busy=${busy}>
|
|
63
150
|
${state?.error ? html`<p>${t("chatFx.failed")}</p><button type="button" class="btn" onClick=${() => location.reload()}>${t("chatFx.reload")}</button>` : null}
|
|
64
151
|
${css ? html`<p>${t("chatFx.css")}</p><button type="button" class="btn" onClick=${() => { onClose(); navigate("/settings/appearance"); }}>${t("chatFx.setting")}</button>` : null}
|
|
65
152
|
${!effects.length && !state?.error ? html`<p>${t(state?.unavailable ? "chatFx.unknown" : state?.loading || !state ? "chatFx.loading" : "chatFx.empty")}</p>` : null}
|
|
66
|
-
${effects.map(p => { const row = rows.find(r => r.id === p.id)
|
|
67
|
-
|
|
153
|
+
${effects.map(p => { const row = rows.find(r => r.id === p.id); return html`<section key=${p.id}><h3>${p.manifest.title}</h3><p>${effectRowText(row, { ownOpen: open, wasRunning: before.current?.get(p.id) === true })}${row?.quality === "low" ? ` · ${t("chatFx.low")}` : ""}</p>
|
|
154
|
+
<${ReasonAction} reason=${row?.reason} onClose=${onClose} />
|
|
155
|
+
${["paused", "host_budget"].includes(row?.reason) ? html`<p>${t(row.reason === "host_budget" ? "chatFx.budget" : "chatFx.pauseHelp")}</p>` : null}
|
|
68
156
|
<button type="button" class="btn" disabled=${busy} onClick=${() => runtime.current?.pause?.(p.id)}>${t("chatFx.pause")}</button>
|
|
69
|
-
<button type="button" class="btn" disabled=${busy} onClick=${() => { if (!runtime.current?.resume?.(p.id)) toast(t("chatFx.resumeFailed"), false); }}>${t("chatFx.resume")}</button>
|
|
157
|
+
<button type="button" class="btn" disabled=${busy} onClick=${() => { if (!runtime.current?.resume?.(p.id)) toast(t(rows.find(r => r.id === p.id)?.reason === "safety_off" ? "chatFx.off3" : "chatFx.resumeFailed"), false); }}>${t("chatFx.resume")}</button>
|
|
70
158
|
${canWrite ? html`<button type="button" class="btn" disabled=${busy} onClick=${() => remove(p.id)}>${t("chatFx.remove")}</button>` : null}</section>`; })}
|
|
71
159
|
</${Dialog}>` : null}`;
|
|
72
160
|
}
|
package/dist/ui/chat-render.js
CHANGED
|
@@ -53,11 +53,14 @@
|
|
|
53
53
|
|
|
54
54
|
// #1630: a Discord server emoji, `<:name:id>` / `<a:name:id>` — escaped by now — drawn as its picture. Only an id the
|
|
55
55
|
// page knows (the fleet's servers: /ui/emojis) and only from the dashboard's own route; the src is built from the
|
|
56
|
-
// matched digits, the name (word characters only) goes into alt/title.
|
|
56
|
+
// matched digits, the name (word characters only) goes into alt/title. Any other — an id the page does not know, or
|
|
57
|
+
// before the list has come — reads `:name:` (never the raw markup); so does a picture that does not load
|
|
58
|
+
// (chat-thread.js swaps it: an <img> sized to an emoji showed an empty box, the user's "tofu").
|
|
57
59
|
var EMOJI_RE = /<(a?):([A-Za-z0-9_]{2,32}):(\d{15,25})>/g;
|
|
58
60
|
function emojiImg(id, name) {
|
|
59
61
|
return '<img class="emoji" src="/ui/img/emoji/' + id + '" alt=":' + name + ':" title=":' + name + ':" decoding="async">';
|
|
60
62
|
}
|
|
63
|
+
function emojiText(name) { return '<span class="emoji-text" title=":' + name + ':">:' + name + ':</span>'; }
|
|
61
64
|
|
|
62
65
|
// #1682: Discord mentions — `<@id>` / `<@!id>` (a user), `<@&id>` (a role), `<#id>` (a channel) — escaped by now (the
|
|
63
66
|
// role's & too), drawn as a pill: the name the page knows (store.mentions(kind, id), inserted escaped), else @user /
|
|
@@ -82,7 +85,7 @@
|
|
|
82
85
|
// path held its whole column wide.
|
|
83
86
|
s = s.replace(/`([^`\n]+)`/g, function (_m, code) { return stash(store, "<code>" + (store.inCell ? code.replace(/\//g, "/<wbr>") : code) + "</code>"); });
|
|
84
87
|
var known = store.emojis;
|
|
85
|
-
|
|
88
|
+
s = s.replace(EMOJI_RE, function (_m, _a, name, id) { return stash(store, known && known(id) ? emojiImg(id, name) : emojiText(name)); });
|
|
86
89
|
var names = store.mentions;
|
|
87
90
|
s = s.replace(MENTION_RE, function (_m, sigil, id) {
|
|
88
91
|
var kind = MENTION_KIND[sigil];
|
|
@@ -577,6 +580,21 @@
|
|
|
577
580
|
* With { htmlCards: true } (a server-marked agent reply, as for renderMarkdown) each .html/.htm file also gets an
|
|
578
581
|
* empty card placeholder <div class="html-card" data-att="<id>"> after the list — the id is 32 hex, nothing else.
|
|
579
582
|
*/
|
|
583
|
+
// The box a photo is drawn in (app.css: .msg .att-img img, max 260 × 220): its own size, scaled down to fit.
|
|
584
|
+
var PHOTO_MAX_W = 260, PHOTO_MAX_H = 220;
|
|
585
|
+
/**
|
|
586
|
+
* #2184: a photo's drawn size as width/height attributes, from the size the server read from its headers: the box is there
|
|
587
|
+
* before the picture loads, so the text around it never moves when it does (a chat opened cold jittered, as each
|
|
588
|
+
* photo grew from nothing). Nothing when the size is not known (drawn as before).
|
|
589
|
+
*/
|
|
590
|
+
function photoBox(a) {
|
|
591
|
+
var w = a.width, h = a.height;
|
|
592
|
+
var ok = function (v) { return typeof v === "number" && v >= 1 && v <= 65535 && Math.floor(v) === v; };
|
|
593
|
+
if (!ok(w) || !ok(h)) return "";
|
|
594
|
+
var k = Math.min(1, PHOTO_MAX_W / w, PHOTO_MAX_H / h);
|
|
595
|
+
return ' width="' + Math.max(1, Math.round(w * k)) + '" height="' + Math.max(1, Math.round(h * k)) + '"';
|
|
596
|
+
}
|
|
597
|
+
|
|
580
598
|
function attachmentsHtml(attachments, opts) {
|
|
581
599
|
if (!Array.isArray(attachments)) return "";
|
|
582
600
|
var cards = !!(opts && opts.htmlCards);
|
|
@@ -599,7 +617,7 @@
|
|
|
599
617
|
else if (kind) after.push('<div class="text-card" data-att="' + a.id + '" data-type="' + kind + '"></div>');
|
|
600
618
|
var name = escapeHtml(a.name || "file");
|
|
601
619
|
if (a.kind === "photo") {
|
|
602
|
-
out.push('<a class="att-img" href="' + url + '" target="_blank" rel="noopener noreferrer"><img src="' + url + '" alt="' + name + '" loading="lazy"></a>');
|
|
620
|
+
out.push('<a class="att-img" href="' + url + '" target="_blank" rel="noopener noreferrer"><img src="' + url + '" alt="' + name + '"' + photoBox(a) + ' loading="lazy"></a>');
|
|
603
621
|
} else {
|
|
604
622
|
out.push('<a class="att-file" href="' + url + '" download="' + name + '">📎 ' + name + ' <span class="att-size">' + escapeHtml(formatSize(a.size)) + "</span></a>");
|
|
605
623
|
}
|
package/dist/ui/chat-strings.js
CHANGED
|
@@ -3,8 +3,25 @@ import { register } from "/assets/app-i18n.js";
|
|
|
3
3
|
|
|
4
4
|
register("chat", {
|
|
5
5
|
en: {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
effectTrialReason_checking: "Checking this session…",
|
|
7
|
+
effectTrialReason_localAdmin: "Sign in as an admin outside the public link to Try.",
|
|
8
|
+
effectTrialReason_chatChanged: "Open the chat that offered this trial.",
|
|
9
|
+
effectTrialReason_busy: "Stop the current trial before starting another.",
|
|
10
|
+
effectTrialReason_safe: "Turn off safe mode to Try.",
|
|
11
|
+
effectTrialReason_effectsOff: "Turn on effects to Try.",
|
|
12
|
+
effectTrialReason_reducedMotion: "Effects follow this device’s reduced-motion setting.",
|
|
13
|
+
effectTrialReason_saveData: "Your device requests reduced data use.",
|
|
14
|
+
effectTrialReason_transport: "The isolated effect player is unavailable. Reload this page.",
|
|
15
|
+
effectTrialReason_unsupported: "Canvas Worker playback is unavailable in this browser.",
|
|
16
|
+
effectTrialReason_inactive: "Return to this page to Try.",
|
|
17
|
+
effectTrialReason_dialog: "Close the other menu or dialog to Try.",
|
|
18
|
+
effectTrialReason_expired: "This trial offer has expired.",
|
|
19
|
+
effectTrialSignIn: "Sign in here",
|
|
20
|
+
effectTrialStopOther: "Stop current trial",
|
|
21
|
+
effectTrialSettings: "Open playback settings",
|
|
22
|
+
effectTrialPlayMotion: "Play effects anyway",
|
|
23
|
+
effectTrial: "Effect trial", effectTrialLocal: "A sample on this page. Nothing is applied or saved.",
|
|
24
|
+
effectTrialStopped: "Try stopped", effectTrialStart: "Try", effectTrialExpired: "This trial offer has expired.", effectTrialUnavailable: "This trial is no longer available.",
|
|
8
25
|
cmdConfirm: "Clear", cmdConfirmBackend: "Switch and restart", cmdRunning: "Running /{0}…", cmdNotCommand: "Not a command here — Enter sends it as a message.", cmdDismiss: "Dismiss", cmdCommands: "Commands",
|
|
9
26
|
compactRunning: "Compacting…", compactDone: "✅ Conversation compacted", compactUnknown: "This backend does not report when compaction ends.",
|
|
10
27
|
compactTimeout: "No sign that compaction finished within {0} minutes — check the agent's own chat.",
|
|
@@ -25,7 +42,8 @@ register("chat", {
|
|
|
25
42
|
a11yWorking: "{0} started working", a11yIdle: "{0} finished", a11yReplied: "{0} replied", conversationWith: "Conversation with {0}",
|
|
26
43
|
stopping: "Stopping {0}…", awaiting: "{0} is waiting for your input", approxNote: "Read from the terminal, so approximate", elapsedTitle: "Time since this page saw it start (approximate)",
|
|
27
44
|
dropHere: "Drop files to attach them", asText: "As text", pasteAttached: "A long paste ({0} characters) was attached as a text file", pasteKeptAsText: "No room for another attachment: the long paste stays as text",
|
|
28
|
-
send: "Send", composerPlaceholder: "Message {0}…", composerHint: "Enter to send · Shift+Enter for a new line", composerMore: "/ for commands · Esc stops the reply",
|
|
45
|
+
send: "Send", composerPlaceholder: "Message {0}…", composerHint: "Enter to send · Shift+Enter for a new line", composerMore: "/ for commands · Esc stops the reply", guestMore: "Esc stops the reply",
|
|
46
|
+
guestNote: "You're a guest: the agent sees your messages as a guest's (recognition only).", guestNoCommands: "Guests can't run commands — send it without the leading /.", attachTitle: "Attach files (any type — or paste / drop them)",
|
|
29
47
|
pvPreview: "Preview", pvStop: "Stop", pvDownload: "Download", pvMenu: "Preview options", pvHtml: "HTML",
|
|
30
48
|
pvAllowButton: "Allow previews", pvAllow: "Allow HTML previews — they may be able to send data out", pvDisallow: "Stop allowing HTML previews",
|
|
31
49
|
pvConfirm: "Allow HTML previews?\n\nThis applies on every device where you are signed in. A preview runs the agent's HTML in an isolated frame. It cannot use your login, but it may be able to send data out, and it can slow or freeze this tab. You still click Preview each time.",
|
|
@@ -71,6 +89,8 @@ register("chat", {
|
|
|
71
89
|
"pvFail_bad-address": "Cloudflare gave an address that could not be used",
|
|
72
90
|
pvFail_unknown: "an unexpected error",
|
|
73
91
|
pvServer_notOffered: "Previews are not available on this page.",
|
|
92
|
+
pvServer_listenFailed: "Previews are unavailable: the fleet could not open its preview port ({0}). Another program may be using it — set web.preview_port, then restart AgEnD.",
|
|
93
|
+
pvServer_notListening: "Previews are not available on this fleet right now.",
|
|
74
94
|
previews: "Allow HTML previews",
|
|
75
95
|
clicked: "Clicked:", clickShow: "Show the message these buttons were on",
|
|
76
96
|
copy: "Copy", copyMessage: "Copy this reply", copied: "Copied", copyFailed: "Copy failed", wrap: "Wrap", showAll: "Show all {0} lines", showMore: "Show more", showLess: "Show less", jumpLatest: "Latest", newBelow: "{0} new",
|
|
@@ -98,11 +118,35 @@ register("chat", {
|
|
|
98
118
|
themeResetDone: "{0}'s theme was reset.", themeLocked: "{0}'s theme is locked: the agent can't change it.", themeUnlocked: "{0}'s theme is unlocked.",
|
|
99
119
|
themeFailed: "The theme was not changed ({0}).",
|
|
100
120
|
widgetRemoveHeader: "Remove the chat header widget", widgetRemoveDetails: "Remove the Details widget", widgetRemoved: "{0}'s widget was removed.",
|
|
121
|
+
// #2117: an agent's ambient effect — why it is not showing here, and a person's Clear.
|
|
122
|
+
ambientBlocked_hidden: "Ambient effect hidden: agents' themes are off — turn them on",
|
|
123
|
+
ambientBlocked_safe: "Ambient effect hidden: safe mode (?safe=1) — leave safe mode",
|
|
124
|
+
ambientBlocked_reducedMotion: "Ambient effect hidden: this device follows reduced motion — play effects anyway",
|
|
125
|
+
ambientBlocked_unsupported: "Ambient effect hidden: this browser can't animate it",
|
|
126
|
+
ambientClearLoop: "Clear the ambient effect", ambientClearClick: "Clear the click effect", ambientCleared: "{0}'s ambient effect was cleared.",
|
|
127
|
+
ambientMotionNote: "Your system asks for reduced motion; effects are on.", ambientMotionNoteLink: "Turn off here", ambientMotionNoteClose: "Close",
|
|
101
128
|
configured: "(configured)", fleetDefault: "(fleet default)",
|
|
102
129
|
},
|
|
103
130
|
"zh-TW": {
|
|
104
|
-
|
|
105
|
-
|
|
131
|
+
effectTrialReason_checking: "正在確認工作階段…",
|
|
132
|
+
effectTrialReason_localAdmin: "請在公開連結以外的儀表板以管理員登入後試播。",
|
|
133
|
+
effectTrialReason_chatChanged: "請開啟發出試播邀請的聊天。",
|
|
134
|
+
effectTrialReason_busy: "請先停止目前的試播。",
|
|
135
|
+
effectTrialReason_safe: "請先關閉安全模式。",
|
|
136
|
+
effectTrialReason_effectsOff: "請先開啟效果。",
|
|
137
|
+
effectTrialReason_reducedMotion: "效果跟隨這台裝置的「減少動態效果」設定。",
|
|
138
|
+
effectTrialReason_saveData: "裝置目前要求節省數據。",
|
|
139
|
+
effectTrialReason_transport: "隔離效果播放器目前無法使用。請重新載入頁面。",
|
|
140
|
+
effectTrialReason_unsupported: "此瀏覽器無法播放 Canvas Worker 效果。",
|
|
141
|
+
effectTrialReason_inactive: "請回到本頁後試播。",
|
|
142
|
+
effectTrialReason_dialog: "請先關閉其他選單或對話框。",
|
|
143
|
+
effectTrialReason_expired: "試播邀請已過期。",
|
|
144
|
+
effectTrialSignIn: "在此登入",
|
|
145
|
+
effectTrialStopOther: "停止目前試播",
|
|
146
|
+
effectTrialSettings: "開啟播放設定",
|
|
147
|
+
effectTrialPlayMotion: "仍然播放效果",
|
|
148
|
+
effectTrial: "效果試播", effectTrialLocal: "僅在本頁試播,不會套用或儲存。",
|
|
149
|
+
effectTrialStopped: "試播已停止", effectTrialStart: "試播", effectTrialExpired: "試播邀請已過期。", effectTrialUnavailable: "此試播已無法使用。",
|
|
106
150
|
cmdConfirm: "清空", cmdConfirmBackend: "切換並重新啟動", cmdRunning: "執行 /{0} 中…", cmdNotCommand: "這裡沒有這個指令——按 Enter 會當成一般訊息送出。", cmdDismiss: "關閉", cmdCommands: "指令",
|
|
107
151
|
compactRunning: "壓縮中…", compactDone: "✅ 對話已壓縮", compactUnknown: "這個後端不會回報壓縮何時完成。",
|
|
108
152
|
compactTimeout: "{0} 分鐘內沒有看到壓縮完成的紀錄,請到代理自己的對話確認。",
|
|
@@ -123,7 +167,8 @@ register("chat", {
|
|
|
123
167
|
a11yWorking: "{0} 開始工作", a11yIdle: "{0} 已完成", a11yReplied: "{0} 已回覆", conversationWith: "與 {0} 的對話",
|
|
124
168
|
stopping: "正在中止 {0}…", awaiting: "{0} 正在等你回應", approxNote: "從終端畫面判讀,僅供參考", elapsedTitle: "從這個頁面看到它開始工作起算(約略)",
|
|
125
169
|
dropHere: "放開即可附加檔案", asText: "改為文字", pasteAttached: "貼上的長文字({0} 個字元)已改為文字檔附加", pasteKeptAsText: "附件已滿,貼上的長文字保留為一般文字",
|
|
126
|
-
send: "送出", composerPlaceholder: "傳訊息給 {0}…", composerHint: "Enter 送出 · Shift+Enter 換行", composerMore: "/ 叫出指令 · Esc 中止回覆",
|
|
170
|
+
send: "送出", composerPlaceholder: "傳訊息給 {0}…", composerHint: "Enter 送出 · Shift+Enter 換行", composerMore: "/ 叫出指令 · Esc 中止回覆", guestMore: "Esc 中止回覆",
|
|
171
|
+
guestNote: "你是訪客:agent 會把你的訊息視為訪客的訊息(僅供辨識)。", guestNoCommands: "訪客不能執行指令,請去掉開頭的 / 再送出。", attachTitle: "附加檔案(任何類型,也可以貼上或拖曳)",
|
|
127
172
|
pvPreview: "預覽", pvStop: "停止", pvDownload: "下載", pvMenu: "預覽選項", pvHtml: "HTML",
|
|
128
173
|
pvAllowButton: "允許預覽", pvAllow: "允許預覽 HTML(預覽可能把資料傳出去)", pvDisallow: "不再允許預覽 HTML",
|
|
129
174
|
pvConfirm: "要允許預覽 HTML 嗎?\n\n這會套用到你登入的每一台裝置。預覽會在隔離的框架裡執行 agent 的 HTML。它無法使用你的登入,但可能把資料傳出去,也可能讓這個分頁變慢或卡住。每次仍需要你按「預覽」。",
|
|
@@ -168,6 +213,8 @@ register("chat", {
|
|
|
168
213
|
"pvFail_bad-address": "Cloudflare 給出的網址無法使用",
|
|
169
214
|
pvFail_unknown: "發生了未預期的錯誤",
|
|
170
215
|
pvServer_notOffered: "這個頁面不提供預覽。",
|
|
216
|
+
pvServer_listenFailed: "無法預覽:fleet 無法開啟預覽用的連接埠({0})。可能有其他程式正在使用它——請設定 web.preview_port,然後重新啟動 AgEnD。",
|
|
217
|
+
pvServer_notListening: "這個 fleet 目前無法預覽。",
|
|
171
218
|
previews: "允許預覽 HTML",
|
|
172
219
|
clicked: "點選了:", clickShow: "顯示這些按鈕所在的訊息",
|
|
173
220
|
copy: "複製", copyMessage: "複製這則回覆", copied: "已複製", copyFailed: "複製失敗", wrap: "換行", showAll: "展開全部 {0} 行", showMore: "顯示更多", showLess: "收合", jumpLatest: "最新", newBelow: "{0} 則新訊息",
|
|
@@ -193,6 +240,12 @@ register("chat", {
|
|
|
193
240
|
themeResetDone: "已重設 {0} 的主題。", themeLocked: "已鎖定 {0} 的主題:agent 無法變更。", themeUnlocked: "已解除 {0} 的主題鎖定。",
|
|
194
241
|
themeFailed: "主題沒有變更({0})。",
|
|
195
242
|
widgetRemoveHeader: "移除聊天標頭的小工具", widgetRemoveDetails: "移除詳細資料頁的小工具", widgetRemoved: "已移除 {0} 的小工具。",
|
|
243
|
+
ambientBlocked_hidden: "環境效果未顯示:已關閉 agent 的主題——開啟",
|
|
244
|
+
ambientBlocked_safe: "環境效果未顯示:安全模式(?safe=1)——離開安全模式",
|
|
245
|
+
ambientBlocked_reducedMotion: "環境效果未顯示:這台裝置跟隨「減少動態效果」——仍然播放",
|
|
246
|
+
ambientBlocked_unsupported: "環境效果未顯示:此瀏覽器無法播放",
|
|
247
|
+
ambientClearLoop: "清除環境效果", ambientClearClick: "清除點擊效果", ambientCleared: "已清除 {0} 的環境效果。",
|
|
248
|
+
ambientMotionNote: "你的系統要求減少動態效果;效果目前開著。", ambientMotionNoteLink: "在這裡關閉", ambientMotionNoteClose: "關閉",
|
|
196
249
|
configured: "(設定值)", fleetDefault: "(fleet 預設)",
|
|
197
250
|
},
|
|
198
251
|
});
|