@songsid/agend 2.3.0-beta.2 → 2.3.0-beta.20
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 +7 -1
- package/README.zh-TW.md +7 -1
- package/dist/agent-cli-instructions.md +9 -2
- package/dist/agent-cli.js +63 -2
- 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 +4 -1
- package/dist/agent-file-read.js +189 -16
- 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 -5
- 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 +18 -8
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-metadata.d.ts +8 -0
- package/dist/backend/codex-metadata.js +74 -17
- package/dist/backend/codex-metadata.js.map +1 -1
- package/dist/backend/codex.js +15 -2
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/credential-profile.d.ts +2 -0
- package/dist/backend/credential-profile.js +2 -0
- package/dist/backend/credential-profile.js.map +1 -1
- package/dist/backend/types.d.ts +6 -0
- package/dist/backend/types.js +15 -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 +23 -3
- package/dist/backend-command.js +25 -4
- package/dist/backend-command.js.map +1 -1
- package/dist/bug-report-cli.d.ts +30 -0
- package/dist/bug-report-cli.js +138 -0
- package/dist/bug-report-cli.js.map +1 -0
- package/dist/bug-report.d.ts +47 -0
- package/dist/bug-report.js +136 -0
- package/dist/bug-report.js.map +1 -0
- 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-ledger.d.ts +16 -3
- package/dist/cache-ledger.js +33 -13
- package/dist/cache-ledger.js.map +1 -1
- package/dist/cache-service.d.ts +55 -3
- package/dist/cache-service.js +152 -16
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/adapters/discord-client-retirement.d.ts +5 -0
- package/dist/channel/adapters/discord-client-retirement.js +57 -0
- package/dist/channel/adapters/discord-client-retirement.js.map +1 -0
- package/dist/channel/adapters/discord.d.ts +9 -0
- package/dist/channel/adapters/discord.js +49 -4
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/mcp-tools.js +22 -11
- 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 +224 -111
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.d.ts +6 -0
- package/dist/config-validator.js +129 -3
- package/dist/config-validator.js.map +1 -1
- package/dist/config.d.ts +13 -1
- package/dist/config.js +14 -5
- package/dist/config.js.map +1 -1
- package/dist/cross-instance-notice.d.ts +7 -0
- package/dist/cross-instance-notice.js +10 -0
- package/dist/cross-instance-notice.js.map +1 -1
- package/dist/daemon.d.ts +24 -1
- package/dist/daemon.js +151 -19
- 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 +17 -1
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/diagnostic-redaction.d.ts +10 -0
- package/dist/diagnostic-redaction.js +167 -0
- package/dist/diagnostic-redaction.js.map +1 -0
- package/dist/fleet-context.d.ts +10 -0
- package/dist/fleet-manager.d.ts +505 -15
- package/dist/fleet-manager.js +1870 -204
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-process-handlers.d.ts +18 -0
- package/dist/fleet-process-handlers.js +69 -0
- package/dist/fleet-process-handlers.js.map +1 -0
- 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/bug-report/SKILL.md +31 -0
- package/dist/general-knowledge/skills/credential-profiles/SKILL.md +17 -6
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +6 -1
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +2 -0
- 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/scheduling/SKILL.md +4 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +190 -47
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +545 -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 +7 -1
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +10 -1
- package/dist/instance-lifecycle.js +79 -18
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instance-names.d.ts +4 -0
- package/dist/instance-names.js +12 -0
- package/dist/instance-names.js.map +1 -0
- package/dist/instructions.d.ts +12 -1
- package/dist/instructions.js +13 -2
- package/dist/instructions.js.map +1 -1
- package/dist/locale.js +173 -12
- package/dist/locale.js.map +1 -1
- package/dist/log-steps.d.ts +1 -0
- package/dist/log-steps.js +15 -0
- package/dist/log-steps.js.map +1 -1
- package/dist/login-controller.d.ts +45 -0
- package/dist/login-controller.js +101 -5
- package/dist/login-controller.js.map +1 -1
- package/dist/ls-attach-resolve.d.ts +96 -0
- package/dist/ls-attach-resolve.js +180 -0
- package/dist/ls-attach-resolve.js.map +1 -0
- package/dist/ls-rows.d.ts +12 -0
- package/dist/ls-rows.js +82 -3
- package/dist/ls-rows.js.map +1 -1
- package/dist/memory-hogs.d.ts +27 -0
- package/dist/memory-hogs.js +124 -0
- package/dist/memory-hogs.js.map +1 -0
- package/dist/needs-you.d.ts +10 -0
- package/dist/needs-you.js +2 -1
- package/dist/needs-you.js.map +1 -1
- package/dist/outbound-handlers.d.ts +11 -0
- package/dist/outbound-handlers.js +139 -11
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +200 -4
- package/dist/outbound-schemas.js +124 -11
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +17 -4
- 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 +19 -1
- package/dist/quickstart-api.js +94 -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 +80 -1
- package/dist/restart-progress.js +306 -21
- 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/db.d.ts +40 -13
- package/dist/scheduler/db.js +123 -89
- package/dist/scheduler/db.js.map +1 -1
- package/dist/scheduler/task-board-text.d.ts +26 -0
- package/dist/scheduler/task-board-text.js +135 -0
- package/dist/scheduler/task-board-text.js.map +1 -0
- package/dist/scheduler/task-board.d.ts +650 -0
- package/dist/scheduler/task-board.js +1938 -0
- package/dist/scheduler/task-board.js.map +1 -0
- package/dist/scheduler/types.d.ts +6 -1
- package/dist/search/search-docs.d.ts +58 -0
- package/dist/search/search-docs.js +63 -0
- package/dist/search/search-docs.js.map +1 -0
- package/dist/search/search-index.d.ts +141 -0
- package/dist/search/search-index.js +440 -0
- package/dist/search/search-index.js.map +1 -0
- package/dist/search/search-store.d.ts +122 -0
- package/dist/search/search-store.js +236 -0
- package/dist/search/search-store.js.map +1 -0
- package/dist/search/search-worker.d.ts +1 -0
- package/dist/search/search-worker.js +163 -0
- package/dist/search/search-worker.js.map +1 -0
- package/dist/service-installer.js +12 -0
- package/dist/service-installer.js.map +1 -1
- package/dist/settings-api.d.ts +23 -0
- package/dist/settings-api.js +164 -3
- 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-confirmation.d.ts +3 -1
- package/dist/settings-confirmation.js +2 -0
- package/dist/settings-confirmation.js.map +1 -1
- package/dist/settings-effect.js +34 -3
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.d.ts +11 -0
- package/dist/settings-http-confirmation.js +10 -0
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/setup-form.d.ts +1 -1
- package/dist/setup-form.js +23 -7
- package/dist/setup-form.js.map +1 -1
- package/dist/spawn-gate.d.ts +1 -0
- package/dist/spawn-gate.js +13 -3
- package/dist/spawn-gate.js.map +1 -1
- package/dist/task-board-tool.d.ts +25 -0
- package/dist/task-board-tool.js +154 -0
- package/dist/task-board-tool.js.map +1 -0
- package/dist/task-board-waker.d.ts +44 -0
- package/dist/task-board-waker.js +128 -0
- package/dist/task-board-waker.js.map +1 -0
- package/dist/tmux-exec-helper.d.ts +94 -0
- package/dist/tmux-exec-helper.js +407 -0
- package/dist/tmux-exec-helper.js.map +1 -0
- package/dist/tmux-manager.d.ts +5 -0
- package/dist/tmux-manager.js +42 -11
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tool-permissions.d.ts +0 -7
- package/dist/tool-permissions.js +44 -5
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.d.ts +17 -1
- package/dist/topic-commands.js +45 -19
- package/dist/topic-commands.js.map +1 -1
- package/dist/tunnel/cloudflared.js +37 -2
- package/dist/tunnel/cloudflared.js.map +1 -1
- package/dist/tunnel/types.d.ts +3 -1
- package/dist/tunnel/types.js.map +1 -1
- package/dist/types.d.ts +63 -1
- package/dist/ui/app-effects.js +90 -32
- package/dist/ui/backend-signin.js +297 -0
- package/dist/ui/chat-ambient.js +307 -0
- package/dist/ui/chat-effect-posters.js +8 -8
- package/dist/ui/chat-effects.js +110 -15
- package/dist/ui/chat-msg-actions.js +176 -0
- package/dist/ui/chat-render.js +21 -3
- package/dist/ui/chat-store.js +64 -12
- package/dist/ui/chat-strings.js +85 -8
- package/dist/ui/chat-thread.js +204 -21
- package/dist/ui/effect-trial-controller.js +13 -8
- package/dist/ui/effect-trial-panel.js +19 -16
- package/dist/ui/effects-waker.js +70 -0
- package/dist/ui/fleet-canvas-layout.js +117 -0
- package/dist/ui/fleet-canvas.js +555 -0
- package/dist/ui/fleet-org.js +27 -12
- package/dist/ui/fleet-route-scene.js +207 -0
- package/dist/ui/fleet-route-worker.js +21 -0
- package/dist/ui/fleet-route.js +88 -0
- package/dist/ui/fleet-task-card.js +436 -0
- package/dist/ui/fleet-task-common.js +448 -0
- package/dist/ui/fleet-tasks.js +535 -0
- package/dist/ui/fleet-traffic.js +359 -0
- package/dist/ui/fleet-usage.js +435 -0
- package/dist/ui/panel-chat.js +264 -66
- package/dist/ui/panel-details.js +2 -1
- package/dist/ui/panel-fleet.js +65 -83
- package/dist/ui/panel-needs.js +4 -2
- package/dist/ui/panel-settings.js +56 -11
- package/dist/ui/preview.js +3 -2
- package/dist/ui/search-dialog.js +349 -0
- package/dist/ui/settings-appearance.js +44 -19
- package/dist/ui/settings-apply.js +3 -3
- package/dist/ui/settings-catalog.js +92 -0
- package/dist/ui/settings-confirm.js +7 -2
- 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 +15 -13
- package/dist/ui/settings-strings.js +122 -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 +11 -2
- package/dist/ui/shared/app-prefs.js +17 -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 +174 -30
- package/dist/ui/shared/app-store.js +26 -1
- package/dist/ui/shared/app-stream.js +5 -1
- package/dist/ui/shared/app-themes.js +140 -7
- package/dist/ui/shared/app.css +704 -20
- package/dist/ui/shared/app.js +26 -15
- package/dist/ui/shared/card-strings.js +8 -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-owner-source.js +8 -1
- 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 +97 -50
- 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 +100 -11
- package/dist/ui/shared/identity-color.js +14 -10
- package/dist/ui/shared/instance-nav.js +179 -23
- package/dist/ui/shared/owner-css.js +30 -1
- package/dist/ui/shared/panel-view.js +24 -4
- package/dist/ui/shared/tokens.css +9 -3
- package/dist/ui/shared/ui-icons.js +2 -0
- package/dist/ui/shared/ui-menu.js +20 -7
- package/dist/ui/shared/ui-toast.js +16 -3
- package/dist/ui/shared/usage-dialog.js +34 -3
- package/dist/ui/shared/view-strings.js +72 -0
- package/dist/ui/shared/web-authorize.js +198 -0
- package/dist/ui/web-terminal/terminal.css +4 -4
- package/dist/ui/web-terminal/terminal.html +1 -1
- package/dist/update-launch.d.ts +9 -0
- package/dist/update-launch.js +38 -12
- package/dist/update-launch.js.map +1 -1
- package/dist/usage/format-rich.js +6 -3
- package/dist/usage/format-rich.js.map +1 -1
- package/dist/usage/i18n-keys.d.ts +1 -1
- package/dist/usage/i18n-keys.js +2 -1
- package/dist/usage/i18n-keys.js.map +1 -1
- package/dist/usage/i18n.d.ts +13 -1
- package/dist/usage/i18n.js +29 -0
- package/dist/usage/i18n.js.map +1 -1
- package/dist/usage/providers.d.ts +81 -2
- package/dist/usage/providers.js +240 -38
- package/dist/usage/providers.js.map +1 -1
- package/dist/usage/usage-api.d.ts +5 -1
- package/dist/usage/usage-api.js +184 -58
- package/dist/usage/usage-api.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/user-systemd.d.ts +24 -0
- package/dist/user-systemd.js +75 -0
- package/dist/user-systemd.js.map +1 -0
- package/dist/view-api.d.ts +39 -0
- package/dist/view-api.js +69 -6
- 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 +98 -14
- package/dist/web-api.js +1027 -83
- 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 +85 -8
- package/dist/web-appearance.js.map +1 -1
- package/dist/web-asset-parts.d.ts +2 -2
- 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-backend-login.d.ts +130 -0
- package/dist/web-backend-login.js +225 -0
- package/dist/web-backend-login.js.map +1 -0
- 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 +83 -0
- package/dist/web-chat-history.js +137 -5
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-commands.d.ts +6 -1
- package/dist/web-commands.js +1 -1
- package/dist/web-commands.js.map +1 -1
- 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 +25 -4
- package/dist/web-effect-service.js.map +1 -1
- package/dist/web-effect-tools.d.ts +1 -0
- package/dist/web-effect-tools.js +4 -4
- package/dist/web-effect-tools.js.map +1 -1
- package/dist/web-effect-trials.d.ts +2 -2
- package/dist/web-effect-trials.js +3 -3
- package/dist/web-effect-trials.js.map +1 -1
- package/dist/web-effect-upload.js +1 -1
- 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 +1 -1
- package/dist/web-guest-access.d.ts +126 -0
- package/dist/web-guest-access.js +238 -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-host-guard.d.ts +11 -0
- package/dist/web-host-guard.js +11 -0
- package/dist/web-host-guard.js.map +1 -1
- 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-libavoid.d.ts +14 -0
- package/dist/web-libavoid.js +46 -0
- package/dist/web-libavoid.js.map +1 -0
- package/dist/web-login.d.ts +47 -0
- package/dist/web-login.js +115 -0
- package/dist/web-login.js.map +1 -1
- package/dist/web-mod-agent.d.ts +1 -1
- package/dist/web-mod-agent.js +7 -5
- package/dist/web-mod-agent.js.map +1 -1
- package/dist/web-mod-bundle.d.ts +9 -1
- package/dist/web-mod-bundle.js +62 -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 +19 -6
- package/dist/web-mod-store.js.map +1 -1
- package/dist/web-owner-css-store.d.ts +44 -1
- package/dist/web-owner-css-store.js +70 -9
- package/dist/web-owner-css-store.js.map +1 -1
- package/dist/web-prefs.d.ts +14 -0
- package/dist/web-prefs.js +37 -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 +94 -0
- package/dist/web-settings-tools.js +301 -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-terminal-http.js +15 -2
- package/dist/web-terminal-http.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 +31 -0
- package/dist/web-theme.js +99 -2
- 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/windows-shortcuts.d.ts +78 -0
- package/dist/windows-shortcuts.js +203 -0
- package/dist/windows-shortcuts.js.map +1 -0
- package/dist/workflow-templates/default.md +4 -1
- package/dist/yaml-shared-nodes.d.ts +25 -0
- package/dist/yaml-shared-nodes.js +185 -0
- package/dist/yaml-shared-nodes.js.map +1 -0
- package/launcher/agend-install.cjs +553 -0
- package/launcher/install-admission.cjs +4 -39
- package/launcher/postinstall.cjs +14 -12
- package/package.json +4 -2
- package/scripts/preinstall-guard.cjs +2 -5
- package/templates/windows-shortcuts.ps1 +181 -0
- package/launcher/old-updater-note.cjs +0 -48
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** #1629: host-issued LOCAL trial paint receipt. No authority, loader, frame factory or pool is created here. */
|
|
2
|
+
import { effectTrialShadow } from "./effect-trial-shadow.js";
|
|
2
3
|
import { effectHostStyle } from "./effect-host-style.js";
|
|
3
|
-
import { effectStockSnapshot } from "./effect-stock-snapshot.js";
|
|
4
|
+
import { effectStockSnapshot, effectStockRefusal } from "./effect-stock-snapshot.js";
|
|
4
5
|
import { STOCK_EFFECT_BARRIERS } from "./effect-stock-trust.js";
|
|
5
6
|
const receipts = new WeakMap(), owners = new WeakMap();
|
|
6
7
|
let serial = 0;
|
|
@@ -58,11 +59,13 @@ export function effectTrialStage(receipt, expected, stock) {
|
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
/** Only the fixed host TrialPanel supplies these elements and a current server-run lease. Not an agent manifest. */
|
|
61
|
-
export function createEffectTrialStage({ window: host, panel, stage, binding: raw, current,
|
|
62
|
+
export function createEffectTrialStage({ window: host, panel, stage, binding: raw, current, onStop = () => {} } = {}) {
|
|
62
63
|
const own = binding(raw);
|
|
63
|
-
if (!own || typeof current !== "function" || typeof
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
if (!own || typeof current !== "function" || typeof onStop !== "function" || !host?.document || !panel || !stage || owners.has(stage)) return null;
|
|
65
|
+
const shell = effectTrialShadow(host, panel), hostSheet = effectHostStyle(host);
|
|
66
|
+
let sheet; try { sheet = shell?.sheet; if (!shell || shell.stage !== stage || !hostSheet || !sheet || host.CSS?.supports("contain", "paint") !== true || host.CSS.supports("overflow", "clip") !== true) return null; } catch { return null; }
|
|
67
|
+
const receipt = Object.freeze(Object.create(null)), frames = new Set(), listeners = new Set(); let dead = false, constraint = null, failure = "stage_unavailable";
|
|
68
|
+
const reject = reason => { failure = reason; return null; };
|
|
66
69
|
const identity = Object.freeze({ key: own.key, id: own.id, instance: own.instance, generation: own.generation, serial: ++serial });
|
|
67
70
|
const invalidate = reason => {
|
|
68
71
|
if (dead) return; dead = true; receipts.delete(receipt); if (owners.get(stage) === receipt) owners.delete(stage);
|
|
@@ -74,62 +77,81 @@ export function createEffectTrialStage({ window: host, panel, stage, binding: ra
|
|
|
74
77
|
};
|
|
75
78
|
const blur = event => { if (event.target === host) invalidate("blur"); };
|
|
76
79
|
function check(stock) {
|
|
80
|
+
failure = "trial_layout_unverified";
|
|
77
81
|
try {
|
|
78
82
|
// This callback may reenter disposal or replace the owner. Recheck identity after it returns.
|
|
79
|
-
if (dead || current(own) !== true || constraint !== null && constraint() !== true || dead || owners.get(stage) !== receipt ||
|
|
83
|
+
if (dead || current(own) !== true || constraint !== null && constraint() !== true || dead || owners.get(stage) !== receipt || dead) return reject("trial_current_changed");
|
|
80
84
|
const proof = effectStockSnapshot(stock), doc = host.document;
|
|
81
|
-
if (
|
|
85
|
+
if (!proof) return reject(effectStockRefusal(stock));
|
|
86
|
+
if (effectHostStyle(host) !== hostSheet || effectTrialShadow(host, panel) !== shell) return reject("trial_style_unavailable");
|
|
82
87
|
// The own panel MUST still suppress ordinary foreground effects. Never synthesize front:true.
|
|
83
|
-
if (
|
|
88
|
+
if (doc.hasFocus?.() !== true) return reject("trial_window_unfocused");
|
|
89
|
+
if (doc.visibilityState !== "visible") return reject("hidden");
|
|
90
|
+
if (proof.front !== false || doc.fullscreenElement || doc.pictureInPictureElement) return reject("trial_overlay_unverified");
|
|
84
91
|
const split = doc.querySelector(".main > .p-chat > .chat-split");
|
|
85
92
|
if (!split || doc.querySelectorAll(".main > .p-chat").length !== 1 || doc.querySelectorAll(".chat-split > .pv-panel").length !== 1
|
|
86
|
-
|| panel.parentElement !== split || panel.ownerDocument !== doc || panel.isConnected !== true || panel.className !== "pv-panel effect-trial-panel" || panel.getAttribute("data-trust") !== "preview") return
|
|
87
|
-
const children = [...
|
|
88
|
-
if (children.length !== names.length || children.some((el, i) => el.className !== names[i]) || children[
|
|
89
|
-
|| stage.className !== "effect-trial-stage" || stage.ownerDocument !== doc || stage.isConnected !== true || stage.hasAttribute("tabindex") || stage.hasAttribute("contenteditable")) return
|
|
93
|
+
|| panel.parentElement !== split || panel.ownerDocument !== doc || panel.isConnected !== true || panel.className !== "pv-panel effect-trial-panel" || panel.getAttribute("data-trust") !== "preview") return reject("trial_panel_unavailable");
|
|
94
|
+
const children = [...shell.root.children], names = ["effect-trial-style", "effect-trial-head", "effect-trial-controls", "effect-trial-body", "effect-trial-note"];
|
|
95
|
+
if (panel.children.length !== 0 || children.length !== names.length || children.some((el, i) => el.className !== names[i]) || children[3].children.length !== 1 || children[3].firstElementChild !== stage
|
|
96
|
+
|| stage.className !== "effect-trial-stage" || stage.ownerDocument !== doc || stage.isConnected !== true || stage.hasAttribute("tabindex") || stage.hasAttribute("contenteditable")) return reject("trial_shadow_unverified");
|
|
97
|
+
for (const control of [shell.head, shell.controls, shell.close, shell.stop, shell.note]) {
|
|
98
|
+
const style = host.getComputedStyle(control);
|
|
99
|
+
if (style.display === "none" || style.visibility !== "visible" || style.opacity !== "1" || !rect(control)) return reject("trial_controls_unavailable");
|
|
100
|
+
}
|
|
90
101
|
if ([...doc.querySelectorAll(STOCK_EFFECT_BARRIERS)].some(el => el !== panel && visible(host, el))
|
|
91
|
-
|| [...doc.querySelectorAll(".pv-panel")].some(el => el !== panel && visible(host, el))) return
|
|
102
|
+
|| [...doc.querySelectorAll(".pv-panel")].some(el => el !== panel && visible(host, el))) return reject("trial_other_overlay");
|
|
92
103
|
const active = doc.activeElement;
|
|
93
|
-
if (active && active !== doc.body && active !== doc.documentElement && (active.matches("input,select,textarea,[contenteditable]") || active.isContentEditable)) return
|
|
104
|
+
if (active && active !== doc.body && active !== doc.documentElement && (active.matches("input,select,textarea,[contenteditable]") || active.isContentEditable)) return reject("trial_editable_focus");
|
|
94
105
|
let el = stage, depth = 0;
|
|
95
|
-
while (el) { const s = host.getComputedStyle(el); if (++depth > 128 || el.ownerDocument !== doc || !neutral(s) || s.opacity !== "1" || s.visibility !== "visible" || s.display === "none" || s.contain !== (el === stage ? "paint" : "none")) return
|
|
96
|
-
if (el !== doc.documentElement) return
|
|
106
|
+
while (el) { const s = host.getComputedStyle(el); if (++depth > 128 || el.ownerDocument !== doc || !neutral(s) || s.opacity !== "1" || s.visibility !== "visible" || s.display === "none" || s.contain !== (el === stage ? "paint" : "none")) return reject("trial_ancestor_paint"); if (el === doc.documentElement) break; el = el.parentElement ?? (el.getRootNode?.() === shell.root ? panel : null); }
|
|
107
|
+
if (el !== doc.documentElement) return reject("trial_ancestor_paint");
|
|
97
108
|
const s = host.getComputedStyle(stage), r = rect(stage), p = rect(panel);
|
|
98
109
|
if (!r || !p || s.position !== "relative" || s.zIndex !== "0" || s.overflowX !== "clip" || s.overflowY !== "clip"
|
|
99
110
|
|| s.paddingLeft !== "0px" || s.paddingRight !== "0px" || s.paddingTop !== "0px" || s.paddingBottom !== "0px"
|
|
100
111
|
|| ["borderLeftWidth", "borderRightWidth", "borderTopWidth", "borderBottomWidth"].some(k => s[k] !== "0px") || !none(s.boxShadow) || s.outlineStyle !== "none"
|
|
101
112
|
|| r.x < p.x || r.y < p.y || r.x + r.width > p.x + p.width || r.y + r.height > p.y + p.height
|
|
102
|
-
|| r.x < 0 || r.y < 0 || r.x + r.width > host.innerWidth || r.y + r.height > host.innerHeight) return
|
|
103
|
-
if ([...stage.children].some(child => ![...frames].some(f => f.element === child))) return
|
|
113
|
+
|| r.x < 0 || r.y < 0 || r.x + r.width > host.innerWidth || r.y + r.height > host.innerHeight) return reject("trial_clip_unverified");
|
|
114
|
+
if ([...stage.children].some(child => ![...frames].some(f => f.element === child))) return reject("trial_frame_unknown");
|
|
104
115
|
const width = Math.floor(r.width), height = Math.floor(r.height);
|
|
105
|
-
if (width < 1 || height < 1 || width > 4096 || height > 4096 || width * height > 8388608 || dead || owners.get(stage) !== receipt) return
|
|
106
|
-
if (current(own) !== true || constraint !== null && constraint() !== true || dead || owners.get(stage) !== receipt ||
|
|
116
|
+
if (width < 1 || height < 1 || width > 4096 || height > 4096 || width * height > 8388608 || dead || owners.get(stage) !== receipt) return reject("trial_size_limit");
|
|
117
|
+
if (current(own) !== true || constraint !== null && constraint() !== true || dead || owners.get(stage) !== receipt || dead || stage.isConnected !== true || panel.parentElement !== split) return reject("trial_current_changed");
|
|
107
118
|
return { x: r.x, y: r.y, width, height };
|
|
108
|
-
} catch { return
|
|
119
|
+
} catch { return reject("trial_check_failed"); }
|
|
109
120
|
}
|
|
110
121
|
function project(stock) {
|
|
111
|
-
const r = check(stock); if (!r) { invalidate(
|
|
122
|
+
const r = check(stock); if (!r) { invalidate(failure); return null; }
|
|
112
123
|
return Object.freeze({ root: stage, rect: Object.freeze(r), identity, bind });
|
|
113
124
|
}
|
|
114
125
|
function bind(frame, { layer } = {}, stock) {
|
|
115
126
|
if (frames.size || !["front", "behind"].includes(layer) || frame?.ownerDocument !== host.document || frame.parentElement !== stage || frame.tagName !== "IFRAME") { frame?.remove?.(); return { ok: false }; }
|
|
116
127
|
// The new frame is temporarily known to this owner before the topology check; it remains hidden until sync.
|
|
117
|
-
const token = `agend-effect-trial-${identity.serial}`; let rule, removed = false;
|
|
128
|
+
const token = `agend-effect-trial-${identity.serial}`; let rule, removed = false, shown = false;
|
|
118
129
|
const remove = () => {
|
|
119
130
|
if (removed) return; removed = true; frame.remove(); frames.delete(handle);
|
|
120
131
|
try { frame.classList.remove(token); const i = [...sheet.cssRules].indexOf(rule); if (i >= 0) sheet.deleteRule(i); } catch { /* physically removed first */ }
|
|
121
132
|
};
|
|
122
|
-
const hide = () => {
|
|
133
|
+
const hide = () => {
|
|
134
|
+
shown = false;
|
|
135
|
+
try { rule.style.setProperty("visibility", "hidden", "important"); if (frame.isConnected && host.getComputedStyle(frame).visibility !== "hidden") { remove(); return false; } return !removed; } catch { remove(); return false; }
|
|
136
|
+
};
|
|
123
137
|
const handle = { ok: true, element: frame, remove, hide,
|
|
124
138
|
sync(proof) {
|
|
125
|
-
|
|
139
|
+
const r = check(proof); if (!r || removed) { invalidate(failure); return false; }
|
|
126
140
|
try {
|
|
141
|
+
const matches = visibility => {
|
|
142
|
+
const s = host.getComputedStyle(frame), actual = rect(frame);
|
|
143
|
+
return !!actual && s.position === "absolute" && s.visibility === visibility && s.pointerEvents === "none" && s.zIndex === "0" && s.opacity === (layer === "front" ? "0.85" : "1") && neutral(s)
|
|
144
|
+
&& ["x", "y", "width", "height"].every(k => Math.abs(actual[k] - r[k]) < 0.02) && actual.x >= r.x && actual.y >= r.y && actual.x + actual.width <= r.x + r.width && actual.y + actual.height <= r.y + r.height
|
|
145
|
+
&& frame.isConnected === true && frame.ownerDocument === host.document && frame.parentElement === stage && !dead && !removed && owners.get(stage) === receipt;
|
|
146
|
+
};
|
|
147
|
+
// Reprove the current stage, clipping and actual frame every tick. Hiding/revealing an
|
|
148
|
+
// unchanged iframe each rAF can starve Firefox's OffscreenCanvas presentation.
|
|
149
|
+
if (shown && matches("visible")) return true;
|
|
150
|
+
if (!hide()) throw Error("local hiding lost");
|
|
127
151
|
for (const [k, v] of Object.entries({ left: "0px", top: "0px", width: `${r.width}px`, height: `${r.height}px` })) rule.style.setProperty(k, v, "important");
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
rule.style.setProperty("visibility", "visible", "important"); return true;
|
|
132
|
-
} catch { invalidate("stage_unavailable"); return false; }
|
|
152
|
+
if (!matches("hidden")) throw Error("local geometry lost");
|
|
153
|
+
rule.style.setProperty("visibility", "visible", "important"); shown = true; return true;
|
|
154
|
+
} catch { invalidate("trial_frame_geometry"); return false; }
|
|
133
155
|
},
|
|
134
156
|
};
|
|
135
157
|
frames.add(handle);
|
|
@@ -137,7 +159,8 @@ export function createEffectTrialStage({ window: host, panel, stage, binding: ra
|
|
|
137
159
|
const i = sheet.insertRule(`.${token}{}`, sheet.cssRules.length); rule = sheet.cssRules[i];
|
|
138
160
|
for (const [k, v] of Object.entries({ position: "absolute", visibility: "hidden", "pointer-events": "none", "z-index": "0", opacity: layer === "front" ? "0.85" : "1", border: "0px", margin: "0px", padding: "0px", "box-sizing": "border-box", "min-width": "0px", "min-height": "0px", "max-width": "none", "max-height": "none", outline: "none", "box-shadow": "none", "background-color": "transparent", animation: "none", transition: "none" })) rule.style.setProperty(k, v, "important");
|
|
139
161
|
frame.classList.add(token);
|
|
140
|
-
if (host.getComputedStyle(frame).visibility !== "hidden"
|
|
162
|
+
if (host.getComputedStyle(frame).visibility !== "hidden") throw Error("initial local hiding lost");
|
|
163
|
+
if (!check(stock)) { remove(); invalidate(failure); return { ok: false }; }
|
|
141
164
|
} catch { remove(); invalidate("stage_unavailable"); return { ok: false }; }
|
|
142
165
|
return handle;
|
|
143
166
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/* #2039: fixed closed-shadow Trial chrome; no inherited owner-CSS typography, parts or slots. */
|
|
2
|
+
:host {
|
|
3
|
+
all: initial !important;
|
|
4
|
+
box-sizing: border-box !important;
|
|
5
|
+
display: flex !important;
|
|
6
|
+
flex: 0 0 45% !important;
|
|
7
|
+
flex-direction: column !important;
|
|
8
|
+
align-self: stretch !important;
|
|
9
|
+
width: 45% !important;
|
|
10
|
+
min-width: 320px !important;
|
|
11
|
+
max-width: calc(100% - 368px) !important;
|
|
12
|
+
min-height: 0 !important;
|
|
13
|
+
height: auto !important;
|
|
14
|
+
position: relative !important;
|
|
15
|
+
z-index: 1 !important;
|
|
16
|
+
overflow: clip !important;
|
|
17
|
+
background: #ffffff !important;
|
|
18
|
+
color: #1b1b1f !important;
|
|
19
|
+
font: 400 16px/1.4 system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", emoji !important;
|
|
20
|
+
direction: ltr !important;
|
|
21
|
+
unicode-bidi: isolate !important;
|
|
22
|
+
text-align: start !important;
|
|
23
|
+
visibility: visible !important;
|
|
24
|
+
opacity: 1 !important;
|
|
25
|
+
}
|
|
26
|
+
:host([data-effect-trial-theme="dark"]) { background: #202024 !important; color: #f0f0f4 !important; }
|
|
27
|
+
:host::before, :host::after { all: initial !important; content: none !important; display: none !important; }
|
|
28
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
29
|
+
[hidden] { display: none !important; }
|
|
30
|
+
.effect-trial-head, .effect-trial-controls, .effect-trial-note { position: relative; z-index: 1; padding: 12px; margin: 0; }
|
|
31
|
+
.effect-trial-head { display: flex; align-items: center; gap: 8px; border-bottom: 1px solid currentColor; }
|
|
32
|
+
.effect-trial-title { flex: 1; min-width: 0; overflow-wrap: anywhere; }
|
|
33
|
+
button { appearance: auto; display: inline-block; font: inherit; color: inherit; background: transparent; border: 1px solid currentColor; border-radius: 6px; padding: 8px 12px; cursor: pointer; }
|
|
34
|
+
button:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
|
|
35
|
+
.effect-trial-body { flex: 1; min-height: 0; display: flex; padding: 12px; }
|
|
36
|
+
.effect-trial-stage { position: relative; z-index: 0; flex: 1; min-width: 0; min-height: 0; contain: paint; overflow: clip; padding: 0; border: 0; outline: none; box-shadow: none; }
|
|
37
|
+
.effect-trial-note { font-size: 14px; }
|
|
38
|
+
@media (max-width: 899px) {
|
|
39
|
+
:host { position: fixed !important; inset: 0 !important; z-index: 37 !important; width: auto !important; min-width: 0 !important; max-width: none !important; padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left) !important; }
|
|
40
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// #2117 (the user's direction, hmsg-3c166c26): agents' effects play whatever the system's reduced-motion setting says,
|
|
2
|
+
// unless this device chose "Effects: follow the system's reduced-motion setting". One per-device switch (not synced:
|
|
3
|
+
// it is about this screen), shared by ambient effects and Canvas Worker effects; it also works on the public link.
|
|
4
|
+
export const FX_FOLLOW_REDUCED_MOTION_KEY = "agend_fx_follow_reduced_motion";
|
|
5
|
+
/** The one-time chat note "your system asks for reduced motion; effects are on" was shown on this device. */
|
|
6
|
+
export const FX_MOTION_NOTE_KEY = "agend_fx_motion_note_seen";
|
|
7
|
+
const listeners = new Set();
|
|
8
|
+
let pageChoice = null, noteShown = false;
|
|
9
|
+
|
|
10
|
+
/** Whether this device asked effects to follow the system's reduced-motion setting (default: no). */
|
|
11
|
+
export function followsReducedMotion() {
|
|
12
|
+
if (pageChoice !== null) return pageChoice;
|
|
13
|
+
try { return globalThis.localStorage.getItem(FX_FOLLOW_REDUCED_MOTION_KEY) === "1"; } catch { return false; }
|
|
14
|
+
}
|
|
15
|
+
export function setFollowsReducedMotion(on) {
|
|
16
|
+
pageChoice = !!on;
|
|
17
|
+
try { if (on) globalThis.localStorage.setItem(FX_FOLLOW_REDUCED_MOTION_KEY, "1"); else globalThis.localStorage.removeItem(FX_FOLLOW_REDUCED_MOTION_KEY); } catch { /* this page only */ }
|
|
18
|
+
for (const fn of [...listeners]) { try { fn(); } catch { /* a listener's own */ } }
|
|
19
|
+
}
|
|
20
|
+
/** `fn()` when the switch or the system's answer moves (this tab, another tab, the OS). Returns the unsubscribe. */
|
|
21
|
+
export function onMotionChange(fn) {
|
|
22
|
+
listeners.add(fn);
|
|
23
|
+
const onStorage = (e) => {
|
|
24
|
+
if (!e || e.key === FX_FOLLOW_REDUCED_MOTION_KEY || e.key === null) {
|
|
25
|
+
pageChoice = e?.key === FX_FOLLOW_REDUCED_MOTION_KEY ? e.newValue === "1" : null;
|
|
26
|
+
fn();
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
let q = null;
|
|
30
|
+
try { q = typeof globalThis.matchMedia === "function" ? globalThis.matchMedia("(prefers-reduced-motion: reduce)") : null; } catch { q = null; }
|
|
31
|
+
try { globalThis.addEventListener && globalThis.addEventListener("storage", onStorage); } catch { /* none */ }
|
|
32
|
+
try { if (q && q.addEventListener) q.addEventListener("change", fn); } catch { /* read again on the next render */ }
|
|
33
|
+
return () => {
|
|
34
|
+
listeners.delete(fn);
|
|
35
|
+
try { globalThis.removeEventListener && globalThis.removeEventListener("storage", onStorage); } catch { /* gone */ }
|
|
36
|
+
try { if (q && q.removeEventListener) q.removeEventListener("change", fn); } catch { /* gone */ }
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** Whether the system asks for reduced motion (false when it can't say: the note is only for a clear yes). */
|
|
40
|
+
export function systemReducesMotion(win = globalThis) {
|
|
41
|
+
try { return typeof win.matchMedia === "function" && win.matchMedia("(prefers-reduced-motion: reduce)").matches === true; } catch { return false; }
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The one-time note (the user's direction): the system asks for reduced motion, this device does not follow it, and the
|
|
45
|
+
* note was not shown here before. Showing it marks it shown.
|
|
46
|
+
*/
|
|
47
|
+
export function motionNoteDue(win = globalThis) {
|
|
48
|
+
if (noteShown || followsReducedMotion() || !systemReducesMotion(win)) return false;
|
|
49
|
+
try { return globalThis.localStorage.getItem(FX_MOTION_NOTE_KEY) !== "1"; } catch { return true; }
|
|
50
|
+
}
|
|
51
|
+
export function markMotionNoteShown() {
|
|
52
|
+
noteShown = true;
|
|
53
|
+
try { globalThis.localStorage.setItem(FX_MOTION_NOTE_KEY, "1"); } catch { /* shown again next time: harmless */ }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* True when effects stay still here: this device follows the system's setting and the system asks for reduced motion
|
|
58
|
+
* (or cannot say — then still, as asked for). With the switch off (the default), never.
|
|
59
|
+
*/
|
|
60
|
+
export function motionBlocked(win = globalThis) {
|
|
61
|
+
if (!followsReducedMotion()) return false;
|
|
62
|
+
try {
|
|
63
|
+
if (typeof win.matchMedia !== "function") return true;
|
|
64
|
+
const q = win.matchMedia("(prefers-reduced-motion: reduce)");
|
|
65
|
+
return !q || typeof q.matches !== "boolean" || q.matches;
|
|
66
|
+
} catch { return true; }
|
|
67
|
+
}
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
//
|
|
5
5
|
// Nothing the agent wrote is markup: the tagline and bio are text nodes (never linkified), the pictures are same-origin
|
|
6
6
|
// <img> elements whose URLs are checked here again, and sizes are class tokens only (card-s | card-m | card-l, heights in
|
|
7
|
-
// app.css) — no style attribute, no CSSOM size (#1300).
|
|
7
|
+
// app.css) — no style attribute, no CSSOM size (#1300). #2086: the banner's focus is a position, not a size: one custom
|
|
8
|
+
// property set through the CSSOM (`--id-focus`), and the banner is never drawn wider than BANNER_MAX_ASPECT : 1. The size is a viewer's choice: every card's default
|
|
8
9
|
// (`card.size`) and the cards set apart from it (`card.sizeByInstance`, at most 200), synced like the other preferences.
|
|
9
10
|
import { html, useEffect, useState } from "./app-html.js";
|
|
10
11
|
import { t } from "./app-i18n.js";
|
|
@@ -13,6 +14,28 @@ import { onPrefsChanged, prefInForce, savePref } from "./app-prefs.js";
|
|
|
13
14
|
import "./card-strings.js";
|
|
14
15
|
|
|
15
16
|
export const CARD_SIZES = ["s", "m", "l"];
|
|
17
|
+
/**
|
|
18
|
+
* #2086: the widest a banner is ever drawn (width : height) — app.css caps its width at this many times its size's
|
|
19
|
+
* tallest height. So the band of the picture shown everywhere is (picture's aspect ÷ this) of its height, at the focus.
|
|
20
|
+
*/
|
|
21
|
+
export const BANNER_MAX_ASPECT = 5;
|
|
22
|
+
/**
|
|
23
|
+
* #2086 (#2089 review): the narrowest a card draws its banner — 9 : 4 (app.css caps a banner's height at its box's width ÷ 2.25, on
|
|
24
|
+
* every layout) — which crops a wide picture's sides. Every card is between this and BANNER_MAX_ASPECT, so the area shown on every screen is
|
|
25
|
+
* the narrowest box's width (centred) × the widest box's height (at the focus).
|
|
26
|
+
*/
|
|
27
|
+
export const BANNER_MIN_ASPECT = 9 / 4;
|
|
28
|
+
/** The share of a picture's height a box of `boxAspect` shows (1: all of it; a narrower box crops the sides instead). */
|
|
29
|
+
export const bannerShownHeight = (pictureAspect, boxAspect) => Math.min(1, pictureAspect / boxAspect);
|
|
30
|
+
/** The share of a picture's width a box of `boxAspect` shows, centred (1: all of it). */
|
|
31
|
+
export const bannerShownWidth = (pictureAspect, boxAspect) => Math.min(1, boxAspect / pictureAspect);
|
|
32
|
+
/** The area every screen shows, as shares of the picture: { left, top, width, height } at focus `f`. */
|
|
33
|
+
export function bannerSafeArea(pictureAspect, f) {
|
|
34
|
+
const width = bannerShownWidth(pictureAspect, BANNER_MIN_ASPECT), height = bannerShownHeight(pictureAspect, BANNER_MAX_ASPECT);
|
|
35
|
+
return { left: (1 - width) / 2, top: bannerBandTop(height, f), width, height };
|
|
36
|
+
}
|
|
37
|
+
/** That band's top, as a share of the picture's height, at focus `f` (0–100) — object-position's own rule. */
|
|
38
|
+
export const bannerBandTop = (shown, f) => (1 - shown) * (f / 100);
|
|
16
39
|
export const MAX_CARD_SIZES = 200;
|
|
17
40
|
const own = (o, k) => !!o && Object.prototype.hasOwnProperty.call(o, k);
|
|
18
41
|
const readLocal = (k) => { try { return localStorage.getItem(k); } catch { return null; } };
|
|
@@ -82,6 +105,9 @@ export function checkCard(name, body) {
|
|
|
82
105
|
const v = body[k];
|
|
83
106
|
if (v && typeof v === "object" && typeof v.text === "string" && v.text.length && v.text.length <= MAX[k] && (v.by === "human" || v.by === "agent")) out[k] = { text: v.text, by: v.by };
|
|
84
107
|
}
|
|
108
|
+
// #2086: the banner's focus, a whole number 0 (top) … 100 (bottom).
|
|
109
|
+
const f = body.banner_focus;
|
|
110
|
+
if (f && typeof f === "object" && Number.isInteger(f.value) && f.value >= 0 && f.value <= 100 && (f.by === "human" || f.by === "agent")) out.banner_focus = { value: f.value, by: f.by };
|
|
85
111
|
return Object.keys(out).length ? out : null;
|
|
86
112
|
}
|
|
87
113
|
// #1889 review: per instance, an epoch that moves whenever the version this page wants changes (a clear included).
|
|
@@ -135,30 +161,93 @@ function SizeControl({ name, size }) {
|
|
|
135
161
|
}
|
|
136
162
|
|
|
137
163
|
/**
|
|
138
|
-
*
|
|
164
|
+
* #2217 hotfix (Prism): pictures that failed to load on this page, by src — shared, so the chat's card menu judges a card
|
|
165
|
+
* as drawn (a broken banner is not drawn, and then the card cannot fold), not by its metadata alone.
|
|
166
|
+
*/
|
|
167
|
+
export const brokenPictures = createStore({});
|
|
168
|
+
const markBroken = (src) => { if (src && !brokenPictures.get()[src]) brokenPictures.set((s) => ({ ...s, [src]: true })); };
|
|
169
|
+
const drawn = (card, slot) => !!(card && card[slot] && !brokenPictures.get()[card[slot].src]);
|
|
170
|
+
/**
|
|
171
|
+
* #2217: whether a card can fold its row away and keep the banner — a banner drawn, and something on its row (a picture
|
|
172
|
+
* drawn, a tagline or a bio). The chat's card menu enables Show picture and bio only then.
|
|
173
|
+
*/
|
|
174
|
+
export const cardFoldable = (card) => !!(card && drawn(card, "banner") && (drawn(card, "portrait") || card.tagline || card.bio));
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* The card. `compact`: the chat header's own small size (no size control; the banner still follows the size choice,
|
|
178
|
+
* #2038). Nothing when the card is empty. The
|
|
139
179
|
* tagline and bio say whose they are (title), since a person's field wins over the agent's.
|
|
180
|
+
* #2217: `rowHidden` — the chat's picture and bio folded away, the banner kept. The user (2026-10-20): no control on the
|
|
181
|
+
* card at all — the chat header's two buttons show / hide the card and fold / unfold its row. Only a card with a banner
|
|
182
|
+
* and something on its row folds (cardFoldable; else it would be the card hidden).
|
|
140
183
|
*/
|
|
141
|
-
export function IdentityCard({ name, card, compact = false, sizeControl = !compact }) {
|
|
184
|
+
export function IdentityCard({ name, card, compact = false, sizeControl = !compact, rowHidden = false }) {
|
|
142
185
|
useStore(cardSizeStore);
|
|
143
|
-
const
|
|
186
|
+
const broken = useStore(brokenPictures);
|
|
144
187
|
if (!card) return null;
|
|
145
188
|
const size = compact ? "c" : cardSizeFor(name);
|
|
189
|
+
// #2038: the chat header's card is its own small size, but its banner follows the person's size choice too.
|
|
190
|
+
const bannerSize = compact ? ` bs-${cardSizeFor(name)}` : "";
|
|
146
191
|
const whose = (f) => t(f.by === "human" ? "card.byHuman" : "card.byAgent");
|
|
147
|
-
const pic = (slot, cls, alt) => card[slot] && broken[
|
|
148
|
-
? html`<img class=${cls} src=${card[slot].src} alt=${alt} title=${whose(card[slot])} decoding="async" onError=${() =>
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
192
|
+
const pic = (slot, cls, alt) => card[slot] && !broken[card[slot].src]
|
|
193
|
+
? html`<img class=${cls} src=${card[slot].src} alt=${alt} title=${whose(card[slot])} decoding="async" onError=${() => markBroken(card[slot].src)} />` : null;
|
|
194
|
+
// #2086: the banner at its focus; on a screen wider than BANNER_MAX_ASPECT it is centred over a blurred copy of itself.
|
|
195
|
+
const focus = card.banner_focus ? card.banner_focus.value : 50;
|
|
196
|
+
const atFocus = (el) => { if (el && el.style) el.style.setProperty("--id-focus", `${focus}%`); };
|
|
197
|
+
const banner = pic("banner", "id-banner", "");
|
|
198
|
+
const portrait = pic("portrait", "id-portrait", t("card.portraitAlt", name));
|
|
199
|
+
const rowShown = !(rowHidden && banner && cardFoldable(card));
|
|
200
|
+
return html`<section class=${`id-card card-${size}${bannerSize}${rowShown ? "" : " row-hidden"}`} aria-label=${t("card.label", name)}>
|
|
201
|
+
${banner ? html`<div class="id-banner-box" ref=${atFocus}><img class="id-banner-fill" src=${card.banner.src} alt="" aria-hidden="true" decoding="async" />${banner}</div>` : null}
|
|
202
|
+
${rowShown ? html`<div class="id-row">
|
|
203
|
+
${portrait}
|
|
153
204
|
<div class="id-text">
|
|
154
205
|
${card.tagline ? html`<p class="id-tagline" title=${whose(card.tagline)}>${card.tagline.text}</p>` : null}
|
|
155
206
|
${card.bio ? html`<p class="id-bio" title=${whose(card.bio)}>${card.bio.text}</p>` : null}
|
|
156
207
|
</div>
|
|
157
208
|
${sizeControl ? html`<${SizeControl} name=${name} size=${size} />` : null}
|
|
158
|
-
</div
|
|
209
|
+
</div>` : null}
|
|
159
210
|
</section>`;
|
|
160
211
|
}
|
|
161
212
|
|
|
213
|
+
// ── #2086: the banner's focus, set in View's Edit profile — the whole picture, what each screen shows of it ──
|
|
214
|
+
/**
|
|
215
|
+
* #2089 review: the picture the focus preview shows — a file just chosen (a blob URL this owns: released when another is
|
|
216
|
+
* chosen and when the dialog closes) or the banner drawn now (a server URL, never released).
|
|
217
|
+
*/
|
|
218
|
+
export function useBannerPreview() {
|
|
219
|
+
const [preview, setPreview] = useState(null);
|
|
220
|
+
useEffect(() => () => { if (preview && preview.blob) { try { URL.revokeObjectURL(preview.blob); } catch { /* already gone */ } } }, [preview]);
|
|
221
|
+
return [preview, {
|
|
222
|
+
fromFile(file) { let url = null; try { url = URL.createObjectURL(file); } catch { return; } setPreview({ src: url, blob: url }); },
|
|
223
|
+
fromSrc(src) { setPreview({ src }); },
|
|
224
|
+
}];
|
|
225
|
+
}
|
|
226
|
+
/** A phone draws an M card's banner at about 3 : 1 (app.css, ≤479 px) — a guide for that size, not every phone card. */
|
|
227
|
+
export const BANNER_PHONE_ASPECT = 3;
|
|
228
|
+
/**
|
|
229
|
+
* The banner whole, with the band every screen shows at this focus (dashed; outside it shaded) and the band a phone
|
|
230
|
+
* shows (solid) — measured from the picture itself once it has loaded. Positions go through the CSSOM (#1300).
|
|
231
|
+
*/
|
|
232
|
+
export function BannerFocusPreview({ src, focus }) {
|
|
233
|
+
const [size, setSize] = useState(null);
|
|
234
|
+
if (!src) return null;
|
|
235
|
+
const ar = size ? size.w / size.h : null;
|
|
236
|
+
const put = (el, a) => { for (const k of ["left", "top", "width", "height"]) el.style.setProperty(k, `${(a[k] * 100).toFixed(2)}%`); };
|
|
237
|
+
// Every screen: the safe area (both crops). The phone guide: an M card on a phone, as drawn there (both crops too).
|
|
238
|
+
const safe = (el) => { if (el && el.style && ar) put(el, bannerSafeArea(ar, focus)); };
|
|
239
|
+
const phone = (el) => {
|
|
240
|
+
if (!el || !el.style || !ar) return;
|
|
241
|
+
const width = bannerShownWidth(ar, BANNER_PHONE_ASPECT), height = bannerShownHeight(ar, BANNER_PHONE_ASPECT);
|
|
242
|
+
put(el, { left: (1 - width) / 2, top: bannerBandTop(height, focus), width, height });
|
|
243
|
+
};
|
|
244
|
+
return html`<div class="bf-wrap">
|
|
245
|
+
<img class="bf-pic" src=${src} alt="" onLoad=${(e) => { const i = e.currentTarget; if (i.naturalWidth && i.naturalHeight) setSize({ w: i.naturalWidth, h: i.naturalHeight }); }} />
|
|
246
|
+
${ar ? html`<div class="bf-band bf-phone" ref=${phone}><span>${t("card.bannerPhone")}</span></div>
|
|
247
|
+
<div class="bf-band bf-safe" ref=${safe}><span>${t("card.bannerSafe")}</span></div>` : null}
|
|
248
|
+
</div>`;
|
|
249
|
+
}
|
|
250
|
+
|
|
162
251
|
// ── A person's picture for the card (View's Edit profile), fitted before it is sent (r4.1 Q3 (b)) ──
|
|
163
252
|
/**
|
|
164
253
|
* `file` fitted to `limit` ({ max_width, max_height, max_bytes }): as it is when it already fits; otherwise, once the
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
// (`color`, `color_show`); this module resolves them as src/web-identity-color.ts does (a test pins the two equal),
|
|
4
4
|
// paints the sidebar row through the CSSOM (no style attribute, #1300), and holds the Color dialog.
|
|
5
5
|
// colour: a person's pick > the agent's (themes shown) > its own bot's role colour > automatic (a few soft colours)
|
|
6
|
-
// places: a person's choice > the agent's (themes shown) > this host's default (color.show) >
|
|
6
|
+
// places: a person's choice > the agent's (themes shown) > this host's default (color.show) > all three (#2056)
|
|
7
7
|
// Settings → Web appearance can turn colours off for the host (color.off): nothing is painted, every pick is kept.
|
|
8
8
|
import { html, useEffect, useState } from "./app-html.js";
|
|
9
9
|
import { createStore, useStore } from "./app-store.js";
|
|
10
10
|
import { onPrefsChanged, prefInForce, savePref } from "./app-prefs.js";
|
|
11
11
|
import { register, t } from "./app-i18n.js";
|
|
12
|
-
import { themesShown, themesStore } from "./app-themes.js";
|
|
12
|
+
import { pageNow, themesShown, themesStore } from "./app-themes.js";
|
|
13
13
|
import { Dialog } from "./ui-dialog.js";
|
|
14
14
|
import { toast } from "./ui-toast.js";
|
|
15
15
|
|
|
@@ -30,7 +30,7 @@ export const AUTO_PALETTE = [
|
|
|
30
30
|
{ id: "moss", light: "#5b7340", dark: "#a9c48d" }, { id: "slate", light: "#5f6b78", dark: "#aeb8c4" },
|
|
31
31
|
];
|
|
32
32
|
export const PLACEMENTS = ["name", "bar", "ring"];
|
|
33
|
-
export const DEFAULT_PLACEMENTS = ["bar", "ring"];
|
|
33
|
+
export const DEFAULT_PLACEMENTS = ["name", "bar", "ring"]; // #2056: all three where nobody chose (was ring + bar)
|
|
34
34
|
const HEX = /^#[0-9a-f]{6}$/;
|
|
35
35
|
const presetOf = (c) => (typeof c === "string" && c.startsWith("preset:") ? IDENTITY_PALETTE.find((p) => p.id === c.slice(7)) : undefined);
|
|
36
36
|
const autoOf = (c) => (typeof c === "string" && c.startsWith("auto:") ? AUTO_PALETTE.find((p) => p.id === c.slice(5)) : undefined);
|
|
@@ -63,16 +63,20 @@ export function contrast(a, b) {
|
|
|
63
63
|
const [l1, l2] = [luminance(a), luminance(b)].sort((x, y) => y - x);
|
|
64
64
|
return (l1 + 0.05) / (l2 + 0.05);
|
|
65
65
|
}
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
/**
|
|
67
|
+
* The shade of `hex` name text uses: itself if readable, else the nearest step toward black (light) or white (dark).
|
|
68
|
+
* `page` (#2196): an agent's colours on the page now — names must read on its background and sidebar instead.
|
|
69
|
+
*/
|
|
70
|
+
export function readableShade(hex, mode, page = null) {
|
|
71
|
+
const backgrounds = page ? [page.bg, page.sidebar] : BG[mode], text = page ? page.text : TEXT[mode];
|
|
72
|
+
if (!HEX.test(hex)) return text;
|
|
69
73
|
const toward = mode === "light" ? 0 : 255;
|
|
70
74
|
const ch = [1, 3, 5].map((i) => parseInt(hex.slice(i, i + 2), 16));
|
|
71
75
|
for (let step = 0; step <= 20; step++) {
|
|
72
76
|
const shade = `#${ch.map((c) => Math.round(c + (toward - c) * (step / 20)).toString(16).padStart(2, "0")).join("")}`;
|
|
73
|
-
if (
|
|
77
|
+
if (backgrounds.every((bg) => contrast(shade, bg) >= 4.5)) return shade;
|
|
74
78
|
}
|
|
75
|
-
return
|
|
79
|
+
return text;
|
|
76
80
|
}
|
|
77
81
|
|
|
78
82
|
// ── Resolution ──
|
|
@@ -115,7 +119,7 @@ export function colorsOff() {
|
|
|
115
119
|
const f = prefInForce("color.off");
|
|
116
120
|
return f ? f.value === true : readLocal("agend_color_off") === "on";
|
|
117
121
|
}
|
|
118
|
-
/** The default places (null: back to
|
|
122
|
+
/** The default places (null: back to all three, #2056). */
|
|
119
123
|
export function setDefaultPlaces(list) {
|
|
120
124
|
const v = list === null ? null : placesOk(list);
|
|
121
125
|
const same = v && v.length === DEFAULT_PLACEMENTS.length && v.every((p, i) => p === DEFAULT_PLACEMENTS[i]);
|
|
@@ -135,7 +139,7 @@ export function identityOf(it, opts = {}) {
|
|
|
135
139
|
const light = colorValue(c.color, "light"), dark = colorValue(c.color, "dark");
|
|
136
140
|
return {
|
|
137
141
|
color: c.color, source: c.source, show: p.show, showSource: p.source, off: opts.off ?? colorsOff(),
|
|
138
|
-
light, dark, nameLight: readableShade(light, "light"), nameDark: readableShade(dark, "dark"),
|
|
142
|
+
light, dark, nameLight: readableShade(light, "light", pageNow("light")), nameDark: readableShade(dark, "dark", pageNow("dark")),
|
|
139
143
|
};
|
|
140
144
|
}
|
|
141
145
|
/** The row's classes for its identity colour ("" when colours are off or shown nowhere). */
|